[Mesa-dev] [PATCH] i965: Throttle rendering to an fbo

Chris Wilson chris at chris-wilson.co.uk
Wed Mar 4 10:57:45 PST 2015


On Wed, Mar 04, 2015 at 10:28:16AM -0800, Chad Versace wrote:
> On 03/04/2015 09:52 AM, Chris Wilson wrote:
> > The manpage for glFlush says
> > 
> > "glFlush can return at any time.  It does not wait until the execution of *all*
> > previously issued GL commands is complete."
> > 
> > Emphasis mine. In double buffered, and normal frontbuffered (non-fbo),
> > rendering the throttle is a no-op as there will not be any old rendering
> > to wait upon.
> 
> That text does not appear in the GL spec. When I read the manpage alongside
> the GL spec, to get a more complete context, I think the manpage contains
> that phrase simply to contrast with glFinish. In my reading, it does not imply that
> glFlush may wait for *some* previously issued GL commands to complete.
> 
> As usual, the GL spec is too terse and too vague. So I quote Apple's GL documentation [1].
> I believe it correctly explains the behavior of glFlush.
> 
>     Q:  What's the difference between glFlush() and glFinish()?
> 
>     A: [...] glFlush() causes all OpenGL commands currently queued to be submitted to
>        the hardware for execution. This function returns immediately after having
>        transferred the pending OpenGL command queue to the hardware (or software)
>        renderer. These commands are queued for execution in some finite amount of time,
>        but glFlush() does not block waiting for command completion.
> 
> [1] https://developer.apple.com/library/mac/qa/qa1158/_index.html
> 
> 
> 
> And I don't agree that the throttle is a no-op in double-buffered rendering. Consider
> the following calls:
> 
>   0 // Setup the draw.
>   1 glDraw();
>   2 eglSwapBuffers(); --> internally calls glFlush
>   3 // Setup the draw
>   4 glDraw();
>   5 eglSwapBuffers(); --> internally calls glFlush
>   6 // Setup the draw
>   7 glDraw();
>   8 eglSwapBuffers(); --> internally calls glFlush
> 
> Before your patch, call 5 returns immediately, even if draw 1 has not
> completed, allowing the app to proceed to the CPU actions in line 6.
> If the app calls eglSwapBuffers too frequently, then call 8 will block
> as needed (assuming EGL_SWAP_INTERVAL != 0 and double-buffering).

Today steps 3, 6, 9... block due to brw->need_throttle
(intel_prepare_render can occur before a draw operation). If double
buffering and swap-interval!=0, then step 2 (naively, for us it would
be step 3) would block. If triple buffering step 5/6, except for the
brw->need_throttle already causing throttling.
 
> After your patch, call 5 may block, throttling on batches that may have been
> submitted during the setup in lines 3 and 4. (The glDraw at 4 may submit batches for
> resolve operations, for example). That prevents the app from proceeding
> to whatever CPU actions are planned for line 6. Double-buffered eglSwapBuffers now
> sometimes blocks, behaving like an almost-glFinish, even when the back buffer is
> free for rendering.

No, actually it won't block in that situation. It only waits for
rendering older than 20ms to complete, which given that your back buffer
is free for rendering must have already completed.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


More information about the mesa-dev mailing list