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 am creating a C#/SharpDx/DirectX10 application to plot line charts in a fast way.

I have a prototype which uses Dynamic Vertex Buffers and fills a fixed-size buffer, say 1M vertices, with new data per frame.

I'm finding sometimes the vertex buffer is filled with new data while the GPU is still drawing the last batch (especially on slower GPUs). Here is my code to create, map, fill and flush a vertex buffer. I wonder if I'm using it in the right way?

// Declare the re-usable buffer (once)
SharpDX.Direct3D10.Buffer d3d10Buffer = new SharpDX.Direct3D10.Buffer(_d3d10Device,          
        new BufferDescription(size,
        ResourceUsage.Dynamic,
        BindFlags.VertexBuffer,
        CpuAccessFlags.Write,
        ResourceOptionFlags.None));

// ... 

// Per-frame, map the buffer, write vertices and draw + Flush()
DataStream vertexBufferStream = d3d10Buffer.Map(MapMode.WriteDiscard,   
        SharpDX.Direct3D10.MapFlags.None);
vertexBufferStream.Write((float)someValue);
vertexBufferStream.Write((float)anotherValue); 
// lots of writing ... 

// Then immediately draw
d3d10Buffer.Unmap();
vertexBufferStream.Dispose();
_d3d10Device.InputAssembler.SetVertexBuffers(0, 
       new VertexBufferBinding(_d3d10Buffer, 16, 0));

_d3d10Device.Draw(); // Assumes shaders and topology have been applied
_d3d10Device.Flush();

So I'm wondering, am I doing this the right way? The MSDN Documentation tells me not to call Flush, but I don't want to overwrite my (shared) dynamic vertex buffer when the next frame begins.

I also saw on the SharpDX website that MapFlags and MapMode have enumerations to prevent overwrite, would MapMode.WriteNoOverwrite and MapFlags.DoNotWait help in this scenario?

share|improve this question
    
1M vertices sounds a lot. Are all visible on screen? –  Maik Semder Feb 20 '13 at 17:21
    
Consider the use-case where you're plotting something like this: bitscope.com/software/dso/32.png and a piece of hardware is pushing data to your computer at the rate of 10M samples per second, you need to display it - then yes its easy to run into millions of new vertices per-frame! –  Dr. ABT Feb 20 '13 at 20:56
    
Not necessarily, 10M samples does not necessarily mean millions of vertices, thats the simplest brute force method, but there are better ways to preprocess the input, select significant data and only render those, since you cannot see 1M vertices anyway, the screen does not have enough pixel –  Maik Semder Feb 20 '13 at 21:05
    
You're right, there are only so many pixels, but as I mentioned with the sheer volume of data, the fastest processor available is the GPU. Try iterating over 10M x,y points as they're coming in and even reducing that dataset. In actual fact datasets can be much larger (100s of millions) so optimizing the drawing is a worthwhile step. –  Dr. ABT Feb 20 '13 at 21:46
1  
You can break up your data into multiple VBOs. Also, for certain kinds of graphs, you can also trivially bound your input (only look at a limited range of samples), all very fast in the CPU. The GPU bus is slow, so sending less invisible data to the GPU is a win, no matter how well the GPU processes the data it already has. –  Sean Middleditch Feb 21 '13 at 1:56
show 3 more comments

1 Answer

up vote 2 down vote accepted

You're mapping with write-discard, so this isn't a problem at all (and the Flush is definitely not needed). If the buffer is currently in use for drawing the driver will just hand you a new block of memory when you map, and release the old memory when it's drawing has finished. Really clever drivers will actually keep the old block lying around and reuse it as a subsequent "new block" some frames later, so that instead of allocating/releasing memory each frame it's just continually cycling through the same few blocks - a classic multi-buffering approach but all handled for you automatically by the driver: neat!

share|improve this answer
    
Ok so question, if my vertex buffer is size N and I need to draw N+1 can I do this: ... 1-Map, 2-Append N vertices, 3-Draw, 4-Unmap, 5-Map, 6-Append M vertices, 7-Draw, 8-Unmap ... with no flushes and it will just automagically work? –  Dr. ABT Feb 20 '13 at 20:56
1  
Yup, that works. –  Jimmy Shelter Feb 20 '13 at 23:38
    
Thanks!! I'll give this a try. I assume Unmap causes a flush so perhaps now I can breause strategies with mapping/unmapping and multiple VBs to keep the GPU pipeline humming –  Dr. ABT Feb 21 '13 at 7:53
1  
There's no flush but there's no need for one - the "discard" is where the magic lies. –  Jimmy Shelter Feb 21 '13 at 10:01
1  
Neither - it means "give me a new block of memory but let any pending drawing continue from the old block" - there's no waiting, nothing gets cancelled, and the old block is automatically recycled when it's finished with. –  Jimmy Shelter Feb 21 '13 at 14:33
show 2 more comments

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.