# Managing constant buffers without FX interface in Direct3D10

This topic is 1891 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I am aware that there is a sample on working without FX in the samplebrowser, and I already checked that one. However, some questions arise:

In the sample:

D3DXMATRIXA16 mWorldViewProj; D3DXMATRIXA16 mWorld; D3DXMATRIXA16 mView; D3DXMATRIXA16 mProj; mWorld = g_World; mView = g_View; mProj = g_Projection; mWorldViewProj = mWorld * mView * mProj; VS_CONSTANT_BUFFER* pConstData; g_pConstantBuffer10->Map( D3D10_MAP_WRITE_DISCARD, NULL, ( void** )&pConstData ); pConstData->mWorldViewProj = mWorldViewProj; pConstData->fTime = fBoundedTime; g_pConstantBuffer10->Unmap(); 

They are copying their D3DXMATRIX'es to D3DXMATRIXA16. Checked on msdn, these new matrices are 16 byte aligned and optimised for intel pentium 4. So as my first question:

1) Is it necessary to copy matrices to D3DXMATRIXA16 before sending them to the constant buffer? And if no, why don't we just use D3DXMATRIXA16 all the time?

I have another question about managing multiple constant buffers within one shader.
Suppose that, within your shader, you have multiple constant buffers that need to be updated at different times:

cbuffer cbNeverChanges { matrix View; }; cbuffer cbChangeOnResize { matrix Projection; }; cbuffer cbChangesEveryFrame { matrix World; float4 vMeshColor; };

Then how would I set these buffers all at different times?
g_pd3dDevice->VSSetConstantBuffers( 0, 1, &g_pConstantBuffer10 );
gives me the possibility to set multiple buffers, but that is within one call.

2) Is that okay even if my constant buffers are updated at different times? And do I suppose I have to make sure the constantbuffers are in the same position in the array as the order they appear in the shader?

##### Share on other sites
The 16-byte aligned version of the matrix probably utilizes the SSE2 instruction set (which is what they mean by P4 optimised).
The matrices are converted into this SSE-friendly format before the two matrix multiplications take place -- that's the significance, not the copying into the buffer afterwards.

Many engines that I've worked with do make use of 16-byte aligned vectors, matrices, and even floats, throughout all math-heavy parts of the code, so that SSE (or equivalent) instruction sets can be used in those parts of the code-base.

The ability to set multiple buffers in a single call to *SSetConstantBuffers is just an optimisation for the times when you would call it 3 times in a row. i.e. You can call it many times to bind resources to many different slots, but if you find that you're making multiple calls in a row, then you can instead pass an array to a single call to reduce the number of API calls you have to make.

2) Yes, updating the contents of a buffer is completely separate to binding that buffer to a slot. If you bind it to a slot, then update it, then it's still bound to the slot.
Basically all your call does is store a pointer to your buffer resource into an array, e.g. conceptually--
device.VertexShaderConstantBuffers[slot] = input;//just storing a pointer // or for( int i=0; i != NumBuffers; ++i ) device.VertexShaderConstantBuffers[i+StartSlot] = input;

To match up the slots correctly when binding buffers, you've got 2 choices:
a) After you compile your shader, reflect on the binary to find which slots your named cbuffers have ended up in.
b) When writing your shaders, manually specify which slot a cbuffer is designated with the register keyword
cbuffer MyData : register(b7) // "MyData" buffer should be bound to slot #7 { }; Edited by Hodgman

##### Share on other sites
Thanks, cleared up all my questions