Jump to content
  • Advertisement
Sign in to follow this  
Achille Depla

[D3D10] Setting the constantbuffer in SharpDX

This topic is 980 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'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);
            }

 

 

 

Edited by Ownie

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

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!