Jump to content
  • Advertisement
Sign in to follow this  
gekon456

OpenGL Constant buffer per object

This topic is 1003 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

Hi,

 

I have shader with uniform inputs for whole object, like Position and Scale.

In OpenGL I used glUniform* functions to pass those values into my struct inside shaders.

 

Now I moving this stuff under D3D11 and I'm not sure if its good idea to have one constant buffer per object?

My simple frame logic is:

 

 - Update global constant buffer (map, write, unmap)

   - Time

   - MVP

 

 - Foreach game objects

   - Call update method which will modify position and scale on CPU side

   - Map constant buffer (which is already created when object is spawned to the scene)

   - Copy CPU position and scale to constant buffer

   - Unmap

   - Draw

 

Is good idea to have one constant buffer per object? Or do I have to use one global constant buffer and just update values for every new object?

Thank you

Share this post


Link to post
Share on other sites
Advertisement

I've never viewed the cbuffer as something that is or has to be tied to an object. Instead a better way to view a cbuffer is as a container (That really could care less what TYPE of data is stored within it) who's only goal is to have the compacity to transfer your data from the CPU to the GPU. Ultimately the job of data interpretation is up to the Shader.

 

A constant buffer that holds let's say, a matrix (like XMMATRIX) is able to carry 64 bytes. Lets say all the Matrices you use throughout your game only ever use 64 bytes. Why would you need another constant buffer to represent a 64 byte container?

D3D11_BUFFER_DESC cDesc;ZeroMemory(&cDesc, sizeof(D3D11_BUFFER_DESC));
cDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cDesc.Usage = D3D11_USAGE_DEFAULT;
cDesc.ByteWidth = sizeof(XMMATRIX); // XMMATRIX being 64 bytes I believe
And not only could you use this cbuffer for other matrices. You could also use to transfer other structures that are 64 bytes in length. i.e.

struct Light
{
    float4 pos;
    float4 diffuse;
    float4 ambient;
    float4 specular;
};
And assign that light to the cbuffer that used the XMMATRIX as a reference for the size.
D3D11_SUBRESOURCE_DATA resource;
resource.pSysMem = &light; // notice how the type is void*, The subresource could care less WHAT the data is. Ultimately that's up to the shader to handle.

But nothing is wrote in stone. If you don't mind burning the extra memory, and object count doesn't get ridculous, you may find it's easier to continue on the path that your on. It then becomes a simple design decision.

 

Marcus

Share this post


Link to post
Share on other sites

In my application i have 2 cbuffers (per stage, in theory you can use only two for all stages).
1 that is updated once per frame and the other is updated for every object.

Those 2 buffers are always bound!
I update them via Map/Unmap and I found out that for my case  binding once buffer and updating it multiple times via Map/Unmap is much faster than just binding new cbuffer.

Share this post


Link to post
Share on other sites

Your design is idling the GPU on every draw as you map, copy to, unmap, and bind the CB

 

This isn't necessarily true -- you don't need to idle the gpu when uploading data to it. Even if this were the case, you'd be doing this when uploading to a single combined constant buffer anyway. 

 

 

 


one fast memcpy to a presistently-mapped buffer

 

Afaik D3D11 doesn't allow presistently mapped buffers? I'm pretty sure a buffer needs to be unmapped if it's going to be used in DX11. Win8/DX11.1 allow D3D11_MAP_WRITE_NO_OVERWRITE to be used with constant buffers which I think would be the next best thing.

Edited by Dingleberry

Share this post


Link to post
Share on other sites

Thank you all for responses.

 

So I will rewrite my design to use just one "Transform Buffer".

If I understand it correctly - for every "game object" I have to map (just one CB), write data and unmap to push data to GPU right?

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!