On Tue, May 02, 2017 at 11:52:07AM +0100, Daniel Stone wrote: > Atomic does not let us have multiple requests in flight at once; if we > don't synchronise with the request completion on the CPU side, we can > get -EBUSY from the atomic commit. > > We already have everything required to do this, namely the out-fence > from the last commit. Block on that with a CPU-side wait before we call > atomic commit, to make sure we'll never attempt to queue an atomic > commit before the previous one has completed. > > Signed-off-by: Daniel Stone <[email protected]> > --- > common.c | 1 + > common.h | 1 + > drm-atomic.c | 21 ++++++++++++++++++++- > 3 files changed, 22 insertions(+), 1 deletion(-) > > diff --git a/common.c b/common.c > index bf2f78e..a2cf630 100644 > --- a/common.c > +++ b/common.c > @@ -155,6 +155,7 @@ int init_egl(struct egl *egl, const struct gbm *gbm) > get_proc_dpy(eglCreateSyncKHR, "EGL_KHR_fence_sync"); > get_proc_dpy(eglDestroySyncKHR, "EGL_KHR_fence_sync"); > get_proc_dpy(eglWaitSyncKHR, "EGL_KHR_fence_sync"); > + get_proc_dpy(eglClientWaitSyncKHR, "EGL_KHR_fence_sync"); > get_proc_dpy(eglDupNativeFenceFDANDROID, > "EGL_ANDROID_native_fence_sync"); > > printf("Using display %p with EGL version %d.%d\n", > diff --git a/common.h b/common.h > index 639bd87..0acf4c0 100644 > --- a/common.h > +++ b/common.h > @@ -79,6 +79,7 @@ struct egl { > PFNEGLCREATESYNCKHRPROC eglCreateSyncKHR; > PFNEGLDESTROYSYNCKHRPROC eglDestroySyncKHR; > PFNEGLWAITSYNCKHRPROC eglWaitSyncKHR; > + PFNEGLCLIENTWAITSYNCKHRPROC eglClientWaitSyncKHR; > PFNEGLDUPNATIVEFENCEFDANDROIDPROC eglDupNativeFenceFDANDROID; > > void (*draw)(unsigned i); > diff --git a/drm-atomic.c b/drm-atomic.c > index 0f3c4f2..65caacd 100644 > --- a/drm-atomic.c > +++ b/drm-atomic.c > @@ -210,6 +210,7 @@ static int atomic_run(const struct gbm *gbm, const struct > egl *egl) > > if (drm.kms_out_fence_fd != -1) { > kms_fence = create_fence(egl, drm.kms_out_fence_fd); > + assert(kms_fence); > > /* driver now has ownership of the fence fd: */ > drm.kms_out_fence_fd = -1; > @@ -220,7 +221,6 @@ static int atomic_run(const struct gbm *gbm, const struct > egl *egl) > * the buffer that is still on screen. > */ > egl->eglWaitSyncKHR(egl->display, kms_fence, 0); > - egl->eglDestroySyncKHR(egl->display, kms_fence); > } > > egl->draw(i++); > @@ -229,6 +229,7 @@ static int atomic_run(const struct gbm *gbm, const struct > egl *egl) > * signaled when gpu rendering done > */ > gpu_fence = create_fence(egl, EGL_NO_NATIVE_FENCE_FD_ANDROID); > + assert(gpu_fence); > > eglSwapBuffers(egl->display, egl->surface); > > @@ -246,6 +247,24 @@ static int atomic_run(const struct gbm *gbm, const > struct egl *egl) > return -1; > } > > + if (kms_fence) { > + EGLint status; > + > + /* Wait on the CPU side for the _previous_ commit to > + * complete before we post the flip through KMS, as > + * atomic will reject the commit if we post a new one > + * whilst the previous one is still pending. > + */ > + do { > + status = egl->eglClientWaitSyncKHR(egl->display, > + kms_fence, > + 0, > + > EGL_FOREVER_KHR); > + } while (status != EGL_CONDITION_SATISFIED_KHR); > + > + egl->eglDestroySyncKHR(egl->display, kms_fence);
Would it be an interesting exercise to use that as the in-fence for the GPU? Not sure which is more in the spirit of kmscube. -Chris -- Chris Wilson, Intel Open Source Technology Centre _______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
