Blame SOURCES/dri-sw-xshm-support.patch

83206f
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
83206f
index 34a5c9fb01a..6e6d62a5142 100644
83206f
--- a/include/GL/internal/dri_interface.h
83206f
+++ b/include/GL/internal/dri_interface.h
83206f
@@ -565,7 +565,7 @@ struct __DRIdamageExtensionRec {
83206f
  * SWRast Loader extension.
83206f
  */
83206f
 #define __DRI_SWRAST_LOADER "DRI_SWRastLoader"
83206f
-#define __DRI_SWRAST_LOADER_VERSION 3
83206f
+#define __DRI_SWRAST_LOADER_VERSION 4
83206f
 struct __DRIswrastLoaderExtensionRec {
83206f
     __DRIextension base;
83206f
 
83206f
@@ -607,6 +607,24 @@ struct __DRIswrastLoaderExtensionRec {
83206f
    void (*getImage2)(__DRIdrawable *readable,
83206f
 		     int x, int y, int width, int height, int stride,
83206f
 		     char *data, void *loaderPrivate);
83206f
+
83206f
+    /**
83206f
+     * Put shm image to drawable
83206f
+     *
83206f
+     * \since 4
83206f
+     */
83206f
+    void (*putImageShm)(__DRIdrawable *drawable, int op,
83206f
+                        int x, int y, int width, int height, int stride,
83206f
+                        int shmid, char *shmaddr, unsigned offset,
83206f
+                        void *loaderPrivate);
83206f
+    /**
83206f
+     * Get shm image from readable
83206f
+     *
83206f
+     * \since 4
83206f
+     */
83206f
+    void (*getImageShm)(__DRIdrawable *readable,
83206f
+                        int x, int y, int width, int height,
83206f
+                        int shmid, void *loaderPrivate);
83206f
 };
83206f
 
83206f
 /**
83206f
diff --git a/src/gallium/auxiliary/renderonly/renderonly.c b/src/gallium/auxiliary/renderonly/renderonly.c
83206f
index d31f458845c..f83910a9404 100644
83206f
--- a/src/gallium/auxiliary/renderonly/renderonly.c
83206f
+++ b/src/gallium/auxiliary/renderonly/renderonly.c
83206f
@@ -98,7 +98,7 @@ renderonly_create_kms_dumb_buffer_for_resource(struct pipe_resource *rsc,
83206f
 
83206f
    /* fill in winsys handle */
83206f
    memset(out_handle, 0, sizeof(*out_handle));
83206f
-   out_handle->type = DRM_API_HANDLE_TYPE_FD;
83206f
+   out_handle->type = WINSYS_HANDLE_TYPE_FD;
83206f
    out_handle->stride = create_dumb.pitch;
83206f
 
83206f
    err = drmPrimeHandleToFD(ro->kms_fd, create_dumb.handle, O_CLOEXEC,
83206f
@@ -130,7 +130,7 @@ renderonly_create_gpu_import_for_resource(struct pipe_resource *rsc,
83206f
    boolean status;
83206f
    int fd, err;
83206f
    struct winsys_handle handle = {
83206f
-      .type = DRM_API_HANDLE_TYPE_FD
83206f
+      .type = WINSYS_HANDLE_TYPE_FD
83206f
    };
83206f
 
83206f
    scanout = CALLOC_STRUCT(renderonly_scanout);
83206f
diff --git a/src/gallium/auxiliary/renderonly/renderonly.h b/src/gallium/auxiliary/renderonly/renderonly.h
83206f
index 6a89c29e2ef..a8d6a686ed4 100644
83206f
--- a/src/gallium/auxiliary/renderonly/renderonly.h
83206f
+++ b/src/gallium/auxiliary/renderonly/renderonly.h
83206f
@@ -85,7 +85,7 @@ renderonly_get_handle(struct renderonly_scanout *scanout,
83206f
    if (!scanout)
83206f
       return FALSE;
83206f
 
83206f
-   assert(handle->type == DRM_API_HANDLE_TYPE_KMS);
83206f
+   assert(handle->type == WINSYS_HANDLE_TYPE_KMS);
83206f
    handle->handle = scanout->handle;
83206f
    handle->stride = scanout->stride;
83206f
 
83206f
diff --git a/src/gallium/auxiliary/vl/vl_winsys_dri.c b/src/gallium/auxiliary/vl/vl_winsys_dri.c
83206f
index 79ebf750cdb..bb1ff504886 100644
83206f
--- a/src/gallium/auxiliary/vl/vl_winsys_dri.c
83206f
+++ b/src/gallium/auxiliary/vl/vl_winsys_dri.c
83206f
@@ -231,7 +231,7 @@ vl_dri2_screen_texture_from_drawable(struct vl_screen *vscreen, void *drawable)
83206f
    }
83206f
 
83206f
    memset(&dri2_handle, 0, sizeof(dri2_handle));
83206f
-   dri2_handle.type = DRM_API_HANDLE_TYPE_SHARED;
83206f
+   dri2_handle.type = WINSYS_HANDLE_TYPE_SHARED;
83206f
    dri2_handle.handle = back_left->name;
83206f
    dri2_handle.stride = back_left->pitch;
83206f
 
83206f
diff --git a/src/gallium/auxiliary/vl/vl_winsys_dri3.c b/src/gallium/auxiliary/vl/vl_winsys_dri3.c
83206f
index 8251087f3f9..8e3c4a0e04d 100644
83206f
--- a/src/gallium/auxiliary/vl/vl_winsys_dri3.c
83206f
+++ b/src/gallium/auxiliary/vl/vl_winsys_dri3.c
83206f
@@ -271,7 +271,7 @@ dri3_alloc_back_buffer(struct vl_dri3_screen *scrn)
83206f
       pixmap_buffer_texture = buffer->texture;
83206f
    }
83206f
    memset(&whandle, 0, sizeof(whandle));
83206f
-   whandle.type= DRM_API_HANDLE_TYPE_FD;
83206f
+   whandle.type= WINSYS_HANDLE_TYPE_FD;
83206f
    usage = PIPE_HANDLE_USAGE_EXPLICIT_FLUSH | PIPE_HANDLE_USAGE_READ;
83206f
    scrn->base.pscreen->resource_get_handle(scrn->base.pscreen, NULL,
83206f
                                            pixmap_buffer_texture, &whandle,
83206f
@@ -492,7 +492,7 @@ dri3_get_front_buffer(struct vl_dri3_screen *scrn)
83206f
       goto free_reply;
83206f
 
83206f
    memset(&whandle, 0, sizeof(whandle));
83206f
-   whandle.type = DRM_API_HANDLE_TYPE_FD;
83206f
+   whandle.type = WINSYS_HANDLE_TYPE_FD;
83206f
    whandle.handle = (unsigned)fds[0];
83206f
    whandle.stride = bp_reply->stride;
83206f
    memset(&templ, 0, sizeof(templ));
83206f
diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.c b/src/gallium/drivers/etnaviv/etnaviv_resource.c
83206f
index d70152e082d..cf870a3ed76 100644
83206f
--- a/src/gallium/drivers/etnaviv/etnaviv_resource.c
83206f
+++ b/src/gallium/drivers/etnaviv/etnaviv_resource.c
83206f
@@ -250,7 +250,7 @@ etna_resource_alloc(struct pipe_screen *pscreen, unsigned layout,
83206f
       if (!scanout)
83206f
          return NULL;
83206f
 
83206f
-      assert(handle.type == DRM_API_HANDLE_TYPE_FD);
83206f
+      assert(handle.type == WINSYS_HANDLE_TYPE_FD);
83206f
       handle.modifier = modifier;
83206f
       rsc = etna_resource(pscreen->resource_from_handle(pscreen, templat,
83206f
                                                         &handle,
83206f
@@ -596,16 +596,16 @@ etna_resource_get_handle(struct pipe_screen *pscreen,
83206f
    handle->stride = rsc->levels[0].stride;
83206f
    handle->modifier = layout_to_modifier(rsc->layout);
83206f
 
83206f
-   if (handle->type == DRM_API_HANDLE_TYPE_SHARED) {
83206f
+   if (handle->type == WINSYS_HANDLE_TYPE_SHARED) {
83206f
       return etna_bo_get_name(rsc->bo, &handle->handle) == 0;
83206f
-   } else if (handle->type == DRM_API_HANDLE_TYPE_KMS) {
83206f
+   } else if (handle->type == WINSYS_HANDLE_TYPE_KMS) {
83206f
       if (renderonly_get_handle(scanout, handle)) {
83206f
          return TRUE;
83206f
       } else {
83206f
          handle->handle = etna_bo_handle(rsc->bo);
83206f
          return TRUE;
83206f
       }
83206f
-   } else if (handle->type == DRM_API_HANDLE_TYPE_FD) {
83206f
+   } else if (handle->type == WINSYS_HANDLE_TYPE_FD) {
83206f
       handle->handle = etna_bo_dmabuf(rsc->bo);
83206f
       return TRUE;
83206f
    } else {
83206f
diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.c b/src/gallium/drivers/etnaviv/etnaviv_screen.c
83206f
index c72793920ab..1997e9f85db 100644
83206f
--- a/src/gallium/drivers/etnaviv/etnaviv_screen.c
83206f
+++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c
83206f
@@ -842,9 +842,9 @@ etna_screen_bo_from_handle(struct pipe_screen *pscreen,
83206f
    struct etna_screen *screen = etna_screen(pscreen);
83206f
    struct etna_bo *bo;
83206f
 
83206f
-   if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
83206f
+   if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) {
83206f
       bo = etna_bo_from_name(screen->dev, whandle->handle);
83206f
-   } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
83206f
+   } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
83206f
       bo = etna_bo_from_dmabuf(screen->dev, whandle->handle);
83206f
    } else {
83206f
       DBG("Attempt to import unsupported handle type %d", whandle->type);
83206f
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c
83206f
index b68685989ca..e0f769a63cd 100644
83206f
--- a/src/gallium/drivers/freedreno/freedreno_screen.c
83206f
+++ b/src/gallium/drivers/freedreno/freedreno_screen.c
83206f
@@ -731,12 +731,12 @@ fd_screen_bo_get_handle(struct pipe_screen *pscreen,
83206f
 {
83206f
 	whandle->stride = stride;
83206f
 
83206f
-	if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
83206f
+	if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) {
83206f
 		return fd_bo_get_name(bo, &whandle->handle) == 0;
83206f
-	} else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
83206f
+	} else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) {
83206f
 		whandle->handle = fd_bo_handle(bo);
83206f
 		return TRUE;
83206f
-	} else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
83206f
+	} else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
83206f
 		whandle->handle = fd_bo_dmabuf(bo);
83206f
 		return TRUE;
83206f
 	} else {
83206f
@@ -751,11 +751,11 @@ fd_screen_bo_from_handle(struct pipe_screen *pscreen,
83206f
 	struct fd_screen *screen = fd_screen(pscreen);
83206f
 	struct fd_bo *bo;
83206f
 
83206f
-	if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
83206f
+	if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) {
83206f
 		bo = fd_bo_from_name(screen->dev, whandle->handle);
83206f
-	} else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
83206f
+	} else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) {
83206f
 		bo = fd_bo_from_handle(screen->dev, whandle->handle, 0);
83206f
-	} else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
83206f
+	} else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
83206f
 		bo = fd_bo_from_dmabuf(screen->dev, whandle->handle);
83206f
 	} else {
83206f
 		DBG("Attempt to import unsupported handle type %d", whandle->type);
83206f
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
83206f
index c144b39b2dd..c97b707955c 100644
83206f
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
83206f
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
83206f
@@ -102,14 +102,14 @@ nouveau_screen_bo_from_handle(struct pipe_screen *pscreen,
83206f
       return NULL;
83206f
    }
83206f
 
83206f
-   if (whandle->type != DRM_API_HANDLE_TYPE_SHARED &&
83206f
-       whandle->type != DRM_API_HANDLE_TYPE_FD) {
83206f
+   if (whandle->type != WINSYS_HANDLE_TYPE_SHARED &&
83206f
+       whandle->type != WINSYS_HANDLE_TYPE_FD) {
83206f
       debug_printf("%s: attempt to import unsupported handle type %d\n",
83206f
                    __FUNCTION__, whandle->type);
83206f
       return NULL;
83206f
    }
83206f
 
83206f
-   if (whandle->type == DRM_API_HANDLE_TYPE_SHARED)
83206f
+   if (whandle->type == WINSYS_HANDLE_TYPE_SHARED)
83206f
       ret = nouveau_bo_name_ref(dev, whandle->handle, &bo);
83206f
    else
83206f
       ret = nouveau_bo_prime_handle_ref(dev, whandle->handle, &bo);
83206f
@@ -133,12 +133,12 @@ nouveau_screen_bo_get_handle(struct pipe_screen *pscreen,
83206f
 {
83206f
    whandle->stride = stride;
83206f
 
83206f
-   if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
83206f
+   if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) {
83206f
       return nouveau_bo_name_get(bo, &whandle->handle) == 0;
83206f
-   } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
83206f
+   } else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) {
83206f
       whandle->handle = bo->handle;
83206f
       return true;
83206f
-   } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
83206f
+   } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
83206f
       return nouveau_bo_set_prime(bo, (int *)&whandle->handle) == 0;
83206f
    } else {
83206f
       return false;
83206f
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
83206f
index 36eff40949f..a9c7b46b7b3 100644
83206f
--- a/src/gallium/drivers/radeon/r600_texture.c
83206f
+++ b/src/gallium/drivers/radeon/r600_texture.c
83206f
@@ -699,7 +699,7 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
83206f
 		if (sscreen->ws->buffer_is_suballocated(res->buf) ||
83206f
 		    rtex->surface.tile_swizzle ||
83206f
 		    (rtex->resource.flags & RADEON_FLAG_NO_INTERPROCESS_SHARING &&
83206f
-		     whandle->type != DRM_API_HANDLE_TYPE_KMS)) {
83206f
+		     whandle->type != WINSYS_HANDLE_TYPE_KMS)) {
83206f
 			assert(!res->b.is_shared);
83206f
 			r600_reallocate_texture_inplace(rctx, rtex,
83206f
 							PIPE_BIND_SHARED, false);
83206f
diff --git a/src/gallium/drivers/vc4/vc4_resource.c b/src/gallium/drivers/vc4/vc4_resource.c
83206f
index cdcbcc917e0..58b6a42d4fd 100644
83206f
--- a/src/gallium/drivers/vc4/vc4_resource.c
83206f
+++ b/src/gallium/drivers/vc4/vc4_resource.c
83206f
@@ -406,7 +406,7 @@ vc4_resource_get_handle(struct pipe_screen *pscreen,
83206f
                 whandle->modifier = DRM_FORMAT_MOD_LINEAR;
83206f
 
83206f
         switch (whandle->type) {
83206f
-        case DRM_API_HANDLE_TYPE_SHARED:
83206f
+        case WINSYS_HANDLE_TYPE_SHARED:
83206f
                 if (screen->ro) {
83206f
                         /* This could probably be supported, assuming that a
83206f
                          * control node was used for pl111.
83206f
@@ -416,12 +416,12 @@ vc4_resource_get_handle(struct pipe_screen *pscreen,
83206f
                 }
83206f
 
83206f
                 return vc4_bo_flink(rsc->bo, &whandle->handle);
83206f
-        case DRM_API_HANDLE_TYPE_KMS:
83206f
+        case WINSYS_HANDLE_TYPE_KMS:
83206f
                 if (screen->ro && renderonly_get_handle(rsc->scanout, whandle))
83206f
                         return TRUE;
83206f
                 whandle->handle = rsc->bo->handle;
83206f
                 return TRUE;
83206f
-        case DRM_API_HANDLE_TYPE_FD:
83206f
+        case WINSYS_HANDLE_TYPE_FD:
83206f
                 /* FDs are cross-device, so we can export directly from vc4.
83206f
                  */
83206f
                 whandle->handle = vc4_bo_get_dmabuf(rsc->bo);
83206f
@@ -716,11 +716,11 @@ vc4_resource_from_handle(struct pipe_screen *pscreen,
83206f
         }
83206f
 
83206f
         switch (whandle->type) {
83206f
-        case DRM_API_HANDLE_TYPE_SHARED:
83206f
+        case WINSYS_HANDLE_TYPE_SHARED:
83206f
                 rsc->bo = vc4_bo_open_name(screen,
83206f
                                            whandle->handle, whandle->stride);
83206f
                 break;
83206f
-        case DRM_API_HANDLE_TYPE_FD:
83206f
+        case WINSYS_HANDLE_TYPE_FD:
83206f
                 rsc->bo = vc4_bo_open_dmabuf(screen,
83206f
                                              whandle->handle, whandle->stride);
83206f
                 break;
83206f
diff --git a/src/gallium/drivers/vc5/vc5_resource.c b/src/gallium/drivers/vc5/vc5_resource.c
83206f
index a9cc27127f0..9754d3d6024 100644
83206f
--- a/src/gallium/drivers/vc5/vc5_resource.c
83206f
+++ b/src/gallium/drivers/vc5/vc5_resource.c
83206f
@@ -314,12 +314,12 @@ vc5_resource_get_handle(struct pipe_screen *pscreen,
83206f
         bo->private = false;
83206f
 
83206f
         switch (whandle->type) {
83206f
-        case DRM_API_HANDLE_TYPE_SHARED:
83206f
+        case WINSYS_HANDLE_TYPE_SHARED:
83206f
                 return vc5_bo_flink(bo, &whandle->handle);
83206f
-        case DRM_API_HANDLE_TYPE_KMS:
83206f
+        case WINSYS_HANDLE_TYPE_KMS:
83206f
                 whandle->handle = bo->handle;
83206f
                 return TRUE;
83206f
-        case DRM_API_HANDLE_TYPE_FD:
83206f
+        case WINSYS_HANDLE_TYPE_FD:
83206f
                 whandle->handle = vc5_bo_get_dmabuf(bo);
83206f
                 return whandle->handle != -1;
83206f
         }
83206f
@@ -592,11 +592,11 @@ vc5_resource_from_handle(struct pipe_screen *pscreen,
83206f
         }
83206f
 
83206f
         switch (whandle->type) {
83206f
-        case DRM_API_HANDLE_TYPE_SHARED:
83206f
+        case WINSYS_HANDLE_TYPE_SHARED:
83206f
                 rsc->bo = vc5_bo_open_name(screen,
83206f
                                            whandle->handle, whandle->stride);
83206f
                 break;
83206f
-        case DRM_API_HANDLE_TYPE_FD:
83206f
+        case WINSYS_HANDLE_TYPE_FD:
83206f
                 rsc->bo = vc5_bo_open_dmabuf(screen,
83206f
                                              whandle->handle, whandle->stride);
83206f
                 break;
83206f
diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
83206f
index 101e229088b..8fd81a4e9a9 100644
83206f
--- a/src/gallium/include/pipe/p_screen.h
83206f
+++ b/src/gallium/include/pipe/p_screen.h
83206f
@@ -191,7 +191,7 @@ struct pipe_screen {
83206f
     * another process by first creating a pipe texture and then calling
83206f
     * resource_get_handle.
83206f
     *
83206f
-    * NOTE: in the case of DRM_API_HANDLE_TYPE_FD handles, the caller
83206f
+    * NOTE: in the case of WINSYS_HANDLE_TYPE_FD handles, the caller
83206f
     * retains ownership of the FD.  (This is consistent with
83206f
     * EGL_EXT_image_dma_buf_import)
83206f
     *
83206f
@@ -238,7 +238,7 @@ struct pipe_screen {
83206f
     * the resource into a format compatible for sharing. The use case is
83206f
     * OpenGL-OpenCL interop. The context parameter is allowed to be NULL.
83206f
     *
83206f
-    * NOTE: in the case of DRM_API_HANDLE_TYPE_FD handles, the caller
83206f
+    * NOTE: in the case of WINSYS_HANDLE_TYPE_FD handles, the caller
83206f
     * takes ownership of the FD.  (This is consistent with
83206f
     * EGL_MESA_image_dma_buf_export)
83206f
     *
83206f
@@ -389,7 +389,7 @@ struct pipe_screen {
83206f
     * Then the underlying memory object is then exported through interfaces
83206f
     * compatible with EXT_external_resources.
83206f
     *
83206f
-    * Note: For DRM_API_HANDLE_TYPE_FD handles, the caller retains ownership
83206f
+    * Note: For WINSYS_HANDLE_TYPE_FD handles, the caller retains ownership
83206f
     * of the fd.
83206f
     *
83206f
     * \param handle  A handle representing the memory object to import
83206f
diff --git a/src/gallium/include/state_tracker/drisw_api.h b/src/gallium/include/state_tracker/drisw_api.h
83206f
index 03d5ee405a4..e365ab81f18 100644
83206f
--- a/src/gallium/include/state_tracker/drisw_api.h
83206f
+++ b/src/gallium/include/state_tracker/drisw_api.h
83206f
@@ -2,6 +2,7 @@
83206f
 #define _DRISW_API_H_
83206f
 
83206f
 #include "pipe/p_compiler.h"
83206f
+#include "sw_winsys.h"
83206f
 
83206f
 struct pipe_screen;
83206f
 struct dri_drawable;
83206f
@@ -18,6 +19,9 @@ struct drisw_loader_funcs
83206f
                       void *data, unsigned width, unsigned height);
83206f
    void (*put_image2) (struct dri_drawable *dri_drawable,
83206f
                        void *data, int x, int y, unsigned width, unsigned height, unsigned stride);
83206f
+   void (*put_image_shm) (struct dri_drawable *dri_drawable,
83206f
+                          int shmid, char *shmaddr, unsigned offset,
83206f
+                          int x, int y, unsigned width, unsigned height, unsigned stride);
83206f
 };
83206f
 
83206f
 #endif
83206f
diff --git a/src/gallium/include/state_tracker/drm_driver.h b/src/gallium/include/state_tracker/drm_driver.h
83206f
index f188b5a7d4c..19cd19f26e1 100644
83206f
--- a/src/gallium/include/state_tracker/drm_driver.h
83206f
+++ b/src/gallium/include/state_tracker/drm_driver.h
83206f
@@ -4,58 +4,13 @@
83206f
 
83206f
 #include "pipe/p_compiler.h"
83206f
 
83206f
+#include "winsys_handle.h"
83206f
+
83206f
 struct pipe_screen;
83206f
 struct pipe_screen_config;
83206f
 struct pipe_context;
83206f
 struct pipe_resource;
83206f
 
83206f
-#define DRM_API_HANDLE_TYPE_SHARED 0
83206f
-#define DRM_API_HANDLE_TYPE_KMS    1
83206f
-#define DRM_API_HANDLE_TYPE_FD     2
83206f
-
83206f
-
83206f
-/**
83206f
- * For use with pipe_screen::{texture_from_handle|texture_get_handle}.
83206f
- */
83206f
-struct winsys_handle
83206f
-{
83206f
-   /**
83206f
-    * Input for texture_from_handle, valid values are
83206f
-    * DRM_API_HANDLE_TYPE_SHARED or DRM_API_HANDLE_TYPE_FD.
83206f
-    * Input to texture_get_handle,
83206f
-    * to select handle for kms, flink, or prime.
83206f
-    */
83206f
-   unsigned type;
83206f
-   /**
83206f
-    * Input for texture_get_handle, allows to export the offset
83206f
-    * of a specific layer of an array texture.
83206f
-    */
83206f
-   unsigned layer;
83206f
-   /**
83206f
-    * Input to texture_from_handle.
83206f
-    * Output for texture_get_handle.
83206f
-    */
83206f
-   unsigned handle;
83206f
-   /**
83206f
-    * Input to texture_from_handle.
83206f
-    * Output for texture_get_handle.
83206f
-    */
83206f
-   unsigned stride;
83206f
-   /**
83206f
-    * Input to texture_from_handle.
83206f
-    * Output for texture_get_handle.
83206f
-    */
83206f
-   unsigned offset;
83206f
-
83206f
-   /**
83206f
-    * Input to resource_from_handle.
83206f
-    * Output from resource_get_handle.
83206f
-    */
83206f
-   uint64_t modifier;
83206f
-};
83206f
-
83206f
-
83206f
-
83206f
 /**
83206f
  * Configuration queries.
83206f
  */
83206f
diff --git a/src/gallium/include/state_tracker/sw_winsys.h b/src/gallium/include/state_tracker/sw_winsys.h
83206f
index 0b792cd0ce4..cd5838ad1d8 100644
83206f
--- a/src/gallium/include/state_tracker/sw_winsys.h
83206f
+++ b/src/gallium/include/state_tracker/sw_winsys.h
83206f
@@ -37,14 +37,13 @@
83206f
 
83206f
 #include "pipe/p_compiler.h" /* for boolean */
83206f
 #include "pipe/p_format.h"
83206f
-
83206f
+#include "state_tracker/winsys_handle.h"
83206f
 
83206f
 #ifdef __cplusplus
83206f
 extern "C" {
83206f
 #endif
83206f
 
83206f
 
83206f
-struct winsys_handle;
83206f
 struct pipe_screen;
83206f
 struct pipe_context;
83206f
 struct pipe_resource;
83206f
diff --git a/src/gallium/include/state_tracker/winsys_handle.h b/src/gallium/include/state_tracker/winsys_handle.h
83206f
new file mode 100644
83206f
index 00000000000..167c1a937fd
83206f
--- /dev/null
83206f
+++ b/src/gallium/include/state_tracker/winsys_handle.h
83206f
@@ -0,0 +1,58 @@
83206f
+
83206f
+#ifndef _WINSYS_HANDLE_H_
83206f
+#define _WINSYS_HANDLE_H_
83206f
+
83206f
+#ifdef __cplusplus
83206f
+extern "C" {
83206f
+#endif
83206f
+
83206f
+#define WINSYS_HANDLE_TYPE_SHARED 0
83206f
+#define WINSYS_HANDLE_TYPE_KMS    1
83206f
+#define WINSYS_HANDLE_TYPE_FD     2
83206f
+#define WINSYS_HANDLE_TYPE_SHMID   3
83206f
+
83206f
+/**
83206f
+ * For use with pipe_screen::{texture_from_handle|texture_get_handle}.
83206f
+ */
83206f
+struct winsys_handle
83206f
+{
83206f
+   /**
83206f
+    * Input for texture_from_handle, valid values are
83206f
+    * WINSYS_HANDLE_TYPE_SHARED or WINSYS_HANDLE_TYPE_FD.
83206f
+    * Input to texture_get_handle,
83206f
+    * to select handle for kms, flink, or prime.
83206f
+    */
83206f
+   unsigned type;
83206f
+   /**
83206f
+    * Input for texture_get_handle, allows to export the offset
83206f
+    * of a specific layer of an array texture.
83206f
+    */
83206f
+   unsigned layer;
83206f
+   /**
83206f
+    * Input to texture_from_handle.
83206f
+    * Output for texture_get_handle.
83206f
+    */
83206f
+   unsigned handle;
83206f
+   /**
83206f
+    * Input to texture_from_handle.
83206f
+    * Output for texture_get_handle.
83206f
+    */
83206f
+   unsigned stride;
83206f
+   /**
83206f
+    * Input to texture_from_handle.
83206f
+    * Output for texture_get_handle.
83206f
+    */
83206f
+   unsigned offset;
83206f
+
83206f
+   /**
83206f
+    * Input to resource_from_handle.
83206f
+    * Output from resource_get_handle.
83206f
+    */
83206f
+   uint64_t modifier;
83206f
+};
83206f
+
83206f
+#ifdef __cplusplus
83206f
+}
83206f
+#endif
83206f
+
83206f
+#endif /* _WINSYS_HANDLE_H_ */
83206f
diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c
83206f
index 2c3a6e0d194..aa219377069 100644
83206f
--- a/src/gallium/state_trackers/dri/dri2.c
83206f
+++ b/src/gallium/state_trackers/dri/dri2.c
83206f
@@ -584,9 +584,9 @@ dri2_allocate_buffer(__DRIscreen *sPriv,
83206f
 
83206f
    memset(&whandle, 0, sizeof(whandle));
83206f
    if (screen->can_share_buffer)
83206f
-      whandle.type = DRM_API_HANDLE_TYPE_SHARED;
83206f
+      whandle.type = WINSYS_HANDLE_TYPE_SHARED;
83206f
    else
83206f
-      whandle.type = DRM_API_HANDLE_TYPE_KMS;
83206f
+      whandle.type = WINSYS_HANDLE_TYPE_KMS;
83206f
 
83206f
    screen->base.screen->resource_get_handle(screen->base.screen, NULL,
83206f
          buffer->resource, &whandle,
83206f
@@ -772,9 +772,9 @@ dri2_allocate_textures(struct dri_context *ctx,
83206f
          whandle.offset = 0;
83206f
          whandle.modifier = DRM_FORMAT_MOD_INVALID;
83206f
          if (screen->can_share_buffer)
83206f
-            whandle.type = DRM_API_HANDLE_TYPE_SHARED;
83206f
+            whandle.type = WINSYS_HANDLE_TYPE_SHARED;
83206f
          else
83206f
-            whandle.type = DRM_API_HANDLE_TYPE_KMS;
83206f
+            whandle.type = WINSYS_HANDLE_TYPE_KMS;
83206f
          drawable->textures[statt] =
83206f
             screen->base.screen->resource_from_handle(screen->base.screen,
83206f
                   &templ, &whandle,
83206f
@@ -1032,7 +1032,7 @@ dri2_create_image_from_name(__DRIscreen *_screen,
83206f
    enum pipe_format pf;
83206f
 
83206f
    memset(&whandle, 0, sizeof(whandle));
83206f
-   whandle.type = DRM_API_HANDLE_TYPE_SHARED;
83206f
+   whandle.type = WINSYS_HANDLE_TYPE_SHARED;
83206f
    whandle.handle = name;
83206f
    whandle.modifier = DRM_FORMAT_MOD_INVALID;
83206f
 
83206f
@@ -1091,7 +1091,7 @@ dri2_create_image_from_fd(__DRIscreen *_screen,
83206f
          goto exit;
83206f
       }
83206f
 
83206f
-      whandles[i].type = DRM_API_HANDLE_TYPE_FD;
83206f
+      whandles[i].type = WINSYS_HANDLE_TYPE_FD;
83206f
       whandles[i].handle = (unsigned)fds[i];
83206f
       whandles[i].stride = (unsigned)strides[i];
83206f
       whandles[i].offset = (unsigned)offsets[i];
83206f
@@ -1231,35 +1231,35 @@ dri2_query_image(__DRIimage *image, int attrib, int *value)
83206f
 
83206f
    switch (attrib) {
83206f
    case __DRI_IMAGE_ATTRIB_STRIDE:
83206f
-      whandle.type = DRM_API_HANDLE_TYPE_KMS;
83206f
+      whandle.type = WINSYS_HANDLE_TYPE_KMS;
83206f
       if (!image->texture->screen->resource_get_handle(image->texture->screen,
83206f
             NULL, image->texture, &whandle, usage))
83206f
          return GL_FALSE;
83206f
       *value = whandle.stride;
83206f
       return GL_TRUE;
83206f
    case __DRI_IMAGE_ATTRIB_OFFSET:
83206f
-      whandle.type = DRM_API_HANDLE_TYPE_KMS;
83206f
+      whandle.type = WINSYS_HANDLE_TYPE_KMS;
83206f
       if (!image->texture->screen->resource_get_handle(image->texture->screen,
83206f
             NULL, image->texture, &whandle, usage))
83206f
          return GL_FALSE;
83206f
       *value = whandle.offset;
83206f
       return GL_TRUE;
83206f
    case __DRI_IMAGE_ATTRIB_HANDLE:
83206f
-      whandle.type = DRM_API_HANDLE_TYPE_KMS;
83206f
+      whandle.type = WINSYS_HANDLE_TYPE_KMS;
83206f
       if (!image->texture->screen->resource_get_handle(image->texture->screen,
83206f
          NULL, image->texture, &whandle, usage))
83206f
          return GL_FALSE;
83206f
       *value = whandle.handle;
83206f
       return GL_TRUE;
83206f
    case __DRI_IMAGE_ATTRIB_NAME:
83206f
-      whandle.type = DRM_API_HANDLE_TYPE_SHARED;
83206f
+      whandle.type = WINSYS_HANDLE_TYPE_SHARED;
83206f
       if (!image->texture->screen->resource_get_handle(image->texture->screen,
83206f
          NULL, image->texture, &whandle, usage))
83206f
          return GL_FALSE;
83206f
       *value = whandle.handle;
83206f
       return GL_TRUE;
83206f
    case __DRI_IMAGE_ATTRIB_FD:
83206f
-      whandle.type= DRM_API_HANDLE_TYPE_FD;
83206f
+      whandle.type= WINSYS_HANDLE_TYPE_FD;
83206f
       if (!image->texture->screen->resource_get_handle(image->texture->screen,
83206f
             NULL, image->texture, &whandle, usage))
83206f
          return GL_FALSE;
83206f
@@ -1287,7 +1287,7 @@ dri2_query_image(__DRIimage *image, int attrib, int *value)
83206f
       *value = 1;
83206f
       return GL_TRUE;
83206f
    case __DRI_IMAGE_ATTRIB_MODIFIER_UPPER:
83206f
-      whandle.type = DRM_API_HANDLE_TYPE_KMS;
83206f
+      whandle.type = WINSYS_HANDLE_TYPE_KMS;
83206f
       whandle.modifier = DRM_FORMAT_MOD_INVALID;
83206f
       if (!image->texture->screen->resource_get_handle(image->texture->screen,
83206f
             NULL, image->texture, &whandle, usage))
83206f
@@ -1297,7 +1297,7 @@ dri2_query_image(__DRIimage *image, int attrib, int *value)
83206f
       *value = (whandle.modifier >> 32) & 0xffffffff;
83206f
       return GL_TRUE;
83206f
    case __DRI_IMAGE_ATTRIB_MODIFIER_LOWER:
83206f
-      whandle.type = DRM_API_HANDLE_TYPE_KMS;
83206f
+      whandle.type = WINSYS_HANDLE_TYPE_KMS;
83206f
       whandle.modifier = DRM_FORMAT_MOD_INVALID;
83206f
       if (!image->texture->screen->resource_get_handle(image->texture->screen,
83206f
             NULL, image->texture, &whandle, usage))
83206f
@@ -1377,7 +1377,7 @@ dri2_from_names(__DRIscreen *screen, int width, int height, int format,
83206f
       return NULL;
83206f
 
83206f
    memset(&whandle, 0, sizeof(whandle));
83206f
-   whandle.type = DRM_API_HANDLE_TYPE_SHARED;
83206f
+   whandle.type = WINSYS_HANDLE_TYPE_SHARED;
83206f
    whandle.handle = names[0];
83206f
    whandle.stride = strides[0];
83206f
    whandle.offset = offsets[0];
83206f
@@ -1909,7 +1909,7 @@ dri2_interop_export_object(__DRIcontext *_ctx,
83206f
    }
83206f
 
83206f
    memset(&whandle, 0, sizeof(whandle));
83206f
-   whandle.type = DRM_API_HANDLE_TYPE_FD;
83206f
+   whandle.type = WINSYS_HANDLE_TYPE_FD;
83206f
 
83206f
    success = screen->resource_get_handle(screen, st->pipe, res, &whandle,
83206f
                                          usage);
83206f
diff --git a/src/gallium/state_trackers/dri/drisw.c b/src/gallium/state_trackers/dri/drisw.c
83206f
index eb5752386dc..e24fcba3869 100644
83206f
--- a/src/gallium/state_trackers/dri/drisw.c
83206f
+++ b/src/gallium/state_trackers/dri/drisw.c
83206f
@@ -26,14 +26,6 @@
83206f
  *
83206f
  **************************************************************************/
83206f
 
83206f
-/* TODO:
83206f
- *
83206f
- * xshm / EGLImage:
83206f
- *
83206f
- * Allow the loaders to use the XSHM extension. It probably requires callbacks
83206f
- * for createImage/destroyImage similar to DRI2 getBuffers.
83206f
- */
83206f
-
83206f
 #include "util/u_format.h"
83206f
 #include "util/u_memory.h"
83206f
 #include "util/u_inlines.h"
83206f
@@ -86,6 +78,19 @@ put_image2(__DRIdrawable *dPriv, void *data, int x, int y,
83206f
                      data, dPriv->loaderPrivate);
83206f
 }
83206f
 
83206f
+static inline void
83206f
+put_image_shm(__DRIdrawable *dPriv, int shmid, char *shmaddr,
83206f
+              unsigned offset, int x, int y,
83206f
+              unsigned width, unsigned height, unsigned stride)
83206f
+{
83206f
+   __DRIscreen *sPriv = dPriv->driScreenPriv;
83206f
+   const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
83206f
+
83206f
+   loader->putImageShm(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
83206f
+                       x, y, width, height, stride,
83206f
+                       shmid, shmaddr, offset, dPriv->loaderPrivate);
83206f
+}
83206f
+
83206f
 static inline void
83206f
 get_image(__DRIdrawable *dPriv, int x, int y, int width, int height, void *data)
83206f
 {
83206f
@@ -112,6 +117,26 @@ get_image2(__DRIdrawable *dPriv, int x, int y, int width, int height, int stride
83206f
                      data, dPriv->loaderPrivate);
83206f
 }
83206f
 
83206f
+static inline bool
83206f
+get_image_shm(__DRIdrawable *dPriv, int x, int y, int width, int height,
83206f
+              struct pipe_resource *res)
83206f
+{
83206f
+   __DRIscreen *sPriv = dPriv->driScreenPriv;
83206f
+   const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
83206f
+   struct winsys_handle whandle;
83206f
+
83206f
+   whandle.type = WINSYS_HANDLE_TYPE_SHMID;
83206f
+
83206f
+   if (loader->base.version < 4 || !loader->getImageShm)
83206f
+      return FALSE;
83206f
+
83206f
+   if (!res->screen->resource_get_handle(res->screen, NULL, res, &whandle, PIPE_HANDLE_USAGE_WRITE))
83206f
+      return FALSE;
83206f
+
83206f
+   loader->getImageShm(dPriv, x, y, width, height, whandle.handle, dPriv->loaderPrivate);
83206f
+   return TRUE;
83206f
+}
83206f
+
83206f
 static void
83206f
 drisw_update_drawable_info(struct dri_drawable *drawable)
83206f
 {
83206f
@@ -152,6 +177,17 @@ drisw_put_image2(struct dri_drawable *drawable,
83206f
    put_image2(dPriv, data, x, y, width, height, stride);
83206f
 }
83206f
 
83206f
+static inline void
83206f
+drisw_put_image_shm(struct dri_drawable *drawable,
83206f
+                    int shmid, char *shmaddr, unsigned offset,
83206f
+                    int x, int y, unsigned width, unsigned height,
83206f
+                    unsigned stride)
83206f
+{
83206f
+   __DRIdrawable *dPriv = drawable->dPriv;
83206f
+
83206f
+   put_image_shm(dPriv, shmid, shmaddr, offset, x, y, width, height, stride);
83206f
+}
83206f
+
83206f
 static inline void
83206f
 drisw_present_texture(__DRIdrawable *dPriv,
83206f
                       struct pipe_resource *ptex, struct pipe_box *sub_box)
83206f
@@ -348,7 +384,8 @@ drisw_update_tex_buffer(struct dri_drawable *drawable,
83206f
                            x, y, w, h, &transfer);
83206f
 
83206f
    /* Copy the Drawable content to the mapped texture buffer */
83206f
-   get_image(dPriv, x, y, w, h, map);
83206f
+   if (!get_image_shm(dPriv, x, y, w, h, res))
83206f
+      get_image(dPriv, x, y, w, h, map);
83206f
 
83206f
    /* The pipe transfer has a pitch rounded up to the nearest 64 pixels.
83206f
       get_image() has a pitch rounded up to 4 bytes.  */
83206f
@@ -394,6 +431,7 @@ static struct drisw_loader_funcs drisw_lf = {
83206f
 static const __DRIconfig **
83206f
 drisw_init_screen(__DRIscreen * sPriv)
83206f
 {
83206f
+   const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
83206f
    const __DRIconfig **configs;
83206f
    struct dri_screen *screen;
83206f
    struct pipe_screen *pscreen = NULL;
83206f
@@ -409,6 +447,10 @@ drisw_init_screen(__DRIscreen * sPriv)
83206f
 
83206f
    sPriv->driverPrivate = (void *)screen;
83206f
    sPriv->extensions = drisw_screen_extensions;
83206f
+   if (loader->base.version >= 4) {
83206f
+      if (loader->putImageShm)
83206f
+         drisw_lf.put_image_shm = drisw_put_image_shm;
83206f
+   }
83206f
 
83206f
    if (pipe_loader_sw_probe_dri(&screen->dev, &drisw_lf)) {
83206f
       dri_init_options(screen);
83206f
diff --git a/src/gallium/state_trackers/nine/swapchain9.c b/src/gallium/state_trackers/nine/swapchain9.c
83206f
index f24a7d05437..7cf5c54bfa8 100644
83206f
--- a/src/gallium/state_trackers/nine/swapchain9.c
83206f
+++ b/src/gallium/state_trackers/nine/swapchain9.c
83206f
@@ -96,7 +96,7 @@ D3DWindowBuffer_create(struct NineSwapChain9 *This,
83206f
     HRESULT hr;
83206f
 
83206f
     memset(&whandle, 0, sizeof(whandle));
83206f
-    whandle.type = DRM_API_HANDLE_TYPE_FD;
83206f
+    whandle.type = WINSYS_HANDLE_TYPE_FD;
83206f
     This->screen->resource_get_handle(This->screen, pipe, resource,
83206f
                                       &whandle,
83206f
                                       for_frontbuffer_reading ?
83206f
diff --git a/src/gallium/state_trackers/va/buffer.c b/src/gallium/state_trackers/va/buffer.c
83206f
index deaeb1939fe..42ec9730fc1 100644
83206f
--- a/src/gallium/state_trackers/va/buffer.c
83206f
+++ b/src/gallium/state_trackers/va/buffer.c
83206f
@@ -305,7 +305,7 @@ vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id,
83206f
          drv->pipe->flush(drv->pipe, NULL, 0);
83206f
 
83206f
          memset(&whandle, 0, sizeof(whandle));
83206f
-         whandle.type = DRM_API_HANDLE_TYPE_FD;
83206f
+         whandle.type = WINSYS_HANDLE_TYPE_FD;
83206f
 
83206f
          if (!screen->resource_get_handle(screen, drv->pipe,
83206f
                                           buf->derived_surface.resource,
83206f
diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c
83206f
index f9412ce52e6..432480c458a 100644
83206f
--- a/src/gallium/state_trackers/va/surface.c
83206f
+++ b/src/gallium/state_trackers/va/surface.c
83206f
@@ -569,7 +569,7 @@ suface_from_external_memory(VADriverContextP ctx, vlVaSurface *surface,
83206f
    res_templ.usage = PIPE_USAGE_DEFAULT;
83206f
 
83206f
    memset(&whandle, 0, sizeof(struct winsys_handle));
83206f
-   whandle.type = DRM_API_HANDLE_TYPE_FD;
83206f
+   whandle.type = WINSYS_HANDLE_TYPE_FD;
83206f
    whandle.handle = memory_attibute->buffers[index];
83206f
    whandle.stride = memory_attibute->pitches[index];
83206f
 
83206f
@@ -1034,7 +1034,7 @@ vlVaExportSurfaceHandle(VADriverContextP ctx,
83206f
       }
83206f
 
83206f
       memset(&whandle, 0, sizeof(whandle));
83206f
-      whandle.type = DRM_API_HANDLE_TYPE_FD;
83206f
+      whandle.type = WINSYS_HANDLE_TYPE_FD;
83206f
 
83206f
       if (!screen->resource_get_handle(screen, drv->pipe, resource,
83206f
                                        &whandle, usage)) {
83206f
diff --git a/src/gallium/state_trackers/vdpau/output.c b/src/gallium/state_trackers/vdpau/output.c
83206f
index 8ef826836c1..6ef7a404474 100644
83206f
--- a/src/gallium/state_trackers/vdpau/output.c
83206f
+++ b/src/gallium/state_trackers/vdpau/output.c
83206f
@@ -805,7 +805,7 @@ VdpStatus vlVdpOutputSurfaceDMABuf(VdpOutputSurface surface,
83206f
    vlsurface->device->context->flush(vlsurface->device->context, NULL, 0);
83206f
 
83206f
    memset(&whandle, 0, sizeof(struct winsys_handle));
83206f
-   whandle.type = DRM_API_HANDLE_TYPE_FD;
83206f
+   whandle.type = WINSYS_HANDLE_TYPE_FD;
83206f
 
83206f
    pscreen = vlsurface->surface->texture->screen;
83206f
    if (!pscreen->resource_get_handle(pscreen, vlsurface->device->context,
83206f
diff --git a/src/gallium/state_trackers/vdpau/surface.c b/src/gallium/state_trackers/vdpau/surface.c
83206f
index 012d3036411..95bab8790db 100644
83206f
--- a/src/gallium/state_trackers/vdpau/surface.c
83206f
+++ b/src/gallium/state_trackers/vdpau/surface.c
83206f
@@ -526,7 +526,7 @@ VdpStatus vlVdpVideoSurfaceDMABuf(VdpVideoSurface surface,
83206f
    }
83206f
 
83206f
    memset(&whandle, 0, sizeof(struct winsys_handle));
83206f
-   whandle.type = DRM_API_HANDLE_TYPE_FD;
83206f
+   whandle.type = WINSYS_HANDLE_TYPE_FD;
83206f
    whandle.layer = surf->u.tex.first_layer;
83206f
 
83206f
    pscreen = surf->texture->screen;
83206f
diff --git a/src/gallium/state_trackers/xa/xa_tracker.c b/src/gallium/state_trackers/xa/xa_tracker.c
83206f
index 03a3abf6835..3d268a17750 100644
83206f
--- a/src/gallium/state_trackers/xa/xa_tracker.c
83206f
+++ b/src/gallium/state_trackers/xa/xa_tracker.c
83206f
@@ -311,12 +311,12 @@ handle_type(enum xa_handle_type type)
83206f
 {
83206f
     switch (type) {
83206f
     case xa_handle_type_kms:
83206f
-	return DRM_API_HANDLE_TYPE_KMS;
83206f
+	return WINSYS_HANDLE_TYPE_KMS;
83206f
     case xa_handle_type_fd:
83206f
-        return DRM_API_HANDLE_TYPE_FD;
83206f
+        return WINSYS_HANDLE_TYPE_FD;
83206f
     case xa_handle_type_shared:
83206f
     default:
83206f
-	return DRM_API_HANDLE_TYPE_SHARED;
83206f
+	return WINSYS_HANDLE_TYPE_SHARED;
83206f
     }
83206f
 }
83206f
 
83206f
@@ -404,7 +404,7 @@ xa_surface_from_handle(struct xa_tracker *xa,
83206f
 		  uint32_t handle, uint32_t stride)
83206f
 {
83206f
     return xa_surface_from_handle2(xa, width, height, depth, stype, xa_format,
83206f
-                                   DRM_API_HANDLE_TYPE_SHARED, flags, handle,
83206f
+                                   WINSYS_HANDLE_TYPE_SHARED, flags, handle,
83206f
                                    stride);
83206f
 }
83206f
 
83206f
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
83206f
index 544403ac84f..b680be7c6ff 100644
83206f
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
83206f
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
83206f
@@ -1275,10 +1275,10 @@ static struct pb_buffer *amdgpu_bo_from_handle(struct radeon_winsys *rws,
83206f
    }
83206f
 
83206f
    switch (whandle->type) {
83206f
-   case DRM_API_HANDLE_TYPE_SHARED:
83206f
+   case WINSYS_HANDLE_TYPE_SHARED:
83206f
       type = amdgpu_bo_handle_type_gem_flink_name;
83206f
       break;
83206f
-   case DRM_API_HANDLE_TYPE_FD:
83206f
+   case WINSYS_HANDLE_TYPE_FD:
83206f
       type = amdgpu_bo_handle_type_dma_buf_fd;
83206f
       break;
83206f
    default:
83206f
@@ -1362,13 +1362,13 @@ static bool amdgpu_bo_get_handle(struct pb_buffer *buffer,
83206f
    bo->u.real.use_reusable_pool = false;
83206f
 
83206f
    switch (whandle->type) {
83206f
-   case DRM_API_HANDLE_TYPE_SHARED:
83206f
+   case WINSYS_HANDLE_TYPE_SHARED:
83206f
       type = amdgpu_bo_handle_type_gem_flink_name;
83206f
       break;
83206f
-   case DRM_API_HANDLE_TYPE_FD:
83206f
+   case WINSYS_HANDLE_TYPE_FD:
83206f
       type = amdgpu_bo_handle_type_dma_buf_fd;
83206f
       break;
83206f
-   case DRM_API_HANDLE_TYPE_KMS:
83206f
+   case WINSYS_HANDLE_TYPE_KMS:
83206f
       type = amdgpu_bo_handle_type_kms;
83206f
       break;
83206f
    default:
83206f
diff --git a/src/gallium/winsys/i915/drm/i915_drm_buffer.c b/src/gallium/winsys/i915/drm/i915_drm_buffer.c
83206f
index 890f7dc2833..509984ac6ac 100644
83206f
--- a/src/gallium/winsys/i915/drm/i915_drm_buffer.c
83206f
+++ b/src/gallium/winsys/i915/drm/i915_drm_buffer.c
83206f
@@ -98,7 +98,7 @@ i915_drm_buffer_from_handle(struct i915_winsys *iws,
83206f
    struct i915_drm_buffer *buf;
83206f
    uint32_t tile = 0, swizzle = 0;
83206f
 
83206f
-   if ((whandle->type != DRM_API_HANDLE_TYPE_SHARED) && (whandle->type != DRM_API_HANDLE_TYPE_FD))
83206f
+   if ((whandle->type != WINSYS_HANDLE_TYPE_SHARED) && (whandle->type != WINSYS_HANDLE_TYPE_FD))
83206f
       return NULL;
83206f
 
83206f
    if (whandle->offset != 0)
83206f
@@ -110,9 +110,9 @@ i915_drm_buffer_from_handle(struct i915_winsys *iws,
83206f
 
83206f
    buf->magic = 0xDEAD1337;
83206f
 
83206f
-   if (whandle->type == DRM_API_HANDLE_TYPE_SHARED)
83206f
+   if (whandle->type == WINSYS_HANDLE_TYPE_SHARED)
83206f
        buf->bo = drm_intel_bo_gem_create_from_name(idws->gem_manager, "gallium3d_from_handle", whandle->handle);
83206f
-   else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
83206f
+   else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
83206f
        int fd = (int) whandle->handle;
83206f
        buf->bo = drm_intel_bo_gem_create_from_prime(idws->gem_manager, fd, height * whandle->stride);
83206f
    }
83206f
@@ -143,7 +143,7 @@ i915_drm_buffer_get_handle(struct i915_winsys *iws,
83206f
 {
83206f
    struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
83206f
 
83206f
-   if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
83206f
+   if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) {
83206f
       if (!buf->flinked) {
83206f
          if (drm_intel_bo_flink(buf->bo, &buf->flink))
83206f
             return FALSE;
83206f
@@ -151,9 +151,9 @@ i915_drm_buffer_get_handle(struct i915_winsys *iws,
83206f
       }
83206f
 
83206f
       whandle->handle = buf->flink;
83206f
-   } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
83206f
+   } else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) {
83206f
       whandle->handle = buf->bo->handle;
83206f
-   } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
83206f
+   } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
83206f
       int fd;
83206f
 
83206f
       if (drm_intel_bo_gem_export_to_prime(buf->bo, &fd))
83206f
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
83206f
index fc95a98620b..6ed23530ab0 100644
83206f
--- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
83206f
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
83206f
@@ -1124,10 +1124,10 @@ static struct pb_buffer *radeon_winsys_bo_from_handle(struct radeon_winsys *rws,
83206f
      * The list of pairs is guarded by a mutex, of course. */
83206f
     mtx_lock(&ws->bo_handles_mutex);
83206f
 
83206f
-    if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
83206f
+    if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) {
83206f
         /* First check if there already is an existing bo for the handle. */
83206f
         bo = util_hash_table_get(ws->bo_names, (void*)(uintptr_t)whandle->handle);
83206f
-    } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
83206f
+    } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
83206f
         /* We must first get the GEM handle, as fds are unreliable keys */
83206f
         r = drmPrimeFDToHandle(ws->fd, whandle->handle, &handle);
83206f
         if (r)
83206f
@@ -1151,7 +1151,7 @@ static struct pb_buffer *radeon_winsys_bo_from_handle(struct radeon_winsys *rws,
83206f
         goto fail;
83206f
     }
83206f
 
83206f
-    if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
83206f
+    if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) {
83206f
         struct drm_gem_open open_arg = {};
83206f
         memset(&open_arg, 0, sizeof(open_arg));
83206f
         /* Open the BO. */
83206f
@@ -1163,7 +1163,7 @@ static struct pb_buffer *radeon_winsys_bo_from_handle(struct radeon_winsys *rws,
83206f
         handle = open_arg.handle;
83206f
         size = open_arg.size;
83206f
         bo->flink_name = whandle->handle;
83206f
-    } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
83206f
+    } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
83206f
         size = lseek(whandle->handle, 0, SEEK_END);
83206f
         /* 
83206f
          * Could check errno to determine whether the kernel is new enough, but
83206f
@@ -1268,7 +1268,7 @@ static bool radeon_winsys_bo_get_handle(struct pb_buffer *buffer,
83206f
 
83206f
     bo->u.real.use_reusable_pool = false;
83206f
 
83206f
-    if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
83206f
+    if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) {
83206f
         if (!bo->flink_name) {
83206f
             flink.handle = bo->handle;
83206f
 
83206f
@@ -1283,9 +1283,9 @@ static bool radeon_winsys_bo_get_handle(struct pb_buffer *buffer,
83206f
             mtx_unlock(&ws->bo_handles_mutex);
83206f
         }
83206f
         whandle->handle = bo->flink_name;
83206f
-    } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
83206f
+    } else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) {
83206f
         whandle->handle = bo->handle;
83206f
-    } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
83206f
+    } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
83206f
         if (drmPrimeHandleToFD(ws->fd, bo->handle, DRM_CLOEXEC, (int*)&whandle->handle))
83206f
             return false;
83206f
     }
83206f
diff --git a/src/gallium/winsys/svga/drm/vmw_screen_dri.c b/src/gallium/winsys/svga/drm/vmw_screen_dri.c
83206f
index 2a0ac7b3337..76f29e2aced 100644
83206f
--- a/src/gallium/winsys/svga/drm/vmw_screen_dri.c
83206f
+++ b/src/gallium/winsys/svga/drm/vmw_screen_dri.c
83206f
@@ -234,11 +234,11 @@ vmw_drm_surface_from_handle(struct svga_winsys_screen *sws,
83206f
     }
83206f
 
83206f
     switch (whandle->type) {
83206f
-    case DRM_API_HANDLE_TYPE_SHARED:
83206f
-    case DRM_API_HANDLE_TYPE_KMS:
83206f
+    case WINSYS_HANDLE_TYPE_SHARED:
83206f
+    case WINSYS_HANDLE_TYPE_KMS:
83206f
        handle = whandle->handle;
83206f
        break;
83206f
-    case DRM_API_HANDLE_TYPE_FD:
83206f
+    case WINSYS_HANDLE_TYPE_FD:
83206f
        ret = drmPrimeFDToHandle(vws->ioctl.drm_fd, whandle->handle,
83206f
                                 &handle);
83206f
        if (ret) {
83206f
@@ -263,7 +263,7 @@ vmw_drm_surface_from_handle(struct svga_winsys_screen *sws,
83206f
     /*
83206f
      * Need to close the handle we got from prime.
83206f
      */
83206f
-    if (whandle->type == DRM_API_HANDLE_TYPE_FD)
83206f
+    if (whandle->type == WINSYS_HANDLE_TYPE_FD)
83206f
        vmw_ioctl_surface_destroy(vws, handle);
83206f
 
83206f
     if (ret) {
83206f
@@ -340,11 +340,11 @@ vmw_drm_surface_get_handle(struct svga_winsys_screen *sws,
83206f
     whandle->offset = 0;
83206f
 
83206f
     switch (whandle->type) {
83206f
-    case DRM_API_HANDLE_TYPE_SHARED:
83206f
-    case DRM_API_HANDLE_TYPE_KMS:
83206f
+    case WINSYS_HANDLE_TYPE_SHARED:
83206f
+    case WINSYS_HANDLE_TYPE_KMS:
83206f
        whandle->handle = vsrf->sid;
83206f
        break;
83206f
-    case DRM_API_HANDLE_TYPE_FD:
83206f
+    case WINSYS_HANDLE_TYPE_FD:
83206f
        ret = drmPrimeHandleToFD(vws->ioctl.drm_fd, vsrf->sid, DRM_CLOEXEC,
83206f
 				(int *)&whandle->handle);
83206f
        if (ret) {
83206f
diff --git a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
83206f
index 62a2af6d650..16dd5c8593a 100644
83206f
--- a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
83206f
+++ b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
83206f
@@ -290,13 +290,13 @@ vmw_ioctl_surface_req(const struct vmw_winsys_screen *vws,
83206f
    int ret;
83206f
 
83206f
    switch(whandle->type) {
83206f
-   case DRM_API_HANDLE_TYPE_SHARED:
83206f
-   case DRM_API_HANDLE_TYPE_KMS:
83206f
+   case WINSYS_HANDLE_TYPE_SHARED:
83206f
+   case WINSYS_HANDLE_TYPE_KMS:
83206f
       *needs_unref = FALSE;
83206f
       req->handle_type = DRM_VMW_HANDLE_LEGACY;
83206f
       req->sid = whandle->handle;
83206f
       break;
83206f
-   case DRM_API_HANDLE_TYPE_FD:
83206f
+   case WINSYS_HANDLE_TYPE_FD:
83206f
       if (!vws->ioctl.have_drm_2_6) {
83206f
          uint32_t handle;
83206f
 
83206f
diff --git a/src/gallium/winsys/sw/dri/dri_sw_winsys.c b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
83206f
index 00849985d6b..8335e52200f 100644
83206f
--- a/src/gallium/winsys/sw/dri/dri_sw_winsys.c
83206f
+++ b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
83206f
@@ -26,6 +26,9 @@
83206f
  *
83206f
  **************************************************************************/
83206f
 
83206f
+#include <sys/ipc.h>
83206f
+#include <sys/shm.h>
83206f
+
83206f
 #include "pipe/p_compiler.h"
83206f
 #include "pipe/p_format.h"
83206f
 #include "util/u_inlines.h"
83206f
@@ -45,6 +48,7 @@ struct dri_sw_displaytarget
83206f
    unsigned stride;
83206f
 
83206f
    unsigned map_flags;
83206f
+   int shmid;
83206f
    void *data;
83206f
    void *mapped;
83206f
    const void *front_private;
83206f
@@ -79,6 +83,25 @@ dri_sw_is_displaytarget_format_supported( struct sw_winsys *ws,
83206f
    return TRUE;
83206f
 }
83206f
 
83206f
+static char *
83206f
+alloc_shm(struct dri_sw_displaytarget *dri_sw_dt, unsigned size)
83206f
+{
83206f
+   char *addr;
83206f
+
83206f
+   dri_sw_dt->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);
83206f
+   if (dri_sw_dt->shmid < 0)
83206f
+      return NULL;
83206f
+
83206f
+   addr = (char *) shmat(dri_sw_dt->shmid, 0, 0);
83206f
+   /* mark the segment immediately for deletion to avoid leaks */
83206f
+   shmctl(dri_sw_dt->shmid, IPC_RMID, 0);
83206f
+
83206f
+   if (addr == (char *) -1)
83206f
+      return NULL;
83206f
+
83206f
+   return addr;
83206f
+}
83206f
+
83206f
 static struct sw_displaytarget *
83206f
 dri_sw_displaytarget_create(struct sw_winsys *winsys,
83206f
                             unsigned tex_usage,
83206f
@@ -88,6 +111,7 @@ dri_sw_displaytarget_create(struct sw_winsys *winsys,
83206f
                             const void *front_private,
83206f
                             unsigned *stride)
83206f
 {
83206f
+   struct dri_sw_winsys *ws = dri_sw_winsys(winsys);
83206f
    struct dri_sw_displaytarget *dri_sw_dt;
83206f
    unsigned nblocksy, size, format_stride;
83206f
 
83206f
@@ -106,7 +130,13 @@ dri_sw_displaytarget_create(struct sw_winsys *winsys,
83206f
    nblocksy = util_format_get_nblocksy(format, height);
83206f
    size = dri_sw_dt->stride * nblocksy;
83206f
 
83206f
-   dri_sw_dt->data = align_malloc(size, alignment);
83206f
+   dri_sw_dt->shmid = -1;
83206f
+   if (ws->lf->put_image_shm)
83206f
+      dri_sw_dt->data = alloc_shm(dri_sw_dt, size);
83206f
+
83206f
+   if(!dri_sw_dt->data)
83206f
+      dri_sw_dt->data = align_malloc(size, alignment);
83206f
+
83206f
    if(!dri_sw_dt->data)
83206f
       goto no_data;
83206f
 
83206f
@@ -125,7 +155,12 @@ dri_sw_displaytarget_destroy(struct sw_winsys *ws,
83206f
 {
83206f
    struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
83206f
 
83206f
-   align_free(dri_sw_dt->data);
83206f
+   if (dri_sw_dt->shmid >= 0) {
83206f
+      shmdt(dri_sw_dt->data);
83206f
+      shmctl(dri_sw_dt->shmid, IPC_RMID, 0);
83206f
+   } else {
83206f
+      align_free(dri_sw_dt->data);
83206f
+   }
83206f
 
83206f
    FREE(dri_sw_dt);
83206f
 }
83206f
@@ -174,7 +209,15 @@ dri_sw_displaytarget_get_handle(struct sw_winsys *winsys,
83206f
                                 struct sw_displaytarget *dt,
83206f
                                 struct winsys_handle *whandle)
83206f
 {
83206f
-   assert(0);
83206f
+   struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
83206f
+
83206f
+   if (whandle->type == WINSYS_HANDLE_TYPE_SHMID) {
83206f
+      if (dri_sw_dt->shmid < 0)
83206f
+         return FALSE;
83206f
+      whandle->handle = dri_sw_dt->shmid;
83206f
+      return TRUE;
83206f
+   }
83206f
+
83206f
    return FALSE;
83206f
 }
83206f
 
83206f
@@ -187,25 +230,38 @@ dri_sw_displaytarget_display(struct sw_winsys *ws,
83206f
    struct dri_sw_winsys *dri_sw_ws = dri_sw_winsys(ws);
83206f
    struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
83206f
    struct dri_drawable *dri_drawable = (struct dri_drawable *)context_private;
83206f
-   unsigned width, height;
83206f
+   unsigned width, height, x = 0, y = 0;
83206f
    unsigned blsize = util_format_get_blocksize(dri_sw_dt->format);
83206f
+   unsigned offset = 0;
83206f
+   void *data = dri_sw_dt->data;
83206f
 
83206f
    /* Set the width to 'stride / cpp'.
83206f
     *
83206f
     * PutImage correctly clips to the width of the dst drawable.
83206f
     */
83206f
-   width = dri_sw_dt->stride / blsize;
83206f
-
83206f
-   height = dri_sw_dt->height;
83206f
-
83206f
    if (box) {
83206f
-       void *data;
83206f
-       data = (char *)dri_sw_dt->data + (dri_sw_dt->stride * box->y) + box->x * blsize;
83206f
-       dri_sw_ws->lf->put_image2(dri_drawable, data,
83206f
-                                 box->x, box->y, box->width, box->height, dri_sw_dt->stride);
83206f
+      offset = (dri_sw_dt->stride * box->y) + box->x * blsize;
83206f
+      data += offset;
83206f
+      x = box->x;
83206f
+      y = box->y;
83206f
+      width = box->width;
83206f
+      height = box->height;
83206f
    } else {
83206f
-       dri_sw_ws->lf->put_image(dri_drawable, dri_sw_dt->data, width, height);
83206f
+      width = dri_sw_dt->stride / blsize;
83206f
+      height = dri_sw_dt->height;
83206f
    }
83206f
+
83206f
+   if (dri_sw_dt->shmid != -1) {
83206f
+      dri_sw_ws->lf->put_image_shm(dri_drawable, dri_sw_dt->shmid, dri_sw_dt->data, offset,
83206f
+                                   x, y, width, height, dri_sw_dt->stride);
83206f
+      return;
83206f
+   }
83206f
+
83206f
+   if (box)
83206f
+      dri_sw_ws->lf->put_image2(dri_drawable, data,
83206f
+                                x, y, width, height, dri_sw_dt->stride);
83206f
+   else
83206f
+      dri_sw_ws->lf->put_image(dri_drawable, data, width, height);
83206f
 }
83206f
 
83206f
 static void
83206f
diff --git a/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c b/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c
83206f
index 22e1c936ac5..2df5f589e48 100644
83206f
--- a/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c
83206f
+++ b/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c
83206f
@@ -292,8 +292,8 @@ kms_sw_displaytarget_from_handle(struct sw_winsys *ws,
83206f
    struct kms_sw_winsys *kms_sw = kms_sw_winsys(ws);
83206f
    struct kms_sw_displaytarget *kms_sw_dt;
83206f
 
83206f
-   assert(whandle->type == DRM_API_HANDLE_TYPE_KMS ||
83206f
-          whandle->type == DRM_API_HANDLE_TYPE_FD);
83206f
+   assert(whandle->type == WINSYS_HANDLE_TYPE_KMS ||
83206f
+          whandle->type == WINSYS_HANDLE_TYPE_FD);
83206f
 
83206f
    if (whandle->offset != 0) {
83206f
       DEBUG_PRINT("KMS-DEBUG: attempt to import unsupported winsys offset %d\n",
83206f
@@ -302,7 +302,7 @@ kms_sw_displaytarget_from_handle(struct sw_winsys *ws,
83206f
    }
83206f
 
83206f
    switch(whandle->type) {
83206f
-   case DRM_API_HANDLE_TYPE_FD:
83206f
+   case WINSYS_HANDLE_TYPE_FD:
83206f
       kms_sw_dt = kms_sw_displaytarget_add_from_prime(kms_sw, whandle->handle,
83206f
                                                       templ->width0,
83206f
                                                       templ->height0,
83206f
@@ -310,7 +310,7 @@ kms_sw_displaytarget_from_handle(struct sw_winsys *ws,
83206f
       if (kms_sw_dt)
83206f
          *stride = kms_sw_dt->stride;
83206f
       return (struct sw_displaytarget *)kms_sw_dt;
83206f
-   case DRM_API_HANDLE_TYPE_KMS:
83206f
+   case WINSYS_HANDLE_TYPE_KMS:
83206f
       kms_sw_dt = kms_sw_displaytarget_find_and_ref(kms_sw, whandle->handle);
83206f
       if (kms_sw_dt) {
83206f
          *stride = kms_sw_dt->stride;
83206f
@@ -334,12 +334,12 @@ kms_sw_displaytarget_get_handle(struct sw_winsys *winsys,
83206f
    struct kms_sw_displaytarget *kms_sw_dt = kms_sw_displaytarget(dt);
83206f
 
83206f
    switch(whandle->type) {
83206f
-   case DRM_API_HANDLE_TYPE_KMS:
83206f
+   case WINSYS_HANDLE_TYPE_KMS:
83206f
       whandle->handle = kms_sw_dt->handle;
83206f
       whandle->stride = kms_sw_dt->stride;
83206f
       whandle->offset = 0;
83206f
       return TRUE;
83206f
-   case DRM_API_HANDLE_TYPE_FD:
83206f
+   case WINSYS_HANDLE_TYPE_FD:
83206f
       if (!drmPrimeHandleToFD(kms_sw->fd, kms_sw_dt->handle,
83206f
                              DRM_CLOEXEC, (int*)&whandle->handle)) {
83206f
          whandle->stride = kms_sw_dt->stride;
83206f
diff --git a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c
83206f
index 71e652ebf31..cd16413bb8e 100644
83206f
--- a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c
83206f
+++ b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c
83206f
@@ -398,7 +398,7 @@ virgl_drm_winsys_resource_create_handle(struct virgl_winsys *qws,
83206f
 
83206f
    mtx_lock(&qdws->bo_handles_mutex);
83206f
 
83206f
-   if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
83206f
+   if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) {
83206f
       res = util_hash_table_get(qdws->bo_names, (void*)(uintptr_t)handle);
83206f
       if (res) {
83206f
          struct virgl_hw_res *r = NULL;
83206f
@@ -407,7 +407,7 @@ virgl_drm_winsys_resource_create_handle(struct virgl_winsys *qws,
83206f
       }
83206f
    }
83206f
 
83206f
-   if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
83206f
+   if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
83206f
       int r;
83206f
       r = drmPrimeFDToHandle(qdws->fd, whandle->handle, &handle);
83206f
       if (r) {
83206f
@@ -428,7 +428,7 @@ virgl_drm_winsys_resource_create_handle(struct virgl_winsys *qws,
83206f
    if (!res)
83206f
       goto done;
83206f
 
83206f
-   if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
83206f
+   if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
83206f
       res->bo_handle = handle;
83206f
    } else {
83206f
       fprintf(stderr, "gem open handle %d\n", handle);
83206f
@@ -478,7 +478,7 @@ static boolean virgl_drm_winsys_resource_get_handle(struct virgl_winsys *qws,
83206f
    if (!res)
83206f
        return FALSE;
83206f
 
83206f
-   if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
83206f
+   if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) {
83206f
       if (!res->flinked) {
83206f
          memset(&flink, 0, sizeof(flink));
83206f
          flink.handle = res->bo_handle;
83206f
@@ -494,9 +494,9 @@ static boolean virgl_drm_winsys_resource_get_handle(struct virgl_winsys *qws,
83206f
          mtx_unlock(&qdws->bo_handles_mutex);
83206f
       }
83206f
       whandle->handle = res->flink;
83206f
-   } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
83206f
+   } else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) {
83206f
       whandle->handle = res->bo_handle;
83206f
-   } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
83206f
+   } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
83206f
       if (drmPrimeHandleToFD(qdws->fd, res->bo_handle, DRM_CLOEXEC, (int*)&whandle->handle))
83206f
             return FALSE;
83206f
       mtx_lock(&qdws->bo_handles_mutex);
83206f
diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c
83206f
index df2467a5c2d..a2777100a32 100644
83206f
--- a/src/glx/drisw_glx.c
83206f
+++ b/src/glx/drisw_glx.c
83206f
@@ -28,10 +28,12 @@
83206f
 #include <dlfcn.h>
83206f
 #include "dri_common.h"
83206f
 #include "drisw_priv.h"
83206f
+#include <X11/extensions/shmproto.h>
83206f
+#include <assert.h>
83206f
 
83206f
 static Bool
83206f
-XCreateDrawable(struct drisw_drawable * pdp,
83206f
-                Display * dpy, XID drawable, int visualid)
83206f
+XCreateGCs(struct drisw_drawable * pdp,
83206f
+           Display * dpy, XID drawable, int visualid)
83206f
 {
83206f
    XGCValues gcvalues;
83206f
    long visMask;
83206f
@@ -56,15 +58,78 @@ XCreateDrawable(struct drisw_drawable * pdp,
83206f
    if (!pdp->visinfo || num_visuals == 0)
83206f
       return False;
83206f
 
83206f
-   /* create XImage */
83206f
-   pdp->ximage = XCreateImage(dpy,
83206f
-                              pdp->visinfo->visual,
83206f
-                              pdp->visinfo->depth,
83206f
-                              ZPixmap, 0,             /* format, offset */
83206f
-                              NULL,                   /* data */
83206f
-                              0, 0,                   /* width, height */
83206f
-                              32,                     /* bitmap_pad */
83206f
-                              0);                     /* bytes_per_line */
83206f
+   return True;
83206f
+}
83206f
+
83206f
+static int xshm_error = 0;
83206f
+static int xshm_opcode = -1;
83206f
+
83206f
+/**
83206f
+ * Catches potential Xlib errors.
83206f
+ */
83206f
+static int
83206f
+handle_xerror(Display *dpy, XErrorEvent *event)
83206f
+{
83206f
+   (void) dpy;
83206f
+
83206f
+   assert(xshm_opcode != -1);
83206f
+   if (event->request_code != xshm_opcode ||
83206f
+       event->minor_code != X_ShmAttach)
83206f
+      return 0;
83206f
+
83206f
+   xshm_error = 1;
83206f
+   return 0;
83206f
+}
83206f
+
83206f
+static Bool
83206f
+XCreateDrawable(struct drisw_drawable * pdp, int shmid, Display * dpy)
83206f
+{
83206f
+   if (pdp->ximage) {
83206f
+      XDestroyImage(pdp->ximage);
83206f
+      pdp->ximage = NULL;
83206f
+   }
83206f
+
83206f
+   if (!xshm_error && shmid >= 0) {
83206f
+      pdp->shminfo.shmid = shmid;
83206f
+      pdp->ximage = XShmCreateImage(dpy,
83206f
+                                    pdp->visinfo->visual,
83206f
+                                    pdp->visinfo->depth,
83206f
+                                    ZPixmap,              /* format */
83206f
+                                    NULL,                 /* data */
83206f
+                                    &pdp->shminfo,        /* shminfo */
83206f
+                                    0, 0);                /* width, height */
83206f
+      if (pdp->ximage != NULL) {
83206f
+         int (*old_handler)(Display *, XErrorEvent *);
83206f
+
83206f
+         /* dispatch pending errors */
83206f
+         XSync(dpy, False);
83206f
+
83206f
+         old_handler = XSetErrorHandler(handle_xerror);
83206f
+         /* This may trigger the X protocol error we're ready to catch: */
83206f
+         XShmAttach(dpy, &pdp->shminfo);
83206f
+         XSync(dpy, False);
83206f
+
83206f
+         if (xshm_error) {
83206f
+         /* we are on a remote display, this error is normal, don't print it */
83206f
+            XDestroyImage(pdp->ximage);
83206f
+            pdp->ximage = NULL;
83206f
+         }
83206f
+
83206f
+         (void) XSetErrorHandler(old_handler);
83206f
+      }
83206f
+   }
83206f
+
83206f
+   if (pdp->ximage == NULL) {
83206f
+      pdp->shminfo.shmid = -1;
83206f
+      pdp->ximage = XCreateImage(dpy,
83206f
+                                 pdp->visinfo->visual,
83206f
+                                 pdp->visinfo->depth,
83206f
+                                 ZPixmap, 0,             /* format, offset */
83206f
+                                 NULL,                   /* data */
83206f
+                                 0, 0,                   /* width, height */
83206f
+                                 32,                     /* bitmap_pad */
83206f
+                                 0);                     /* bytes_per_line */
83206f
+   }
83206f
 
83206f
   /**
83206f
    * swrast does not handle 24-bit depth with 24 bpp, so let X do the
83206f
@@ -79,7 +144,9 @@ XCreateDrawable(struct drisw_drawable * pdp,
83206f
 static void
83206f
 XDestroyDrawable(struct drisw_drawable * pdp, Display * dpy, XID drawable)
83206f
 {
83206f
-   XDestroyImage(pdp->ximage);
83206f
+   if (pdp->ximage)
83206f
+      XDestroyImage(pdp->ximage);
83206f
+
83206f
    free(pdp->visinfo);
83206f
 
83206f
    XFreeGC(dpy, pdp->gc);
83206f
@@ -133,9 +200,9 @@ bytes_per_line(unsigned pitch_bits, unsigned mul)
83206f
 }
83206f
 
83206f
 static void
83206f
-swrastPutImage2(__DRIdrawable * draw, int op,
83206f
+swrastXPutImage(__DRIdrawable * draw, int op,
83206f
                 int x, int y, int w, int h, int stride,
83206f
-                char *data, void *loaderPrivate)
83206f
+                int shmid, char *data, void *loaderPrivate)
83206f
 {
83206f
    struct drisw_drawable *pdp = loaderPrivate;
83206f
    __GLXDRIdrawable *pdraw = &(pdp->base);
83206f
@@ -144,6 +211,11 @@ swrastPutImage2(__DRIdrawable * draw, int op,
83206f
    XImage *ximage;
83206f
    GC gc;
83206f
 
83206f
+   if (!pdp->ximage || shmid != pdp->shminfo.shmid) {
83206f
+      if (!XCreateDrawable(pdp, shmid, dpy))
83206f
+         return;
83206f
+   }
83206f
+
83206f
    switch (op) {
83206f
    case __DRI_SWRAST_IMAGE_OP_DRAW:
83206f
       gc = pdp->gc;
83206f
@@ -156,24 +228,52 @@ swrastPutImage2(__DRIdrawable * draw, int op,
83206f
    }
83206f
 
83206f
    drawable = pdraw->xDrawable;
83206f
-
83206f
    ximage = pdp->ximage;
83206f
-   ximage->data = data;
83206f
-   ximage->width = w;
83206f
-   ximage->height = h;
83206f
    ximage->bytes_per_line = stride ? stride : bytes_per_line(w * ximage->bits_per_pixel, 32);
83206f
+   ximage->data = data;
83206f
 
83206f
-   XPutImage(dpy, drawable, gc, ximage, 0, 0, x, y, w, h);
83206f
-
83206f
+   if (pdp->shminfo.shmid >= 0) {
83206f
+      ximage->width = ximage->bytes_per_line / ((ximage->bits_per_pixel + 7)/ 8);
83206f
+      ximage->height = h;
83206f
+      XShmPutImage(dpy, drawable, gc, ximage, 0, 0, x, y, w, h, False);
83206f
+      XSync(dpy, False);
83206f
+   } else {
83206f
+      ximage->width = w;
83206f
+      ximage->height = h;
83206f
+      XPutImage(dpy, drawable, gc, ximage, 0, 0, x, y, w, h);
83206f
+   }
83206f
    ximage->data = NULL;
83206f
 }
83206f
 
83206f
+static void
83206f
+swrastPutImageShm(__DRIdrawable * draw, int op,
83206f
+                  int x, int y, int w, int h, int stride,
83206f
+                  int shmid, char *shmaddr, unsigned offset,
83206f
+                  void *loaderPrivate)
83206f
+{
83206f
+   struct drisw_drawable *pdp = loaderPrivate;
83206f
+
83206f
+   pdp->shminfo.shmaddr = shmaddr;
83206f
+   swrastXPutImage(draw, op, x, y, w, h, stride, shmid,
83206f
+                   shmaddr + offset, loaderPrivate);
83206f
+}
83206f
+
83206f
+static void
83206f
+swrastPutImage2(__DRIdrawable * draw, int op,
83206f
+                int x, int y, int w, int h, int stride,
83206f
+                char *data, void *loaderPrivate)
83206f
+{
83206f
+   swrastXPutImage(draw, op, x, y, w, h, stride, -1,
83206f
+                   data, loaderPrivate);
83206f
+}
83206f
+
83206f
 static void
83206f
 swrastPutImage(__DRIdrawable * draw, int op,
83206f
                int x, int y, int w, int h,
83206f
                char *data, void *loaderPrivate)
83206f
 {
83206f
-   swrastPutImage2(draw, op, x, y, w, h, 0, data, loaderPrivate);
83206f
+   swrastXPutImage(draw, op, x, y, w, h, 0, -1,
83206f
+                   data, loaderPrivate);
83206f
 }
83206f
 
83206f
 static void
83206f
@@ -187,6 +287,11 @@ swrastGetImage2(__DRIdrawable * read,
83206f
    Drawable readable;
83206f
    XImage *ximage;
83206f
 
83206f
+   if (!prp->ximage || prp->shminfo.shmid >= 0) {
83206f
+      if (!XCreateDrawable(prp, -1, dpy))
83206f
+         return;
83206f
+   }
83206f
+
83206f
    readable = pread->xDrawable;
83206f
 
83206f
    ximage = prp->ximage;
83206f
@@ -208,6 +313,49 @@ swrastGetImage(__DRIdrawable * read,
83206f
    swrastGetImage2(read, x, y, w, h, 0, data, loaderPrivate);
83206f
 }
83206f
 
83206f
+static void
83206f
+swrastGetImageShm(__DRIdrawable * read,
83206f
+                  int x, int y, int w, int h,
83206f
+                  int shmid, void *loaderPrivate)
83206f
+{
83206f
+   struct drisw_drawable *prp = loaderPrivate;
83206f
+   __GLXDRIdrawable *pread = &(prp->base);
83206f
+   Display *dpy = pread->psc->dpy;
83206f
+   Drawable readable;
83206f
+   XImage *ximage;
83206f
+
83206f
+   if (!prp->ximage || shmid != prp->shminfo.shmid) {
83206f
+      if (!XCreateDrawable(prp, shmid, dpy))
83206f
+         return;
83206f
+   }
83206f
+   readable = pread->xDrawable;
83206f
+
83206f
+   ximage = prp->ximage;
83206f
+   ximage->data = prp->shminfo.shmaddr; /* no offset */
83206f
+   ximage->width = w;
83206f
+   ximage->height = h;
83206f
+   ximage->bytes_per_line = bytes_per_line(w * ximage->bits_per_pixel, 32);
83206f
+
83206f
+   XShmGetImage(dpy, readable, ximage, x, y, ~0L);
83206f
+}
83206f
+
83206f
+static const __DRIswrastLoaderExtension swrastLoaderExtension_shm = {
83206f
+   .base = {__DRI_SWRAST_LOADER, 4 },
83206f
+
83206f
+   .getDrawableInfo     = swrastGetDrawableInfo,
83206f
+   .putImage            = swrastPutImage,
83206f
+   .getImage            = swrastGetImage,
83206f
+   .putImage2           = swrastPutImage2,
83206f
+   .getImage2           = swrastGetImage2,
83206f
+   .putImageShm         = swrastPutImageShm,
83206f
+   .getImageShm         = swrastGetImageShm,
83206f
+};
83206f
+
83206f
+static const __DRIextension *loader_extensions_shm[] = {
83206f
+   &swrastLoaderExtension_shm.base,
83206f
+   NULL
83206f
+};
83206f
+
83206f
 static const __DRIswrastLoaderExtension swrastLoaderExtension = {
83206f
    .base = {__DRI_SWRAST_LOADER, 3 },
83206f
 
83206f
@@ -218,7 +366,7 @@ static const __DRIswrastLoaderExtension swrastLoaderExtension = {
83206f
    .getImage2           = swrastGetImage2,
83206f
 };
83206f
 
83206f
-static const __DRIextension *loader_extensions[] = {
83206f
+static const __DRIextension *loader_extensions_noshm[] = {
83206f
    &swrastLoaderExtension.base,
83206f
    NULL
83206f
 };
83206f
@@ -527,7 +675,7 @@ driswCreateDrawable(struct glx_screen *base, XID xDrawable,
83206f
    pdp->base.drawable = drawable;
83206f
    pdp->base.psc = &psc->base;
83206f
 
83206f
-   ret = XCreateDrawable(pdp, psc->base.dpy, xDrawable, modes->visualID);
83206f
+   ret = XCreateGCs(pdp, psc->base.dpy, xDrawable, modes->visualID);
83206f
    if (!ret) {
83206f
       free(pdp);
83206f
       return NULL;
83206f
@@ -661,6 +809,14 @@ driswBindExtensions(struct drisw_screen *psc, const __DRIextension **extensions)
83206f
    }
83206f
 }
83206f
 
83206f
+static int
83206f
+check_xshm(Display *dpy)
83206f
+{
83206f
+   int ignore;
83206f
+
83206f
+   return XQueryExtension(dpy, "MIT-SHM", &xshm_opcode, &ignore, &ignore);
83206f
+}
83206f
+
83206f
 static struct glx_screen *
83206f
 driswCreateScreen(int screen, struct glx_display *priv)
83206f
 {
83206f
@@ -670,6 +826,7 @@ driswCreateScreen(int screen, struct glx_display *priv)
83206f
    struct drisw_screen *psc;
83206f
    struct glx_config *configs = NULL, *visuals = NULL;
83206f
    int i;
83206f
+   const __DRIextension **loader_extensions_local;
83206f
 
83206f
    psc = calloc(1, sizeof *psc);
83206f
    if (psc == NULL)
83206f
@@ -688,6 +845,11 @@ driswCreateScreen(int screen, struct glx_display *priv)
83206f
    if (extensions == NULL)
83206f
       goto handle_error;
83206f
 
83206f
+   if (!check_xshm(psc->base.dpy))
83206f
+      loader_extensions_local = loader_extensions_noshm;
83206f
+   else
83206f
+      loader_extensions_local = loader_extensions_shm;
83206f
+
83206f
    for (i = 0; extensions[i]; i++) {
83206f
       if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
83206f
 	 psc->core = (__DRIcoreExtension *) extensions[i];
83206f
@@ -704,12 +866,12 @@ driswCreateScreen(int screen, struct glx_display *priv)
83206f
 
83206f
    if (psc->swrast->base.version >= 4) {
83206f
       psc->driScreen =
83206f
-         psc->swrast->createNewScreen2(screen, loader_extensions,
83206f
+         psc->swrast->createNewScreen2(screen, loader_extensions_local,
83206f
                                        extensions,
83206f
                                        &driver_configs, psc);
83206f
    } else {
83206f
       psc->driScreen =
83206f
-         psc->swrast->createNewScreen(screen, loader_extensions,
83206f
+         psc->swrast->createNewScreen(screen, loader_extensions_local,
83206f
                                       &driver_configs, psc);
83206f
    }
83206f
    if (psc->driScreen == NULL) {
83206f
diff --git a/src/glx/drisw_priv.h b/src/glx/drisw_priv.h
83206f
index 5d479003114..a670da2d33b 100644
83206f
--- a/src/glx/drisw_priv.h
83206f
+++ b/src/glx/drisw_priv.h
83206f
@@ -23,6 +23,8 @@
83206f
  * SOFTWARE.
83206f
  */
83206f
 
83206f
+#include <X11/extensions/XShm.h>
83206f
+
83206f
 struct drisw_display
83206f
 {
83206f
    __GLXDRIdisplay base;
83206f
@@ -62,6 +64,7 @@ struct drisw_drawable
83206f
    __DRIdrawable *driDrawable;
83206f
    XVisualInfo *visinfo;
83206f
    XImage *ximage;
83206f
+   XShmSegmentInfo shminfo;
83206f
 };
83206f
 
83206f
 _X_HIDDEN int
83206f
diff --git a/src/mesa/state_tracker/st_cb_memoryobjects.c b/src/mesa/state_tracker/st_cb_memoryobjects.c
83206f
index 63a8c2a0e00..39174bc9f75 100644
83206f
--- a/src/mesa/state_tracker/st_cb_memoryobjects.c
83206f
+++ b/src/mesa/state_tracker/st_cb_memoryobjects.c
83206f
@@ -65,7 +65,7 @@ st_import_memoryobj_fd(struct gl_context *ctx,
83206f
    struct pipe_screen *screen = pipe->screen;
83206f
    struct winsys_handle whandle;
83206f
 
83206f
-   whandle.type = DRM_API_HANDLE_TYPE_FD;
83206f
+   whandle.type = WINSYS_HANDLE_TYPE_FD;
83206f
    whandle.handle = fd;
83206f
    whandle.offset = 0;
83206f
    whandle.layer = 0;
83206f
diff --git a/src/mesa/state_tracker/st_vdpau.c b/src/mesa/state_tracker/st_vdpau.c
83206f
index eb61aef1116..d0b9cfbf4f8 100644
83206f
--- a/src/mesa/state_tracker/st_vdpau.c
83206f
+++ b/src/mesa/state_tracker/st_vdpau.c
83206f
@@ -127,7 +127,7 @@ st_vdpau_resource_from_description(struct gl_context *ctx,
83206f
    templ.usage = PIPE_USAGE_DEFAULT;
83206f
 
83206f
    memset(&whandle, 0, sizeof(whandle));
83206f
-   whandle.type = DRM_API_HANDLE_TYPE_FD;
83206f
+   whandle.type = WINSYS_HANDLE_TYPE_FD;
83206f
    whandle.handle = desc->handle;
83206f
    whandle.offset = desc->offset;
83206f
    whandle.stride = desc->stride;