[Mesa-dev] [PATCH v13 09/36] st/dri: refactor multi-planar YUV import path
Daniel Stone
daniels at collabora.com
Fri May 19 09:37:52 UTC 2017
From: Varad Gautam <varad.gautam at collabora.com>
we currently ignore the plane count when converting from
__DRI_IMAGE_FORMAT* tokens to __DRI_IMAGE_FOURCC* for multiplanar
images, and only return the first plane's simplified fourcc.
this adds a fourcc to __DRI_IMAGE_FORMAT_* mapping to dri, allowing
us to return the correct fourcc format from DRIimage queries, and
simplifies the multiplane import logic.
Signed-off-by: Varad Gautam <varad.gautam at collabora.com>
Signed-off-by: Daniel Stone <daniels at collabora.com>
---
src/gallium/state_trackers/dri/dri2.c | 288 +++++++++++++++-------------
src/gallium/state_trackers/dri/dri_screen.h | 13 ++
2 files changed, 168 insertions(+), 133 deletions(-)
diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c
index ed6004f836..0c5783cbd3 100644
--- a/src/gallium/state_trackers/dri/dri2.c
+++ b/src/gallium/state_trackers/dri/dri2.c
@@ -52,93 +52,133 @@
#include "dri_query_renderer.h"
#include "dri2_buffer.h"
-static int convert_fourcc(int format, int *dri_components_p)
+/* format list taken from intel_screen.c */
+static struct image_format image_formats[] = {
+ { __DRI_IMAGE_FOURCC_ARGB8888, __DRI_IMAGE_COMPONENTS_RGBA, 1,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB8888, 4 } } },
+
+ { __DRI_IMAGE_FOURCC_ABGR8888, __DRI_IMAGE_COMPONENTS_RGBA, 1,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR8888, 4 } } },
+
+ { __DRI_IMAGE_FOURCC_SARGB8888, __DRI_IMAGE_COMPONENTS_RGBA, 1,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_SARGB8, 4 } } },
+
+ { __DRI_IMAGE_FOURCC_XRGB8888, __DRI_IMAGE_COMPONENTS_RGB, 1,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_XRGB8888, 4 }, } },
+
+ { __DRI_IMAGE_FOURCC_XBGR8888, __DRI_IMAGE_COMPONENTS_RGB, 1,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_XBGR8888, 4 }, } },
+
+ { __DRI_IMAGE_FOURCC_ARGB1555, __DRI_IMAGE_COMPONENTS_RGBA, 1,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB1555, 2 } } },
+
+ { __DRI_IMAGE_FOURCC_RGB565, __DRI_IMAGE_COMPONENTS_RGB, 1,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_RGB565, 2 } } },
+
+ { __DRI_IMAGE_FOURCC_R8, __DRI_IMAGE_COMPONENTS_R, 1,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, } },
+
+ { __DRI_IMAGE_FOURCC_R16, __DRI_IMAGE_COMPONENTS_R, 1,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_R16, 1 }, } },
+
+ { __DRI_IMAGE_FOURCC_GR88, __DRI_IMAGE_COMPONENTS_RG, 1,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88, 2 }, } },
+
+ { __DRI_IMAGE_FOURCC_GR1616, __DRI_IMAGE_COMPONENTS_RG, 1,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR1616, 2 }, } },
+
+ { __DRI_IMAGE_FOURCC_YUV410, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+ { 1, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 },
+ { 2, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 } } },
+
+ { __DRI_IMAGE_FOURCC_YUV411, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+ { 1, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+ { 2, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
+
+ { __DRI_IMAGE_FOURCC_YUV420, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+ { 1, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 },
+ { 2, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 } } },
+
+ { __DRI_IMAGE_FOURCC_YUV422, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+ { 1, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+ { 2, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
+
+ { __DRI_IMAGE_FOURCC_YUV444, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+ { 1, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+ { 2, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
+
+ { __DRI_IMAGE_FOURCC_YVU410, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+ { 2, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 },
+ { 1, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 } } },
+
+ { __DRI_IMAGE_FOURCC_YVU411, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+ { 2, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+ { 1, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
+
+ { __DRI_IMAGE_FOURCC_YVU420, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+ { 2, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 },
+ { 1, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 } } },
+
+ { __DRI_IMAGE_FOURCC_YVU422, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+ { 2, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+ { 1, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
+
+ { __DRI_IMAGE_FOURCC_YVU444, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+ { 2, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+ { 1, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
+
+ { __DRI_IMAGE_FOURCC_NV12, __DRI_IMAGE_COMPONENTS_Y_UV, 2,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+ { 1, 1, 1, __DRI_IMAGE_FORMAT_GR88, 2 } } },
+
+ { __DRI_IMAGE_FOURCC_NV16, __DRI_IMAGE_COMPONENTS_Y_UV, 2,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+ { 1, 1, 0, __DRI_IMAGE_FORMAT_GR88, 2 } } },
+
+ { __DRI_IMAGE_FOURCC_YUYV, __DRI_IMAGE_COMPONENTS_Y_XUXV, 2,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88, 2 },
+ { 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888, 4 } } }
+};
+
+static struct image_format *
+image_format_from_fourcc(int fourcc)
{
- int dri_components;
- switch(format) {
- case __DRI_IMAGE_FOURCC_RGB565:
- format = __DRI_IMAGE_FORMAT_RGB565;
- dri_components = __DRI_IMAGE_COMPONENTS_RGB;
- break;
- case __DRI_IMAGE_FOURCC_ARGB8888:
- format = __DRI_IMAGE_FORMAT_ARGB8888;
- dri_components = __DRI_IMAGE_COMPONENTS_RGBA;
- break;
- case __DRI_IMAGE_FOURCC_XRGB8888:
- format = __DRI_IMAGE_FORMAT_XRGB8888;
- dri_components = __DRI_IMAGE_COMPONENTS_RGB;
- break;
- case __DRI_IMAGE_FOURCC_ABGR8888:
- format = __DRI_IMAGE_FORMAT_ABGR8888;
- dri_components = __DRI_IMAGE_COMPONENTS_RGBA;
- break;
- case __DRI_IMAGE_FOURCC_XBGR8888:
- format = __DRI_IMAGE_FORMAT_XBGR8888;
- dri_components = __DRI_IMAGE_COMPONENTS_RGB;
- break;
- case __DRI_IMAGE_FOURCC_R8:
- format = __DRI_IMAGE_FORMAT_R8;
- dri_components = __DRI_IMAGE_COMPONENTS_R;
- break;
- case __DRI_IMAGE_FOURCC_GR88:
- format = __DRI_IMAGE_FORMAT_GR88;
- dri_components = __DRI_IMAGE_COMPONENTS_RG;
- break;
- /*
- * For multi-planar YUV formats, we return the format of the first
- * plane only. Since there is only one caller which supports multi-
- * planar YUV it gets to figure out the remaining planes on it's
- * own.
- */
- case __DRI_IMAGE_FOURCC_YUV420:
- case __DRI_IMAGE_FOURCC_YVU420:
- format = __DRI_IMAGE_FORMAT_R8;
- dri_components = __DRI_IMAGE_COMPONENTS_Y_U_V;
- break;
- case __DRI_IMAGE_FOURCC_NV12:
- format = __DRI_IMAGE_FORMAT_R8;
- dri_components = __DRI_IMAGE_COMPONENTS_Y_UV;
- break;
- default:
- return -1;
+ struct image_format *f = NULL;
+
+ for (unsigned i = 0; i < ARRAY_SIZE(image_formats); i++) {
+ if (image_formats[i].fourcc == fourcc) {
+ f = &image_formats[i];
+ break;
+ }
}
- *dri_components_p = dri_components;
- return format;
+
+ return f;
}
-/* NOTE this probably isn't going to do the right thing for YUV images
- * (but I think the same can be said for intel_query_image()). I think
- * only needed for exporting dmabuf's, so I think I won't loose much
- * sleep over it.
- */
-static int convert_to_fourcc(int format)
+static struct image_format *
+image_format_from_dri2_format(int dri_format, int nplanes)
{
- switch(format) {
- case __DRI_IMAGE_FORMAT_RGB565:
- format = __DRI_IMAGE_FOURCC_RGB565;
- break;
- case __DRI_IMAGE_FORMAT_ARGB8888:
- format = __DRI_IMAGE_FOURCC_ARGB8888;
- break;
- case __DRI_IMAGE_FORMAT_XRGB8888:
- format = __DRI_IMAGE_FOURCC_XRGB8888;
- break;
- case __DRI_IMAGE_FORMAT_ABGR8888:
- format = __DRI_IMAGE_FOURCC_ABGR8888;
- break;
- case __DRI_IMAGE_FORMAT_XBGR8888:
- format = __DRI_IMAGE_FOURCC_XBGR8888;
- break;
- case __DRI_IMAGE_FORMAT_R8:
- format = __DRI_IMAGE_FOURCC_R8;
- break;
- case __DRI_IMAGE_FORMAT_GR88:
- format = __DRI_IMAGE_FOURCC_GR88;
- break;
- default:
- return -1;
+ struct image_format *f = NULL;
+
+ for (unsigned i = 0; i < ARRAY_SIZE(image_formats); i++) {
+ if (image_formats[i].planes[0].dri_format == dri_format &&
+ image_formats[i].nplanes == nplanes) {
+ f = &image_formats[i];
+ break;
+ }
}
- return format;
+
+ return f;
}
static enum pipe_format dri2_format_to_pipe_format (int format)
@@ -791,13 +831,13 @@ dri2_create_image_from_winsys(__DRIscreen *_screen,
__DRIimage *img;
struct pipe_resource templ;
unsigned tex_usage;
- enum pipe_format pf;
+ struct image_format *f = NULL;
int i;
tex_usage = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
- pf = dri2_format_to_pipe_format (format);
- if (pf == PIPE_FORMAT_NONE)
+ f = image_format_from_dri2_format(format, num_handles);
+ if (f == NULL)
return NULL;
img = CALLOC_STRUCT(__DRIimageRec);
@@ -811,31 +851,12 @@ dri2_create_image_from_winsys(__DRIscreen *_screen,
templ.depth0 = 1;
templ.array_size = 1;
- for (i = num_handles - 1; i >= 0; i--) {
+ for (i = f->nplanes - 1; i >= 0; i--) {
struct pipe_resource *tex;
- /* TODO: something a lot less ugly */
- switch (i) {
- case 0:
- templ.width0 = width;
- templ.height0 = height;
- templ.format = pf;
- break;
- case 1:
- templ.width0 = width / 2;
- templ.height0 = height / 2;
- templ.format = (num_handles == 2) ?
- PIPE_FORMAT_RG88_UNORM : /* NV12, etc */
- PIPE_FORMAT_R8_UNORM; /* I420, etc */
- break;
- case 2:
- templ.width0 = width / 2;
- templ.height0 = height / 2;
- templ.format = PIPE_FORMAT_R8_UNORM;
- break;
- default:
- unreachable("too many planes!");
- }
+ templ.width0 = width >> f->planes[i].width_shift;
+ templ.height0 = height >> f->planes[i].height_shift;
+ templ.format = dri2_format_to_pipe_format(f->planes[i].dri_format);
tex = pscreen->resource_from_handle(pscreen,
&templ, &whandle[i], PIPE_HANDLE_USAGE_READ_WRITE);
@@ -890,32 +911,18 @@ dri2_create_image_from_fd(__DRIscreen *_screen,
struct winsys_handle whandles[3];
int format;
__DRIimage *img = NULL;
+ struct image_format *f = NULL;
unsigned err = __DRI_IMAGE_ERROR_SUCCESS;
- int expected_num_fds, i;
-
- switch (fourcc) {
- case __DRI_IMAGE_FOURCC_YUV420:
- case __DRI_IMAGE_FOURCC_YVU420:
- expected_num_fds = 3;
- break;
- case __DRI_IMAGE_FOURCC_NV12:
- expected_num_fds = 2;
- break;
- default:
- expected_num_fds = 1;
- break;
- }
+ int i;
- if (num_fds != expected_num_fds) {
+ f = image_format_from_fourcc(fourcc);
+ if (f == NULL || num_fds != f->nplanes) {
err = __DRI_IMAGE_ERROR_BAD_MATCH;
goto exit;
}
- format = convert_fourcc(fourcc, dri_components);
- if (format == -1) {
- err = __DRI_IMAGE_ERROR_BAD_MATCH;
- goto exit;
- }
+ format = f->planes[0].dri_format;
+ *dri_components = f->components;
memset(whandles, 0, sizeof(whandles));
@@ -1026,7 +1033,9 @@ static GLboolean
dri2_query_image(__DRIimage *image, int attrib, int *value)
{
struct winsys_handle whandle;
+ struct image_format *f = NULL;
unsigned usage;
+ int nplanes;
if (image->use & __DRI_IMAGE_USE_BACKBUFFER)
usage = PIPE_HANDLE_USAGE_EXPLICIT_FLUSH | PIPE_HANDLE_USAGE_READ;
@@ -1077,7 +1086,19 @@ dri2_query_image(__DRIimage *image, int attrib, int *value)
*value = image->dri_components;
return GL_TRUE;
case __DRI_IMAGE_ATTRIB_FOURCC:
- *value = convert_to_fourcc(image->dri_format);
+ switch (image->dri_components) {
+ case __DRI_IMAGE_COMPONENTS_Y_U_V:
+ nplanes = 3;
+ break;
+ case __DRI_IMAGE_COMPONENTS_Y_UV:
+ case __DRI_IMAGE_COMPONENTS_Y_XUXV:
+ nplanes = 2;
+ break;
+ default:
+ nplanes = 1;
+ }
+ f = image_format_from_dri2_format(image->dri_format, nplanes);
+ *value = f->fourcc;
return GL_TRUE;
case __DRI_IMAGE_ATTRIB_NUM_PLANES:
*value = 1;
@@ -1128,14 +1149,14 @@ dri2_from_names(__DRIscreen *screen, int width, int height, int format,
void *loaderPrivate)
{
__DRIimage *img;
- int dri_components;
struct winsys_handle whandle;
+ struct image_format *f = NULL;
if (num_names != 1)
return NULL;
- format = convert_fourcc(format, &dri_components);
- if (format == -1)
+ f = image_format_from_fourcc(format);
+ if (f == NULL)
return NULL;
memset(&whandle, 0, sizeof(whandle));
@@ -1144,12 +1165,13 @@ dri2_from_names(__DRIscreen *screen, int width, int height, int format,
whandle.stride = strides[0];
whandle.offset = offsets[0];
- img = dri2_create_image_from_winsys(screen, width, height, format,
+ img = dri2_create_image_from_winsys(screen, width, height,
+ f->planes[0].dri_format,
1, &whandle, loaderPrivate);
if (img == NULL)
return NULL;
- img->dri_components = dri_components;
+ img->dri_components = f->components;
return img;
}
diff --git a/src/gallium/state_trackers/dri/dri_screen.h b/src/gallium/state_trackers/dri/dri_screen.h
index 7f5fd13630..de88cd26db 100644
--- a/src/gallium/state_trackers/dri/dri_screen.h
+++ b/src/gallium/state_trackers/dri/dri_screen.h
@@ -103,6 +103,19 @@ dri_screen(__DRIscreen * sPriv)
return (struct dri_screen *)sPriv->driverPrivate;
}
+struct image_format {
+ int fourcc;
+ int components;
+ int nplanes;
+ struct {
+ int buffer_index;
+ int width_shift;
+ int height_shift;
+ uint32_t dri_format;
+ int cpp;
+ } planes[3];
+};
+
struct __DRIimageRec {
struct pipe_resource *texture;
unsigned level;
--
2.13.0
More information about the mesa-dev
mailing list