Constant buffer - Memory error

Started by
5 comments, last by Kamil9132 9 years, 7 months ago

I have constant buffer with 2 variables, when i add one more variable to constant buffer i got this error in output window:


First-chance exception at 0x7673C42D in Game.exe: Microsoft C++ exception: _com_error at memory location 0x0021F90C.
First-chance exception at 0x7673C42D in Game.exe: Microsoft C++ exception: _com_error at memory location 0x0021F90C.

What is wrong in this code?

.fx:


Texture2D txDiffuse : register( t0 );
SamplerState samLinear : register( s0 );

cbuffer cbNeverChanges : register( b0 )
{
	matrix View;
};

cbuffer cbChangeOnResize : register( b1 )
{
    matrix Projection;
};

cbuffer cbChangesEveryFrame : register( b2 )
{
    matrix World;
	bool cPrzez;
	int kolorP;
};

cbuffer cbPixelShader : register( b3 )
{
	float4 kolorS;
	float4 kolorL;
	int Trans;

};
 

main.cpp:


struct SimpleVertex{

    XMFLOAT3 Pos;
    XMFLOAT2 Tex;

};

struct CBNeverChanges{  

	XMMATRIX mView;

};

struct CBChangeOnResize{

    XMMATRIX mProjection;

};

struct CBChangesEveryFrame{

	XMMATRIX mWorld;
	int cPrzez;
	int cKolorP;

};

struct CBPixelShader{

	XMFLOAT4 kolorS;
	XMFLOAT4 kolorL;
	int Trans;

};

struct INS{

	XMFLOAT4X4 IN_N;
	float Light_Simple;

};

    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.ByteWidth = sizeof(CBNeverChanges);
    bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    bd.CPUAccessFlags = 0;
    d3d11Device->CreateBuffer( &bd, NULL, &g_pCBNeverChanges );
 
    bd.ByteWidth = sizeof(CBChangeOnResize);
    d3d11Device->CreateBuffer( &bd, NULL, &g_pCBChangeOnResize );

    bd.ByteWidth = sizeof(CBPixelShader);
    d3d11Device->CreateBuffer( &bd, NULL, &g_pCBPixelShader );
  
	bd.ByteWidth = sizeof(CBChangesEveryFrame);
    d3d11Device->CreateBuffer( &bd, NULL, &g_pCBChangesEveryFrame );

I got error on this line:


    d3d11Device->CreateBuffer( &bd, NULL, &g_pCBPixelShader );

If i delete int Trans from main.cpp and .fx, program will work properly.

Advertisement

First of all, enable the D3D Debug Layer, it will help you debug D3D related errors in the future.

That error is probably thrown because the size of Constant Buffers be a multiple of 16, and sizeof(CBPixelShader) = 36, which isn't a multiple of 16.

Check the remarks of D3D11_BUFFER_DESC:

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.

To fix this: add some padding variables to your structures:


struct CBChangesEveryFrame{

	XMMATRIX mWorld;
	int cPrzez;
	int cKolorP;
        int pad0, pad1; //Padding
};

struct CBPixelShader{

	XMFLOAT4 kolorS;
	XMFLOAT4 kolorL;
	int Trans;
        int pad0, pad1, pad2; //Padding
};

struct INS{

	XMFLOAT4X4 IN_N;
	float Light_Simple;
        float pad0, pad1, pad2; //Padding
};

You don't have to add padding in your .fx files (HLSL) because the HLSL compiler automatically adds the necessary padding to pack data into 4 and 16 byte boundaries.

Some more info regarding packing rules for HLSL. I strongly advise you to read it.

Thank you for help. I thought that padding is automatically added.

Thank you for help. I thought that padding is automatically added.

Yes in HLSL, no in C/C++.

Well, actually yes in the latter too, but to a different alignment (which may vary based on your compiler and build options). When in doubt an explicit #pragma pack on structs that are going to be used in cbuffers is your friend (although it doesn't resolve every possible difference).

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

Should I use this rule (multiple of 16) with vertex buffer?

Should I use this rule (multiple of 16) with vertex buffer?

Vertex buffers don't have this restriction.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

Thanks.

This topic is closed to new replies.

Advertisement