我有一个D3D11缓冲区,其中有几百万个元素,应该以该R8G8B8A8_UNorm
格式保存数据。
所需的行为如下:一个着色器计算avec4
并将其以随机访问模式写入缓冲区。在下一个过程中,另一个着色器将以随机访问模式读取数据并进一步处理它们。
我最好的猜测是UnorderedAccessView
使用R8G8B8A8_UNorm
格式创建。但是,如何RWBuffer<?>
在HLSL中声明,以及如何对其进行写入和读取?是否有必要将其声明为RWBuffer<uint>
和做包装vec4
,以uint
手动?
在OpenGL中,我将创建一个缓冲区和一个缓冲区纹理。然后,我可以在着色器中使用格式声明一个imageBuffer
,rgba8
使用imageLoad
和进行访问imageStore
,然后硬件会为我完成所有转换。在D3D11中可以吗?
由于存在许多不同的陷阱,因此这有点棘手,但是您应该可以执行类似的操作。
在写入缓冲区的着色器中声明:
RWBuffer<float4> WriteBuf : register( u1 );
请注意,它一定要注册u1
而不是u0
。无序访问视图(UAV)必须从插槽1开始,因为该u#
寄存器还用于渲染目标。
要写入缓冲区,只需执行以下操作:
WriteBuf[0] = float4(0.5, 0.5, 0, 1);
请注意,您必须一次写入所有4个值。
在您的C ++代码中,您必须创建一个无序的访问缓冲区,并将其绑定到UAV。您可以使用DXGI_FORMAT_R8G8B8A8_UNORM
格式。当您向其写入4个浮点数时,值将自动转换并打包。可以使用将UAV绑定到管道OMSetRenderTargetsAndUnorderedAccessViews
。
在从缓冲区读取的着色器中,声明一个只读缓冲区:
Buffer<float4> ReadBuf : register( t0 );
请注意,使用此缓冲区t0
是因为它将绑定为着色器资源视图(SRV)而不是UAV。
要访问缓冲区,请使用类似以下内容的方法:
float4 val = ReadBuf[0];
在您的C ++代码中,您可以将先前创建的相同缓冲区绑定到SRV而不是UAV。SRV可以使用绑定到管道PSSetShaderResources
,也可以使用创建DXGI_FORMAT_R8G8B8A8_UNORM
。
您不能将使用同一缓冲区的SRV和UAV同时绑定到管道。因此,您必须首先绑定无人机并运行第一个着色器通道。然后取消绑定无人机,绑定SRV,然后运行第二个着色器通道。
可能还有其他方法可以做到这一点。请注意,所有这些都需要着色器模型5。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句