gbm: Explicitly disallow a planar dumb BO
[mesa.git] / src / gbm / backends / dri / gbm_dri.c
index e7c0e8941b5f4da25b352d80d42294972a268c3d..3faa19e3f19312bb7536dd54766000c0757a3b16 100644 (file)
@@ -29,6 +29,7 @@
 #include <stdlib.h>
 #include <stddef.h>
 #include <stdint.h>
+#include <stdbool.h>
 #include <string.h>
 #include <errno.h>
 #include <limits.h>
@@ -245,7 +246,8 @@ struct dri_extension_match {
 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 },
+   { __DRI2_FENCE, 1, offsetof(struct gbm_dri_device, fence), 1 },
+   { __DRI2_INTEROP, 1, offsetof(struct gbm_dri_device, interop), 1 },
    { NULL, 0, 0 }
 };
 
@@ -362,8 +364,8 @@ dri_open_driver(struct gbm_dri_device *dri)
       return NULL;
    }
 
-   if (asprintf(&get_extensions_name, "%s_%s",
-                __DRI_DRIVER_GET_EXTENSIONS, dri->base.driver_name) != -1) {
+   get_extensions_name = loader_get_extensions_name(dri->base.driver_name);
+   if (get_extensions_name) {
       const __DRIextension **(*get_extensions)(void);
 
       get_extensions = dlsym(dri->driver, get_extensions_name);
@@ -516,7 +518,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;
 
@@ -694,6 +696,7 @@ gbm_dri_bo_import(struct gbm_device *gbm,
          gbm_format = GBM_FORMAT_YUYV;
          break;
       default:
+         dri->image->destroyImage(image);
          return NULL;
       }
       break;
@@ -714,6 +717,7 @@ gbm_dri_bo_import(struct gbm_device *gbm,
       gbm_format = gbm_dri_to_gbm_format(dri_format);
       if (gbm_format == 0) {
          errno = EINVAL;
+         dri->image->destroyImage(image);
          return NULL;
       }
       break;
@@ -758,8 +762,10 @@ gbm_dri_bo_import(struct gbm_device *gbm,
 
 
    bo = calloc(1, sizeof *bo);
-   if (bo == NULL)
+   if (bo == NULL) {
+      dri->image->destroyImage(image);
       return NULL;
+   }
 
    bo->image = image;
 
@@ -770,6 +776,7 @@ gbm_dri_bo_import(struct gbm_device *gbm,
    if (dri->image->base.version >= 2 &&
        !dri->image->validateUsage(bo->image, dri_use)) {
       errno = EINVAL;
+      dri->image->destroyImage(bo->image);
       free(bo);
       return NULL;
    }
@@ -789,6 +796,31 @@ gbm_dri_bo_import(struct gbm_device *gbm,
    return &bo->base.base;
 }
 
+static bool
+is_planar_format(uint32_t format)
+{
+   switch (format) {
+   case GBM_FORMAT_NV12:
+   case GBM_FORMAT_NV21:
+   case GBM_FORMAT_NV16:
+   case GBM_FORMAT_NV61:
+   case GBM_FORMAT_YUV410:
+   case GBM_FORMAT_YVU410:
+   case GBM_FORMAT_YUV411:
+   case GBM_FORMAT_YVU411:
+   case GBM_FORMAT_YUV420:
+   case GBM_FORMAT_YVU420:
+   case GBM_FORMAT_YUV422:
+   case GBM_FORMAT_YVU422:
+   case GBM_FORMAT_YUV444:
+   case GBM_FORMAT_YVU444:
+      return true;
+   default:
+      return false;
+   }
+
+}
+
 static struct gbm_bo *
 create_dumb(struct gbm_device *gbm,
                   uint32_t width, uint32_t height,
@@ -810,6 +842,11 @@ create_dumb(struct gbm_device *gbm,
       return NULL;
    }
 
+   if (is_planar_format(format)) {
+      errno = EINVAL;
+      return NULL;
+   }
+
    bo = calloc(1, sizeof *bo);
    if (bo == NULL)
       return NULL;