gbm: track buffer format through DRI drivers
authorJesse Barnes <jbarnes@virtuousgeek.org>
Tue, 21 Feb 2012 20:53:09 +0000 (12:53 -0800)
committerJesse Barnes <jbarnes@virtuousgeek.org>
Wed, 22 Feb 2012 17:41:40 +0000 (09:41 -0800)
GBM needs the buffer format in order to communicate with DRM and clients
for things like scanout.

So track the DRI format requested in the various back ends and use it to
return the DRI format back to GBM when requested.  GBM will then map
this into the GBM surface type (which is in turn based on the DRM fb
format list).

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
include/GL/internal/dri_interface.h
src/gallium/state_trackers/dri/common/dri_screen.h
src/gallium/state_trackers/dri/drm/dri2.c
src/gbm/backends/dri/gbm_dri.c
src/gbm/main/gbm.c
src/gbm/main/gbm.h
src/gbm/main/gbmint.h
src/mesa/drivers/dri/intel/intel_regions.h
src/mesa/drivers/dri/intel/intel_screen.c
src/mesa/drivers/dri/radeon/radeon_screen.c
src/mesa/drivers/dri/radeon/radeon_screen.h

index 701e83e7831091b75ad62daa5c23767ae436a6cb..da8366652fe2c505044015faae791fc90aeec59e 100644 (file)
@@ -894,7 +894,7 @@ struct __DRIdri2ExtensionRec {
  * extensions.
  */
 #define __DRI_IMAGE "DRI_IMAGE"
-#define __DRI_IMAGE_VERSION 2
+#define __DRI_IMAGE_VERSION 3
 
 /**
  * These formats correspond to the similarly named MESA_FORMAT_*
@@ -918,6 +918,7 @@ struct __DRIdri2ExtensionRec {
 #define __DRI_IMAGE_ATTRIB_STRIDE      0x2000
 #define __DRI_IMAGE_ATTRIB_HANDLE      0x2001
 #define __DRI_IMAGE_ATTRIB_NAME                0x2002
+#define __DRI_IMAGE_ATTRIB_FORMAT      0x2003 /* available in versions 3+ */
 
 typedef struct __DRIimageRec          __DRIimage;
 typedef struct __DRIimageExtensionRec __DRIimageExtension;
index 8c961955ac9ed35aa5e7181c65b3b98e5556b5ee..2818e9c2683e3dc0a17556c35d98195c513809dc 100644 (file)
@@ -85,6 +85,7 @@ struct __DRIimageRec {
    struct pipe_resource *texture;
    unsigned level;
    unsigned layer;
+   uint32_t dri_format;
 
    void *loader_private;
 };
index 4c08a025ed22d7f5c8e4d8040acf3f55173d6cde..cc8023d02d573c6026cf8aacbbd8e0a5f119c2ec 100644 (file)
@@ -440,6 +440,8 @@ dri2_create_image_from_name(__DRIscreen *_screen,
 
    tex_usage = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
 
+   img->dri_format = format;
+
    switch (format) {
    case __DRI_IMAGE_FORMAT_RGB565:
       pf = PIPE_FORMAT_B5G6R5_UNORM;
@@ -569,6 +571,7 @@ dri2_create_image(__DRIscreen *_screen,
 
    img->level = 0;
    img->layer = 0;
+   img->dri_format = format;
 
    img->loader_private = loaderPrivate;
    return img;
@@ -598,6 +601,9 @@ dri2_query_image(__DRIimage *image, int attrib, int *value)
          image->texture, &whandle);
       *value = whandle.handle;
       return GL_TRUE;
+   case __DRI_IMAGE_ATTRIB_FORMAT:
+      *value = image->dri_format;
+      return GL_TRUE;
    default:
       return GL_FALSE;
    }
index ddd153a7db44056f3d21174a617d8bd6e06c243b..34f07de4bba6ad4400a1405430fd4ad50df4378f 100644 (file)
@@ -216,13 +216,15 @@ free_screen:
 
 static int
 gbm_dri_is_format_supported(struct gbm_device *gbm,
-                            enum gbm_bo_format format,
+                            uint32_t format,
                             uint32_t usage)
 {
    switch (format) {
    case GBM_BO_FORMAT_XRGB8888:
+   case GBM_FORMAT_XRGB8888:
       break;
    case GBM_BO_FORMAT_ARGB8888:
+   case GBM_FORMAT_ARGB8888:
       if (usage & GBM_BO_USE_SCANOUT)
          return 0;
       break;
@@ -247,6 +249,32 @@ gbm_dri_bo_destroy(struct gbm_bo *_bo)
    free(bo);
 }
 
+static uint32_t
+gbm_dri_to_gbm_format(uint32_t dri_format)
+{
+   uint32_t ret = 0;
+
+   switch (dri_format) {
+   case __DRI_IMAGE_FORMAT_RGB565:
+      ret = GBM_FORMAT_RGB565;
+      break;
+   case __DRI_IMAGE_FORMAT_XRGB8888:
+      ret = GBM_FORMAT_XRGB8888;
+      break;
+   case __DRI_IMAGE_FORMAT_ARGB8888:
+      ret = GBM_FORMAT_ARGB8888;
+      break;
+   case __DRI_IMAGE_FORMAT_ABGR8888:
+      ret = GBM_FORMAT_ABGR8888;
+      break;
+   default:
+      ret = 0;
+      break;
+   }
+
+   return ret;
+}
+
 static struct gbm_bo *
 gbm_dri_bo_create_from_egl_image(struct gbm_device *gbm,
                                  void *egl_dpy, void *egl_img,
@@ -255,6 +283,7 @@ gbm_dri_bo_create_from_egl_image(struct gbm_device *gbm,
 {
    struct gbm_dri_device *dri = gbm_dri_device(gbm);
    struct gbm_dri_bo *bo;
+   int dri_format;
    unsigned dri_use = 0;
 
    (void) egl_dpy;
@@ -291,6 +320,10 @@ gbm_dri_bo_create_from_egl_image(struct gbm_device *gbm,
                           &bo->base.base.handle.s32);
    dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE,
                           (int *) &bo->base.base.pitch);
+   dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_FORMAT,
+                         &dri_format);
+
+   bo->base.base.format = gbm_dri_to_gbm_format(dri_format);
 
    return &bo->base.base;
 }
@@ -298,7 +331,7 @@ gbm_dri_bo_create_from_egl_image(struct gbm_device *gbm,
 static struct gbm_bo *
 gbm_dri_bo_create(struct gbm_device *gbm,
                   uint32_t width, uint32_t height,
-                  enum gbm_bo_format format, uint32_t usage)
+                  uint32_t format, uint32_t usage)
 {
    struct gbm_dri_device *dri = gbm_dri_device(gbm);
    struct gbm_dri_bo *bo;
@@ -314,12 +347,20 @@ gbm_dri_bo_create(struct gbm_device *gbm,
    bo->base.base.height = height;
 
    switch (format) {
+   case GBM_FORMAT_RGB565:
+      dri_format =__DRI_IMAGE_FORMAT_RGB565;
+      break;
+   case GBM_FORMAT_XRGB8888:
    case GBM_BO_FORMAT_XRGB8888:
       dri_format = __DRI_IMAGE_FORMAT_XRGB8888;
       break;
+   case GBM_FORMAT_ARGB8888:
    case GBM_BO_FORMAT_ARGB8888:
       dri_format = __DRI_IMAGE_FORMAT_ARGB8888;
       break;
+   case GBM_FORMAT_ABGR8888:
+      dri_format = __DRI_IMAGE_FORMAT_ABGR8888;
+      break;
    default:
       return NULL;
    }
index 03fc52b161ac3d7a427047d21f5025fc7090e697..9459720261f7219af16f442bcad66f23a0576795 100644 (file)
@@ -205,6 +205,19 @@ gbm_bo_get_pitch(struct gbm_bo *bo)
    return bo->pitch;
 }
 
+/** Get the format of the buffer object
+ *
+ * The format of the pixels in the buffer.
+ *
+ * \param bo The buffer object
+ * \return The format of buffer object, on of the GBM_FORMAT_* codes
+ */
+GBM_EXPORT uint32_t
+gbm_bo_get_format(struct gbm_bo *bo)
+{
+   return bo->format;
+}
+
 /** Get the handle of the buffer object
  *
  * This is stored in the platform generic union gbm_bo_handle type. However
index c4ae51db022623f30c3912c9ba17c6c18b41626b..ecebf11f7b9f40842e257c6f829063e8336646c4 100644 (file)
@@ -75,6 +75,108 @@ enum gbm_bo_format {
    GBM_BO_FORMAT_ARGB8888
 };
 
+#define __gbm_fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \
+                             ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
+
+#define GBM_FORMAT_BIG_ENDIAN (1<<31) /* format is big endian instead of little endian */
+
+/* color index */
+#define GBM_FORMAT_C8          __gbm_fourcc_code('C', '8', ' ', ' ') /* [7:0] C */
+
+/* 8 bpp RGB */
+#define GBM_FORMAT_RGB332      __gbm_fourcc_code('R', 'G', 'B', '8') /* [7:0] R:G:B 3:3:2 */
+#define GBM_FORMAT_BGR233      __gbm_fourcc_code('B', 'G', 'R', '8') /* [7:0] B:G:R 2:3:3 */
+
+/* 16 bpp RGB */
+#define GBM_FORMAT_XRGB4444    __gbm_fourcc_code('X', 'R', '1', '2') /* [15:0] x:R:G:B 4:4:4:4 little endian */
+#define GBM_FORMAT_XBGR4444    __gbm_fourcc_code('X', 'B', '1', '2') /* [15:0] x:B:G:R 4:4:4:4 little endian */
+#define GBM_FORMAT_RGBX4444    __gbm_fourcc_code('R', 'X', '1', '2') /* [15:0] R:G:B:x 4:4:4:4 little endian */
+#define GBM_FORMAT_BGRX4444    __gbm_fourcc_code('B', 'X', '1', '2') /* [15:0] B:G:R:x 4:4:4:4 little endian */
+
+#define GBM_FORMAT_ARGB4444    __gbm_fourcc_code('A', 'R', '1', '2') /* [15:0] A:R:G:B 4:4:4:4 little endian */
+#define GBM_FORMAT_ABGR4444    __gbm_fourcc_code('A', 'B', '1', '2') /* [15:0] A:B:G:R 4:4:4:4 little endian */
+#define GBM_FORMAT_RGBA4444    __gbm_fourcc_code('R', 'A', '1', '2') /* [15:0] R:G:B:A 4:4:4:4 little endian */
+#define GBM_FORMAT_BGRA4444    __gbm_fourcc_code('B', 'A', '1', '2') /* [15:0] B:G:R:A 4:4:4:4 little endian */
+
+#define GBM_FORMAT_XRGB1555    __gbm_fourcc_code('X', 'R', '1', '5') /* [15:0] x:R:G:B 1:5:5:5 little endian */
+#define GBM_FORMAT_XBGR1555    __gbm_fourcc_code('X', 'B', '1', '5') /* [15:0] x:B:G:R 1:5:5:5 little endian */
+#define GBM_FORMAT_RGBX5551    __gbm_fourcc_code('R', 'X', '1', '5') /* [15:0] R:G:B:x 5:5:5:1 little endian */
+#define GBM_FORMAT_BGRX5551    __gbm_fourcc_code('B', 'X', '1', '5') /* [15:0] B:G:R:x 5:5:5:1 little endian */
+
+#define GBM_FORMAT_ARGB1555    __gbm_fourcc_code('A', 'R', '1', '5') /* [15:0] A:R:G:B 1:5:5:5 little endian */
+#define GBM_FORMAT_ABGR1555    __gbm_fourcc_code('A', 'B', '1', '5') /* [15:0] A:B:G:R 1:5:5:5 little endian */
+#define GBM_FORMAT_RGBA5551    __gbm_fourcc_code('R', 'A', '1', '5') /* [15:0] R:G:B:A 5:5:5:1 little endian */
+#define GBM_FORMAT_BGRA5551    __gbm_fourcc_code('B', 'A', '1', '5') /* [15:0] B:G:R:A 5:5:5:1 little endian */
+
+#define GBM_FORMAT_RGB565      __gbm_fourcc_code('R', 'G', '1', '6') /* [15:0] R:G:B 5:6:5 little endian */
+#define GBM_FORMAT_BGR565      __gbm_fourcc_code('B', 'G', '1', '6') /* [15:0] B:G:R 5:6:5 little endian */
+
+/* 24 bpp RGB */
+#define GBM_FORMAT_RGB888      __gbm_fourcc_code('R', 'G', '2', '4') /* [23:0] R:G:B little endian */
+#define GBM_FORMAT_BGR888      __gbm_fourcc_code('B', 'G', '2', '4') /* [23:0] B:G:R little endian */
+
+/* 32 bpp RGB */
+#define GBM_FORMAT_XRGB8888    __gbm_fourcc_code('X', 'R', '2', '4') /* [31:0] x:R:G:B 8:8:8:8 little endian */
+#define GBM_FORMAT_XBGR8888    __gbm_fourcc_code('X', 'B', '2', '4') /* [31:0] x:B:G:R 8:8:8:8 little endian */
+#define GBM_FORMAT_RGBX8888    __gbm_fourcc_code('R', 'X', '2', '4') /* [31:0] R:G:B:x 8:8:8:8 little endian */
+#define GBM_FORMAT_BGRX8888    __gbm_fourcc_code('B', 'X', '2', '4') /* [31:0] B:G:R:x 8:8:8:8 little endian */
+
+#define GBM_FORMAT_ARGB8888    __gbm_fourcc_code('A', 'R', '2', '4') /* [31:0] A:R:G:B 8:8:8:8 little endian */
+#define GBM_FORMAT_ABGR8888    __gbm_fourcc_code('A', 'B', '2', '4') /* [31:0] A:B:G:R 8:8:8:8 little endian */
+#define GBM_FORMAT_RGBA8888    __gbm_fourcc_code('R', 'A', '2', '4') /* [31:0] R:G:B:A 8:8:8:8 little endian */
+#define GBM_FORMAT_BGRA8888    __gbm_fourcc_code('B', 'A', '2', '4') /* [31:0] B:G:R:A 8:8:8:8 little endian */
+
+#define GBM_FORMAT_XRGB2101010 __gbm_fourcc_code('X', 'R', '3', '0') /* [31:0] x:R:G:B 2:10:10:10 little endian */
+#define GBM_FORMAT_XBGR2101010 __gbm_fourcc_code('X', 'B', '3', '0') /* [31:0] x:B:G:R 2:10:10:10 little endian */
+#define GBM_FORMAT_RGBX1010102 __gbm_fourcc_code('R', 'X', '3', '0') /* [31:0] R:G:B:x 10:10:10:2 little endian */
+#define GBM_FORMAT_BGRX1010102 __gbm_fourcc_code('B', 'X', '3', '0') /* [31:0] B:G:R:x 10:10:10:2 little endian */
+
+#define GBM_FORMAT_ARGB2101010 __gbm_fourcc_code('A', 'R', '3', '0') /* [31:0] A:R:G:B 2:10:10:10 little endian */
+#define GBM_FORMAT_ABGR2101010 __gbm_fourcc_code('A', 'B', '3', '0') /* [31:0] A:B:G:R 2:10:10:10 little endian */
+#define GBM_FORMAT_RGBA1010102 __gbm_fourcc_code('R', 'A', '3', '0') /* [31:0] R:G:B:A 10:10:10:2 little endian */
+#define GBM_FORMAT_BGRA1010102 __gbm_fourcc_code('B', 'A', '3', '0') /* [31:0] B:G:R:A 10:10:10:2 little endian */
+
+/* packed YCbCr */
+#define GBM_FORMAT_YUYV                __gbm_fourcc_code('Y', 'U', 'Y', 'V') /* [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian */
+#define GBM_FORMAT_YVYU                __gbm_fourcc_code('Y', 'V', 'Y', 'U') /* [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian */
+#define GBM_FORMAT_UYVY                __gbm_fourcc_code('U', 'Y', 'V', 'Y') /* [31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian */
+#define GBM_FORMAT_VYUY                __gbm_fourcc_code('V', 'Y', 'U', 'Y') /* [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian */
+
+#define GBM_FORMAT_AYUV                __gbm_fourcc_code('A', 'Y', 'U', 'V') /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
+
+/*
+ * 2 plane YCbCr
+ * index 0 = Y plane, [7:0] Y
+ * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
+ * or
+ * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
+ */
+#define GBM_FORMAT_NV12                __gbm_fourcc_code('N', 'V', '1', '2') /* 2x2 subsampled Cr:Cb plane */
+#define GBM_FORMAT_NV21                __gbm_fourcc_code('N', 'V', '2', '1') /* 2x2 subsampled Cb:Cr plane */
+#define GBM_FORMAT_NV16                __gbm_fourcc_code('N', 'V', '1', '6') /* 2x1 subsampled Cr:Cb plane */
+#define GBM_FORMAT_NV61                __gbm_fourcc_code('N', 'V', '6', '1') /* 2x1 subsampled Cb:Cr plane */
+
+/*
+ * 3 plane YCbCr
+ * index 0: Y plane, [7:0] Y
+ * index 1: Cb plane, [7:0] Cb
+ * index 2: Cr plane, [7:0] Cr
+ * or
+ * index 1: Cr plane, [7:0] Cr
+ * index 2: Cb plane, [7:0] Cb
+ */
+#define GBM_FORMAT_YUV410      __gbm_fourcc_code('Y', 'U', 'V', '9') /* 4x4 subsampled Cb (1) and Cr (2) planes */
+#define GBM_FORMAT_YVU410      __gbm_fourcc_code('Y', 'V', 'U', '9') /* 4x4 subsampled Cr (1) and Cb (2) planes */
+#define GBM_FORMAT_YUV411      __gbm_fourcc_code('Y', 'U', '1', '1') /* 4x1 subsampled Cb (1) and Cr (2) planes */
+#define GBM_FORMAT_YVU411      __gbm_fourcc_code('Y', 'V', '1', '1') /* 4x1 subsampled Cr (1) and Cb (2) planes */
+#define GBM_FORMAT_YUV420      __gbm_fourcc_code('Y', 'U', '1', '2') /* 2x2 subsampled Cb (1) and Cr (2) planes */
+#define GBM_FORMAT_YVU420      __gbm_fourcc_code('Y', 'V', '1', '2') /* 2x2 subsampled Cr (1) and Cb (2) planes */
+#define GBM_FORMAT_YUV422      __gbm_fourcc_code('Y', 'U', '1', '6') /* 2x1 subsampled Cb (1) and Cr (2) planes */
+#define GBM_FORMAT_YVU422      __gbm_fourcc_code('Y', 'V', '1', '6') /* 2x1 subsampled Cr (1) and Cb (2) planes */
+#define GBM_FORMAT_YUV444      __gbm_fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */
+#define GBM_FORMAT_YVU444      __gbm_fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */
+
+
 /**
  * Flags to indicate the intended use for the buffer - these are passed into
  * gbm_bo_create(). The caller must set the union of all the flags that are
@@ -108,8 +210,7 @@ gbm_device_get_backend_name(struct gbm_device *gbm);
 
 int
 gbm_device_is_format_supported(struct gbm_device *gbm,
-                               enum gbm_bo_format format,
-                               uint32_t usage);
+                               uint32_t format, uint32_t usage);
 
 void
 gbm_device_destroy(struct gbm_device *gbm);
@@ -120,7 +221,7 @@ gbm_create_device(int fd);
 struct gbm_bo *
 gbm_bo_create(struct gbm_device *gbm,
               uint32_t width, uint32_t height,
-              enum gbm_bo_format format, uint32_t flags);
+              uint32_t format, uint32_t flags);
 
 struct gbm_bo *
 gbm_bo_create_from_egl_image(struct gbm_device *gbm,
@@ -137,6 +238,9 @@ gbm_bo_get_height(struct gbm_bo *bo);
 uint32_t
 gbm_bo_get_pitch(struct gbm_bo *bo);
 
+uint32_t
+gbm_bo_get_format(struct gbm_bo *bo);
+
 union gbm_bo_handle
 gbm_bo_get_handle(struct gbm_bo *bo);
 
index 9e4072ef6ea60e47a052390f8afbb50c3545a512..66c4c41cf8e8d043d7bee6973ad9dbdcf62df6cd 100644 (file)
@@ -83,6 +83,7 @@ struct gbm_bo {
    uint32_t width;
    uint32_t height;
    uint32_t pitch;
+   uint32_t format;
    union gbm_bo_handle  handle;
 };
 
index 8c7e13862e57013503bfb05d8d7ed1edc0551eff..4ea970ad6d139201347e5f86093219e25f953b36 100644 (file)
@@ -132,6 +132,7 @@ void _mesa_copy_rect(GLubyte * dst,
 struct __DRIimageRec {
    struct intel_region *region;
    GLenum internal_format;
+   uint32_t dri_format;
    GLuint format;
    GLenum data_type;
    void *data;
index 4eeeb2f856107085abd6bf79da1d167806cab2ee..a13e6755a7cc80300991644fa2cc4f652a05cba5 100644 (file)
@@ -245,6 +245,8 @@ intel_create_image(__DRIscreen *screen,
    if (image == NULL)
       return NULL;
 
+   image->dri_format = format;
+
    switch (format) {
    case __DRI_IMAGE_FORMAT_RGB565:
       image->format = MESA_FORMAT_RGB565;
@@ -297,6 +299,8 @@ intel_query_image(__DRIimage *image, int attrib, int *value)
       return true;
    case __DRI_IMAGE_ATTRIB_NAME:
       return intel_region_flink(image->region, (uint32_t *) value);
+   case __DRI_IMAGE_ATTRIB_FORMAT:
+      return image->dri_format;
    default:
       return false;
    }
index 1f60f2ae43f3c70cd9d5f3bdc48a13bd6fa35eff..85cfe17ad76aa548b103dbddbb92b61557f78863 100644 (file)
@@ -314,6 +314,8 @@ radeon_create_image(__DRIscreen *screen,
    if (image == NULL)
       return NULL;
 
+   image->dri_format = format;
+
    switch (format) {
    case __DRI_IMAGE_FORMAT_RGB565:
       image->format = MESA_FORMAT_RGB565;
index 1f0f383c683d0e970e6de2585efc67aba4e8fd2b..dd618f5836f1f4b1be2e60259bd787ba61573a53 100644 (file)
@@ -109,6 +109,7 @@ typedef struct radeon_screen {
 struct __DRIimageRec {
    struct radeon_bo *bo;
    GLenum internal_format;
+   uint32_t dri_format;
    GLuint format;
    GLenum data_type;
    int width, height;  /* in pixels */