Jump to content
  • Advertisement
Tape_Worm

DX11 VSSetConstantBuffers1 Problems

Recommended Posts

Posted (edited)

So I've been playing around today with some things in D3D 11.1, specifically the constant buffer offset stuff.  And just FYI, I'm doing this in C# with SharpDX (latest version).

I got everything set up, I have my constant buffer populating with data during each frame, and calling VSSetConstantBuffers1 and passing in the offset/count as needed.

But, unfortunately, I get nothing on my screen.  If I go back to using the older D3D11 SetConstantBuffers method (without the offset/count), everything works great.

I get nothing from the D3D runtime debug spew, and a look in the graphics debugger stuff tells me that my constant buffer does indeed have data at the offsets that I'm providing.  And the data (World * Projection matrix) is correct at each offset.  The offsets, according again to the graphics debugger, are correct.

could be using it incorrectly, but what little (and seriously, there's not a lot) info I found seems to indicate that I'm doing it correctly.  But here's my workflow (I'd post code, but it's rather massive):

Frame #0:

  • Map constant buffer with discard
  • Write matrix at offset 0, count 64
  • Unmap
  • VSSetConstantBuffers1(0, 1, buffers, new int[] { offset }, new int[] { count });  // Where offset is the offset above, same with count
  • Draw single triangle

Frame #1:

  • Map constant buffer with no-overwrite
  • Write matrix at offset 64, count 64.
  • Unmap
  • VSSetConstantBuffers1(0, 1, buffers, new int[] { offset }, new int[] { count });  // Where offset is the offset above, same with count
  • Draw single triangle

Etc... it repeats until the end of the buffer, and starts over with a discard when the buffer is full.

Has anyone ever used these offset cbuffer functions before?  Can you help a brother out?

Edit:
I've added screenshots of what I'm seeing the VS 2017 graphics debugger.  As I said before, if I use the old VSSetConstantBuffers method, it works like a charm and I see my triangle.

VSSetConstantBuffers1_2.PNG

VSSetConstantBuffers1.PNG

VSSetConstantBuffers1_3.PNG

Edited by Tape_Worm
Adding more info

Share this post


Link to post
Share on other sites
Advertisement

Hi!

Are you sure the numbers and offsets are correct? The documentation says that "an offset of 2 indicates that the start of the associated constant buffer is 32 bytes into the constant buffer". It isn't an offset in bytes but an offset in 16-byte (float4) constants.

Share this post


Link to post
Share on other sites

Well, when I use anything less than a multiple of 16, the debug spew complains that I'm not using a multiple of 16.  

Share this post


Link to post
Share on other sites
51 minutes ago, Tape_Worm said:

Well, when I use anything less than a multiple of 16, the debug spew complains that I'm not using a multiple of 16.  

That's correct, you need to use 256-byte offsets, which is 16 "constants" where each constant is 4 floats (16 bytes).

Share this post


Link to post
Share on other sites

And... of course... I just figured that out. I had misread the documentation, so I'd thought it was 16 bytes per element.  

That said, isn't that kind of wasteful?  I mean, if a matrix is 64 bytes, and each element is 256 bytes, that leaves a lot of unused space.  I had assumed constant buffer elements were laid out using 16 byte alignments, and that viewing into them in this way would follow similar alignment rules.

Share this post


Link to post
Share on other sites
Posted (edited)

I haven't used this variant personally, so I was just shooting from the hip. It's a bit surprising, indeed. Maybe it has to do with a typical 256 byte texture alignment - who knows if some implementations don't have to do it with textures behind the scenes and texture descriptors usually contain 256-aligned addresses...

Also, write-combining at least 256 bytes instead of only 16 bytes over the various complicated buses to the GPU-visible memory seems reasonable. You're trading minimum overhead in regards of time for (possibly no) overhead in regards of memory.

Edited by pcmaster

Share this post


Link to post
Share on other sites
6 hours ago, Tape_Worm said:

That said, isn't that kind of wasteful?  I mean, if a matrix is 64 bytes, and each element is 256 bytes, that leaves a lot of unused space

So try to put more than one matrix in each buffer :)

The 256 minimum constant buffer size/alignment matches the rules in GL/D3D12 too :(

Share this post


Link to post
Share on other sites
3 hours ago, Hodgman said:

So try to put more than one matrix in each buffer :)

The 256 minimum constant buffer size/alignment matches the rules in GL/D3D12 too :(

Oh I know. It just makes things harder to explain when documenting the functionality I'm writing.  Especially since I've had it drilled in to me that cbuffers need 16 byte alignment.  

Besides, I only need 1 matrix.  Whatever would I do with 2? :)  That's just madness.

Share this post


Link to post
Share on other sites

256 byte minimum? 

I have always bust made my CB's meet a 16 byte alignment and have never run into any problems.

Share this post


Link to post
Share on other sites

It's 256 minimum if you're going to offset into the buffer with xxSetConstantBuffers1.  I can assume, if you don't offset into the buffer, the size is still an actual minimum of 16 bytes.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!