diff --git a/SOURCES/0001-pkgconfig-Fix-gl.pc-when-glvnd-is-enabled.patch b/SOURCES/0001-pkgconfig-Fix-gl.pc-when-glvnd-is-enabled.patch new file mode 100644 index 0000000..39930b7 --- /dev/null +++ b/SOURCES/0001-pkgconfig-Fix-gl.pc-when-glvnd-is-enabled.patch @@ -0,0 +1,29 @@ +From 7c137cfbffb4962b4e080052ef05cfb2266e758a Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Tue, 29 May 2018 09:47:35 -0400 +Subject: [PATCH] pkgconfig: Fix gl.pc when glvnd is enabled + +GL_LIB expands to GLX_mesa, but applications should not link against +that. -lGL is never wrong, just hardcode it. + +Signed-off-by: Adam Jackson +--- + src/mesa/gl.pc.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/mesa/gl.pc.in b/src/mesa/gl.pc.in +index 181724b97b..8c7b7da8d7 100644 +--- a/src/mesa/gl.pc.in ++++ b/src/mesa/gl.pc.in +@@ -7,7 +7,7 @@ Name: gl + Description: Mesa OpenGL library + Requires.private: @GL_PC_REQ_PRIV@ + Version: @PACKAGE_VERSION@ +-Libs: -L${libdir} -l@GL_LIB@ ++Libs: -L${libdir} -lGL + Libs.private: @GL_PC_LIB_PRIV@ + Cflags: -I${includedir} @GL_PC_CFLAGS@ + glx_tls: @GLX_TLS@ +-- +2.17.0 + diff --git a/SOURCES/dri-sw-xshm-support.patch b/SOURCES/dri-sw-xshm-support.patch new file mode 100644 index 0000000..33700e8 --- /dev/null +++ b/SOURCES/dri-sw-xshm-support.patch @@ -0,0 +1,1690 @@ +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-timeout-warnings.patch b/SOURCES/fix-timeout-warnings.patch new file mode 100644 index 0000000..e0c7bf7 --- /dev/null +++ b/SOURCES/fix-timeout-warnings.patch @@ -0,0 +1,39 @@ +diff -up mesa-20180530/src/gallium/drivers/r600/Makefile.am.dma mesa-20180530/src/gallium/drivers/r600/Makefile.am +--- mesa-20180530/src/gallium/drivers/r600/Makefile.am.dma 2018-07-19 10:24:26.110829986 +1000 ++++ mesa-20180530/src/gallium/drivers/r600/Makefile.am 2018-07-19 10:24:44.569297131 +1000 +@@ -10,7 +10,8 @@ AM_CFLAGS = \ + $(GALLIUM_DRIVER_CFLAGS) \ + $(RADEON_CFLAGS) \ + $(LIBELF_CFLAGS) \ +- -I$(top_srcdir)/src/amd/common ++ -I$(top_srcdir)/src/amd/common \ ++ -Wstrict-overflow=0 + + AM_CXXFLAGS = \ + $(GALLIUM_DRIVER_CXXFLAGS) \ +diff -up mesa-20180530/src/gallium/winsys/virgl/drm/Makefile.am.dma mesa-20180530/src/gallium/winsys/virgl/drm/Makefile.am +--- mesa-20180530/src/gallium/winsys/virgl/drm/Makefile.am.dma 2018-07-19 10:25:13.089018307 +1000 ++++ mesa-20180530/src/gallium/winsys/virgl/drm/Makefile.am 2018-07-19 10:25:34.775566694 +1000 +@@ -26,7 +26,8 @@ include $(top_srcdir)/src/gallium/Automa + AM_CFLAGS = \ + -I$(top_srcdir)/src/gallium/drivers \ + $(GALLIUM_WINSYS_CFLAGS) \ +- $(LIBDRM_CFLAGS) ++ $(LIBDRM_CFLAGS) \ ++ -Wstrict-overflow=0 + + noinst_LTLIBRARIES = libvirgldrm.la + +diff -up mesa-20180530/src/gallium/winsys/virgl/vtest/Makefile.am.dma mesa-20180530/src/gallium/winsys/virgl/vtest/Makefile.am +--- mesa-20180530/src/gallium/winsys/virgl/vtest/Makefile.am.dma 2018-07-19 10:25:48.521914297 +1000 ++++ mesa-20180530/src/gallium/winsys/virgl/vtest/Makefile.am 2018-07-19 10:26:05.622346714 +1000 +@@ -25,7 +25,8 @@ include $(top_srcdir)/src/gallium/Automa + + AM_CFLAGS = \ + -I$(top_srcdir)/src/gallium/drivers \ +- $(GALLIUM_WINSYS_CFLAGS) ++ $(GALLIUM_WINSYS_CFLAGS) \ ++ -Wstrict-overflow=0 + + noinst_LTLIBRARIES = libvirglvtest.la + diff --git a/SOURCES/make-git-snapshot.sh b/SOURCES/make-git-snapshot.sh index 64a5bec..4d1f635 100755 --- a/SOURCES/make-git-snapshot.sh +++ b/SOURCES/make-git-snapshot.sh @@ -1,31 +1,28 @@ #!/bin/sh -proto=$1 -branch=$2 +# Usage: ./make-git-snapshot.sh [COMMIT] +# +# to make a snapshot of the given tag/branch. Defaults to HEAD. +# Point env var REF to a local mesa repo to reduce clone time. -if [ -z "$proto" ]; then - echo "Usage: $0 []" - exit 1 +if [ -e /usr/bin/pxz ]; then + XZ=/usr/bin/pxz +else + XZ=/usr/bin/xz fi -dirname=$proto-$( date +%Y%m%d ) +DIRNAME=mesa-$( date +%Y%m%d ) -rm -rf $dirname -git clone git://git.freedesktop.org/git/xorg/proto/$proto $dirname -cd $dirname -if [ -z "$branch" ]; then - git log | head -1 -else - git checkout $branch -fi -sha=`git rev-list --max-count=1 --abbrev-commit HEAD` -git repack -a -d -cd .. - -# append sha to dirname -mv $dirname $dirname-git$sha -dirname=$dirname-git$sha -tarball=$dirname.tar.bz2 -tar jcf $tarball $dirname -rm -rf $dirname -echo "$tarball is now available" +echo REF ${REF:+--reference $REF} +echo DIRNAME $DIRNAME +echo HEAD ${1:-18.0} + +rm -rf $DIRNAME + +git clone --depth 1 ${REF:+--reference $REF} --branch 18.0 \ + git://git.freedesktop.org/git/mesa/mesa $DIRNAME + +GIT_DIR=$DIRNAME/.git git archive --format=tar --prefix=$DIRNAME/ ${1:-HEAD} \ + | $XZ > $DIRNAME.tar.xz + +# rm -rf $DIRNAME diff --git a/SPECS/mesa.spec b/SPECS/mesa.spec index e676192..1b7ce7e 100644 --- a/SPECS/mesa.spec +++ b/SPECS/mesa.spec @@ -55,19 +55,19 @@ %define _default_patch_fuzz 2 -%define gitdate 20171019 +#define gitdate 20180530 #% define snapshot Summary: Mesa graphics libraries Name: mesa -Version: 17.2.3 -Release: 8.%{gitdate}%{?dist} +Version: 18.0.5 +Release: 3%{?dist} License: MIT Group: System Environment/Libraries URL: http://www.mesa3d.org -# Source0: MesaLib-%{version}.tar.xz -Source0: %{name}-%{gitdate}.tar.xz +Source0: mesa-%{version}.tar.xz +#Source0: %{name}-%{gitdate}.tar.xz Source1: sanitize-tarball.sh Source2: make-release-tarball.sh Source3: make-git-snapshot.sh @@ -77,23 +77,16 @@ Source3: make-git-snapshot.sh # Fedora opts to ignore the optional part of clause 2 and treat that code as 2 clause BSD. Source4: Mesa-MLAA-License-Clarification-Email.txt -Patch0: mesa-17.3-final.patch Patch1: nv50-fix-build.patch -Patch2: 0001-mesa-Squash-merge-of-S3TC-support.patch -Patch9: mesa-8.0-llvmpipe-shmget.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 Patch12: mesa-8.0.1-fix-16bpp.patch Patch15: mesa-9.2-hardware-float.patch Patch20: mesa-10.2-evergreen-big-endian.patch - -# For bz1503861, fix visual artifacts on DRI PRIME offloading -# Feel free to drop these patches during the next mesa rebase (>17.2.3) -Patch30: 0001-intel-blorp-Use-mocs.tex-for-depth-stencil.patch -Patch31: 0002-anv-blorp-Add-a-device-parameter-to-blorp_surf_for_a.patch -Patch32: 0003-blorp-Turn-anv_CmdCopyBuffer-into-a-blorp_buffer_cop.patch -Patch33: 0004-intel-blorp-Make-the-MOCS-setting-part-of-blorp_addr.patch -Patch34: 0005-i965-Use-PTE-MOCS-for-all-external-buffers.patch - -Patch40: 0001-intel-Add-more-Coffee-Lake-PCI-IDs.patch +Patch21: 0001-pkgconfig-Fix-gl.pc-when-glvnd-is-enabled.patch BuildRequires: pkgconfig autoconf automake libtool %if %{with_hardware} @@ -119,7 +112,7 @@ BuildRequires: python-mako BuildRequires: gettext %if 0%{?with_llvm} %if 0%{?with_private_llvm} -BuildRequires: llvm-private-devel >= 5.0 +BuildRequires: llvm-private-devel >= 6.0 %else BuildRequires: llvm-devel >= 3.0 %endif @@ -133,11 +126,12 @@ BuildRequires: pkgconfig(wayland-client) >= 1.11 BuildRequires: pkgconfig(wayland-server) >= 1.11 BuildRequires: pkgconfig(wayland-protocols) >= 1.8.0 %endif -BuildRequires: mesa-libGL-devel +# BuildRequires: mesa-libGL-devel %if 0%{?with_vdpau} BuildRequires: libvdpau-devel %endif BuildRequires: zlib-devel +BuildRequires: libglvnd-devel %description Mesa @@ -148,6 +142,7 @@ Group: System Environment/Libraries Provides: libGL Requires: mesa-libglapi = %{version}-%{release} Requires: libdrm >= 2.4.83 +Requires: libglvnd-glx%{?_isa} >= 1:1.0.1-0.7 %description libGL Mesa libGL runtime library. @@ -156,6 +151,7 @@ Mesa libGL runtime library. Summary: Mesa libEGL runtime libraries Group: System Environment/Libraries Requires: mesa-libgbm = %{version}-%{release} +Requires: libglvnd-egl%{?_isa} %description libEGL Mesa libEGL runtime libraries @@ -164,6 +160,7 @@ Mesa libEGL runtime libraries Summary: Mesa libGLES runtime libraries Group: System Environment/Libraries Requires: mesa-libglapi = %{version}-%{release} +Requires: libglvnd-gles%{?_isa} %description libGLES Mesa GLES runtime libraries @@ -200,6 +197,7 @@ Summary: Mesa libGL development package Group: Development/Libraries Requires: mesa-libGL = %{version}-%{release} Requires: gl-manpages +Requires: libglvnd-devel%{?_isa} Provides: libGL-devel %description libGL-devel @@ -209,6 +207,7 @@ Mesa libGL development package Summary: Mesa libEGL development package Group: Development/Libraries Requires: mesa-libEGL = %{version}-%{release} +Requires: libglvnd-devel%{?_isa} Provides: khrplatform-devel = %{version}-%{release} Obsoletes: khrplatform-devel < %{version}-%{release} @@ -219,6 +218,7 @@ Mesa libEGL development package Summary: Mesa libGLES development package Group: Development/Libraries Requires: mesa-libGLES = %{version}-%{release} +Requires: libglvnd-devel%{?_isa} %description libGLES-devel Mesa libGLES development package @@ -321,35 +321,19 @@ The drivers with support for the Vulkan API. %endif %prep -#setup -q -n Mesa-%{version}%{?snapshot} -%setup -q -n mesa-%{gitdate} +%setup -q -n mesa-%{version}%{?snapshot} +#setup -q -n mesa-%{gitdate} # 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 -%patch0 -p1 -b .mesa17.2.3 %patch1 -p1 -b .nv50rtti -%patch2 -p1 -b .s3tc - -# this fastpath is: -# - broken with swrast classic -# - broken on 24bpp -# - not a huge win anyway -# - ABI-broken wrt upstream -# - eventually obsoleted by vgem -# -# dear ajax: fix this one way or the other -#patch9 -p1 -b .shmget +%patch2 -p1 -b .xshm +%patch3 -p1 -b .timeout + #patch12 -p1 -b .16bpp %patch15 -p1 -b .hwfloat #patch20 -p1 -b .egbe - -%patch30 -p1 -b .bz1503861_patch1 -%patch31 -p1 -b .bz1503861_patch2 -%patch32 -p1 -b .bz1503861_patch3 -%patch33 -p1 -b .bz1503861_patch4 -%patch34 -p1 -b .bz1503861_patch5 - -%patch40 -p1 -b .cfl_ids +%patch21 -p1 -b .glpc %if 0%{with_private_llvm} sed -i 's/\[llvm-config\]/\[llvm-private-config-%{__isa_bits}\]/g' configure.ac @@ -383,6 +367,7 @@ export CXXFLAGS="$RPM_OPT_FLAGS -fno-rtti -fno-exceptions" %configure \ %{?asm_flags} \ + --enable-libglvnd \ --enable-selinux \ --enable-osmesa \ --with-dri-driverdir=%{_libdir}/dri \ @@ -410,9 +395,6 @@ export CXXFLAGS="$RPM_OPT_FLAGS -fno-rtti -fno-exceptions" %endif %{?dri_drivers} -# this seems to be neccessary for s390 -make -C src/mesa/drivers/dri/common/xmlpool/ - make %{?_smp_mflags} MKDEP=/bin/true %install @@ -433,6 +415,17 @@ rm -f $RPM_BUILD_ROOT%{_sysconfdir}/drirc # libvdpau opens the versioned name, don't bother including the unversioned rm -f $RPM_BUILD_ROOT%{_libdir}/vdpau/*.so +# likewise glvnd +rm -f %{buildroot}%{_libdir}/libGLX_mesa.so +rm -f %{buildroot}%{_libdir}/libEGL_mesa.so +# XXX can we just not build this +rm -f %{buildroot}%{_libdir}/libGLES* + +# XXX wayland-egl? + +# glvnd needs a default provider for indirect rendering where it cannot +# determine the vendor +ln -s %{_libdir}/libGLX_mesa.so.0 %{buildroot}%{_libdir}/libGLX_system.so.0 # strip out useless headers rm -f $RPM_BUILD_ROOT%{_includedir}/GL/w*.h @@ -479,18 +472,17 @@ rm -rf $RPM_BUILD_ROOT %files libGL %defattr(-,root,root,-) -%{_libdir}/libGL.so.1 -%{_libdir}/libGL.so.1.* +%{_libdir}/libGLX_mesa.so.0* +%{_libdir}/libGLX_system.so.0* %files libEGL %defattr(-,root,root,-) -%{_libdir}/libEGL.so.1 -%{_libdir}/libEGL.so.1.* +%{_datadir}/glvnd/egl_vendor.d/50_mesa.json +%{_libdir}/libEGL_mesa.so.0* %files libGLES %defattr(-,root,root,-) -%{_libdir}/libGLESv2.so.2 -%{_libdir}/libGLESv2.so.2.* +# no files, all provided by libglvnd %files filesystem %defattr(-,root,root,-) @@ -569,7 +561,6 @@ rm -rf $RPM_BUILD_ROOT %dir %{_includedir}/GL/internal %{_includedir}/GL/internal/dri_interface.h %{_libdir}/pkgconfig/dri.pc -%{_libdir}/libGL.so %{_libdir}/libglapi.so %{_libdir}/pkgconfig/gl.pc @@ -584,7 +575,6 @@ rm -rf $RPM_BUILD_ROOT %dir %{_includedir}/KHR %{_includedir}/KHR/khrplatform.h %{_libdir}/pkgconfig/egl.pc -%{_libdir}/libEGL.so %files libGLES-devel %defattr(-,root,root,-) @@ -599,7 +589,6 @@ rm -rf $RPM_BUILD_ROOT %{_includedir}/GLES3/gl32.h %{_includedir}/GLES3/gl3ext.h %{_libdir}/pkgconfig/glesv2.pc -%{_libdir}/libGLESv2.so %files libOSMesa %defattr(-,root,root,-) @@ -670,6 +659,32 @@ rm -rf $RPM_BUILD_ROOT %endif %changelog +* Tue Jul 24 2018 Dave Airlie - 18.0.5-3 +- rename fedora to system in glvnd fallback + +* Thu Jul 19 2018 Dave Airlie - 18.0.5-2 +- Fix timeout overflow warnings (backport from upstream + virgl) + +* Wed Jun 20 2018 Adam Jackson - 18.0.5-1 +- Mesa 18.0.5 + +* Wed May 30 2018 Dave Airlie - 18.0.3-5.20180508 +- Fix gl.pc when using glvnd +- Fix subpackage dependencies for glvnd + +* Fri May 25 2018 Adam Jackson - 18.0.3-2.20180508 +- Use glvnd + +* Tue May 08 2018 Dave Airlie 18.0.3-1.20180508 +- rebase to 18.0.3 + +* Wed Apr 18 2018 Adam Jackson - 17.2.3-9 +- Rebuild for new llvm + * Mon Jan 15 2018 Dave Airlie - 17.2.3-8.20171019 - Add missing Intel CFL ids.