c++ - Failure to bind UAV RDG Buffer in compute shader in Unreal Engine 5 - Stack Overflow

I am writing a compute shader, that counts white pixels on the screen, and, in the future, calculates l

I am writing a compute shader, that counts white pixels on the screen, and, in the future, calculates luminance. Right now counting white pixels works well, but problems arise when I try to connect second RWBuffer to read back luminance. It seems like buffer is created, passed to the shader, but cannot be read or modified, and seems to be zero for shader. When trying readback it just returns start values from AddClearUAVPass, without using or modifying them.

PassParams definition:

BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
        SHADER_PARAMETER_RDG_TEXTURE(Texture2D, InputTexture)
        SHADER_PARAMETER_RDG_TEXTURE(Texture2D, CameraTexture)
        SHADER_PARAMETER_RDG_BUFFER_UAV(RWBuffer<int>, Output)
        SHADER_PARAMETER_RDG_BUFFER_UAV(RWBuffer<int>, Luminance)
END_SHADER_PARAMETER_STRUCT()

Buffers creation (as you can see both buffers are declared the same, OutputBuffer works, while LuminanceBuffer - no)

            FRDGBufferRef OutputBuffer = GraphBuilder.CreateBuffer(
                FRDGBufferDesc::CreateBufferDesc(sizeof(int32), 1),
                TEXT("OutputBuffer"));

            FRDGBufferRef LuminanceBuffer = GraphBuilder.CreateBuffer(
                FRDGBufferDesc::CreateBufferDesc(sizeof(int32), 2),
                TEXT("LuminanceBuffer"));


            PassParameters->Output = GraphBuilder.CreateUAV(FRDGBufferUAVDesc(OutputBuffer, PF_R32_SINT));
            PassParameters->Luminance = GraphBuilder.CreateUAV(FRDGBufferUAVDesc(LuminanceBuffer, PF_R32_SINT));
            AddClearUAVPass(GraphBuilder, PassParameters->Output, 0);
            AddClearUAVPass(GraphBuilder, PassParameters->Luminance, 13);

(13 in AddClearUAVPass for testing)

Readback (Output buffer returns correct values, LumBuffer returns 13)

FRHIGPUBufferReadback* GPUOutputBufferReadback = new FRHIGPUBufferReadback(TEXT("ExecuteTestOutput"));
FRHIGPUBufferReadback* GPULuminanceBufferReadback = new FRHIGPUBufferReadback(TEXT("ExecuteTestOutput1"));
AddEnqueueCopyPass(GraphBuilder, GPUOutputBufferReadback, OutputBuffer, 0u);
AddEnqueueCopyPass(GraphBuilder, GPULuminanceBufferReadback, LuminanceBuffer, 0u);

auto RunnerFunc = [GPUOutputBufferReadback, GPULuminanceBufferReadback, AsyncCallback](auto&& RunnerFunc) -> void {
    if (GPUOutputBufferReadback->IsReady() && GPULuminanceBufferReadback->IsReady()) {
        
        int32* Buffer = (int32*)GPUOutputBufferReadback->Lock(sizeof(int32));
        int32 ObjectSize = Buffer[0];
        
        GPUOutputBufferReadback->Unlock();

        int32* LumBuffer = (int32*)(GPULuminanceBufferReadback->Lock(8));
        UE_LOG(LogTemp, Log, TEXT("Luminance Buffer: %d, %d"), LumBuffer[0], LumBuffer[1]);
        int32 ObjectLum = LumBuffer[0];
        int32 OtherLum = LumBuffer[1];
        GPULuminanceBufferReadback->Unlock();

        AsyncTask(ENamedThreads::GameThread, [AsyncCallback, ObjectSize, ObjectLum, OtherLum]() {
            AsyncCallback(ObjectSize, ObjectLum, OtherLum);
        });

        delete GPUOutputBufferReadback;
        delete GPULuminanceBufferReadback;
    } else {
        AsyncTask(ENamedThreads::ActualRenderingThread, [RunnerFunc]() {
            RunnerFunc(RunnerFunc);
        });
    }
};

Here is shader itself. In InterlockedAdd I add Luminance[0] to check if shader can access the buffer, and it seems empty. When trying to modify Luminance[0] and Luminance[1] it does nothing

#include "/Engine/Public/Platform.ush"

Texture2D<float4> InputTexture;
Texture2D<float4> CameraTexture;
RWBuffer<int> Output;
RWBuffer<int> Luminance;

[numthreads(32, 32, 1)]
void Test(uint3 DispatchThreadId : SV_DispatchThreadID, uint GroupIndex : SV_GroupIndex)
{
    uint width, height;
    InputTexture.GetDimensions(width, height);

    if (DispatchThreadId.x >= width || DispatchThreadId.y >= height)
        return;

    float4 colorData = InputTexture.Load(int3(DispatchThreadId.xy, 0));
    float3 color = colorData.rgb;

    float threshold = 0.9;
    bool isWhite = (color.r > threshold && color.g > threshold && color.b > threshold);

    if (isWhite)
    {
        InterlockedAdd(Output[0], Luminance[0]);

    }
    if (DispatchThreadId.x == 0 && DispatchThreadId.y == 0) 
    {
        Luminance[0] = 41;
        Luminance[1] = 24; 
    }
}

Ive tried to replace float values from Luminance to int, and it didnt change anything.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744399119a4572297.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信