mesa: Changes to 'ubuntu'
debian/changelog | 9
debian/patches/egl-platform-mir.patch | 855 +++++++++++++++++++++++++++-------
2 files changed, 695 insertions(+), 169 deletions(-)
New commits:
commit b12216e5d09fa3fe8d64337f593397be35c6b0c3
Author: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
Date: Wed Dec 11 12:45:35 2013 +0800
Update Mir EGL platform patch
diff --git a/debian/changelog b/debian/changelog
index f82a9cb..8bcdeab 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
+mesa (10.0.0-1ubuntu3) trusty; urgency=low
+
+ * Refresh Mir EGL platform patch.
+ + Adds EGL_KHR_image support, needed for nested Mir-on-Mir support
+ + Adds resize support (LP: #1227744)
+ + Properly free()s surface front and back buffers on destroy (LP: #1211982)
+
+ -- Christopher James Halse Rogers <raof@ubuntu.com> Wed, 11 Dec 2013 12:24:46 +0800
+
mesa (10.0.0-1ubuntu2) trusty; urgency=low
* Do not require libdrm-intel on arm, fixes FTBFS regression.
diff --git a/debian/patches/egl-platform-mir.patch b/debian/patches/egl-platform-mir.patch
index 611d105..00d6b7f 100644
--- a/debian/patches/egl-platform-mir.patch
+++ b/debian/patches/egl-platform-mir.patch
@@ -137,7 +137,7 @@
char *
--- /dev/null
+++ b/src/egl/drivers/dri2/platform_mir.c
-@@ -0,0 +1,347 @@
+@@ -0,0 +1,435 @@
+/*
+ * Copyright © 2012 Canonical, Inc
+ *
@@ -171,6 +171,7 @@
+
+#include <stdlib.h>
+#include <string.h>
++#include <unistd.h>
+
+static __DRIbuffer *
+dri2_get_buffers_with_format(__DRIdrawable * driDrawable,
@@ -283,6 +284,12 @@
+ assert(buffer_package.data_items == 0);
+ assert(buffer_package.fd_items == 1);
+
++ /* Mir ABIs prior to release 0.1.2 lacked width and height */
++ if (buffer_package.width && buffer_package.height) {
++ surf->base.Width = buffer_package.width;
++ surf->base.Height = buffer_package.height;
++ }
++
+ surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]->name = 0;
+ surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]->fd = buffer_package.fd[0];
+ surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]->pitch = buffer_package.stride;
@@ -333,10 +340,28 @@
+ if(!mir_advance_colour_buffer(dri2_surf))
+ goto cleanup_surf;
+
-+ dri2_surf->dri_drawable =
-+ (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
-+ dri2_conf->dri_double_config,
-+ dri2_surf);
++ if (dri2_dpy->gbm_dri) {
++ struct gbm_dri_surface *surf = malloc(sizeof *surf);
++
++ dri2_surf->gbm_surf = surf;
++ surf->base.gbm = &dri2_dpy->gbm_dri->base;
++ surf->base.width = dri2_surf->base.Width;
++ surf->base.height = dri2_surf->base.Height;
++ surf->base.format = GBM_FORMAT_ARGB8888;
++ surf->base.flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
++ surf->dri_private = dri2_surf;
++
++ dri2_surf->dri_drawable =
++ (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
++ dri2_conf->dri_double_config,
++ dri2_surf->gbm_surf);
++ }
++ else {
++ dri2_surf->dri_drawable =
++ (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
++ dri2_conf->dri_double_config,
++ dri2_surf);
++ }
+
+ if (dri2_surf->dri_drawable == NULL) {
+ _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
@@ -370,7 +395,10 @@
+ dri2_surf->dri_buffers[i]);
+ }
+ }
++ free(dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT]);
++ free(dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]);
+
++ free(dri2_surf->gbm_surf);
+ free(surf);
+
+ return EGL_TRUE;
@@ -413,10 +441,56 @@
+ return 0;
+}
+
++static _EGLImage *
++dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
++ EGLClientBuffer buffer, const EGLint *attr_list)
++{
++ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
++ struct gbm_dri_bo *dri_bo = gbm_dri_bo((struct gbm_bo *) buffer);
++ struct dri2_egl_image *dri2_img;
++
++ dri2_img = malloc(sizeof *dri2_img);
++ if (!dri2_img) {
++ _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr_pixmap");
++ return NULL;
++ }
++
++ if (!_eglInitImage(&dri2_img->base, disp)) {
++ free(dri2_img);
++ return NULL;
++ }
++
++
++ dri2_img->dri_image = dri2_dpy->image->dupImage(dri_bo->image, dri2_img);
++ if (dri2_img->dri_image == NULL) {
++ free(dri2_img);
++ _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr_pixmap");
++ return NULL;
++ }
++
++ return &dri2_img->base;
++}
++
++static _EGLImage *
++dri2_mir_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
++ _EGLContext *ctx, EGLenum target,
++ EGLClientBuffer buffer, const EGLint *attr_list)
++{
++ (void) drv;
++
++ switch (target) {
++ case EGL_NATIVE_PIXMAP_KHR:
++ return dri2_create_image_khr_pixmap(disp, ctx, buffer, attr_list);
++ default:
++ return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list);
++ }
++}
++
+EGLBoolean
+dri2_initialize_mir(_EGLDriver *drv, _EGLDisplay *disp)
+{
+ struct dri2_egl_display *dri2_dpy;
++ struct gbm_device *gbm = NULL;
+ MirPlatformPackage platform;
+ const __DRIconfig *config;
+ static const unsigned int argb_masks[4] =
@@ -431,8 +505,8 @@
+/* drv->API.CreatePixmapSurface = dri2_create_pixmap_surface;
+ drv->API.CreatePbufferSurface = dri2_create_pbuffer_surface;
+ drv->API.CopyBuffers = dri2_copy_buffers;
-+ drv->API.CreateImageKHR = dri2_x11_create_image_khr;
+*/
++ drv->API.CreateImageKHR = dri2_mir_create_image_khr;
+
+ dri2_dpy = calloc(1, sizeof *dri2_dpy);
+ if (!dri2_dpy)
@@ -442,30 +516,44 @@
+ dri2_dpy->mir_disp = disp->PlatformDisplay;
+ dri2_dpy->mir_disp->display_get_platform(dri2_dpy->mir_disp, &platform);
+ dri2_dpy->fd = platform.fd[0];
-+ dri2_dpy->driver_name = dri2_get_driver_for_fd(dri2_dpy->fd);
+ dri2_dpy->device_name = dri2_get_device_name_for_fd(dri2_dpy->fd);
+
-+ if (dri2_dpy->driver_name == NULL ||
-+ dri2_dpy->device_name == NULL)
-+ goto cleanup_dpy;
++ /*
++ * At the moment, a pointer to gbm_device is the first and only
++ * information optionally contained in platform.data[].
++ */
++ if (platform.data_items == 0) {
++ dri2_dpy->own_device = 1;
++ dri2_dpy->fd = dup(dri2_dpy->fd);
++ gbm = gbm_create_device(dri2_dpy->fd);
++ if (gbm == NULL)
++ goto cleanup_dpy;
++ }
++ else {
++ gbm = *(struct gbm_device**)platform.data;
++ }
++
++ if (gbm) {
++ struct gbm_dri_device *gbm_dri = gbm_dri_device(gbm);
+
-+ if (!dri2_load_driver(disp))
-+ goto cleanup_dpy;
++ dri2_dpy->gbm_dri = gbm_dri;
++ dri2_dpy->driver_name = gbm_dri->base.driver_name;
++ dri2_dpy->dri_screen = gbm_dri->screen;
++ dri2_dpy->core = gbm_dri->core;
++ dri2_dpy->dri2 = gbm_dri->dri2;
++ dri2_dpy->image = gbm_dri->image;
++ dri2_dpy->flush = gbm_dri->flush;
++ dri2_dpy->driver_configs = gbm_dri->driver_configs;
+
-+ dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER;
-+ dri2_dpy->dri2_loader_extension.base.version = 4;
-+ dri2_dpy->dri2_loader_extension.getBuffers = dri2_get_buffers;
-+ dri2_dpy->dri2_loader_extension.flushFrontBuffer = dri2_flush_front_buffer;
-+ dri2_dpy->dri2_loader_extension.getBuffersWithFormat =
-+ dri2_get_buffers_with_format;
++ gbm_dri->lookup_image = dri2_lookup_egl_image;
++ gbm_dri->lookup_user_data = disp;
+
-+ dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base;
-+ dri2_dpy->extensions[1] = &image_lookup_extension.base;
-+ dri2_dpy->extensions[2] = &use_invalidate.base;
-+ dri2_dpy->extensions[3] = NULL;
++ gbm_dri->get_buffers = dri2_get_buffers;
++ gbm_dri->flush_front_buffer = dri2_flush_front_buffer;
++ gbm_dri->get_buffers_with_format = dri2_get_buffers_with_format;
+
-+ if (!dri2_create_screen(disp))
-+ goto cleanup_dpy;
++ dri2_setup_screen(disp);
++ }
+
+ types = EGL_WINDOW_BIT;
+ for (i = 0; dri2_dpy->driver_configs[i]; i++) {
@@ -757,23 +845,24 @@
DBG("ref name 0x%08x failed", whandle->handle);
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
-@@ -86,7 +86,18 @@
+@@ -85,8 +85,19 @@
+ struct nouveau_device *dev = nouveau_screen(pscreen)->device;
struct nouveau_bo *bo = 0;
int ret;
-
-- ret = nouveau_bo_name_ref(dev, whandle->handle, &bo);
++
+ if (whandle->type != DRM_API_HANDLE_TYPE_SHARED &&
+ whandle->type != DRM_API_HANDLE_TYPE_FD) {
+ debug_printf("%s: attempt to import unsupported handle type %d\n",
+ __FUNCTION__, whandle->type);
-+ return NULL;
++ return NULL;
+ }
+
+ if (whandle->type == DRM_API_HANDLE_TYPE_SHARED)
+ ret = nouveau_bo_name_ref(dev, whandle->handle, &bo);
+ else
+ ret = nouveau_bo_prime_handle_ref(dev, whandle->handle, &bo);
-+
+
+- ret = nouveau_bo_name_ref(dev, whandle->handle, &bo);
if (ret) {
debug_printf("%s: ref name 0x%08x failed with %d\n",
__FUNCTION__, whandle->handle, ret);
@@ -811,9 +900,28 @@
*/
unsigned type;
/**
+@@ -42,6 +45,8 @@
+ enum drm_conf {
+ /* How many frames to allow before throttling. Or -1 to indicate any number */
+ DRM_CONF_THROTTLE, /* DRM_CONF_INT. */
++ /* Can this driver, running on this kernel, import and export dma-buf fds? */
++ DRM_CONF_SHARE_FD, /* DRM_CONF_BOOL. */
+ DRM_CONF_MAX
+ };
+
--- a/src/gallium/state_trackers/dri/drm/dri2.c
+++ b/src/gallium/state_trackers/dri/drm/dri2.c
-@@ -262,7 +262,13 @@
+@@ -33,6 +33,9 @@
+ #include "util/u_format.h"
+ #include "util/u_debug.h"
+ #include "state_tracker/drm_driver.h"
++#include "state_tracker/st_texture.h"
++#include "state_tracker/st_context.h"
++#include "main/texobj.h"
+
+ #include "dri_screen.h"
+ #include "dri_context.h"
+@@ -262,7 +265,13 @@
templ.format = format;
templ.bind = bind;
@@ -828,7 +936,7 @@
whandle.stride = buf->pitch;
drawable->textures[statt] =
-@@ -526,14 +532,14 @@
+@@ -526,14 +535,14 @@
}
static __DRIimage *
@@ -847,7 +955,7 @@
unsigned tex_usage;
enum pipe_format pf;
-@@ -573,12 +579,10 @@
+@@ -573,12 +582,10 @@
templ.depth0 = 1;
templ.array_size = 1;
@@ -862,7 +970,7 @@
if (!img->texture) {
FREE(img);
return NULL;
-@@ -593,6 +597,39 @@
+@@ -593,6 +600,39 @@
}
static __DRIimage *
@@ -902,7 +1010,7 @@
dri2_create_image_from_renderbuffer(__DRIcontext *context,
int renderbuffer, void *loaderPrivate)
{
-@@ -686,6 +723,7 @@
+@@ -686,6 +726,7 @@
switch (attrib) {
case __DRI_IMAGE_ATTRIB_STRIDE:
@@ -910,7 +1018,7 @@
image->texture->screen->resource_get_handle(image->texture->screen,
image->texture, &whandle);
*value = whandle.stride;
-@@ -702,6 +740,11 @@
+@@ -702,6 +743,12 @@
image->texture, &whandle);
*value = whandle.handle;
return GL_TRUE;
@@ -919,10 +1027,11 @@
+ image->texture->screen->resource_get_handle(image->texture->screen,
+ image->texture, &whandle);
+ *value = whandle.handle;
++ return GL_TRUE;
case __DRI_IMAGE_ATTRIB_FORMAT:
*value = image->dri_format;
return GL_TRUE;
-@@ -825,6 +868,67 @@
+@@ -825,6 +872,122 @@
return img;
}
@@ -931,9 +1040,65 @@
+ int depth, int level, unsigned *error,
+ void *loaderPrivate)
+{
-+ /* Bad parameter seems like the least-incorrect error */
-+ *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
-+ return NULL;
++ __DRIimage *img;
++ struct gl_context *ctx = ((struct st_context *)dri_context(context)->st)->ctx;
++ struct gl_texture_object *obj;
++ struct pipe_resource *tex;
++ GLuint face = 0;
++
++ obj = _mesa_lookup_texture(ctx, texture);
++ if (!obj || obj->Target != target) {
++ *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
++ return NULL;
++ }
++
++ tex = st_get_texobj_resource(obj);
++ if (!tex) {
++ *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
++ return NULL;
++ }
++
++ if (target == GL_TEXTURE_CUBE_MAP)
++ face = depth;
++
++ _mesa_test_texobj_completeness(ctx, obj);
++ if (!obj->_BaseComplete || (level > 0 && !obj->_MipmapComplete)) {
++ *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
++ return NULL;
++ }
++
++ if (level < obj->BaseLevel || level > obj->_MaxLevel) {
++ *error = __DRI_IMAGE_ERROR_BAD_MATCH;
++ return NULL;
++ }
++
++ if (target == GL_TEXTURE_3D && obj->Image[face][level]->Depth < depth) {
++ *error = __DRI_IMAGE_ERROR_BAD_MATCH;
++ return NULL;
++ }
++
++ img = CALLOC_STRUCT(__DRIimageRec);
++ if (!img) {
++ *error = __DRI_IMAGE_ERROR_BAD_ALLOC;
++ return NULL;
++ }
++
++ img->level = level;
++ img->layer = depth;
++ img->dri_format = driGLFormatToImageFormat(obj->Image[face][level]->TexFormat);
++
++ img->loader_private = loaderPrivate;
++
++ if (img->dri_format == __DRI_IMAGE_FORMAT_NONE) {
++ *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
++ free(img);
++ return NULL;
++ }
++
++ pipe_resource_reference(&img->texture, tex);
++
++ *error = __DRI_IMAGE_ERROR_SUCCESS;
++ return img;
+}
+
+static __DRIimage *
@@ -986,28 +1151,57 @@
+ return img;
+}
+
-+
static void
dri2_destroy_image(__DRIimage *img)
{
-@@ -833,7 +937,7 @@
+@@ -833,7 +996,7 @@
}
static struct __DRIimageExtensionRec dri2ImageExtension = {
- { __DRI_IMAGE, 5 },
-+ { __DRI_IMAGE, 7 },
++ { __DRI_IMAGE, 6 },
dri2_create_image_from_name,
dri2_create_image_from_renderbuffer,
dri2_destroy_image,
-@@ -843,6 +947,8 @@
+@@ -843,6 +1006,7 @@
dri2_validate_usage,
dri2_from_names,
dri2_from_planar,
+ dri2_create_from_texture,
-+ dri2_from_fds,
};
/*
+@@ -870,6 +1034,7 @@
+ struct dri_screen *screen;
+ struct pipe_screen *pscreen;
+ const struct drm_conf_ret *throttle_ret = NULL;
++ const struct drm_conf_ret *dmabuf_ret = NULL;
+
+ screen = CALLOC_STRUCT(dri_screen);
+ if (!screen)
+@@ -881,14 +1046,21 @@
+ sPriv->driverPrivate = (void *)screen;
+
+ pscreen = driver_descriptor.create_screen(screen->fd);
+- if (driver_descriptor.configuration)
++ if (driver_descriptor.configuration) {
+ throttle_ret = driver_descriptor.configuration(DRM_CONF_THROTTLE);
++ dmabuf_ret = driver_descriptor.configuration(DRM_CONF_SHARE_FD);
++ }
+
+ if (throttle_ret && throttle_ret->val.val_int != -1) {
+ screen->throttling_enabled = TRUE;
+ screen->default_throttle_frames = throttle_ret->val.val_int;
+ }
+
++ if (dmabuf_ret && dmabuf_ret->val.val_bool) {
++ dri2ImageExtension.base.version = 7;
++ dri2ImageExtension.createImageFromFds = dri2_from_fds;
++ }
++
+ sPriv->extensions = dri_screen_extensions;
+
+ /* dri_init_screen_helper checks pscreen for us */
--- a/src/gallium/state_trackers/egl/common/native_helper.c
+++ b/src/gallium/state_trackers/egl/common/native_helper.c
@@ -427,6 +427,7 @@
@@ -1028,6 +1222,82 @@
whandle.stride = xbuf->pitch;
whandle.handle = xbuf->name;
dri2surf->textures[natt] = dri2dpy->base.screen->resource_from_handle(
+--- a/src/gallium/targets/dri-ilo/target.c
++++ b/src/gallium/targets/dri-ilo/target.c
+@@ -24,4 +24,21 @@
+ return screen;
+ }
+
+-DRM_DRIVER_DESCRIPTOR("i965", "i915", create_screen, NULL)
++
++static const struct drm_conf_ret share_fd_ret = {
++ .type = DRM_CONF_BOOL,
++ .val.val_int = true,
++};
++
++static const struct drm_conf_ret *drm_configuration(enum drm_conf conf)
++{
++ switch (conf) {
++ case DRM_CONF_SHARE_FD:
++ return &share_fd_ret;
++ default:
++ break;
++ }
++ return NULL;
++}
++
++DRM_DRIVER_DESCRIPTOR("i965", "i915", create_screen, drm_configuration)
+--- a/src/gallium/targets/dri-nouveau/target.c
++++ b/src/gallium/targets/dri-nouveau/target.c
+@@ -17,4 +17,20 @@
+ return screen;
+ }
+
+-DRM_DRIVER_DESCRIPTOR("nouveau", "nouveau", create_screen, NULL)
++static const struct drm_conf_ret share_fd_ret = {
++ .type = DRM_CONF_BOOL,
++ .val.val_int = true,
++};
++
++static const struct drm_conf_ret *drm_configuration(enum drm_conf conf)
++{
++ switch (conf) {
++ case DRM_CONF_SHARE_FD:
++ return &share_fd_ret;
++ default:
++ break;
++ }
++ return NULL;
++}
++
++DRM_DRIVER_DESCRIPTOR("nouveau", "nouveau", create_screen, drm_configuration)
+--- a/src/gallium/targets/dri-vmwgfx/target.c
++++ b/src/gallium/targets/dri-vmwgfx/target.c
+@@ -31,11 +31,24 @@
+ .val.val_int = 2,
+ };
+
++/* Technically this requires kernel support that is not yet
++ * widespread.
++ *
++ * We could check for support in create_screen and return the correct
++ * value, but for now just return true in all cases.
++ */
++static const struct drm_conf_ret share_fd_ret = {
++ .type = DRM_CONF_BOOL,
++ .val.val_int = true,
++};
++
+ static const struct drm_conf_ret *drm_configuration(enum drm_conf conf)
+ {
+ switch (conf) {
+ case DRM_CONF_THROTTLE:
+ return &throttle_ret;
++ case DRM_CONF_SHARE_FD:
++ return &share_fd_ret;
+ default:
+ break;
+ }
--- a/src/gallium/winsys/i915/drm/i915_drm_buffer.c
+++ b/src/gallium/winsys/i915/drm/i915_drm_buffer.c
@@ -95,9 +95,13 @@
@@ -1063,22 +1333,6 @@
default:
bo = NULL;
break;
-@@ -308,7 +306,6 @@
- case DRM_API_HANDLE_TYPE_KMS:
- handle->handle = ((drm_intel_bo *) bo)->handle;
- break;
--#if 0
- case DRM_API_HANDLE_TYPE_FD:
- {
- int fd;
-@@ -318,7 +315,6 @@
- handle->handle = fd;
- }
- break;
--#endif
- default:
- err = -EINVAL;
- break;
--- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
@@ -40,6 +40,7 @@
@@ -1117,16 +1371,14 @@
if (bo->ptr)
os_munmap(bo->ptr, bo->base.size);
-@@ -660,7 +664,8 @@
+@@ -660,6 +664,7 @@
static void radeon_bomgr_destroy(struct pb_manager *_mgr)
{
struct radeon_bomgr *mgr = radeon_bomgr(_mgr);
-- util_hash_table_destroy(mgr->bo_handles);
+ util_hash_table_destroy(mgr->bo_names);
-+ util_hash_table_destroy(mgr->bo_handles);;
+ util_hash_table_destroy(mgr->bo_handles);
pipe_mutex_destroy(mgr->bo_handles_mutex);
pipe_mutex_destroy(mgr->bo_va_mutex);
- FREE(mgr);
@@ -692,6 +697,7 @@
mgr->base.is_buffer_busy = radeon_bomgr_is_buffer_busy;
@@ -1154,15 +1406,21 @@
return (struct pb_buffer*)buffer;
}
-@@ -874,6 +885,7 @@
+@@ -872,10 +883,10 @@
+ struct radeon_drm_winsys *ws = radeon_drm_winsys(rws);
+ struct radeon_bo *bo;
struct radeon_bomgr *mgr = radeon_bomgr(ws->kman);
- struct drm_gem_open open_arg = {};
+- struct drm_gem_open open_arg = {};
++ struct drm_radeon_gem_busy args;
int r;
-+ unsigned handle, size;
-
- memset(&open_arg, 0, sizeof(open_arg));
+-
+- memset(&open_arg, 0, sizeof(open_arg));
++ unsigned handle;
++ uint64_t size;
-@@ -885,8 +897,20 @@
+ /* We must maintain a list of pairs <handle, bo>, so that we always return
+ * the same BO for one particular handle. If we didn't do that and created
+@@ -885,8 +896,20 @@
* The list of pairs is guarded by a mutex, of course. */
pipe_mutex_lock(mgr->bo_handles_mutex);
@@ -1185,7 +1443,7 @@
if (bo) {
/* Increase the refcount. */
struct pb_buffer *b = NULL;
-@@ -900,27 +924,38 @@
+@@ -900,27 +923,48 @@
goto fail;
}
@@ -1195,6 +1453,8 @@
- FREE(bo);
- goto fail;
+ if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
++ struct drm_gem_open open_arg = {};
++ memset(&open_arg, 0, sizeof(open_arg));
+ /* Open the BO. */
+ open_arg.name = whandle->handle;
+ if (drmIoctl(ws->fd, DRM_IOCTL_GEM_OPEN, &open_arg)) {
@@ -1205,8 +1465,16 @@
+ size = open_arg.size;
+ bo->name = whandle->handle;
+ } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
-+ /* Oh, oh! What to do here? */
-+ size = 0;
++ size = lseek(whandle->handle, 0, SEEK_END);
++ /*
++ * Could check errno to determine whether the kernel is new enough, but
++ * it doesn't really matter why this failed, just that it failed.
++ */
++ if (size == (off_t)-1) {
++ FREE(bo);
++ goto fail;
++ }
++ lseek(whandle->handle, 0, SEEK_SET);
}
- bo->handle = open_arg.handle;
- bo->name = whandle->handle;
@@ -1218,7 +1486,7 @@
bo->base.alignment = 0;
bo->base.usage = PB_USAGE_GPU_WRITE | PB_USAGE_GPU_READ;
- bo->base.size = open_arg.size;
-+ bo->base.size = size;
++ bo->base.size = (unsigned) size;
bo->base.vtbl = &radeon_bo_vtbl;
bo->mgr = mgr;
bo->rws = mgr->rws;
@@ -1233,17 +1501,46 @@
done:
pipe_mutex_unlock(mgr->bo_handles_mutex);
-@@ -958,6 +993,9 @@
- ws->allocated_vram += align(open_arg.size, 4096);
- bo->initial_domain = RADEON_DOMAIN_VRAM;
+@@ -931,7 +975,7 @@
+ if (mgr->va && !bo->va) {
+ struct drm_radeon_gem_va va;
-+ if (whandle->type == DRM_API_HANDLE_TYPE_FD)
-+ bo->initial_domain = RADEON_DOMAIN_GTT;
+- bo->va_size = ((bo->base.size + 4095) & ~4095);
++ bo->va_size = ((size + 4095) & ~4095);
+ bo->va = radeon_bomgr_find_va(mgr, bo->va_size, 1 << 20);
+
+ va.handle = bo->handle;
+@@ -955,8 +999,27 @@
+ }
+ }
+
+- ws->allocated_vram += align(open_arg.size, 4096);
+- bo->initial_domain = RADEON_DOMAIN_VRAM;
++ memset(&args, 0, sizeof(args));
++
++ args.handle = bo->handle;
++ r = drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_BUSY, &args, sizeof(args));
++ /* We don't mind if the bo is busy; we're just after the memory domain */
++ if (r && r != -EBUSY) {
++ fprintf(stderr, "radeon: Failed to find initial domain for imported bo\n");
++ radeon_bo_destroy(&bo->base);
++ return NULL;
++ }
++ bo->initial_domain = args.domain;
++
++ switch (bo->initial_domain) {
++ case RADEON_DOMAIN_GTT:
++ ws->allocated_gtt += align(size, 4096);
++ break;
++ case RADEON_DOMAIN_VRAM:
++ ws->allocated_vram += align(size, 4096);
++ break;
++ }
+
+
return (struct pb_buffer*)bo;
- fail:
-@@ -986,12 +1024,15 @@
+@@ -986,12 +1049,15 @@
bo->flink = flink.name;
pipe_mutex_lock(bo->mgr->bo_handles_mutex);
@@ -1262,19 +1559,144 @@
whandle->stride = stride;
--- a/src/gallium/winsys/svga/drm/vmw_screen_dri.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_dri.c
-@@ -163,6 +163,12 @@
+@@ -40,6 +40,7 @@
+ #include <xf86drm.h>
+
+ #include <stdio.h>
++#include <fcntl.h>
+
+ struct dri1_api_version {
+ int major;
+@@ -160,31 +161,57 @@
+ union drm_vmw_surface_reference_arg arg;
+ struct drm_vmw_surface_arg *req = &arg.req;
+ struct drm_vmw_surface_create_req *rep = &arg.rep;
++ uint32_t handle = 0;
int ret;
int i;
-+ if (whandle->type != DRM_API_HANDLE_TYPE_SHARED) {
-+ vmw_error("Attempt to import unknown handle type %d\n",
-+ whandle->type);
-+ return NULL;
+- /**
+- * The vmware device specific handle is the hardware SID.
+- * FIXME: We probably want to move this to the ioctl implementations.
+- */
++ switch (whandle->type) {
++ case DRM_API_HANDLE_TYPE_SHARED:
++ case DRM_API_HANDLE_TYPE_KMS:
++ handle = whandle->handle;
++ break;
++ case DRM_API_HANDLE_TYPE_FD:
++ ret = drmPrimeFDToHandle(vws->ioctl.drm_fd, whandle->handle,
++ &handle);
++ if (ret) {
++ vmw_error("Failed to get handle from prime fd %d.\n",
++ (int) whandle->handle);
++ return NULL;
++ }
++ break;
++ default:
++ vmw_error("Attempt to import unsupported handle type %d.\n",
++ whandle->type);
++ return NULL;
++ }
+
+ memset(&arg, 0, sizeof(arg));
+- req->sid = whandle->handle;
++ req->sid = handle;
+
+ ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_REF_SURFACE,
+ &arg, sizeof(arg));
+
++ /*
++ * Need to close the handle we got from prime.
++ */
++ if (whandle->type == DRM_API_HANDLE_TYPE_FD)
++ vmw_ioctl_surface_destroy(vws, handle);
++
+ if (ret) {
+- vmw_error("Failed referencing shared surface. SID %d.\n"
+- "Error %d (%s).\n",
+- whandle->handle, ret, strerror(-ret));
+- return NULL;
++ /*
++ * Any attempt to share something other than a surface, like a dumb
++ * kms buffer, should fail here.
++ */
++ vmw_error("Failed referencing shared surface. SID %d.\n"
++ "Error %d (%s).\n",
++ handle, ret, strerror(-ret));
++ return NULL;
+ }
+
+ if (rep->mip_levels[0] != 1) {
+ vmw_error("Incorrect number of mipmap levels on shared surface."
+ " SID %d, levels %d\n",
+- whandle->handle, rep->mip_levels[0]);
++ handle, rep->mip_levels[0]);
+ goto out_mip;
+ }
+
+@@ -192,7 +219,7 @@
+ if (rep->mip_levels[i] != 0) {
+ vmw_error("Incorrect number of faces levels on shared surface."
+ " SID %d, face %d present.\n",
+- whandle->handle, i);
++ handle, i);
+ goto out_mip;
+ }
+ }
+@@ -204,14 +231,15 @@
+ pipe_reference_init(&vsrf->refcnt, 1);
+ p_atomic_set(&vsrf->validated, 0);
+ vsrf->screen = vws;
+- vsrf->sid = whandle->handle;
++ vsrf->sid = handle;
+ ssrf = svga_winsys_surface(vsrf);
+ *format = rep->format;
+
+ return ssrf;
+
+ out_mip:
+- vmw_ioctl_surface_destroy(vws, whandle->handle);
++ vmw_ioctl_surface_destroy(vws, handle);
++
+ return NULL;
+ }
+
+@@ -221,7 +249,9 @@
+ unsigned stride,
+ struct winsys_handle *whandle)
+ {
++ struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
+ struct vmw_svga_winsys_surface *vsrf;
++ int ret;
+
+ if (!surface)
+ return FALSE;
+@@ -230,5 +260,24 @@
+ whandle->handle = vsrf->sid;
+ whandle->stride = stride;
+
++ switch (whandle->type) {
++ case DRM_API_HANDLE_TYPE_SHARED:
++ case DRM_API_HANDLE_TYPE_KMS:
++ whandle->handle = vsrf->sid;
++ break;
++ case DRM_API_HANDLE_TYPE_FD:
++ ret = drmPrimeHandleToFD(vws->ioctl.drm_fd, vsrf->sid, DRM_CLOEXEC,
++ (int *)&whandle->handle);
++ if (ret) {
++ vmw_error("Failed to get file descriptor from prime.\n");
++ return FALSE;
++ }
++ break;
++ default:
++ vmw_error("Attempt to export unsupported handle type %d.\n",
++ whandle->type);
++ return FALSE;
+ }
+
- /**
- * The vmware device specific handle is the hardware SID.
- * FIXME: We probably want to move this to the ioctl implementations.
+ return TRUE;
+ }
--- a/src/gbm/backends/dri/gbm_dri.c
+++ b/src/gbm/backends/dri/gbm_dri.c
@@ -44,6 +44,8 @@
@@ -1286,6 +1708,15 @@
/* For importing wl_buffer */
#if HAVE_WAYLAND_PLATFORM
+@@ -132,7 +134,7 @@
+ };
+
+ static const __DRIdri2LoaderExtension dri2_loader_extension = {
+- { __DRI_DRI2_LOADER, 3 },
++ { __DRI_DRI2_LOADER, 4 },
+ dri_get_buffers,
+ dri_flush_front_buffer,
+ dri_get_buffers_with_format,
@@ -327,9 +329,11 @@
switch (format) {
case GBM_BO_FORMAT_XRGB8888:
@@ -1298,35 +1729,17 @@
if (usage & GBM_BO_USE_SCANOUT)
return 0;
break;
-@@ -364,9 +368,9 @@
- struct gbm_dri_bo *bo = gbm_dri_bo(_bo);
- struct drm_mode_destroy_dumb arg;
-
-- if (bo->image != NULL) {
-+ if (bo->image)
- dri->image->destroyImage(bo->image);
-- } else {
-+ if (bo->map) {
- munmap(bo->map, bo->size);
- memset(&arg, 0, sizeof(arg));
- arg.handle = bo->handle;
-@@ -394,6 +398,15 @@
+@@ -394,6 +398,9 @@
case __DRI_IMAGE_FORMAT_ABGR8888:
ret = GBM_FORMAT_ABGR8888;
break;
+ case __DRI_IMAGE_FORMAT_XBGR8888:
+ ret = GBM_FORMAT_XBGR8888;
+ break;
-+ case __DRI_IMAGE_FORMAT_ARGB2101010:
-+ ret = GBM_FORMAT_ARGB2101010;
-+ break;
-+ case __DRI_IMAGE_FORMAT_XRGB2101010:
-+ ret = GBM_FORMAT_XRGB2101010;
-+ break;
default:
ret = 0;
break;
-@@ -402,6 +415,43 @@
+@@ -402,6 +409,41 @@
return ret;
}
@@ -1350,18 +1763,16 @@
+ case GBM_FORMAT_ABGR8888:
+ dri_format = __DRI_IMAGE_FORMAT_ABGR8888;
+ break;
-+ case GBM_FORMAT_XBGR8888:
-+ dri_format = __DRI_IMAGE_FORMAT_XBGR8888;
-+ break;
+ case GBM_FORMAT_ARGB2101010:
+ dri_format = __DRI_IMAGE_FORMAT_ARGB2101010;
+ break;
+ case GBM_FORMAT_XRGB2101010:
+ dri_format = __DRI_IMAGE_FORMAT_XRGB2101010;
++ case GBM_FORMAT_XBGR8888:
++ dri_format = __DRI_IMAGE_FORMAT_XBGR8888;
+ break;
+ default:
+ dri_format = __DRI_IMAGE_FORMAT_NONE;
-+ break;
+ }
+
+ return dri_format;
@@ -1370,53 +1781,7 @@
static struct gbm_bo *
gbm_dri_bo_import(struct gbm_device *gbm,
uint32_t type, void *buffer, uint32_t usage)
-@@ -513,9 +563,8 @@
- struct drm_mode_destroy_dumb destroy_arg;
- int ret;
-
-- if (!(usage & GBM_BO_USE_CURSOR_64X64))
-- return NULL;
-- if (format != GBM_FORMAT_ARGB8888)
-+ if ((format != GBM_FORMAT_ARGB8888) &&
-+ (format != GBM_FORMAT_XRGB8888))
- return NULL;
-
- bo = calloc(1, sizeof *bo);
-@@ -530,6 +579,7 @@
- if (ret)
- goto free_bo;
-
-+ bo->base.base.format = format;
- bo->base.base.gbm = gbm;
- bo->base.base.width = width;
- bo->base.base.height = height;
-@@ -551,6 +601,25 @@
- if (bo->map == MAP_FAILED)
- goto destroy_dumb;
-
-+ if (usage & GBM_BO_USE_RENDERING)
-+ {
-+ struct drm_gem_flink flink_arg;
-+ memset(&flink_arg, 0, sizeof(flink_arg));
-+ flink_arg.handle = bo->handle;
Reply to: