loader: remove loader_get_driver_for_fd() driver_type
[mesa.git] / src / gbm / backends / dri / gbm_dri.c
index 51d51dde3d0755f50ab6f175de8d5229c8c637bf..51c4117ba70f50c0fdb7c227c592da6c47b0ca4a 100644 (file)
@@ -32,6 +32,7 @@
 #include <string.h>
 #include <errno.h>
 #include <limits.h>
+#include <assert.h>
 
 #include <sys/types.h>
 #include <unistd.h>
@@ -238,11 +239,13 @@ struct dri_extension_match {
    const char *name;
    int version;
    int offset;
+   int optional;
 };
 
 static struct dri_extension_match dri_core_extensions[] = {
    { __DRI2_FLUSH, 1, offsetof(struct gbm_dri_device, flush) },
    { __DRI_IMAGE, 1, offsetof(struct gbm_dri_device, image) },
+   { __DRI2_FENCE, 2, offsetof(struct gbm_dri_device, fence), 1 },
    { NULL, 0, 0 }
 };
 
@@ -278,7 +281,7 @@ dri_bind_extensions(struct gbm_dri_device *dri,
 
    for (j = 0; matches[j].name; j++) {
       field = ((char *) dri + matches[j].offset);
-      if (*(const __DRIextension **) field == NULL) {
+      if ((*(const __DRIextension **) field == NULL) && !matches[j].optional) {
          ret = -1;
       }
    }
@@ -436,19 +439,19 @@ dri_screen_create_dri2(struct gbm_dri_device *dri, char *driver_name)
       return ret;
    };
 
-   dri->extensions = gbm_dri_screen_extensions;
+   dri->loader_extensions = gbm_dri_screen_extensions;
 
    if (dri->dri2 == NULL)
       return -1;
 
    if (dri->dri2->base.version >= 4) {
       dri->screen = dri->dri2->createNewScreen2(0, dri->base.base.fd,
-                                                dri->extensions,
+                                                dri->loader_extensions,
                                                 dri->driver_extensions,
                                                 &dri->driver_configs, dri);
    } else {
       dri->screen = dri->dri2->createNewScreen(0, dri->base.base.fd,
-                                               dri->extensions,
+                                               dri->loader_extensions,
                                                &dri->driver_configs, dri);
    }
    if (dri->screen == NULL)
@@ -486,17 +489,17 @@ dri_screen_create_swrast(struct gbm_dri_device *dri)
       return ret;
    }
 
-   dri->extensions = gbm_dri_screen_extensions;
+   dri->loader_extensions = gbm_dri_screen_extensions;
 
    if (dri->swrast == NULL)
       return -1;
 
    if (dri->swrast->base.version >= 4) {
-      dri->screen = dri->swrast->createNewScreen2(0, dri->extensions,
+      dri->screen = dri->swrast->createNewScreen2(0, dri->loader_extensions,
                                                   dri->driver_extensions,
                                                   &dri->driver_configs, dri);
    } else {
-      dri->screen = dri->swrast->createNewScreen(0, dri->extensions,
+      dri->screen = dri->swrast->createNewScreen(0, dri->loader_extensions,
                                                  &dri->driver_configs, dri);
    }
    if (dri->screen == NULL)
@@ -513,7 +516,7 @@ dri_screen_create(struct gbm_dri_device *dri)
 {
    char *driver_name;
 
-   driver_name = loader_get_driver_for_fd(dri->base.base.fd, 0);
+   driver_name = loader_get_driver_for_fd(dri->base.base.fd);
    if (!driver_name)
       return -1;
 
@@ -588,7 +591,8 @@ gbm_dri_bo_get_fd(struct gbm_bo *_bo)
    if (bo->image == NULL)
       return -1;
 
-   dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_FD, &fd);
+   if (!dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_FD, &fd))
+      return -1;
 
    return fd;
 }
