ID3dX11Effect constant buffer

Started by
2 comments, last by osiris11 12 years ago
Hey.

I am investigating the use of constant buffers in effect files. Say, my effect file had buffer declarations like this:


cbuffer cbPerViewBuffer
{
matrix viewMatrix;
};


When initializing my shader, i would get a pointer to this effect variable by name, and store it in my object:



ID3DX11EffectMatrixVariable *p_view;
ID3DX11Effect* p_effect;

//... Compiling effect ...//


p_view = p_effect->GetVariableByName("viewMatrix")->AsMatrix();


On rendering, I do


D3DXMATRIX v;
//... doing the math on v ...//

p_view->SetMatrix( v);


There is no buffer mapping or else involved. So my question is, is this even using the advantages of constant buffers, or is this an absurdely abuse of mentioned features?
Should I instead create a custom buffer type, create a buffer of this type, bind it as dynamic to the effect, and use map on each render call?
Can the view buffer even be updated, I have seen no flag specifying it as DYNAMIC?

Thanks for your help.
Advertisement
The effects framework does a Map or UpdateResource behind the scenes. It's been a while since I looked at the effect code, but it should flag a variable as "dirty" and only update the constant buffer if one of the values changed. So it is not really an abuse.

However, one example of an improvement is your "per-frame" constant buffer. You only need one of these and all your effects can share it. I use a header and always put the per-frame cb in slot 0. Then I use ID3DX11Effect::GetConstantBufferByName and set the per-frame CB for each effect; this is just a bind operation (when Apply() is called), as the per-frame CB is only updated once per-frame.

If you don't do this, then each effect will maintain its own per-frame cbuffer. This is still not likely to make a performance impact, but still.
-----Quat
This is how it's done:

[source] // Retrieve the handles to the constant buffers
//
m_pD3DXEffectEveryFrameConstBuffer = m_pD3DXEffect->GetConstantBufferByName("CBEveryFrame"); // Constant buffer that changes every frame
if(!m_pD3DXEffectEveryFrameConstBuffer->IsValid())
return E_FAIL;
update constant buffer:
D3D11_MAPPED_SUBRESOURCE oD3DMappedSubresource;
CHECK_COM(pD3DDeviceContext->Map(m_pD3DMaterialConstbuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &oD3DMappedSubresource)); // Get a pointer to the data in the constant buffer
::memcpy(oD3DMappedSubresource.pData, pMaterialConstantBuffer, sizeof(SMaterialConstantBuffer)); // Copy the constant buffers
pD3DDeviceContext->Unmap(m_pD3DMaterialConstbuffer, 0);
CHECK_COM(m_pD3DXEffectMaterialConstBuffer->SetConstantBuffer(m_pD3DMaterialConstbuffer)); // Set material constant buffer in the shader
Assuming the constant buffer was created dynamic usage flag. If it's created with default usage flag then you have to use UpdateSubresource method to do so[/source]
@ Quat: Your answer sounds good: it's easy, would not require me to do too much changes, and would not need me to do obscure things.

@ Asesh: It's quite the opposite to what Quat suggested: You tell me to actually take everything in my own responsibility, and actually mapping the buffer. In this case, would I have to create the buffers myself? As I see it, the effect creates the declared buffers within it on compilation(?) and I can just access it with the GetConstantBufferFunction. Where can I make it's usage DYNAMIC? Do I have to create the buffer myself and replace it with the one the shader generated?


Actually, now I'm as wise as before: It seems to me I have two concurring opinions on this topic, and (of course I am tempted to use the easier one for the time being) still can't decide which option to settle with.
Are there any more opinions?

This topic is closed to new replies.

Advertisement