Blame SOURCES/0001-swrast-gallium-classic-add-MESA_copy_sub_buffer-supp.patch

13f4a0
From cbefe3f43f3d7e81367f7515512950b97fc0dd2c Mon Sep 17 00:00:00 2001
13f4a0
From: Dave Airlie <airlied@gmail.com>
13f4a0
Date: Thu, 28 Nov 2013 11:08:11 +1000
13f4a0
Subject: [PATCH] swrast* (gallium, classic): add MESA_copy_sub_buffer support
13f4a0
 (v3)
13f4a0
13f4a0
This patches add MESA_copy_sub_buffer support to the dri sw loader and
13f4a0
then to gallium state tracker, llvmpipe, softpipe and other bits.
13f4a0
13f4a0
It reuses the dri1 driver extension interface, and it updates the swrast
13f4a0
loader interface for a new putimage which can take a stride.
13f4a0
13f4a0
I've tested this with gnome-shell with a cogl hacked to reenable sub copies
13f4a0
for llvmpipe and the one piglit test.
13f4a0
13f4a0
I could probably split this patch up as well.
13f4a0
13f4a0
v2: pass a pipe_box, to reduce the entrypoints, as per Jose's review,
13f4a0
add to p_screen doc comments.
13f4a0
13f4a0
v3: finish off winsys interfaces, add swrast classic support as well.
13f4a0
13f4a0
Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
13f4a0
Signed-off-by: Dave Airlie <airlied@redhat.com>
13f4a0
13f4a0
swrast: add support for copy_sub_buffer
13f4a0
13f4a0
Conflicts:
13f4a0
	src/gallium/state_trackers/dri/sw/drisw.c
13f4a0
	src/gallium/targets/haiku-softpipe/GalliumContext.cpp
13f4a0
	src/mesa/drivers/dri/common/dri_util.c
13f4a0
	src/mesa/drivers/dri/swrast/swrast.c
13f4a0
---
13f4a0
 include/GL/internal/dri_interface.h                |  9 +++-
13f4a0
 src/gallium/auxiliary/vl/vl_winsys_dri.c           |  2 +-
13f4a0
 src/gallium/drivers/galahad/glhd_screen.c          |  5 +-
13f4a0
 src/gallium/drivers/i915/i915_screen.c             |  4 +-
13f4a0
 src/gallium/drivers/identity/id_screen.c           |  5 +-
13f4a0
 src/gallium/drivers/llvmpipe/lp_screen.c           |  6 +--
13f4a0
 src/gallium/drivers/noop/noop_pipe.c               |  2 +-
13f4a0
 src/gallium/drivers/rbug/rbug_screen.c             |  4 +-
13f4a0
 src/gallium/drivers/softpipe/sp_screen.c           |  5 +-
13f4a0
 src/gallium/drivers/trace/tr_screen.c              |  5 +-
13f4a0
 src/gallium/include/pipe/p_screen.h                |  7 +--
13f4a0
 src/gallium/include/state_tracker/drisw_api.h      |  2 +
13f4a0
 src/gallium/include/state_tracker/sw_winsys.h      |  5 +-
13f4a0
 src/gallium/state_trackers/dri/sw/drisw.c          | 58 ++++++++++++++++++++--
13f4a0
 .../state_trackers/egl/common/native_helper.c      |  2 +-
13f4a0
 src/gallium/state_trackers/egl/x11/native_ximage.c |  2 +-
13f4a0
 src/gallium/state_trackers/glx/xlib/xm_st.c        |  2 +-
13f4a0
 src/gallium/state_trackers/vdpau/presentation.c    |  2 +-
13f4a0
 src/gallium/state_trackers/xvmc/surface.c          |  2 +-
13f4a0
 src/gallium/tests/graw/clear.c                     |  2 +-
13f4a0
 src/gallium/tests/graw/fs-test.c                   |  2 +-
13f4a0
 src/gallium/tests/graw/graw_util.h                 |  2 +-
13f4a0
 src/gallium/tests/graw/gs-test.c                   |  2 +-
13f4a0
 src/gallium/tests/graw/quad-sample.c               |  2 +-
13f4a0
 src/gallium/tests/graw/shader-leak.c               |  2 +-
13f4a0
 src/gallium/tests/graw/tri-gs.c                    |  2 +-
13f4a0
 src/gallium/tests/graw/tri-instanced.c             |  2 +-
13f4a0
 src/gallium/tests/graw/vs-test.c                   |  2 +-
13f4a0
 .../winsys/sw/android/android_sw_winsys.cpp        |  3 +-
13f4a0
 src/gallium/winsys/sw/dri/dri_sw_winsys.c          | 16 ++++--
13f4a0
 src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c      |  3 +-
13f4a0
 src/gallium/winsys/sw/gdi/gdi_sw_winsys.c          |  3 +-
13f4a0
 src/gallium/winsys/sw/hgl/hgl_sw_winsys.c          |  3 +-
13f4a0
 src/gallium/winsys/sw/null/null_sw_winsys.c        |  3 +-
13f4a0
 src/gallium/winsys/sw/wayland/wayland_sw_winsys.c  |  3 +-
13f4a0
 src/gallium/winsys/sw/xlib/xlib_sw_winsys.c        |  3 +-
13f4a0
 src/glx/drisw_glx.c                                | 43 ++++++++++++++--
13f4a0
 src/mesa/drivers/dri/common/dri_util.h             |  5 +-
13f4a0
 src/mesa/drivers/dri/common/drisw_util.c           | 15 ++++++
13f4a0
 src/mesa/drivers/dri/swrast/swrast.c               | 35 +++++++++++++
13f4a0
 40 files changed, 225 insertions(+), 57 deletions(-)
