BACKPORT: UPSTREAM: mesa/st: Account for YUV color space and range.
- Upstream patch description:
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 <andrescj@chromium.org>
Reviewed-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16651>
(cherry picked from commit cd04679a08c7c276a7cadad5ddb5ced540d95300)
- Upstream MR:
https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16651
- Upstream commit:
https://gitlab.freedesktop.org/mesa/mesa/-/commit/cd04679a08c7c276a7cadad5ddb5ced540d95300
- Conflicts:
In st_program.c: it looks like st_create_fp_variant() has changed quite
a bit upstream. I went ahead and added the new options.bt709_external,
options.bt2020_external, and options.yuv_full_range_external right above
the NIR_PASS_V(state.ir.nir, nir_lower_tex, &options) call in the
ChromeOS version of st_create_fp_variant().
BUG=b:220336463
TEST=Play full-range video on drallion with the mesa-iris driver
Cq-Depend: chromium:3718548
Change-Id: I85d483eb06bfba03ff7c03afb8a7f7ba28a49e74
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/mesa/+/3718549
Tested-by: Andres Calderon Jaramillo <andrescj@chromium.org>
Commit-Queue: Andres Calderon Jaramillo <andrescj@chromium.org>
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
Reviewed-by: Chad Versace <chadversary@chromium.org>
diff --git a/src/gallium/frontends/dri/dri_screen.c b/src/gallium/frontends/dri/dri_screen.c
index e68a8c1..a57d8dd 100644
--- a/src/gallium/frontends/dri/dri_screen.c
+++ b/src/gallium/frontends/dri/dri_screen.c
@@ -458,6 +458,9 @@
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 c7aab40..57a6a45 100644
--- a/src/gallium/include/frontend/api.h
+++ b/src/gallium/include/frontend/api.h
@@ -187,6 +187,12 @@
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 cd2af9f..fec26d2 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -893,6 +893,16 @@
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 @@
*/
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 0768db8..0912c35 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 <olv@lunarg.com>
*/
+#include <GL/internal/dri_interface.h>
#include "main/errors.h"
#include "main/texobj.h"
#include "main/teximage.h"
@@ -382,6 +383,22 @@
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 46b4455..18ad5cf 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -1465,6 +1465,9 @@
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 3570d3d..5dd63c2 100644
--- a/src/mesa/state_tracker/st_program.h
+++ b/src/mesa/state_tracker/st_program.h
@@ -57,6 +57,9 @@
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
@@ -126,6 +129,20 @@
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;