How would I write & read from render targets directly without making temporary textures and copy passes?
I have this example with copy passes and temporary texture:
if (bIsShaderValid) {
FPressMapCS::FParameters* PassParameters = GraphBuilder.AllocParameters<FPressMapCS::FParameters>();
//FRDGTextureUAVDesc UAVDesc0(Params.PressMap0->GetRenderTargetTexture(), 0,PF_B8G8R8A8 );
FRDGTextureDesc Desc(FRDGTextureDesc::Create2D(Params.PressMap0->GetSizeXY(), PF_B8G8R8A8, FClearValueBinding::Black, TexCreate_RenderTargetable | TexCreate_ShaderResource | TexCreate_UAV));
FRDGTextureDesc Desc2(FRDGTextureDesc::Create2D(Params.PressMap1->GetSizeXY(), PF_B8G8R8A8, FClearValueBinding::Black, TexCreate_RenderTargetable | TexCreate_ShaderResource | TexCreate_UAV));
FRDGTextureRef TmpTexture = GraphBuilder.CreateTexture(Desc, TEXT("PressMapCS_TempTexture"));
FRDGTextureRef TmpTexture2 = GraphBuilder.CreateTexture(Desc2, TEXT("PressMapCS_TempTexture2"));
FRDGTextureRef TargetTexture = RegisterExternalTexture(GraphBuilder, Params.PressMap0->GetRenderTargetTexture(), TEXT("PressMapCS_RT"));
FRDGTextureRef TargetTexture2 = RegisterExternalTexture(GraphBuilder, Params.PressMap1->GetRenderTargetTexture(), TEXT("PressMapCS_RT2"));
PassParameters->PressMap0 = GraphBuilder.CreateUAV(TmpTexture);
PassParameters->PressMap1 = GraphBuilder.CreateUAV(TmpTexture2);
PassParameters->Position = Params.Position;
AddCopyTexturePass(GraphBuilder, TargetTexture, TmpTexture, FRHICopyTextureInfo());
AddCopyTexturePass(GraphBuilder, TargetTexture2, TmpTexture2, FRHICopyTextureInfo());
auto GroupCount = FComputeShaderUtils::GetGroupCount(FIntVector(Params.X, Params.Y, Params.Z), FComputeShaderUtils::kGolden2DGroupSize);
GraphBuilder.AddPass(
RDG_EVENT_NAME("ExecutePressMapCS"),
PassParameters,
ERDGPassFlags::Compute,
[&PassParameters, ComputeShader, GroupCount](FRHIComputeCommandList& RHICmdList)
{
FComputeShaderUtils::Dispatch(RHICmdList, ComputeShader, *PassParameters, GroupCount);
});
// The copy will fail if we don't have matching formats, let's check and make sure we do.
if (TargetTexture->Desc.Format == PF_B8G8R8A8) {
AddCopyTexturePass(GraphBuilder, TmpTexture, TargetTexture, FRHICopyTextureInfo());
AddCopyTexturePass(GraphBuilder, TmpTexture2, TargetTexture2, FRHICopyTextureInfo());
} else {
#if WITH_EDITOR
GEngine->AddOnScreenDebugMessage((uint64)42145125184, 6.f, FColor::Red, FString(TEXT("The provided render target has an incompatible format (Please change the RT format to: RGBA8).")));
#endif
}
} else {
#if WITH_EDITOR
GEngine->AddOnScreenDebugMessage((uint64)42145125184, 6.f, FColor::Red, FString(TEXT("The compute shader has a problem.")));
#endif
// We exit here as we don't want to crash the game if the shader is not found or has an error.
}
} if (bIsShaderValid) {
FPressMapCS::FParameters* PassParameters = GraphBuilder.AllocParameters<FPressMapCS::FParameters>();
//FRDGTextureUAVDesc UAVDesc0(Params.PressMap0->GetRenderTargetTexture(), 0,PF_B8G8R8A8 );
FRDGTextureDesc Desc(FRDGTextureDesc::Create2D(Params.PressMap0->GetSizeXY(), PF_B8G8R8A8, FClearValueBinding::Black, TexCreate_RenderTargetable | TexCreate_ShaderResource | TexCreate_UAV));
FRDGTextureDesc Desc2(FRDGTextureDesc::Create2D(Params.PressMap1->GetSizeXY(), PF_B8G8R8A8, FClearValueBinding::Black, TexCreate_RenderTargetable | TexCreate_ShaderResource | TexCreate_UAV));
FRDGTextureRef TmpTexture = GraphBuilder.CreateTexture(Desc, TEXT("PressMapCS_TempTexture"));
FRDGTextureRef TmpTexture2 = GraphBuilder.CreateTexture(Desc2, TEXT("PressMapCS_TempTexture2"));
FRDGTextureRef TargetTexture = RegisterExternalTexture(GraphBuilder, Params.PressMap0->GetRenderTargetTexture(), TEXT("PressMapCS_RT"));
FRDGTextureRef TargetTexture2 = RegisterExternalTexture(GraphBuilder, Params.PressMap1->GetRenderTargetTexture(), TEXT("PressMapCS_RT2"));
PassParameters->PressMap0 = GraphBuilder.CreateUAV(TmpTexture);
PassParameters->PressMap1 = GraphBuilder.CreateUAV(TmpTexture2);
PassParameters->Position = Params.Position;
AddCopyTexturePass(GraphBuilder, TargetTexture, TmpTexture, FRHICopyTextureInfo());
AddCopyTexturePass(GraphBuilder, TargetTexture2, TmpTexture2, FRHICopyTextureInfo());
auto GroupCount = FComputeShaderUtils::GetGroupCount(FIntVector(Params.X, Params.Y, Params.Z), FComputeShaderUtils::kGolden2DGroupSize);
GraphBuilder.AddPass(
RDG_EVENT_NAME("ExecutePressMapCS"),
PassParameters,
ERDGPassFlags::Compute,
[&PassParameters, ComputeShader, GroupCount](FRHIComputeCommandList& RHICmdList)
{
FComputeShaderUtils::Dispatch(RHICmdList, ComputeShader, *PassParameters, GroupCount);
});
// The copy will fail if we don't have matching formats, let's check and make sure we do.
if (TargetTexture->Desc.Format == PF_B8G8R8A8) {
AddCopyTexturePass(GraphBuilder, TmpTexture, TargetTexture, FRHICopyTextureInfo());
AddCopyTexturePass(GraphBuilder, TmpTexture2, TargetTexture2, FRHICopyTextureInfo());
} else {
#if WITH_EDITOR
GEngine->AddOnScreenDebugMessage((uint64)42145125184, 6.f, FColor::Red, FString(TEXT("The provided render target has an incompatible format (Please change the RT format to: RGBA8).")));
#endif
}
} else {
#if WITH_EDITOR
GEngine->AddOnScreenDebugMessage((uint64)42145125184, 6.f, FColor::Red, FString(TEXT("The compute shader has a problem.")));
#endif
// We exit here as we don't want to crash the game if the shader is not found or has an error.
}
}