3

Good evening,

I'm trying to send a XMFLOAT3X3 to a constant buffer (see code below).

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;
}

But the compiler tells me that XMFLOAT3X3 is an invalid dimension for the constant buffer bytewidth:

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 ]

However, I'm sort of new to HLSL, so I'm not sure if I set the bytewidth to 48, the float3x3 in the cbuffer of the shader will register properly. How should I handle this best?

If you need any more information, comment and I'll edit the question. I hope it's clear enough.

xcrypt
  • 3,276
  • 5
  • 39
  • 63

2 Answers2

6

In your case, you can just change the ByteWidth to 48 and it will be fine. If you want to group more than one value together, you're going to need to make sure that your data is aligned to 16 byte boundaries. To do this you can just add __declspec(align(16)) before defining your structures.

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

    //other stuff here
};

This way you can use sizeof(Data) and be guaranteed that your ByteWidth will be valid. I apologize for giving you an incorrect answer earlier, you do not need to manually pad.

Patrick Lafferty
  • 571
  • 3
  • 12
3

“If the bind flag is D3D11_BIND_CONSTANT_BUFFER, you must set the ByteWidth value in multiples of 16”
See the MSDN ,notably the remarks.

Bos
  • 365
  • 2
  • 13