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

Direct3D 12描述符范围多描述符配置后register(b1)未初始化问题

问题诊断与修正

首先,你对描述符范围的理解是正确的:描述符范围确实可以指定一组连续的着色器寄存器(这里是常量缓冲区寄存器b0和b1),你的根签名和描述符堆的设置方向是对的。问题出在两个关键地方:

1. HLSL中常量寄存器的用法错误

你当前的HLSL代码直接把单个float绑定到b0/b1寄存器,这是不符合D3D12规范的:b系列寄存器是专门用来绑定**整个常量缓冲区(cbuffer)**的,不能直接绑定单个变量。

错误写法:

// 错误:单个float不能直接绑定到b寄存器
float value0 : register(b0);
float value1 : register(b1);

正确写法应该是将变量包裹在cbuffer块中,每个cbuffer对应一个b寄存器:

// 正确:每个cbuffer绑定到对应的b寄存器
cbuffer CBuffer0 : register(b0) {
    float value0;
}

cbuffer CBuffer1 : register(b1) {
    float value1;
}

这样着色器才能正确识别b0和b1对应的常量缓冲区,并读取其中的变量。

2. 确认C++端的缓冲区数据写入逻辑

你的AllocateConstantBuffer函数逻辑是正确的,但需要确保你确实把数据写入了对应的映射指针:

// 确保你在映射后写入了正确的数据
*m_constPtrvalue0 = m_value0; // 写入b0对应缓冲区的数据
*m_constPtrvalue1 = m_value1; // 写入b1对应缓冲区的数据

如果没有这一步,即使CBV创建正确,着色器读取的也是未初始化的内存。

额外验证点

  • 确认根签名序列化与创建的代码正确:使用D3D12SerializeRootSignature1序列化D3D12_ROOT_SIGNATURE_DESC1,再通过CreateRootSignature创建根签名(你没贴这部分代码,但这是常见的疏漏点)。
  • 确认命令列表在设置根描述符表前,已经正确设置了根签名:m_commandList->SetGraphicsRootSignature(m_rootSignature);

修正后的完整流程小结

  1. 修正HLSL的常量缓冲区声明,将变量放入对应的cbuffer并绑定到b0/b1。
  2. 确保向映射后的上传缓冲区写入了正确的数据。
  3. 验证根签名的序列化与绑定逻辑正确。

这样修改后,b0和b1对应的常量缓冲区数据就能被顶点着色器正确读取了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:12:16