diff --git a/.gitignore b/.gitignore index ef2c689..1058255 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/mesa-18.0.5.tar.xz +SOURCES/mesa-18.3.4.tar.xz diff --git a/.mesa.metadata b/.mesa.metadata index a7a554b..d4b88d0 100644 --- a/.mesa.metadata +++ b/.mesa.metadata @@ -1 +1 @@ -116b35ae962e04326a4d61eab66b16108a7e33f0 SOURCES/mesa-18.0.5.tar.xz +0a3c4d1883aab3d6fa143d0699c7a81799d77fd6 SOURCES/mesa-18.3.4.tar.xz diff --git a/SOURCES/0001-glx-fix-shared-memory-leak-in-X11.patch b/SOURCES/0001-glx-fix-shared-memory-leak-in-X11.patch new file mode 100644 index 0000000..4cb6895 --- /dev/null +++ b/SOURCES/0001-glx-fix-shared-memory-leak-in-X11.patch @@ -0,0 +1,31 @@ +From b344e32cdf7064a1f2ff7ef37027edda6589404f Mon Sep 17 00:00:00 2001 +From: Ray Zhang +Date: Wed, 27 Feb 2019 06:54:05 +0000 +Subject: [PATCH] glx: fix shared memory leak in X11 + +call XShmDetach to allow X server to free shared memory + +Fixes: bcd80be49a8260c2233d "drisw/glx: use XShm if possible" +Signed-off-by: Ray Zhang +Reviewed-by: Dave Airlie +--- + src/glx/drisw_glx.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c +index 00c7fa100ab..48c03ca42e0 100644 +--- a/src/glx/drisw_glx.c ++++ b/src/glx/drisw_glx.c +@@ -147,6 +147,9 @@ XDestroyDrawable(struct drisw_drawable * pdp, Display * dpy, XID drawable) + if (pdp->ximage) + XDestroyImage(pdp->ximage); + ++ if (pdp->shminfo.shmid > 0) ++ XShmDetach(dpy, &pdp->shminfo); ++ + free(pdp->visinfo); + + XFreeGC(dpy, pdp->gc); +-- +2.20.1 + diff --git a/SOURCES/dri-sw-xshm-support.patch b/SOURCES/dri-sw-xshm-support.patch deleted file mode 100644 index 33700e8..0000000 --- a/SOURCES/dri-sw-xshm-support.patch +++ /dev/null @@ -1,1690 +0,0 @@ -diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h -index 34a5c9fb01a..6e6d62a5142 100644 ---- a/include/GL/internal/dri_interface.h -+++ b/include/GL/internal/dri_interface.h -@@ -565,7 +565,7 @@ struct __DRIdamageExtensionRec { - * SWRast Loader extension. - */ - #define __DRI_SWRAST_LOADER "DRI_SWRastLoader" --#define __DRI_SWRAST_LOADER_VERSION 3 -+#define __DRI_SWRAST_LOADER_VERSION 4 - struct __DRIswrastLoaderExtensionRec { - __DRIextension base; - -@@ -607,6 +607,24 @@ struct __DRIswrastLoaderExtensionRec { - void (*getImage2)(__DRIdrawable *readable, - int x, int y, int width, int height, int stride, - char *data, void *loaderPrivate); -+ -+ /** -+ * Put shm image to drawable -+ * -+ * \since 4 -+ */ -+ void (*putImageShm)(__DRIdrawable *drawable, int op, -+ int x, int y, int width, int height, int stride, -+ int shmid, char *shmaddr, unsigned offset, -+ void *loaderPrivate); -+ /** -+ * Get shm image from readable -+ * -+ * \since 4 -+ */ -+ void (*getImageShm)(__DRIdrawable *readable, -+ int x, int y, int width, int height, -+ int shmid, void *loaderPrivate); - }; - - /** -diff --git a/src/gallium/auxiliary/renderonly/renderonly.c b/src/gallium/auxiliary/renderonly/renderonly.c -index d31f458845c..f83910a9404 100644 ---- a/src/gallium/auxiliary/renderonly/renderonly.c -+++ b/src/gallium/auxiliary/renderonly/renderonly.c -@@ -98,7 +98,7 @@ renderonly_create_kms_dumb_buffer_for_resource(struct pipe_resource *rsc, - - /* fill in winsys handle */ - memset(out_handle, 0, sizeof(*out_handle)); -- out_handle->type = DRM_API_HANDLE_TYPE_FD; -+ out_handle->type = WINSYS_HANDLE_TYPE_FD; - out_handle->stride = create_dumb.pitch; - - err = drmPrimeHandleToFD(ro->kms_fd, create_dumb.handle, O_CLOEXEC, -@@ -130,7 +130,7 @@ renderonly_create_gpu_import_for_resource(struct pipe_resource *rsc, - boolean status; - int fd, err; - struct winsys_handle handle = { -- .type = DRM_API_HANDLE_TYPE_FD -+ .type = WINSYS_HANDLE_TYPE_FD - }; - - scanout = CALLOC_STRUCT(renderonly_scanout); -diff --git a/src/gallium/auxiliary/renderonly/renderonly.h b/src/gallium/auxiliary/renderonly/renderonly.h -index 6a89c29e2ef..a8d6a686ed4 100644 ---- a/src/gallium/auxiliary/renderonly/renderonly.h -+++ b/src/gallium/auxiliary/renderonly/renderonly.h -@@ -85,7 +85,7 @@ renderonly_get_handle(struct renderonly_scanout *scanout, - if (!scanout) - return FALSE; - -- assert(handle->type == DRM_API_HANDLE_TYPE_KMS); -+ assert(handle->type == WINSYS_HANDLE_TYPE_KMS); - handle->handle = scanout->handle; - handle->stride = scanout->stride; - -diff --git a/src/gallium/auxiliary/vl/vl_winsys_dri.c b/src/gallium/auxiliary/vl/vl_winsys_dri.c -index 79ebf750cdb..bb1ff504886 100644 ---- a/src/gallium/auxiliary/vl/vl_winsys_dri.c -+++ b/src/gallium/auxiliary/vl/vl_winsys_dri.c -@@ -231,7 +231,7 @@ vl_dri2_screen_texture_from_drawable(struct vl_screen *vscreen, void *drawable) - } - - memset(&dri2_handle, 0, sizeof(dri2_handle)); -- dri2_handle.type = DRM_API_HANDLE_TYPE_SHARED; -+ dri2_handle.type = WINSYS_HANDLE_TYPE_SHARED; - dri2_handle.handle = back_left->name; - dri2_handle.stride = back_left->pitch; - -diff --git a/src/gallium/auxiliary/vl/vl_winsys_dri3.c b/src/gallium/auxiliary/vl/vl_winsys_dri3.c -index 8251087f3f9..8e3c4a0e04d 100644 ---- a/src/gallium/auxiliary/vl/vl_winsys_dri3.c -+++ b/src/gallium/auxiliary/vl/vl_winsys_dri3.c -@@ -271,7 +271,7 @@ dri3_alloc_back_buffer(struct vl_dri3_screen *scrn) - pixmap_buffer_texture = buffer->texture; - } - memset(&whandle, 0, sizeof(whandle)); -- whandle.type= DRM_API_HANDLE_TYPE_FD; -+ whandle.type= WINSYS_HANDLE_TYPE_FD; - usage = PIPE_HANDLE_USAGE_EXPLICIT_FLUSH | PIPE_HANDLE_USAGE_READ; - scrn->base.pscreen->resource_get_handle(scrn->base.pscreen, NULL, - pixmap_buffer_texture, &whandle, -@@ -492,7 +492,7 @@ dri3_get_front_buffer(struct vl_dri3_screen *scrn) - goto free_reply; - - memset(&whandle, 0, sizeof(whandle)); -- whandle.type = DRM_API_HANDLE_TYPE_FD; -+ whandle.type = WINSYS_HANDLE_TYPE_FD; - whandle.handle = (unsigned)fds[0]; - whandle.stride = bp_reply->stride; - memset(&templ, 0, sizeof(templ)); -diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.c b/src/gallium/drivers/etnaviv/etnaviv_resource.c -index d70152e082d..cf870a3ed76 100644 ---- a/src/gallium/drivers/etnaviv/etnaviv_resource.c -+++ b/src/gallium/drivers/etnaviv/etnaviv_resource.c -@@ -250,7 +250,7 @@ etna_resource_alloc(struct pipe_screen *pscreen, unsigned layout, - if (!scanout) - return NULL; - -- assert(handle.type == DRM_API_HANDLE_TYPE_FD); -+ assert(handle.type == WINSYS_HANDLE_TYPE_FD); - handle.modifier = modifier; - rsc = etna_resource(pscreen->resource_from_handle(pscreen, templat, - &handle, -@@ -596,16 +596,16 @@ etna_resource_get_handle(struct pipe_screen *pscreen, - handle->stride = rsc->levels[0].stride; - handle->modifier = layout_to_modifier(rsc->layout); - -- if (handle->type == DRM_API_HANDLE_TYPE_SHARED) { -+ if (handle->type == WINSYS_HANDLE_TYPE_SHARED) { - return etna_bo_get_name(rsc->bo, &handle->handle) == 0; -- } else if (handle->type == DRM_API_HANDLE_TYPE_KMS) { -+ } else if (handle->type == WINSYS_HANDLE_TYPE_KMS) { - if (renderonly_get_handle(scanout, handle)) { - return TRUE; - } else { - handle->handle = etna_bo_handle(rsc->bo); - return TRUE; - } -- } else if (handle->type == DRM_API_HANDLE_TYPE_FD) { -+ } else if (handle->type == WINSYS_HANDLE_TYPE_FD) { - handle->handle = etna_bo_dmabuf(rsc->bo); - return TRUE; - } else { -diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.c b/src/gallium/drivers/etnaviv/etnaviv_screen.c -index c72793920ab..1997e9f85db 100644 ---- a/src/gallium/drivers/etnaviv/etnaviv_screen.c -+++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c -@@ -842,9 +842,9 @@ etna_screen_bo_from_handle(struct pipe_screen *pscreen, - struct etna_screen *screen = etna_screen(pscreen); - struct etna_bo *bo; - -- if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { -+ if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) { - bo = etna_bo_from_name(screen->dev, whandle->handle); -- } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) { -+ } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) { - bo = etna_bo_from_dmabuf(screen->dev, whandle->handle); - } else { - DBG("Attempt to import unsupported handle type %d", whandle->type); -diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c -index b68685989ca..e0f769a63cd 100644 ---- a/src/gallium/drivers/freedreno/freedreno_screen.c -+++ b/src/gallium/drivers/freedreno/freedreno_screen.c -@@ -731,12 +731,12 @@ fd_screen_bo_get_handle(struct pipe_screen *pscreen, - { - whandle->stride = stride; - -- if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { -+ if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) { - return fd_bo_get_name(bo, &whandle->handle) == 0; -- } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) { -+ } else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) { - whandle->handle = fd_bo_handle(bo); - return TRUE; -- } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) { -+ } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) { - whandle->handle = fd_bo_dmabuf(bo); - return TRUE; - } else { -@@ -751,11 +751,11 @@ fd_screen_bo_from_handle(struct pipe_screen *pscreen, - struct fd_screen *screen = fd_screen(pscreen); - struct fd_bo *bo; - -- if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { -+ if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) { - bo = fd_bo_from_name(screen->dev, whandle->handle); -- } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) { -+ } else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) { - bo = fd_bo_from_handle(screen->dev, whandle->handle, 0); -- } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) { -+ } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) { - bo = fd_bo_from_dmabuf(screen->dev, whandle->handle); - } else { - DBG("Attempt to import unsupported handle type %d", whandle->type); -diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c -index c144b39b2dd..c97b707955c 100644 ---- a/src/gallium/drivers/nouveau/nouveau_screen.c -+++ b/src/gallium/drivers/nouveau/nouveau_screen.c -@@ -102,14 +102,14 @@ nouveau_screen_bo_from_handle(struct pipe_screen *pscreen, - return NULL; - } - -- if (whandle->type != DRM_API_HANDLE_TYPE_SHARED && -- whandle->type != DRM_API_HANDLE_TYPE_FD) { -+ if (whandle->type != WINSYS_HANDLE_TYPE_SHARED && -+ whandle->type != WINSYS_HANDLE_TYPE_FD) { - debug_printf("%s: attempt to import unsupported handle type %d\n", - __FUNCTION__, whandle->type); - return NULL; - } - -- if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) -+ if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) - ret = nouveau_bo_name_ref(dev, whandle->handle, &bo); - else - ret = nouveau_bo_prime_handle_ref(dev, whandle->handle, &bo); -@@ -133,12 +133,12 @@ nouveau_screen_bo_get_handle(struct pipe_screen *pscreen, - { - whandle->stride = stride; - -- if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { -+ if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) { - return nouveau_bo_name_get(bo, &whandle->handle) == 0; -- } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) { -+ } else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) { - whandle->handle = bo->handle; - return true; -- } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) { -+ } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) { - return nouveau_bo_set_prime(bo, (int *)&whandle->handle) == 0; - } else { - return false; -diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c -index 36eff40949f..a9c7b46b7b3 100644 ---- a/src/gallium/drivers/radeon/r600_texture.c -+++ b/src/gallium/drivers/radeon/r600_texture.c -@@ -699,7 +699,7 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen, - if (sscreen->ws->buffer_is_suballocated(res->buf) || - rtex->surface.tile_swizzle || - (rtex->resource.flags & RADEON_FLAG_NO_INTERPROCESS_SHARING && -- whandle->type != DRM_API_HANDLE_TYPE_KMS)) { -+ whandle->type != WINSYS_HANDLE_TYPE_KMS)) { - assert(!res->b.is_shared); - r600_reallocate_texture_inplace(rctx, rtex, - PIPE_BIND_SHARED, false); -diff --git a/src/gallium/drivers/vc4/vc4_resource.c b/src/gallium/drivers/vc4/vc4_resource.c -index cdcbcc917e0..58b6a42d4fd 100644 ---- a/src/gallium/drivers/vc4/vc4_resource.c -+++ b/src/gallium/drivers/vc4/vc4_resource.c -@@ -406,7 +406,7 @@ vc4_resource_get_handle(struct pipe_screen *pscreen, - whandle->modifier = DRM_FORMAT_MOD_LINEAR; - - switch (whandle->type) { -- case DRM_API_HANDLE_TYPE_SHARED: -+ case WINSYS_HANDLE_TYPE_SHARED: - if (screen->ro) { - /* This could probably be supported, assuming that a - * control node was used for pl111. -@@ -416,12 +416,12 @@ vc4_resource_get_handle(struct pipe_screen *pscreen, - } - - return vc4_bo_flink(rsc->bo, &whandle->handle); -- case DRM_API_HANDLE_TYPE_KMS: -+ case WINSYS_HANDLE_TYPE_KMS: - if (screen->ro && renderonly_get_handle(rsc->scanout, whandle)) - return TRUE; - whandle->handle = rsc->bo->handle; - return TRUE; -- case DRM_API_HANDLE_TYPE_FD: -+ case WINSYS_HANDLE_TYPE_FD: - /* FDs are cross-device, so we can export directly from vc4. - */ - whandle->handle = vc4_bo_get_dmabuf(rsc->bo); -@@ -716,11 +716,11 @@ vc4_resource_from_handle(struct pipe_screen *pscreen, - } - - switch (whandle->type) { -- case DRM_API_HANDLE_TYPE_SHARED: -+ case WINSYS_HANDLE_TYPE_SHARED: - rsc->bo = vc4_bo_open_name(screen, - whandle->handle, whandle->stride); - break; -- case DRM_API_HANDLE_TYPE_FD: -+ case WINSYS_HANDLE_TYPE_FD: - rsc->bo = vc4_bo_open_dmabuf(screen, - whandle->handle, whandle->stride); - break; -diff --git a/src/gallium/drivers/vc5/vc5_resource.c b/src/gallium/drivers/vc5/vc5_resource.c -index a9cc27127f0..9754d3d6024 100644 ---- a/src/gallium/drivers/vc5/vc5_resource.c -+++ b/src/gallium/drivers/vc5/vc5_resource.c -@@ -314,12 +314,12 @@ vc5_resource_get_handle(struct pipe_screen *pscreen, - bo->private = false; - - switch (whandle->type) { -- case DRM_API_HANDLE_TYPE_SHARED: -+ case WINSYS_HANDLE_TYPE_SHARED: - return vc5_bo_flink(bo, &whandle->handle); -- case DRM_API_HANDLE_TYPE_KMS: -+ case WINSYS_HANDLE_TYPE_KMS: - whandle->handle = bo->handle; - return TRUE; -- case DRM_API_HANDLE_TYPE_FD: -+ case WINSYS_HANDLE_TYPE_FD: - whandle->handle = vc5_bo_get_dmabuf(bo); - return whandle->handle != -1; - } -@@ -592,11 +592,11 @@ vc5_resource_from_handle(struct pipe_screen *pscreen, - } - - switch (whandle->type) { -- case DRM_API_HANDLE_TYPE_SHARED: -+ case WINSYS_HANDLE_TYPE_SHARED: - rsc->bo = vc5_bo_open_name(screen, - whandle->handle, whandle->stride); - break; -- case DRM_API_HANDLE_TYPE_FD: -+ case WINSYS_HANDLE_TYPE_FD: - rsc->bo = vc5_bo_open_dmabuf(screen, - whandle->handle, whandle->stride); - break; -diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h -index 101e229088b..8fd81a4e9a9 100644 ---- a/src/gallium/include/pipe/p_screen.h -+++ b/src/gallium/include/pipe/p_screen.h -@@ -191,7 +191,7 @@ struct pipe_screen { - * another process by first creating a pipe texture and then calling - * resource_get_handle. - * -- * NOTE: in the case of DRM_API_HANDLE_TYPE_FD handles, the caller -+ * NOTE: in the case of WINSYS_HANDLE_TYPE_FD handles, the caller - * retains ownership of the FD. (This is consistent with - * EGL_EXT_image_dma_buf_import) - * -@@ -238,7 +238,7 @@ struct pipe_screen { - * the resource into a format compatible for sharing. The use case is - * OpenGL-OpenCL interop. The context parameter is allowed to be NULL. - * -- * NOTE: in the case of DRM_API_HANDLE_TYPE_FD handles, the caller -+ * NOTE: in the case of WINSYS_HANDLE_TYPE_FD handles, the caller - * takes ownership of the FD. (This is consistent with - * EGL_MESA_image_dma_buf_export) - * -@@ -389,7 +389,7 @@ struct pipe_screen { - * Then the underlying memory object is then exported through interfaces - * compatible with EXT_external_resources. - * -- * Note: For DRM_API_HANDLE_TYPE_FD handles, the caller retains ownership -+ * Note: For WINSYS_HANDLE_TYPE_FD handles, the caller retains ownership - * of the fd. - * - * \param handle A handle representing the memory object to import -diff --git a/src/gallium/include/state_tracker/drisw_api.h b/src/gallium/include/state_tracker/drisw_api.h -index 03d5ee405a4..e365ab81f18 100644 ---- a/src/gallium/include/state_tracker/drisw_api.h -+++ b/src/gallium/include/state_tracker/drisw_api.h -@@ -2,6 +2,7 @@ - #define _DRISW_API_H_ - - #include "pipe/p_compiler.h" -+#include "sw_winsys.h" - - struct pipe_screen; - struct dri_drawable; -@@ -18,6 +19,9 @@ struct drisw_loader_funcs - void *data, unsigned width, unsigned height); - void (*put_image2) (struct dri_drawable *dri_drawable, - void *data, int x, int y, unsigned width, unsigned height, unsigned stride); -+ void (*put_image_shm) (struct dri_drawable *dri_drawable, -+ int shmid, char *shmaddr, unsigned offset, -+ int x, int y, unsigned width, unsigned height, unsigned stride); - }; - - #endif -diff --git a/src/gallium/include/state_tracker/drm_driver.h b/src/gallium/include/state_tracker/drm_driver.h -index f188b5a7d4c..19cd19f26e1 100644 ---- a/src/gallium/include/state_tracker/drm_driver.h -+++ b/src/gallium/include/state_tracker/drm_driver.h -@@ -4,58 +4,13 @@ - - #include "pipe/p_compiler.h" - -+#include "winsys_handle.h" -+ - struct pipe_screen; - struct pipe_screen_config; - struct pipe_context; - struct pipe_resource; - --#define DRM_API_HANDLE_TYPE_SHARED 0 --#define DRM_API_HANDLE_TYPE_KMS 1 --#define DRM_API_HANDLE_TYPE_FD 2 -- -- --/** -- * For use with pipe_screen::{texture_from_handle|texture_get_handle}. -- */ --struct winsys_handle --{ -- /** -- * Input for texture_from_handle, valid values are -- * DRM_API_HANDLE_TYPE_SHARED or DRM_API_HANDLE_TYPE_FD. -- * Input to texture_get_handle, -- * to select handle for kms, flink, or prime. -- */ -- unsigned type; -- /** -- * Input for texture_get_handle, allows to export the offset -- * of a specific layer of an array texture. -- */ -- unsigned layer; -- /** -- * Input to texture_from_handle. -- * Output for texture_get_handle. -- */ -- unsigned handle; -- /** -- * Input to texture_from_handle. -- * Output for texture_get_handle. -- */ -- unsigned stride; -- /** -- * Input to texture_from_handle. -- * Output for texture_get_handle. -- */ -- unsigned offset; -- -- /** -- * Input to resource_from_handle. -- * Output from resource_get_handle. -- */ -- uint64_t modifier; --}; -- -- -- - /** - * Configuration queries. - */ -diff --git a/src/gallium/include/state_tracker/sw_winsys.h b/src/gallium/include/state_tracker/sw_winsys.h -index 0b792cd0ce4..cd5838ad1d8 100644 ---- a/src/gallium/include/state_tracker/sw_winsys.h -+++ b/src/gallium/include/state_tracker/sw_winsys.h -@@ -37,14 +37,13 @@ - - #include "pipe/p_compiler.h" /* for boolean */ - #include "pipe/p_format.h" -- -+#include "state_tracker/winsys_handle.h" - - #ifdef __cplusplus - extern "C" { - #endif - - --struct winsys_handle; - struct pipe_screen; - struct pipe_context; - struct pipe_resource; -diff --git a/src/gallium/include/state_tracker/winsys_handle.h b/src/gallium/include/state_tracker/winsys_handle.h -new file mode 100644 -index 00000000000..167c1a937fd ---- /dev/null -+++ b/src/gallium/include/state_tracker/winsys_handle.h -@@ -0,0 +1,58 @@ -+ -+#ifndef _WINSYS_HANDLE_H_ -+#define _WINSYS_HANDLE_H_ -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#define WINSYS_HANDLE_TYPE_SHARED 0 -+#define WINSYS_HANDLE_TYPE_KMS 1 -+#define WINSYS_HANDLE_TYPE_FD 2 -+#define WINSYS_HANDLE_TYPE_SHMID 3 -+ -+/** -+ * For use with pipe_screen::{texture_from_handle|texture_get_handle}. -+ */ -+struct winsys_handle -+{ -+ /** -+ * Input for texture_from_handle, valid values are -+ * WINSYS_HANDLE_TYPE_SHARED or WINSYS_HANDLE_TYPE_FD. -+ * Input to texture_get_handle, -+ * to select handle for kms, flink, or prime. -+ */ -+ unsigned type; -+ /** -+ * Input for texture_get_handle, allows to export the offset -+ * of a specific layer of an array texture. -+ */ -+ unsigned layer; -+ /** -+ * Input to texture_from_handle. -+ * Output for texture_get_handle. -+ */ -+ unsigned handle; -+ /** -+ * Input to texture_from_handle. -+ * Output for texture_get_handle. -+ */ -+ unsigned stride; -+ /** -+ * Input to texture_from_handle. -+ * Output for texture_get_handle. -+ */ -+ unsigned offset; -+ -+ /** -+ * Input to resource_from_handle. -+ * Output from resource_get_handle. -+ */ -+ uint64_t modifier; -+}; -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* _WINSYS_HANDLE_H_ */ -diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c -index 2c3a6e0d194..aa219377069 100644 ---- a/src/gallium/state_trackers/dri/dri2.c -+++ b/src/gallium/state_trackers/dri/dri2.c -@@ -584,9 +584,9 @@ dri2_allocate_buffer(__DRIscreen *sPriv, - - memset(&whandle, 0, sizeof(whandle)); - if (screen->can_share_buffer) -- whandle.type = DRM_API_HANDLE_TYPE_SHARED; -+ whandle.type = WINSYS_HANDLE_TYPE_SHARED; - else -- whandle.type = DRM_API_HANDLE_TYPE_KMS; -+ whandle.type = WINSYS_HANDLE_TYPE_KMS; - - screen->base.screen->resource_get_handle(screen->base.screen, NULL, - buffer->resource, &whandle, -@@ -772,9 +772,9 @@ dri2_allocate_textures(struct dri_context *ctx, - whandle.offset = 0; - whandle.modifier = DRM_FORMAT_MOD_INVALID; - if (screen->can_share_buffer) -- whandle.type = DRM_API_HANDLE_TYPE_SHARED; -+ whandle.type = WINSYS_HANDLE_TYPE_SHARED; - else -- whandle.type = DRM_API_HANDLE_TYPE_KMS; -+ whandle.type = WINSYS_HANDLE_TYPE_KMS; - drawable->textures[statt] = - screen->base.screen->resource_from_handle(screen->base.screen, - &templ, &whandle, -@@ -1032,7 +1032,7 @@ dri2_create_image_from_name(__DRIscreen *_screen, - enum pipe_format pf; - - memset(&whandle, 0, sizeof(whandle)); -- whandle.type = DRM_API_HANDLE_TYPE_SHARED; -+ whandle.type = WINSYS_HANDLE_TYPE_SHARED; - whandle.handle = name; - whandle.modifier = DRM_FORMAT_MOD_INVALID; - -@@ -1091,7 +1091,7 @@ dri2_create_image_from_fd(__DRIscreen *_screen, - goto exit; - } - -- whandles[i].type = DRM_API_HANDLE_TYPE_FD; -+ whandles[i].type = WINSYS_HANDLE_TYPE_FD; - whandles[i].handle = (unsigned)fds[i]; - whandles[i].stride = (unsigned)strides[i]; - whandles[i].offset = (unsigned)offsets[i]; -@@ -1231,35 +1231,35 @@ dri2_query_image(__DRIimage *image, int attrib, int *value) - - switch (attrib) { - case __DRI_IMAGE_ATTRIB_STRIDE: -- whandle.type = DRM_API_HANDLE_TYPE_KMS; -+ whandle.type = WINSYS_HANDLE_TYPE_KMS; - if (!image->texture->screen->resource_get_handle(image->texture->screen, - NULL, image->texture, &whandle, usage)) - return GL_FALSE; - *value = whandle.stride; - return GL_TRUE; - case __DRI_IMAGE_ATTRIB_OFFSET: -- whandle.type = DRM_API_HANDLE_TYPE_KMS; -+ whandle.type = WINSYS_HANDLE_TYPE_KMS; - if (!image->texture->screen->resource_get_handle(image->texture->screen, - NULL, image->texture, &whandle, usage)) - return GL_FALSE; - *value = whandle.offset; - return GL_TRUE; - case __DRI_IMAGE_ATTRIB_HANDLE: -- whandle.type = DRM_API_HANDLE_TYPE_KMS; -+ whandle.type = WINSYS_HANDLE_TYPE_KMS; - if (!image->texture->screen->resource_get_handle(image->texture->screen, - NULL, image->texture, &whandle, usage)) - return GL_FALSE; - *value = whandle.handle; - return GL_TRUE; - case __DRI_IMAGE_ATTRIB_NAME: -- whandle.type = DRM_API_HANDLE_TYPE_SHARED; -+ whandle.type = WINSYS_HANDLE_TYPE_SHARED; - if (!image->texture->screen->resource_get_handle(image->texture->screen, - NULL, image->texture, &whandle, usage)) - return GL_FALSE; - *value = whandle.handle; - return GL_TRUE; - case __DRI_IMAGE_ATTRIB_FD: -- whandle.type= DRM_API_HANDLE_TYPE_FD; -+ whandle.type= WINSYS_HANDLE_TYPE_FD; - if (!image->texture->screen->resource_get_handle(image->texture->screen, - NULL, image->texture, &whandle, usage)) - return GL_FALSE; -@@ -1287,7 +1287,7 @@ dri2_query_image(__DRIimage *image, int attrib, int *value) - *value = 1; - return GL_TRUE; - case __DRI_IMAGE_ATTRIB_MODIFIER_UPPER: -- whandle.type = DRM_API_HANDLE_TYPE_KMS; -+ whandle.type = WINSYS_HANDLE_TYPE_KMS; - whandle.modifier = DRM_FORMAT_MOD_INVALID; - if (!image->texture->screen->resource_get_handle(image->texture->screen, - NULL, image->texture, &whandle, usage)) -@@ -1297,7 +1297,7 @@ dri2_query_image(__DRIimage *image, int attrib, int *value) - *value = (whandle.modifier >> 32) & 0xffffffff; - return GL_TRUE; - case __DRI_IMAGE_ATTRIB_MODIFIER_LOWER: -- whandle.type = DRM_API_HANDLE_TYPE_KMS; -+ whandle.type = WINSYS_HANDLE_TYPE_KMS; - whandle.modifier = DRM_FORMAT_MOD_INVALID; - if (!image->texture->screen->resource_get_handle(image->texture->screen, - NULL, image->texture, &whandle, usage)) -@@ -1377,7 +1377,7 @@ dri2_from_names(__DRIscreen *screen, int width, int height, int format, - return NULL; - - memset(&whandle, 0, sizeof(whandle)); -- whandle.type = DRM_API_HANDLE_TYPE_SHARED; -+ whandle.type = WINSYS_HANDLE_TYPE_SHARED; - whandle.handle = names[0]; - whandle.stride = strides[0]; - whandle.offset = offsets[0]; -@@ -1909,7 +1909,7 @@ dri2_interop_export_object(__DRIcontext *_ctx, - } - - memset(&whandle, 0, sizeof(whandle)); -- whandle.type = DRM_API_HANDLE_TYPE_FD; -+ whandle.type = WINSYS_HANDLE_TYPE_FD; - - success = screen->resource_get_handle(screen, st->pipe, res, &whandle, - usage); -diff --git a/src/gallium/state_trackers/dri/drisw.c b/src/gallium/state_trackers/dri/drisw.c -index eb5752386dc..e24fcba3869 100644 ---- a/src/gallium/state_trackers/dri/drisw.c -+++ b/src/gallium/state_trackers/dri/drisw.c -@@ -26,14 +26,6 @@ - * - **************************************************************************/ - --/* TODO: -- * -- * xshm / EGLImage: -- * -- * Allow the loaders to use the XSHM extension. It probably requires callbacks -- * for createImage/destroyImage similar to DRI2 getBuffers. -- */ -- - #include "util/u_format.h" - #include "util/u_memory.h" - #include "util/u_inlines.h" -@@ -86,6 +78,19 @@ put_image2(__DRIdrawable *dPriv, void *data, int x, int y, - data, dPriv->loaderPrivate); - } - -+static inline void -+put_image_shm(__DRIdrawable *dPriv, int shmid, char *shmaddr, -+ unsigned offset, int x, int y, -+ unsigned width, unsigned height, unsigned stride) -+{ -+ __DRIscreen *sPriv = dPriv->driScreenPriv; -+ const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader; -+ -+ loader->putImageShm(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP, -+ x, y, width, height, stride, -+ shmid, shmaddr, offset, dPriv->loaderPrivate); -+} -+ - static inline void - get_image(__DRIdrawable *dPriv, int x, int y, int width, int height, void *data) - { -@@ -112,6 +117,26 @@ get_image2(__DRIdrawable *dPriv, int x, int y, int width, int height, int stride - data, dPriv->loaderPrivate); - } - -+static inline bool -+get_image_shm(__DRIdrawable *dPriv, int x, int y, int width, int height, -+ struct pipe_resource *res) -+{ -+ __DRIscreen *sPriv = dPriv->driScreenPriv; -+ const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader; -+ struct winsys_handle whandle; -+ -+ whandle.type = WINSYS_HANDLE_TYPE_SHMID; -+ -+ if (loader->base.version < 4 || !loader->getImageShm) -+ return FALSE; -+ -+ if (!res->screen->resource_get_handle(res->screen, NULL, res, &whandle, PIPE_HANDLE_USAGE_WRITE)) -+ return FALSE; -+ -+ loader->getImageShm(dPriv, x, y, width, height, whandle.handle, dPriv->loaderPrivate); -+ return TRUE; -+} -+ - static void - drisw_update_drawable_info(struct dri_drawable *drawable) - { -@@ -152,6 +177,17 @@ drisw_put_image2(struct dri_drawable *drawable, - put_image2(dPriv, data, x, y, width, height, stride); - } - -+static inline void -+drisw_put_image_shm(struct dri_drawable *drawable, -+ int shmid, char *shmaddr, unsigned offset, -+ int x, int y, unsigned width, unsigned height, -+ unsigned stride) -+{ -+ __DRIdrawable *dPriv = drawable->dPriv; -+ -+ put_image_shm(dPriv, shmid, shmaddr, offset, x, y, width, height, stride); -+} -+ - static inline void - drisw_present_texture(__DRIdrawable *dPriv, - struct pipe_resource *ptex, struct pipe_box *sub_box) -@@ -348,7 +384,8 @@ drisw_update_tex_buffer(struct dri_drawable *drawable, - x, y, w, h, &transfer); - - /* Copy the Drawable content to the mapped texture buffer */ -- get_image(dPriv, x, y, w, h, map); -+ if (!get_image_shm(dPriv, x, y, w, h, res)) -+ get_image(dPriv, x, y, w, h, map); - - /* The pipe transfer has a pitch rounded up to the nearest 64 pixels. - get_image() has a pitch rounded up to 4 bytes. */ -@@ -394,6 +431,7 @@ static struct drisw_loader_funcs drisw_lf = { - static const __DRIconfig ** - drisw_init_screen(__DRIscreen * sPriv) - { -+ const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader; - const __DRIconfig **configs; - struct dri_screen *screen; - struct pipe_screen *pscreen = NULL; -@@ -409,6 +447,10 @@ drisw_init_screen(__DRIscreen * sPriv) - - sPriv->driverPrivate = (void *)screen; - sPriv->extensions = drisw_screen_extensions; -+ if (loader->base.version >= 4) { -+ if (loader->putImageShm) -+ drisw_lf.put_image_shm = drisw_put_image_shm; -+ } - - if (pipe_loader_sw_probe_dri(&screen->dev, &drisw_lf)) { - dri_init_options(screen); -diff --git a/src/gallium/state_trackers/nine/swapchain9.c b/src/gallium/state_trackers/nine/swapchain9.c -index f24a7d05437..7cf5c54bfa8 100644 ---- a/src/gallium/state_trackers/nine/swapchain9.c -+++ b/src/gallium/state_trackers/nine/swapchain9.c -@@ -96,7 +96,7 @@ D3DWindowBuffer_create(struct NineSwapChain9 *This, - HRESULT hr; - - memset(&whandle, 0, sizeof(whandle)); -- whandle.type = DRM_API_HANDLE_TYPE_FD; -+ whandle.type = WINSYS_HANDLE_TYPE_FD; - This->screen->resource_get_handle(This->screen, pipe, resource, - &whandle, - for_frontbuffer_reading ? -diff --git a/src/gallium/state_trackers/va/buffer.c b/src/gallium/state_trackers/va/buffer.c -index deaeb1939fe..42ec9730fc1 100644 ---- a/src/gallium/state_trackers/va/buffer.c -+++ b/src/gallium/state_trackers/va/buffer.c -@@ -305,7 +305,7 @@ vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id, - drv->pipe->flush(drv->pipe, NULL, 0); - - memset(&whandle, 0, sizeof(whandle)); -- whandle.type = DRM_API_HANDLE_TYPE_FD; -+ whandle.type = WINSYS_HANDLE_TYPE_FD; - - if (!screen->resource_get_handle(screen, drv->pipe, - buf->derived_surface.resource, -diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c -index f9412ce52e6..432480c458a 100644 ---- a/src/gallium/state_trackers/va/surface.c -+++ b/src/gallium/state_trackers/va/surface.c -@@ -569,7 +569,7 @@ suface_from_external_memory(VADriverContextP ctx, vlVaSurface *surface, - res_templ.usage = PIPE_USAGE_DEFAULT; - - memset(&whandle, 0, sizeof(struct winsys_handle)); -- whandle.type = DRM_API_HANDLE_TYPE_FD; -+ whandle.type = WINSYS_HANDLE_TYPE_FD; - whandle.handle = memory_attibute->buffers[index]; - whandle.stride = memory_attibute->pitches[index]; - -@@ -1034,7 +1034,7 @@ vlVaExportSurfaceHandle(VADriverContextP ctx, - } - - memset(&whandle, 0, sizeof(whandle)); -- whandle.type = DRM_API_HANDLE_TYPE_FD; -+ whandle.type = WINSYS_HANDLE_TYPE_FD; - - if (!screen->resource_get_handle(screen, drv->pipe, resource, - &whandle, usage)) { -diff --git a/src/gallium/state_trackers/vdpau/output.c b/src/gallium/state_trackers/vdpau/output.c -index 8ef826836c1..6ef7a404474 100644 ---- a/src/gallium/state_trackers/vdpau/output.c -+++ b/src/gallium/state_trackers/vdpau/output.c -@@ -805,7 +805,7 @@ VdpStatus vlVdpOutputSurfaceDMABuf(VdpOutputSurface surface, - vlsurface->device->context->flush(vlsurface->device->context, NULL, 0); - - memset(&whandle, 0, sizeof(struct winsys_handle)); -- whandle.type = DRM_API_HANDLE_TYPE_FD; -+ whandle.type = WINSYS_HANDLE_TYPE_FD; - - pscreen = vlsurface->surface->texture->screen; - if (!pscreen->resource_get_handle(pscreen, vlsurface->device->context, -diff --git a/src/gallium/state_trackers/vdpau/surface.c b/src/gallium/state_trackers/vdpau/surface.c -index 012d3036411..95bab8790db 100644 ---- a/src/gallium/state_trackers/vdpau/surface.c -+++ b/src/gallium/state_trackers/vdpau/surface.c -@@ -526,7 +526,7 @@ VdpStatus vlVdpVideoSurfaceDMABuf(VdpVideoSurface surface, - } - - memset(&whandle, 0, sizeof(struct winsys_handle)); -- whandle.type = DRM_API_HANDLE_TYPE_FD; -+ whandle.type = WINSYS_HANDLE_TYPE_FD; - whandle.layer = surf->u.tex.first_layer; - - pscreen = surf->texture->screen; -diff --git a/src/gallium/state_trackers/xa/xa_tracker.c b/src/gallium/state_trackers/xa/xa_tracker.c -index 03a3abf6835..3d268a17750 100644 ---- a/src/gallium/state_trackers/xa/xa_tracker.c -+++ b/src/gallium/state_trackers/xa/xa_tracker.c -@@ -311,12 +311,12 @@ handle_type(enum xa_handle_type type) - { - switch (type) { - case xa_handle_type_kms: -- return DRM_API_HANDLE_TYPE_KMS; -+ return WINSYS_HANDLE_TYPE_KMS; - case xa_handle_type_fd: -- return DRM_API_HANDLE_TYPE_FD; -+ return WINSYS_HANDLE_TYPE_FD; - case xa_handle_type_shared: - default: -- return DRM_API_HANDLE_TYPE_SHARED; -+ return WINSYS_HANDLE_TYPE_SHARED; - } - } - -@@ -404,7 +404,7 @@ xa_surface_from_handle(struct xa_tracker *xa, - uint32_t handle, uint32_t stride) - { - return xa_surface_from_handle2(xa, width, height, depth, stype, xa_format, -- DRM_API_HANDLE_TYPE_SHARED, flags, handle, -+ WINSYS_HANDLE_TYPE_SHARED, flags, handle, - stride); - } - -diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c -index 544403ac84f..b680be7c6ff 100644 ---- a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c -+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c -@@ -1275,10 +1275,10 @@ static struct pb_buffer *amdgpu_bo_from_handle(struct radeon_winsys *rws, - } - - switch (whandle->type) { -- case DRM_API_HANDLE_TYPE_SHARED: -+ case WINSYS_HANDLE_TYPE_SHARED: - type = amdgpu_bo_handle_type_gem_flink_name; - break; -- case DRM_API_HANDLE_TYPE_FD: -+ case WINSYS_HANDLE_TYPE_FD: - type = amdgpu_bo_handle_type_dma_buf_fd; - break; - default: -@@ -1362,13 +1362,13 @@ static bool amdgpu_bo_get_handle(struct pb_buffer *buffer, - bo->u.real.use_reusable_pool = false; - - switch (whandle->type) { -- case DRM_API_HANDLE_TYPE_SHARED: -+ case WINSYS_HANDLE_TYPE_SHARED: - type = amdgpu_bo_handle_type_gem_flink_name; - break; -- case DRM_API_HANDLE_TYPE_FD: -+ case WINSYS_HANDLE_TYPE_FD: - type = amdgpu_bo_handle_type_dma_buf_fd; - break; -- case DRM_API_HANDLE_TYPE_KMS: -+ case WINSYS_HANDLE_TYPE_KMS: - type = amdgpu_bo_handle_type_kms; - break; - default: -diff --git a/src/gallium/winsys/i915/drm/i915_drm_buffer.c b/src/gallium/winsys/i915/drm/i915_drm_buffer.c -index 890f7dc2833..509984ac6ac 100644 ---- a/src/gallium/winsys/i915/drm/i915_drm_buffer.c -+++ b/src/gallium/winsys/i915/drm/i915_drm_buffer.c -@@ -98,7 +98,7 @@ i915_drm_buffer_from_handle(struct i915_winsys *iws, - struct i915_drm_buffer *buf; - uint32_t tile = 0, swizzle = 0; - -- if ((whandle->type != DRM_API_HANDLE_TYPE_SHARED) && (whandle->type != DRM_API_HANDLE_TYPE_FD)) -+ if ((whandle->type != WINSYS_HANDLE_TYPE_SHARED) && (whandle->type != WINSYS_HANDLE_TYPE_FD)) - return NULL; - - if (whandle->offset != 0) -@@ -110,9 +110,9 @@ i915_drm_buffer_from_handle(struct i915_winsys *iws, - - buf->magic = 0xDEAD1337; - -- if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) -+ if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) - buf->bo = drm_intel_bo_gem_create_from_name(idws->gem_manager, "gallium3d_from_handle", whandle->handle); -- else if (whandle->type == DRM_API_HANDLE_TYPE_FD) { -+ else if (whandle->type == WINSYS_HANDLE_TYPE_FD) { - int fd = (int) whandle->handle; - buf->bo = drm_intel_bo_gem_create_from_prime(idws->gem_manager, fd, height * whandle->stride); - } -@@ -143,7 +143,7 @@ i915_drm_buffer_get_handle(struct i915_winsys *iws, - { - struct i915_drm_buffer *buf = i915_drm_buffer(buffer); - -- if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { -+ if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) { - if (!buf->flinked) { - if (drm_intel_bo_flink(buf->bo, &buf->flink)) - return FALSE; -@@ -151,9 +151,9 @@ i915_drm_buffer_get_handle(struct i915_winsys *iws, - } - - whandle->handle = buf->flink; -- } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) { -+ } else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) { - whandle->handle = buf->bo->handle; -- } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) { -+ } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) { - int fd; - - if (drm_intel_bo_gem_export_to_prime(buf->bo, &fd)) -diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c -index fc95a98620b..6ed23530ab0 100644 ---- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c -+++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c -@@ -1124,10 +1124,10 @@ static struct pb_buffer *radeon_winsys_bo_from_handle(struct radeon_winsys *rws, - * The list of pairs is guarded by a mutex, of course. */ - mtx_lock(&ws->bo_handles_mutex); - -- if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { -+ if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) { - /* First check if there already is an existing bo for the handle. */ - bo = util_hash_table_get(ws->bo_names, (void*)(uintptr_t)whandle->handle); -- } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) { -+ } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) { - /* We must first get the GEM handle, as fds are unreliable keys */ - r = drmPrimeFDToHandle(ws->fd, whandle->handle, &handle); - if (r) -@@ -1151,7 +1151,7 @@ static struct pb_buffer *radeon_winsys_bo_from_handle(struct radeon_winsys *rws, - goto fail; - } - -- if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { -+ if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) { - struct drm_gem_open open_arg = {}; - memset(&open_arg, 0, sizeof(open_arg)); - /* Open the BO. */ -@@ -1163,7 +1163,7 @@ static struct pb_buffer *radeon_winsys_bo_from_handle(struct radeon_winsys *rws, - handle = open_arg.handle; - size = open_arg.size; - bo->flink_name = whandle->handle; -- } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) { -+ } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) { - size = lseek(whandle->handle, 0, SEEK_END); - /* - * Could check errno to determine whether the kernel is new enough, but -@@ -1268,7 +1268,7 @@ static bool radeon_winsys_bo_get_handle(struct pb_buffer *buffer, - - bo->u.real.use_reusable_pool = false; - -- if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { -+ if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) { - if (!bo->flink_name) { - flink.handle = bo->handle; - -@@ -1283,9 +1283,9 @@ static bool radeon_winsys_bo_get_handle(struct pb_buffer *buffer, - mtx_unlock(&ws->bo_handles_mutex); - } - whandle->handle = bo->flink_name; -- } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) { -+ } else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) { - whandle->handle = bo->handle; -- } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) { -+ } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) { - if (drmPrimeHandleToFD(ws->fd, bo->handle, DRM_CLOEXEC, (int*)&whandle->handle)) - return false; - } -diff --git a/src/gallium/winsys/svga/drm/vmw_screen_dri.c b/src/gallium/winsys/svga/drm/vmw_screen_dri.c -index 2a0ac7b3337..76f29e2aced 100644 ---- a/src/gallium/winsys/svga/drm/vmw_screen_dri.c -+++ b/src/gallium/winsys/svga/drm/vmw_screen_dri.c -@@ -234,11 +234,11 @@ vmw_drm_surface_from_handle(struct svga_winsys_screen *sws, - } - - switch (whandle->type) { -- case DRM_API_HANDLE_TYPE_SHARED: -- case DRM_API_HANDLE_TYPE_KMS: -+ case WINSYS_HANDLE_TYPE_SHARED: -+ case WINSYS_HANDLE_TYPE_KMS: - handle = whandle->handle; - break; -- case DRM_API_HANDLE_TYPE_FD: -+ case WINSYS_HANDLE_TYPE_FD: - ret = drmPrimeFDToHandle(vws->ioctl.drm_fd, whandle->handle, - &handle); - if (ret) { -@@ -263,7 +263,7 @@ vmw_drm_surface_from_handle(struct svga_winsys_screen *sws, - /* - * Need to close the handle we got from prime. - */ -- if (whandle->type == DRM_API_HANDLE_TYPE_FD) -+ if (whandle->type == WINSYS_HANDLE_TYPE_FD) - vmw_ioctl_surface_destroy(vws, handle); - - if (ret) { -@@ -340,11 +340,11 @@ vmw_drm_surface_get_handle(struct svga_winsys_screen *sws, - whandle->offset = 0; - - switch (whandle->type) { -- case DRM_API_HANDLE_TYPE_SHARED: -- case DRM_API_HANDLE_TYPE_KMS: -+ case WINSYS_HANDLE_TYPE_SHARED: -+ case WINSYS_HANDLE_TYPE_KMS: - whandle->handle = vsrf->sid; - break; -- case DRM_API_HANDLE_TYPE_FD: -+ case WINSYS_HANDLE_TYPE_FD: - ret = drmPrimeHandleToFD(vws->ioctl.drm_fd, vsrf->sid, DRM_CLOEXEC, - (int *)&whandle->handle); - if (ret) { -diff --git a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c -index 62a2af6d650..16dd5c8593a 100644 ---- a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c -+++ b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c -@@ -290,13 +290,13 @@ vmw_ioctl_surface_req(const struct vmw_winsys_screen *vws, - int ret; - - switch(whandle->type) { -- case DRM_API_HANDLE_TYPE_SHARED: -- case DRM_API_HANDLE_TYPE_KMS: -+ case WINSYS_HANDLE_TYPE_SHARED: -+ case WINSYS_HANDLE_TYPE_KMS: - *needs_unref = FALSE; - req->handle_type = DRM_VMW_HANDLE_LEGACY; - req->sid = whandle->handle; - break; -- case DRM_API_HANDLE_TYPE_FD: -+ case WINSYS_HANDLE_TYPE_FD: - if (!vws->ioctl.have_drm_2_6) { - uint32_t handle; - -diff --git a/src/gallium/winsys/sw/dri/dri_sw_winsys.c b/src/gallium/winsys/sw/dri/dri_sw_winsys.c -index 00849985d6b..8335e52200f 100644 ---- a/src/gallium/winsys/sw/dri/dri_sw_winsys.c -+++ b/src/gallium/winsys/sw/dri/dri_sw_winsys.c -@@ -26,6 +26,9 @@ - * - **************************************************************************/ - -+#include -+#include -+ - #include "pipe/p_compiler.h" - #include "pipe/p_format.h" - #include "util/u_inlines.h" -@@ -45,6 +48,7 @@ struct dri_sw_displaytarget - unsigned stride; - - unsigned map_flags; -+ int shmid; - void *data; - void *mapped; - const void *front_private; -@@ -79,6 +83,25 @@ dri_sw_is_displaytarget_format_supported( struct sw_winsys *ws, - return TRUE; - } - -+static char * -+alloc_shm(struct dri_sw_displaytarget *dri_sw_dt, unsigned size) -+{ -+ char *addr; -+ -+ dri_sw_dt->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777); -+ if (dri_sw_dt->shmid < 0) -+ return NULL; -+ -+ addr = (char *) shmat(dri_sw_dt->shmid, 0, 0); -+ /* mark the segment immediately for deletion to avoid leaks */ -+ shmctl(dri_sw_dt->shmid, IPC_RMID, 0); -+ -+ if (addr == (char *) -1) -+ return NULL; -+ -+ return addr; -+} -+ - static struct sw_displaytarget * - dri_sw_displaytarget_create(struct sw_winsys *winsys, - unsigned tex_usage, -@@ -88,6 +111,7 @@ dri_sw_displaytarget_create(struct sw_winsys *winsys, - const void *front_private, - unsigned *stride) - { -+ struct dri_sw_winsys *ws = dri_sw_winsys(winsys); - struct dri_sw_displaytarget *dri_sw_dt; - unsigned nblocksy, size, format_stride; - -@@ -106,7 +130,13 @@ dri_sw_displaytarget_create(struct sw_winsys *winsys, - nblocksy = util_format_get_nblocksy(format, height); - size = dri_sw_dt->stride * nblocksy; - -- dri_sw_dt->data = align_malloc(size, alignment); -+ dri_sw_dt->shmid = -1; -+ if (ws->lf->put_image_shm) -+ dri_sw_dt->data = alloc_shm(dri_sw_dt, size); -+ -+ if(!dri_sw_dt->data) -+ dri_sw_dt->data = align_malloc(size, alignment); -+ - if(!dri_sw_dt->data) - goto no_data; - -@@ -125,7 +155,12 @@ dri_sw_displaytarget_destroy(struct sw_winsys *ws, - { - struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt); - -- align_free(dri_sw_dt->data); -+ if (dri_sw_dt->shmid >= 0) { -+ shmdt(dri_sw_dt->data); -+ shmctl(dri_sw_dt->shmid, IPC_RMID, 0); -+ } else { -+ align_free(dri_sw_dt->data); -+ } - - FREE(dri_sw_dt); - } -@@ -174,7 +209,15 @@ dri_sw_displaytarget_get_handle(struct sw_winsys *winsys, - struct sw_displaytarget *dt, - struct winsys_handle *whandle) - { -- assert(0); -+ struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt); -+ -+ if (whandle->type == WINSYS_HANDLE_TYPE_SHMID) { -+ if (dri_sw_dt->shmid < 0) -+ return FALSE; -+ whandle->handle = dri_sw_dt->shmid; -+ return TRUE; -+ } -+ - return FALSE; - } - -@@ -187,25 +230,38 @@ dri_sw_displaytarget_display(struct sw_winsys *ws, - struct dri_sw_winsys *dri_sw_ws = dri_sw_winsys(ws); - struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt); - struct dri_drawable *dri_drawable = (struct dri_drawable *)context_private; -- unsigned width, height; -+ unsigned width, height, x = 0, y = 0; - unsigned blsize = util_format_get_blocksize(dri_sw_dt->format); -+ unsigned offset = 0; -+ void *data = dri_sw_dt->data; - - /* Set the width to 'stride / cpp'. - * - * PutImage correctly clips to the width of the dst drawable. - */ -- width = dri_sw_dt->stride / blsize; -- -- height = dri_sw_dt->height; -- - if (box) { -- void *data; -- data = (char *)dri_sw_dt->data + (dri_sw_dt->stride * box->y) + box->x * blsize; -- dri_sw_ws->lf->put_image2(dri_drawable, data, -- box->x, box->y, box->width, box->height, dri_sw_dt->stride); -+ offset = (dri_sw_dt->stride * box->y) + box->x * blsize; -+ data += offset; -+ x = box->x; -+ y = box->y; -+ width = box->width; -+ height = box->height; - } else { -- dri_sw_ws->lf->put_image(dri_drawable, dri_sw_dt->data, width, height); -+ width = dri_sw_dt->stride / blsize; -+ height = dri_sw_dt->height; - } -+ -+ if (dri_sw_dt->shmid != -1) { -+ dri_sw_ws->lf->put_image_shm(dri_drawable, dri_sw_dt->shmid, dri_sw_dt->data, offset, -+ x, y, width, height, dri_sw_dt->stride); -+ return; -+ } -+ -+ if (box) -+ dri_sw_ws->lf->put_image2(dri_drawable, data, -+ x, y, width, height, dri_sw_dt->stride); -+ else -+ dri_sw_ws->lf->put_image(dri_drawable, data, width, height); - } - - static void -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 -index 22e1c936ac5..2df5f589e48 100644 ---- a/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c -+++ b/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c -@@ -292,8 +292,8 @@ kms_sw_displaytarget_from_handle(struct sw_winsys *ws, - struct kms_sw_winsys *kms_sw = kms_sw_winsys(ws); - struct kms_sw_displaytarget *kms_sw_dt; - -- assert(whandle->type == DRM_API_HANDLE_TYPE_KMS || -- whandle->type == DRM_API_HANDLE_TYPE_FD); -+ assert(whandle->type == WINSYS_HANDLE_TYPE_KMS || -+ whandle->type == WINSYS_HANDLE_TYPE_FD); - - if (whandle->offset != 0) { - DEBUG_PRINT("KMS-DEBUG: attempt to import unsupported winsys offset %d\n", -@@ -302,7 +302,7 @@ kms_sw_displaytarget_from_handle(struct sw_winsys *ws, - } - - switch(whandle->type) { -- case DRM_API_HANDLE_TYPE_FD: -+ case WINSYS_HANDLE_TYPE_FD: - kms_sw_dt = kms_sw_displaytarget_add_from_prime(kms_sw, whandle->handle, - templ->width0, - templ->height0, -@@ -310,7 +310,7 @@ kms_sw_displaytarget_from_handle(struct sw_winsys *ws, - if (kms_sw_dt) - *stride = kms_sw_dt->stride; - return (struct sw_displaytarget *)kms_sw_dt; -- case DRM_API_HANDLE_TYPE_KMS: -+ case WINSYS_HANDLE_TYPE_KMS: - kms_sw_dt = kms_sw_displaytarget_find_and_ref(kms_sw, whandle->handle); - if (kms_sw_dt) { - *stride = kms_sw_dt->stride; -@@ -334,12 +334,12 @@ kms_sw_displaytarget_get_handle(struct sw_winsys *winsys, - struct kms_sw_displaytarget *kms_sw_dt = kms_sw_displaytarget(dt); - - switch(whandle->type) { -- case DRM_API_HANDLE_TYPE_KMS: -+ case WINSYS_HANDLE_TYPE_KMS: - whandle->handle = kms_sw_dt->handle; - whandle->stride = kms_sw_dt->stride; - whandle->offset = 0; - return TRUE; -- case DRM_API_HANDLE_TYPE_FD: -+ case WINSYS_HANDLE_TYPE_FD: - if (!drmPrimeHandleToFD(kms_sw->fd, kms_sw_dt->handle, - DRM_CLOEXEC, (int*)&whandle->handle)) { - whandle->stride = kms_sw_dt->stride; -diff --git a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c -index 71e652ebf31..cd16413bb8e 100644 ---- a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c -+++ b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c -@@ -398,7 +398,7 @@ virgl_drm_winsys_resource_create_handle(struct virgl_winsys *qws, - - mtx_lock(&qdws->bo_handles_mutex); - -- if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { -+ if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) { - res = util_hash_table_get(qdws->bo_names, (void*)(uintptr_t)handle); - if (res) { - struct virgl_hw_res *r = NULL; -@@ -407,7 +407,7 @@ virgl_drm_winsys_resource_create_handle(struct virgl_winsys *qws, - } - } - -- if (whandle->type == DRM_API_HANDLE_TYPE_FD) { -+ if (whandle->type == WINSYS_HANDLE_TYPE_FD) { - int r; - r = drmPrimeFDToHandle(qdws->fd, whandle->handle, &handle); - if (r) { -@@ -428,7 +428,7 @@ virgl_drm_winsys_resource_create_handle(struct virgl_winsys *qws, - if (!res) - goto done; - -- if (whandle->type == DRM_API_HANDLE_TYPE_FD) { -+ if (whandle->type == WINSYS_HANDLE_TYPE_FD) { - res->bo_handle = handle; - } else { - fprintf(stderr, "gem open handle %d\n", handle); -@@ -478,7 +478,7 @@ static boolean virgl_drm_winsys_resource_get_handle(struct virgl_winsys *qws, - if (!res) - return FALSE; - -- if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { -+ if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) { - if (!res->flinked) { - memset(&flink, 0, sizeof(flink)); - flink.handle = res->bo_handle; -@@ -494,9 +494,9 @@ static boolean virgl_drm_winsys_resource_get_handle(struct virgl_winsys *qws, - mtx_unlock(&qdws->bo_handles_mutex); - } - whandle->handle = res->flink; -- } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) { -+ } else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) { - whandle->handle = res->bo_handle; -- } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) { -+ } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) { - if (drmPrimeHandleToFD(qdws->fd, res->bo_handle, DRM_CLOEXEC, (int*)&whandle->handle)) - return FALSE; - mtx_lock(&qdws->bo_handles_mutex); -diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c -index df2467a5c2d..a2777100a32 100644 ---- a/src/glx/drisw_glx.c -+++ b/src/glx/drisw_glx.c -@@ -28,10 +28,12 @@ - #include - #include "dri_common.h" - #include "drisw_priv.h" -+#include -+#include - - static Bool --XCreateDrawable(struct drisw_drawable * pdp, -- Display * dpy, XID drawable, int visualid) -+XCreateGCs(struct drisw_drawable * pdp, -+ Display * dpy, XID drawable, int visualid) - { - XGCValues gcvalues; - long visMask; -@@ -56,15 +58,78 @@ XCreateDrawable(struct drisw_drawable * pdp, - if (!pdp->visinfo || num_visuals == 0) - return False; - -- /* create XImage */ -- pdp->ximage = XCreateImage(dpy, -- pdp->visinfo->visual, -- pdp->visinfo->depth, -- ZPixmap, 0, /* format, offset */ -- NULL, /* data */ -- 0, 0, /* width, height */ -- 32, /* bitmap_pad */ -- 0); /* bytes_per_line */ -+ return True; -+} -+ -+static int xshm_error = 0; -+static int xshm_opcode = -1; -+ -+/** -+ * Catches potential Xlib errors. -+ */ -+static int -+handle_xerror(Display *dpy, XErrorEvent *event) -+{ -+ (void) dpy; -+ -+ assert(xshm_opcode != -1); -+ if (event->request_code != xshm_opcode || -+ event->minor_code != X_ShmAttach) -+ return 0; -+ -+ xshm_error = 1; -+ return 0; -+} -+ -+static Bool -+XCreateDrawable(struct drisw_drawable * pdp, int shmid, Display * dpy) -+{ -+ if (pdp->ximage) { -+ XDestroyImage(pdp->ximage); -+ pdp->ximage = NULL; -+ } -+ -+ if (!xshm_error && shmid >= 0) { -+ pdp->shminfo.shmid = shmid; -+ pdp->ximage = XShmCreateImage(dpy, -+ pdp->visinfo->visual, -+ pdp->visinfo->depth, -+ ZPixmap, /* format */ -+ NULL, /* data */ -+ &pdp->shminfo, /* shminfo */ -+ 0, 0); /* width, height */ -+ if (pdp->ximage != NULL) { -+ int (*old_handler)(Display *, XErrorEvent *); -+ -+ /* dispatch pending errors */ -+ XSync(dpy, False); -+ -+ old_handler = XSetErrorHandler(handle_xerror); -+ /* This may trigger the X protocol error we're ready to catch: */ -+ XShmAttach(dpy, &pdp->shminfo); -+ XSync(dpy, False); -+ -+ if (xshm_error) { -+ /* we are on a remote display, this error is normal, don't print it */ -+ XDestroyImage(pdp->ximage); -+ pdp->ximage = NULL; -+ } -+ -+ (void) XSetErrorHandler(old_handler); -+ } -+ } -+ -+ if (pdp->ximage == NULL) { -+ pdp->shminfo.shmid = -1; -+ pdp->ximage = XCreateImage(dpy, -+ pdp->visinfo->visual, -+ pdp->visinfo->depth, -+ ZPixmap, 0, /* format, offset */ -+ NULL, /* data */ -+ 0, 0, /* width, height */ -+ 32, /* bitmap_pad */ -+ 0); /* bytes_per_line */ -+ } - - /** - * swrast does not handle 24-bit depth with 24 bpp, so let X do the -@@ -79,7 +144,9 @@ XCreateDrawable(struct drisw_drawable * pdp, - static void - XDestroyDrawable(struct drisw_drawable * pdp, Display * dpy, XID drawable) - { -- XDestroyImage(pdp->ximage); -+ if (pdp->ximage) -+ XDestroyImage(pdp->ximage); -+ - free(pdp->visinfo); - - XFreeGC(dpy, pdp->gc); -@@ -133,9 +200,9 @@ bytes_per_line(unsigned pitch_bits, unsigned mul) - } - - static void --swrastPutImage2(__DRIdrawable * draw, int op, -+swrastXPutImage(__DRIdrawable * draw, int op, - int x, int y, int w, int h, int stride, -- char *data, void *loaderPrivate) -+ int shmid, char *data, void *loaderPrivate) - { - struct drisw_drawable *pdp = loaderPrivate; - __GLXDRIdrawable *pdraw = &(pdp->base); -@@ -144,6 +211,11 @@ swrastPutImage2(__DRIdrawable * draw, int op, - XImage *ximage; - GC gc; - -+ if (!pdp->ximage || shmid != pdp->shminfo.shmid) { -+ if (!XCreateDrawable(pdp, shmid, dpy)) -+ return; -+ } -+ - switch (op) { - case __DRI_SWRAST_IMAGE_OP_DRAW: - gc = pdp->gc; -@@ -156,24 +228,52 @@ swrastPutImage2(__DRIdrawable * draw, int op, - } - - drawable = pdraw->xDrawable; -- - ximage = pdp->ximage; -- ximage->data = data; -- ximage->width = w; -- ximage->height = h; - ximage->bytes_per_line = stride ? stride : bytes_per_line(w * ximage->bits_per_pixel, 32); -+ ximage->data = data; - -- XPutImage(dpy, drawable, gc, ximage, 0, 0, x, y, w, h); -- -+ if (pdp->shminfo.shmid >= 0) { -+ ximage->width = ximage->bytes_per_line / ((ximage->bits_per_pixel + 7)/ 8); -+ ximage->height = h; -+ XShmPutImage(dpy, drawable, gc, ximage, 0, 0, x, y, w, h, False); -+ XSync(dpy, False); -+ } else { -+ ximage->width = w; -+ ximage->height = h; -+ XPutImage(dpy, drawable, gc, ximage, 0, 0, x, y, w, h); -+ } - ximage->data = NULL; - } - -+static void -+swrastPutImageShm(__DRIdrawable * draw, int op, -+ int x, int y, int w, int h, int stride, -+ int shmid, char *shmaddr, unsigned offset, -+ void *loaderPrivate) -+{ -+ struct drisw_drawable *pdp = loaderPrivate; -+ -+ pdp->shminfo.shmaddr = shmaddr; -+ swrastXPutImage(draw, op, x, y, w, h, stride, shmid, -+ shmaddr + offset, loaderPrivate); -+} -+ -+static void -+swrastPutImage2(__DRIdrawable * draw, int op, -+ int x, int y, int w, int h, int stride, -+ char *data, void *loaderPrivate) -+{ -+ swrastXPutImage(draw, op, x, y, w, h, stride, -1, -+ data, loaderPrivate); -+} -+ - static void - swrastPutImage(__DRIdrawable * draw, int op, - int x, int y, int w, int h, - char *data, void *loaderPrivate) - { -- swrastPutImage2(draw, op, x, y, w, h, 0, data, loaderPrivate); -+ swrastXPutImage(draw, op, x, y, w, h, 0, -1, -+ data, loaderPrivate); - } - - static void -@@ -187,6 +287,11 @@ swrastGetImage2(__DRIdrawable * read, - Drawable readable; - XImage *ximage; - -+ if (!prp->ximage || prp->shminfo.shmid >= 0) { -+ if (!XCreateDrawable(prp, -1, dpy)) -+ return; -+ } -+ - readable = pread->xDrawable; - - ximage = prp->ximage; -@@ -208,6 +313,49 @@ swrastGetImage(__DRIdrawable * read, - swrastGetImage2(read, x, y, w, h, 0, data, loaderPrivate); - } - -+static void -+swrastGetImageShm(__DRIdrawable * read, -+ int x, int y, int w, int h, -+ int shmid, void *loaderPrivate) -+{ -+ struct drisw_drawable *prp = loaderPrivate; -+ __GLXDRIdrawable *pread = &(prp->base); -+ Display *dpy = pread->psc->dpy; -+ Drawable readable; -+ XImage *ximage; -+ -+ if (!prp->ximage || shmid != prp->shminfo.shmid) { -+ if (!XCreateDrawable(prp, shmid, dpy)) -+ return; -+ } -+ readable = pread->xDrawable; -+ -+ ximage = prp->ximage; -+ ximage->data = prp->shminfo.shmaddr; /* no offset */ -+ ximage->width = w; -+ ximage->height = h; -+ ximage->bytes_per_line = bytes_per_line(w * ximage->bits_per_pixel, 32); -+ -+ XShmGetImage(dpy, readable, ximage, x, y, ~0L); -+} -+ -+static const __DRIswrastLoaderExtension swrastLoaderExtension_shm = { -+ .base = {__DRI_SWRAST_LOADER, 4 }, -+ -+ .getDrawableInfo = swrastGetDrawableInfo, -+ .putImage = swrastPutImage, -+ .getImage = swrastGetImage, -+ .putImage2 = swrastPutImage2, -+ .getImage2 = swrastGetImage2, -+ .putImageShm = swrastPutImageShm, -+ .getImageShm = swrastGetImageShm, -+}; -+ -+static const __DRIextension *loader_extensions_shm[] = { -+ &swrastLoaderExtension_shm.base, -+ NULL -+}; -+ - static const __DRIswrastLoaderExtension swrastLoaderExtension = { - .base = {__DRI_SWRAST_LOADER, 3 }, - -@@ -218,7 +366,7 @@ static const __DRIswrastLoaderExtension swrastLoaderExtension = { - .getImage2 = swrastGetImage2, - }; - --static const __DRIextension *loader_extensions[] = { -+static const __DRIextension *loader_extensions_noshm[] = { - &swrastLoaderExtension.base, - NULL - }; -@@ -527,7 +675,7 @@ driswCreateDrawable(struct glx_screen *base, XID xDrawable, - pdp->base.drawable = drawable; - pdp->base.psc = &psc->base; - -- ret = XCreateDrawable(pdp, psc->base.dpy, xDrawable, modes->visualID); -+ ret = XCreateGCs(pdp, psc->base.dpy, xDrawable, modes->visualID); - if (!ret) { - free(pdp); - return NULL; -@@ -661,6 +809,14 @@ driswBindExtensions(struct drisw_screen *psc, const __DRIextension **extensions) - } - } - -+static int -+check_xshm(Display *dpy) -+{ -+ int ignore; -+ -+ return XQueryExtension(dpy, "MIT-SHM", &xshm_opcode, &ignore, &ignore); -+} -+ - static struct glx_screen * - driswCreateScreen(int screen, struct glx_display *priv) - { -@@ -670,6 +826,7 @@ driswCreateScreen(int screen, struct glx_display *priv) - struct drisw_screen *psc; - struct glx_config *configs = NULL, *visuals = NULL; - int i; -+ const __DRIextension **loader_extensions_local; - - psc = calloc(1, sizeof *psc); - if (psc == NULL) -@@ -688,6 +845,11 @@ driswCreateScreen(int screen, struct glx_display *priv) - if (extensions == NULL) - goto handle_error; - -+ if (!check_xshm(psc->base.dpy)) -+ loader_extensions_local = loader_extensions_noshm; -+ else -+ loader_extensions_local = loader_extensions_shm; -+ - for (i = 0; extensions[i]; i++) { - if (strcmp(extensions[i]->name, __DRI_CORE) == 0) - psc->core = (__DRIcoreExtension *) extensions[i]; -@@ -704,12 +866,12 @@ driswCreateScreen(int screen, struct glx_display *priv) - - if (psc->swrast->base.version >= 4) { - psc->driScreen = -- psc->swrast->createNewScreen2(screen, loader_extensions, -+ psc->swrast->createNewScreen2(screen, loader_extensions_local, - extensions, - &driver_configs, psc); - } else { - psc->driScreen = -- psc->swrast->createNewScreen(screen, loader_extensions, -+ psc->swrast->createNewScreen(screen, loader_extensions_local, - &driver_configs, psc); - } - if (psc->driScreen == NULL) { -diff --git a/src/glx/drisw_priv.h b/src/glx/drisw_priv.h -index 5d479003114..a670da2d33b 100644 ---- a/src/glx/drisw_priv.h -+++ b/src/glx/drisw_priv.h -@@ -23,6 +23,8 @@ - * SOFTWARE. - */ - -+#include -+ - struct drisw_display - { - __GLXDRIdisplay base; -@@ -62,6 +64,7 @@ struct drisw_drawable - __DRIdrawable *driDrawable; - XVisualInfo *visinfo; - XImage *ximage; -+ XShmSegmentInfo shminfo; - }; - - _X_HIDDEN int -diff --git a/src/mesa/state_tracker/st_cb_memoryobjects.c b/src/mesa/state_tracker/st_cb_memoryobjects.c -index 63a8c2a0e00..39174bc9f75 100644 ---- a/src/mesa/state_tracker/st_cb_memoryobjects.c -+++ b/src/mesa/state_tracker/st_cb_memoryobjects.c -@@ -65,7 +65,7 @@ st_import_memoryobj_fd(struct gl_context *ctx, - struct pipe_screen *screen = pipe->screen; - struct winsys_handle whandle; - -- whandle.type = DRM_API_HANDLE_TYPE_FD; -+ whandle.type = WINSYS_HANDLE_TYPE_FD; - whandle.handle = fd; - whandle.offset = 0; - whandle.layer = 0; -diff --git a/src/mesa/state_tracker/st_vdpau.c b/src/mesa/state_tracker/st_vdpau.c -index eb61aef1116..d0b9cfbf4f8 100644 ---- a/src/mesa/state_tracker/st_vdpau.c -+++ b/src/mesa/state_tracker/st_vdpau.c -@@ -127,7 +127,7 @@ st_vdpau_resource_from_description(struct gl_context *ctx, - templ.usage = PIPE_USAGE_DEFAULT; - - memset(&whandle, 0, sizeof(whandle)); -- whandle.type = DRM_API_HANDLE_TYPE_FD; -+ whandle.type = WINSYS_HANDLE_TYPE_FD; - whandle.handle = desc->handle; - whandle.offset = desc->offset; - whandle.stride = desc->stride; diff --git a/SOURCES/fix-llvmpipe-remote-shm.patch b/SOURCES/fix-llvmpipe-remote-shm.patch new file mode 100644 index 0000000..b03ae67 --- /dev/null +++ b/SOURCES/fix-llvmpipe-remote-shm.patch @@ -0,0 +1,68 @@ +From 607a59f2922b1261920bae94efe4dc87da18d576 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Tue, 5 Mar 2019 15:31:51 -0500 +Subject: [PATCH] drisw: Try harder to probe whether MIT-SHM works + +XQueryExtension merely tells you whether the extension exists, it +doesn't tell you whether you're local enough for it to work. +XShmQueryVersion is not enough to discover this either, you need to +provoke the server to do actual work, and if it thinks you're remote it +will throw BadRequest at you. So send an invalid ShmDetach and use the +error code to distinguish local from remote. + +Signed-off-by: Adam Jackson +--- + src/glx/drisw_glx.c | 26 ++++++++++++++++++++++---- + 1 file changed, 22 insertions(+), 4 deletions(-) + +diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c +index c63b097a71a..67698d1c450 100644 +--- a/src/glx/drisw_glx.c ++++ b/src/glx/drisw_glx.c +@@ -73,11 +73,10 @@ handle_xerror(Display *dpy, XErrorEvent *event) + (void) dpy; + + assert(xshm_opcode != -1); +- if (event->request_code != xshm_opcode || +- event->minor_code != X_ShmAttach) ++ if (event->request_code != xshm_opcode) + return 0; + +- xshm_error = 1; ++ xshm_error = event->error_code; + return 0; + } + +@@ -826,9 +825,28 @@ driswBindExtensions(struct drisw_screen *psc, const __DRIextension **extensions) + static int + check_xshm(Display *dpy) + { ++ int (*old_handler)(Display *, XErrorEvent *); ++ + int ignore; ++ XShmSegmentInfo info = { 0, }; ++ ++ if (!XQueryExtension(dpy, "MIT-SHM", &xshm_opcode, &ignore, &ignore)) ++ return False; ++ ++ old_handler = XSetErrorHandler(handle_xerror); ++ XShmDetach(dpy, &info); ++ XSync(dpy, False); ++ (void) XSetErrorHandler(old_handler); + +- return XQueryExtension(dpy, "MIT-SHM", &xshm_opcode, &ignore, &ignore); ++ /* BadRequest means we're a remote client. If we were local we'd ++ * expect BadValue since 'info' has an invalid segment name. ++ */ ++ if (xshm_error == BadRequest) ++ return False; ++ ++ /* reset this as others read it later */ ++ xshm_error = 0; ++ return True; + } + + static struct glx_screen * +-- +2.20.1 + diff --git a/SOURCES/xshm-disable.patch b/SOURCES/xshm-disable.patch deleted file mode 100644 index bf6e3f4..0000000 --- a/SOURCES/xshm-disable.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up mesa-18.0.5/src/glx/drisw_glx.c.dma mesa-18.0.5/src/glx/drisw_glx.c ---- mesa-18.0.5/src/glx/drisw_glx.c.dma 2018-12-07 10:42:42.332659700 +1000 -+++ mesa-18.0.5/src/glx/drisw_glx.c 2018-12-07 10:43:08.312349783 +1000 -@@ -812,6 +812,8 @@ static int - check_xshm(Display *dpy) - { - int ignore; -+ /* disable shm paths for now */ -+ return 0; - - return XQueryExtension(dpy, "MIT-SHM", &xshm_opcode, &ignore, &ignore); - } diff --git a/SPECS/mesa.spec b/SPECS/mesa.spec index 40c88d9..104b3a5 100644 --- a/SPECS/mesa.spec +++ b/SPECS/mesa.spec @@ -41,7 +41,7 @@ %endif %endif -%ifarch x86_64 ppc64le +%ifarch %{ix86} x86_64 ppc64le %define with_vulkan 1 %else %define with_vulkan 0 @@ -60,8 +60,8 @@ Summary: Mesa graphics libraries Name: mesa -Version: 18.0.5 -Release: 4%{?dist} +Version: 18.3.4 +Release: 5%{?dist} License: MIT Group: System Environment/Libraries URL: http://www.mesa3d.org @@ -78,14 +78,14 @@ Source3: make-git-snapshot.sh Source4: Mesa-MLAA-License-Clarification-Email.txt Patch1: nv50-fix-build.patch -# backport of dri sw xshm support to help qxl -Patch2: dri-sw-xshm-support.patch # fix some timeout mismatch warnings (backport from upstream) Patch3: fix-timeout-warnings.patch -# disable xshm -Patch4: xshm-disable.patch +# Fix dri shm leak +Patch4: 0001-glx-fix-shared-memory-leak-in-X11.patch +# fix remove shm +Patch5: fix-llvmpipe-remote-shm.patch Patch12: mesa-8.0.1-fix-16bpp.patch Patch15: mesa-9.2-hardware-float.patch @@ -109,6 +109,7 @@ BuildRequires: libXfixes-devel BuildRequires: libXdamage-devel BuildRequires: libXi-devel BuildRequires: libXmu-devel +BuildRequires: libXrandr-devel BuildRequires: libxshmfence-devel BuildRequires: elfutils BuildRequires: python @@ -177,6 +178,11 @@ Obsoletes: mesa-dri-filesystem < %{version}-%{release} %description filesystem Mesa driver filesystem +%package khr-devel +Summary: Mesa Khronos development headers +%description khr-devel +%{summary} + %package dri-drivers Summary: Mesa-based DRI drivers Group: User Interface/X Hardware Support @@ -202,6 +208,7 @@ Group: Development/Libraries Requires: mesa-libGL = %{version}-%{release} Requires: gl-manpages Requires: libglvnd-devel%{?_isa} +Requires: %{name}-khr-devel%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release} Provides: libGL-devel %description libGL-devel @@ -212,6 +219,7 @@ Summary: Mesa libEGL development package Group: Development/Libraries Requires: mesa-libEGL = %{version}-%{release} Requires: libglvnd-devel%{?_isa} +Requires: %{name}-khr-devel%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release} Provides: khrplatform-devel = %{version}-%{release} Obsoletes: khrplatform-devel < %{version}-%{release} @@ -222,6 +230,7 @@ Mesa libEGL development package Summary: Mesa libGLES development package Group: Development/Libraries Requires: mesa-libGLES = %{version}-%{release} +Requires: %{name}-khr-devel%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release} Requires: libglvnd-devel%{?_isa} %description libGLES-devel @@ -330,15 +339,15 @@ The drivers with support for the Vulkan API. # make sure you run sanitize-tarball.sh on mesa source tarball or next line will exit grep -q ^/ src/gallium/auxiliary/vl/vl_decoder.c && exit 1 %patch1 -p1 -b .nv50rtti -%patch2 -p1 -b .xshm %patch3 -p1 -b .timeout -%patch4 -p1 -b .noshm +%patch4 -p1 -b .shmleak +%patch5 -p1 -b .shmremote #patch12 -p1 -b .16bpp %patch15 -p1 -b .hwfloat #patch20 -p1 -b .egbe -%patch21 -p1 -b .glpc +#%patch21 -p1 -b .glpc %if 0%{with_private_llvm} sed -i 's/\[llvm-config\]/\[llvm-private-config-%{__isa_bits}\]/g' configure.ac @@ -466,15 +475,15 @@ rm -rf $RPM_BUILD_ROOT %postun libglapi -p /sbin/ldconfig %post libgbm -p /sbin/ldconfig %postun libgbm -p /sbin/ldconfig -%if !0%{?rhel} -%post libwayland-egl -p /sbin/ldconfig -%postun libwayland-egl -p /sbin/ldconfig -%endif %if 0%{?with_vmware} %post libxatracker -p /sbin/ldconfig %postun libxatracker -p /sbin/ldconfig %endif +%files khr-devel +%dir %{_includedir}/KHR +%{_includedir}/KHR/khrplatform.h + %files libGL %defattr(-,root,root,-) %{_libdir}/libGLX_mesa.so.0* @@ -505,8 +514,9 @@ rm -rf $RPM_BUILD_ROOT %files dri-drivers %defattr(-,root,root,-) +%dir %{_datadir}/drirc.d +%{_datadir}/drirc.d/00-mesa-defaults.conf %if %{with_hardware} -%config(noreplace) %{_sysconfdir}/drirc %if !0%{?rhel} %{_libdir}/dri/radeon_dri.so %{_libdir}/dri/r200_dri.so @@ -577,8 +587,6 @@ rm -rf $RPM_BUILD_ROOT %{_includedir}/EGL/eglmesaext.h %{_includedir}/EGL/eglextchromium.h %{_includedir}/EGL/eglplatform.h -%dir %{_includedir}/KHR -%{_includedir}/KHR/khrplatform.h %{_libdir}/pkgconfig/egl.pc %files libGLES-devel @@ -617,18 +625,6 @@ rm -rf $RPM_BUILD_ROOT %{_includedir}/gbm.h %{_libdir}/pkgconfig/gbm.pc -%if %{with wayland} -%files libwayland-egl -%defattr(-,root,root,-) -%{_libdir}/libwayland-egl.so.1 -%{_libdir}/libwayland-egl.so.1.* - -%files libwayland-egl-devel -%defattr(-,root,root,-) -%{_libdir}/libwayland-egl.so -%{_libdir}/pkgconfig/wayland-egl.pc -%endif - %if 0%{?with_vmware} %files libxatracker %defattr(-,root,root,-) @@ -650,20 +646,48 @@ rm -rf $RPM_BUILD_ROOT %if 0%{?with_vulkan} %files vulkan-drivers -%ifarch x86_64 +%ifarch %{ix86} x86_64 %{_libdir}/libvulkan_intel.so -%{_datadir}/vulkan/icd.d/intel_icd.x86_64.json %endif %{_libdir}/libvulkan_radeon.so %ifarch x86_64 +%{_datadir}/vulkan/icd.d/intel_icd.x86_64.json %{_datadir}/vulkan/icd.d/radeon_icd.x86_64.json %endif +%ifarch %{ix86} +%{_datadir}/vulkan/icd.d/intel_icd.i686.json +%{_datadir}/vulkan/icd.d/radeon_icd.i686.json +%endif %ifarch ppc64le %{_datadir}/vulkan/icd.d/radeon_icd.powerpc64le.json %endif %endif %changelog +* Thu Apr 04 2019 Dave Airlie - 18.3.4-5 +- fix remote shm patch + +* Wed Mar 27 2019 Dave Airlie - 18.3.4-4 +- Enable i686 vulkan drivers for 32-bit apps + +* Tue Mar 26 2019 Dave Airlie - 18.3.4-3 +- fix remote shm + +* Fri Mar 01 2019 Dave Airlie - 18.3.4-2 +- add shm fix + +* Tue Feb 19 2019 Dave Airlie - 18.3.4-1 +- mesa 18.3.4 + +* Wed Feb 13 2019 Dave Airlie - 18.3.3-2 +- Add khr-devel to fix buildroot GL/EGL devel (#1676392) + +* Wed Feb 06 2019 Dave Airlie - 18.3.3-1 +- mesa 18.3.3 + +* Thu Jan 31 2019 Dave Airlie - 18.3.2-1 +- mesa 18.3.2 + * Sat Dec 15 2018 Dave Airlie - 18.0.5-4 - disable shm put/get for now it caused regressions