2
\$\begingroup\$

I want to set a buffer that is updated every frame but can't figure it out, what i have to do.

The only working thing i have is this:

mdexcription = new BufferDescription(Matrix.SizeInBytes * Matrices.Length, ResourceUsage.Dynamic, BindFlags.VertexBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None, 0);
instanceBuffer = SharpDX.Direct3D11.Buffer.Create(Device, Matrices, mdexcription);

vBB = new VertexBufferBinding(instanceBuffer, Matrix.SizeInBytes, 0);
DeviceContext.InputAssembler.SetVertexBuffers(1, vBB);

Draw:

//Change Matrices (Matrix[]) every frame...
instanceBuffer.Dispose();
instanceBuffer = SharpDX.Direct3D11.Buffer.Create(Device, Matrices, mdexcription);

vBB = new VertexBufferBinding(instanceBuffer, Matrix.SizeInBytes, 0);
DeviceContext.InputAssembler.SetVertexBuffers(1, vBB);

I guess Dispose() and creating a new buffer is slow and can be done much faster.

I've read about DataStream but i do not know, how to set this up properly.

What steps do i have to do to set up a DataStream to achieve fast every-frame update?


Edit:

Finally got it. I used that:

mdescription = new BufferDescription(Matrix.SizeInBytes * Matrices.Length, ResourceUsage.Dynamic, BindFlags.VertexBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None, 0);
instanceBuffer = SharpDX.Direct3D11.Buffer.Create(Device, Matrices, mdescription);

vBB = new VertexBufferBinding(instanceBuffer, Matrix.SizeInBytes, 0);
DeviceContext.InputAssembler.SetVertexBuffers(instSlot, vBB);

Draw:

DataStream stream;
var dataBox = DeviceContext.MapSubresource(instanceBuffer, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out stream);
stream.WriteRange(Matrices);
DeviceContext.UnmapSubresource(instanceBuffer, 0); //to update the data on GPU

stream.Dispose();
\$\endgroup\$
4
\$\begingroup\$

There are two basic ways to update a buffer.

  1. Use DeviceContext.UpdateSubresource(). source is your source data, in the form of a DataBox (you can pass most value types and arrays as DataBox), and resource is your vertex buffer.

    This is the easiest way to copy small data in one pass, and I use it mostly for updating constant buffers.

    In your case it could be:

    DeviceContext.UpdateSubresource(yourMatrixArray, yourVertexBuffer);
    
  2. Use DeviceContext.MapSubresource. resource is your vertex bufffer, mode is the way you want to update your data, flags are obviously flags, and you get a DataStream (inherits from Stream) which you can use to copy your data.

    I use this when I'm updating complex data that may have complex structures, like vertex buffers.

    In your case, it could be:

    DataStream dataStream;
    
    ImmediateContext.MapSubresource(yourVertexBuffer, MapMode.WriteDiscard, MapFlags.None, out dataStream);
    
    dataStream.Write(...);
    

    Don't forget to unmap the resource when finished.

    dataStream.Dispose(); // Not 100% sure if necessary
    ImmediateContext.UnmapSubresource(yourVertexBuffer, 0);
    

There are lots of other options, like when you're using subresources and stuff. Make sure you read the docs.

\$\endgroup\$
1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .