计算着色器完成后如何使用数据?

时间:2017-04-03 15:52:30

标签: directx-11

我有这种格式的输出缓冲区:

D3D11_BUFFER_DESC rgbaGPUBuffer;

rgbaGPUBuffer.ByteWidth             = width * height * 16; // 4 * 4 floats (RGBA)
rgbaGPUBuffer.Usage                 = D3D11_USAGE_DEFAULT;
rgbaGPUBuffer.BindFlags             = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE;
rgbaGPUBuffer.CPUAccessFlags        = 0;
rgbaGPUBuffer.MiscFlags             = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
rgbaGPUBuffer.StructureByteStride   = 4; // shader will output one rgba component by one

我有一个无序的访问视图:

D3D11_UNORDERED_ACCESS_VIEW_DESC descView;
descView.Format                     = DXGI_FORMAT_UNKNOWN;
descView.ViewDimension              = D3D11_UAV_DIMENSION_BUFFER;
descView.Buffer.FirstElement        = 0;
descView.Buffer.NumElements         = rgbaGPUBuffer.ByteWidth / rgbaGPUBuffer.StructureByteStride;
descView.Buffer.Flags               = 0;

缓冲区的用法必须是D3D11_USAGE_DEFAULT,并且不能设置CPUAccessFlags。因此,访问权限的视图格式必须为DXGI_FORMAT_UNKNOWN。具有讽刺意味的是,一旦计算着色器完成,输出缓冲区实际上保持DXGI_FORMAT_R8G8B8A8_UNORM格式。我的渲染目标交换链采用该格式,我无法对数据做任何事情。

  1. 我无法访问它,因为无法设置CPUFlags。
  2. 我无法复制,因为当源和目标不属于同一资源类型时,CopyResource不起作用。
  3. 所以,问题是,如何使用这些数据?

1 个答案:

答案 0 :(得分:0)

它们是GPU可以写入的资源与CPU可以读取的资源之间的障碍。

如果你需要一个回读(除非你从gpu工作添加几帧延迟到cpu工作,打破并行性),唯一的方法是在{{1}中创建一个没有gpu绑定的单独资源池并运行D3D11_USAGE_STAGING将您的gpu工作转移到cpu可访问资源。