C++ DirectX11如何从常量缓冲区中删除未使用的变量?
我调用C++ DirectX11如何从常量缓冲区中删除未使用的变量?,c++,directx,directx-11,C++,Directx,Directx 11,我调用D3DReflect()来推断编译着色器使用的常量缓冲区的布局,我注意到它们通常包含未使用的变量 我已经在使用D3DStripShader()删除调试信息,我想知道在调用D3DReflect()之前是否有类似的方法从常量缓冲区删除这些未使用的变量 这通常是一种好的做法吗? 由于这意味着大多数时候每个原始CBUFER/阶段/程序都有一个CBUFER,我不知道剥离未使用变量的收益是否优于拥有更多(更小)CBUFER的损失?没有简单的方法做到这一点。常数缓冲区的幼稚观点是,每个人都会做出显式的
D3DReflect()
来推断编译着色器使用的常量缓冲区的布局,我注意到它们通常包含未使用的变量
我已经在使用D3DStripShader()
删除调试信息,我想知道在调用D3DReflect()
之前是否有类似的方法从常量缓冲区删除这些未使用的变量
这通常是一种好的做法吗?
由于这意味着大多数时候每个原始CBUFER/阶段/程序都有一个CBUFER,我不知道剥离未使用变量的收益是否优于拥有更多(更小)CBUFER的损失?没有简单的方法做到这一点。常数缓冲区的幼稚观点是,每个人都会做出显式的结构来保存它们的常量,这些结构将被着色器和调用C++代码共享(或者不管C)。因此,如果着色器编译器更改了结构的布局,一切都将中断 在处理DX示例应用程序时,从微观角度来看,这是有意义的。对于一个更大的项目,很多人不这样做。相反,它们具有较旧样式的着色器,其常量在全局范围内声明。在DX9和其他类似平台上,常量映射到寄存器,因此编译器可以剥离未使用的常量(确实如此)。对于DX11,编译器获取所有这些全局常量,并将它们放在一个特殊的“全局”常量缓冲区中。然后它决定您真的关心缓冲区的结构,所以它拒绝删除任何内容 因此,通常有两种选择:
STRIPPED\u constant\u DEFINITIONS
以包含该字符串):
请注意,您仍然需要将剥离的常量声明为静态,因为引用这些变量的任何未使用的代码路径或未调用的函数都将导致着色器无法编译,否则。确定它们未使用吗?大多数GPU将非常高兴地优化出任何真正未使用的变量。。。在任何情况下,我都会保留它们,因为几乎可以肯定的是,如果它们加载了一次数据,就会出现字节对齐和令人毛骨悚然的小优化……它们是未使用的,因为编译后的代码不读取它们(使用
D3D\u SVF\u USED
)检测到它们,但是它们仍然在cbuffer中,我想创建一个没有它们的新的粗糙cbuffer(或者打包原始的)。如何编译着色器?我使用带有标记的D3DCompile\u OPTIMIZATION\u LEVEL3的D3DCompile()
。如何声明常量缓冲区?您可能会看到填充,或者某个变量未被当前编译的着色器引用,但被同一文件中的其他着色器引用。我还非常小心删除常量缓冲区中未使用的变量,因为编译的字节码将向量偏移引用到该缓冲区中。如果其中一个变量存在于中间,那么在删除了一个变量之后,您就将所有引用的代码无效。谢谢,这正是我的目标。宏回退到静态var确实是剥离全局cbuffer的一种聪明方法。您是每个程序只使用一个唯一的剥离常量缓冲区,还是尝试在不同阶段之间共享它们?我们仍然使用效果框架加载着色器,但我们独立编译每个着色器阶段(使用上述技巧编译两次)。因此,我们有一个包含所有阶段的所有常量的标题,但是VS/PS/etc。。。每个都获得一个唯一的全局cbuffer,该全局cbuffer仅包含该阶段中使用的常量。由于着色器的数量以及由此产生的复杂性,我们不会在不同着色器或阶段之间共享cbuffer布局。
#if defined (STRIPPED_CONSTANT_DEFINITIONS)
STRIPPED_CONSTANT_DEFINITIONS
#else
bool someConstant;
float4 color;
...
#endif