Constant Buffer

To exchange data between CPU and GPU,  you have to generate two buffers. One on CPU and one on GPU.

To exchange Data between CPU/GPU in SlimDX you have to:

  • create a structure of data that corresponds to the structure in shader
  • create a DirectX buffer, at least in the byte size of the structure. The byte size of the buffer must be dividable by 16.
  • write the structure into a DataStream
  • Update the DirectX buffer with the DataStream

In the example slot 3 is used for constant buffer.

CPU

'#Pixel Shader Variablen
Public Structure BufferStructurePS
  Public Color As Vector4
  Public GlowColor As Vector4
  Public EmessivePower As Single
  Public SpecularPower As Single
  Public SpecularIntensity As Single
End Structure

GPU

//BUFFER
cbuffer CONSTANT_BUFFER : register(b3)
{
 float4 DiffuseColor;
 float4 GlowColor;
 float  EmessivePower;
 float  SpecularPower;
 float  SpecularIntensity;
};

Classe
I put all the things in on class, doins all the work for us.

Imports SlimDX
Imports SlimDX.Direct3D11
Imports System.Runtime.InteropServices

Public Class ConstantBuffer

Public ReadOnly Property ByteData As Byte()
    Get
        Return _RawData
    End Get
End Property

Public ReadOnly Property RawSize As Integer
    Get
        Return _RawSize
    End Get
End Property

Public ReadOnly Property Data As Buffer
    Get
        Return _CBuffer
    End Get
End Property

Private _CBuffer As Buffer
Private _RawSize As Integer
Private _RawSize16 As Integer
Private _Context As DeviceContext
Private _RawData() As Byte

Public Sub New(RawSize As Integer, DX11Device As DX11Device)
  'If the bind flag is D3D11_BIND_CONSTANT_BUFFER,
  'you must set the ByteWidth value in multiples of 16

  ReDim _RawData(RawSize - 1)
  _RawSize = RawSize
  _RawSize16 = CInt(Math.Ceiling(RawSize / 16) * 16)

  _Context = DX11Device.Device.ImmediateContext
  _CBuffer = CreateBuffer(_RawSize16, DX11Device.Device)
  AddHandler DX11Device.Disposing, AddressOf Dispose
End Sub

Private Function CreateBuffer(RawSize16 As Integer, Device As Device) As Buffer
 '#Create Buffer
  Dim BufferDesc As New BufferDescription
  With BufferDesc
   .Usage = ResourceUsage.Default
   .SizeInBytes = RawSize16
   .BindFlags = BindFlags.ConstantBuffer
  End With
  Return New Buffer(Device, BufferDesc)
End Function

Public Sub Update(CBufferStructure As Object)
 '#Convert Structure to DataStream
  Dim buffer As IntPtr = Marshal.AllocHGlobal(_RawSize)
  Marshal.StructureToPtr(CBufferStructure, buffer, False)
  Marshal.Copy(buffer, _RawData, 0, RawSize)
  Marshal.FreeHGlobal(buffer)

  Using DS As New DataStream(_RawSize16, True, True)
   DS.WriteRange(_RawData, 0, _RawSize)
   DS.Position = 0

   '#Update Buffer
    With _Context
     .UpdateSubresource(New DataBox(0, 0, DS), _CBuffer, 0)
    End With
  End Using
End Sub

Private Sub Dispose()
  '#Dispose Buffer
  If Not _CBuffer Is Nothing Then _CBuffer.Dispose()
End Sub

End Class

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s