@@ -866,8 +870,14 @@ gbm_dri_bo_create(struct gbm_device *gbm,
    bo->base.base.format = format;
 
    switch (format) {
+   case GBM_FORMAT_R8:
+      dri_format = __DRI_IMAGE_FORMAT_R8;
+      break;
+   case GBM_FORMAT_GR88:
+      dri_format = __DRI_IMAGE_FORMAT_GR88;
+      break;
    case GBM_FORMAT_RGB565:
-      dri_format =__DRI_IMAGE_FORMAT_RGB565;
+      dri_format = __DRI_IMAGE_FORMAT_RGB565;
       break;
    case GBM_FORMAT_XRGB8888:
    case GBM_BO_FORMAT_XRGB8888:
@@ -924,6 +934,61 @@ failed:
    return NULL;
 }
 
+static void *
+gbm_dri_bo_map(struct gbm_bo *_bo,
+              uint32_t x, uint32_t y,
+              uint32_t width, uint32_t height,
+              uint32_t flags, uint32_t *stride, void **map_data)
+{
+   struct gbm_dri_device *dri = gbm_dri_device(_bo->gbm);
+   struct gbm_dri_bo *bo = gbm_dri_bo(_bo);
+
+   /* If it's a dumb buffer, we already have a mapping */
+   if (bo->map) {
+      *map_data = (char *)bo->map + (bo->base.base.stride * y) + (x * 4);
+      *stride = bo->base.base.stride;
+      return *map_data;
+   }
+
+   if (!dri->image || dri->image->base.version < 12 || !dri->image->mapImage) {
+      errno = ENOSYS;
+      return NULL;
+   }
+
+   mtx_lock(&dri->mutex);
+   if (!dri->context)
+      dri->context = dri->dri2->createNewContext(dri->screen, NULL,
+                                                 NULL, NULL);
+   assert(dri->context);
+   mtx_unlock(&dri->mutex);
+
+   /* GBM flags and DRI flags are the same, so just pass them on */
+   return dri->image->mapImage(dri->context, bo->image, x, y,
+                               width, height, flags, (int *)stride,
+                               map_data);
+}
+
+static void
+gbm_dri_bo_unmap(struct gbm_bo *_bo, void *map_data)
+{
+   struct gbm_dri_device *dri = gbm_dri_device(_bo->gbm);
+   struct gbm_dri_bo *bo = gbm_dri_bo(_bo);
+
+   /* Check if it's a dumb buffer and check the pointer is in range */
+   if (bo->map) {
+      assert(map_data >= bo->map);
+      assert(map_data < (bo->map + bo->size));
+      return;
+   }
+
+   if (!dri->context || !dri->image ||
+       dri->image->base.version < 12 || !dri->image->unmapImage)
+      return;
+
+   dri->image->unmapImage(dri->context, bo->image, map_data);
+}
+
+
 static struct gbm_surface *
 gbm_dri_surface_create(struct gbm_device *gbm,
                        uint32_t width, uint32_t height,
@@ -958,6 +1023,9 @@ dri_destroy(struct gbm_device *gbm)
    struct gbm_dri_device *dri = gbm_dri_device(gbm);
    unsigned i;
 
+   if (dri->context)
+      dri->core->destroyContext(dri->context);
+
    dri->core->destroyScreen(dri->screen);
    for (i = 0; dri->driver_configs[i]; i++)
       free((__DRIconfig *) dri->driver_configs[i]);
@@ -981,6 +1049,8 @@ dri_device_create(int fd)
    dri->base.base.fd = fd;
    dri->base.base.bo_create = gbm_dri_bo_create;
    dri->base.base.bo_import = gbm_dri_bo_import;
+   dri->base.base.bo_map = gbm_dri_bo_map;
+   dri->base.base.bo_unmap = gbm_dri_bo_unmap;
    dri->base.base.is_format_supported = gbm_dri_is_format_supported;
    dri->base.base.bo_write = gbm_dri_bo_write;
    dri->base.base.bo_get_fd = gbm_dri_bo_get_fd;
@@ -992,6 +1062,8 @@ dri_device_create(int fd)
    dri->base.type = GBM_DRM_DRIVER_TYPE_DRI;
    dri->base.base.name = "drm";
 
+   mtx_init(&dri->mutex, mtx_plain);
+
    force_sw = getenv("GBM_ALWAYS_SOFTWARE") != NULL;
    if (!force_sw) {
       ret = dri_screen_create(dri);