Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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();
share|improve this question

1 Answer 1

up vote 3 down vote accepted

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.

share|improve this answer
    
For the specific case of updating a buffer every frame (a buffer declared with ResourceUsage.Dynamic) part 2 of the answer (Map with MapMode.WriteDiscard) should be used. See msdn.microsoft.com/en-us/library/windows/desktop/… –  Jens Nolte Jun 13 '14 at 12:33

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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