X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fstate_tracker%2Fst_cb_flush.c;h=1329f807bc9a43a81e53992478bf2b9a8df48ddd;hb=f67bc2e87255298ac22e8ccd98f482cc62d0ec26;hp=f8621ab125fbd37df70a1bb10ac28ba3073d0bef;hpb=59edbc70cd1042a884e7d153ba547c2f7f87318d;p=mesa.git diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c index f8621ab125f..1329f807bc9 100644 --- a/src/mesa/state_tracker/st_cb_flush.c +++ b/src/mesa/state_tracker/st_cb_flush.c @@ -47,10 +47,19 @@ #include "util/u_blit.h" +/** Check if we have a front color buffer and if it's been drawn to. */ static INLINE GLboolean is_front_buffer_dirty(struct st_context *st) { - return st->frontbuffer_status == FRONT_STATUS_DIRTY; + if (st->frontbuffer_status == FRONT_STATUS_DIRTY) { + return GL_TRUE; + } + else { + GLframebuffer *fb = st->ctx->DrawBuffer; + struct st_renderbuffer *strb + = st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + return strb && strb->defined; + } } @@ -63,23 +72,26 @@ display_front_buffer(struct st_context *st) GLframebuffer *fb = st->ctx->DrawBuffer; struct st_renderbuffer *strb = st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); - struct pipe_surface *front_surf = strb->surface; - /* Hook for copying "fake" frontbuffer if necessary: - */ - st->pipe->screen->flush_frontbuffer( st->pipe->screen, front_surf, - st->pipe->priv ); - - /* - st->frontbuffer_status = FRONT_STATUS_UNDEFINED; - */ + if (strb) { + struct pipe_surface *front_surf = strb->surface; + + /* Hook for copying "fake" frontbuffer if necessary: + */ + st->pipe->screen->flush_frontbuffer( st->pipe->screen, front_surf, + st->pipe->priv ); + + /* + st->frontbuffer_status = FRONT_STATUS_UNDEFINED; + */ + } } void st_flush( struct st_context *st, uint pipeFlushFlags, struct pipe_fence_handle **fence ) { - FLUSH_VERTICES(st->ctx, 0); + FLUSH_CURRENT(st->ctx, 0); /* Release any vertex buffers that might potentially be accessed in * successive frames: @@ -117,13 +129,16 @@ static void st_glFlush(GLcontext *ctx) { struct st_context *st = ctx->st; + /* Don't call st_finish() here. It is not the state tracker's + * responsibilty to inject sleeps in the hope of avoiding buffer + * synchronization issues. Calling finish() here will just hide + * problems that need to be fixed elsewhere. + */ + st_flush(st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); + if (is_front_buffer_dirty(st)) { - st_finish(st); display_front_buffer(st); } - else { - st_flush(st, PIPE_FLUSH_RENDER_CACHE, NULL); - } } @@ -146,4 +161,16 @@ void st_init_flush_functions(struct dd_function_table *functions) { functions->Flush = st_glFlush; functions->Finish = st_glFinish; + + /* Windows opengl32.dll calls glFinish prior to every swapbuffers. + * This is unnecessary and degrades performance. Luckily we have some + * scope to work around this, as the externally-visible behaviour of + * Finish() is identical to Flush() in all cases - no differences in + * rendering or ReadPixels are visible if we opt not to wait here. + * + * Only set this up on windows to avoid suprise elsewhere. + */ +#ifdef PIPE_OS_WINDOWS + functions->Finish = st_glFlush; +#endif }