0e9fd6
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
0e9fd6
index 6f9c2c8b8cf..c1c15013a58 100644
0e9fd6
--- a/include/GL/internal/dri_interface.h
0e9fd6
+++ b/include/GL/internal/dri_interface.h
0e9fd6
@@ -589,7 +589,7 @@ struct __DRIdamageExtensionRec {
0e9fd6
  * SWRast Loader extension.
0e9fd6
  */
0e9fd6
 #define __DRI_SWRAST_LOADER "DRI_SWRastLoader"
0e9fd6
-#define __DRI_SWRAST_LOADER_VERSION 4
0e9fd6
+#define __DRI_SWRAST_LOADER_VERSION 5
0e9fd6
 struct __DRIswrastLoaderExtensionRec {
0e9fd6
     __DRIextension base;
0e9fd6
 
0e9fd6
@@ -649,6 +649,23 @@ struct __DRIswrastLoaderExtensionRec {
0e9fd6
     void (*getImageShm)(__DRIdrawable *readable,
0e9fd6
                         int x, int y, int width, int height,
0e9fd6
                         int shmid, void *loaderPrivate);
0e9fd6
+
0e9fd6
+   /**
0e9fd6
+     * Put shm image to drawable (v2)
0e9fd6
+     *
0e9fd6
+     * The original version fixes srcx/y to 0, and expected
0e9fd6
+     * the offset to be adjusted. This version allows src x,y
0e9fd6
+     * to not be included in the offset. This is needed to
0e9fd6
+     * avoid certain overflow checks in the X server, that
0e9fd6
+     * result in lost rendering.
0e9fd6
+     *
0e9fd6
+     * \since 5
0e9fd6
+     */
0e9fd6
+    void (*putImageShm2)(__DRIdrawable *drawable, int op,
0e9fd6
+                         int x, int y,
0e9fd6
+                         int width, int height, int stride,
0e9fd6
+                         int shmid, char *shmaddr, unsigned offset,
0e9fd6
+                         void *loaderPrivate);
0e9fd6
 };
0e9fd6
 
0e9fd6
 /**
0e9fd6
diff --git a/src/gallium/include/state_tracker/drisw_api.h b/src/gallium/include/state_tracker/drisw_api.h
0e9fd6
index e365ab81f18..4b5d36c1797 100644
0e9fd6
--- a/src/gallium/include/state_tracker/drisw_api.h
0e9fd6
+++ b/src/gallium/include/state_tracker/drisw_api.h
0e9fd6
@@ -20,7 +20,7 @@ struct drisw_loader_funcs
0e9fd6
    void (*put_image2) (struct dri_drawable *dri_drawable,
0e9fd6
                        void *data, int x, int y, unsigned width, unsigned height, unsigned stride);
0e9fd6
    void (*put_image_shm) (struct dri_drawable *dri_drawable,
0e9fd6
-                          int shmid, char *shmaddr, unsigned offset,
0e9fd6
+                          int shmid, char *shmaddr, unsigned offset, unsigned offset_x,
0e9fd6
                           int x, int y, unsigned width, unsigned height, unsigned stride);
0e9fd6
 };
0e9fd6
 
0e9fd6
diff --git a/src/gallium/state_trackers/dri/drisw.c b/src/gallium/state_trackers/dri/drisw.c
0e9fd6
index 5a0d2e1354d..927ac39ce65 100644
0e9fd6
--- a/src/gallium/state_trackers/dri/drisw.c
0e9fd6
+++ b/src/gallium/state_trackers/dri/drisw.c
0e9fd6
@@ -79,15 +79,21 @@ put_image2(__DRIdrawable *dPriv, void *data, int x, int y,
0e9fd6
 
0e9fd6
 static inline void
0e9fd6
 put_image_shm(__DRIdrawable *dPriv, int shmid, char *shmaddr,
0e9fd6
-              unsigned offset, int x, int y,
0e9fd6
+              unsigned offset, unsigned offset_x, int x, int y,
0e9fd6
               unsigned width, unsigned height, unsigned stride)
0e9fd6
 {
0e9fd6
    __DRIscreen *sPriv = dPriv->driScreenPriv;
0e9fd6
    const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
0e9fd6
 
0e9fd6
-   loader->putImageShm(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
0e9fd6
-                       x, y, width, height, stride,
0e9fd6
-                       shmid, shmaddr, offset, dPriv->loaderPrivate);
0e9fd6
+   /* if we have the newer interface, don't have to add the offset_x here. */
0e9fd6
+   if (loader->base.version > 4 && loader->putImageShm2)
0e9fd6
+     loader->putImageShm2(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
0e9fd6
+                          x, y, width, height, stride,
0e9fd6
+                          shmid, shmaddr, offset, dPriv->loaderPrivate);
0e9fd6
+   else
0e9fd6
+     loader->putImageShm(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
0e9fd6
+                         x, y, width, height, stride,
0e9fd6
+                         shmid, shmaddr, offset + offset_x, dPriv->loaderPrivate);
0e9fd6
 }
0e9fd6
 
0e9fd6
 static inline void
0e9fd6
@@ -179,12 +185,13 @@ drisw_put_image2(struct dri_drawable *drawable,
0e9fd6
 static inline void
0e9fd6
 drisw_put_image_shm(struct dri_drawable *drawable,
0e9fd6
                     int shmid, char *shmaddr, unsigned offset,
0e9fd6
+                    unsigned offset_x,
0e9fd6
                     int x, int y, unsigned width, unsigned height,
0e9fd6
                     unsigned stride)
0e9fd6
 {
0e9fd6
    __DRIdrawable *dPriv = drawable->dPriv;
0e9fd6
 
0e9fd6
-   put_image_shm(dPriv, shmid, shmaddr, offset, x, y, width, height, stride);
0e9fd6
+   put_image_shm(dPriv, shmid, shmaddr, offset, offset_x, x, y, width, height, stride);
0e9fd6
 }
0e9fd6
 
0e9fd6
 static inline void
0e9fd6
diff --git a/src/gallium/winsys/sw/dri/dri_sw_winsys.c b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
0e9fd6
index cd44b036c6f..c0200f939b6 100644
0e9fd6
--- a/src/gallium/winsys/sw/dri/dri_sw_winsys.c
0e9fd6
+++ b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
0e9fd6
@@ -244,15 +244,20 @@ dri_sw_displaytarget_display(struct sw_winsys *ws,
0e9fd6
    unsigned width, height, x = 0, y = 0;
0e9fd6
    unsigned blsize = util_format_get_blocksize(dri_sw_dt->format);
0e9fd6
    unsigned offset = 0;
0e9fd6
+   unsigned offset_x = 0;
0e9fd6
    char *data = dri_sw_dt->data;
0e9fd6
-
0e9fd6
+   bool is_shm = dri_sw_dt->shmid != -1;
0e9fd6
    /* Set the width to 'stride / cpp'.
0e9fd6
     *
0e9fd6
     * PutImage correctly clips to the width of the dst drawable.
0e9fd6
     */
0e9fd6
    if (box) {
0e9fd6
-      offset = (dri_sw_dt->stride * box->y) + box->x * blsize;
0e9fd6
+      offset = dri_sw_dt->stride * box->y;
0e9fd6
+      offset_x = box->x * blsize;
0e9fd6
       data += offset;
0e9fd6
+      /* don't add x offset for shm, the put_image_shm will deal with it */
0e9fd6
+      if (!is_shm)
0e9fd6
+         data += offset_x;
0e9fd6
       x = box->x;
0e9fd6
       y = box->y;
0e9fd6
       width = box->width;
0e9fd6
@@ -262,8 +267,8 @@ dri_sw_displaytarget_display(struct sw_winsys *ws,
0e9fd6
       height = dri_sw_dt->height;
0e9fd6
    }
0e9fd6
 
0e9fd6
-   if (dri_sw_dt->shmid != -1) {
0e9fd6
-      dri_sw_ws->lf->put_image_shm(dri_drawable, dri_sw_dt->shmid, dri_sw_dt->data, offset,
0e9fd6
+   if (is_shm) {
0e9fd6
+      dri_sw_ws->lf->put_image_shm(dri_drawable, dri_sw_dt->shmid, dri_sw_dt->data, offset, offset_x,
0e9fd6
                                    x, y, width, height, dri_sw_dt->stride);
0e9fd6
       return;
0e9fd6
    }
0e9fd6
diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c
0e9fd6
index a2777100a32..fa0f0d7bf6f 100644
0e9fd6
--- a/src/glx/drisw_glx.c
0e9fd6
+++ b/src/glx/drisw_glx.c
0e9fd6
@@ -201,7 +201,8 @@ bytes_per_line(unsigned pitch_bits, unsigned mul)
0e9fd6
 
0e9fd6
 static void
0e9fd6
 swrastXPutImage(__DRIdrawable * draw, int op,
0e9fd6
-                int x, int y, int w, int h, int stride,
0e9fd6
+                int srcx, int srcy, int x, int y,
0e9fd6
+                int w, int h, int stride,
0e9fd6
                 int shmid, char *data, void *loaderPrivate)
0e9fd6
 {
0e9fd6
    struct drisw_drawable *pdp = loaderPrivate;
0e9fd6
@@ -235,12 +236,12 @@ swrastXPutImage(__DRIdrawable * draw, int op,
0e9fd6
    if (pdp->shminfo.shmid >= 0) {
0e9fd6
       ximage->width = ximage->bytes_per_line / ((ximage->bits_per_pixel + 7)/ 8);
0e9fd6
       ximage->height = h;
0e9fd6
-      XShmPutImage(dpy, drawable, gc, ximage, 0, 0, x, y, w, h, False);
0e9fd6
+      XShmPutImage(dpy, drawable, gc, ximage, srcx, srcy, x, y, w, h, False);
0e9fd6
       XSync(dpy, False);
0e9fd6
    } else {
0e9fd6
       ximage->width = w;
0e9fd6
       ximage->height = h;
0e9fd6
-      XPutImage(dpy, drawable, gc, ximage, 0, 0, x, y, w, h);
0e9fd6
+      XPutImage(dpy, drawable, gc, ximage, srcx, srcy, x, y, w, h);
0e9fd6
    }
0e9fd6
    ximage->data = NULL;
0e9fd6
 }
0e9fd6
@@ -254,7 +255,21 @@ swrastPutImageShm(__DRIdrawable * draw, int op,
0e9fd6
    struct drisw_drawable *pdp = loaderPrivate;
0e9fd6
 
0e9fd6
    pdp->shminfo.shmaddr = shmaddr;
0e9fd6
-   swrastXPutImage(draw, op, x, y, w, h, stride, shmid,
0e9fd6
+   swrastXPutImage(draw, op, 0, 0, x, y, w, h, stride, shmid,
0e9fd6
+                   shmaddr + offset, loaderPrivate);
0e9fd6
+}
0e9fd6
+
0e9fd6
+static void
0e9fd6
+swrastPutImageShm2(__DRIdrawable * draw, int op,
0e9fd6
+                   int x, int y,
0e9fd6
+                   int w, int h, int stride,
0e9fd6
+		   int shmid, char *shmaddr, unsigned offset,
0e9fd6
+		   void *loaderPrivate)
0e9fd6
+{
0e9fd6
+   struct drisw_drawable *pdp = loaderPrivate;
0e9fd6
+
0e9fd6
+   pdp->shminfo.shmaddr = shmaddr;
0e9fd6
+   swrastXPutImage(draw, op, x, 0, x, y, w, h, stride, shmid,
0e9fd6
                    shmaddr + offset, loaderPrivate);
0e9fd6
 }
0e9fd6
 
0e9fd6
@@ -263,7 +278,7 @@ swrastPutImage2(__DRIdrawable * draw, int op,
0e9fd6
                 int x, int y, int w, int h, int stride,
0e9fd6
                 char *data, void *loaderPrivate)
0e9fd6
 {
0e9fd6
-   swrastXPutImage(draw, op, x, y, w, h, stride, -1,
0e9fd6
+   swrastXPutImage(draw, op, 0, 0, x, y, w, h, stride, -1,
0e9fd6
                    data, loaderPrivate);
0e9fd6
 }
0e9fd6
 
0e9fd6
@@ -272,7 +287,7 @@ swrastPutImage(__DRIdrawable * draw, int op,
0e9fd6
                int x, int y, int w, int h,
0e9fd6
                char *data, void *loaderPrivate)
0e9fd6
 {
0e9fd6
-   swrastXPutImage(draw, op, x, y, w, h, 0, -1,
0e9fd6
+   swrastXPutImage(draw, op, 0, 0, x, y, w, h, 0, -1,
0e9fd6
                    data, loaderPrivate);
0e9fd6
 }
0e9fd6
 
0e9fd6
@@ -340,7 +355,7 @@ swrastGetImageShm(__DRIdrawable * read,
0e9fd6
 }
0e9fd6
 
0e9fd6
 static const __DRIswrastLoaderExtension swrastLoaderExtension_shm = {
0e9fd6
-   .base = {__DRI_SWRAST_LOADER, 4 },
0e9fd6
+   .base = {__DRI_SWRAST_LOADER, 5 },
0e9fd6
 
0e9fd6
    .getDrawableInfo     = swrastGetDrawableInfo,
0e9fd6
    .putImage            = swrastPutImage,
0e9fd6
@@ -349,6 +364,7 @@ static const __DRIswrastLoaderExtension swrastLoaderExtension_shm = {
0e9fd6
    .getImage2           = swrastGetImage2,
0e9fd6
    .putImageShm         = swrastPutImageShm,
0e9fd6
    .getImageShm         = swrastGetImageShm,
0e9fd6
+   .putImageShm2        = swrastPutImageShm2,
0e9fd6
 };
0e9fd6
 
0e9fd6
 static const __DRIextension *loader_extensions_shm[] = {