VSSetConstantBuffers1 Problems

Started by
9 comments, last by Tape_Worm 5 years, 11 months ago

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

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.

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

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).

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.

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.

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 :(

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.

256 byte minimum? 

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

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.

This topic is closed to new replies.

Advertisement