Re: [Mesa-dev] [PATCH RFC 1/2] dri: Let drivers reset the damage region

2019-08-29 Thread Boris Brezillon
On Thu, 29 Aug 2019 13:54:15 +0200
Boris Brezillon  wrote:

> dri2_set_damage_region() must call st_validate_state(UPDATE_FRAMEBUFFER)
> to make sure the BACK_LEFT attachment is up-to-date.
> Problem is, dri2_swap_buffers_xxx() functions are actually targeting
> the old backbuffer when they call ->set_damage_region(0, NULL), and
> more importantly, they are not expecting the caller to pull a new back
> buffer at this point, which will happen if st_validate_state() is
> called.
> 
> Let's delegate the damage region reset to drivers (they should take
> care of that at flush/swap time) so we don't have to deal with this
> extra complexity at the EGL level.
> 
> The only gallium driver implementing ->set_damage_region() is patched
> accordingly.
> 
> Signed-off-by: Boris Brezillon 
> ---
>  include/GL/internal/dri_interface.h |  4 
>  src/egl/drivers/dri2/egl_dri2.c | 24 -
>  src/gallium/drivers/panfrost/pan_context.c  | 14 +++-
>  src/gallium/drivers/panfrost/pan_resource.c |  2 +-
>  src/gallium/drivers/panfrost/pan_resource.h |  2 ++
>  5 files changed, 20 insertions(+), 26 deletions(-)
> 
> diff --git a/include/GL/internal/dri_interface.h 
> b/include/GL/internal/dri_interface.h
> index 4b5583820ed0..4c60d349ddd5 100644
> --- a/include/GL/internal/dri_interface.h
> +++ b/include/GL/internal/dri_interface.h
> @@ -521,6 +521,10 @@ struct __DRI2bufferDamageExtensionRec {
>  * reset the region, followed by a second call with a populated region,
>  * before a rendering call is made.
>  *
> +* Drivers implementing this entrypoint should take care of resetting the
> +* damage region of resources being written to at swapbuffer/flush time.
> +* The DRI core will not automate that for you.
> +*
>  * Used to implement EGL_KHR_partial_update.
>  *
>  * \param drawable affected drawable
> diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
> index 526cb1969c18..ea8ae5d44c56 100644
> --- a/src/egl/drivers/dri2/egl_dri2.c
> +++ b/src/egl/drivers/dri2/egl_dri2.c
> @@ -1767,7 +1767,6 @@ static EGLBoolean
>  dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
>  {
> struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
> -   __DRIdrawable *dri_drawable = dri2_dpy->vtbl->get_dri_drawable(surf);
> _EGLContext *ctx = _eglGetCurrentContext();
> EGLBoolean ret;
>  
> @@ -1775,13 +1774,6 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, 
> _EGLSurface *surf)
>dri2_surf_update_fence_fd(ctx, disp, surf);
> ret = dri2_dpy->vtbl->swap_buffers(drv, disp, surf);
>  
> -   /* SwapBuffers marks the end of the frame; reset the damage region for
> -* use again next time.
> -*/
> -   if (ret && dri2_dpy->buffer_damage &&
> -   dri2_dpy->buffer_damage->set_damage_region)
> -  dri2_dpy->buffer_damage->set_damage_region(dri_drawable, 0, NULL);
> -
> return ret;
>  }
>  
> @@ -1791,7 +1783,6 @@ dri2_swap_buffers_with_damage(_EGLDriver *drv, 
> _EGLDisplay *disp,
>const EGLint *rects, EGLint n_rects)
>  {
> struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
> -   __DRIdrawable *dri_drawable = dri2_dpy->vtbl->get_dri_drawable(surf);
> _EGLContext *ctx = _eglGetCurrentContext();
> EGLBoolean ret;
>  
> @@ -1800,13 +1791,6 @@ dri2_swap_buffers_with_damage(_EGLDriver *drv, 
> _EGLDisplay *disp,
> ret = dri2_dpy->vtbl->swap_buffers_with_damage(drv, disp, surf,
>rects, n_rects);
>  
> -   /* SwapBuffers marks the end of the frame; reset the damage region for
> -* use again next time.
> -*/
> -   if (ret && dri2_dpy->buffer_damage &&
> -   dri2_dpy->buffer_damage->set_damage_region)
> -  dri2_dpy->buffer_damage->set_damage_region(dri_drawable, 0, NULL);
> -
> return ret;
>  }
>  
> @@ -1815,18 +1799,10 @@ dri2_swap_buffers_region(_EGLDriver *drv, _EGLDisplay 
> *disp, _EGLSurface *surf,
>   EGLint numRects, const EGLint *rects)
>  {
> struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
> -   __DRIdrawable *dri_drawable = dri2_dpy->vtbl->get_dri_drawable(surf);
> EGLBoolean ret;
>  
> ret = dri2_dpy->vtbl->swap_buffers_region(drv, disp, surf, numRects, 
> rects);
>  
> -   /* SwapBuffers marks the end of the frame; reset the damage region for
> -* use again next time.
> -*/
> -   if (ret && dri2_dpy->buffer_damage &&
> -   dri2_dpy->buffer_damage->set_damage_region)
> -  dri2_dpy->buffer_damage->set_damage_region(dri_drawable, 0, NULL);
> -
> return ret;
>  }
>  
> diff --git a/src/gallium/drivers/panfrost/pan_context.c 
> b/src/gallium/drivers/panfrost/pan_context.c
> index fa9c92af9f6a..4069ec238fe4 100644
> --- a/src/gallium/drivers/panfrost/pan_context.c
> +++ b/src/gallium/drivers/panfrost/pan_context.c
> @@ -1461,7 +1461,8 @@ panfrost_flush(
>  struct panfr

[Mesa-dev] [PATCH RFC 1/2] dri: Let drivers reset the damage region

2019-08-29 Thread Boris Brezillon
dri2_set_damage_region() must call st_validate_state(UPDATE_FRAMEBUFFER)
to make sure the BACK_LEFT attachment is up-to-date.
Problem is, dri2_swap_buffers_xxx() functions are actually targeting
the old backbuffer when they call ->set_damage_region(0, NULL), and
more importantly, they are not expecting the caller to pull a new back
buffer at this point, which will happen if st_validate_state() is
called.

Let's delegate the damage region reset to drivers (they should take
care of that at flush/swap time) so we don't have to deal with this
extra complexity at the EGL level.

The only gallium driver implementing ->set_damage_region() is patched
accordingly.

Signed-off-by: Boris Brezillon 
---
 include/GL/internal/dri_interface.h |  4 
 src/egl/drivers/dri2/egl_dri2.c | 24 -
 src/gallium/drivers/panfrost/pan_context.c  | 14 +++-
 src/gallium/drivers/panfrost/pan_resource.c |  2 +-
 src/gallium/drivers/panfrost/pan_resource.h |  2 ++
 5 files changed, 20 insertions(+), 26 deletions(-)

diff --git a/include/GL/internal/dri_interface.h 
b/include/GL/internal/dri_interface.h
index 4b5583820ed0..4c60d349ddd5 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -521,6 +521,10 @@ struct __DRI2bufferDamageExtensionRec {
 * reset the region, followed by a second call with a populated region,
 * before a rendering call is made.
 *
+* Drivers implementing this entrypoint should take care of resetting the
+* damage region of resources being written to at swapbuffer/flush time.
+* The DRI core will not automate that for you.
+*
 * Used to implement EGL_KHR_partial_update.
 *
 * \param drawable affected drawable
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 526cb1969c18..ea8ae5d44c56 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -1767,7 +1767,6 @@ static EGLBoolean
 dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
 {
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
-   __DRIdrawable *dri_drawable = dri2_dpy->vtbl->get_dri_drawable(surf);
_EGLContext *ctx = _eglGetCurrentContext();
EGLBoolean ret;
 
@@ -1775,13 +1774,6 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, 
_EGLSurface *surf)
   dri2_surf_update_fence_fd(ctx, disp, surf);
ret = dri2_dpy->vtbl->swap_buffers(drv, disp, surf);
 
-   /* SwapBuffers marks the end of the frame; reset the damage region for
-* use again next time.
-*/
-   if (ret && dri2_dpy->buffer_damage &&
-   dri2_dpy->buffer_damage->set_damage_region)
-  dri2_dpy->buffer_damage->set_damage_region(dri_drawable, 0, NULL);
-
return ret;
 }
 
@@ -1791,7 +1783,6 @@ dri2_swap_buffers_with_damage(_EGLDriver *drv, 
_EGLDisplay *disp,
   const EGLint *rects, EGLint n_rects)
 {
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
-   __DRIdrawable *dri_drawable = dri2_dpy->vtbl->get_dri_drawable(surf);
_EGLContext *ctx = _eglGetCurrentContext();
EGLBoolean ret;
 
@@ -1800,13 +1791,6 @@ dri2_swap_buffers_with_damage(_EGLDriver *drv, 
_EGLDisplay *disp,
ret = dri2_dpy->vtbl->swap_buffers_with_damage(drv, disp, surf,
   rects, n_rects);
 
-   /* SwapBuffers marks the end of the frame; reset the damage region for
-* use again next time.
-*/
-   if (ret && dri2_dpy->buffer_damage &&
-   dri2_dpy->buffer_damage->set_damage_region)
-  dri2_dpy->buffer_damage->set_damage_region(dri_drawable, 0, NULL);
-
return ret;
 }
 
@@ -1815,18 +1799,10 @@ dri2_swap_buffers_region(_EGLDriver *drv, _EGLDisplay 
*disp, _EGLSurface *surf,
  EGLint numRects, const EGLint *rects)
 {
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
-   __DRIdrawable *dri_drawable = dri2_dpy->vtbl->get_dri_drawable(surf);
EGLBoolean ret;
 
ret = dri2_dpy->vtbl->swap_buffers_region(drv, disp, surf, numRects, rects);
 
-   /* SwapBuffers marks the end of the frame; reset the damage region for
-* use again next time.
-*/
-   if (ret && dri2_dpy->buffer_damage &&
-   dri2_dpy->buffer_damage->set_damage_region)
-  dri2_dpy->buffer_damage->set_damage_region(dri_drawable, 0, NULL);
-
return ret;
 }
 
diff --git a/src/gallium/drivers/panfrost/pan_context.c 
b/src/gallium/drivers/panfrost/pan_context.c
index fa9c92af9f6a..4069ec238fe4 100644
--- a/src/gallium/drivers/panfrost/pan_context.c
+++ b/src/gallium/drivers/panfrost/pan_context.c
@@ -1461,7 +1461,8 @@ panfrost_flush(
 struct panfrost_job *job = panfrost_get_job_for_fbo(ctx);
 
 /* Nothing to do! */
-if (!job->last_job.gpu && !job->clear) return;
+if (!job->last_job.gpu && !job->clear)
+goto reset_damage;
 
 if (!job->clear && job->last_tiler.gpu)
 panfrost_draw