Why isn't there a queued SetData() ?
#1 Members - Reputation: 215
Posted 14 February 2012 - 11:45 AM
(SetData() is "out-of-band" as it isn't a queued command like DrawPrimitives())
We know data can be transferred in the command queue - that is how DrawUserPrimitives() works
So why not allow incremental updates to vertex buffers as a queued command?
#2 Moderators - Reputation: 5643
Posted 14 February 2012 - 01:26 PM
Drivers handle per-frame updates of dynamic resources through other means. Typically it will cycle through a ring buffer of memory (or multiple copies of a resource) in sync with GPU frames, so that the GPU can be pulling from one area of memory while the CPU writes to a different area.
#3 Members - Reputation: 4032
Posted 14 February 2012 - 04:09 PM
It's worth noting that D3D10/11 have UpdatesubResource which meets the criteria of a "queued SetData". Vendors don't recommend it for use with textures, but I've personally found at least one use case where it's measurably faster than the preferred approach - updating hundreds of small scattered subrects in a texture (real world example: lightmaps).
It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.
#4 Moderators - Reputation: 14300
Posted 14 February 2012 - 05:50 PM
N.B. you can use this mechanism to update a resource if you want to -- e.g. issuing a draw-points command to plot individual pixels into a texture -- however, you'll discover why it's usually a worse idea than the usual way of doing things when your command buffer fills up ;)We know data can be transferred in the command queue - that is how DrawUserPrimitives() works
Buffer updates are queued (assuming you use the appropriate create/lock flags), just in a different way.So why not allow incremental updates to vertex buffers as a queued command?
#5 Members - Reputation: 215
Posted 16 February 2012 - 02:38 AM
I am thinking about keeping an index buffer "defragmented" so I can use a single Draw() call,
this requires updating a percentage of the index buffer every frame.
(edit)
Oh I see there is no automatic copy operation
so there is only appending data with NoOverwrite
or rebuilding everything with Discard
or lock waits with Default
which brings me back to the original question ...
I can see no good reason for not supporting queued incremental updates.
In a terrain renderer, for example, only the vertices that are changing between not-potentially-visible and potentially-visible
need to be loaded/unloaded from the GPU - which is a tiny percentage!
The way DX9 is designed forces us to: update the entire index buffer every frame *and* forces the GPU to maintain multiple versions of the buffers.
Sending 2kb per frame via command buffer versus 100kb per frame via SetData() has to be more sensible.
#6 Members - Reputation: 180
Posted 16 February 2012 - 03:29 AM
#7 Members - Reputation: 215
Posted 16 February 2012 - 06:04 PM
One approach that works reasonably well is to use a D3DPOOL_MANAGED resource. Lock it, write into it, then Unlock when done
That does sound like a perfect solution, except for DX docs:
Resource management (D3DPOOL_MANAGED) is not recommended for resources which change with high frequency. For example, vertex and index buffers which are used to traverse a scene graph every frame rendering only geometry visible to the user changes every frame. Since managed resources are backed by system memory, the constant changes must be updated in system memory, which can cause a severe degradation in performance. For this particular scenario, D3DPOOL_DEFAULT along with D3DUSAGE_DYNAMIC should be used.
(Of course only profiling will give a true answer)
#9 Members - Reputation: 215
Posted 17 February 2012 - 05:52 AM
DrawUserPrimitives internally causes an unqueued SetData before queueing a regular draw command
Strange ... here: http://msdn.microsoft.com/en-us/library/ff552842%28v=VS.85%29.aspx

it shows the command buffer storing "immediate" mode vertex data
but only for LineList and TriangleFan ... not for TriangleStrip or List!
Still a mystery as to why ...






