What BeginScene()/EndScene() really mean?

Started by
12 comments, last by initial_y 20 years, 6 months ago
Why would it be insanely difficult? The DX driver is running in a separate thread anyway; why would this make it the slightest bit harder to implement?

How appropriate. You fight like a cow.
Advertisement
It is async. D3D can buffer several frames worth of data, if your code is faster than your GPU. This would never happen if it didn''t return without finishing. All of D3D is async.

Also, D3D doesn''t just buffer until EndScene(). It buffers data, but also renders when there are more than a few vertices to process. EndScene will flush the buffers, but it''s not the only thing that starts rendering to occur. The benefit of a GPU is parallelism, which is lost if you just buffer everything, and then do a syncronous call at the end.

There is a cap entry for no 2d while doing 3d. On such a card, no 2d can be performed between begin and end. This makes debugging difficult, as it will use the 2D acceleration of GDI. New cards don''t have such limitations.

Now, having written this, I think I''ve tracked down a mysterious, occasional visual glitch I get when using dynamic buffers... Since I present, then endscene, I''m not flushing properly. This occurs so rarely it''s been a nightmare to try and track it down, but I think you just made something click! I''ll have to check into this at work in the morning. Thank you noobs!
I suppose if all of Direct 3D was asynchronus it wouldn''t be harder... but doesn''t this slow it down a bit? Or did they pull a MMOJ (Mad Microsoft Optimization Job)
OpenGL Revolutions http://students.hightechhigh.org/~jjensen/
The quick overview of how D3D works... kinda sorta off topic, but the previous post kinda sorta asked...

Basically all state changes, and render calls are stuffed into a queue. Rendering begins when a) the queue reaches a minimum size, b) a resource in the queue is requested by the app, or c) end scene flushes it.

Locking a resource that is in the queue, such as a VB, or surface, will wait until the resource is no longer in the queue, then return with the resource locked. These are the stalls nVidia and Microsoft talk about and plead you to try to avoid. This is why you''re not supposed to lock a static VB, or lock a texture.

The stuffing into a queue happens syncronously, but the actual rendering is async, happening when the hardware gets to that part of the queue. Switching render targets, rendering primitives, setting texture, render and sampler states, doing present, etc, are all stuffed onto a queue.

Even though the CPU just places things on a queue and returns quickly, the total time to draw a scene can be affected by HOW you place things on the queue. The GPU can draw something else pretty quickly after finishing a previous draw call, providing you don''t change anything between the two calls to draw. Changing states takes a bit more time for the GPU to process (1 state or 20 doesn''t matter, changing states causes a slight GPU stall). Changing textures, render targets, and shaders take a lot longer for the GPU to process.

This is why you''re told to sort by texture, and effect, and why CPU profiling doesn''t show a problem with ignoring this advice... the CPU just queues. The GPU is doing the work, incurring the stall. Because rendering is async, your CPU profiler doesn''t show it at all.

Also, certain drivers limit the number of queued frames (often to 3 frames). Trying to place more data in the queue will stall the CPU until the GPU catches up. In this case you''ll see a large percentage of time spent in Present. This doesn''t really mean Present is taking a long time, it just means that you''re GPU is saturated... you could add more AI, physics, etc, and not affect the frame rate in the slightest.

This topic is closed to new replies.

Advertisement