You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

D3D12多纹理绑定至像素着色器失败,求助解决方法

关于D3D12多纹理绑定着色器的问题

问题场景

像素着色器声明了两个Texture2D资源,使用Load(int3)方法访问像素,无需采样器:

Texture2D<uint> u_texture : register(t0);
Texture2D u_palette : register(t1);

当前实现代码

1. SRV堆创建

D3D12_DESCRIPTOR_HEAP_DESC srvHeapDesc = {};
srvHeapDesc.NumDescriptors = 1;
srvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
srvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
ThrowIfFailed(g_device->CreateDescriptorHeap(&srvHeapDesc, IID_PPV_ARGS(&i_srvHeap)));

2. SRV创建(单个纹理)

D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
srvDesc.Format = DXGI_FORMAT_R8_UINT;
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = 1;
g_device->CreateShaderResourceView(t->texture.Get(),
                                   &srvDesc,
                                   i_srvHeap->GetCPUDescriptorHandleForHeapStart());

(另一个纹理使用不同纹素格式,未完成SRV写入堆的操作)

3. 渲染命令绑定

i_commandList->SetPipelineState(p->pipelineState);
i_commandList->SetGraphicsRootSignature(p->signature);
i_commandList->SetGraphicsRootDescriptorTable(0, i_srvHeap->GetGPUDescriptorHandleForHeapStart());
i_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
i_commandList->IASetVertexBuffers(0, 1, &v->view);
i_commandList->DrawInstanced(count, 1, 0, 0);

错误信息

D3D12 ERROR: CGraphicsCommandList::SetGraphicsRootDescriptorTable: Specified GPU Descriptor Handle (ptr = 0x8000019dcfe14d3d at 0 offsetInDescriptorsFromDescriptorHeapStart) of type SRV, for Root Signature (0x0000019E56769000:'Unnamed ID3D12RootSignature Object')'s Descriptor Table (at Parameter Index [0])'s Descriptor Range (at Range Index [0] of type D3D12_DESCRIPTOR_RANGE_TYPE_CBV) have mismatching types. All descriptors of descriptor ranges declared STATIC (not-DESCRIPTORS_VOLATILE) in a root signature must be initialized prior to being set on the command list. [ EXECUTION ERROR #646: INVALID_DESCRIPTOR_HANDLE]

解决思路

  1. 修正根签名资源类型匹配:错误明确根签名中参数索引0的描述符范围类型为D3D12_DESCRIPTOR_RANGE_TYPE_CBV,但绑定的是SRV类型资源。需修改根签名创建代码,将对应描述符范围类型设为D3D12_DESCRIPTOR_RANGE_TYPE_SRV,同时设置范围大小为2,对应t0和t1两个寄存器。
  2. 扩展SRV堆容量:当前SRV堆仅申请1个描述符空间,无法容纳两个纹理的SRV,需将srvHeapDesc.NumDescriptors改为2。
  3. 正确写入第二个纹理的SRV:第一个纹理的SRV写入堆起始位置后,第二个纹理需写入堆的下一个描述符位置。通过设备接口获取描述符步长,计算目标句柄:
    UINT srvIncrement = g_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
    D3D12_CPU_DESCRIPTOR_HANDLE secondSrvHandle = i_srvHeap->GetCPUDescriptorHandleForHeapStart();
    secondSrvHandle.ptr += srvIncrement;
    // 调用CreateShaderResourceView将第二个纹理的SRV写入secondSrvHandle
    
  4. 验证根签名布局:确保根签名中描述符表的BaseShaderRegister设为0,NumDescriptors设为2,与着色器中的t0、t1寄存器绑定完全对应。

内容的提问来源于stack exchange,提问作者Gunnar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 00:42:36