重构温度计算:使用正确的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())
|
if (!TemperatureBufferA.IsValid() || !TemperatureBufferB.IsValid())
|
||||||
{
|
{
|
||||||
|
UE_LOG(LogTemp, Error, TEXT("DynamicIronBlock: Temperature buffers not valid! A=%d B=%d"),
|
||||||
|
TemperatureBufferA.IsValid(), TemperatureBufferB.IsValid());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -867,30 +869,22 @@ void ADynamicIronBlock::DispatchTemperatureCompute(float DeltaTime)
|
|||||||
float ForgeMin = ForgeTemperatureMin;
|
float ForgeMin = ForgeTemperatureMin;
|
||||||
float ForgeMax = ForgeTemperatureMax;
|
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 InputBuffer = bUseBufferA ? TemperatureBufferA : TemperatureBufferB;
|
||||||
FBufferRHIRef OutputBuffer = bUseBufferA ? TemperatureBufferB : TemperatureBufferA;
|
FBufferRHIRef OutputBuffer = bUseBufferA ? TemperatureBufferB : TemperatureBufferA;
|
||||||
FBufferRHIRef FlagsBuffer = SurfaceVoxelFlagsBuffer;
|
FBufferRHIRef FlagsBuffer = SurfaceVoxelFlagsBuffer;
|
||||||
FBufferRHIRef PlasticityBuf = PlasticityBuffer;
|
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使用新的缓冲区)
|
// 切换缓冲区(下次Tick使用新的缓冲区)
|
||||||
bUseBufferA = !bUseBufferA;
|
bUseBufferA = !bUseBufferA;
|
||||||
|
|
||||||
// 调度GPU计算(直接使用RHI,不用RDG)
|
// 调度GPU计算(使用RDG正确的资源管理)
|
||||||
ENQUEUE_RENDER_COMMAND(DispatchTemperatureCS)(
|
ENQUEUE_RENDER_COMMAND(DispatchTemperatureCS)(
|
||||||
[Resolution, Conductivity, Cooling, Ambient, ForgeMin, ForgeMax, DeltaTime,
|
[Resolution, Conductivity, Cooling, Ambient, ForgeMin, ForgeMax, DeltaTime,
|
||||||
InputBuffer, OutputBuffer, FlagsBuffer, PlasticityBuf,
|
InputBuffer, OutputBuffer, FlagsBuffer, PlasticityBuf]
|
||||||
InputSRV, InputSRV_B, FlagsSRV, OutputUAV_A, OutputUAV_B, PlasticityUAV_Ref, bReadFromA]
|
|
||||||
(FRHICommandListImmediate& RHICmdList)
|
(FRHICommandListImmediate& RHICmdList)
|
||||||
{
|
{
|
||||||
// 检查ShaderMap是否有效
|
// 检查ShaderMap是否有效
|
||||||
@@ -909,21 +903,30 @@ void ADynamicIronBlock::DispatchTemperatureCompute(float DeltaTime)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用RDG(简化版本 - 创建临时缓冲区)
|
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock [RenderThread]: Shader valid, creating RDG..."));
|
||||||
|
|
||||||
|
// 使用RDG
|
||||||
FRDGBuilder GraphBuilder(RHICmdList, RDG_EVENT_NAME("TemperatureConduction"));
|
FRDGBuilder GraphBuilder(RHICmdList, RDG_EVENT_NAME("TemperatureConduction"));
|
||||||
|
|
||||||
// 创建RDG缓冲区描述
|
// 将外部RHI缓冲区正确注册到RDG系统
|
||||||
FRDGBufferDesc TempBufferDesc = FRDGBufferDesc::CreateBufferDesc(sizeof(float), InputBuffer->GetSize() / sizeof(float));
|
// 创建缓冲区描述符
|
||||||
FRDGBufferDesc FlagsBufferDesc = FRDGBufferDesc::CreateBufferDesc(sizeof(uint32), FlagsBuffer->GetSize() / sizeof(uint32));
|
const uint32 NumElements = InputBuffer->GetSize() / sizeof(float);
|
||||||
|
FRDGBufferDesc TempBufferDesc = FRDGBufferDesc::CreateBufferDesc(sizeof(float), NumElements);
|
||||||
|
FRDGBufferDesc FlagsBufferDesc = FRDGBufferDesc::CreateBufferDesc(sizeof(uint32), NumElements);
|
||||||
|
|
||||||
// 创建RDG缓冲区
|
// 创建FRDGPooledBuffer并注册
|
||||||
FRDGBufferRef InputTempRDG = GraphBuilder.CreateBuffer(TempBufferDesc, TEXT("InputTemperatureBuffer"));
|
TRefCountPtr<FRDGPooledBuffer> InputPooledBuffer = new FRDGPooledBuffer(RHICmdList, InputBuffer, TempBufferDesc, NumElements, TEXT("InputTemperatureBuffer"));
|
||||||
FRDGBufferRef OutputTempRDG = GraphBuilder.CreateBuffer(TempBufferDesc, TEXT("OutputTemperatureBuffer"));
|
TRefCountPtr<FRDGPooledBuffer> OutputPooledBuffer = new FRDGPooledBuffer(RHICmdList, OutputBuffer, TempBufferDesc, NumElements, TEXT("OutputTemperatureBuffer"));
|
||||||
FRDGBufferRef FlagsRDG = GraphBuilder.CreateBuffer(FlagsBufferDesc, TEXT("SurfaceVoxelFlagsBuffer"));
|
TRefCountPtr<FRDGPooledBuffer> FlagsPooledBuffer = new FRDGPooledBuffer(RHICmdList, FlagsBuffer, FlagsBufferDesc, NumElements, TEXT("SurfaceVoxelFlagsBuffer"));
|
||||||
FRDGBufferRef PlasticityRDG = GraphBuilder.CreateBuffer(TempBufferDesc, TEXT("PlasticityBuffer"));
|
TRefCountPtr<FRDGPooledBuffer> PlasticityPooledBuffer = new FRDGPooledBuffer(RHICmdList, PlasticityBuf, TempBufferDesc, NumElements, TEXT("PlasticityBuffer"));
|
||||||
|
|
||||||
// TODO: 添加数据复制Pass(从RHI到RDG)
|
FRDGBufferRef InputTempRDG = GraphBuilder.RegisterExternalBuffer(InputPooledBuffer);
|
||||||
// 暂时跳过,shader会处理未初始化数据
|
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参数
|
// 设置Shader参数
|
||||||
FTemperatureComputeShader::FParameters* PassParameters = GraphBuilder.AllocParameters<FTemperatureComputeShader::FParameters>();
|
FTemperatureComputeShader::FParameters* PassParameters = GraphBuilder.AllocParameters<FTemperatureComputeShader::FParameters>();
|
||||||
@@ -935,10 +938,13 @@ void ADynamicIronBlock::DispatchTemperatureCompute(float DeltaTime)
|
|||||||
PassParameters->ForgeTemperatureMax = ForgeMax;
|
PassParameters->ForgeTemperatureMax = ForgeMax;
|
||||||
PassParameters->DeltaTime = DeltaTime;
|
PassParameters->DeltaTime = DeltaTime;
|
||||||
|
|
||||||
PassParameters->InputTemperatureBuffer = GraphBuilder.CreateSRV(InputTempRDG, PF_R32_FLOAT);
|
// 创建SRV和UAV(使用正确注册的RDG资源)
|
||||||
PassParameters->SurfaceVoxelFlagsBuffer = GraphBuilder.CreateSRV(FlagsRDG, PF_R32_UINT);
|
PassParameters->InputTemperatureBuffer = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(InputTempRDG, PF_R32_FLOAT));
|
||||||
PassParameters->OutputTemperatureBuffer = GraphBuilder.CreateUAV(OutputTempRDG, PF_R32_FLOAT);
|
PassParameters->SurfaceVoxelFlagsBuffer = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(FlagsRDG, PF_R32_UINT));
|
||||||
PassParameters->OutputPlasticityBuffer = GraphBuilder.CreateUAV(PlasticityRDG, PF_R32_FLOAT);
|
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();
|
FIntVector GroupSize = FTemperatureComputeShader::GetGroupSize();
|
||||||
@@ -948,6 +954,9 @@ void ADynamicIronBlock::DispatchTemperatureCompute(float DeltaTime)
|
|||||||
FMath::DivideAndRoundUp(Resolution.Z, GroupSize.Z)
|
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
|
// 添加计算Pass
|
||||||
FComputeShaderUtils::AddPass(
|
FComputeShaderUtils::AddPass(
|
||||||
GraphBuilder,
|
GraphBuilder,
|
||||||
@@ -957,13 +966,12 @@ void ADynamicIronBlock::DispatchTemperatureCompute(float DeltaTime)
|
|||||||
GroupCount
|
GroupCount
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: 添加数据复制Pass(从RDG回RHI)
|
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock [RenderThread]: Compute pass added, executing RDG..."));
|
||||||
// 暂时跳过,需要实现正确的缓冲区提取
|
|
||||||
|
|
||||||
// 执行RDG
|
// 执行RDG,自动处理资源转换和同步
|
||||||
GraphBuilder.Execute();
|
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);
|
GroupCount.X, GroupCount.Y, GroupCount.Z);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user