X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fstate_tracker%2Fst_cb_flush.c;h=5a2343d3aec30991a542c783dff0aebce9200144;hb=3f9e78ac390a095d42f94b8edc02016f18b255dd;hp=d8f9537d2de63e5ed7ac66420d39b88d879f4b38;hpb=7468765b18be202a64d58b83f6267b6973ea4897;p=mesa.git diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c index d8f9537d2de..5a2343d3aec 100644 --- a/src/mesa/state_tracker/st_cb_flush.c +++ b/src/mesa/state_tracker/st_cb_flush.c @@ -37,48 +37,57 @@ #include "st_context.h" #include "st_cb_bitmap.h" #include "st_cb_flush.h" +#include "st_cb_clear.h" #include "st_cb_fbo.h" -#include "st_public.h" +#include "st_manager.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_winsys.h" +#include "pipe/p_screen.h" +#include "util/u_gen_mipmap.h" +#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; + struct gl_framebuffer *fb = st->ctx->DrawBuffer; + struct st_renderbuffer *strb + = st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + return strb && strb->defined; } /** - * Tell the winsys to display the front color buffer on-screen. + * Tell the screen to display the front color buffer on-screen. */ static void display_front_buffer(struct st_context *st) { - GLframebuffer *fb = st->ctx->DrawBuffer; + struct gl_framebuffer *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->winsys->flush_frontbuffer( st->pipe->winsys, front_surf, - st->pipe->priv ); - /* - st->frontbuffer_status = FRONT_STATUS_UNDEFINED; - */ + if (strb) { + /* Hook for copying "fake" frontbuffer if necessary: + */ + st_manager_flush_frontbuffer(st); + } } void st_flush( struct st_context *st, uint pipeFlushFlags, struct pipe_fence_handle **fence ) { - FLUSH_VERTICES(st->ctx, 0); + FLUSH_CURRENT(st->ctx, 0); - st_flush_bitmap_cache(st); + /* Release any vertex buffers that might potentially be accessed in + * successive frames: + */ + st_flush_bitmap(st); + st_flush_clear(st); + util_blit_flush(st->blit); + util_gen_mipmap_flush(st->gen_mipmap); st->pipe->flush( st->pipe, pipeFlushFlags, fence ); } @@ -93,8 +102,10 @@ void st_finish( struct st_context *st ) st_flush(st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, &fence); - st->pipe->winsys->fence_finish(st->pipe->winsys, fence, 0); - st->pipe->winsys->fence_reference(st->pipe->winsys, &fence, NULL); + if(fence) { + st->pipe->screen->fence_finish(st->pipe->screen, fence, 0); + st->pipe->screen->fence_reference(st->pipe->screen, &fence, NULL); + } } @@ -102,26 +113,29 @@ void st_finish( struct st_context *st ) /** * Called via ctx->Driver.Flush() */ -static void st_glFlush(GLcontext *ctx) +static void st_glFlush(struct gl_context *ctx) { - struct st_context *st = ctx->st; + struct st_context *st = st_context(ctx); + + /* 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); - } } /** * Called via ctx->Driver.Finish() */ -static void st_glFinish(GLcontext *ctx) +static void st_glFinish(struct gl_context *ctx) { - struct st_context *st = ctx->st; + struct st_context *st = st_context(ctx); st_finish(st); @@ -135,4 +149,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 }