1
votes

I have the following buffer:

RWTexture2D<float4> Output : register(u0);

This buffer is used by a compute shader for rendering a computed image. To write a pixel in that texture, I just use code similar to this:

Output[XY] = SomeFunctionReturningFloat4(SomeArgument);

This works very well and my computed image is correctly rendered on screen.

Now at some stage in the compute shader, I would like to read back an already computed pixel and process it again.

Output[XY] = SomeOtherFunctionReturningFloat4(Output[XY]);

The compiler return an error:

error X3676: typed UAV loads are only allowed for single-component 32-bit element types

Any help appreciated.

1

1 Answers

3
votes

In Compute Shaders, data access is limited on some data types, and not at all intuitive and straightforward. In your case, you use a RWTexture2D<float4> That is a UAV typed of DXGI_FORMAT_R32G32B32A32_FLOAT format. This forma is only supported for UAV typed store, but it’s not supported by UAV typed load. Basically, you can only write on it, but not read it. UAV typed load only supports 32 bit formats, in your case DXGI_FORMAT_R32_FLOAT, that can only contain a single component (32 bits and that’s all).

Your code should run if you use a RWTexture2D<float> but I suppose this is not enough for you. Possible workarounds that spring to my minds are: 1. using 4 different RWTexture2D<float>, one for each component 2. using 2 different textures, RWTexture2D<float4> to write your values and Texture2D<float4> to read from 3. Use a RWStructuredBufferinstead of the texture.

I don’t know your code so I don’t know if solutions 1. and 2. could be viable. However, I strongly suggest going for 3. and using StructuredBuffer. A RWStructuredBuffer can hold any type of struct and can easily cover all your needs. To be honest, in compute shaders I almost only use them to pass data. If you need the final output to be a texture, you can do all your calculations on the buffer, then copy the results on the texture when you’re done. I would add that drivers often use CompletePath to access RWTexture2D data, and FastPath to access RWStructuredBuffer data, making the former awfully slower than the latter.

Reference for data type access is here. Scroll down to UAV typed load.