Jump to content

  • Log In with Google      Sign In   
  • Create Account


Why isn't there a queued SetData() ?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
8 replies to this topic

#1 skytiger   Members   -  Reputation: 258

Like
0Likes
Like

Posted 14 February 2012 - 11:45 AM

So many CPU to GPU problems are caused by a lack of a queued SetData() command in DirectX

(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?

Sponsor:

#2 MJP   Moderators   -  Reputation: 10659

Like
0Likes
Like

Posted 14 February 2012 - 01:26 PM

In general stuffing lots of data into the command buffer is slow. You really don't want to have to do it if you don't have to.

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 mhagain   Crossbones+   -  Reputation: 7644

Like
0Likes
Like

Posted 14 February 2012 - 04:09 PM

One approach that works reasonably well is to use a D3DPOOL_MANAGED resource. Lock it, write into it, then Unlock when done. You won't stall the pipeline as you're Locking/Unlocking the system memory copy, and while it may need to stall for updating the GPU memory copy you have some measure of control over when that stall may happen (for textures at least) using D3DLOCK_NO_DIRTY_UPDATE and AddDirtyRect.

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 Hodgman   Moderators   -  Reputation: 28653

Like
0Likes
Like

Posted 14 February 2012 - 05:50 PM

We know data can be transferred in the command queue - that is how DrawUserPrimitives() works

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 ;)

So why not allow incremental updates to vertex buffers as a queued command?

Buffer updates are queued (assuming you use the appropriate create/lock flags), just in a different way.

#5 skytiger   Members   -  Reputation: 258

Like
0Likes
Like

Posted 16 February 2012 - 02:38 AM

Thanks for those useful posts.

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 Butabee   Members   -  Reputation: 228

Like
0Likes
Like

Posted 16 February 2012 - 03:29 AM

If you're interested in fast as possible cpu to gpu copies, you should look into getting an AMD fusion processor. Data isn't really copied anywhere, but rather telling the cpu to access certain portions of memory and vice versa. Of coarse you'd also have to use opencl.

#7 skytiger   Members   -  Reputation: 258

Like
0Likes
Like

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)

#8 Promit   Moderators   -  Reputation: 6349

Like
0Likes
Like

Posted 16 February 2012 - 06:24 PM

We know data can be transferred in the command queue - that is how DrawUserPrimitives() works

Nope. DrawUserPrimitives internally causes an unqueued SetData before queueing a regular draw command.

#9 skytiger   Members   -  Reputation: 258

Like
0Likes
Like

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

Posted Image

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 ...




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS