From 8de5c355fa2bf0f30df2c7cf39aee01e793284bf Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 21 Feb 2012 12:53:09 -0800 Subject: [PATCH] gbm: track buffer format through DRI drivers 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 --- include/GL/internal/dri_interface.h | 3 +- .../state_trackers/dri/common/dri_screen.h | 1 + src/gallium/state_trackers/dri/drm/dri2.c | 6 + src/gbm/backends/dri/gbm_dri.c | 45 ++++++- src/gbm/main/gbm.c | 13 +++ src/gbm/main/gbm.h | 110 +++++++++++++++++- src/gbm/main/gbmint.h | 1 + src/mesa/drivers/dri/intel/intel_regions.h | 1 + src/mesa/drivers/dri/intel/intel_screen.c | 4 + src/mesa/drivers/dri/radeon/radeon_screen.c | 2 + src/mesa/drivers/dri/radeon/radeon_screen.h | 1 + 11 files changed, 181 insertions(+), 6 deletions(-) diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index 701e83e7831..da8366652fe 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -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; diff --git a/src/gallium/state_trackers/dri/common/dri_screen.h b/src/gallium/state_trackers/dri/common/dri_screen.h index 8c961955ac9..2818e9c2683 100644 --- a/src/gallium/state_trackers/dri/common/dri_screen.h +++ b/src/gallium/state_trackers/dri/common/dri_screen.h @@ -85,6 +85,7 @@ struct __DRIimageRec { struct pipe_resource *texture; unsigned level; unsigned layer; + uint32_t dri_format; void *loader_private; }; diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c index 4c08a025ed2..cc8023d02d5 100644 --- a/src/gallium/state_trackers/dri/drm/dri2.c +++ b/src/gallium/state_trackers/dri/drm/dri2.c @@ -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; } diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c index ddd153a7db4..34f07de4bba 100644 --- a/src/gbm/backends/dri/gbm_dri.c +++ b/src/gbm/backends/dri/gbm_dri.c @@ -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; } diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c index 03fc52b161a..9459720261f 100644 --- a/src/gbm/main/gbm.c +++ b/src/gbm/main/gbm.c @@ -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 diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h index c4ae51db022..ecebf11f7b9 100644 --- a/src/gbm/main/gbm.h +++ b/src/gbm/main/gbm.h @@ -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); diff --git a/src/gbm/main/gbmint.h b/src/gbm/main/gbmint.h index 9e4072ef6ea..66c4c41cf8e 100644 --- a/src/gbm/main/gbmint.h +++ b/src/gbm/main/gbmint.h @@ -83,6 +83,7 @@ struct gbm_bo { uint32_t width; uint32_t height; uint32_t pitch; + uint32_t format; union gbm_bo_handle handle; }; diff --git a/src/mesa/drivers/dri/intel/intel_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h index 8c7e13862e5..4ea970ad6d1 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.h +++ b/src/mesa/drivers/dri/intel/intel_regions.h @@ -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; diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index 4eeeb2f8561..a13e6755a7c 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -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; } diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 1f60f2ae43f..85cfe17ad76 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -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; diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.h b/src/mesa/drivers/dri/radeon/radeon_screen.h index 1f0f383c683..dd618f5836f 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.h +++ b/src/mesa/drivers/dri/radeon/radeon_screen.h @@ -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 */ -- 2.30.2