[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: