重构温度计算:使用正确的RDG API替代SkipTracking
重构内容: - 移除SkipTracking标志,使用FRDGPooledBuffer包装外部RHI缓冲区 - 使用RegisterExternalBuffer正确注册外部缓冲区到RDG系统 - 简化lambda捕获列表,移除不需要的SRV/UAV引用 - 添加详细的日志输出以便调试 技术改进: - RDG系统现在能正确追踪资源依赖和状态转换 - 自动处理内存屏障和资源同步 - 符合UE5最佳实践 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -856,6 +856,8 @@ void ADynamicIronBlock::DispatchTemperatureCompute(float DeltaTime)
|
||||
{
|
||||
if (!TemperatureBufferA.IsValid() || !TemperatureBufferB.IsValid())
|
||||
{
|
||||
UE_LOG(LogTemp, Error, TEXT("DynamicIronBlock: Temperature buffers not valid! A=%d B=%d"),
|
||||
TemperatureBufferA.IsValid(), TemperatureBufferB.IsValid());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -867,30 +869,22 @@ void ADynamicIronBlock::DispatchTemperatureCompute(float DeltaTime)
|
||||
float ForgeMin = ForgeTemperatureMin;
|
||||
float ForgeMax = ForgeTemperatureMax;
|
||||
|
||||
// Ping-Pong缓冲区引用
|
||||
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock: Dispatching temperature compute - Resolution=(%d,%d,%d), DeltaTime=%.4f"),
|
||||
Resolution.X, Resolution.Y, Resolution.Z, DeltaTime);
|
||||
|
||||
// Ping-Pong缓冲区引用(捕获到lambda传递给RDG)
|
||||
FBufferRHIRef InputBuffer = bUseBufferA ? TemperatureBufferA : TemperatureBufferB;
|
||||
FBufferRHIRef OutputBuffer = bUseBufferA ? TemperatureBufferB : TemperatureBufferA;
|
||||
FBufferRHIRef FlagsBuffer = SurfaceVoxelFlagsBuffer;
|
||||
FBufferRHIRef PlasticityBuf = PlasticityBuffer;
|
||||
|
||||
// 创建SRV/UAV(在游戏线程创建,捕获到lambda)
|
||||
FShaderResourceViewRHIRef InputSRV = TemperatureSRV_A;
|
||||
FShaderResourceViewRHIRef InputSRV_B = TemperatureSRV_B;
|
||||
FShaderResourceViewRHIRef FlagsSRV = SurfaceVoxelSRV;
|
||||
FUnorderedAccessViewRHIRef OutputUAV_A = TemperatureUAV_A;
|
||||
FUnorderedAccessViewRHIRef OutputUAV_B = TemperatureUAV_B;
|
||||
FUnorderedAccessViewRHIRef PlasticityUAV_Ref = PlasticityUAV;
|
||||
|
||||
bool bReadFromA = bUseBufferA;
|
||||
|
||||
// 切换缓冲区(下次Tick使用新的缓冲区)
|
||||
bUseBufferA = !bUseBufferA;
|
||||
|
||||
// 调度GPU计算(直接使用RHI,不用RDG)
|
||||
// 调度GPU计算(使用RDG正确的资源管理)
|
||||
ENQUEUE_RENDER_COMMAND(DispatchTemperatureCS)(
|
||||
[Resolution, Conductivity, Cooling, Ambient, ForgeMin, ForgeMax, DeltaTime,
|
||||
InputBuffer, OutputBuffer, FlagsBuffer, PlasticityBuf,
|
||||
InputSRV, InputSRV_B, FlagsSRV, OutputUAV_A, OutputUAV_B, PlasticityUAV_Ref, bReadFromA]
|
||||
InputBuffer, OutputBuffer, FlagsBuffer, PlasticityBuf]
|
||||
(FRHICommandListImmediate& RHICmdList)
|
||||
{
|
||||
// 检查ShaderMap是否有效
|
||||
@@ -909,21 +903,30 @@ void ADynamicIronBlock::DispatchTemperatureCompute(float DeltaTime)
|
||||
return;
|
||||
}
|
||||
|
||||
// 使用RDG(简化版本 - 创建临时缓冲区)
|
||||
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock [RenderThread]: Shader valid, creating RDG..."));
|
||||
|
||||
// 使用RDG
|
||||
FRDGBuilder GraphBuilder(RHICmdList, RDG_EVENT_NAME("TemperatureConduction"));
|
||||
|
||||
// 创建RDG缓冲区描述
|
||||
FRDGBufferDesc TempBufferDesc = FRDGBufferDesc::CreateBufferDesc(sizeof(float), InputBuffer->GetSize() / sizeof(float));
|
||||
FRDGBufferDesc FlagsBufferDesc = FRDGBufferDesc::CreateBufferDesc(sizeof(uint32), FlagsBuffer->GetSize() / sizeof(uint32));
|
||||
// 将外部RHI缓冲区正确注册到RDG系统
|
||||
// 创建缓冲区描述符
|
||||
const uint32 NumElements = InputBuffer->GetSize() / sizeof(float);
|
||||
FRDGBufferDesc TempBufferDesc = FRDGBufferDesc::CreateBufferDesc(sizeof(float), NumElements);
|
||||
FRDGBufferDesc FlagsBufferDesc = FRDGBufferDesc::CreateBufferDesc(sizeof(uint32), NumElements);
|
||||
|
||||
// 创建RDG缓冲区
|
||||
FRDGBufferRef InputTempRDG = GraphBuilder.CreateBuffer(TempBufferDesc, TEXT("InputTemperatureBuffer"));
|
||||
FRDGBufferRef OutputTempRDG = GraphBuilder.CreateBuffer(TempBufferDesc, TEXT("OutputTemperatureBuffer"));
|
||||
FRDGBufferRef FlagsRDG = GraphBuilder.CreateBuffer(FlagsBufferDesc, TEXT("SurfaceVoxelFlagsBuffer"));
|
||||
FRDGBufferRef PlasticityRDG = GraphBuilder.CreateBuffer(TempBufferDesc, TEXT("PlasticityBuffer"));
|
||||
// 创建FRDGPooledBuffer并注册
|
||||
TRefCountPtr<FRDGPooledBuffer> InputPooledBuffer = new FRDGPooledBuffer(RHICmdList, InputBuffer, TempBufferDesc, NumElements, TEXT("InputTemperatureBuffer"));
|
||||
TRefCountPtr<FRDGPooledBuffer> OutputPooledBuffer = new FRDGPooledBuffer(RHICmdList, OutputBuffer, TempBufferDesc, NumElements, TEXT("OutputTemperatureBuffer"));
|
||||
TRefCountPtr<FRDGPooledBuffer> FlagsPooledBuffer = new FRDGPooledBuffer(RHICmdList, FlagsBuffer, FlagsBufferDesc, NumElements, TEXT("SurfaceVoxelFlagsBuffer"));
|
||||
TRefCountPtr<FRDGPooledBuffer> PlasticityPooledBuffer = new FRDGPooledBuffer(RHICmdList, PlasticityBuf, TempBufferDesc, NumElements, TEXT("PlasticityBuffer"));
|
||||
|
||||
// TODO: 添加数据复制Pass(从RHI到RDG)
|
||||
// 暂时跳过,shader会处理未初始化数据
|
||||
FRDGBufferRef InputTempRDG = GraphBuilder.RegisterExternalBuffer(InputPooledBuffer);
|
||||
FRDGBufferRef OutputTempRDG = GraphBuilder.RegisterExternalBuffer(OutputPooledBuffer);
|
||||
FRDGBufferRef FlagsRDG = GraphBuilder.RegisterExternalBuffer(FlagsPooledBuffer);
|
||||
FRDGBufferRef PlasticityRDG = GraphBuilder.RegisterExternalBuffer(PlasticityPooledBuffer);
|
||||
|
||||
|
||||
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock [RenderThread]: External RHI buffers registered to RDG, setting shader parameters..."));
|
||||
|
||||
// 设置Shader参数
|
||||
FTemperatureComputeShader::FParameters* PassParameters = GraphBuilder.AllocParameters<FTemperatureComputeShader::FParameters>();
|
||||
@@ -935,10 +938,13 @@ void ADynamicIronBlock::DispatchTemperatureCompute(float DeltaTime)
|
||||
PassParameters->ForgeTemperatureMax = ForgeMax;
|
||||
PassParameters->DeltaTime = DeltaTime;
|
||||
|
||||
PassParameters->InputTemperatureBuffer = GraphBuilder.CreateSRV(InputTempRDG, PF_R32_FLOAT);
|
||||
PassParameters->SurfaceVoxelFlagsBuffer = GraphBuilder.CreateSRV(FlagsRDG, PF_R32_UINT);
|
||||
PassParameters->OutputTemperatureBuffer = GraphBuilder.CreateUAV(OutputTempRDG, PF_R32_FLOAT);
|
||||
PassParameters->OutputPlasticityBuffer = GraphBuilder.CreateUAV(PlasticityRDG, PF_R32_FLOAT);
|
||||
// 创建SRV和UAV(使用正确注册的RDG资源)
|
||||
PassParameters->InputTemperatureBuffer = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(InputTempRDG, PF_R32_FLOAT));
|
||||
PassParameters->SurfaceVoxelFlagsBuffer = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(FlagsRDG, PF_R32_UINT));
|
||||
PassParameters->OutputTemperatureBuffer = GraphBuilder.CreateUAV(FRDGBufferUAVDesc(OutputTempRDG, PF_R32_FLOAT));
|
||||
PassParameters->OutputPlasticityBuffer = GraphBuilder.CreateUAV(FRDGBufferUAVDesc(PlasticityRDG, PF_R32_FLOAT));
|
||||
|
||||
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock [RenderThread]: Shader parameters set, calculating group count..."));
|
||||
|
||||
// 计算线程组数量
|
||||
FIntVector GroupSize = FTemperatureComputeShader::GetGroupSize();
|
||||
@@ -948,6 +954,9 @@ void ADynamicIronBlock::DispatchTemperatureCompute(float DeltaTime)
|
||||
FMath::DivideAndRoundUp(Resolution.Z, GroupSize.Z)
|
||||
);
|
||||
|
||||
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock [RenderThread]: GroupCount=(%d,%d,%d), adding compute pass..."),
|
||||
GroupCount.X, GroupCount.Y, GroupCount.Z);
|
||||
|
||||
// 添加计算Pass
|
||||
FComputeShaderUtils::AddPass(
|
||||
GraphBuilder,
|
||||
@@ -957,13 +966,12 @@ void ADynamicIronBlock::DispatchTemperatureCompute(float DeltaTime)
|
||||
GroupCount
|
||||
);
|
||||
|
||||
// TODO: 添加数据复制Pass(从RDG回RHI)
|
||||
// 暂时跳过,需要实现正确的缓冲区提取
|
||||
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock [RenderThread]: Compute pass added, executing RDG..."));
|
||||
|
||||
// 执行RDG
|
||||
// 执行RDG,自动处理资源转换和同步
|
||||
GraphBuilder.Execute();
|
||||
|
||||
UE_LOG(LogTemp, Warning, TEXT("DynamicIronBlock: Temperature compute dispatched (%d x %d x %d groups) - Data copy not yet implemented"),
|
||||
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock: Temperature compute dispatched successfully (%d x %d x %d groups)"),
|
||||
GroupCount.X, GroupCount.Y, GroupCount.Z);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user