diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index eed7d06766a..6562db4eade 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -1638,18 +1638,18 @@ zink_flush(struct pipe_context *pctx, zink_fence_reference(zink_screen(pctx->screen), (struct zink_fence **)pfence, batch->fence); - /* HACK: - * For some strange reason, we need to finish before presenting, or else - * we start rendering on top of the back-buffer for the next frame. This - * seems like a bug in the DRI-driver to me, because we really should - * be properly protected by fences here, and the back-buffer should - * either be swapped with the front-buffer, or blitted from. But for - * some strange reason, neither of these things happen. - */ - if (flags & PIPE_FLUSH_END_OF_FRAME) - pctx->screen->fence_finish(pctx->screen, pctx, - (struct pipe_fence_handle *)batch->fence, - PIPE_TIMEOUT_INFINITE); + + if (flags & PIPE_FLUSH_END_OF_FRAME) { + /* if the first frame has not yet occurred, we need an explicit fence here + * in some cases in order to correctly draw the first frame, though it's + * unknown at this time why this is the case + */ + if (!ctx->first_frame_done) + pctx->screen->fence_finish(pctx->screen, pctx, + (struct pipe_fence_handle *)batch->fence, + PIPE_TIMEOUT_INFINITE); + ctx->first_frame_done = true; + } } void diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h index 5db1b421f5c..d4d770f1581 100644 --- a/src/gallium/drivers/zink/zink_context.h +++ b/src/gallium/drivers/zink/zink_context.h @@ -214,6 +214,7 @@ struct zink_context { struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_OUTPUTS]; bool dirty_so_targets; bool xfb_barrier; + bool first_frame_done; }; static inline struct zink_context *