Mesa (master): i965: Resolve framebuffers before signaling the fence

Chris Wilson ickle at kemper.freedesktop.org
Tue Jul 11 14:48:27 UTC 2017


Module: Mesa
Branch: master
Commit: 618be8cc1ad1760103930b69ffbf528d7b861ab3
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=618be8cc1ad1760103930b69ffbf528d7b861ab3

Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jun 12 15:17:20 2017 +0100

i965: Resolve framebuffers before signaling the fence

>From KHR_fence_sync:

  When the condition of the sync object is satisfied by the fence
  command, the sync is signaled by the associated client API context,
  causing any eglClientWaitSyncKHR commands (see below) blocking on
  <sync> to unblock. The only condition currently supported is
  EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR, which is satisfied by
  completion of the fence command corresponding to the sync object,
  and all preceding commands in the associated client API context's
  command stream. The sync object will not be signaled until all
  effects from these commands on the client API's internal and
  framebuffer state are fully realized. No other state is affected by
  execution of the fence command.

If clients are passing the fence fd (from EGL_ANDROID_native_fence_sync)
to a compositor, that fence must only be signaled once the framebuffer
is resolved and not before as is currently the case.

v2: fixup assert to use GL_SYNC_GPU_COMMANDS_COMPLETE (Chad)

Reported-by: Sergi Granell <xerpi.g.12 at gmail.com>
Fixes: c636284ee8ee ("i965/sync: Implement DRI2_Fence extension")
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Sergi Granell <xerpi.g.12 at gmail.com>
Cc: Rob Clark <robdclark at gmail.com>
Cc: Chad Versace <chadversary at chromium.org>
Cc: Daniel Stone <daniels at collabora.com>
Cc: Kenneth Graunke <kenneth at whitecape.org>
Reviewed-by: Chad Versace <chadversary at chromium.org>

---

 src/mesa/drivers/dri/i965/brw_sync.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_sync.c b/src/mesa/drivers/dri/i965/brw_sync.c
index a8356c304f..edfb1881bc 100644
--- a/src/mesa/drivers/dri/i965/brw_sync.c
+++ b/src/mesa/drivers/dri/i965/brw_sync.c
@@ -110,6 +110,35 @@ brw_fence_finish(struct brw_fence *fence)
 static bool MUST_CHECK
 brw_fence_insert_locked(struct brw_context *brw, struct brw_fence *fence)
 {
+   __DRIcontext *driContext = brw->driContext;
+   __DRIdrawable *driDrawable = driContext->driDrawablePriv;
+
+   /*
+    * From KHR_fence_sync:
+    *
+    *   When the condition of the sync object is satisfied by the fence
+    *   command, the sync is signaled by the associated client API context,
+    *   causing any eglClientWaitSyncKHR commands (see below) blocking on
+    *   <sync> to unblock. The only condition currently supported is
+    *   EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR, which is satisfied by
+    *   completion of the fence command corresponding to the sync object,
+    *   and all preceding commands in the associated client API context's
+    *   command stream. The sync object will not be signaled until all
+    *   effects from these commands on the client API's internal and
+    *   framebuffer state are fully realized. No other state is affected by
+    *   execution of the fence command.
+    *
+    * Note the emphasis there on ensuring that the framebuffer is fully
+    * realised before the fence is signaled. We cannot just flush the batch,
+    * but must also resolve the drawable first. The importance of this is,
+    * for example, in creating a fence for a frame to be passed to a
+    * remote compositor. Without us flushing the drawable explicitly, the
+    * resolve will be in a following batch (when the client finally calls
+    * SwapBuffers, or triggers a resolve via some other path) and so the
+    * compositor may read the incomplete framebuffer instead.
+    */
+   if (driDrawable)
+      intel_resolve_for_dri2_flush(brw, driDrawable);
    brw_emit_mi_flush(brw);
 
    switch (fence->type) {
@@ -335,6 +364,9 @@ brw_gl_fence_sync(struct gl_context *ctx, struct gl_sync_object *_sync,
    struct brw_context *brw = brw_context(ctx);
    struct brw_gl_sync *sync = (struct brw_gl_sync *) _sync;
 
+   /* brw_fence_insert_locked() assumes it must do a complete flush */
+   assert(condition == GL_SYNC_GPU_COMMANDS_COMPLETE);
+
    brw_fence_init(brw, &sync->fence, BRW_FENCE_TYPE_BO_WAIT);
 
    if (!brw_fence_insert_locked(brw, &sync->fence)) {




More information about the mesa-commit mailing list