st/mesa: don't lower YUV when driver supports it natively
This fixes YUYV support on etnaviv.
Fixes: 7404833c
"gallium: add handling for YUV planar surfaces"
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/1896>
This commit is contained in:

committed by
Marge Bot

parent
4e3c81517b
commit
a554b45d73
@@ -738,7 +738,7 @@ dri2_create_image_from_winsys(__DRIscreen *_screen,
|
|||||||
struct pipe_resource templ;
|
struct pipe_resource templ;
|
||||||
unsigned tex_usage = 0;
|
unsigned tex_usage = 0;
|
||||||
int i;
|
int i;
|
||||||
bool is_yuv = util_format_is_yuv(map->pipe_format);
|
bool use_lowered = false;
|
||||||
|
|
||||||
if (pscreen->is_format_supported(pscreen, map->pipe_format, screen->target, 0, 0,
|
if (pscreen->is_format_supported(pscreen, map->pipe_format, screen->target, 0, 0,
|
||||||
PIPE_BIND_RENDER_TARGET))
|
PIPE_BIND_RENDER_TARGET))
|
||||||
@@ -747,13 +747,14 @@ dri2_create_image_from_winsys(__DRIscreen *_screen,
|
|||||||
PIPE_BIND_SAMPLER_VIEW))
|
PIPE_BIND_SAMPLER_VIEW))
|
||||||
tex_usage |= PIPE_BIND_SAMPLER_VIEW;
|
tex_usage |= PIPE_BIND_SAMPLER_VIEW;
|
||||||
|
|
||||||
if (!tex_usage && is_yuv) {
|
if (!tex_usage && util_format_is_yuv(map->pipe_format)) {
|
||||||
/* YUV format sampling can be emulated by the Mesa state tracker by
|
/* YUV format sampling can be emulated by the Mesa state tracker by
|
||||||
* using multiple samplers of varying formats.
|
* using multiple samplers of varying formats.
|
||||||
* If no tex_usage is set and we detect a YUV format,
|
* If no tex_usage is set and we detect a YUV format,
|
||||||
* test for support of the first plane's sampler format and
|
* test for support of the first plane's sampler format and
|
||||||
* add sampler view usage.
|
* add sampler view usage.
|
||||||
*/
|
*/
|
||||||
|
use_lowered = true;
|
||||||
if (pscreen->is_format_supported(pscreen,
|
if (pscreen->is_format_supported(pscreen,
|
||||||
dri2_get_pipe_format_for_dri_format(map->planes[0].dri_format),
|
dri2_get_pipe_format_for_dri_format(map->planes[0].dri_format),
|
||||||
screen->target, 0, 0,
|
screen->target, 0, 0,
|
||||||
@@ -775,19 +776,20 @@ dri2_create_image_from_winsys(__DRIscreen *_screen,
|
|||||||
templ.depth0 = 1;
|
templ.depth0 = 1;
|
||||||
templ.array_size = 1;
|
templ.array_size = 1;
|
||||||
|
|
||||||
for (i = num_handles - 1; i >= 0; i--) {
|
for (i = (use_lowered ? map->nplanes : num_handles) - 1; i >= 0; i--) {
|
||||||
struct pipe_resource *tex;
|
struct pipe_resource *tex;
|
||||||
|
|
||||||
templ.width0 = width >> map->planes[i].width_shift;
|
templ.width0 = width >> map->planes[i].width_shift;
|
||||||
templ.height0 = height >> map->planes[i].height_shift;
|
templ.height0 = height >> map->planes[i].height_shift;
|
||||||
if (is_yuv)
|
if (use_lowered)
|
||||||
templ.format = dri2_get_pipe_format_for_dri_format(map->planes[i].dri_format);
|
templ.format = dri2_get_pipe_format_for_dri_format(map->planes[i].dri_format);
|
||||||
else
|
else
|
||||||
templ.format = map->pipe_format;
|
templ.format = map->pipe_format;
|
||||||
assert(templ.format != PIPE_FORMAT_NONE);
|
assert(templ.format != PIPE_FORMAT_NONE);
|
||||||
|
|
||||||
tex = pscreen->resource_from_handle(pscreen,
|
tex = pscreen->resource_from_handle(pscreen,
|
||||||
&templ, &whandle[i], PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE);
|
&templ, &whandle[use_lowered ? map->planes[i].buffer_index : i],
|
||||||
|
PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE);
|
||||||
if (!tex) {
|
if (!tex) {
|
||||||
pipe_resource_reference(&img->texture, NULL);
|
pipe_resource_reference(&img->texture, NULL);
|
||||||
FREE(img);
|
FREE(img);
|
||||||
@@ -911,25 +913,23 @@ dri2_create_image_from_fd(__DRIscreen *_screen,
|
|||||||
|
|
||||||
memset(whandles, 0, sizeof(whandles));
|
memset(whandles, 0, sizeof(whandles));
|
||||||
|
|
||||||
for (i = 0; i < num_handles; i++) {
|
for (i = 0; i < num_fds; i++) {
|
||||||
int fdnum = i >= num_fds ? 0 : i;
|
if (fds[i] < 0) {
|
||||||
int index = i >= map->nplanes ? i : map->planes[i].buffer_index;
|
|
||||||
if (fds[fdnum] < 0) {
|
|
||||||
err = __DRI_IMAGE_ERROR_BAD_ALLOC;
|
err = __DRI_IMAGE_ERROR_BAD_ALLOC;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
whandles[i].type = WINSYS_HANDLE_TYPE_FD;
|
whandles[i].type = WINSYS_HANDLE_TYPE_FD;
|
||||||
whandles[i].handle = (unsigned)fds[fdnum];
|
whandles[i].handle = (unsigned)fds[i];
|
||||||
whandles[i].stride = (unsigned)strides[index];
|
whandles[i].stride = (unsigned)strides[i];
|
||||||
whandles[i].offset = (unsigned)offsets[index];
|
whandles[i].offset = (unsigned)offsets[i];
|
||||||
whandles[i].format = map->pipe_format;
|
whandles[i].format = map->pipe_format;
|
||||||
whandles[i].modifier = modifier;
|
whandles[i].modifier = modifier;
|
||||||
whandles[i].plane = index;
|
whandles[i].plane = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
img = dri2_create_image_from_winsys(_screen, width, height, map,
|
img = dri2_create_image_from_winsys(_screen, width, height, map,
|
||||||
num_handles, whandles, loaderPrivate);
|
num_fds, whandles, loaderPrivate);
|
||||||
if(img == NULL) {
|
if(img == NULL) {
|
||||||
err = __DRI_IMAGE_ERROR_BAD_ALLOC;
|
err = __DRI_IMAGE_ERROR_BAD_ALLOC;
|
||||||
goto exit;
|
goto exit;
|
||||||
|
@@ -304,7 +304,8 @@ update_shader_samplers(struct st_context *st,
|
|||||||
st_get_texture_object(st->ctx, prog, unit);
|
st_get_texture_object(st->ctx, prog, unit);
|
||||||
struct pipe_sampler_state *sampler = samplers + unit;
|
struct pipe_sampler_state *sampler = samplers + unit;
|
||||||
|
|
||||||
if (!stObj)
|
/* if resource format matches then YUV wasn't lowered */
|
||||||
|
if (!stObj || st_get_view_format(stObj) == stObj->pt->format)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch (st_get_view_format(stObj)) {
|
switch (st_get_view_format(stObj)) {
|
||||||
|
@@ -182,6 +182,10 @@ update_textures(struct st_context *st,
|
|||||||
/* use original view as template: */
|
/* use original view as template: */
|
||||||
tmpl = *sampler_views[unit];
|
tmpl = *sampler_views[unit];
|
||||||
|
|
||||||
|
/* if resource format matches then YUV wasn't lowered */
|
||||||
|
if (st_get_view_format(stObj) == stObj->pt->format)
|
||||||
|
continue;
|
||||||
|
|
||||||
switch (st_get_view_format(stObj)) {
|
switch (st_get_view_format(stObj)) {
|
||||||
case PIPE_FORMAT_NV12:
|
case PIPE_FORMAT_NV12:
|
||||||
/* we need one additional R8G8 view: */
|
/* we need one additional R8G8 view: */
|
||||||
|
@@ -42,11 +42,12 @@
|
|||||||
static bool
|
static bool
|
||||||
is_format_supported(struct pipe_screen *screen, enum pipe_format format,
|
is_format_supported(struct pipe_screen *screen, enum pipe_format format,
|
||||||
unsigned nr_samples, unsigned nr_storage_samples,
|
unsigned nr_samples, unsigned nr_storage_samples,
|
||||||
unsigned usage)
|
unsigned usage, bool *native_supported)
|
||||||
{
|
{
|
||||||
bool supported = screen->is_format_supported(screen, format, PIPE_TEXTURE_2D,
|
bool supported = screen->is_format_supported(screen, format, PIPE_TEXTURE_2D,
|
||||||
nr_samples, nr_storage_samples,
|
nr_samples, nr_storage_samples,
|
||||||
usage);
|
usage);
|
||||||
|
*native_supported = supported;
|
||||||
|
|
||||||
/* for sampling, some formats can be emulated.. it doesn't matter that
|
/* for sampling, some formats can be emulated.. it doesn't matter that
|
||||||
* the surface will have a format that the driver can't cope with because
|
* the surface will have a format that the driver can't cope with because
|
||||||
@@ -115,7 +116,8 @@ is_format_supported(struct pipe_screen *screen, enum pipe_format format,
|
|||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
st_get_egl_image(struct gl_context *ctx, GLeglImageOES image_handle,
|
st_get_egl_image(struct gl_context *ctx, GLeglImageOES image_handle,
|
||||||
unsigned usage, const char *error, struct st_egl_image *out)
|
unsigned usage, const char *error, struct st_egl_image *out,
|
||||||
|
bool *native_supported)
|
||||||
{
|
{
|
||||||
struct st_context *st = st_context(ctx);
|
struct st_context *st = st_context(ctx);
|
||||||
struct pipe_screen *screen = st->pipe->screen;
|
struct pipe_screen *screen = st->pipe->screen;
|
||||||
@@ -133,7 +135,8 @@ st_get_egl_image(struct gl_context *ctx, GLeglImageOES image_handle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!is_format_supported(screen, out->format, out->texture->nr_samples,
|
if (!is_format_supported(screen, out->format, out->texture->nr_samples,
|
||||||
out->texture->nr_storage_samples, usage)) {
|
out->texture->nr_storage_samples, usage,
|
||||||
|
native_supported)) {
|
||||||
/* unable to specify a texture object using the specified EGL image */
|
/* unable to specify a texture object using the specified EGL image */
|
||||||
pipe_resource_reference(&out->texture, NULL);
|
pipe_resource_reference(&out->texture, NULL);
|
||||||
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(format not supported)", error);
|
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(format not supported)", error);
|
||||||
@@ -180,10 +183,11 @@ st_egl_image_target_renderbuffer_storage(struct gl_context *ctx,
|
|||||||
{
|
{
|
||||||
struct st_renderbuffer *strb = st_renderbuffer(rb);
|
struct st_renderbuffer *strb = st_renderbuffer(rb);
|
||||||
struct st_egl_image stimg;
|
struct st_egl_image stimg;
|
||||||
|
bool native_supported;
|
||||||
|
|
||||||
if (st_get_egl_image(ctx, image_handle, PIPE_BIND_RENDER_TARGET,
|
if (st_get_egl_image(ctx, image_handle, PIPE_BIND_RENDER_TARGET,
|
||||||
"glEGLImageTargetRenderbufferStorage",
|
"glEGLImageTargetRenderbufferStorage",
|
||||||
&stimg)) {
|
&stimg, &native_supported)) {
|
||||||
struct pipe_context *pipe = st_context(ctx)->pipe;
|
struct pipe_context *pipe = st_context(ctx)->pipe;
|
||||||
struct pipe_surface *ps, surf_tmpl;
|
struct pipe_surface *ps, surf_tmpl;
|
||||||
|
|
||||||
@@ -212,7 +216,8 @@ st_bind_egl_image(struct gl_context *ctx,
|
|||||||
struct gl_texture_object *texObj,
|
struct gl_texture_object *texObj,
|
||||||
struct gl_texture_image *texImage,
|
struct gl_texture_image *texImage,
|
||||||
struct st_egl_image *stimg,
|
struct st_egl_image *stimg,
|
||||||
bool tex_storage)
|
bool tex_storage,
|
||||||
|
bool native_supported)
|
||||||
{
|
{
|
||||||
struct st_context *st = st_context(ctx);
|
struct st_context *st = st_context(ctx);
|
||||||
struct st_texture_object *stObj;
|
struct st_texture_object *stObj;
|
||||||
@@ -239,34 +244,39 @@ st_bind_egl_image(struct gl_context *ctx,
|
|||||||
/* TODO RequiredTextureImageUnits should probably be reset back
|
/* TODO RequiredTextureImageUnits should probably be reset back
|
||||||
* to 1 somewhere if different texture is bound??
|
* to 1 somewhere if different texture is bound??
|
||||||
*/
|
*/
|
||||||
switch (stimg->format) {
|
if (!native_supported) {
|
||||||
case PIPE_FORMAT_NV12:
|
switch (stimg->format) {
|
||||||
texFormat = MESA_FORMAT_R_UNORM8;
|
case PIPE_FORMAT_NV12:
|
||||||
texObj->RequiredTextureImageUnits = 2;
|
texFormat = MESA_FORMAT_R_UNORM8;
|
||||||
break;
|
texObj->RequiredTextureImageUnits = 2;
|
||||||
case PIPE_FORMAT_P016:
|
break;
|
||||||
texFormat = MESA_FORMAT_R_UNORM16;
|
case PIPE_FORMAT_P016:
|
||||||
texObj->RequiredTextureImageUnits = 2;
|
texFormat = MESA_FORMAT_R_UNORM16;
|
||||||
break;
|
texObj->RequiredTextureImageUnits = 2;
|
||||||
case PIPE_FORMAT_IYUV:
|
break;
|
||||||
texFormat = MESA_FORMAT_R_UNORM8;
|
case PIPE_FORMAT_IYUV:
|
||||||
texObj->RequiredTextureImageUnits = 3;
|
texFormat = MESA_FORMAT_R_UNORM8;
|
||||||
break;
|
texObj->RequiredTextureImageUnits = 3;
|
||||||
case PIPE_FORMAT_YUYV:
|
break;
|
||||||
case PIPE_FORMAT_UYVY:
|
case PIPE_FORMAT_YUYV:
|
||||||
texFormat = MESA_FORMAT_RG_UNORM8;
|
case PIPE_FORMAT_UYVY:
|
||||||
texObj->RequiredTextureImageUnits = 2;
|
texFormat = MESA_FORMAT_RG_UNORM8;
|
||||||
break;
|
texObj->RequiredTextureImageUnits = 2;
|
||||||
case PIPE_FORMAT_AYUV:
|
break;
|
||||||
texFormat = MESA_FORMAT_R8G8B8A8_UNORM;
|
case PIPE_FORMAT_AYUV:
|
||||||
internalFormat = GL_RGBA;
|
texFormat = MESA_FORMAT_R8G8B8A8_UNORM;
|
||||||
texObj->RequiredTextureImageUnits = 1;
|
internalFormat = GL_RGBA;
|
||||||
break;
|
texObj->RequiredTextureImageUnits = 1;
|
||||||
case PIPE_FORMAT_XYUV:
|
break;
|
||||||
texFormat = MESA_FORMAT_R8G8B8X8_UNORM;
|
case PIPE_FORMAT_XYUV:
|
||||||
texObj->RequiredTextureImageUnits = 1;
|
texFormat = MESA_FORMAT_R8G8B8X8_UNORM;
|
||||||
break;
|
texObj->RequiredTextureImageUnits = 1;
|
||||||
default:
|
break;
|
||||||
|
default:
|
||||||
|
unreachable("unexpected emulated format");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
texFormat = st_pipe_format_to_mesa_format(stimg->format);
|
texFormat = st_pipe_format_to_mesa_format(stimg->format);
|
||||||
/* Use previously derived internalformat as specified by
|
/* Use previously derived internalformat as specified by
|
||||||
* EXT_EGL_image_storage.
|
* EXT_EGL_image_storage.
|
||||||
@@ -279,7 +289,6 @@ st_bind_egl_image(struct gl_context *ctx,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
assert(texFormat != MESA_FORMAT_NONE);
|
assert(texFormat != MESA_FORMAT_NONE);
|
||||||
|
|
||||||
@@ -311,12 +320,14 @@ st_egl_image_target_texture_2d(struct gl_context *ctx, GLenum target,
|
|||||||
GLeglImageOES image_handle)
|
GLeglImageOES image_handle)
|
||||||
{
|
{
|
||||||
struct st_egl_image stimg;
|
struct st_egl_image stimg;
|
||||||
|
bool native_supported;
|
||||||
|
|
||||||
if (!st_get_egl_image(ctx, image_handle, PIPE_BIND_SAMPLER_VIEW,
|
if (!st_get_egl_image(ctx, image_handle, PIPE_BIND_SAMPLER_VIEW,
|
||||||
"glEGLImageTargetTexture2D", &stimg))
|
"glEGLImageTargetTexture2D", &stimg,
|
||||||
|
&native_supported))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
st_bind_egl_image(ctx, texObj, texImage, &stimg, false);
|
st_bind_egl_image(ctx, texObj, texImage, &stimg, false, native_supported);
|
||||||
pipe_resource_reference(&stimg.texture, NULL);
|
pipe_resource_reference(&stimg.texture, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,12 +338,14 @@ st_egl_image_target_tex_storage(struct gl_context *ctx, GLenum target,
|
|||||||
GLeglImageOES image_handle)
|
GLeglImageOES image_handle)
|
||||||
{
|
{
|
||||||
struct st_egl_image stimg;
|
struct st_egl_image stimg;
|
||||||
|
bool native_supported;
|
||||||
|
|
||||||
if (!st_get_egl_image(ctx, image_handle, PIPE_BIND_SAMPLER_VIEW,
|
if (!st_get_egl_image(ctx, image_handle, PIPE_BIND_SAMPLER_VIEW,
|
||||||
"glEGLImageTargetTexture2D", &stimg))
|
"glEGLImageTargetTexture2D", &stimg,
|
||||||
|
&native_supported))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
st_bind_egl_image(ctx, texObj, texImage, &stimg, true);
|
st_bind_egl_image(ctx, texObj, texImage, &stimg, true, native_supported);
|
||||||
pipe_resource_reference(&stimg.texture, NULL);
|
pipe_resource_reference(&stimg.texture, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -71,8 +71,13 @@ st_get_external_sampler_key(struct st_context *st, struct gl_program *prog)
|
|||||||
unsigned unit = u_bit_scan(&mask);
|
unsigned unit = u_bit_scan(&mask);
|
||||||
struct st_texture_object *stObj =
|
struct st_texture_object *stObj =
|
||||||
st_get_texture_object(st->ctx, prog, unit);
|
st_get_texture_object(st->ctx, prog, unit);
|
||||||
|
enum pipe_format format = st_get_view_format(stObj);
|
||||||
|
|
||||||
switch (st_get_view_format(stObj)) {
|
/* if resource format matches then YUV wasn't lowered */
|
||||||
|
if (format == stObj->pt->format)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (format) {
|
||||||
case PIPE_FORMAT_NV12:
|
case PIPE_FORMAT_NV12:
|
||||||
case PIPE_FORMAT_P010:
|
case PIPE_FORMAT_P010:
|
||||||
case PIPE_FORMAT_P016:
|
case PIPE_FORMAT_P016:
|
||||||
@@ -95,7 +100,7 @@ st_get_external_sampler_key(struct st_context *st, struct gl_program *prog)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("mesa: st_get_external_sampler_key: unhandled pipe format %u\n",
|
printf("mesa: st_get_external_sampler_key: unhandled pipe format %u\n",
|
||||||
st_get_view_format(stObj));
|
format);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -489,6 +489,10 @@ get_sampler_view_format(struct st_context *st,
|
|||||||
if (srgb_skip_decode)
|
if (srgb_skip_decode)
|
||||||
format = util_format_linear(format);
|
format = util_format_linear(format);
|
||||||
|
|
||||||
|
/* if resource format matches then YUV wasn't lowered */
|
||||||
|
if (format == stObj->pt->format)
|
||||||
|
return format;
|
||||||
|
|
||||||
/* Use R8_UNORM for video formats */
|
/* Use R8_UNORM for video formats */
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case PIPE_FORMAT_NV12:
|
case PIPE_FORMAT_NV12:
|
||||||
|
Reference in New Issue
Block a user