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 */ +#include #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;