如何创建具有有效维度的常量缓冲区

时间:2011-09-22 20:39:32

标签: c++ shader direct3d hlsl direct3d11

晚上好,

我试图将XMFLOAT3X3发送到常量缓冲区(请参阅下面的代码)。

ZeroMemory(&constDesc, sizeof(constDesc));
constDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
constDesc.ByteWidth = sizeof(XMFLOAT3X3);
constDesc.Usage = D3D11_USAGE_DEFAULT;

result = m_pDevice->CreateBuffer(&constDesc,0,&m_pTexTransformCB);

if (FAILED(result)) {
    MessageBoxA(NULL,"Error creating constant buffer m_pTexTransformCB", "Error", MB_OK);
    return false;
}

但编译器告诉我XMFLOAT3X3是常量缓冲区字节宽度的无效维度:

D3D11: ERROR: ID3D11Device::CreateBuffer: The Dimensions are invalid. For ConstantBuffers, marked with the D3D11_BIND_CONSTANT_BUFFER BindFlag, the ByteWidth (value = 36) must be a multiple of 16 and be less than or equal to 65536. [ STATE_CREATION ERROR #66: CREATEBUFFER_INVALIDDIMENSIONS ]

但是,我对HLSL并不熟悉,所以我不确定是否将字节宽度设置为48,着色器的cbuffer中的float3x3将正确注册。我该怎样处理这个最好的?

如果您需要更多信息,请发表评论,我会编辑问题。我希望它足够清楚。

2 个答案:

答案 0 :(得分:6)

在您的情况下,您只需将ByteWidth更改为48即可。如果要将多个值组合在一起,则需要确保数据与16字节边界对齐。为此,您可以在定义结构之前添加__declspec(align(16))。

__declspec(align(16))
struct Data
{
    XMFLOAT3X3 a;

    //other stuff here
};

这样你就可以使用sizeof(Data)并保证你的ByteWidth有效。我为之前给你错误的答案道歉,你不需要手动填充。

答案 1 :(得分:3)

“如果绑定标志为D3D11_BIND_CONSTANT_BUFFER,则必须将ByteWidth值设置为16的倍数” 查看MSDN ,尤其是评论。