Search code examples
c++directx-11hlsl

Why is my constant buffer not being updated?


Bellow is the cpu side declaration for the buffer I'm having the issue:

struct PSMaterialTransform {
        float Alpha;
        bool WrapUV;
        XMFLOAT2 padding;
    } static m_PSMaterialTransformDesc;

And bellow is the gpu side declaration for the buffer:

cbuffer MaterialTransform: register(b1) {
float Alpha;
bool WrapUV;
float2 padding;
};

This is how I'm creating all my constant buffers:

template<typename T>
bool Seraph::ShaderManager<T>::Create(ID3D11Device* pDevice) {
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(D3D11_BUFFER_DESC));

bd.ByteWidth = sizeof(T);
bd.Usage = D3D11_USAGE_DYNAMIC;
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;

hr = pDevice->CreateBuffer(&bd, nullptr, &m_pBuffer);
if (FAILED(hr))
    return Log("Failed to create constant buffer.");
return true;
}

And finally, this is the code I'm using to update my constant buffer:

template<typename T>
bool Seraph::ShaderManager<T>::SetPS(ID3D11DeviceContext* pDeviceContext, T& Data, int ID) {
D3D11_MAPPED_SUBRESOURCE ms;
ZeroMemory(&ms, sizeof(D3D11_MAPPED_SUBRESOURCE));

hr = pDeviceContext->Map(m_pBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &ms);
if (FAILED(hr))
    return Log("Failed to update constant buffer.");

*(T*)ms.pData = Data;

pDeviceContext->Unmap(m_pBuffer, 0);
pDeviceContext->PSSetConstantBuffers(ID, 1, &m_pBuffer);

return true;
}

The variable ID represents the slot where the buffer is declared, I've already checked 3 times and the ID is 1 for MaterialTransform, but doesn't matter what value I send to the gpu, the boolean value WrapUV is always TRUE, even though the floating point Alpha seems to update normally.


Solution

  • The size of bool in HLSL is 4 bytes, so your CPU structure should be something like

    struct PSMaterialTransform 
    {
            float Alpha;
            int32_t WrapUV; //or uint32_t
            XMFLOAT2 padding;
    } 
    

    If you want, you can use typedef/using alias like this:

    typedef int32_t bool32; //or
    using bool32 = int32_t;
    

    Then you can write bool32 WrapUV; instead.