13f4a0
13f4a0
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
13f4a0
index 5c99d55..09c1406 100644
13f4a0
--- a/include/GL/internal/dri_interface.h
13f4a0
+++ b/include/GL/internal/dri_interface.h
13f4a0
@@ -439,7 +439,7 @@ struct __DRIdamageExtensionRec {
13f4a0
  * SWRast Loader extension.
13f4a0
  */
13f4a0
 #define __DRI_SWRAST_LOADER "DRI_SWRastLoader"
13f4a0
-#define __DRI_SWRAST_LOADER_VERSION 1
13f4a0
+#define __DRI_SWRAST_LOADER_VERSION 2
13f4a0
 struct __DRIswrastLoaderExtensionRec {
13f4a0
     __DRIextension base;
13f4a0
 
13f4a0
@@ -463,6 +463,13 @@ struct __DRIswrastLoaderExtensionRec {
13f4a0
     void (*getImage)(__DRIdrawable *readable,
13f4a0
 		     int x, int y, int width, int height,
13f4a0
 		     char *data, void *loaderPrivate);
13f4a0
+
13f4a0
+    /**
13f4a0
+     * Put image to drawable
13f4a0
+     */
13f4a0
+    void (*putImage2)(__DRIdrawable *drawable, int op,
13f4a0
+                      int x, int y, int width, int height, int stride,
13f4a0
+                      char *data, void *loaderPrivate);
13f4a0
 };
13f4a0
 
13f4a0
 /**
13f4a0
diff --git a/src/gallium/auxiliary/vl/vl_winsys_dri.c b/src/gallium/auxiliary/vl/vl_winsys_dri.c
13f4a0
index 7aec3fe..e747a66 100644
13f4a0
--- a/src/gallium/auxiliary/vl/vl_winsys_dri.c
13f4a0
+++ b/src/gallium/auxiliary/vl/vl_winsys_dri.c
13f4a0
@@ -115,7 +115,7 @@ static void
13f4a0
 vl_dri2_flush_frontbuffer(struct pipe_screen *screen,
13f4a0
                           struct pipe_resource *resource,
13f4a0
                           unsigned level, unsigned layer,
13f4a0
-                          void *context_private)
13f4a0
+                          void *context_private, struct pipe_box *sub_box)
13f4a0
 {
13f4a0
    struct vl_dri_screen *scrn = (struct vl_dri_screen*)context_private;
13f4a0
    uint32_t msc_hi, msc_lo;
13f4a0
diff --git a/src/gallium/drivers/galahad/glhd_screen.c b/src/gallium/drivers/galahad/glhd_screen.c
13f4a0
index 16a5ff1..5a91077 100644
13f4a0
--- a/src/gallium/drivers/galahad/glhd_screen.c
13f4a0
+++ b/src/gallium/drivers/galahad/glhd_screen.c
13f4a0
@@ -275,7 +275,8 @@ static void
13f4a0
 galahad_screen_flush_frontbuffer(struct pipe_screen *_screen,
13f4a0
                                   struct pipe_resource *_resource,
13f4a0
                                   unsigned level, unsigned layer,
13f4a0
-                                  void *context_private)
13f4a0
+                                  void *context_private,
13f4a0
+                                  struct pipe_box *sub_box)
13f4a0
 {
13f4a0
    struct galahad_screen *glhd_screen = galahad_screen(_screen);
13f4a0
    struct galahad_resource *glhd_resource = galahad_resource(_resource);
13f4a0
@@ -285,7 +286,7 @@ galahad_screen_flush_frontbuffer(struct pipe_screen *_screen,
13f4a0
    screen->flush_frontbuffer(screen,
13f4a0
                              resource,
13f4a0
                              level, layer,
13f4a0
-                             context_private);
13f4a0
+                             context_private, sub_box);
13f4a0
 }
13f4a0
 
13f4a0
 static void
13f4a0
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
13f4a0
index 556dda8..0ff2640 100644
13f4a0
--- a/src/gallium/drivers/i915/i915_screen.c
13f4a0
+++ b/src/gallium/drivers/i915/i915_screen.c
13f4a0
@@ -419,7 +419,8 @@ static void
13f4a0
 i915_flush_frontbuffer(struct pipe_screen *screen,
13f4a0
                        struct pipe_resource *resource,
13f4a0
                        unsigned level, unsigned layer,
13f4a0
-                       void *winsys_drawable_handle)
13f4a0
+                       void *winsys_drawable_handle,
13f4a0
+                       struct pipe_box *sub_box)
13f4a0
 {
13f4a0
    /* XXX: Dummy right now. */
13f4a0
    (void)screen;
13f4a0
@@ -427,6 +428,7 @@ i915_flush_frontbuffer(struct pipe_screen *screen,
13f4a0
    (void)level;
13f4a0
    (void)layer;
13f4a0
    (void)winsys_drawable_handle;
13f4a0
+   (void)sub_box;
13f4a0
 }
13f4a0
 
13f4a0
 static void
13f4a0
diff --git a/src/gallium/drivers/identity/id_screen.c b/src/gallium/drivers/identity/id_screen.c
13f4a0
index 26df7f6..28cfa1f6 100644
13f4a0
--- a/src/gallium/drivers/identity/id_screen.c
13f4a0
+++ b/src/gallium/drivers/identity/id_screen.c
13f4a0
@@ -192,7 +192,8 @@ static void
13f4a0
 identity_screen_flush_frontbuffer(struct pipe_screen *_screen,
13f4a0
                                   struct pipe_resource *_resource,
13f4a0
                                   unsigned level, unsigned layer,
13f4a0
-                                  void *context_private)
13f4a0
+                                  void *context_private,
13f4a0
+                                  struct pipe_box *sub_box)
13f4a0
 {
13f4a0
    struct identity_screen *id_screen = identity_screen(_screen);
13f4a0
    struct identity_resource *id_resource = identity_resource(_resource);
13f4a0
@@ -202,7 +203,7 @@ identity_screen_flush_frontbuffer(struct pipe_screen *_screen,
13f4a0
    screen->flush_frontbuffer(screen,
13f4a0
                              resource,
13f4a0
                              level, layer,
13f4a0
-                             context_private);
13f4a0
+                             context_private, sub_box);
13f4a0
 }
13f4a0
 
13f4a0
 static void
13f4a0
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
13f4a0
index b3cd77f..f488d6d 100644
13f4a0
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
13f4a0
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
13f4a0
@@ -403,7 +403,8 @@ static void
13f4a0
 llvmpipe_flush_frontbuffer(struct pipe_screen *_screen,
13f4a0
                            struct pipe_resource *resource,
13f4a0
                            unsigned level, unsigned layer,
13f4a0
-                           void *context_private)
13f4a0
+                           void *context_private,
13f4a0
+                           struct pipe_box *sub_box)
13f4a0
 {
13f4a0
    struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
13f4a0
    struct sw_winsys *winsys = screen->winsys;
13f4a0
@@ -411,10 +412,9 @@ llvmpipe_flush_frontbuffer(struct pipe_screen *_screen,
13f4a0
 
13f4a0
    assert(texture->dt);
13f4a0
    if (texture->dt)
13f4a0
-      winsys->displaytarget_display(winsys, texture->dt, context_private);
13f4a0
+      winsys->displaytarget_display(winsys, texture->dt, context_private, sub_box);
13f4a0
 }
13f4a0
 
13f4a0
-
13f4a0
 static void
13f4a0
 llvmpipe_destroy_screen( struct pipe_screen *_screen )
13f4a0
 {
13f4a0
diff --git a/src/gallium/drivers/noop/noop_pipe.c b/src/gallium/drivers/noop/noop_pipe.c
13f4a0
index ac837b1..849a4d1 100644
13f4a0
--- a/src/gallium/drivers/noop/noop_pipe.c
13f4a0
+++ b/src/gallium/drivers/noop/noop_pipe.c
13f4a0
@@ -288,7 +288,7 @@ static struct pipe_context *noop_create_context(struct pipe_screen *screen, void
13f4a0
 static void noop_flush_frontbuffer(struct pipe_screen *_screen,
13f4a0
 				   struct pipe_resource *resource,
13f4a0
 				   unsigned level, unsigned layer,
13f4a0
-				   void *context_private)
13f4a0
+				   void *context_private, struct pipe_box *box)
13f4a0
 {
13f4a0
 }
13f4a0
 
13f4a0
diff --git a/src/gallium/drivers/rbug/rbug_screen.c b/src/gallium/drivers/rbug/rbug_screen.c
13f4a0
index 2471fdb..8576e2f 100644
13f4a0
--- a/src/gallium/drivers/rbug/rbug_screen.c
13f4a0
+++ b/src/gallium/drivers/rbug/rbug_screen.c
13f4a0
@@ -190,7 +190,7 @@ static void
13f4a0
 rbug_screen_flush_frontbuffer(struct pipe_screen *_screen,
13f4a0
                               struct pipe_resource *_resource,
13f4a0
                               unsigned level, unsigned layer,
13f4a0
-                              void *context_private)
13f4a0
+                              void *context_private, struct pipe_box *sub_box)
13f4a0
 {
13f4a0
    struct rbug_screen *rb_screen = rbug_screen(_screen);
13f4a0
    struct rbug_resource *rb_resource = rbug_resource(_resource);
13f4a0
@@ -200,7 +200,7 @@ rbug_screen_flush_frontbuffer(struct pipe_screen *_screen,
13f4a0
    screen->flush_frontbuffer(screen,
13f4a0
                              resource,
13f4a0
                              level, layer,
13f4a0
-                             context_private);
13f4a0
+                             context_private, sub_box);
13f4a0
 }
13f4a0
 
13f4a0
 static void
13f4a0
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
13f4a0
index f6acdc8..3e3f366 100644
13f4a0
--- a/src/gallium/drivers/softpipe/sp_screen.c
13f4a0
+++ b/src/gallium/drivers/softpipe/sp_screen.c
13f4a0
@@ -364,7 +364,8 @@ static void
13f4a0
 softpipe_flush_frontbuffer(struct pipe_screen *_screen,
13f4a0
                            struct pipe_resource *resource,
13f4a0
                            unsigned level, unsigned layer,
13f4a0
-                           void *context_private)
13f4a0
+                           void *context_private,
13f4a0
+                           struct pipe_box *sub_box)
13f4a0
 {
13f4a0
    struct softpipe_screen *screen = softpipe_screen(_screen);
13f4a0
    struct sw_winsys *winsys = screen->winsys;
13f4a0
@@ -372,7 +373,7 @@ softpipe_flush_frontbuffer(struct pipe_screen *_screen,
13f4a0
 
13f4a0
    assert(texture->dt);
13f4a0
    if (texture->dt)
13f4a0
-      winsys->displaytarget_display(winsys, texture->dt, context_private);
13f4a0
+      winsys->displaytarget_display(winsys, texture->dt, context_private, sub_box);
13f4a0
 }
13f4a0
 
13f4a0
 static uint64_t
13f4a0
diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c
13f4a0
index 5281ba8..b71ebbe 100644
13f4a0
--- a/src/gallium/drivers/trace/tr_screen.c
13f4a0
+++ b/src/gallium/drivers/trace/tr_screen.c
13f4a0
@@ -210,7 +210,8 @@ static void
13f4a0
 trace_screen_flush_frontbuffer(struct pipe_screen *_screen,
13f4a0
                                struct pipe_resource *_resource,
13f4a0
                                unsigned level, unsigned layer,
13f4a0
-                               void *context_private)
13f4a0
+                               void *context_private,
13f4a0
+                               struct pipe_box *sub_box)
13f4a0
 {
13f4a0
    struct trace_screen *tr_scr = trace_screen(_screen);
13f4a0
    struct trace_resource *tr_res = trace_resource(_resource);
13f4a0
@@ -227,7 +228,7 @@ trace_screen_flush_frontbuffer(struct pipe_screen *_screen,
13f4a0
    trace_dump_arg(ptr, context_private);
13f4a0
    */
13f4a0
 
13f4a0
-   screen->flush_frontbuffer(screen, resource, level, layer, context_private);
13f4a0
+   screen->flush_frontbuffer(screen, resource, level, layer, context_private, sub_box);
13f4a0
 
13f4a0
    trace_dump_call_end();
13f4a0
 }
13f4a0
diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
13f4a0
index c487e8e..c0f4fd1 100644
13f4a0
--- a/src/gallium/include/pipe/p_screen.h
13f4a0
+++ b/src/gallium/include/pipe/p_screen.h
13f4a0
@@ -56,6 +56,7 @@ struct pipe_fence_handle;
13f4a0
 struct pipe_resource;
13f4a0
 struct pipe_surface;
13f4a0
 struct pipe_transfer;
13f4a0
+struct pipe_box;
13f4a0
 
13f4a0
 
13f4a0
 /**
13f4a0
@@ -179,13 +180,13 @@ struct pipe_screen {
13f4a0
     * displayed, eg copy fake frontbuffer.
13f4a0
     * \param winsys_drawable_handle  an opaque handle that the calling context
13f4a0
     *                                gets out-of-band
13f4a0
+    * \param subbox an optional sub region to flush
13f4a0
     */
13f4a0
    void (*flush_frontbuffer)( struct pipe_screen *screen,
13f4a0
                               struct pipe_resource *resource,
13f4a0
                               unsigned level, unsigned layer,
13f4a0
-                              void *winsys_drawable_handle );
13f4a0
-
13f4a0
-
13f4a0
+                              void *winsys_drawable_handle,
13f4a0
+                              struct pipe_box *subbox );
13f4a0
 
13f4a0
    /** Set ptr = fence, with reference counting */
13f4a0
    void (*fence_reference)( struct pipe_screen *screen,
13f4a0
diff --git a/src/gallium/include/state_tracker/drisw_api.h b/src/gallium/include/state_tracker/drisw_api.h
13f4a0
index 944a649..328440c 100644
13f4a0
--- a/src/gallium/include/state_tracker/drisw_api.h
13f4a0
+++ b/src/gallium/include/state_tracker/drisw_api.h
13f4a0
@@ -13,6 +13,8 @@ struct drisw_loader_funcs
13f4a0
 {
13f4a0
    void (*put_image) (struct dri_drawable *dri_drawable,
13f4a0
                       void *data, unsigned width, unsigned height);
13f4a0
+   void (*put_image2) (struct dri_drawable *dri_drawable,
13f4a0
+                       void *data, int x, int y, unsigned width, unsigned height, unsigned stride);
13f4a0
 };
13f4a0
 
13f4a0
 /**
13f4a0
diff --git a/src/gallium/include/state_tracker/sw_winsys.h b/src/gallium/include/state_tracker/sw_winsys.h
13f4a0
index 0b11fe3..d08ddd6 100644
13f4a0
--- a/src/gallium/include/state_tracker/sw_winsys.h
13f4a0
+++ b/src/gallium/include/state_tracker/sw_winsys.h
13f4a0
@@ -48,7 +48,7 @@ struct winsys_handle;
13f4a0
 struct pipe_screen;
13f4a0
 struct pipe_context;
13f4a0
 struct pipe_resource;
13f4a0
-
13f4a0
+struct pipe_box;
13f4a0
 
13f4a0
 /**
13f4a0
  * Opaque pointer.
13f4a0
@@ -129,7 +129,8 @@ struct sw_winsys
13f4a0
    void
13f4a0
    (*displaytarget_display)( struct sw_winsys *ws, 
13f4a0
                              struct sw_displaytarget *dt,
13f4a0
-                             void *context_private );
13f4a0
+                             void *context_private,
13f4a0
+                             struct pipe_box *box );
13f4a0
 
13f4a0
    void 
13f4a0
    (*displaytarget_destroy)( struct sw_winsys *ws, 
13f4a0
diff --git a/src/gallium/state_trackers/dri/sw/drisw.c b/src/gallium/state_trackers/dri/sw/drisw.c
13f4a0
index 121a205..aa0d3e0 100644
13f4a0
--- a/src/gallium/state_trackers/dri/sw/drisw.c
13f4a0
+++ b/src/gallium/state_trackers/dri/sw/drisw.c
13f4a0
@@ -37,6 +37,7 @@
13f4a0
 #include "util/u_format.h"
13f4a0
 #include "util/u_memory.h"
13f4a0
 #include "util/u_inlines.h"
13f4a0
+#include "util/u_box.h"
13f4a0
 #include "pipe/p_context.h"
13f4a0
 #include "state_tracker/drisw_api.h"
13f4a0
 #include "state_tracker/st_context.h"
13f4a0
@@ -71,6 +72,18 @@ put_image(__DRIdrawable *dPriv, void *data, unsigned width, unsigned height)
13f4a0
 }
13f4a0
 
13f4a0
 static INLINE void
13f4a0
+put_image2(__DRIdrawable *dPriv, void *data, int x, int y,
13f4a0
+           unsigned width, unsigned height, unsigned stride)
13f4a0
+{
13f4a0
+   __DRIscreen *sPriv = dPriv->driScreenPriv;
13f4a0
+   const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
13f4a0
+
13f4a0
+   loader->putImage2(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
13f4a0
+                     x, y, width, height, stride,
13f4a0
+                     data, dPriv->loaderPrivate);
13f4a0
+}
13f4a0
+
13f4a0
+static INLINE void
13f4a0
 get_image(__DRIdrawable *dPriv, int x, int y, int width, int height, void *data)
13f4a0
 {
13f4a0
    __DRIscreen *sPriv = dPriv->driScreenPriv;
13f4a0
@@ -99,9 +112,19 @@ drisw_put_image(struct dri_drawable *drawable,
13f4a0
    put_image(dPriv, data, width, height);
13f4a0
 }
13f4a0
 
13f4a0
+static void
13f4a0
+drisw_put_image2(struct dri_drawable *drawable,
13f4a0
+                 void *data, int x, int y, unsigned width, unsigned height,
13f4a0
+                 unsigned stride)
13f4a0
+{
13f4a0
+   __DRIdrawable *dPriv = drawable->dPriv;
13f4a0
+
13f4a0
+   put_image2(dPriv, data, x, y, width, height, stride);
13f4a0
+}
13f4a0
+
13f4a0
 static INLINE void
13f4a0
 drisw_present_texture(__DRIdrawable *dPriv,
13f4a0
-                      struct pipe_resource *ptex)
13f4a0
+                      struct pipe_resource *ptex, struct pipe_box *sub_box)
13f4a0
 {
13f4a0
    struct dri_drawable *drawable = dri_drawable(dPriv);
13f4a0
    struct dri_screen *screen = dri_screen(drawable->sPriv);
13f4a0
@@ -109,7 +132,7 @@ drisw_present_texture(__DRIdrawable *dPriv,
13f4a0
    if (swrast_no_present)
13f4a0
       return;
13f4a0
 
13f4a0
-   screen->base.screen->flush_frontbuffer(screen->base.screen, ptex, 0, 0, drawable);
13f4a0
+   screen->base.screen->flush_frontbuffer(screen->base.screen, ptex, 0, 0, drawable, sub_box);
13f4a0
 }
13f4a0
 
13f4a0
 static INLINE void
13f4a0
@@ -126,7 +149,7 @@ static INLINE void
13f4a0
 drisw_copy_to_front(__DRIdrawable * dPriv,
13f4a0
                     struct pipe_resource *ptex)
13f4a0
 {
13f4a0
-   drisw_present_texture(dPriv, ptex);
13f4a0
+   drisw_present_texture(dPriv, ptex, NULL);
13f4a0
 
13f4a0
    drisw_invalidate_drawable(dPriv);
13f4a0
 }
13f4a0
@@ -158,6 +181,30 @@ drisw_swap_buffers(__DRIdrawable *dPriv)
13f4a0
 }
13f4a0
 
13f4a0
 static void
13f4a0
+drisw_copy_sub_buffer(__DRIdrawable *dPriv, int x, int y,
13f4a0
+                      int w, int h)
13f4a0
+{
13f4a0
+   struct dri_context *ctx = dri_get_current(dPriv->driScreenPriv);
13f4a0
+   struct dri_drawable *drawable = dri_drawable(dPriv);
13f4a0
+   struct pipe_resource *ptex;
13f4a0
+   struct pipe_box box;
13f4a0
+   if (!ctx)
13f4a0
+      return;
13f4a0
+
13f4a0
+   ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
13f4a0
+
13f4a0
+   if (ptex) {
13f4a0
+      if (ctx->pp && drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL])
13f4a0
+         pp_run(ctx->pp, ptex, ptex, drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL]);
13f4a0
+
13f4a0
+      ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL);
13f4a0
+
13f4a0
+      u_box_2d(x, dPriv->h - y - h, w, h, &box);
13f4a0
+      drisw_present_texture(dPriv, ptex, &box);
13f4a0
+   }
13f4a0
+}
13f4a0
+
13f4a0
+static void
13f4a0
 drisw_flush_frontbuffer(struct dri_context *ctx,
13f4a0
                         struct dri_drawable *drawable,
13f4a0
                         enum st_attachment_type statt)
13f4a0
@@ -288,7 +335,8 @@ static const __DRIextension *drisw_screen_extensions[] = {
13f4a0
 };
13f4a0
 
13f4a0
 static struct drisw_loader_funcs drisw_lf = {
13f4a0
-   .put_image = drisw_put_image
13f4a0
+   .put_image = drisw_put_image,
13f4a0
+   .put_image2 = drisw_put_image2
13f4a0
 };
13f4a0
 
13f4a0
 static const __DRIconfig **
13f4a0
@@ -359,12 +407,14 @@ const struct __DriverAPIRec driDriverAPI = {
13f4a0
    .SwapBuffers = drisw_swap_buffers,
13f4a0
    .MakeCurrent = dri_make_current,
13f4a0
    .UnbindContext = dri_unbind_context,
13f4a0
+   .CopySubBuffer = drisw_copy_sub_buffer,
13f4a0
 };
13f4a0
 
13f4a0
 /* This is the table of extensions that the loader will dlsym() for. */
13f4a0
 PUBLIC const __DRIextension *__driDriverExtensions[] = {
13f4a0
     &driCoreExtension.base,
13f4a0
     &driSWRastExtension.base,
13f4a0
+    &driCopySubBufferExtension.base,
13f4a0
     NULL
13f4a0
 };
13f4a0
 
13f4a0
diff --git a/src/gallium/state_trackers/egl/common/native_helper.c b/src/gallium/state_trackers/egl/common/native_helper.c
13f4a0
index b578a8a..5c2be19 100644
13f4a0
--- a/src/gallium/state_trackers/egl/common/native_helper.c
13f4a0
+++ b/src/gallium/state_trackers/egl/common/native_helper.c
13f4a0
@@ -244,7 +244,7 @@ resource_surface_present(struct resource_surface *rsurf,
13f4a0
       return TRUE;
13f4a0
 
13f4a0
    rsurf->screen->flush_frontbuffer(rsurf->screen,
13f4a0
-         pres, 0, 0, winsys_drawable_handle);
13f4a0
+         pres, 0, 0, winsys_drawable_handle, NULL);
13f4a0
 
13f4a0
    return TRUE;
13f4a0
 }
13f4a0
diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c
13f4a0
index 28c6442..019e535 100644
13f4a0
--- a/src/gallium/state_trackers/egl/x11/native_ximage.c
13f4a0
+++ b/src/gallium/state_trackers/egl/x11/native_ximage.c
13f4a0
@@ -476,7 +476,7 @@ ximage_display_copy_to_pixmap(struct native_display *ndpy,
13f4a0
       xdraw.drawable = (Drawable) pix;
13f4a0
 
13f4a0
       xdpy->base.screen->flush_frontbuffer(xdpy->base.screen,
13f4a0
-            src, 0, 0, &xdraw);
13f4a0
+            src, 0, 0, &xdraw, NULL);
13f4a0
 
13f4a0
       return TRUE;
13f4a0
    }
13f4a0
diff --git a/src/gallium/state_trackers/glx/xlib/xm_st.c b/src/gallium/state_trackers/glx/xlib/xm_st.c
13f4a0
index fb69998..7f73a3a 100644
13f4a0
--- a/src/gallium/state_trackers/glx/xlib/xm_st.c
13f4a0
+++ b/src/gallium/state_trackers/glx/xlib/xm_st.c
13f4a0
@@ -74,7 +74,7 @@ xmesa_st_framebuffer_display(struct st_framebuffer_iface *stfbi,
13f4a0
       pres = xstfb->display_resource;
13f4a0
    }
13f4a0
 
13f4a0
-   xstfb->screen->flush_frontbuffer(xstfb->screen, pres, 0, 0, &xstfb->buffer->ws);
13f4a0
+   xstfb->screen->flush_frontbuffer(xstfb->screen, pres, 0, 0, &xstfb->buffer->ws, NULL);
13f4a0
    return TRUE;
13f4a0
 }
13f4a0
 
13f4a0
diff --git a/src/gallium/state_trackers/vdpau/presentation.c b/src/gallium/state_trackers/vdpau/presentation.c
13f4a0
index c9f8ea7..e68e25f 100644
13f4a0
--- a/src/gallium/state_trackers/vdpau/presentation.c
13f4a0
+++ b/src/gallium/state_trackers/vdpau/presentation.c
13f4a0
@@ -269,7 +269,7 @@ vlVdpPresentationQueueDisplay(VdpPresentationQueue presentation_queue,
13f4a0
    pipe->screen->flush_frontbuffer
13f4a0
    (
13f4a0
       pipe->screen, tex, 0, 0,
13f4a0
-      vl_screen_get_private(pq->device->vscreen)
13f4a0
+      vl_screen_get_private(pq->device->vscreen), NULL
13f4a0
    );
13f4a0
 
13f4a0
    pipe->screen->fence_reference(pipe->screen, &surf->fence, NULL);
13f4a0
diff --git a/src/gallium/state_trackers/xvmc/surface.c b/src/gallium/state_trackers/xvmc/surface.c
13f4a0
index 6a895aa..ea778a3 100644
13f4a0
--- a/src/gallium/state_trackers/xvmc/surface.c
13f4a0
+++ b/src/gallium/state_trackers/xvmc/surface.c
13f4a0
@@ -441,7 +441,7 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
13f4a0
    pipe->screen->flush_frontbuffer
13f4a0
    (
13f4a0
       pipe->screen, tex, 0, 0,
13f4a0
-      vl_screen_get_private(context_priv->vscreen)
13f4a0
+      vl_screen_get_private(context_priv->vscreen), NULL
13f4a0
    );
13f4a0
 
13f4a0
    if(dump_window == -1) {
13f4a0
diff --git a/src/gallium/tests/graw/clear.c b/src/gallium/tests/graw/clear.c
13f4a0
index 77c59db..f38da47 100644
13f4a0
--- a/src/gallium/tests/graw/clear.c
13f4a0
+++ b/src/gallium/tests/graw/clear.c
13f4a0
@@ -33,7 +33,7 @@ static void draw( void )
13f4a0
 
13f4a0
    graw_save_surface_to_file(ctx, surf, NULL);
13f4a0
 
13f4a0
-   screen->flush_frontbuffer(screen, tex, 0, 0, window);
13f4a0
+   screen->flush_frontbuffer(screen, tex, 0, 0, window, NULL);
13f4a0
 }
13f4a0
 
13f4a0
 static void init( void )
13f4a0
diff --git a/src/gallium/tests/graw/fs-test.c b/src/gallium/tests/graw/fs-test.c
13f4a0
index 38a2c4b..a01c014 100644
13f4a0
--- a/src/gallium/tests/graw/fs-test.c
13f4a0
+++ b/src/gallium/tests/graw/fs-test.c
13f4a0
@@ -240,7 +240,7 @@ static void draw( void )
13f4a0
 
13f4a0
    graw_save_surface_to_file(ctx, surf, NULL);
13f4a0
 
13f4a0
-   screen->flush_frontbuffer(screen, rttex, 0, 0, window);
13f4a0
+   screen->flush_frontbuffer(screen, rttex, 0, 0, window, NULL);
13f4a0
 }
13f4a0
 
13f4a0
 #define SIZE 16
13f4a0
diff --git a/src/gallium/tests/graw/graw_util.h b/src/gallium/tests/graw/graw_util.h
13f4a0
index 8557285..1856f0d 100644
13f4a0
--- a/src/gallium/tests/graw/graw_util.h
13f4a0
+++ b/src/gallium/tests/graw/graw_util.h
13f4a0
@@ -211,7 +211,7 @@ static INLINE void
13f4a0
 graw_util_flush_front(const struct graw_info *info)
13f4a0
 {
13f4a0
    info->screen->flush_frontbuffer(info->screen, info->color_buf[0],
13f4a0
-                                   0, 0, info->window);
13f4a0
+                                   0, 0, info->window, NULL);
13f4a0
 }
13f4a0
 
13f4a0
 
13f4a0
diff --git a/src/gallium/tests/graw/gs-test.c b/src/gallium/tests/graw/gs-test.c
13f4a0
index e4e4f61..1745c84 100644
13f4a0
--- a/src/gallium/tests/graw/gs-test.c
13f4a0
+++ b/src/gallium/tests/graw/gs-test.c
13f4a0
@@ -347,7 +347,7 @@ static void draw( void )
13f4a0
 
13f4a0
    graw_save_surface_to_file(ctx, surf, NULL);
13f4a0
 
13f4a0
-   screen->flush_frontbuffer(screen, rttex, 0, 0, window);
13f4a0
+   screen->flush_frontbuffer(screen, rttex, 0, 0, window, NULL);
13f4a0
 }
13f4a0
 
13f4a0
 #define SIZE 16
13f4a0
diff --git a/src/gallium/tests/graw/quad-sample.c b/src/gallium/tests/graw/quad-sample.c
13f4a0
index 969ffa7..9960c30 100644
13f4a0
--- a/src/gallium/tests/graw/quad-sample.c
13f4a0
+++ b/src/gallium/tests/graw/quad-sample.c
13f4a0
@@ -156,7 +156,7 @@ static void draw( void )
13f4a0
 
13f4a0
    graw_save_surface_to_file(ctx, surf, NULL);
13f4a0
 
13f4a0
-   screen->flush_frontbuffer(screen, rttex, 0, 0, window);
13f4a0
+   screen->flush_frontbuffer(screen, rttex, 0, 0, window, NULL);
13f4a0
 }
13f4a0
 
13f4a0
 #define SIZE 16
13f4a0
diff --git a/src/gallium/tests/graw/shader-leak.c b/src/gallium/tests/graw/shader-leak.c
13f4a0
index 4ef752b..754ada6 100644
13f4a0
--- a/src/gallium/tests/graw/shader-leak.c
13f4a0
+++ b/src/gallium/tests/graw/shader-leak.c
13f4a0
@@ -158,7 +158,7 @@ static void draw( void )
13f4a0
       ctx->delete_fs_state(ctx, fs);
13f4a0
    }
13f4a0
 
13f4a0
-   screen->flush_frontbuffer(screen, tex, 0, 0, window);
13f4a0
+   screen->flush_frontbuffer(screen, tex, 0, 0, window, NULL);
13f4a0
    ctx->destroy(ctx);
13f4a0
 
13f4a0
    exit(0);
13f4a0
diff --git a/src/gallium/tests/graw/tri-gs.c b/src/gallium/tests/graw/tri-gs.c
13f4a0
index 37323aa..24de12b 100644
13f4a0
--- a/src/gallium/tests/graw/tri-gs.c
13f4a0
+++ b/src/gallium/tests/graw/tri-gs.c
13f4a0
@@ -168,7 +168,7 @@ static void draw( void )
13f4a0
    util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3);
13f4a0
    ctx->flush(ctx, NULL, 0);
13f4a0
 
13f4a0
-   screen->flush_frontbuffer(screen, tex, 0, 0, window);
13f4a0
+   screen->flush_frontbuffer(screen, tex, 0, 0, window, NULL);
13f4a0
 }
13f4a0
 
13f4a0
 
13f4a0
diff --git a/src/gallium/tests/graw/tri-instanced.c b/src/gallium/tests/graw/tri-instanced.c
13f4a0
index f84463d..55bc3a5 100644
13f4a0
--- a/src/gallium/tests/graw/tri-instanced.c
13f4a0
+++ b/src/gallium/tests/graw/tri-instanced.c
13f4a0
@@ -219,7 +219,7 @@ static void draw( void )
13f4a0
 
13f4a0
    graw_save_surface_to_file(ctx, surf, NULL);
13f4a0
 
13f4a0
-   screen->flush_frontbuffer(screen, tex, 0, 0, window);
13f4a0
+   screen->flush_frontbuffer(screen, tex, 0, 0, window, NULL);
13f4a0
 }
13f4a0
 
13f4a0
 
13f4a0
diff --git a/src/gallium/tests/graw/vs-test.c b/src/gallium/tests/graw/vs-test.c
13f4a0
index 5a7d0a0..ce1941d 100644
13f4a0
--- a/src/gallium/tests/graw/vs-test.c
13f4a0
+++ b/src/gallium/tests/graw/vs-test.c
13f4a0
@@ -234,7 +234,7 @@ static void draw( void )
13f4a0
 
13f4a0
    graw_save_surface_to_file(ctx, surf, NULL);
13f4a0
 
13f4a0
-   screen->flush_frontbuffer(screen, rttex, 0, 0, window);
13f4a0
+   screen->flush_frontbuffer(screen, rttex, 0, 0, window, NULL);
13f4a0
 }
13f4a0
 
13f4a0
 #define SIZE 16
13f4a0
diff --git a/src/gallium/winsys/sw/android/android_sw_winsys.cpp b/src/gallium/winsys/sw/android/android_sw_winsys.cpp
13f4a0
index cb91aad..4b1040c 100644
13f4a0
--- a/src/gallium/winsys/sw/android/android_sw_winsys.cpp
13f4a0
+++ b/src/gallium/winsys/sw/android/android_sw_winsys.cpp
13f4a0
@@ -74,7 +74,8 @@ namespace android {
13f4a0
 static void
13f4a0
 android_displaytarget_display(struct sw_winsys *ws,
13f4a0
                               struct sw_displaytarget *dt,
13f4a0
-                              void *context_private)
13f4a0
+                              void *context_private,
13f4a0
+                              struct pipe_box *box)
13f4a0
 {
13f4a0
 }
13f4a0
 
13f4a0
diff --git a/src/gallium/winsys/sw/dri/dri_sw_winsys.c b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
13f4a0
index edb3a38..6fed22b 100644
13f4a0
--- a/src/gallium/winsys/sw/dri/dri_sw_winsys.c
13f4a0
+++ b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
13f4a0
@@ -166,25 +166,33 @@ dri_sw_displaytarget_get_handle(struct sw_winsys *winsys,
13f4a0
 static void
13f4a0
 dri_sw_displaytarget_display(struct sw_winsys *ws,
13f4a0
                              struct sw_displaytarget *dt,
13f4a0
-                             void *context_private)
13f4a0
+                             void *context_private,
13f4a0
+                             struct pipe_box *box)
13f4a0
 {
13f4a0
    struct dri_sw_winsys *dri_sw_ws = dri_sw_winsys(ws);
13f4a0
    struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
13f4a0
    struct dri_drawable *dri_drawable = (struct dri_drawable *)context_private;
13f4a0
    unsigned width, height;
13f4a0
+   unsigned blsize = util_format_get_blocksize(dri_sw_dt->format);
13f4a0
 
13f4a0
    /* Set the width to 'stride / cpp'.
13f4a0
     *
13f4a0
     * PutImage correctly clips to the width of the dst drawable.
13f4a0
     */
13f4a0
-   width = dri_sw_dt->stride / util_format_get_blocksize(dri_sw_dt->format);
13f4a0
+   width = dri_sw_dt->stride / blsize;
13f4a0
 
13f4a0
    height = dri_sw_dt->height;
13f4a0
 
13f4a0
-   dri_sw_ws->lf->put_image(dri_drawable, dri_sw_dt->data, width, height);
13f4a0
+   if (box) {
13f4a0
+       void *data;
13f4a0
+       data = dri_sw_dt->data + (dri_sw_dt->stride * box->y) + box->x * blsize;
13f4a0
+       dri_sw_ws->lf->put_image2(dri_drawable, data,
13f4a0
+                                 box->x, box->y, box->width, box->height, dri_sw_dt->stride);
13f4a0
+   } else {
13f4a0
+       dri_sw_ws->lf->put_image(dri_drawable, dri_sw_dt->data, width, height);
13f4a0
+   }
13f4a0
 }
13f4a0
 
13f4a0
-
13f4a0
 static void
13f4a0
 dri_destroy_sw_winsys(struct sw_winsys *winsys)
13f4a0
 {
13f4a0
diff --git a/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c b/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c
13f4a0
index a280985..cc3ce1a 100644
13f4a0
--- a/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c
13f4a0
+++ b/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c
13f4a0
@@ -74,7 +74,8 @@ fbdev_sw_winsys(struct sw_winsys *ws)
13f4a0
 static void
13f4a0
 fbdev_displaytarget_display(struct sw_winsys *ws,
13f4a0
                             struct sw_displaytarget *dt,
13f4a0
-                            void *winsys_private)
13f4a0
+                            void *winsys_private,
13f4a0
+                            struct pipe_box *box)
13f4a0
 {
13f4a0
    struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws);
13f4a0
    struct fbdev_sw_displaytarget *src = fbdev_sw_displaytarget(dt);
