On Wed, 29 Oct 2003 08:56:09 -0800 Ian Romanick <[EMAIL PROTECTED]> wrote:
Felix Kühling wrote:
I've been thinking about ways to implement a combined "wait for vblank and buffer swap" operation. But somehow I can't get the pieces together partly because I have a pretty vague understanding what the hardware does or can do on a low level.
I've thought about this problem a few times myself. I haven't done any work (or even proposed any work to do) yet because there are a lot of subtle issues. It turns out to be a hard problem.
The main problem I wanted to solve was having an application sleep while waiting for the swap interval to complete. If the swap interval is 8, the application could sleep for 7.9 vertical blanks. We want to return to the application ASAP so that they can do other work (i.e., physics, AI, etc.).
[snip]
The 3D engine finishes rendering a frame. Then it generates an interrupt. At this point the engine has to suspend _somehow_ until the buffer swap has completed. The kernel waits for the software interrupt. If the deadline for the frame has passed it executes a buffer swap immediately. Otherwise it also waits for a specified vblank interrupt and then executes the buffer swap. When the swap is completed it _somehow_ makes the 3D engine resume executing rendering commands for the next frame.
"_somehow_" marks the places I'm not sure about. Could someone comment on this please? Even if this is all crap, maybe you have a better idea.
There are a bunch of problems with this, some of which Keith pointed out already. Three things are needed:
1. Stop issuing rendering commands to the specific *drawable* until all commands issued before the swap have completed.
2. When the swap interval (or other vsync requirements) have been met, issue the swap.
3. Resume issuing commands.
Note that this must be done per drawable. If an application has 5 windows and 200 pbuffers but only 1 GL context, issuing a swap command on one window should not impact rendering to any of the other drawables. The exception being if SGIX_swap_group is being used. I only mention that because we will want to expose that extension eventually. The Nvidia drivers expose it, and I think a few applications use it.
http://oss.sgi.com/projects/ogl-sample/registry/SGIX/swap_group.txt
I believe that #2 should be implemented as a single ioctl. Each driver will have to implement it in its own way. I'm not sure there's any way to 100% guarantee that a non-pageflipped, non-triple buffered display will be tear-free with multiple processes issuing rendering commands. In other words, there's no way to guarantee latency on the swap. All we can do is make a best effort.
I also believe the #1 and #3 will require a bit of work in the client-side driver. It would need to batch up commands and wait to issue them. The problem is state changes. The driver usually knows the current hardware state before issuing a command. Since commands are just being queued, there's know way to know what the state will be when they are actually issued. The queuing is done per-drawable, but state is tracked per-context. I think that's solvable, but it will take some work.
So you want to do the queueing in user space? The scheduler that Keith and I were talking about would be in the kernel. I guess the user space approach would be easier to implement. The question is how you resume
Buffering the commands in user space avoids having to do state switching in the kernel, which is nice. It should also be faster in the common case.
submitting commands. You can't do it asynchronously while the application is computing physics or AI. But the next GL function call could trigger flushing queued commands.
Right. That shouldn't be a problem, though. If the application is computing physics or AI there won't be any commands to queue. :) I did think of another "problem" case. What happens when the application calls glXSwapBuffers while the previous swap is still pending? I'm guessing that we'd sleep, flush out all the commands (for the whole frame!), then issue the new swap. Queuing texture uploads would be interesting...
Basically, queuing commands while we wait for a swap to complete is like building a display list. Maybe it would be easier to tackle the problem from that point of view? When a swap is pending we'd "somehow" switch to build-display list mode. When the swap completed we'd execute the currently built display list and switch back to immediate mode. Dunno...
------------------------------------------------------- This SF.net email is sponsored by: SF.net Giveback Program. Does SourceForge.net help you be more productive? Does it help you create better code? SHARE THE LOVE, and help us help YOU! Click Here: http://sourceforge.net/donate/ _______________________________________________ Dri-devel mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/dri-devel