swrast* (gallium, classic): add MESA_copy_sub_buffer support (v3)
authorDave Airlie <airlied@gmail.com>
Thu, 28 Nov 2013 01:08:11 +0000 (11:08 +1000)
committerDave Airlie <airlied@gmail.com>
Fri, 13 Dec 2013 04:37:01 +0000 (14:37 +1000)
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.

v3: finish off winsys interfaces, add swrast classic support as well.

Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
swrast: add support for copy_sub_buffer

41 files changed:
include/GL/internal/dri_interface.h
src/gallium/auxiliary/vl/vl_winsys_dri.c
src/gallium/drivers/galahad/glhd_screen.c
src/gallium/drivers/i915/i915_screen.c
src/gallium/drivers/identity/id_screen.c
src/gallium/drivers/llvmpipe/lp_screen.c
src/gallium/drivers/noop/noop_pipe.c
src/gallium/drivers/rbug/rbug_screen.c
src/gallium/drivers/softpipe/sp_screen.c
src/gallium/drivers/trace/tr_screen.c
src/gallium/include/pipe/p_screen.h
src/gallium/include/state_tracker/drisw_api.h
src/gallium/include/state_tracker/sw_winsys.h
src/gallium/state_trackers/dri/sw/drisw.c
src/gallium/state_trackers/egl/common/native_helper.c
src/gallium/state_trackers/egl/x11/native_ximage.c
src/gallium/state_trackers/glx/xlib/xm_st.c
src/gallium/state_trackers/vdpau/presentation.c
src/gallium/state_trackers/xvmc/surface.c
src/gallium/targets/haiku-softpipe/GalliumContext.cpp
src/gallium/tests/graw/clear.c
src/gallium/tests/graw/fs-test.c
src/gallium/tests/graw/graw_util.h
src/gallium/tests/graw/gs-test.c
src/gallium/tests/graw/quad-sample.c
src/gallium/tests/graw/shader-leak.c
src/gallium/tests/graw/tri-gs.c
src/gallium/tests/graw/tri-instanced.c
src/gallium/tests/graw/vs-test.c
src/gallium/winsys/sw/android/android_sw_winsys.cpp
src/gallium/winsys/sw/dri/dri_sw_winsys.c
src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c
src/gallium/winsys/sw/gdi/gdi_sw_winsys.c
src/gallium/winsys/sw/hgl/hgl_sw_winsys.c
src/gallium/winsys/sw/null/null_sw_winsys.c
src/gallium/winsys/sw/wayland/wayland_sw_winsys.c
src/gallium/winsys/sw/xlib/xlib_sw_winsys.c
src/glx/drisw_glx.c
src/mesa/drivers/dri/common/dri_util.c
src/mesa/drivers/dri/common/dri_util.h
src/mesa/drivers/dri/swrast/swrast.c

index b012570ae133cdb077c95b0623cbe38a029303a6..81f7e60e55fbd5246bb661e37089e0fdcc777d80 100644 (file)
@@ -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);
 };
 
 /**
index 7aec3fee685e7d1e8e19adcf67b85103299d284c..e747a66f0d6f376538dd92b38b9969cfe9bf0b2a 100644 (file)
@@ -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;
index 16a5ff1ceae7f8b8fcc61eb759f541a5ee348f7c..5a910779948f3106e197c250fabdc76e27ee7017 100644 (file)
@@ -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
index abb97966c66ca03afff85501e823a08653b33c9c..8b29fc2e57d20d9e4527a34cd175ddf8b11ca1d3 100644 (file)
@@ -423,7 +423,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;
@@ -431,6 +432,7 @@ i915_flush_frontbuffer(struct pipe_screen *screen,
    (void)level;
    (void)layer;
    (void)winsys_drawable_handle;
+   (void)sub_box;
 }
 
 static void
index 26df7f6f7cea46e363f6b96ffbfcaa0ca8a61589..28cfa1f62b1ae660bbf066af05f7e0c3a220a321 100644 (file)
@@ -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
index 742e7f296cea94220e3be2230b824a72efc32f6b..c8eb3babde50d4be00e595f435ef641d200bf4a5 100644 (file)
@@ -411,7 +411,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;
@@ -419,10 +420,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 )
 {
index 889e95ee76f9ea169594cca3107cf14dc69f26e5..27197a504545b706b088d95629a147b06c43f563 100644 (file)
@@ -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)
 {
 }
 
index 2471fdb46610a44923cd0eddaa0391f3496cee67..8576e2f089752bf13359ce84ecffa71c2ab222a8 100644 (file)
@@ -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
index 0c8c94d0e19543eb4a881224bf490848b6fde373..69cb09fd84da896b21fc098d8eb06d54b3f3aea0 100644 (file)
@@ -369,7 +369,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;
@@ -377,7 +378,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
index c6745af09f2f76cd621ff6c8427d85737422db10..debd031084f690c063349fb241907b8ce7661f60 100644 (file)
@@ -209,7 +209,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);
@@ -226,7 +227,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();
 }
index 3ed7f269e4f86639e4dfb05ff81ecb9c05add4a6..bdd727d8cb45a7aedc4f7c06ca4d6acb1f092558 100644 (file)
@@ -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,
index 944a649257e08e8f31f1567f17f79b0a46264906..328440cf5ffe76be9e454f95e4cb65fad2cc62c6 100644 (file)
@@ -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);
 };
 
 /**
index 0b11fe3beb922ec6ae4156b4f60ea72c202ee6c2..d08ddd6c397b84bc64c26f75a35fa9a9a9dcb0a2 100644 (file)
@@ -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, 
index 9f00a53152e8dd272e7da4d08f0a18cbb6fe94cc..64a64af14ecdc1b085e26ba750ac81dd9ae81599 100644 (file)
@@ -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"
@@ -70,6 +71,18 @@ put_image(__DRIdrawable *dPriv, void *data, unsigned width, unsigned height)
                     data, dPriv->loaderPrivate);
 }
 
+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)
 {
@@ -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);
 }
@@ -157,6 +180,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,
@@ -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
 };
index d1e1acdab4c488d0fed813443f1b0cbdd3d3ed32..4a77a502e8703a8de7088b1b612be72521fa938d 100644 (file)
@@ -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;
 }
index 28c6442d82189b5bad7a8c48d9517e1ef502ffc5..019e53551287926e42eb60eebd76b461d86008f0 100644 (file)
@@ -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;
    }
index fb6999826a9c235af208f10de4de25625f456450..7f73a3a44fe2ed25d19fd4318257fe5c7a591ff7 100644 (file)
@@ -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;
 }
 
index 81e0328a09610b718edadd04f12dc6dd4752f290..b574ddd2cd5be3c826a9f923eb6bcf2b43f8f66f 100644 (file)
@@ -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);
index 13f337c61cd121a3383ff2685892c2680908655f..f6876be943b5ee68406b0dca59267d9cb7becd8f 100644 (file)
@@ -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) {
index b750f6578f401018ba18a7c6c08ab7dccc927676..1078cb7b38031185e3cdbeb90ffd501c8b3e269a 100644 (file)
@@ -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;
index 77c59db8a3f45056f57250d318e90ce7067969c3..f38da47407fc982552f512b03547ae4051a6dbd6 100644 (file)
@@ -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 )
index 4d38e084b80b16cd45049e6b7d266e4ce41f90ab..0560e31723e30bc3d26a7e107d0cdb6489d52327 100644 (file)
@@ -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
index 8557285e0eacfb206aa925f94241118c75b1fdb2..1856f0d7df4d98dd9386024e2c9bdd3a067add1b 100644 (file)
@@ -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);
 }
 
 
index 3ada18a30eef795c1782b010ddeaaee04db24f95..879bf3e8324803ae13cb6155c5321403e2942cc1 100644 (file)
@@ -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
index b4a29e101e43793a6b61b24e587bee723b2901de..2e248a8a6f4b30d87372a86f597301faa2b50fc3 100644 (file)
@@ -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
index 4ef752b412f443b89e27048b0c7c38de5ab5d7ca..754ada6cf10c3f0516abb4820453d937a434862e 100644 (file)
@@ -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);
index 37323aa08648642a1807faab373bd06608fe2d15..24de12b723cee940565e7a191acd62bfada71707 100644 (file)
@@ -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);
 }
 
 
index f84463d8ce7fc579e64aca56e823e5f5c6f31e19..55bc3a551da1cf56864acffb06cca18154f77ec9 100644 (file)
@@ -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);
 }
 
 
index f7d4d7342ec4add1894f28443a9cd277e0c3f469..0e9fc53e1b8e274e5f53d271de4f94634b379b7d 100644 (file)
@@ -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
index cb91aade0a819ea411aa3865b6370e1a49687f8a..4b1040cb6ee7cb46370c5816bb31776dfb821cc9 100644 (file)
@@ -74,7 +74,8 @@ namespace android {
 static void
 android_displaytarget_display(struct sw_winsys *ws,
                               struct sw_displaytarget *dt,
-                              void *context_private)
+                              void *context_private,
+                              struct pipe_box *box)
 {
 }
 
index edb3a381a749bbf769568eb66e239be9a187322d..6fed22bbd7c8c2cf6dff03a694aa18c8c178f3aa 100644 (file)
@@ -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)
 {
index a2809854710f5b9bdfa07783c52b2449f0410afa..cc3ce1a78d2d1b273e0fe722a91804736cbacde9 100644 (file)
@@ -74,7 +74,8 @@ fbdev_sw_winsys(struct sw_winsys *ws)
 static void
 fbdev_displaytarget_display(struct sw_winsys *ws,
                             struct sw_displaytarget *dt,
-                            void *winsys_private)
+                            void *winsys_private,
+                            struct pipe_box *box)
 {
    struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws);
    struct fbdev_sw_displaytarget *src = fbdev_sw_displaytarget(dt);
index 2e12f6e6cc866424e58ff7df6d9d0123d41a5bb1..aae3ec55a251c893e7ce4f6990ebd10f4016d810 100644 (file)
@@ -207,7 +207,8 @@ gdi_sw_display( struct sw_winsys *winsys,
 static void
 gdi_sw_displaytarget_display(struct sw_winsys *winsys, 
                              struct sw_displaytarget *dt,
-                             void *context_private)
+                             void *context_private,
+                             struct pipe_box *box)
 {
     /* nasty:
      */
index b09584c39a4b36b2b4e7711782e8a9ff04a6b5b5..27eca2ba2804842f0866948d54f2fbd4521e85e4 100644 (file)
@@ -160,7 +160,8 @@ hgl_winsys_displaytarget_unmap(struct sw_winsys* winsys,
 
 static void
 hgl_winsys_displaytarget_display(struct sw_winsys* winsys,
-       struct sw_displaytarget* displayTarget, void* contextPrivate)
+       struct sw_displaytarget* displayTarget, void* contextPrivate,
+       struct pipe_box *box)
 {
        assert(contextPrivate);
 
index 44849da14031d92ec46e39b22b9dccb613c9752c..9c8b3ec43968bc576dca0847fcee284a6daa1525 100644 (file)
@@ -114,7 +114,8 @@ null_sw_displaytarget_get_handle(struct sw_winsys *winsys,
 static void
 null_sw_displaytarget_display(struct sw_winsys *winsys,
                               struct sw_displaytarget *dt,
-                              void *context_private)
+                              void *context_private,
+                              struct pipe_box *box)
 {
    assert(0);
 }
index f432de98fef34f747eac2ae57ac70fc75a9ad0be..e4286136fe4556373efdebfb8c0559dfabe4d9df 100644 (file)
@@ -75,7 +75,8 @@ wayland_sw_winsys(struct sw_winsys *ws)
 static void
 wayland_displaytarget_display(struct sw_winsys *ws,
                               struct sw_displaytarget *dt,
-                              void *context_private)
+                              void *context_private,
+                              struct pipe_box *box)
 {
 }
 