13f4a0
diff --git a/src/gallium/winsys/sw/gdi/gdi_sw_winsys.c b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.c
13f4a0
index 2e12f6e..aae3ec5 100644
13f4a0
--- a/src/gallium/winsys/sw/gdi/gdi_sw_winsys.c
13f4a0
+++ b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.c
13f4a0
@@ -207,7 +207,8 @@ gdi_sw_display( struct sw_winsys *winsys,
13f4a0
 static void
13f4a0
 gdi_sw_displaytarget_display(struct sw_winsys *winsys, 
13f4a0
                              struct sw_displaytarget *dt,
13f4a0
-                             void *context_private)
13f4a0
+                             void *context_private,
13f4a0
+                             struct pipe_box *box)
13f4a0
 {
13f4a0
     /* nasty:
13f4a0
      */
13f4a0
diff --git a/src/gallium/winsys/sw/hgl/hgl_sw_winsys.c b/src/gallium/winsys/sw/hgl/hgl_sw_winsys.c
13f4a0
index 1d51dd6..f09272a 100644
13f4a0
--- a/src/gallium/winsys/sw/hgl/hgl_sw_winsys.c
13f4a0
+++ b/src/gallium/winsys/sw/hgl/hgl_sw_winsys.c
13f4a0
@@ -147,7 +147,8 @@ hgl_winsys_displaytarget_unmap(struct sw_winsys* winsys,
13f4a0
 
13f4a0
 static void
13f4a0
 hgl_winsys_displaytarget_display(struct sw_winsys* winsys,
13f4a0
-	struct sw_displaytarget* displayTarget, void* contextPrivate)
13f4a0
+	struct sw_displaytarget* displayTarget, void* contextPrivate,
13f4a0
+	struct pipe_box *box)
13f4a0
 {
13f4a0
 	assert(contextPrivate);
13f4a0
 
13f4a0
diff --git a/src/gallium/winsys/sw/null/null_sw_winsys.c b/src/gallium/winsys/sw/null/null_sw_winsys.c
13f4a0
index 44849da..9c8b3ec 100644
13f4a0
--- a/src/gallium/winsys/sw/null/null_sw_winsys.c
13f4a0
+++ b/src/gallium/winsys/sw/null/null_sw_winsys.c
13f4a0
@@ -114,7 +114,8 @@ null_sw_displaytarget_get_handle(struct sw_winsys *winsys,
13f4a0
 static void
13f4a0
 null_sw_displaytarget_display(struct sw_winsys *winsys,
13f4a0
                               struct sw_displaytarget *dt,
13f4a0
-                              void *context_private)
13f4a0
+                              void *context_private,
13f4a0
+                              struct pipe_box *box)
13f4a0
 {
13f4a0
    assert(0);
13f4a0
 }
13f4a0
diff --git a/src/gallium/winsys/sw/wayland/wayland_sw_winsys.c b/src/gallium/winsys/sw/wayland/wayland_sw_winsys.c
13f4a0
index f432de9..e428613 100644
13f4a0
--- a/src/gallium/winsys/sw/wayland/wayland_sw_winsys.c
13f4a0
+++ b/src/gallium/winsys/sw/wayland/wayland_sw_winsys.c
13f4a0
@@ -75,7 +75,8 @@ wayland_sw_winsys(struct sw_winsys *ws)
13f4a0
 static void
13f4a0
 wayland_displaytarget_display(struct sw_winsys *ws,
13f4a0
                               struct sw_displaytarget *dt,
13f4a0
-                              void *context_private)
13f4a0
+                              void *context_private,
13f4a0
+                              struct pipe_box *box)
13f4a0
 {
13f4a0
 }
13f4a0
 
13f4a0
diff --git a/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c b/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c
13f4a0
index 6e71530..99da2ae 100644
13f4a0
--- a/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c
13f4a0
+++ b/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c
13f4a0
@@ -376,7 +376,8 @@ xlib_sw_display(struct xlib_drawable *xlib_drawable,
13f4a0
 static void
13f4a0
 xlib_displaytarget_display(struct sw_winsys *ws,
13f4a0
                            struct sw_displaytarget *dt,
13f4a0
-                           void *context_private)
13f4a0
+                           void *context_private,
13f4a0
+                           struct pipe_box *box)
13f4a0
 {
13f4a0
    struct xlib_drawable *xlib_drawable = (struct xlib_drawable *)context_private;
13f4a0
    xlib_sw_display(xlib_drawable, dt);
13f4a0
diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c
13f4a0
index 393be20..f903b2d 100644
13f4a0
--- a/src/glx/drisw_glx.c
13f4a0
+++ b/src/glx/drisw_glx.c
13f4a0
@@ -49,6 +49,7 @@ struct drisw_screen
13f4a0
    const __DRIcoreExtension *core;
13f4a0
    const __DRIswrastExtension *swrast;
13f4a0
    const __DRItexBufferExtension *texBuffer;
13f4a0
+   const __DRIcopySubBufferExtension *copySubBuffer;
13f4a0
 
13f4a0
    const __DRIconfig **driver_configs;
13f4a0
 
13f4a0
@@ -171,9 +172,9 @@ bytes_per_line(unsigned pitch_bits, unsigned mul)
13f4a0
 }
13f4a0
 
13f4a0
 static void
13f4a0
-swrastPutImage(__DRIdrawable * draw, int op,
13f4a0
-               int x, int y, int w, int h,
13f4a0
-               char *data, void *loaderPrivate)
13f4a0
+swrastPutImage2(__DRIdrawable * draw, int op,
13f4a0
+                int x, int y, int w, int h, int stride,
13f4a0
+                char *data, void *loaderPrivate)
13f4a0
 {
13f4a0
    struct drisw_drawable *pdp = loaderPrivate;
13f4a0
    __GLXDRIdrawable *pdraw = &(pdp->base);
13f4a0
@@ -199,7 +200,7 @@ swrastPutImage(__DRIdrawable * draw, int op,
13f4a0
    ximage->data = data;
13f4a0
    ximage->width = w;
13f4a0
    ximage->height = h;
13f4a0
-   ximage->bytes_per_line = bytes_per_line(w * ximage->bits_per_pixel, 32);
13f4a0
+   ximage->bytes_per_line = stride ? stride : bytes_per_line(w * ximage->bits_per_pixel, 32);
13f4a0
 
13f4a0
    XPutImage(dpy, drawable, gc, ximage, 0, 0, x, y, w, h);
13f4a0
 
13f4a0
@@ -207,6 +208,14 @@ swrastPutImage(__DRIdrawable * draw, int op,
13f4a0
 }
13f4a0
 
13f4a0
 static void
13f4a0
+swrastPutImage(__DRIdrawable * draw, int op,
13f4a0
+               int x, int y, int w, int h,
13f4a0
+               char *data, void *loaderPrivate)
13f4a0
+{
13f4a0
+   swrastPutImage2(draw, op, x, y, w, h, 0, data, loaderPrivate);
13f4a0
+}
13f4a0
+
13f4a0
+static void
13f4a0
 swrastGetImage(__DRIdrawable * read,
13f4a0
                int x, int y, int w, int h,
13f4a0
                char *data, void *loaderPrivate)
13f4a0
@@ -234,7 +243,8 @@ static const __DRIswrastLoaderExtension swrastLoaderExtension = {
13f4a0
    {__DRI_SWRAST_LOADER, __DRI_SWRAST_LOADER_VERSION},
13f4a0
    swrastGetDrawableInfo,
13f4a0
    swrastPutImage,
13f4a0
-   swrastGetImage
13f4a0
+   swrastGetImage,
13f4a0
+   swrastPutImage2,
13f4a0
 };
13f4a0
 
13f4a0
 static const __DRIextension *loader_extensions[] = {
13f4a0
@@ -585,6 +595,21 @@ driswSwapBuffers(__GLXDRIdrawable * pdraw,
13f4a0
 }
13f4a0
 
13f4a0
 static void
13f4a0
+driswCopySubBuffer(__GLXDRIdrawable * pdraw,
13f4a0
+                   int x, int y, int width, int height, Bool flush)
13f4a0
+{
13f4a0
+   struct drisw_drawable *pdp = (struct drisw_drawable *) pdraw;
13f4a0
+   struct drisw_screen *psc = (struct drisw_screen *) pdp->base.psc;
13f4a0
+
13f4a0
+   if (flush) {
13f4a0
+      glFlush();
13f4a0
+   }
13f4a0
+
13f4a0
+   (*psc->copySubBuffer->copySubBuffer) (pdp->driDrawable,
13f4a0
+					    x, y, width, height);
13f4a0
+}
13f4a0
+
13f4a0
+static void
13f4a0
 driswDestroyScreen(struct glx_screen *base)
13f4a0
 {
13f4a0
    struct drisw_screen *psc = (struct drisw_screen *) base;
13f4a0
@@ -632,6 +657,9 @@ driswBindExtensions(struct drisw_screen *psc, const __DRIextension **extensions)
13f4a0
 				 "GLX_EXT_create_context_es2_profile");
13f4a0
    }
13f4a0
 
13f4a0
+   if (psc->copySubBuffer)
13f4a0
+      __glXEnableDirectExtension(&psc->base, "GLX_MESA_copy_sub_buffer");      
13f4a0
+
13f4a0
    /* FIXME: Figure out what other extensions can be ported here from dri2. */
13f4a0
    for (i = 0; extensions[i]; i++) {
13f4a0
       if ((strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0)) {
13f4a0
@@ -675,6 +703,8 @@ driswCreateScreen(int screen, struct glx_display *priv)
13f4a0
 	 psc->core = (__DRIcoreExtension *) extensions[i];
13f4a0
       if (strcmp(extensions[i]->name, __DRI_SWRAST) == 0)
13f4a0
 	 psc->swrast = (__DRIswrastExtension *) extensions[i];
13f4a0
+      if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0)
13f4a0
+	 psc->copySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
13f4a0
    }
13f4a0
 
13f4a0
    if (psc->core == NULL || psc->swrast == NULL) {
13f4a0
@@ -713,6 +743,9 @@ driswCreateScreen(int screen, struct glx_display *priv)
13f4a0
    psp->createDrawable = driswCreateDrawable;
13f4a0
    psp->swapBuffers = driswSwapBuffers;
13f4a0
 
13f4a0
+   if (psc->copySubBuffer)
13f4a0
+      psp->copySubBuffer = driswCopySubBuffer;
13f4a0
+
13f4a0
    return &psc->base;
13f4a0
 
13f4a0
  handle_error:
13f4a0
diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h
13f4a0
index 900f048..4c71fe4 100644
13f4a0
--- a/src/mesa/drivers/dri/common/dri_util.h
13f4a0
+++ b/src/mesa/drivers/dri/common/dri_util.h
13f4a0
@@ -65,7 +65,7 @@ extern const __DRIcoreExtension driCoreExtension;
13f4a0
 extern const __DRIswrastExtension driSWRastExtension;
13f4a0
 extern const __DRIdri2Extension driDRI2Extension;
13f4a0
 extern const __DRI2configQueryExtension dri2ConfigQueryExtension;
13f4a0
-
13f4a0
+extern const __DRIcopySubBufferExtension driCopySubBufferExtension;
13f4a0
 /**
13f4a0
  * Driver callback functions.
13f4a0
  *
13f4a0
@@ -113,6 +113,9 @@ struct __DriverAPIRec {
13f4a0
                                     int width, int height);
13f4a0
 
13f4a0
     void (*ReleaseBuffer) (__DRIscreen *screenPrivate, __DRIbuffer *buffer);
13f4a0
+
13f4a0
+    void (*CopySubBuffer)(__DRIdrawable *driDrawPriv, int x, int y,
13f4a0
+                          int w, int h);
13f4a0
 };
13f4a0
 
13f4a0
 extern const struct __DriverAPIRec driDriverAPI;
13f4a0
diff --git a/src/mesa/drivers/dri/common/drisw_util.c b/src/mesa/drivers/dri/common/drisw_util.c
13f4a0
index 89f03c3..0da4142 100644
13f4a0
--- a/src/mesa/drivers/dri/common/drisw_util.c
13f4a0
+++ b/src/mesa/drivers/dri/common/drisw_util.c
13f4a0
@@ -373,3 +373,18 @@ const __DRIswrastExtension driSWRastExtension = {
13f4a0
     driCreateNewContextForAPI,
13f4a0
     driCreateContextAttribs
13f4a0
 };
13f4a0
+
13f4a0
+/* swrast copy sub buffer entrypoint. */
13f4a0
+static void driCopySubBuffer(__DRIdrawable *pdp, int x, int y,
13f4a0
+                             int w, int h)
13f4a0
+{
13f4a0
+    assert(pdp->driScreenPriv->swrast_loader);
13f4a0
+
13f4a0
+    driDriverAPI.CopySubBuffer(pdp, x, y, w, h);
13f4a0
+}
13f4a0
+
13f4a0
+/* for swrast only */
13f4a0
+const __DRIcopySubBufferExtension driCopySubBufferExtension = {
13f4a0
+   { __DRI_COPY_SUB_BUFFER, 1 },
13f4a0
+   .copySubBuffer = driCopySubBuffer,
13f4a0
+};
13f4a0
diff --git a/src/mesa/drivers/dri/swrast/swrast.c b/src/mesa/drivers/dri/swrast/swrast.c
13f4a0
index 3870673..eb6d23b 100644
13f4a0
--- a/src/mesa/drivers/dri/swrast/swrast.c
13f4a0
+++ b/src/mesa/drivers/dri/swrast/swrast.c
13f4a0
@@ -830,6 +830,39 @@ dri_unbind_context(__DRIcontext * cPriv)
13f4a0
     return GL_TRUE;
13f4a0
 }
13f4a0
 
13f4a0
+static void
13f4a0
+dri_copy_sub_buffer(__DRIdrawable *dPriv, int x, int y,
13f4a0
+                    int w, int h)
13f4a0
+{
13f4a0
+    __DRIscreen *sPriv = dPriv->driScreenPriv;
13f4a0
+    void *data;
13f4a0
+    int iy;
13f4a0
+    struct dri_drawable *drawable = dri_drawable(dPriv);
13f4a0
+    struct gl_framebuffer *fb;
13f4a0
+    struct dri_swrast_renderbuffer *frontrb, *backrb;
13f4a0
+
13f4a0
+    TRACE;
13f4a0
+
13f4a0
+    fb = &drawable->Base;
13f4a0
+
13f4a0
+    frontrb =
13f4a0
+	dri_swrast_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
13f4a0
+    backrb =
13f4a0
+	dri_swrast_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
13f4a0
+
13f4a0
+    /* check for signle-buffered */
13f4a0
+    if (backrb == NULL)
13f4a0
+       return;
13f4a0
+
13f4a0
+    iy = frontrb->Base.Base.Height - y - h;
13f4a0
+    data = (char *)backrb->Base.Buffer + (iy * backrb->pitch) + (x * ((backrb->bpp + 7) / 8));
13f4a0
+    sPriv->swrast_loader->putImage2(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
13f4a0
+                                    x, iy, w, h,
13f4a0
+                                    frontrb->pitch,
13f4a0
+                                    data,
13f4a0
+                                    dPriv->loaderPrivate);
13f4a0
+}
13f4a0
+
13f4a0
 
13f4a0
 const struct __DriverAPIRec driDriverAPI = {
13f4a0
     .InitScreen = dri_init_screen,
13f4a0
@@ -841,11 +874,13 @@ const struct __DriverAPIRec driDriverAPI = {
13f4a0
     .SwapBuffers = dri_swap_buffers,
13f4a0
     .MakeCurrent = dri_make_current,
13f4a0
     .UnbindContext = dri_unbind_context,
13f4a0
+    .CopySubBuffer = dri_copy_sub_buffer,
13f4a0
 };
13f4a0
 
13f4a0
 /* This is the table of extensions that the loader will dlsym() for. */
13f4a0
 PUBLIC const __DRIextension *__driDriverExtensions[] = {
13f4a0
     &driCoreExtension.base,
13f4a0
     &driSWRastExtension.base,
13f4a0
+    &driCopySubBufferExtension.base,
13f4a0
     NULL
13f4a0
 };
13f4a0
-- 
13f4a0
1.8.4.2
13f4a0