Jump to content
  • Advertisement
Sign in to follow this  

Problem with Constant Buffer Size.

This topic is 1492 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts


I have a question regarding Constant Buffers in Directx 11, I'm not sure if this should go to the beginners forum feel free to move it if so. 

Anyhow. Im getting the following error: 


D3D11 WARNING: ID3D11DeviceContext::DrawIndexed: The size of the Constant Buffer at slot 0 of the Pixel Shader unit is too small (48 bytes provided, 80 bytes, at least, expected). This is OK, as out-of-bounds reads are defined to return 0. It is also possible the developer knows the missing data will not be used anyway. This is only a problem if the developer actually intended to bind a sufficiently large Constant Buffer for what the shader expects.  [ EXECUTION WARNING #351: DEVICE_DRAW_CONSTANT_BUFFER_TOO_SMALL]


If I'm understanding this message correctly it says that my buffer is 48 bytes large but it should be 80 bytes.


This is how my buffer looks:

struct cbPerLight
XMFLOAT4 lightDirection;  //16 bytes
XMFLOAT4 lightColor;   //16 bytes 
XMFLOAT4 lightPosition; //16 bytes
XMFLOAT4 lightAngle; //16 bytes
XMFLOAT4 lightRange;      //16 bytes

 16*5 = 80 bytes. And all of the is 16 bytes each so no problem that that one of the is over the 16 block.


This is how my PixelShader looks

Texture2D txDiffuse : register(t0);
Texture2D txNormal : register(t1);
Texture2D txDepth : register(t2);
Texture2D txSpecular : register(t3);
SamplerState samLinear0 : register( s0 );
SamplerState samLinear1 : register( s1 );
SamplerState samLinear2 : register( s2 );
SamplerState samLinear3 : register( s3 );
cbuffer cbLight : register(b0)
	float4 lightDirection;
	float4 lightColor;	
	float4 lightPosition;
	float4 lightAngles;
	float4 lightRange;
struct PS_INPUT
  float4 position	 : SV_POSITION;
  float2 texcoord	 : TEXCOORD0;	
float4 main(PS_INPUT input) : SV_Target0
      float4 diffuseAlbedo = txDiffuse.Sample(samLinear0, input.texcoord);
      float4 normal = txNormal.Sample(samLinear1, input.texcoord);
      float4 depth = txDepth.Sample(samLinear2, input.texcoord);
      float4 specular = txDepth.Sample(samLinear3, input.texcoord);
      float4 L = lightPosition - input.position;
      float distance =  length(L);		
       L /= distance;
       float attenuation = max(0, 1.0f - (distance / lightRange.x));

       float4 L2 = lightDirection;
       float rho = dot(-L, L2);
	attenuation *= saturate((rho - lightAngles.y) / (lightAngles.x - lightAngles.y));

	const float diffuseNormalizationFactor = 1.0f / 3.14159265f;		
	float d1 = dot(normal, L);
	float nDotL = saturate(d1);
	float4 diffuse = nDotL * lightColor * diffuseAlbedo * diffuseNormalizationFactor;
	return diffuse * attenuation;

Its a light stage in my render, should render a spotlight when its finished (It not complete yet).


I have to say that I'm not really understanding how the constant buffer should be allocated in memory but I think they should be in blocks of 16bytes and no variable should cross a 16 byte block.  And one could use padding variable to achieve this.. 

My output is currently black because it seems that some of variables seems to be corrupt in the shader,, with makes me think that it has to do something with the allocation. 


But in this case I'm not sure where it gets 48bytes from. Does anyone has any suggestions? 


thx for you help.

Share this post

Link to post
Share on other sites

The structure looks ok to me. Is it possible that a different constant buffer is bound to slot b0 than what you expect? Do you create any other constant buffers that are 48 bytes? Can you also show the code where you create the constant buffer and where you bind it before the draw call?

Share this post

Link to post
Share on other sites

Hi, I realized that I hade another constant buffer that was 48bytes long on b0 as well (thx megadan). I have now changed light structure to b1, no warnings, but all values in the structure (in shader space) are zero, so I guess I need to change something on the c++ side so the structure fills at register 1 and not 0?

	struct cbPerLight sCbLight;	 		
	sCbLight.lightColor = light.Color;
	sCbLight.lightDirection = light.Direction;
	sCbLight.lightPosition = light.Position;
	sCbLight.lightAngle = light.Angles;
	sCbLight.lightRange = XMFLOAT4(2.0f, 1.0f, 1.0f, 1.0f);	

m_pContext->UpdateSubresource(pixelShader.GetConstantBuffer()->m_pBuffer, 0, nullptr, &sCbLight, 0, 0);

your help is much appreciated.

Share this post

Link to post
Share on other sites

so I guess I need to change something on the c++ side so the structure fills at register 1 and not 0?

Your call to PSSetConstantBuffers will need to pass 1 as the first parameter to bind to slot 1. Alternatively, you can bind both buffers at the same time with a single call to PSSetConstantBuffers by passing the buffers as an array to the function and setting StartSlot to 0. The first buffer will then be bound to 0 and the second will be bound to 1.

Share this post

Link to post
Share on other sites

Hi, thx a lot for your help. No more warnings, now off to the second problem to try to make the shader to work.. 



Share this post

Link to post
Share on other sites
Sign in to follow this  

  • 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!