Question

I have the following code to instantiate a constantbuffer and bind it to the pixel shader. ConstantBuffers.EveryFrame is a struct in the ConstantBuffers class which holds all of the data I need to update on a per frame basis (currently just a single Color3 object).

everyFrame is a Direct3D11 Buffer object which I use as my constant buffer. Context is my D3DDevice.ImmediateContext

int sizeInBytes;
ConstantBuffers.EveryFrame cb1 = new ConstantBuffers.EveryFrame();
cb1.Color = new Color3(0, 0, 0);
sizeInBytes = Marshal.SizeOf(typeof(ConstantBuffers.EveryFrame));
using (DataStream data = new DataStream(sizeInBytes, true, true))
{
    data.Write(cb1);
    data.Position = 0;
    everyFrame = new D3D.Buffer(device, data, new BufferDescription
    {
        Usage = ResourceUsage.Default,
        SizeInBytes = sizeInBytes,
        BindFlags = BindFlags.ConstantBuffer
    });
    context.PixelShader.SetConstantBuffer(everyFrame, 0);
}

When I run this code I get the following error:

SlimDX.Direct3D11.Direct3D11Exception was unhandled
  Message=E_INVALIDARG: An invalid parameter was passed to the returning function (-2147024809)
  Source=SlimDX
  StackTrace:
   at SlimDX.Result.Throw[T](Object dataKey, Object dataValue)
   at SlimDX.Result.Record[T](Int32 hr, Boolean failed, Object dataKey, Object dataValue)
   at SlimDX.Direct3D11.Buffer.Build(Device device, DataStream data, Int32 sizeInBytes, ResourceUsage usage, BindFlags bindFlags, CpuAccessFlags accessFlags, ResourceOptionFlags optionFlags, Int32 structureByteStride)
   at SlimDX.Direct3D11.Buffer..ctor(Device device, DataStream data, BufferDescription description)
   at VoxelGame.Form1.SetupConstantBuffers() in d:\files\my documents\visual studio 2010\Projects\VoxelGame\VoxelGame\Form1.cs:line 119
   at VoxelGame.Form1..ctor() in d:\files\my documents\visual studio 2010\Projects\VoxelGame\VoxelGame\Form1.cs:line 91
   at VoxelGame.Program.Main() in d:\files\my documents\visual studio 2010\Projects\VoxelGame\VoxelGame\Program.cs:line 21
   at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

However when this following code runs (just a few calls before the above code) it works fine. This code doesn't touch any of the variables the code above uses, and mostly operates in a separate class (the device is passed in through the class' constructor, constantBuffer is a Direct3D11 Buffer stored in the class' variables)

ConstantBuffers.EveryMotion cb2 = new ConstantBuffers.EveryMotion();
int sizeInBytes = Marshal.SizeOf(typeof(ConstantBuffers.EveryMotion));
using (DataStream data = new DataStream(sizeInBytes, true, true))
{
    data.Write(cb2);
    data.Position = 0;
    constantBuffer = new D3D.Buffer(device, data, new BufferDescription
    {
        Usage = ResourceUsage.Default,
        SizeInBytes = sizeInBytes,
        BindFlags = BindFlags.ConstantBuffer
    });
    device.ImmediateContext.VertexShader.SetConstantBuffer(constantBuffer, 0);
}

for reference here are the ConstantBuffer structs

[StructLayout(LayoutKind.Sequential)]
public struct EveryMotion
{
    public Matrix WorldViewProjection;
}

[StructLayout(LayoutKind.Sequential)]
public struct EveryFrame
{
    public Color3 Color;
}
Was it helpful?

Solution

Constant buffers need their data aligned properly; the SizeInBytes property needs to be a multiple of 16, which is the case for a Matrix (4*4*4), but not the case for Color3 (4*3).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top