[D3D10] Setting the constantbuffer in SharpDX

Started by
1 comment, last by unbird 8 years, 3 months ago

I'm trying to set 2 constantbuffers (in register 4 and 5) in SharpDX but I'm not sure if I'm doing it right.
Is there any way to check it?

[D3D10]

HLSL


cbuffer GS_CONSTANT_BUFFER_EDGETABLE : register(b4)
{
	int4 edgeTable[256];
};

cbuffer GS_CONSTANT_BUFFER_TRITABLE : register(b5)
{
	int4 triTable[256][16];
};

C#


        [StructLayout(LayoutKind.Sequential)]
        public struct GS_CONSTANT_BUFFER_EDGETABLE
        {
            public Int4[] edgeTable;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct GS_CONSTANT_BUFFER_TRITABLE
        {
            public Int4[][] triTable;
        }

        private GS_CONSTANT_BUFFER_EDGETABLE _dataEdge;
        private GS_CONSTANT_BUFFER_TRITABLE _dataTri;

        private Buffer _bufferEdge;
        private Buffer _bufferTri;

            BufferDescription desc = new BufferDescription();
            desc.Usage = ResourceUsage.Dynamic;
            desc.BindFlags = BindFlags.ConstantBuffer;
            desc.CpuAccessFlags = CpuAccessFlags.Write;
            desc.SizeInBytes = _dataEdge.edgeTable.Length * Marshal.SizeOf(_dataEdge.edgeTable[0]);

            _bufferEdge = Buffer.Create(device, ref _dataEdge, desc);

            desc.SizeInBytes = _dataTri.triTable.Length * Marshal.SizeOf(_dataTri.triTable[0][0]) * 16;
            _bufferTri = Buffer.Create(device, ref _dataTri, desc);

            for (int i = 0; i < Shader.Technique.Description.PassCount; ++i)
            {
                 Shader.Technique.GetPassByIndex(i).Apply();

                 //_device.UpdateSubresource(ref _dataEdge, _bufferEdge, 4);
                 //_device.UpdateSubresource(ref _dataTri, _bufferTri, 5);
                 _device.GeometryShader.SetConstantBuffers(4, 2, _buffers);

                 _device.DrawIndexed(Model.IndexCount, 0, 0);
            }

Advertisement

Update:

HLSL


cbuffer GS_CONSTANT_BUFFER_EDGETABLE : register(b1)
{
	int edgeTable[256];
};

cbuffer GS_CONSTANT_BUFFER_TRITABLE : register(b2)
{
	int triTable[256][16];
};

Structure


        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct GS_CONSTANT_BUFFER_EDGETABLE
        {
            //[FieldOffset(0), MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
            public int[] edgeTable;
        }

        //[StructLayout(LayoutKind.Explicit, Size = 65536 + 12)]
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct GS_CONSTANT_BUFFER_TRITABLE
        {
            //[FieldOffset(0), MarshalAs(UnmanagedType.ByValArray, SizeConst = 4096)]
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256*16)]
            public int[,] triTable;
        }

Buffer creation


            GCHandle pinnedArray = GCHandle.Alloc(edgeTable, GCHandleType.Pinned);
            IntPtr pointer = pinnedArray.AddrOfPinnedObject();
            _dataEdge = (GS_CONSTANT_BUFFER_EDGETABLE)Marshal.PtrToStructure(pointer, typeof(GS_CONSTANT_BUFFER_EDGETABLE));
            pinnedArray.Free();

            pinnedArray = GCHandle.Alloc(triTable, GCHandleType.Pinned);
            pointer = pinnedArray.AddrOfPinnedObject();
            _dataTri = (GS_CONSTANT_BUFFER_TRITABLE)Marshal.PtrToStructure(pointer, typeof(GS_CONSTANT_BUFFER_TRITABLE));
            pinnedArray.Free();

            BufferDescription desc = new BufferDescription();
            desc.Usage = ResourceUsage.Dynamic;
            desc.BindFlags = BindFlags.ConstantBuffer;
            desc.CpuAccessFlags = CpuAccessFlags.Write;
            desc.SizeInBytes = _dataEdge.edgeTable.Length * Marshal.SizeOf(_dataEdge.edgeTable[0]);
            desc.OptionFlags = 0;

            _bufferEdge = Buffer.Create(device, ref _dataEdge, desc);

            desc.SizeInBytes = _dataTri.triTable.Length * Marshal.SizeOf(_dataTri.triTable[0,0]);
            _bufferTri = Buffer.Create(device, ref _dataTri, desc);

            _buffers = new Buffer[2];
            _buffers[0] = _bufferEdge;
            _buffers[1] = _bufferTri;

Rendering


                Device.InputAssembler.InputLayout = Shader.InputLayout;
                Device.InputAssembler.PrimitiveTopology = Model.PrimitiveTopology;
                Device.InputAssembler.SetIndexBuffer(Model.IndexBuffer, Format.R32_UInt, 0);
                Device.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(Model.VertexBuffer, Model.VertexStride, 0));

                for (int i = 0; i < Shader.Technique.Description.PassCount; ++i)
                {
                    Shader.Technique.GetPassByIndex(i).Apply();

                    Device.GeometryShader.SetConstantBuffers(1, 2, _buffers);

                    Device.DrawIndexed(Model.IndexCount, 0, 0);
                }

Unfortunately the result is still wrong, perhaps my buffer marshalling is wrong?

Likely. I never had much luck "POD-ing" fixed size arrays, less so with custom value types. Rather go manually with a DataStream. Here some SlimDX code for D3D11 but I hope you get the idea:


var array = new Int4[256];
// ... fill that with values

var bufferDesc = new BufferDescription()
{
    BindFlags = BindFlags.ConstantBuffer,
    CpuAccessFlags = CpuAccessFlags.None,
    OptionFlags = ResourceOptionFlags.None,
    SizeInBytes = Marshal.SizeOf(typeof(Int4)) * array.Length,
    Usage = ResourceUsage.Immutable,
    StructureByteStride = 0,
};
SlimDX.Direct3D11.Buffer buffer;
using(var stream = new DataStream(array, true, true))
{
    buffer = new SlimDX.Direct3D11.Buffer(device, stream, bufferDesc);
}

// or explicity (dunno if SharpDX allows the above DataStream constructor)
using (var stream = new DataStream(bufferDesc.SizeInBytes, true, true))
{
    stream.WriteRange(array);
    stream.Position = 0;
    buffer = new SlimDX.Direct3D11.Buffer(device, stream, bufferDesc);
}

Good luck with the marching ... dodecahedra tongue.png

Edit: For multidimensional arrays: Flatten them to a 1D array first.

This topic is closed to new replies.

Advertisement