This tutorial is part of a Collection: 03. DirectX 11 - Braynzar Soft Tutorials
rate up
2
rate down
6620
views
bookmark
37. Constant Buffer Packaging

Just a bit about constant buffer packaging

There are no files for this tutorial
I've been getting a few comments about problems with constant buffers not being able to be created. This is usually because of the way HLSL "packs" constant buffers. HLSL packs constant buffers into groups of 16 bytes. An easy way to look at this is 4 float elements. When you send a constant buffer to the shaders, you need to make sure that no variable is split between two groups of 16 bytes. You can be sure that no variable is "split" by using "padding", or sometimes just by re-organizing the structure. I know this probably sounds confusing, so i'm going to show you with an example: struct constantBuffer { // first group of 16 bytes float variable1; // 4 bytes float variable2; // 4 bytes float variable3; // 4 bytes float variable4; // 4 bytes // second group of only 12 bytes D3DXVECTOR3 variable5; // 12 bytes (4 * 3) // Since the above group only contains 12 bytes, it will take the next 4 bytes to complete the group // This is where you would find an error D3DXVECTOR3 variable6; // First 4 bytes are put into the above group, // meaning this variable is "split", which would cause an error }; One way to go about fixing this problem, is just "re-organizing" the structure like this: struct constantBuffer { // first group of 16 bytes D3DXVECTOR3 variable5; // 12 bytes (4 * 3) float variable1; // 4 bytes // second group of 16 bytes after re-organizing D3DXVECTOR3 variable6; // 12 bytes (4 * 3) float variable2; // 4 bytes // Last group containing 8 bytes float variable3; // 4 bytes float variable4; // 4 bytes }; The other way to go about fixing this problem, is by using "padding" like this: struct constantBuffer { // first group of 16 bytes float variable1; // 4 bytes float variable2; // 4 bytes float variable3; // 4 bytes float variable4; // 4 bytes // second group now contains 16 bytes by including the "pad" D3DXVECTOR3 variable3; // 12 bytes (4 * 3) float pad1; // 4 bytes // Now that the above group contains 16 bytes, // this next variable is no longer split D3DXVECTOR3 variable3; // 12 bytes, not split // HLSL will add padding automatically to the end }; Another thing to mention, is different types can be different sizes as you can see. I remember running into a problem using a boolean type. I was using the default C++ type "bool" in my constant buffer, which was causing an error. This is because the C++ "bool" type is only one byte, so switching to Window's "BOOL" type, which is 4 bytes, solved the problem. You can easily find the size of a data type by using the function sizeof(), which returns the size in bytes. Here's a little table of some common types and their sizes: (Remember 1 byte is 8 bits) **bool **1 byte **char **1 byte **short **2 bytes **int **4 bytes **long **4 bytes **long long **8 bytes **float **4 bytes **double **8 bytes **BOOL **4 bytes **BYTE **1 byte **CHAR **1 byte **DWORD **4 bytes **FLOAT **4 bytes **INT **4 bytes **INT64 **8 bytes **LONG **4 bytes **SHORT **2 bytes **WCHAR **2 bytes **WORD **2 bytes Check it out yourself: #include <iostream> #include <Windows.h> int main() { std::cout << "bool - " << sizeof(bool) << " bytes" << std::endl; std::cout << "char - " << sizeof(char) << " bytes" << std::endl; std::cout << "short - " << sizeof(short) << " bytes" << std::endl; std::cout << "int - " << sizeof(int) << " bytes" << std::endl; std::cout << "long - " << sizeof(long) << " bytes" << std::endl; std::cout << "long long - " << sizeof(long long) << " bytes" << std::endl; std::cout << "float - " << sizeof(float) << " bytes" << std::endl; std::cout << "double - " << sizeof(double) << " bytes" << std::endl; std::cout << "BOOL - " << sizeof(BOOL) << " bytes" << std::endl; std::cout << "BYTE - " << sizeof(BYTE) << " bytes" << std::endl; std::cout << "DWORD - " << sizeof(DWORD) << " bytes" << std::endl; std::cout << "FLOAT - " << sizeof(FLOAT) << " bytes" << std::endl; std::cout << "INT - " << sizeof(INT) << " bytes" << std::endl; std::cout << "INT64 - " << sizeof(INT64) << " bytes" << std::endl; std::cout << "LONG - " << sizeof(LONG) << " bytes" << std::endl; std::cout << "SHORT - " << sizeof(SHORT) << " bytes" << std::endl; std::cout << "WCHAR - " << sizeof(WCHAR) << " bytes" << std::endl; std::cout << "WORD - " << sizeof(WORD) << " bytes" << std::endl; Sleep(10000); return 0; }