From: Varad Gautam <varad.gau...@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.gau...@collabora.com> Signed-off-by: Daniel Stone <dani...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev