1
votes

getting really frustrated with my CBuffer in HLSL D3D11 not updating, the initial values get set upon application launch but updating is a no go, used UpdateSubResource, also tried ID3D11DeviceContext::Map & ID3D11DeviceContext::UnMap.

NOTE: CBuffer setup with D3D11_USAGE_DYNAMIC & D3D11_CPU_ACCESS_WRITE.

My ID3D11Buffer (constant buffer) only returning 4 bytes when it's size is queried.... sounds like part of the problem

struct VS_CBUFFER_DATA
{
    XMFLOAT4X4 world;
    XMFLOAT4X4 view;
    XMFLOAT4X4 projection;

    VS_CBUFFER_DATA()
    {
        XMStoreFloat4x4(&world, DirectX::XMMatrixIdentity());
        XMStoreFloat4x4(&view, DirectX::XMMatrixIdentity());
        XMStoreFloat4x4(&projection, DirectX::XMMatrixIdentity());
    }
};

D3D11_BUFFER_DESC cbufferDesc;
memset(&cbufferDesc, 0, sizeof(cbufferDesc));

cbufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER
cbufferDesc.Usage = D3D11_USAGE_DYNAMIC;
cbufferDesc.ByteWidth = sizeof(m_CBufferData);
cbufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbufferDesc.MiscFlags = 0;
cbufferDesc.StructureByteStride = 0;

D3D11_SUBRESOURCE_DATA subdata;
memset(&subdata, 0, sizeof(subdata));

subdata.pSysMem = &m_CBufferData;

if (FAILED(pRendererTemp->CreateBuffer(cbufferDesc
{
    OutputDebugString("Failed to create CBuffer!")
    goto failed;
}

void Cube::UpdateViewProjection(__in const Renderer* pRenderer, __in const    XMFLOAT4X4   &view, __in const XMFLOAT4X4 &proj)
{
    D3D11_MAPPED_SUBRESOURCE mappedSubResource;
    memset(&mappedSubResource, 0, sizeof(mappedSubResource));

    if (SUCCEEDED(pRenderer->GetDevContext()->Map(m_pCBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE,  0, &mappedSubResource))) 
    {
        Primitive::UpdateViewProjection(NULL, view, proj);
        VS_CBUFFER_DATA* cbData = (VS_CBUFFER_DATA*)&mappedSubResource.pData;

        memcpy(cbData, &m_CBufferData, sizeof(cbData));
        pRenderer->GetDevContext()->Unmap(m_pCBuffer, 0);
        SetBuffers(pRenderer);
    }
}

// SHADER.vsh
cbuffer cbMatrixBuffer : register(b0)
{
    float4x4 world;
    float4x4 view;
    float4x4 projection;
};
2
So after another close look it seems the constant buffer pointer's values are not getting updated with the new ones when I "Map" the resource....Sixjac
If you are updating the entire CB as you are here, use D3D11_MAP_WRITE_DISCARD. Also, where are you setting the constant buffer to use? Where is the struct definition of VS_CBUFFER_DATA?Chuck Walbourn
Hi Chuck, Yes I have been doing that and my scene just disappears,VS_CBUFFER_DATA is 3 XMFLOAT4X4's w, v & p matrices 16 byte aligned. I have the world matrix updating through UpdateSubResource. CheersSixjac
Also I have a feeling only the world is being updated and the cbuffer is throwing the view & projection away.....Sixjac

2 Answers

3
votes

Your problem is in the memcpy. This line here:

memcpy(cbData, &m_CBufferData, sizeof(cbData));

is copying a number of bytes equal to the size of a VS_CBUFFER_DATA pointer, which on 32 bit systems is 4 bytes (8 bytes on x64). The code should read:

memcpy(cbData, &m_CBufferData, sizeof(VS_CBUFFER_DATA));

which will copy 48 bytes of data as opposed to 4/8 (whatever sizeof(void*) evaluates to).

In general, avoid using sizeof to query the size of an array, and especially avoid it in regards to pointers (unless you have a need for that).

0
votes

Ok, I used reflection to check the accuracy of the size of the buffer, the problem turned out to be the following line:

VS_CBUFFER_DATA* cbData = (VS_CBUFFER_DATA*)&mappedSubResource.pData;

I omitted it and just used memcpy and the size of the buffer that was returned from the reflection query.

Thanks for the assistance though guys.