首页 > 解决方案 > DirectCompute:如何从 RWTexture2D 中读取数据?

问题描述

我有以下缓冲区:

RWTexture2D<float4> Output : register(u0);

计算着色器使用此缓冲区来渲染计算图像。要在该纹理中写入像素,我只需使用类似于以下的代码:

Output[XY] = SomeFunctionReturningFloat4(SomeArgument);

这很好用,我的计算图像在屏幕上正确呈现。

现在在计算着色器的某个阶段,我想读回一个已经计算过的像素并再次处理它。

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

编译器返回错误:

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

任何帮助表示赞赏。

标签: directxhlsldirectcompute

解决方案


在计算着色器中,数据访问受限于某些数据类型,而且一点也不直观和直接。在您的情况下,您使用的 RWTexture2D<float4> 是一种 UAV 类型的DXGI_FORMAT_R32G32B32A32_FLOAT格式。此格式仅受 支持UAV typed store,但不受UAV typed load. 基本上,你只能在上面写,不能读。UAV typed load仅支持 32 位格式,在您的情况下DXGI_FORMAT_R32_FLOAT,只能包含单个组件(32 位仅此而已)。

如果您使用 a,您的代码应该运行,RWTexture2D<float>但我想这对您来说还不够。我想到的可能的解决方法是: 1. 使用 4 个不同RWTexture2D<float>的,每个组件一个 2. 使用 2 个不同的纹理,RWTexture2D<float4>写入您的值并Texture2D<float4>从中读取 3. 使用 aRWStructuredBuffer而不是纹理。

我不知道您的代码,所以我不知道解决方案 1. 和 2. 是否可行。但是,我强烈建议选择 3. 并使用 StructuredBuffer。ARWStructuredBuffer可以容纳任何类型,struct并且可以轻松满足您的所有需求。老实说,在计算着色器中,我几乎只使用它们来传递数据。如果您需要最终输出为纹理,则可以在缓冲区上进行所有计算,然后在完成后将结果复制到纹理上。我要补充一点,驱动程序经常使用 CompletePath 来访问 RWTexture2D 数据,并使用 FastPath 来访问 RWStructuredBuffer 数据,这使得前者比后者慢得多。

数据类型访问的参考在这里。向下滚动到UAV typed load


推荐阅读