Jump to content
  • Advertisement
Sign in to follow this  
n3Xus

[DX10]Constant buffer confusion

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

when creating constant buffers I saw that there are vs, ps and gs interface functions in the ID3D10Device to set constant buffers. So i must sort them by ps,vs and gs in addition to frequency of use? And would it be very wrong to set a value in a vs cbuffer that is going to be used in ps (will it crash the app or cause any major problems-Im just curious about this last thing since i didn't find any articles on this subject)?

Share this post


Link to post
Share on other sites
Advertisement
Fundamentally a constant buffer is just a blob of variables that the compiled shader knows how to use. There isn't anything specific about a VS, GS or PS constant buffer in that sense.

However, the layout of a CB may well change between the shader units - different execution paths may include/exclude different constants and therefore the packing rules will change. Thus having the same cbuffer code for multiple shaders may not necessarily mean that they're the same at runtime.

I don't honestly know if this is the behaviour via FX10, but I'm pretty sure thats how I came across it when going straight to the shaders and bypassing the FX framework a while back.

If you grab the cbuffer spec back from multiple shaders and the description matches then you should be ok for sharing them. What you don't want is for the VS to be looking at bytes 0-15 for a float4 vector and have the PS looking for the same variable at bytes 16-31 instead.

Quote:
So i must sort them by ps,vs and gs in addition to frequency of use?
Sort them by frequency of update, not usage. Creating and modifying the cbuffer is expensive thus you don't want a high-frequency variable mixed with a low-frequency one if you can avoid it. There will be some correlation between the most updated constants and the most used constants, but they are seperate metrics.

hth
Jack

Share this post


Link to post
Share on other sites
Quote:
Original post by jollyjeffers
What you don't want is for the VS to be looking at bytes 0-15 for a float4 vector and have the PS looking for the same variable at bytes 16-31 instead.



I don't really understand what you mean by this?

Share this post


Link to post
Share on other sites
There should be no problem reading the same constant buffer from a pixel shader and a vertex shader at the same time from the hardware point of view.

I'm not 100% sure what Jack is referring to but I could possibly guess :
packing rules define how constant are packed from their definition in the HLSL file.

cbuffer cb
{
float fFoo : packoffset(c0); // fFoo is in c0.x
float fBar : packoffset(c1.y); // fBar is in c1.y
};


So if your vertex and pixel shader agree where each constant is placed in the buffer then there should be no problem (that will also determine how you update the constant buffers).

For your question on how to group constants, it's a FAQ :

What is the best way to organize my constant buffers?

LeGreg

Share this post


Link to post
Share on other sites
ah ok. thx

I have another question: in some examples that come with the DX SDK the .fx files have cbuffers in them but they are not created and updated in the .cpp files. What's the point of this?


And another qusetion: i always get E_INVALIDARG when i try to create my constant buffer. here is the code:



ID3D10Buffer* m_pCBTest

struct sCBTest
{
float time;
};

.............................
D3D10_BUFFER_DESC db;
ZeroMemory(&db,sizeof(db));
db.BindFlags=D3D10_BIND_CONSTANT_BUFFER;
db.ByteWidth=sizeof(sCBTest);
db.CPUAccessFlags=D3D10_CPU_ACCESS_WRITE;
db.MiscFlags=0;
db.Usage=D3D10_USAGE_DYNAMIC;

if(FAILED( m_pDevice10->CreateBuffer(&db,NULL,&m_pCBTest) ))
{
ONMESSAGE("could not create constant buffer fast","ERROR: DX10_FONT");
}


Share this post


Link to post
Share on other sites
Quote:
Original post by n3Xus
I have another question: in some examples that come with the DX SDK the .fx files have cbuffers in them but they are not created and updated in the .cpp files. What's the point of this?


They are using the effects library (FX10). That library hides some of the implementation details. But you can check the sample called HLSLWithoutFX to check how it's done without that library.

Quote:
Original post by n3Xus
And another qusetion: i always get E_INVALIDARG when i try to create my constant buffer.


Constant buffers size are always a multiple of 16 bytes because constants are grouped by vector4 of float (c0 = c0.x, c0.y, c0.z, c0.w). Your constant buffer size is 4 bytes so the call will fail.

LeGreg


Share this post


Link to post
Share on other sites
thank you!

heres another question: how does the shader know which cbuffer I updated, since I can't get it to update it (m_pDevice10->VSSetConstantBuffers(0,1,&m_pCBOnce); gets called only once, is this OK?)?



ID3D10Buffer* m_pCBOnce;

struct sCBOnce
{
D3DXMATRIX view;
D3DXMATRIX projection;
};

.................................

sCBOnce* cb1;
m_pCBOnce->Map(D3D10_MAP_WRITE_DISCARD,0,(void**)&cb1);
cb1->projection=*m_pProjection;
cb1->view=*m_pView;
m_pCBOnce->Unmap();

m_pDevice10->VSSetConstantBuffers(0,1,&m_pCBOnce);

Share this post


Link to post
Share on other sites
EDIT: nvm the upper post, I figured it out.

[Edited by - n3Xus on July 23, 2008 5:54:02 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by LeGreg
I'm not 100% sure what Jack is referring to but I could possibly guess :
...snip...
So if your vertex and pixel shader agree where each constant is placed in the buffer then there should be no problem
Yes, this is what I was getting at.

There have been many cases posted in this forum over the years where people mess up vertex declarations and find that the pipeline grabs the wrong chunk of bits for the wrong purpose and all sorts of crazy things happen.

The same thing is possible if you're trying to share cbuffer's and possibly mixing up declarations.


Jack

Share this post


Link to post
Share on other sites
ok.

well I got another problem now: in the shader, in my cbuffer if I make 4 float4 (one for every row of the view matrix) i can assign the correct matrix variables to a view matrix so it works, but if I put a matrix or a float4x4 in my cbuffer the values don't get assigned correctly. does this has to anything with packoffests or how the D3DXMATRIX gets copied from my app to the shader?


// Works (r1,r2,r3&r4 have the correct values):
cbuffer CBOnce
{
float4 r1;
float4 r2;
float4 r3;
float4 r4;
}
// Doesnt work (view doesn't have the correct values):
cbuffer CBOnce
{
float4x4 view;
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!