index 6e71530e635c275809b3ad0badfdd47be59424bf..99da2ae991c421489da769b2811b5619e2f4ef93 100644 (file)
@@ -376,7 +376,8 @@ xlib_sw_display(struct xlib_drawable *xlib_drawable,
 static void
 xlib_displaytarget_display(struct sw_winsys *ws,
                            struct sw_displaytarget *dt,
-                           void *context_private)
+                           void *context_private,
+                           struct pipe_box *box)
 {
    struct xlib_drawable *xlib_drawable = (struct xlib_drawable *)context_private;
    xlib_sw_display(xlib_drawable, dt);
index cb1d650b5c19eb757a318ed1b94a7b395bcbf64f..13a4b96a1fb9db8f6a7c75544f3565382e640a57 100644 (file)
@@ -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,13 +200,21 @@ 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);
 
    ximage->data = NULL;
 }
 
+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,
@@ -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[] = {
@@ -584,6 +594,21 @@ driswSwapBuffers(__GLXDRIdrawable * pdraw,
    return 0;
 }
 
+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)
 {
@@ -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:
index 0bce77ea9c72ccb6c2433980454169deec780966..fd2eca715c37b1051c36dc10a35ac60a73196eaf 100644 (file)
@@ -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,
+};
index 79a8564ad5178af0d57c2ffd842dceed9f2b96f2..4cfa75dd3e467a5da39fc866503816928a18c4f4 100644 (file)
@@ -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;
index 0e1c530b39df93e350243d4cbfb9646de719d11a..7eed5a418cb02cc7d5453752d7fd7b65c13842e9 100644 (file)
@@ -820,6 +820,39 @@ dri_unbind_context(__DRIcontext * cPriv)
     return GL_TRUE;
 }
 
+static void
+dri_copy_sub_buffer(__DRIdrawable *dPriv, int x, int y,
+                    int w, int h)
+{
+    __DRIscreen *sPriv = dPriv->driScreenPriv;
+    void *data;
+    int iy;
+    struct dri_drawable *drawable = dri_drawable(dPriv);
+    struct gl_framebuffer *fb;
+    struct dri_swrast_renderbuffer *frontrb, *backrb;
+
+    TRACE;
+
+    fb = &drawable->Base;
+
+    frontrb =
+       dri_swrast_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
+    backrb =
+       dri_swrast_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
+
+    /* check for signle-buffered */
+    if (backrb == NULL)
+       return;
+
+    iy = frontrb->Base.Base.Height - y - h;
+    data = (char *)backrb->Base.Buffer + (iy * backrb->pitch) + (x * ((backrb->bpp + 7) / 8));
+    sPriv->swrast_loader->putImage2(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
+                                    x, iy, w, h,
+                                    frontrb->pitch,
+                                    data,
+                                    dPriv->loaderPrivate);
+}
+
 
 static const struct __DriverAPIRec swrast_driver_api = {
     .InitScreen = dri_init_screen,
@@ -831,6 +864,7 @@ static const struct __DriverAPIRec swrast_driver_api = {
     .SwapBuffers = dri_swap_buffers,
     .MakeCurrent = dri_make_current,
     .UnbindContext = dri_unbind_context,
+    .CopySubBuffer = dri_copy_sub_buffer,
 };
 
 static const struct __DRIDriverVtableExtensionRec swrast_vtable = {
@@ -841,6 +875,7 @@ static const struct __DRIDriverVtableExtensionRec swrast_vtable = {
 static const __DRIextension *swrast_driver_extensions[] = {
     &driCoreExtension.base,
     &driSWRastExtension.base,
+    &driCopySubBufferExtension.base,
     &swrast_vtable.base,
     NULL
 };