Multiples of 16B constant buffer or Microsoft gone mad.

Started by
17 comments, last by NightCreature83 9 years, 7 months ago

heya

i was doing my stuff when i got a weird error. i could not create a constant buffer, filling in the actual size of the structure (12B = 3 floats) in 'D3D11_BUFFER_DESC.ByteWidth'

i debugged fof hours just to discover that it works for 48B, but not 47B... then i thought.. is it multiples of 16 for some reason. after a few hours I found this, saying:

Remarks

This structure is used by ID3D11Device::CreateBuffer to create buffer resources.

In addition to this structure, you can also use the CD3D11_BUFFER_DESC derived structure, which is defined in D3D11.h and behaves like an inherited class, to help create a buffer description.

If the bind flag is D3D11_BIND_CONSTANT_BUFFER, you must set the ByteWidth value in multiples of 16, and less than or equal to D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT.

what the hell? why? what is this? how do i know what size do i need to set based on the size of my struct?

most importantly... is there another, better way?!

Advertisement
http://thecodinglove.com/post/97565023437/when-i-use-a-new-library-without-reading-the

Also, alignment.


http://thecodinglove.com/post/97565023437/when-i-use-a-new-library-without-reading-the

Also, alignment.

a-har a-har a-har... not.

seriously, one thing is to read documentation the other is reading hundreds of pages just to prevent something you have no idea of what. most functions and other programming instruments offer functionality that isn't needed most of the time. that's like reading about rocket science just because you are interested in a fuel tank that is also used in rockets by coincidence.


http://thecodinglove.com/post/97565023437/when-i-use-a-new-library-without-reading-the

Also, alignment.

a-har a-har a-har... not.

seriously, one thing is to read documentation the other is reading hundreds of pages just to prevent something you have no idea of what. most functions and other programming instruments offer functionality that isn't needed most of the time. that's like reading about rocket science just because you are interested in a fuel tank that is also used in rockets by coincidence.

Welcome to the world of software engineering. Data alignments are an extremely common requirement, especially on consoles and especially when dealing with graphics/DSP hardware.

For Direct3D: have you tried building with the debug layer enabled? If you had done so earlier, you would have gotten a message in your debug output informing you that you're not allowed to create a constant buffer whose size is not a multiple of 16. Then you wouldn't have had to spend ages digging through documentation to find out where you went wrong.

Also, when using structs on the CPU that you plan to memcpy into a constant buffer, you have to be very vigilant to ensure your struct has the same layout as you're expecting on the CPU. You'll want to familiarize yourself with constant buffer packing rules.

EDIT: Page detailing how to use the Direct3D debug layer: http://msdn.microsoft.com/en-us/library/windows/desktop/jj200584(v=vs.85).aspx


You'll want to familiarize yourself with constant buffer packing rules.

this? because HLSL expects 16B aligned data for faster processing(ala less address computation) ?

thanks for preemptively answering about the debug layer, i was going to ask about it.

One of the most, if not the most, useful programming skills you will learn is how to learn. I'm not saying you don't know how to learn - I'm saying learning how to learn to use an API (identifying what is important to get started, what is the "functionality that isn't needed most of the time", and so on) or language or piece of hardware is a skill in itself that takes practice and experience.

Understanding that data alignment is a fundamental concept with 3d APIs (or nearly any hardware-related API really) is something you must learn. Now, when you go and try out a new 3d API in the future, you won't blindly dig through 100s of pages of documentation, but instead you will say "ah yes I bet it's this".


One of the most, if not the most, useful programming skills you will learn is how to learn. I'm not saying you don't know how to learn - I'm saying learning how to learn to use an API (identifying what is important to get started, what is the "functionality that isn't needed most of the time", and so on) or language or piece of hardware is a skill in itself that takes practice and experience.

Understanding that data alignment is a fundamental concept with 3d APIs (or nearly any hardware-related API really) is something you must learn. Now, when you go and try out a new 3d API in the future, you won't blindly dig through 100s of pages of documentation, but instead you will say "ah yes I bet it's this".

while i agree, this doesn't really help. or are you implying that i should go and learn everything by myself? if so then, socialisation and tools to collaboratively solve problems exist for a reason.

OpenGL aligns buffer range binding to 32 bytes (for most cards). JVM aligns object's fields to 8 bytes (which is important to estimate the size of your objects). Alignment is everywhere dude.

"I AM ZE EMPRAH OPENGL 3.3 THE CORE, I DEMAND FROM THEE ZE SHADERZ AND MATRIXEZ"

My journals: dustArtemis ECS framework and Making a Terrain Generator

Almost every piece of hardware has alignment requirements.

There is really only one exception: The x86 family decided in the early 1980s to allow misaligned integers and to (silently) take a performance hit instead. Here's one of many results, suggesting somewhere around a 2x performance hit, although it is hard to be certain due to the nature of modern processors. Back in the 386 era it was closer to a 3x performance hit. In 2011 Intel "fixed" them starting in the Sandy Bridge architecture, I'm not sure about AMD. Of course, the value can still cross two cache lines which is still somewhat painful.

Just about every other chipset out there will crash on misaligned values.

Keep your data properly aligned. Don't force your compiler to use strange packing values. It is usually a sign you're doing something wrong.

thanks Samith for the debug layer, it seems to report the alignment requirement. for anyone who views this thread with similar problems this is a note to pay attention to:

If you run your application with the debug layer enabled, the application will be substantially slower. But, to ensure that your application is clean of errors and warnings before you ship it, use the debug layer.





i can see how it can get 2x works, as doing 2 reads instead of 1 to obtain the whole value(yeah, optimisation might lower the hits but purely theoretically i think that's about right).


1. i am aware that alignment exists and it's impact, but i only met and comprehend the concept of 4B and 8B alignments, because that's the "word" "dword" and makes sense for 32bit and 64bit reads. i can't imagine why 16B would be forced...

2. assuming it is as it is, what would be a solution to this problem?
do i just ignore the 4 byte overhead(or 12B--15B if I only wanted to pass 1 char). if ignoring is an option then i might as well create more variable "for free" in the remaining 16B alignment gaps with no additional performance hits, yeah?

This topic is closed to new replies.

Advertisement