[Mesa-dev] [PATCH] drisw/gallium/llvmpipe: add MESA_copy_sub_buffer support (v2)

Jose Fonseca jfonseca at vmware.com
Tue Dec 10 08:33:49 PST 2013


Sorry for the delay.  Thanks for the update. 

Please update the other sw_winsys implementations in src/gallium/winsys/sw too.  I think that updating the prototype and ignoring the new parameter should be fine.

Otherwise looks good.

Jose

----- Original Message -----
> This patches add MESA_copy_sub_buffer support to the dri sw loader and
> then to gallium state tracker, llvmpipe, softpipe and other bits.
> 
> It reuses the dri1 driver extension interface, and it updates the swrast
> loader interface for a new putimage which can take a stride.
> 
> I've tested this with gnome-shell with a cogl hacked to reenable sub copies
> for llvmpipe and the one piglit test.
> 
> I could probably split this patch up as well.
> 
> v2: pass a pipe_box, to reduce the entrypoints, as per Jose's review,
> add to p_screen doc comments.
> 
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
>  include/GL/internal/dri_interface.h                |  9 +++-
>  src/gallium/auxiliary/vl/vl_winsys_dri.c           |  2 +-
>  src/gallium/drivers/galahad/glhd_screen.c          |  5 +-
>  src/gallium/drivers/i915/i915_screen.c             |  4 +-
>  src/gallium/drivers/identity/id_screen.c           |  5 +-
>  src/gallium/drivers/llvmpipe/lp_screen.c           |  6 +--
>  src/gallium/drivers/noop/noop_pipe.c               |  2 +-
>  src/gallium/drivers/rbug/rbug_screen.c             |  4 +-
>  src/gallium/drivers/softpipe/sp_screen.c           |  5 +-
>  src/gallium/drivers/trace/tr_screen.c              |  5 +-
>  src/gallium/include/pipe/p_screen.h                |  7 +--
>  src/gallium/include/state_tracker/drisw_api.h      |  2 +
>  src/gallium/include/state_tracker/sw_winsys.h      |  5 +-
>  src/gallium/state_trackers/dri/sw/drisw.c          | 58
>  ++++++++++++++++++++--
>  .../state_trackers/egl/common/native_helper.c      |  2 +-
>  src/gallium/state_trackers/egl/x11/native_ximage.c |  2 +-
>  src/gallium/state_trackers/glx/xlib/xm_st.c        |  2 +-
>  src/gallium/state_trackers/vdpau/presentation.c    |  2 +-
>  src/gallium/state_trackers/xvmc/surface.c          |  2 +-
>  .../targets/haiku-softpipe/GalliumContext.cpp      |  4 +-
>  src/gallium/tests/graw/clear.c                     |  2 +-
>  src/gallium/tests/graw/fs-test.c                   |  2 +-
>  src/gallium/tests/graw/graw_util.h                 |  2 +-
>  src/gallium/tests/graw/gs-test.c                   |  2 +-
>  src/gallium/tests/graw/quad-sample.c               |  2 +-
>  src/gallium/tests/graw/shader-leak.c               |  2 +-
>  src/gallium/tests/graw/tri-gs.c                    |  2 +-
>  src/gallium/tests/graw/tri-instanced.c             |  2 +-
>  src/gallium/tests/graw/vs-test.c                   |  2 +-
>  src/gallium/winsys/sw/dri/dri_sw_winsys.c          | 17 +++++--
>  src/glx/drisw_glx.c                                | 43 ++++++++++++++--
>  src/mesa/drivers/dri/common/dri_util.c             | 15 ++++++
>  src/mesa/drivers/dri/common/dri_util.h             |  5 +-
>  33 files changed, 178 insertions(+), 53 deletions(-)
> 
> diff --git a/include/GL/internal/dri_interface.h
> b/include/GL/internal/dri_interface.h
> index b012570..81f7e60 100644
> --- a/include/GL/internal/dri_interface.h
> +++ b/include/GL/internal/dri_interface.h
> @@ -437,7 +437,7 @@ struct __DRIdamageExtensionRec {
>   * SWRast Loader extension.
>   */
>  #define __DRI_SWRAST_LOADER "DRI_SWRastLoader"
> -#define __DRI_SWRAST_LOADER_VERSION 1
> +#define __DRI_SWRAST_LOADER_VERSION 2
>  struct __DRIswrastLoaderExtensionRec {
>      __DRIextension base;
>  
> @@ -461,6 +461,13 @@ struct __DRIswrastLoaderExtensionRec {
>      void (*getImage)(__DRIdrawable *readable,
>  		     int x, int y, int width, int height,
>  		     char *data, void *loaderPrivate);
> +
> +    /**
> +     * Put image to drawable
> +     */
> +    void (*putImage2)(__DRIdrawable *drawable, int op,
> +                      int x, int y, int width, int height, int stride,
> +                      char *data, void *loaderPrivate);
>  };
>  
>  /**
> diff --git a/src/gallium/auxiliary/vl/vl_winsys_dri.c
> b/src/gallium/auxiliary/vl/vl_winsys_dri.c
> index 7aec3fe..e747a66 100644
> --- a/src/gallium/auxiliary/vl/vl_winsys_dri.c
> +++ b/src/gallium/auxiliary/vl/vl_winsys_dri.c
> @@ -115,7 +115,7 @@ static void
>  vl_dri2_flush_frontbuffer(struct pipe_screen *screen,
>                            struct pipe_resource *resource,
>                            unsigned level, unsigned layer,
> -                          void *context_private)
> +                          void *context_private, struct pipe_box *sub_box)
>  {
>     struct vl_dri_screen *scrn = (struct vl_dri_screen*)context_private;
>     uint32_t msc_hi, msc_lo;
> diff --git a/src/gallium/drivers/galahad/glhd_screen.c
> b/src/gallium/drivers/galahad/glhd_screen.c
> index 16a5ff1..5a91077 100644
> --- a/src/gallium/drivers/galahad/glhd_screen.c
> +++ b/src/gallium/drivers/galahad/glhd_screen.c
> @@ -275,7 +275,8 @@ static void
>  galahad_screen_flush_frontbuffer(struct pipe_screen *_screen,
>                                    struct pipe_resource *_resource,
>                                    unsigned level, unsigned layer,
> -                                  void *context_private)
> +                                  void *context_private,
> +                                  struct pipe_box *sub_box)
>  {
>     struct galahad_screen *glhd_screen = galahad_screen(_screen);
>     struct galahad_resource *glhd_resource = galahad_resource(_resource);
> @@ -285,7 +286,7 @@ galahad_screen_flush_frontbuffer(struct pipe_screen
> *_screen,
>     screen->flush_frontbuffer(screen,
>                               resource,
>                               level, layer,
> -                             context_private);
> +                             context_private, sub_box);
>  }
>  
>  static void
> diff --git a/src/gallium/drivers/i915/i915_screen.c
> b/src/gallium/drivers/i915/i915_screen.c
> index 77607d0..7e35d84 100644
> --- a/src/gallium/drivers/i915/i915_screen.c
> +++ b/src/gallium/drivers/i915/i915_screen.c
> @@ -420,7 +420,8 @@ static void
>  i915_flush_frontbuffer(struct pipe_screen *screen,
>                         struct pipe_resource *resource,
>                         unsigned level, unsigned layer,
> -                       void *winsys_drawable_handle)
> +                       void *winsys_drawable_handle,
> +                       struct pipe_box *sub_box)
>  {
>     /* XXX: Dummy right now. */
>     (void)screen;
> @@ -428,6 +429,7 @@ i915_flush_frontbuffer(struct pipe_screen *screen,
>     (void)level;
>     (void)layer;
>     (void)winsys_drawable_handle;
> +   (void)sub_box;
>  }
>  
>  static void
> diff --git a/src/gallium/drivers/identity/id_screen.c
> b/src/gallium/drivers/identity/id_screen.c
> index 26df7f6..28cfa1f6 100644
> --- a/src/gallium/drivers/identity/id_screen.c
> +++ b/src/gallium/drivers/identity/id_screen.c
> @@ -192,7 +192,8 @@ static void
>  identity_screen_flush_frontbuffer(struct pipe_screen *_screen,
>                                    struct pipe_resource *_resource,
>                                    unsigned level, unsigned layer,
> -                                  void *context_private)
> +                                  void *context_private,
> +                                  struct pipe_box *sub_box)
>  {
>     struct identity_screen *id_screen = identity_screen(_screen);
>     struct identity_resource *id_resource = identity_resource(_resource);
> @@ -202,7 +203,7 @@ identity_screen_flush_frontbuffer(struct pipe_screen
> *_screen,
>     screen->flush_frontbuffer(screen,
>                               resource,
>                               level, layer,
> -                             context_private);
> +                             context_private, sub_box);
>  }
>  
>  static void
> diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c
> b/src/gallium/drivers/llvmpipe/lp_screen.c
> index f61df98..3501387 100644
> --- a/src/gallium/drivers/llvmpipe/lp_screen.c
> +++ b/src/gallium/drivers/llvmpipe/lp_screen.c
> @@ -404,7 +404,8 @@ static void
>  llvmpipe_flush_frontbuffer(struct pipe_screen *_screen,
>                             struct pipe_resource *resource,
>                             unsigned level, unsigned layer,
> -                           void *context_private)
> +                           void *context_private,
> +                           struct pipe_box *sub_box)
>  {
>     struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
>     struct sw_winsys *winsys = screen->winsys;
> @@ -412,10 +413,9 @@ llvmpipe_flush_frontbuffer(struct pipe_screen *_screen,
>  
>     assert(texture->dt);
>     if (texture->dt)
> -      winsys->displaytarget_display(winsys, texture->dt, context_private);
> +      winsys->displaytarget_display(winsys, texture->dt, context_private,
> sub_box);
>  }
>  
> -
>  static void
>  llvmpipe_destroy_screen( struct pipe_screen *_screen )
>  {
> diff --git a/src/gallium/drivers/noop/noop_pipe.c
> b/src/gallium/drivers/noop/noop_pipe.c
> index 889e95e..27197a5 100644
> --- a/src/gallium/drivers/noop/noop_pipe.c
> +++ b/src/gallium/drivers/noop/noop_pipe.c
> @@ -296,7 +296,7 @@ static struct pipe_context *noop_create_context(struct
> pipe_screen *screen, void
>  static void noop_flush_frontbuffer(struct pipe_screen *_screen,
>  				   struct pipe_resource *resource,
>  				   unsigned level, unsigned layer,
> -				   void *context_private)
> +				   void *context_private, struct pipe_box *box)
>  {
>  }
>  
> diff --git a/src/gallium/drivers/rbug/rbug_screen.c
> b/src/gallium/drivers/rbug/rbug_screen.c
> index 2471fdb..8576e2f 100644
> --- a/src/gallium/drivers/rbug/rbug_screen.c
> +++ b/src/gallium/drivers/rbug/rbug_screen.c
> @@ -190,7 +190,7 @@ static void
>  rbug_screen_flush_frontbuffer(struct pipe_screen *_screen,
>                                struct pipe_resource *_resource,
>                                unsigned level, unsigned layer,
> -                              void *context_private)
> +                              void *context_private, struct pipe_box
> *sub_box)
>  {
>     struct rbug_screen *rb_screen = rbug_screen(_screen);
>     struct rbug_resource *rb_resource = rbug_resource(_resource);
> @@ -200,7 +200,7 @@ rbug_screen_flush_frontbuffer(struct pipe_screen
> *_screen,
>     screen->flush_frontbuffer(screen,
>                               resource,
>                               level, layer,
> -                             context_private);
> +                             context_private, sub_box);
>  }
>  
>  static void
> diff --git a/src/gallium/drivers/softpipe/sp_screen.c
> b/src/gallium/drivers/softpipe/sp_screen.c
> index 47ef20e..358b552 100644
> --- a/src/gallium/drivers/softpipe/sp_screen.c
> +++ b/src/gallium/drivers/softpipe/sp_screen.c
> @@ -366,7 +366,8 @@ static void
>  softpipe_flush_frontbuffer(struct pipe_screen *_screen,
>                             struct pipe_resource *resource,
>                             unsigned level, unsigned layer,
> -                           void *context_private)
> +                           void *context_private,
> +                           struct pipe_box *sub_box)
>  {
>     struct softpipe_screen *screen = softpipe_screen(_screen);
>     struct sw_winsys *winsys = screen->winsys;
> @@ -374,7 +375,7 @@ softpipe_flush_frontbuffer(struct pipe_screen *_screen,
>  
>     assert(texture->dt);
>     if (texture->dt)
> -      winsys->displaytarget_display(winsys, texture->dt, context_private);
> +      winsys->displaytarget_display(winsys, texture->dt, context_private,
> sub_box);
>  }
>  
>  static uint64_t
> diff --git a/src/gallium/drivers/trace/tr_screen.c
> b/src/gallium/drivers/trace/tr_screen.c
> index 5281ba8..b71ebbe 100644
> --- a/src/gallium/drivers/trace/tr_screen.c
> +++ b/src/gallium/drivers/trace/tr_screen.c
> @@ -210,7 +210,8 @@ static void
>  trace_screen_flush_frontbuffer(struct pipe_screen *_screen,
>                                 struct pipe_resource *_resource,
>                                 unsigned level, unsigned layer,
> -                               void *context_private)
> +                               void *context_private,
> +                               struct pipe_box *sub_box)
>  {
>     struct trace_screen *tr_scr = trace_screen(_screen);
>     struct trace_resource *tr_res = trace_resource(_resource);
> @@ -227,7 +228,7 @@ trace_screen_flush_frontbuffer(struct pipe_screen
> *_screen,
>     trace_dump_arg(ptr, context_private);
>     */
>  
> -   screen->flush_frontbuffer(screen, resource, level, layer,
> context_private);
> +   screen->flush_frontbuffer(screen, resource, level, layer,
> context_private, sub_box);
>  
>     trace_dump_call_end();
>  }
> diff --git a/src/gallium/include/pipe/p_screen.h
> b/src/gallium/include/pipe/p_screen.h
> index 3ed7f26..bdd727d 100644
> --- a/src/gallium/include/pipe/p_screen.h
> +++ b/src/gallium/include/pipe/p_screen.h
> @@ -56,6 +56,7 @@ struct pipe_fence_handle;
>  struct pipe_resource;
>  struct pipe_surface;
>  struct pipe_transfer;
> +struct pipe_box;
>  
>  
>  /**
> @@ -181,13 +182,13 @@ struct pipe_screen {
>      * displayed, eg copy fake frontbuffer.
>      * \param winsys_drawable_handle  an opaque handle that the calling
>      context
>      *                                gets out-of-band
> +    * \param subbox an optional sub region to flush
>      */
>     void (*flush_frontbuffer)( struct pipe_screen *screen,
>                                struct pipe_resource *resource,
>                                unsigned level, unsigned layer,
> -                              void *winsys_drawable_handle );
> -
> -
> +                              void *winsys_drawable_handle,
> +                              struct pipe_box *subbox );
>  
>     /** Set ptr = fence, with reference counting */
>     void (*fence_reference)( struct pipe_screen *screen,
> diff --git a/src/gallium/include/state_tracker/drisw_api.h
> b/src/gallium/include/state_tracker/drisw_api.h
> index 944a649..328440c 100644
> --- a/src/gallium/include/state_tracker/drisw_api.h
> +++ b/src/gallium/include/state_tracker/drisw_api.h
> @@ -13,6 +13,8 @@ struct drisw_loader_funcs
>  {
>     void (*put_image) (struct dri_drawable *dri_drawable,
>                        void *data, unsigned width, unsigned height);
> +   void (*put_image2) (struct dri_drawable *dri_drawable,
> +                       void *data, int x, int y, unsigned width, unsigned
> height, unsigned stride);
>  };
>  
>  /**
> diff --git a/src/gallium/include/state_tracker/sw_winsys.h
> b/src/gallium/include/state_tracker/sw_winsys.h
> index 0b11fe3..d08ddd6 100644
> --- a/src/gallium/include/state_tracker/sw_winsys.h
> +++ b/src/gallium/include/state_tracker/sw_winsys.h
> @@ -48,7 +48,7 @@ struct winsys_handle;
>  struct pipe_screen;
>  struct pipe_context;
>  struct pipe_resource;
> -
> +struct pipe_box;
>  
>  /**
>   * Opaque pointer.
> @@ -129,7 +129,8 @@ struct sw_winsys
>     void
>     (*displaytarget_display)( struct sw_winsys *ws,
>                               struct sw_displaytarget *dt,
> -                             void *context_private );
> +                             void *context_private,
> +                             struct pipe_box *box );
>  
>     void
>     (*displaytarget_destroy)( struct sw_winsys *ws,
> diff --git a/src/gallium/state_trackers/dri/sw/drisw.c
> b/src/gallium/state_trackers/dri/sw/drisw.c
> index 9f00a53..64a64af 100644
> --- a/src/gallium/state_trackers/dri/sw/drisw.c
> +++ b/src/gallium/state_trackers/dri/sw/drisw.c
> @@ -37,6 +37,7 @@
>  #include "util/u_format.h"
>  #include "util/u_memory.h"
>  #include "util/u_inlines.h"
> +#include "util/u_box.h"
>  #include "pipe/p_context.h"
>  #include "state_tracker/drisw_api.h"
>  #include "state_tracker/st_context.h"
> @@ -71,6 +72,18 @@ put_image(__DRIdrawable *dPriv, void *data, unsigned
> width, unsigned height)
>  }
>  
>  static INLINE void
> +put_image2(__DRIdrawable *dPriv, void *data, int x, int y,
> +           unsigned width, unsigned height, unsigned stride)
> +{
> +   __DRIscreen *sPriv = dPriv->driScreenPriv;
> +   const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
> +
> +   loader->putImage2(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
> +                     x, y, width, height, stride,
> +                     data, dPriv->loaderPrivate);
> +}
> +
> +static INLINE void
>  get_image(__DRIdrawable *dPriv, int x, int y, int width, int height, void
>  *data)
>  {
>     __DRIscreen *sPriv = dPriv->driScreenPriv;
> @@ -99,9 +112,19 @@ drisw_put_image(struct dri_drawable *drawable,
>     put_image(dPriv, data, width, height);
>  }
>  
> +static void
> +drisw_put_image2(struct dri_drawable *drawable,
> +                 void *data, int x, int y, unsigned width, unsigned height,
> +                 unsigned stride)
> +{
> +   __DRIdrawable *dPriv = drawable->dPriv;
> +
> +   put_image2(dPriv, data, x, y, width, height, stride);
> +}
> +
>  static INLINE void
>  drisw_present_texture(__DRIdrawable *dPriv,
> -                      struct pipe_resource *ptex)
> +                      struct pipe_resource *ptex, struct pipe_box *sub_box)
>  {
>     struct dri_drawable *drawable = dri_drawable(dPriv);
>     struct dri_screen *screen = dri_screen(drawable->sPriv);
> @@ -109,7 +132,7 @@ drisw_present_texture(__DRIdrawable *dPriv,
>     if (swrast_no_present)
>        return;
>  
> -   screen->base.screen->flush_frontbuffer(screen->base.screen, ptex, 0, 0,
> drawable);
> +   screen->base.screen->flush_frontbuffer(screen->base.screen, ptex, 0, 0,
> drawable, sub_box);
>  }
>  
>  static INLINE void
> @@ -126,7 +149,7 @@ static INLINE void
>  drisw_copy_to_front(__DRIdrawable * dPriv,
>                      struct pipe_resource *ptex)
>  {
> -   drisw_present_texture(dPriv, ptex);
> +   drisw_present_texture(dPriv, ptex, NULL);
>  
>     drisw_invalidate_drawable(dPriv);
>  }
> @@ -158,6 +181,30 @@ drisw_swap_buffers(__DRIdrawable *dPriv)
>  }
>  
>  static void
> +drisw_copy_sub_buffer(__DRIdrawable *dPriv, int x, int y,
> +                      int w, int h)
> +{
> +   struct dri_context *ctx = dri_get_current(dPriv->driScreenPriv);
> +   struct dri_drawable *drawable = dri_drawable(dPriv);
> +   struct pipe_resource *ptex;
> +   struct pipe_box box;
> +   if (!ctx)
> +      return;
> +
> +   ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
> +
> +   if (ptex) {
> +      if (ctx->pp && drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL])
> +         pp_run(ctx->pp, ptex, ptex,
> drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL]);
> +
> +      ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL);
> +
> +      u_box_2d(x, dPriv->h - y - h, w, h, &box);
> +      drisw_present_texture(dPriv, ptex, &box);
> +   }
> +}
> +
> +static void
>  drisw_flush_frontbuffer(struct dri_context *ctx,
>                          struct dri_drawable *drawable,
>                          enum st_attachment_type statt)
> @@ -288,7 +335,8 @@ static const __DRIextension *drisw_screen_extensions[] =
> {
>  };
>  
>  static struct drisw_loader_funcs drisw_lf = {
> -   .put_image = drisw_put_image
> +   .put_image = drisw_put_image,
> +   .put_image2 = drisw_put_image2
>  };
>  
>  static const __DRIconfig **
> @@ -359,12 +407,14 @@ const struct __DriverAPIRec driDriverAPI = {
>     .SwapBuffers = drisw_swap_buffers,
>     .MakeCurrent = dri_make_current,
>     .UnbindContext = dri_unbind_context,
> +   .CopySubBuffer = drisw_copy_sub_buffer,
>  };
>  
>  /* This is the table of extensions that the loader will dlsym() for. */
>  PUBLIC const __DRIextension *__driDriverExtensions[] = {
>      &driCoreExtension.base,
>      &driSWRastExtension.base,
> +    &driCopySubBufferExtension,
>      &gallium_config_options.base,
>      NULL
>  };
> diff --git a/src/gallium/state_trackers/egl/common/native_helper.c
> b/src/gallium/state_trackers/egl/common/native_helper.c
> index b578a8a..5c2be19 100644
> --- a/src/gallium/state_trackers/egl/common/native_helper.c
> +++ b/src/gallium/state_trackers/egl/common/native_helper.c
> @@ -244,7 +244,7 @@ resource_surface_present(struct resource_surface *rsurf,
>        return TRUE;
>  
>     rsurf->screen->flush_frontbuffer(rsurf->screen,
> -         pres, 0, 0, winsys_drawable_handle);
> +         pres, 0, 0, winsys_drawable_handle, NULL);
>  
>     return TRUE;
>  }
> diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c
> b/src/gallium/state_trackers/egl/x11/native_ximage.c
> index 28c6442..019e535 100644
> --- a/src/gallium/state_trackers/egl/x11/native_ximage.c
> +++ b/src/gallium/state_trackers/egl/x11/native_ximage.c
> @@ -476,7 +476,7 @@ ximage_display_copy_to_pixmap(struct native_display
> *ndpy,
>        xdraw.drawable = (Drawable) pix;
>  
>        xdpy->base.screen->flush_frontbuffer(xdpy->base.screen,
> -            src, 0, 0, &xdraw);
> +            src, 0, 0, &xdraw, NULL);
>  
>        return TRUE;
>     }
> diff --git a/src/gallium/state_trackers/glx/xlib/xm_st.c
> b/src/gallium/state_trackers/glx/xlib/xm_st.c
> index fb69998..7f73a3a 100644
> --- a/src/gallium/state_trackers/glx/xlib/xm_st.c
> +++ b/src/gallium/state_trackers/glx/xlib/xm_st.c
> @@ -74,7 +74,7 @@ xmesa_st_framebuffer_display(struct st_framebuffer_iface
> *stfbi,
>        pres = xstfb->display_resource;
>     }
>  
> -   xstfb->screen->flush_frontbuffer(xstfb->screen, pres, 0, 0,
> &xstfb->buffer->ws);
> +   xstfb->screen->flush_frontbuffer(xstfb->screen, pres, 0, 0,
> &xstfb->buffer->ws, NULL);
>     return TRUE;
>  }
>  
> diff --git a/src/gallium/state_trackers/vdpau/presentation.c
> b/src/gallium/state_trackers/vdpau/presentation.c
> index 81e0328..b574ddd 100644
> --- a/src/gallium/state_trackers/vdpau/presentation.c
> +++ b/src/gallium/state_trackers/vdpau/presentation.c
> @@ -269,7 +269,7 @@ vlVdpPresentationQueueDisplay(VdpPresentationQueue
> presentation_queue,
>     pipe->screen->flush_frontbuffer
>     (
>        pipe->screen, tex, 0, 0,
> -      vl_screen_get_private(pq->device->vscreen)
> +      vl_screen_get_private(pq->device->vscreen), NULL
>     );
>  
>     pipe->screen->fence_reference(pipe->screen, &surf->fence, NULL);
> diff --git a/src/gallium/state_trackers/xvmc/surface.c
> b/src/gallium/state_trackers/xvmc/surface.c
> index 13f337c..f6876be 100644
> --- a/src/gallium/state_trackers/xvmc/surface.c
> +++ b/src/gallium/state_trackers/xvmc/surface.c
> @@ -447,7 +447,7 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface,
> Drawable drawable,
>     pipe->screen->flush_frontbuffer
>     (
>        pipe->screen, tex, 0, 0,
> -      vl_screen_get_private(context_priv->vscreen)
> +      vl_screen_get_private(context_priv->vscreen), NULL
>     );
>  
>     if(dump_window == -1) {
> diff --git a/src/gallium/targets/haiku-softpipe/GalliumContext.cpp
> b/src/gallium/targets/haiku-softpipe/GalliumContext.cpp
> index b750f65..1078cb7 100644
> --- a/src/gallium/targets/haiku-softpipe/GalliumContext.cpp
> +++ b/src/gallium/targets/haiku-softpipe/GalliumContext.cpp
> @@ -504,14 +504,14 @@ GalliumContext::SwapBuffers(context_id contextID)
>  		// We pass our destination bitmap to flush_fronbuffer which passes it
>  		// to the private winsys display call.
>  		fScreen->flush_frontbuffer(fScreen, surface->texture, 0, 0,
> -			context->bitmap);
> +			context->bitmap, NULL);
>  	}
>  
>  	#if 0
>  	// TODO... should we flush the z stencil buffer?
>  	pipe_surface* zSurface = stContext->state.framebuffer.zsbuf;
>  	fScreen->flush_frontbuffer(fScreen, zSurface->texture, 0, 0,
> -		context->bitmap);
> +		context->bitmap, NULL);
>  	#endif
>  
>  	return B_OK;
> diff --git a/src/gallium/tests/graw/clear.c b/src/gallium/tests/graw/clear.c
> index 77c59db..f38da47 100644
> --- a/src/gallium/tests/graw/clear.c
> +++ b/src/gallium/tests/graw/clear.c
> @@ -33,7 +33,7 @@ static void draw( void )
>  
>     graw_save_surface_to_file(ctx, surf, NULL);
>  
> -   screen->flush_frontbuffer(screen, tex, 0, 0, window);
> +   screen->flush_frontbuffer(screen, tex, 0, 0, window, NULL);
>  }
>  
>  static void init( void )
> diff --git a/src/gallium/tests/graw/fs-test.c
> b/src/gallium/tests/graw/fs-test.c
> index 4d38e08..0560e31 100644
> --- a/src/gallium/tests/graw/fs-test.c
> +++ b/src/gallium/tests/graw/fs-test.c
> @@ -240,7 +240,7 @@ static void draw( void )
>  
>     graw_save_surface_to_file(ctx, surf, NULL);
>  
> -   screen->flush_frontbuffer(screen, rttex, 0, 0, window);
> +   screen->flush_frontbuffer(screen, rttex, 0, 0, window, NULL);
>  }
>  
>  #define SIZE 16
> diff --git a/src/gallium/tests/graw/graw_util.h
> b/src/gallium/tests/graw/graw_util.h
> index 8557285..1856f0d 100644
> --- a/src/gallium/tests/graw/graw_util.h
> +++ b/src/gallium/tests/graw/graw_util.h
> @@ -211,7 +211,7 @@ static INLINE void
>  graw_util_flush_front(const struct graw_info *info)
>  {
>     info->screen->flush_frontbuffer(info->screen, info->color_buf[0],
> -                                   0, 0, info->window);
> +                                   0, 0, info->window, NULL);
>  }
>  
>  
> diff --git a/src/gallium/tests/graw/gs-test.c
> b/src/gallium/tests/graw/gs-test.c
> index 3ada18a..879bf3e 100644
> --- a/src/gallium/tests/graw/gs-test.c
> +++ b/src/gallium/tests/graw/gs-test.c
> @@ -347,7 +347,7 @@ static void draw( void )
>  
>     graw_save_surface_to_file(ctx, surf, NULL);
>  
> -   screen->flush_frontbuffer(screen, rttex, 0, 0, window);
> +   screen->flush_frontbuffer(screen, rttex, 0, 0, window, NULL);
>  }
>  
>  #define SIZE 16
> diff --git a/src/gallium/tests/graw/quad-sample.c
> b/src/gallium/tests/graw/quad-sample.c
> index b4a29e1..2e248a8 100644
> --- a/src/gallium/tests/graw/quad-sample.c
> +++ b/src/gallium/tests/graw/quad-sample.c
> @@ -156,7 +156,7 @@ static void draw( void )
>  
>     graw_save_surface_to_file(ctx, surf, NULL);
>  
> -   screen->flush_frontbuffer(screen, rttex, 0, 0, window);
> +   screen->flush_frontbuffer(screen, rttex, 0, 0, window, NULL);
>  }
>  
>  #define SIZE 16
> diff --git a/src/gallium/tests/graw/shader-leak.c
> b/src/gallium/tests/graw/shader-leak.c
> index 4ef752b..754ada6 100644
> --- a/src/gallium/tests/graw/shader-leak.c
> +++ b/src/gallium/tests/graw/shader-leak.c
> @@ -158,7 +158,7 @@ static void draw( void )
>        ctx->delete_fs_state(ctx, fs);
>     }
>  
> -   screen->flush_frontbuffer(screen, tex, 0, 0, window);
> +   screen->flush_frontbuffer(screen, tex, 0, 0, window, NULL);
>     ctx->destroy(ctx);
>  
>     exit(0);
> diff --git a/src/gallium/tests/graw/tri-gs.c
> b/src/gallium/tests/graw/tri-gs.c
> index 37323aa..24de12b 100644
> --- a/src/gallium/tests/graw/tri-gs.c
> +++ b/src/gallium/tests/graw/tri-gs.c
> @@ -168,7 +168,7 @@ static void draw( void )
>     util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3);
>     ctx->flush(ctx, NULL, 0);
>  
> -   screen->flush_frontbuffer(screen, tex, 0, 0, window);
> +   screen->flush_frontbuffer(screen, tex, 0, 0, window, NULL);
>  }
>  
>  
> diff --git a/src/gallium/tests/graw/tri-instanced.c
> b/src/gallium/tests/graw/tri-instanced.c
> index f84463d..55bc3a5 100644
> --- a/src/gallium/tests/graw/tri-instanced.c
> +++ b/src/gallium/tests/graw/tri-instanced.c
> @@ -219,7 +219,7 @@ static void draw( void )
>  
>     graw_save_surface_to_file(ctx, surf, NULL);
>  
> -   screen->flush_frontbuffer(screen, tex, 0, 0, window);
> +   screen->flush_frontbuffer(screen, tex, 0, 0, window, NULL);
>  }
>  
>  
> diff --git a/src/gallium/tests/graw/vs-test.c
> b/src/gallium/tests/graw/vs-test.c
> index f7d4d73..0e9fc53 100644
> --- a/src/gallium/tests/graw/vs-test.c
> +++ b/src/gallium/tests/graw/vs-test.c
> @@ -234,7 +234,7 @@ static void draw( void )
>  
>     graw_save_surface_to_file(ctx, surf, NULL);
>  
> -   screen->flush_frontbuffer(screen, rttex, 0, 0, window);
> +   screen->flush_frontbuffer(screen, rttex, 0, 0, window, NULL);
>  }
>  
>  #define SIZE 16
> diff --git a/src/gallium/winsys/sw/dri/dri_sw_winsys.c
> b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
> index edb3a38..cc3b4a1 100644
> --- a/src/gallium/winsys/sw/dri/dri_sw_winsys.c
> +++ b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
> @@ -166,25 +166,33 @@ dri_sw_displaytarget_get_handle(struct sw_winsys
> *winsys,
>  static void
>  dri_sw_displaytarget_display(struct sw_winsys *ws,
>                               struct sw_displaytarget *dt,
> -                             void *context_private)
> +                             void *context_private,
> +                             struct pipe_box *box)
>  {
>     struct dri_sw_winsys *dri_sw_ws = dri_sw_winsys(ws);
>     struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
>     struct dri_drawable *dri_drawable = (struct dri_drawable
>     *)context_private;
>     unsigned width, height;
> +   unsigned blsize = util_format_get_blocksize(dri_sw_dt->format);
>  
>     /* Set the width to 'stride / cpp'.
>      *
>      * PutImage correctly clips to the width of the dst drawable.
>      */
> -   width = dri_sw_dt->stride / util_format_get_blocksize(dri_sw_dt->format);
> +   width = dri_sw_dt->stride / blsize;
>  
>     height = dri_sw_dt->height;
>  
> -   dri_sw_ws->lf->put_image(dri_drawable, dri_sw_dt->data, width, height);
> +   if (box) {
> +       void *data;
> +       data = dri_sw_dt->data + (dri_sw_dt->stride * box->y) + box->x *
> blsize;
> +       dri_sw_ws->lf->put_image2(dri_drawable, data,
> +                                 box->x, box->y, box->width, box->height,
> dri_sw_dt->stride);
> +   } else {
> +       dri_sw_ws->lf->put_image(dri_drawable, dri_sw_dt->data, width,
> height);
> +   }
>  }
>  
> -
>  static void
>  dri_destroy_sw_winsys(struct sw_winsys *winsys)
>  {
> @@ -216,7 +224,6 @@ dri_create_sw_winsys(struct drisw_loader_funcs *lf)
>     ws->base.displaytarget_unmap = dri_sw_displaytarget_unmap;
>  
>     ws->base.displaytarget_display = dri_sw_displaytarget_display;
> -
>     return &ws->base;
>  }
>  
> diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c
> index cb1d650..13a4b96 100644
> --- a/src/glx/drisw_glx.c
> +++ b/src/glx/drisw_glx.c
> @@ -49,6 +49,7 @@ struct drisw_screen
>     const __DRIcoreExtension *core;
>     const __DRIswrastExtension *swrast;
>     const __DRItexBufferExtension *texBuffer;
> +   const __DRIcopySubBufferExtension *copySubBuffer;
>  
>     const __DRIconfig **driver_configs;
>  
> @@ -171,9 +172,9 @@ bytes_per_line(unsigned pitch_bits, unsigned mul)
>  }
>  
>  static void
> -swrastPutImage(__DRIdrawable * draw, int op,
> -               int x, int y, int w, int h,
> -               char *data, void *loaderPrivate)
> +swrastPutImage2(__DRIdrawable * draw, int op,
> +                int x, int y, int w, int h, int stride,
> +                char *data, void *loaderPrivate)
>  {
>     struct drisw_drawable *pdp = loaderPrivate;
>     __GLXDRIdrawable *pdraw = &(pdp->base);
> @@ -199,7 +200,7 @@ swrastPutImage(__DRIdrawable * draw, int op,
>     ximage->data = data;
>     ximage->width = w;
>     ximage->height = h;
> -   ximage->bytes_per_line = bytes_per_line(w * ximage->bits_per_pixel, 32);
> +   ximage->bytes_per_line = stride ? stride : bytes_per_line(w *
> ximage->bits_per_pixel, 32);
>  
>     XPutImage(dpy, drawable, gc, ximage, 0, 0, x, y, w, h);
>  
> @@ -207,6 +208,14 @@ swrastPutImage(__DRIdrawable * draw, int op,
>  }
>  
>  static void
> +swrastPutImage(__DRIdrawable * draw, int op,
> +               int x, int y, int w, int h,
> +               char *data, void *loaderPrivate)
> +{
> +   swrastPutImage2(draw, op, x, y, w, h, 0, data, loaderPrivate);
> +}
> +
> +static void
>  swrastGetImage(__DRIdrawable * read,
>                 int x, int y, int w, int h,
>                 char *data, void *loaderPrivate)
> @@ -234,7 +243,8 @@ static const __DRIswrastLoaderExtension
> swrastLoaderExtension = {
>     {__DRI_SWRAST_LOADER, __DRI_SWRAST_LOADER_VERSION},
>     swrastGetDrawableInfo,
>     swrastPutImage,
> -   swrastGetImage
> +   swrastGetImage,
> +   swrastPutImage2,
>  };
>  
>  static const __DRIextension *loader_extensions[] = {
> @@ -585,6 +595,21 @@ driswSwapBuffers(__GLXDRIdrawable * pdraw,
>  }
>  
>  static void
> +driswCopySubBuffer(__GLXDRIdrawable * pdraw,
> +                   int x, int y, int width, int height, Bool flush)
> +{
> +   struct drisw_drawable *pdp = (struct drisw_drawable *) pdraw;
> +   struct drisw_screen *psc = (struct drisw_screen *) pdp->base.psc;
> +
> +   if (flush) {
> +      glFlush();
> +   }
> +
> +   (*psc->copySubBuffer->copySubBuffer) (pdp->driDrawable,
> +					    x, y, width, height);
> +}
> +
> +static void
>  driswDestroyScreen(struct glx_screen *base)
>  {
>     struct drisw_screen *psc = (struct drisw_screen *) base;
> @@ -632,6 +657,9 @@ driswBindExtensions(struct drisw_screen *psc, const
> __DRIextension **extensions)
>  				 "GLX_EXT_create_context_es2_profile");
>     }
>  
> +   if (psc->copySubBuffer)
> +      __glXEnableDirectExtension(&psc->base, "GLX_MESA_copy_sub_buffer");
> +
>     /* FIXME: Figure out what other extensions can be ported here from dri2.
>     */
>     for (i = 0; extensions[i]; i++) {
>        if ((strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0)) {
> @@ -673,6 +701,8 @@ driswCreateScreen(int screen, struct glx_display *priv)
>  	 psc->core = (__DRIcoreExtension *) extensions[i];
>        if (strcmp(extensions[i]->name, __DRI_SWRAST) == 0)
>  	 psc->swrast = (__DRIswrastExtension *) extensions[i];
> +      if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0)
> +	 psc->copySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
>     }
>  
>     if (psc->core == NULL || psc->swrast == NULL) {
> @@ -718,6 +748,9 @@ driswCreateScreen(int screen, struct glx_display *priv)
>     psp->createDrawable = driswCreateDrawable;
>     psp->swapBuffers = driswSwapBuffers;
>  
> +   if (psc->copySubBuffer)
> +      psp->copySubBuffer = driswCopySubBuffer;
> +
>     return &psc->base;
>  
>   handle_error:
> diff --git a/src/mesa/drivers/dri/common/dri_util.c
> b/src/mesa/drivers/dri/common/dri_util.c
> index 0bce77e..fd2eca7 100644
> --- a/src/mesa/drivers/dri/common/dri_util.c
> +++ b/src/mesa/drivers/dri/common/dri_util.c
> @@ -873,3 +873,18 @@ const __DRIimageDriverExtension driImageDriverExtension
> = {
>      .getAPIMask                 = driGetAPIMask,
>      .createContextAttribs       = driCreateContextAttribs,
>  };
> +
> +/* swrast copy sub buffer entrypoint. */
> +static void driCopySubBuffer(__DRIdrawable *pdp, int x, int y,
> +                             int w, int h)
> +{
> +    assert(pdp->driScreenPriv->swrast_loader);
> +
> +    pdp->driScreenPriv->driver->CopySubBuffer(pdp, x, y, w, h);
> +}
> +
> +/* for swrast only */
> +const __DRIcopySubBufferExtension driCopySubBufferExtension = {
> +   { __DRI_COPY_SUB_BUFFER, 1 },
> +   .copySubBuffer = driCopySubBuffer,
> +};
> diff --git a/src/mesa/drivers/dri/common/dri_util.h
> b/src/mesa/drivers/dri/common/dri_util.h
> index 79a8564..4cfa75d 100644
> --- a/src/mesa/drivers/dri/common/dri_util.h
> +++ b/src/mesa/drivers/dri/common/dri_util.h
> @@ -66,7 +66,7 @@ extern const __DRIcoreExtension driCoreExtension;
>  extern const __DRIswrastExtension driSWRastExtension;
>  extern const __DRIdri2Extension driDRI2Extension;
>  extern const __DRI2configQueryExtension dri2ConfigQueryExtension;
> -
> +extern const __DRIcopySubBufferExtension driCopySubBufferExtension;
>  /**
>   * Driver callback functions.
>   *
> @@ -115,6 +115,9 @@ struct __DriverAPIRec {
>                                      int width, int height);
>  
>      void (*ReleaseBuffer) (__DRIscreen *screenPrivate, __DRIbuffer *buffer);
> +
> +    void (*CopySubBuffer)(__DRIdrawable *driDrawPriv, int x, int y,
> +                          int w, int h);
>  };
>  
>  extern const struct __DriverAPIRec driDriverAPI;
> --
> 1.8.3.1
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://urldefense.proofpoint.com/v1/url?u=http://lists.freedesktop.org/mailman/listinfo/mesa-dev&k=oIvRg1%2BdGAgOoM1BIlLLqw%3D%3D%0A&r=NMr9uy2iTjWVixC0wOcYCWEIYhfo80qKwRgdodpoDzA%3D%0A&m=PHP1BdGxAuEdcENkoQ%2B%2BXlDEXMYDu5rLFjO6X6QcDT0%3D%0A&s=4de8284e02612630341b3ad329b14aa430b5e4affaf15273cd5d77b4aae6d8ae
> 


More information about the mesa-dev mailing list