Alright, I'm having a hard time grasping how constant buffers are bound to a pipeline stage and updated. I understand that DirectX11 can have up to 15 shader-constant buffers per stage and each buffer can hold up to 4096 constants. However, I don't understand whether the ID3D11Buffer COM used to interact with the constant buffers is just a mechanism (or handle) used for fill these buffer slots or if the object actually references a particular instance of buffer data that is pushed back and forth between the GPU and CPU.
I think my confusion on the topic is the cause of a problem I'm having using two different constant buffers.
Here is some example shader code.
cbuffer PerFrame : register(b0) {
float4x4 view;
};
cbuffer PerObject : register(b1) {
float4x4 scale;
float4x4 rotation;
float4x4 translation;
};
The way my code is organized, the camera will be handling updating the relevant per frame data and GameObjects will be updating their own per object data. Both classes have their own ID3D11Buffer that is used to do this (Using a hub architecture, so one GameObject class will handle the rendering of all the instanced GameObjects in the world).
The problem is I can only get one updated at a time, depending on the slot and I presume the update order one buffer gets filled while the other gets zero'd out.
This is essentially my code. Both classes use identical update logic.
static PerObjectShaderBuffer _updatedBuffer; // PerFrameShaderBuffer if Camera class
_updatedBuffer.scale = _rScale;
_updatedBuffer.rotation = _rRotation;
_updatedBuffer.translation = _rTranslation;
pDeviceContext->UpdateSubresource(pShaderBuffer, 0 , 0, &_updatedBuffer, 0, 0);
pDeviceContext->VSSetShader(pVShader->GetShaderPtr(), 0, 0);
pDeviceContext->PSSetShader(pPShader->GetShaderPtr(), 0, 0);
pDeviceContext->VSSetConstantBuffers(1, 1, &pShaderBuffer);
pDeviceContext->IASetVertexBuffers(0, 1, &pVertexBuffer, &vStride, &_offset );
pDeviceContext->IASetPrimitiveTopology(topologyType);
pDeviceContext->Draw(bufSize, 0);
My main questions are -
- Do I need to set or bind the ShaderBuffer in order to update it with the UpdateSubresource call? (Meaning manipulate it only when it is in the pipeline) Or is it a blob of data that will be sent in with the VSSetConstantBuffer call? (Meaning the order of binding and updating data doesn't matter, I can update it in the pipeline or somehow on the cpu)
- When setting or binding the buffer, do I need to reference slot 0 to update the PerFrame buffer and slot 1 to update the PerObject buffer? Could some kind of confusion with this call in my code cause all the buffers to be overwritten?
- How does D3D11 know which buffer I want to update or map? Does it know from the ID3D11Buffer COM used?
Edit -
Changed the constant buffer register tags in the example above. Using (cb#) instead of (b#) was affecting the buffers from updating correctly for some reason. Not sure where I picked up the original syntax or if it's valid at all, but it appears to of been my main problem.