Module: Mesa Branch: main Commit: cd04679a08c7c276a7cadad5ddb5ced540d95300 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=cd04679a08c7c276a7cadad5ddb5ced540d95300
Author: Andres Calderon Jaramillo <[email protected]> Date: Sat May 21 23:27:34 2022 +0000 mesa/st: Account for YUV color space and range. This patch plumbs the YUV color space and range provided through EGL_EXT_image_dma_buf_import all the way to nir_lower_tex(). NIR already accounts for the YUV color space courtesy of commit d8fdb8da. However, the color space was wired only for i965/i915 (see 6c11a799) and not for Gallium. Tested-by: Andres Calderon Jaramillo <[email protected]> Reviewed-by: Rob Clark <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16651> --- src/gallium/frontends/dri/dri_screen.c | 3 +++ src/gallium/include/frontend/api.h | 6 ++++++ src/mesa/main/mtypes.h | 16 ++++++++++++++++ src/mesa/state_tracker/st_cb_eglimage.c | 17 +++++++++++++++++ src/mesa/state_tracker/st_program.c | 3 +++ src/mesa/state_tracker/st_program.h | 17 +++++++++++++++++ 6 files changed, 62 insertions(+) diff --git a/src/gallium/frontends/dri/dri_screen.c b/src/gallium/frontends/dri/dri_screen.c index f331057fdcb..ffc5a50adeb 100644 --- a/src/gallium/frontends/dri/dri_screen.c +++ b/src/gallium/frontends/dri/dri_screen.c @@ -747,6 +747,9 @@ dri_get_egl_image(struct st_manager *smapi, stimg->internalformat = driGLFormatToSizedInternalGLFormat(mesa_format); } + stimg->yuv_color_space = img->yuv_color_space; + stimg->yuv_range = img->sample_range; + return TRUE; } diff --git a/src/gallium/include/frontend/api.h b/src/gallium/include/frontend/api.h index c7aab405159..57a6a453e1f 100644 --- a/src/gallium/include/frontend/api.h +++ b/src/gallium/include/frontend/api.h @@ -187,6 +187,12 @@ struct st_egl_image unsigned layer; /* GL internal format. */ unsigned internalformat; + + /* one of __DRI_YUV_COLOR_SPACE_* */ + unsigned yuv_color_space; + + /* one of __DRI_YUV_RANGE_* */ + unsigned yuv_range; }; /** diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 4fa389d7e00..670a40ee545 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -893,6 +893,16 @@ struct gl_sampler_object struct util_dynarray Handles; }; +/** + * YUV color space that should be used to sample textures backed by YUV + * images. + */ +enum gl_texture_yuv_color_space +{ + GL_TEXTURE_YUV_COLOR_SPACE_REC601, + GL_TEXTURE_YUV_COLOR_SPACE_REC709, + GL_TEXTURE_YUV_COLOR_SPACE_REC2020, +}; /** * Texture object state. Contains the array of mipmap images, border color, @@ -1009,6 +1019,12 @@ struct gl_texture_object */ enum pipe_format surface_format; + /* If surface_based is true and surface_format is a YUV format, these + * settings should be used to convert from YUV to RGB. + */ + enum gl_texture_yuv_color_space yuv_color_space; + bool yuv_full_range; + /* When non-negative, samplers should use this level instead of the level * range specified by the GL state. * diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c index 0768db8cf7c..0912c35f5ae 100644 --- a/src/mesa/state_tracker/st_cb_eglimage.c +++ b/src/mesa/state_tracker/st_cb_eglimage.c @@ -25,6 +25,7 @@ * Chia-I Wu <[email protected]> */ +#include <GL/internal/dri_interface.h> #include "main/errors.h" #include "main/texobj.h" #include "main/teximage.h" @@ -382,6 +383,22 @@ st_bind_egl_image(struct gl_context *ctx, st->screen->resource_changed(st->screen, texImage->pt); texObj->surface_format = stimg->format; + + switch (stimg->yuv_color_space) { + case __DRI_YUV_COLOR_SPACE_ITU_REC709: + texObj->yuv_color_space = GL_TEXTURE_YUV_COLOR_SPACE_REC709; + break; + case __DRI_YUV_COLOR_SPACE_ITU_REC2020: + texObj->yuv_color_space = GL_TEXTURE_YUV_COLOR_SPACE_REC2020; + break; + default: + texObj->yuv_color_space = GL_TEXTURE_YUV_COLOR_SPACE_REC601; + break; + } + + if (stimg->yuv_range == __DRI_YUV_FULL_RANGE) + texObj->yuv_full_range = true; + texObj->level_override = stimg->level; texObj->layer_override = stimg->layer; diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 159658a2b8a..3cd167ab095 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -1020,6 +1020,9 @@ st_create_fp_variant(struct st_context *st, options.lower_yuv_external = key->external.lower_yuv; options.lower_yu_yv_external = key->external.lower_yu_yv; options.lower_y41x_external = key->external.lower_y41x; + options.bt709_external = key->external.bt709; + options.bt2020_external = key->external.bt2020; + options.yuv_full_range_external = key->external.yuv_full_range; NIR_PASS_V(state.ir.nir, nir_lower_tex, &options); finalize = true; need_lower_tex_src_plane = true; diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index da2b9aaf7bc..c9d1676625e 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -56,6 +56,9 @@ struct st_external_sampler_key GLuint lower_yuv; GLuint lower_yu_yv; GLuint lower_y41x; + GLuint bt709; + GLuint bt2020; + GLuint yuv_full_range; }; static inline struct st_external_sampler_key @@ -125,6 +128,20 @@ st_get_external_sampler_key(struct st_context *st, struct gl_program *prog) format); break; } + + switch (stObj->yuv_color_space) { + case GL_TEXTURE_YUV_COLOR_SPACE_REC601: + break; + case GL_TEXTURE_YUV_COLOR_SPACE_REC709: + key.bt709 |= (1 << unit); + break; + case GL_TEXTURE_YUV_COLOR_SPACE_REC2020: + key.bt2020 |= (1 << unit); + break; + } + + if (stObj->yuv_full_range) + key.yuv_full_range |= (1 << unit); } return key;
