diff options
-rw-r--r-- | src/gallium/state_trackers/dri/dri2.c | 253 | ||||
-rw-r--r-- | src/gallium/state_trackers/dri/dri_screen.c | 17 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_atom_sampler.c | 3 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_atom_texture.c | 26 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_eglimage.c | 61 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_program.c | 21 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_program.h | 18 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_sampler_view.c | 13 |
8 files changed, 328 insertions, 84 deletions
diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c index 5a7ec878bab..7b6fc37c0f6 100644 --- a/src/gallium/state_trackers/dri/dri2.c +++ b/src/gallium/state_trackers/dri/dri2.c @@ -67,52 +67,164 @@ dri2_buffer(__DRIbuffer * driBufferPriv) struct dri2_format_mapping { int dri_fourcc; - int dri_format; + int dri_format; /* image format */ int dri_components; enum pipe_format pipe_format; + int nplanes; + struct { + int buffer_index; + int width_shift; + int height_shift; + uint32_t dri_format; /* plane format */ + int cpp; + } planes[3]; }; static const struct dri2_format_mapping dri2_format_table[] = { { __DRI_IMAGE_FOURCC_ARGB2101010, __DRI_IMAGE_FORMAT_ARGB2101010, - __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_B10G10R10A2_UNORM }, + __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_B10G10R10A2_UNORM, 1, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB2101010, 4 } } }, { __DRI_IMAGE_FOURCC_XRGB2101010, __DRI_IMAGE_FORMAT_XRGB2101010, - __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_B10G10R10X2_UNORM }, + __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_B10G10R10X2_UNORM, 1, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_XRGB2101010, 4 } } }, { __DRI_IMAGE_FOURCC_ABGR2101010, __DRI_IMAGE_FORMAT_ABGR2101010, - __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_R10G10B10A2_UNORM }, + __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_R10G10B10A2_UNORM, 1, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR2101010, 4 } } }, { __DRI_IMAGE_FOURCC_XBGR2101010, __DRI_IMAGE_FORMAT_XBGR2101010, - __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_R10G10B10X2_UNORM }, + __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_R10G10B10X2_UNORM, 1, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_XBGR2101010, 4 } } }, { __DRI_IMAGE_FOURCC_ARGB8888, __DRI_IMAGE_FORMAT_ARGB8888, - __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_BGRA8888_UNORM }, + __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_BGRA8888_UNORM, 1, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB8888, 4 } } }, { __DRI_IMAGE_FOURCC_ABGR8888, __DRI_IMAGE_FORMAT_ABGR8888, - __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_RGBA8888_UNORM }, + __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_RGBA8888_UNORM, 1, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR8888, 4 } } }, { __DRI_IMAGE_FOURCC_SARGB8888, __DRI_IMAGE_FORMAT_SARGB8, - __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_BGRA8888_SRGB }, + __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_BGRA8888_SRGB, 1, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_SARGB8, 4 } } }, { __DRI_IMAGE_FOURCC_XRGB8888, __DRI_IMAGE_FORMAT_XRGB8888, - __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_BGRX8888_UNORM }, + __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_BGRX8888_UNORM, 1, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_XRGB8888, 4 }, } }, { __DRI_IMAGE_FOURCC_XBGR8888, __DRI_IMAGE_FORMAT_XBGR8888, - __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_RGBX8888_UNORM }, + __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_RGBX8888_UNORM, 1, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_XBGR8888, 4 }, } }, { __DRI_IMAGE_FOURCC_ARGB1555, __DRI_IMAGE_FORMAT_ARGB1555, - __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_B5G5R5A1_UNORM }, + __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_B5G5R5A1_UNORM, 1, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB1555, 2 } } }, { __DRI_IMAGE_FOURCC_RGB565, __DRI_IMAGE_FORMAT_RGB565, - __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_B5G6R5_UNORM }, + __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_B5G6R5_UNORM, 1, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_RGB565, 2 } } }, { __DRI_IMAGE_FOURCC_R8, __DRI_IMAGE_FORMAT_R8, - __DRI_IMAGE_COMPONENTS_R, PIPE_FORMAT_R8_UNORM }, + __DRI_IMAGE_COMPONENTS_R, PIPE_FORMAT_R8_UNORM, 1, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, } }, { __DRI_IMAGE_FOURCC_R16, __DRI_IMAGE_FORMAT_R16, - __DRI_IMAGE_COMPONENTS_R, PIPE_FORMAT_R16_UNORM }, + __DRI_IMAGE_COMPONENTS_R, PIPE_FORMAT_R16_UNORM, 1, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_R16, 1 }, } }, { __DRI_IMAGE_FOURCC_GR88, __DRI_IMAGE_FORMAT_GR88, - __DRI_IMAGE_COMPONENTS_RG, PIPE_FORMAT_RG88_UNORM }, + __DRI_IMAGE_COMPONENTS_RG, PIPE_FORMAT_RG88_UNORM, 1, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88, 2 }, } }, { __DRI_IMAGE_FOURCC_GR1616, __DRI_IMAGE_FORMAT_GR1616, - __DRI_IMAGE_COMPONENTS_RG, PIPE_FORMAT_RG1616_UNORM }, + __DRI_IMAGE_COMPONENTS_RG, PIPE_FORMAT_RG1616_UNORM, 1, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR1616, 2 }, } }, + + { __DRI_IMAGE_FOURCC_YUV410, __DRI_IMAGE_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 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_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 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_FORMAT_NONE, - __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV }, + __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 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_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 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_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 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_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_YV12, 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_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_YV12, 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_FORMAT_NONE, - __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_YV12 }, + __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_YV12, 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_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_YV12, 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_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_YV12, 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_FORMAT_NONE, - __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_NV12 }, - { __DRI_IMAGE_FOURCC_YUYV, __DRI_IMAGE_FORMAT_YUYV, - __DRI_IMAGE_COMPONENTS_Y_XUXV, PIPE_FORMAT_YUYV }, - { __DRI_IMAGE_FOURCC_UYVY, __DRI_IMAGE_FORMAT_UYVY, - __DRI_IMAGE_COMPONENTS_Y_UXVX, PIPE_FORMAT_UYVY }, + __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_NV12, 2, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, + { 1, 1, 1, __DRI_IMAGE_FORMAT_GR88, 2 } } }, + + { __DRI_IMAGE_FOURCC_P010, __DRI_IMAGE_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_P016, 2, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_R16, 2 }, + { 1, 1, 1, __DRI_IMAGE_FORMAT_GR1616, 4 } } }, + { __DRI_IMAGE_FOURCC_P012, __DRI_IMAGE_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_P016, 2, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_R16, 2 }, + { 1, 1, 1, __DRI_IMAGE_FORMAT_GR1616, 4 } } }, + { __DRI_IMAGE_FOURCC_P016, __DRI_IMAGE_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_P016, 2, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_R16, 2 }, + { 1, 1, 1, __DRI_IMAGE_FORMAT_GR1616, 4 } } }, + + { __DRI_IMAGE_FOURCC_NV16, __DRI_IMAGE_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_NV12, 2, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, + { 1, 1, 0, __DRI_IMAGE_FORMAT_GR88, 2 } } }, + + { __DRI_IMAGE_FOURCC_AYUV, __DRI_IMAGE_FORMAT_ABGR8888, + __DRI_IMAGE_COMPONENTS_AYUV, PIPE_FORMAT_AYUV, 1, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR8888, 4 } } }, + { __DRI_IMAGE_FOURCC_XYUV8888, __DRI_IMAGE_FORMAT_XBGR8888, + __DRI_IMAGE_COMPONENTS_XYUV, PIPE_FORMAT_XYUV, 1, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_XBGR8888, 4 } } }, + + /* For YUYV and UYVY buffers, we set up two overlapping DRI images + * and treat them as planar buffers in the compositors. + * Plane 0 is GR88 and samples YU or YV pairs and places Y into + * the R component, while plane 1 is ARGB/ABGR and samples YUYV/UYVY + * clusters and places pairs and places U into the G component and + * V into A. This lets the texture sampler interpolate the Y + * components correctly when sampling from plane 0, and interpolate + * U and V correctly when sampling from plane 1. */ + { __DRI_IMAGE_FOURCC_YUYV, __DRI_IMAGE_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_XUXV, PIPE_FORMAT_YUYV, 2, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88, 2 }, + { 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888, 4 } } }, + { __DRI_IMAGE_FOURCC_UYVY, __DRI_IMAGE_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_UXVX, PIPE_FORMAT_UYVY, 2, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88, 2 }, + { 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR8888, 4 } } } }; static const struct dri2_format_mapping * @@ -137,6 +249,17 @@ dri2_get_mapping_by_format(int format) return NULL; } +static enum pipe_format +dri2_get_pipe_format_for_dri_format(int format) +{ + for (unsigned i = 0; i < ARRAY_SIZE(dri2_format_table); i++) { + if (dri2_format_table[i].dri_format == format) + return dri2_format_table[i].pipe_format; + } + + return PIPE_FORMAT_NONE; +} + /** * DRI2 flush extension. */ @@ -791,22 +914,25 @@ dri2_create_image_from_winsys(__DRIscreen *_screen, struct pipe_resource templ; unsigned tex_usage = 0; int i; - enum pipe_format pf = map->pipe_format; + bool is_yuv = util_format_is_yuv(map->pipe_format); - if (pscreen->is_format_supported(pscreen, pf, screen->target, 0, 0, + if (pscreen->is_format_supported(pscreen, map->pipe_format, screen->target, 0, 0, PIPE_BIND_RENDER_TARGET)) tex_usage |= PIPE_BIND_RENDER_TARGET; - if (pscreen->is_format_supported(pscreen, pf, screen->target, 0, 0, + if (pscreen->is_format_supported(pscreen, map->pipe_format, screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) tex_usage |= PIPE_BIND_SAMPLER_VIEW; - if (!tex_usage && util_format_is_yuv(pf)) { + if (!tex_usage && is_yuv) { /* YUV format sampling can be emulated by the Mesa state tracker by - * using multiple R8/RG88 samplers. So try to rewrite the pipe format. + * using multiple samplers of varying formats. + * If no tex_usage is set and we detect a YUV format, + * test for support of the first plane's sampler format and + * add sampler view usage. */ - pf = PIPE_FORMAT_R8_UNORM; - - if (pscreen->is_format_supported(pscreen, pf, screen->target, 0, 0, + if (pscreen->is_format_supported(pscreen, + dri2_get_pipe_format_for_dri_format(map->planes[0].dri_format), + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) tex_usage |= PIPE_BIND_SAMPLER_VIEW; } @@ -828,28 +954,13 @@ dri2_create_image_from_winsys(__DRIscreen *_screen, for (i = num_handles - 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 >> map->planes[i].width_shift; + templ.height0 = height >> map->planes[i].height_shift; + if (is_yuv) + templ.format = dri2_get_pipe_format_for_dri_format(map->planes[i].dri_format); + else + templ.format = map->pipe_format; + assert(templ.format != PIPE_FORMAT_NONE); tex = pscreen->resource_from_handle(pscreen, &templ, &whandle[i], PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE); @@ -914,7 +1025,7 @@ dri2_create_image_from_fd(__DRIscreen *_screen, const struct dri2_format_mapping *map = dri2_get_mapping_by_fourcc(fourcc); __DRIimage *img = NULL; unsigned err = __DRI_IMAGE_ERROR_SUCCESS; - int expected_num_fds, i; + int i, expected_num_fds; if (!map) { err = __DRI_IMAGE_ERROR_BAD_MATCH; @@ -922,15 +1033,12 @@ dri2_create_image_from_fd(__DRIscreen *_screen, } 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; + case __DRI_IMAGE_FOURCC_YUYV: + case __DRI_IMAGE_FOURCC_UYVY: + expected_num_fds = 1; break; default: - expected_num_fds = 1; + expected_num_fds = map->nplanes; break; } @@ -941,30 +1049,23 @@ dri2_create_image_from_fd(__DRIscreen *_screen, memset(whandles, 0, sizeof(whandles)); - for (i = 0; i < num_fds; i++) { - if (fds[i] < 0) { + for (i = 0; i < map->nplanes; i++) { + int fdnum = i >= num_fds ? 0 : i; + int index = map->planes[i].buffer_index; + if (fds[fdnum] < 0) { err = __DRI_IMAGE_ERROR_BAD_ALLOC; goto exit; } whandles[i].type = WINSYS_HANDLE_TYPE_FD; - whandles[i].handle = (unsigned)fds[i]; - whandles[i].stride = (unsigned)strides[i]; - whandles[i].offset = (unsigned)offsets[i]; + whandles[i].handle = (unsigned)fds[fdnum]; + whandles[i].stride = (unsigned)strides[index]; + whandles[i].offset = (unsigned)offsets[index]; whandles[i].modifier = modifier; } - if (fourcc == __DRI_IMAGE_FOURCC_YVU420) { - /* convert to YUV420 by swapping 2nd and 3rd planes: */ - struct winsys_handle tmp = whandles[1]; - whandles[1] = whandles[2]; - whandles[2] = tmp; - fourcc = __DRI_IMAGE_FOURCC_YUV420; - map = dri2_get_mapping_by_fourcc(fourcc); - } - img = dri2_create_image_from_winsys(_screen, width, height, map, - num_fds, whandles, loaderPrivate); + map->nplanes, whandles, loaderPrivate); if(img == NULL) { err = __DRI_IMAGE_ERROR_BAD_ALLOC; goto exit; diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c index 2aed6ad3f12..188d50dc6e3 100644 --- a/src/gallium/state_trackers/dri/dri_screen.c +++ b/src/gallium/state_trackers/dri/dri_screen.c @@ -438,7 +438,22 @@ dri_get_egl_image(struct st_manager *smapi, stimg->format = PIPE_FORMAT_IYUV; break; case __DRI_IMAGE_COMPONENTS_Y_UV: - stimg->format = PIPE_FORMAT_NV12; + if (img->texture->format == PIPE_FORMAT_R8_UNORM) + stimg->format = PIPE_FORMAT_NV12; + else /* P0XX uses R16 for first texture */ + stimg->format = PIPE_FORMAT_P016; + break; + case __DRI_IMAGE_COMPONENTS_AYUV: + stimg->format = PIPE_FORMAT_RGBA8888_UNORM; + break; + case __DRI_IMAGE_COMPONENTS_XYUV: + stimg->format = PIPE_FORMAT_RGBX8888_UNORM; + break; + case __DRI_IMAGE_COMPONENTS_Y_XUXV: + stimg->format = PIPE_FORMAT_YUYV; + break; + case __DRI_IMAGE_COMPONENTS_Y_UXVX: + stimg->format = PIPE_FORMAT_UYVY; break; default: stimg->format = img->texture->format; diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index 27e4da31581..758ace10b8a 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -309,6 +309,9 @@ update_shader_samplers(struct st_context *st, switch (st_get_view_format(stObj)) { case PIPE_FORMAT_NV12: + case PIPE_FORMAT_P016: + case PIPE_FORMAT_YUYV: + case PIPE_FORMAT_UYVY: /* we need one additional sampler: */ extra = u_bit_scan(&free_slots); states[extra] = sampler; diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index ce7755f0c58..8a881c24fb3 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -191,6 +191,14 @@ update_textures(struct st_context *st, sampler_views[extra] = st->pipe->create_sampler_view(st->pipe, stObj->pt->next, &tmpl); break; + case PIPE_FORMAT_P016: + /* we need one additional R16G16 view: */ + tmpl.format = PIPE_FORMAT_RG1616_UNORM; + tmpl.swizzle_g = PIPE_SWIZZLE_Y; /* tmpl from Y plane is R16 */ + extra = u_bit_scan(&free_slots); + sampler_views[extra] = + st->pipe->create_sampler_view(st->pipe, stObj->pt->next, &tmpl); + break; case PIPE_FORMAT_IYUV: /* we need two additional R8 views: */ tmpl.format = PIPE_FORMAT_R8_UNORM; @@ -201,6 +209,24 @@ update_textures(struct st_context *st, sampler_views[extra] = st->pipe->create_sampler_view(st->pipe, stObj->pt->next->next, &tmpl); break; + case PIPE_FORMAT_YUYV: + /* we need one additional BGRA8888 view: */ + tmpl.format = PIPE_FORMAT_BGRA8888_UNORM; + tmpl.swizzle_b = PIPE_SWIZZLE_Z; + tmpl.swizzle_a = PIPE_SWIZZLE_W; + extra = u_bit_scan(&free_slots); + sampler_views[extra] = + st->pipe->create_sampler_view(st->pipe, stObj->pt->next, &tmpl); + break; + case PIPE_FORMAT_UYVY: + /* we need one additional RGBA8888 view: */ + tmpl.format = PIPE_FORMAT_RGBA8888_UNORM; + tmpl.swizzle_b = PIPE_SWIZZLE_Z; + tmpl.swizzle_a = PIPE_SWIZZLE_W; + extra = u_bit_scan(&free_slots); + sampler_views[extra] = + st->pipe->create_sampler_view(st->pipe, stObj->pt->next, &tmpl); + break; default: break; } diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c index 08697c42dfa..77abe55cfb2 100644 --- a/src/mesa/state_tracker/st_cb_eglimage.c +++ b/src/mesa/state_tracker/st_cb_eglimage.c @@ -54,17 +54,56 @@ is_format_supported(struct pipe_screen *screen, enum pipe_format format, * a shader variant that converts. */ if ((usage == PIPE_BIND_SAMPLER_VIEW) && !supported) { - if (format == PIPE_FORMAT_IYUV) { + switch (format) { + case PIPE_FORMAT_IYUV: supported = screen->is_format_supported(screen, PIPE_FORMAT_R8_UNORM, PIPE_TEXTURE_2D, nr_samples, nr_storage_samples, usage); - } else if (format == PIPE_FORMAT_NV12) { + break; + case PIPE_FORMAT_NV12: supported = screen->is_format_supported(screen, PIPE_FORMAT_R8_UNORM, PIPE_TEXTURE_2D, nr_samples, nr_storage_samples, usage) && screen->is_format_supported(screen, PIPE_FORMAT_R8G8_UNORM, PIPE_TEXTURE_2D, nr_samples, nr_storage_samples, usage); + break; + case PIPE_FORMAT_P016: + supported = screen->is_format_supported(screen, PIPE_FORMAT_R16_UNORM, + PIPE_TEXTURE_2D, nr_samples, + nr_storage_samples, usage) && + screen->is_format_supported(screen, PIPE_FORMAT_R16G16_UNORM, + PIPE_TEXTURE_2D, nr_samples, + nr_storage_samples, usage); + break; + case PIPE_FORMAT_YUYV: + supported = screen->is_format_supported(screen, PIPE_FORMAT_RG88_UNORM, + PIPE_TEXTURE_2D, nr_samples, + nr_storage_samples, usage) && + screen->is_format_supported(screen, PIPE_FORMAT_BGRA8888_UNORM, + PIPE_TEXTURE_2D, nr_samples, + nr_storage_samples, usage); + break; + case PIPE_FORMAT_UYVY: + supported = screen->is_format_supported(screen, PIPE_FORMAT_RG88_UNORM, + PIPE_TEXTURE_2D, nr_samples, + nr_storage_samples, usage) && + screen->is_format_supported(screen, PIPE_FORMAT_RGBA8888_UNORM, + PIPE_TEXTURE_2D, nr_samples, + nr_storage_samples, usage); + break; + case PIPE_FORMAT_AYUV: + supported = screen->is_format_supported(screen, PIPE_FORMAT_RGBA8888_UNORM, + PIPE_TEXTURE_2D, nr_samples, + nr_storage_samples, usage); + break; + case PIPE_FORMAT_XYUV: + supported = screen->is_format_supported(screen, PIPE_FORMAT_RGBX8888_UNORM, + PIPE_TEXTURE_2D, nr_samples, + nr_storage_samples, usage); + break; + default: + break; } } @@ -204,10 +243,28 @@ st_bind_egl_image(struct gl_context *ctx, texFormat = MESA_FORMAT_R_UNORM8; texObj->RequiredTextureImageUnits = 2; break; + case PIPE_FORMAT_P016: + texFormat = MESA_FORMAT_R_UNORM16; + texObj->RequiredTextureImageUnits = 2; + break; case PIPE_FORMAT_IYUV: texFormat = MESA_FORMAT_R_UNORM8; texObj->RequiredTextureImageUnits = 3; break; + case PIPE_FORMAT_YUYV: + case PIPE_FORMAT_UYVY: + texFormat = MESA_FORMAT_R8G8_UNORM; + texObj->RequiredTextureImageUnits = 2; + break; + case PIPE_FORMAT_AYUV: + texFormat = MESA_FORMAT_R8G8B8A8_UNORM; + internalFormat = GL_RGBA; + texObj->RequiredTextureImageUnits = 1; + break; + case PIPE_FORMAT_XYUV: + texFormat = MESA_FORMAT_R8G8B8X8_UNORM; + texObj->RequiredTextureImageUnits = 1; + break; default: texFormat = st_pipe_format_to_mesa_format(stimg->format); break; diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 7d1ed5634eb..81065612adb 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -1201,20 +1201,28 @@ st_create_fp_variant(struct st_context *st, NIR_PASS_V(tgsi.ir.nir, nir_lower_drawpixels, &options); } - if (unlikely(key->external.lower_nv12 || key->external.lower_iyuv)) { + if (unlikely(key->external.lower_nv12 || key->external.lower_iyuv || + key->external.lower_xy_uxvx || key->external.lower_yx_xuxv || + key->external.lower_ayuv || key->external.lower_xyuv)) { nir_lower_tex_options options = {0}; options.lower_y_uv_external = key->external.lower_nv12; options.lower_y_u_v_external = key->external.lower_iyuv; + options.lower_xy_uxvx_external = key->external.lower_xy_uxvx; + options.lower_yx_xuxv_external = key->external.lower_yx_xuxv; + options.lower_ayuv_external = key->external.lower_ayuv; + options.lower_xyuv_external = key->external.lower_xyuv; NIR_PASS_V(tgsi.ir.nir, nir_lower_tex, &options); } st_finalize_nir(st, &stfp->Base, stfp->shader_program, tgsi.ir.nir); - if (unlikely(key->external.lower_nv12 || key->external.lower_iyuv)) { + if (unlikely(key->external.lower_nv12 || key->external.lower_iyuv || + key->external.lower_xy_uxvx || key->external.lower_yx_xuxv)) { /* This pass needs to happen *after* nir_lower_sampler */ NIR_PASS_V(tgsi.ir.nir, st_nir_lower_tex_src_plane, ~stfp->Base.SamplersUsed, - key->external.lower_nv12, + key->external.lower_nv12 || key->external.lower_xy_uxvx || + key->external.lower_yx_xuxv, key->external.lower_iyuv); } @@ -1318,7 +1326,8 @@ st_create_fp_variant(struct st_context *st, fprintf(stderr, "mesa: cannot create a shader for glDrawPixels\n"); } - if (unlikely(key->external.lower_nv12 || key->external.lower_iyuv)) { + if (unlikely(key->external.lower_nv12 || key->external.lower_iyuv || + key->external.lower_xy_uxvx || key->external.lower_yx_xuxv)) { const struct tgsi_token *tokens; /* samplers inserted would conflict, but this should be unpossible: */ @@ -1326,7 +1335,9 @@ st_create_fp_variant(struct st_context *st, tokens = st_tgsi_lower_yuv(tgsi.tokens, ~stfp->Base.SamplersUsed, - key->external.lower_nv12, + key->external.lower_nv12 || + key->external.lower_xy_uxvx || + key->external.lower_yx_xuxv, key->external.lower_iyuv); if (tokens) { if (tgsi.tokens != stfp->tgsi.tokens) diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index 59a60368039..caaa779287a 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -53,6 +53,10 @@ struct st_external_sampler_key { GLuint lower_nv12; /**< bitmask of 2 plane YUV samplers */ GLuint lower_iyuv; /**< bitmask of 3 plane YUV samplers */ + GLuint lower_xy_uxvx; /**< bitmask of 2 plane YUV samplers */ + GLuint lower_yx_xuxv; /**< bitmask of 2 plane YUV samplers */ + GLuint lower_ayuv; + GLuint lower_xyuv; }; static inline struct st_external_sampler_key @@ -70,12 +74,26 @@ st_get_external_sampler_key(struct st_context *st, struct gl_program *prog) switch (st_get_view_format(stObj)) { case PIPE_FORMAT_NV12: + case PIPE_FORMAT_P016: key.lower_nv12 |= (1 << unit); break; case PIPE_FORMAT_IYUV: key.lower_iyuv |= (1 << unit); break; + case PIPE_FORMAT_YUYV: + key.lower_yx_xuxv |= (1 << unit); + break; + case PIPE_FORMAT_UYVY: + key.lower_xy_uxvx |= (1 << unit); + break; + case PIPE_FORMAT_AYUV: + key.lower_ayuv |= (1 << unit); + break; + case PIPE_FORMAT_XYUV: + key.lower_xyuv |= (1 << unit); + break; default: + printf("unhandled %u\n", st_get_view_format(stObj)); break; } } diff --git a/src/mesa/state_tracker/st_sampler_view.c b/src/mesa/state_tracker/st_sampler_view.c index 9c45de6032d..2fa08815085 100644 --- a/src/mesa/state_tracker/st_sampler_view.c +++ b/src/mesa/state_tracker/st_sampler_view.c @@ -495,6 +495,19 @@ get_sampler_view_format(struct st_context *st, case PIPE_FORMAT_IYUV: format = PIPE_FORMAT_R8_UNORM; break; + case PIPE_FORMAT_P016: + format = PIPE_FORMAT_R16_UNORM; + break; + case PIPE_FORMAT_YUYV: + case PIPE_FORMAT_UYVY: + format = PIPE_FORMAT_R8G8_UNORM; + break; + case PIPE_FORMAT_AYUV: + format = PIPE_FORMAT_RGBA8888_UNORM; + break; + case PIPE_FORMAT_XYUV: + format = PIPE_FORMAT_RGBX8888_UNORM; + break; default: break; } |