Jump to content
  • Advertisement
Sign in to follow this  
dave09cbank

DX11 Cannot Create A Constant Buffer

This topic is 722 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

hi 

 

I'm trying to create a constant buffer (below) using SharpDx which fails.

var textureInfoBuffer = new SharpDX.Direct3D11.Buffer(m_Dx11Device, Utilities.SizeOf<PerFrameTextureInfo>(), ResourceUsage.Default, 
                             BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);

Structure (PreframeTextureInfo):

using SharpDX;
using System.Runtime.InteropServices;
/// <summary>
/// Per Object constant buffer (matrices)
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct PerFrameTextureInfo
{
    // texture width
    public float Width;

    // texture height
    public float Height;    
}

shader file code:

Texture2D ShaderTexture : register(t0);
SamplerState Sampler = sampler_state    //sampler for doing the texture-lookup
{
	Texture = (ShaderTexture);          //apply a texture to the sampler
	MipFilter = LINEAR;         //sampler states
	MinFilter = LINEAR;
	MagFilter = LINEAR;
};

cbuffer PerObject : register(b0)
{
	float4x4 ViewProjection;
	float4x4 World;
};

cbuffer PerFrameTextureInfo : register(b1)
{
	float Width;
	float Height;
};

Error Message:

[attachment=32663:sharpdx_CB_Error.PNG]

 

 

Now i can't seem to figure out as to why does this fail or what have i done wrong as i manage to create my PerObject buffer for my projection matrices using similiar code.

 

Any help or suggestions ?

 

Using C# with SharpDx and Directx11

Share this post


Link to post
Share on other sites
Advertisement

A constant buffer has to have a size, that is a multiple of 16 bytes. PerFrameTextureInfo is 8 byte so creation fails, while PerObject is 128 byte.

Share this post


Link to post
Share on other sites

You can use static_assert with condition sizeof % 16 == 0 just below structure definition. This way you will get compile time error instead of runtime.

Share this post


Link to post
Share on other sites

Its not directX problem, its C in general. Just read on "structure alignment" (its very easy) and padding.

 

For example, having struct with 4x4 matrix and xyz vector would need 1 addition padding float. The 4x4 float matrix takes 64 bytes, it will be placed at offset 0. Next, you want to pack the 3 float vector, at offset 64, taking 12 bytes. The structure is 76 bytes in size then, do you add 1 float (or int, or 4 char array - whatever with size of 4 bytes) and magically the structure grows to 80 bytes :) It is 16 byte aligned, buffer works.

Share this post


Link to post
Share on other sites

Ok if i understand correctly then i will need to ensure the structure size is always a multiple of 16. if it isn't then i will need to pad by adding dummy variables.

 

thus for instance as i have two variable Width and height defined so i will need to make sure i add 2 additional variables even if i don't use them to make them into a multiple of 16.

 

Is my understanding correct ?

Share this post


Link to post
Share on other sites

Yes, but thats only for gpu buffers. If you need own structure for own (not gpu) processing then obviously you do not have to do that... :)

Share this post


Link to post
Share on other sites

Ok if i understand correctly then i will need to ensure the structure size is always a multiple of 16. if it isn't then i will need to pad by adding dummy variables.

 

thus for instance as i have two variable Width and height defined so i will need to make sure i add 2 additional variables even if i don't use them to make them into a multiple of 16.

 

Is my understanding correct ?

You can skip the headache of manual padding and dummy variables by using attributes to explicitly set the structure size and field offsets:

 

//Explicit layout kind, specify size (which must be a multiple of 16)
[StructLayout(LayoutKind.Explicit, Size = 16)]
public struct PerFrameTextureInfo
{
    [FieldOffset(0)]
    public float Width;

    [FieldOffset(4)]
    public float Height; 
}

 

Source (and also a resource I highly recommend reading): http://timjones.tw/blog/archive/2011/03/08/marshalling-c-structures-into-directd-cbuffers-using

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!