diff --git a/src/gallium/frontends/wgl/stw_context.c b/src/gallium/frontends/wgl/stw_context.c index 57dd85c382d..91861cd42e9 100644 --- a/src/gallium/frontends/wgl/stw_context.c +++ b/src/gallium/frontends/wgl/stw_context.c @@ -446,13 +446,11 @@ stw_make_current(HDC hDrawDC, HDC hReadDC, DHGLRC dhglrc) } } else { if (old_ctx->shared) { - struct pipe_fence_handle *fence = NULL; - old_ctx->st->flush(old_ctx->st, - ST_FLUSH_FRONT | ST_FLUSH_WAIT, &fence, - NULL, NULL); - } - else { - old_ctx->st->flush(old_ctx->st, ST_FLUSH_FRONT, NULL, NULL, NULL); + stw_st_flush(old_ctx->st, old_ctx->current_framebuffer->stfb, + ST_FLUSH_FRONT | ST_FLUSH_WAIT); + } else { + stw_st_flush(old_ctx->st, old_ctx->current_framebuffer->stfb, + ST_FLUSH_FRONT); } } } diff --git a/src/gallium/frontends/wgl/stw_framebuffer.c b/src/gallium/frontends/wgl/stw_framebuffer.c index 8a213f6de35..f5260989478 100644 --- a/src/gallium/frontends/wgl/stw_framebuffer.c +++ b/src/gallium/frontends/wgl/stw_framebuffer.c @@ -665,7 +665,7 @@ DrvSwapBuffers(HDC hdc) if (ctx->current_framebuffer == fb) { /* flush current context */ - ctx->st->flush(ctx->st, ST_FLUSH_END_OF_FRAME, NULL, NULL, NULL); + stw_st_flush(ctx->st, fb->stfb, ST_FLUSH_END_OF_FRAME); } } diff --git a/src/gallium/frontends/wgl/stw_st.c b/src/gallium/frontends/wgl/stw_st.c index ca885d182fc..b640e0b6ebe 100644 --- a/src/gallium/frontends/wgl/stw_st.c +++ b/src/gallium/frontends/wgl/stw_st.c @@ -205,6 +205,9 @@ stw_pipe_blit(struct pipe_context *pipe, { struct pipe_blit_info blit; + if (!dst || !src) + return; + /* From the GL spec, version 4.2, section 4.1.11 (Additional Multisample * Fragment Operations): * @@ -243,6 +246,48 @@ stw_pipe_blit(struct pipe_context *pipe, pipe->blit(pipe, &blit); } +struct notify_before_flush_cb_args { + struct st_context_iface *stctx; + struct stw_st_framebuffer *stwfb; + unsigned flags; +}; + +static void +notify_before_flush_cb(void* _args) +{ + struct notify_before_flush_cb_args *args = (struct notify_before_flush_cb_args *) _args; + struct st_context_iface *st = args->stctx; + struct pipe_context *pipe = st->pipe; + + if (args->stwfb->stvis.samples > 1) { + /* Resolve the MSAA back buffer. */ + stw_pipe_blit(pipe, + args->stwfb->textures[ST_ATTACHMENT_BACK_LEFT], + args->stwfb->msaa_textures[ST_ATTACHMENT_BACK_LEFT]); + + /* FRONT_LEFT is resolved in flush_frontbuffer. */ + } +} + +void +stw_st_flush(struct st_context_iface *stctx, + struct st_framebuffer_iface *stfb, + unsigned flags) +{ + struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb); + struct notify_before_flush_cb_args args; + struct pipe_fence_handle **pfence = NULL; + struct pipe_fence_handle *fence = NULL; + + args.stctx = stctx; + args.stwfb = stwfb; + args.flags = flags; + + if (flags & ST_FLUSH_WAIT) + pfence = &fence; + stctx->flush(stctx, flags, pfence, notify_before_flush_cb, &args); +} + /** * Present an attachment of the framebuffer. */ @@ -257,12 +302,6 @@ stw_st_framebuffer_present_locked(HDC hdc, assert(stw_own_mutex(&stwfb->fb->mutex)); - if (stwfb->stvis.samples > 1) { - stw_pipe_blit(stctx->pipe, - stwfb->textures[statt], - stwfb->msaa_textures[statt]); - } - resource = stwfb->textures[statt]; if (resource) { stw_framebuffer_present_locked(hdc, stwfb->fb, resource); @@ -282,11 +321,22 @@ stw_st_framebuffer_flush_front(struct st_context_iface *stctx, enum st_attachment_type statt) { struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb); + struct pipe_context *pipe = stctx->pipe; bool ret; HDC hDC; + if (statt != ST_ATTACHMENT_FRONT_LEFT) + return false; + stw_framebuffer_lock(stwfb->fb); + if (stwfb->stvis.samples > 1) { + /* Resolve the front buffer. */ + stw_pipe_blit(pipe, stwfb->textures[statt], stwfb->msaa_textures[statt]); + } + + pipe->flush(pipe, NULL, 0); + /* We must not cache HDCs anywhere, as they can be invalidated by the * application, or screen resolution changes. */ diff --git a/src/gallium/frontends/wgl/stw_st.h b/src/gallium/frontends/wgl/stw_st.h index 91b8fffc2ce..c4d735663e6 100644 --- a/src/gallium/frontends/wgl/stw_st.h +++ b/src/gallium/frontends/wgl/stw_st.h @@ -46,6 +46,10 @@ stw_st_create_framebuffer(struct stw_framebuffer *fb); void stw_st_destroy_framebuffer_locked(struct st_framebuffer_iface *stfb); +void +stw_st_flush(struct st_context_iface *st, struct st_framebuffer_iface *stfb, + unsigned flags); + bool stw_st_swap_framebuffer_locked(HDC hdc, struct st_context_iface *stctx, struct st_framebuffer_iface *stfb);