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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.