DirectX:渲染到Texture2DArray,并在计算着色器中从中加载
DirectX: rendering to Texture2DArray, and Loading from it in compute shader
我想将多个图像渲染到Texture2DArray,并在计算着色器中访问生成的图像。但是,计算着色器中的Load
方法返回[0.0, 0.0, 0.0, 0.0]
,而不是图像数据。
目前,我正在做以下工作:
1.设置
我首先通过使用CreateTexture2D
和texArrayDesc.ArraySize = numRenderSlots
:创建Texture2DArray来准备一组"渲染槽"
texArrayDesc.Width = width;
texArrayDesc.Height = height;
texArrayDesc.MipLevels = 1;
texArrayDesc.ArraySize = numRenderSlots;
texArrayDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
texArrayDesc.Usage = D3D11_USAGE_DEFAULT;
texArrayDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
texArrayDesc.CPUAccessFlags = 0;
m_device->CreateTexture2D(&texArrayDesc, NULL, &m_renderSlotsTexArray);
然后,我为这个纹理数组创建一个ShaderResourceView,这样我就可以从计算着色器访问它:
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
srvDesc.Texture2DArray.FirstArraySlice = 0;
srvDesc.Texture2DArray.MostDetailedMip = 0;
srvDesc.Texture2DArray.MipLevels = 1;
srvDesc.Texture2DArray.ArraySize = numRenderSlots;
m_device->CreateShaderResourceView(m_renderSlotsTexArray, &srvDesc, &m_renderSlotsSrv);
对于Texture2DArray中的每个切片,我都会创建一个RenderTargetView,以便对其进行渲染。
rtvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
rtvDesc.Texture2DArray.MipSlice = 0;
rtvDesc.Texture2DArray.ArraySize = 1;
for (int i = 0; i < numRenderSlots; i++) {
// Change slot RTV desc to choose correct slice from array
rtvDesc.Texture2DArray.FirstArraySlice = D3D11CalcSubresource(0, i, 1);
// Create the RTV for the slot in m_renderSlotsTexArray
ID3D11RenderTargetView* slotRtv;
m_device->CreateRenderTargetView(m_renderSlotsTexArray, &rtvDesc, &slotRtv);
// Add the RenderTargetView to a list
m_slotRtvs.push_back(slotRtv);
}
2.用途
然后,我通过将关联的渲染窗设置为渲染目标来渲染一组不同的图像。请注意,背景颜色不是[0,0,0,0]
。简化代码:
for (int i = 0; i < numRenderSlots; i++) {
setupScene(i);
deviceContext->OMSetRenderTargets(1, &m_slotRtvs[i], depthStencilView);
deviceContext->ClearRenderTargetView(m_slotRtvs[slotIdx], {0.2,0.2,0.2,0.0});
deviceContext->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
render();
}
然后,我设置了一个具有StructuredBuffer的计算着色器,用于具有关联UnorderedAccessView的着色器输出。我将其与渲染槽Texture2DArray的SRV一起传递到着色器中。我最终调度了着色器,以32x32大小的块对图像进行操作。
deviceContext->CSSetShader(m_computeShader, NULL, 0);
deviceContext->CSSetShaderResources(0, 1, &renderSlotsSrv);
deviceContext->CSSetUnorderedAccessViews(0, 1, &outputUav, nullptr);
deviceContext->Dispatch(img_width / 32, img_height / 32, numParams);
然后,我尝试访问计算着色器中的渲染图像数据然而,imgs.Load
似乎总是返回[0.0, 0.0, 0.0, 0.0]
Texture2DArray<float4> imgs : register(t0);
RWStructuredBuffer<float3> output : register(u0);
[numthreads(32,32,1)]
void ComputeShaderMain(
uint3 gID : SV_GroupID,
uint3 dtID : SV_DispatchThreadID,
uint3 tID : SV_GroupThreadID,
uint gi : SV_GroupIndex )
{
int idx_x = (gID.x * 32 + tID.x);
int idx_y = (gID.y * 32 + tID.y);
float4 px = imgs.Load(int4(idx_x,idx_y,gID.z,0));
...
output[outIdx] = float3(px.x, px.y, px.z);
}
我知道渲染槽正在工作,因为我可以通过在暂存纹理中执行CopySubresourceRegion来访问每个渲染槽,以查看字节数据。然而,这次GPU->CPU
转移是我试图避免的。
此外,我知道计算着色器输出正在工作,因为我可以映射输出缓冲区并检查一些基本的测试数据。
我做错了什么?提前谢谢。
解决了这个问题。我创建了启用调试的D3D设备,注意到:
D3D11 WARNING: ID3D11DeviceContext::CSSetShaderResources:
Resource being set to CS shader resource slot 0 is still bound on output!
所以问题是,当我试图将Texture2DArray设置为计算着色器中的资源时,它仍然被绑定为渲染目标。
通过解除渲染目标的绑定轻松修复,如:
deviceContext->OMSetRenderTargets(0, NULL, NULL);
在使用CCD_ 9之前。
我希望这能帮助到任何有类似问题的人。
- std::原子加载和存储都需要吗
- 如何加载(或映射)文件部分的最大大小,但适合在Windows上的RAM
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 为什么加载SDF会导致Mobilizer创建闭环错误
- C++atioglxx.pdb未加载错误glBufferData OpenGL
- 如何使用tinyxml2从XML加载父实体和子实体
- 如何在C++中使用pybind11加载一个pickle python列表
- 系统.将数组移交给c#中动态加载的c++DLL时发生AccessViolationException
- 当我尝试加载内核模块时,如何修复C++中的这个 malloc() 错误?
- 树莓上的 Libtorch 无法加载 pt 文件,但在 ubuntu 上工作
- Python ctypes:不会按预期加载 dll
- 为什么会出现 gettnig 运行时错误:加载类型为"_Bit_type"(stl_bvector.h) 的空指针?
- 我的程序有一个保存配置文件的GUI,如何双击此配置文件以直接加载带有配置数据的GUI?
- 保存/加载大量短数组到二进制文件
- 如何使用 strlen 计算空间并在 sprintf 中加载
- 如何计算将文件加载到应用程序中的时间C++
- 使用循环从加载的 TXT 文件执行计算时出现问题C++
- 在某些计算机上加载C++DLL失败
- 第一次计算,第二次加载
- DirectX:渲染到Texture2DArray,并在计算着色器中从中加载