[vlc-commits] [Git][videolan/vlc][master] 15 commits: opengl: interop_sw: warn when not rendering directly
Steve Lhomme (@robUx4)
gitlab at videolan.org
Fri Jan 17 15:05:29 UTC 2025
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
ddb10174 by Thomas Guillem at 2025-01-17T14:33:10+00:00
opengl: interop_sw: warn when not rendering directly
- - - - -
66e4a5e9 by Thomas Guillem at 2025-01-17T14:33:10+00:00
opengl: interop_sw: don't try opaque chromas
It is possible to get opaque chromas from vlc_fourcc_GetYUVFallback().
This fixes a vlc_assert_unreachable() in the desc->plane_count
switch/case.
It was unlikely as opaque chromas are generally at the end of the list.
- - - - -
32abaa35 by Thomas Guillem at 2025-01-17T14:33:10+00:00
opengl: sampler: specify sampler?D precision
Fixes the following error on GLES2 when using libplacebo shaders.
[00007fe3cc815910] gl generic error: Shader source:
1: #version 300 es
2: precision highp float;
3: uniform sampler2D Textures[3];
4: uniform mat3 _2;
5: uniform mat3 _3;
6: uniform mat3 _4;
7: uniform float _a;
8: uniform float _b;
9: uniform mat3 _19;
10: uniform sampler2D _6;
11: uniform sampler3D _d;
12:
13: const float _8 = float(0.001953125);
14: const float _9 = float(0.99609375);
15: #define _7(x) (_9 * (x) + _8)
16: #define _5(pos) (textureLod(_6, vec2(\
17: _7(float(pos))\
18: ,0.5\
19: ), 0.0).x)
20: const float _f = float(0.010416666977107525);
21: const float _10 = float(0.9791666269302368);
22: #define _e(x) (_10 * (x) + _f)
23: const float _12 = float(0.015625);
24: const float _13 = float(0.96875);
25: #define _11(x) (_13 * (x) + _12)
26: const float _15 = float(0.001953125);
27: const float _16 = float(0.99609375);
28: #define _14(x) (_16 * (x) + _15)
29: #define _c(pos) (textureLod(_d, vec3(\
30: _e(vec3(pos).x)\
31: ,_11(vec3(pos).y)\
32: ,_14(vec3(pos).z)\
33: ), 0.0).xyzw)
34: const float _17 = float(-0.16753844916820526);
35: const float _18 = float(2.0106043815612793);
36: const float _1a = float(0.0595848374068737);
37: const float _1b = float(1.149015188217163);
38: vec4 _1(vec4 color) {
39: // pl_shader_color_map
40: {
41: // pl_shader_linearize
42: color.rgb = max(color.rgb, 0.0);
43: color.rgb = pow(color.rgb, vec3(1.0/78.84375));
44: color.rgb = max(color.rgb - vec3(0.8359375), 0.0)
45: / (vec3(18.8515625) - vec3(18.6875) * color.rgb);
46: color.rgb = pow(color.rgb, vec3(1.0/0.1593017578125));
47: color.rgb *= vec3(49.26108374384236);
48: vec3 lms = _4 * color.rgb;
49: vec3 lmspq = 0.0203000009059906 * lms;
50: lmspq = pow(max(lmspq, 0.0), vec3(0.1593017578125));
51: lmspq = (vec3(0.8359375) + 18.8515625 * lmspq)
52: / (vec3(1.0) + 18.6875 * lmspq);
53: lmspq = pow(lmspq, vec3(78.84375));
54: vec3 ipt = _2 * lmspq;
55: float i_orig = ipt.x;
56: #define tone_map(x) (_5(_b * (x) + _a))
57: ipt.x = tone_map(ipt.x);
58: vec2 hull = vec2(i_orig, ipt.x);
59: hull = ((hull - 6.0) * hull + 9.0) * hull;
60: ipt.yz *= min(i_orig / ipt.x, hull.y / hull.x);
61: vec3 idx;
62: idx.x = _18 * ipt.x + _17;
63: idx.y = 2.0 * length(ipt.yz);
64: idx.z = 0.15915494309189535 * atan(ipt.z, ipt.y) + 0.5;
65: ipt = _c(idx).xyz;
66: ipt.yz -= vec2(32768.0/65535.0);
67: lmspq = _3 * ipt;
68: lms = pow(max(lmspq, 0.0), vec3(1.0/78.84375));
69: lms = max(lms - vec3(0.8359375), 0.0)
70: / (vec3(18.8515625) - 18.6875 * lms);
71: lms = pow(lms, vec3(1.0/0.1593017578125));
72: lms *= 49.261085510253906;
73: color.rgb = _19 * lms;
74: #undef tone_map
75: // pl_shader_delinearize
76: color.rgb = max(color.rgb, 0.0);
77: color.rgb = pow(_1b * color.rgb, vec3(1.0/2.4)) - vec3(_1a);
78: }
79: return color;
80: }
81:
82: uniform mat4 ConvMatrix;
83: vec4 vlc_texture(vec2 tex_coords) {
84: vec4 pixel = vec4(
85: texture(Textures[0], tex_coords).r
86: , texture(Textures[1], tex_coords).r
87: , texture(Textures[2], tex_coords).r
88: , 1.0);
89: vec4 result = ConvMatrix * pixel;
90: result = _1(result);
91: return result;
92: }
93: #if __VERSION__ < 300
94: #define FragColor gl_FragColor
95: varying vec2 PicCoords;
96: #else
97: in vec2 PicCoords;
98: out vec4 FragColor;
99: #endif
100: void main() {
101: FragColor = vlc_texture(PicCoords);
102: }
[00007fe3cc815910] gl generic error: shader: 0:11(1): error: No precision specified in this scope for type `sampler3D'
- - - - -
a7c3c204 by Thomas Guillem at 2025-01-17T14:33:10+00:00
opengl: interop_sw: fix >= 10bits rendering
Fixes a regression from 67bddf900c76ec30cd2f7d319714101a3ca0d61f
vlc_gl_interop_GetTexFormatSize() would always return an error for the
GL_R16UI / GL_RED combination. It's either GL_R16/GL_RED or
GL_R16UI/GL_RED_INTEGER.
But the sampler is using sampler2D and not usampler2D, so let's keep
GL_R16.
- - - - -
6eaedcc6 by Thomas Guillem at 2025-01-17T14:33:10+00:00
opengl: interop_sw: replace hardcoded value
Not fixing anything since it's always GL_UNSIGNED_SHORT for 16bits (for
now).
- - - - -
30425f09 by Thomas Guillem at 2025-01-17T14:33:10+00:00
opengl: interop_sw: add type in fixGLFormat()
This function does not change the type for now.
- - - - -
5b90bacc by Thomas Guillem at 2025-01-17T14:33:10+00:00
opengl: interop: add missing format in GetTexFormatSize()
- - - - -
afa5e3ef by Thomas Guillem at 2025-01-17T14:33:10+00:00
opengl: interop_sw: test fixed arguments
This could lead to false positives or negatives.
- - - - -
a6fc4ed1 by Thomas Guillem at 2025-01-17T14:33:10+00:00
opengl: interop_sw: check tex alloc from fixGLFormat()
- - - - -
e749eb32 by Thomas Guillem at 2025-01-17T14:33:10+00:00
opengl: interop_sw: add intermediate variables for readability
- - - - -
98fd945c by Thomas Guillem at 2025-01-17T14:33:10+00:00
opengl: interop_sw: rework fixGLFormat()
- - - - -
87200918 by Thomas Guillem at 2025-01-17T14:33:10+00:00
opengl: render 10bits with GL_EXT_texture_integer
When available.
- - - - -
1aca33a3 by Thomas Guillem at 2025-01-17T14:33:10+00:00
opengl: add R16F and HALF_FLOAT defines
- - - - -
bfbffa5b by Thomas Guillem at 2025-01-17T14:33:10+00:00
opengl: add planar >=10bits support on Android:
Via GL_HALF_FLOAT, should work starting GLES 3.0.
Semiplanar is not supported as a CPU pass may be necessary to convert to
HALF_FLOAT:
Indeed, half-float data format consists of 1 sign bit, 5 exponent bits
and 10 mantissa bits. If you try to treat P010’s integer layout as
half-float, the GPU misinterprets those bits as exponent and mantissa,
causing corruption.
- - - - -
d43e5e02 by Thomas Guillem at 2025-01-17T14:33:10+00:00
opengl: interop_sw: log when fixing GL format
- - - - -
6 changed files:
- modules/video_output/opengl/gl_common.h
- modules/video_output/opengl/importer.c
- modules/video_output/opengl/interop.c
- modules/video_output/opengl/interop_sw.c
- modules/video_output/opengl/picture.h
- modules/video_output/opengl/sampler.c
Changes:
=====================================
modules/video_output/opengl/gl_common.h
=====================================
@@ -76,6 +76,9 @@
#ifndef GL_R16UI
# define GL_R16UI 0x8234
#endif
+#ifndef GL_R16F
+# define GL_R16F 0x822D
+#endif
#ifndef GL_BGRA
# define GL_BGRA 0x80E1
#endif
@@ -127,6 +130,9 @@
#ifndef GL_DYNAMIC_DRAW
# define GL_DYNAMIC_DRAW 0x88E8
#endif
+#ifndef GL_HALF_FLOAT
+# define GL_HALF_FLOAT 0x140B
+#endif
#ifndef GL_READ_FRAMEBUFFER
# define GL_READ_FRAMEBUFFER 0x8CA8
=====================================
modules/video_output/opengl/importer.c
=====================================
@@ -220,6 +220,7 @@ vlc_gl_importer_New(struct vlc_gl_interop *interop)
glfmt->fmt = interop->fmt_out;
glfmt->tex_target = interop->tex_target;
glfmt->tex_count = interop->tex_count;
+ glfmt->half_float = interop->texs[0].type == GL_HALF_FLOAT;
/* This matrix may be updated on new pictures */
memcpy(&importer->mtx_coords_map, MATRIX2x3_IDENTITY,
=====================================
modules/video_output/opengl/interop.c
=====================================
@@ -123,10 +123,12 @@ static int GetTexFormatSize(struct vlc_gl_interop *interop, GLenum target,
mul = 4;
/* fall through */
case GL_RED:
+ case GL_RED_INTEGER:
case GL_RG:
tex_param_size = GL_TEXTURE_RED_SIZE;
break;
case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
tex_param_size = GL_TEXTURE_LUMINANCE_SIZE;
break;
default:
=====================================
modules/video_output/opengl/interop_sw.c
=====================================
@@ -47,7 +47,9 @@ struct priv
{
bool has_gl_3;
bool has_texture_rg;
+ bool has_texture_integer;
bool has_unpack_subimage;
+ bool unsigned_sampler;
void * texture_temp_buf;
size_t texture_temp_buf_size;
struct {
@@ -70,7 +72,8 @@ struct priv
X(PFNGLBUFFERSUBDATAPROC, BufferSubData) \
X(PFNGLDELETEBUFFERSPROC, DeleteBuffers) \
X(PFNGLGENBUFFERSPROC, GenBuffers) \
- X(PFNGLPIXELSTOREIPROC, PixelStorei)
+ X(PFNGLPIXELSTOREIPROC, PixelStorei) \
+ X(PFNGLTEXPARAMETERIPROC, TexParameteri)
struct {
#define DECLARE_SYMBOL(type, name) type name;
OPENGL_VTABLE_F(DECLARE_SYMBOL)
@@ -246,6 +249,14 @@ tc_common_allocate_textures(const struct vlc_gl_interop *interop, uint32_t textu
priv->gl.TexImage2D(interop->tex_target, 0, interop->texs[i].internal,
tex_width[i], tex_height[i], 0, interop->texs[i].format,
interop->texs[i].type, NULL);
+
+ /* Integer textures cannot be filtered using GL_LINEAR. They must use
+ * GL_NEAREST. */
+ if (priv->unsigned_sampler)
+ {
+ priv->gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ priv->gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ }
GL_ASSERT_NOERROR(&priv->gl);
}
return VLC_SUCCESS;
@@ -368,67 +379,135 @@ DivideRationalByTwo(vlc_rational_t *r) {
r->den *= 2;
}
-static bool fixGLFormat(struct vlc_gl_interop *interop, GLint* intfmt, GLint* fmt)
+static bool fixGLFormat(struct vlc_gl_interop *interop, unsigned pixel_size,
+ GLint* intfmt, GLint* fmt, GLint *type)
{
struct priv *priv = interop->priv;
if (*intfmt == 0)
return true;
- //GLES 3.0, OpenGL 3.0 and OpenGL with GL_ARB_texture_rg
- //don't need transformations
- if (priv->has_gl_3
- || (priv->has_texture_rg && interop->gl->api_type == VLC_OPENGL))
- return true;
+ bool gles2, gles3, gl2, gl3;
+ if (priv->has_gl_3)
+ {
+ gl3 = interop->gl->api_type == VLC_OPENGL;
+ gl2 = false;
+ gles3 = interop->gl->api_type == VLC_OPENGL_ES2;
+ gles2 = false;
+ }
+ else
+ {
+ gl3 = false;
+ gl2 = interop->gl->api_type == VLC_OPENGL;
+ gles3 = false;
+ gles2 = interop->gl->api_type == VLC_OPENGL_ES2;
+ }
+ assert(gl3 || gl2 || gles3 || gles2);
- //for GLES2 GL_EXT_texture_rg we need to use GL_RED/GL_RG as internal format
- if (priv->has_texture_rg)
+ if (gles3)
{
switch (*intfmt) {
case GL_R8:
+ case GL_RG8:
+ break;
+ case GL_R16:
+ if (priv->has_texture_integer)
+ {
+ msg_Dbg(interop->gl, "fallback to GL_R16UI");
+ *intfmt = GL_R16UI;
+ *fmt = GL_RED_INTEGER;
+ }
+
+ /* Android is unlikely to support GL_R16UI or GL_R16: */
+ if (vlc_gl_interop_GetTexFormatSize(interop, GL_TEXTURE_2D, *fmt,
+ *intfmt, *type) != 16)
+ {
+ /* XXX: Quality loss with 12 and 16bits since half float has
+ * 10bits of mantissa */
+ msg_Dbg(interop->gl, "fallback to GL_R16F");
+ *intfmt = GL_R16F;
+ *fmt = GL_RED;
+ *type = GL_HALF_FLOAT;
+ }
+ break;
+ case GL_RG16:
+ if (priv->has_texture_integer)
+ {
+ msg_Dbg(interop->gl, "fallback to GL_R1G6UI ?");
+ *intfmt = GL_RG16UI;
+ *fmt = GL_RED_INTEGER;
+ }
+ /* XXX Is GL_RG16F possible with semi planar ? */
+ break;
+ default:
+ vlc_assert_unreachable();
+ }
+ }
+ else if (gles2 && priv->has_texture_rg)
+ {
+ //for GLES2 GL_EXT_texture_rg we need to use GL_RED/GL_RG as internal format
+ switch (*intfmt) {
+ case GL_R8:
+ msg_Dbg(interop->gl, "fallback to GL_GED");
*intfmt = GL_RED;
*fmt = GL_RED;
break;
case GL_RG8:
+ msg_Dbg(interop->gl, "fallback to GL_RG8");
*intfmt = GL_RG;
*fmt = GL_RG;
break;
- case GL_R16UI:
- case GL_RG16UI:
+ case GL_R16:
+ case GL_RG16:
return false;
default:
vlc_assert_unreachable();
}
-
- return true;
}
+ else if (gles2 || (gl2 && !priv->has_texture_rg))
+ {
+ //fallback to GL_LUMINANCE / GL_LUMINANCE_ALPHA
+ switch (*intfmt) {
+ case GL_R8:
+ msg_Dbg(interop->gl, "fallback to GL_LUMINANCE");
+ *intfmt = GL_LUMINANCE;
+ *fmt = GL_LUMINANCE;
+ break;
+ case GL_R16:
+ if (gles2)
+ return false;
- //fallback to GL_LUMINANCE / GL_LUMINANCE_ALPHA
- switch (*intfmt) {
- case GL_R8:
- *intfmt = GL_LUMINANCE;
- *fmt = GL_LUMINANCE;
- break;
- case GL_R16UI:
- if (interop->gl->api_type == VLC_OPENGL_ES2)
- return false;
-
- *intfmt = GL_LUMINANCE16;
- *fmt = GL_LUMINANCE;
- break;
- case GL_RG8:
- *intfmt = GL_LUMINANCE_ALPHA;
- *fmt = GL_LUMINANCE_ALPHA;
- break;
- case GL_RG16UI:
- if (interop->gl->api_type == VLC_OPENGL_ES2)
- return false;
+ msg_Dbg(interop->gl, "fallback to GL_LUMINANCE16");
+ *intfmt = GL_LUMINANCE16;
+ *fmt = GL_LUMINANCE;
+ break;
+ case GL_RG8:
+ msg_Dbg(interop->gl, "fallback to GL_LUMINANCE_ALPHA");
+ *intfmt = GL_LUMINANCE_ALPHA;
+ *fmt = GL_LUMINANCE_ALPHA;
+ break;
+ case GL_RG16:
+ if (gles2)
+ return false;
- *intfmt = GL_LUMINANCE16_ALPHA16;
- *fmt = GL_LUMINANCE_ALPHA;
- break;
- default:
- vlc_assert_unreachable();
+ msg_Dbg(interop->gl, "fallback to GL_LUMINANCE16_ALPHA16");
+ *intfmt = GL_LUMINANCE16_ALPHA16;
+ *fmt = GL_LUMINANCE_ALPHA;
+ break;
+ default:
+ vlc_assert_unreachable();
+ }
}
+ else
+ {
+ //OpenGL 3.0 and OpenGL with GL_ARB_texture_rg
+ //don't need transformations
+ assert(gl3 || (gl2 && priv->has_texture_rg));
+ }
+
+ if (pixel_size == 2
+ && vlc_gl_interop_GetTexFormatSize(interop, GL_TEXTURE_2D, *fmt,
+ *intfmt, *type) != 16)
+ return false;
return true;
}
@@ -449,12 +528,12 @@ interop_yuv_base_init(struct vlc_gl_interop *interop,
// 8 bits pixels
{ GL_R8, GL_RED, 0, 0, GL_UNSIGNED_BYTE, 0 },
// 16 bits pixels
- { GL_R16UI, GL_RED, 0, 0, GL_UNSIGNED_SHORT, 0 },
+ { GL_R16, GL_RED, 0, 0, GL_UNSIGNED_SHORT, 0 },
// 2 planes
// 8 bits pixels
{ GL_R8, GL_RED, GL_RG8, GL_RG, GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE },
// 16 bits pixels
- { GL_R16UI, GL_RED, GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_SHORT },
+ { GL_R16, GL_RED, GL_RG16, GL_RG, GL_UNSIGNED_SHORT, GL_UNSIGNED_SHORT },
// 1 plane is a special case that will be handled explicitly
};
@@ -481,17 +560,18 @@ interop_yuv_base_init(struct vlc_gl_interop *interop,
* #26712. */
GLint intfmt = GL_RG8;
GLint fmt = GL_RG;
- if (!fixGLFormat(interop, &intfmt, &fmt))
+ GLint type = GL_UNSIGNED_BYTE;
+ if (!fixGLFormat(interop, desc->pixel_size, &intfmt, &fmt, &type))
return VLC_EGENERIC;
interop->tex_count = 2;
interop->texs[0] = (struct vlc_gl_tex_cfg) {
{ 1, 1 }, { 1, 1 },
- intfmt, fmt, GL_UNSIGNED_BYTE
+ intfmt, fmt, type
};
interop->texs[1] = (struct vlc_gl_tex_cfg) {
{ 1, 2 }, { 1, 1 },
- GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE
+ GL_RGBA, GL_RGBA, type
};
return VLC_SUCCESS;
}
@@ -527,27 +607,23 @@ interop_yuv_base_init(struct vlc_gl_interop *interop,
GLint plane1_intfmt = format->intfmt;
GLint plane1_fmt = format->fmt;
- if (!fixGLFormat(interop, &plane1_intfmt, &plane1_fmt))
+ GLint plane1_type = format->type;
+ if (!fixGLFormat(interop, desc->pixel_size, &plane1_intfmt, &plane1_fmt,
+ &plane1_type))
return VLC_EGENERIC;
GLint plane2_intfmt = format->plane2_intfmt;
GLint plane2_fmt = format->plane2_fmt;
- if (!fixGLFormat(interop, &plane2_intfmt, &plane2_fmt))
+ GLint plane2_type = format->plane2_type;
+ if (!fixGLFormat(interop, desc->pixel_size, &plane2_intfmt, &plane2_fmt,
+ &plane2_type))
return VLC_EGENERIC;
msg_Dbg(interop, "Using format at index %u", format_index);
msg_Dbg(interop, "Plane1: fmt=%#x intfmt=%#x type=%#x", plane1_fmt,
- plane1_intfmt, format->type);
+ plane1_intfmt, plane1_type);
msg_Dbg(interop, "Plane2: fmt=%#x intfmt=%#x type=%#x", plane2_fmt,
- plane2_intfmt, format->plane2_type);
-
-
- if (desc->pixel_size == 2)
- {
- if (vlc_gl_interop_GetTexFormatSize(interop, GL_TEXTURE_2D, format->fmt,
- format->intfmt, GL_UNSIGNED_SHORT) != 16)
- return VLC_EGENERIC;
- }
+ plane2_intfmt, plane2_type);
if (desc->plane_count >= 3)
{
@@ -557,7 +633,7 @@ interop_yuv_base_init(struct vlc_gl_interop *interop,
interop->texs[i] = (struct vlc_gl_tex_cfg) {
{ desc->p[i].w.num, desc->p[i].w.den },
{ desc->p[i].h.num, desc->p[i].h.den },
- plane1_intfmt, plane1_fmt, format->type
+ plane1_intfmt, plane1_fmt, plane1_type
};
}
}
@@ -565,22 +641,15 @@ interop_yuv_base_init(struct vlc_gl_interop *interop,
{
interop->tex_count = 2;
- if (desc->pixel_size == 2 &&
- vlc_gl_interop_GetTexFormatSize(interop, GL_TEXTURE_2D, format->plane2_fmt,
- format->plane2_intfmt, format->plane2_type) != 16)
- {
- return VLC_EGENERIC;
- }
-
interop->texs[0] = (struct vlc_gl_tex_cfg) {
{ desc->p[0].w.num, desc->p[0].w.den },
{ desc->p[0].h.num, desc->p[0].h.den },
- plane1_intfmt, plane1_fmt, format->type
+ plane1_intfmt, plane1_fmt, plane1_type
};
interop->texs[1] = (struct vlc_gl_tex_cfg) {
{ desc->p[1].w.num, desc->p[1].w.den },
{ desc->p[1].h.num, desc->p[1].h.den },
- plane2_intfmt, plane2_fmt, format->plane2_type
+ plane2_intfmt, plane2_fmt, plane2_type
};
/*
@@ -655,7 +724,7 @@ opengl_interop_init(struct vlc_gl_interop *interop,
{
const vlc_chroma_description_t *desc =
vlc_fourcc_GetChromaDescription(chroma);
- if (!desc)
+ if (!desc || desc->plane_count == 0)
return VLC_EGENERIC;
assert(!interop->fmt_out.p_palette);
@@ -718,6 +787,10 @@ opengl_interop_generic_init(struct vlc_gl_interop *interop, bool allow_dr)
|| (interop->gl->api_type == VLC_OPENGL_ES2
&& vlc_gl_HasExtension(&extension_vt, "GL_EXT_texture_rg"));
+ priv->has_texture_integer = priv->has_gl_3 &&
+ (interop->gl->api_type == VLC_OPENGL
+ || vlc_gl_HasExtension(&extension_vt, "GL_EXT_texture_integer"));
+
video_color_space_t space;
const vlc_fourcc_t *list;
const bool is_yup = vlc_fourcc_IsYUV(interop->fmt_in.i_chroma);
@@ -770,6 +843,10 @@ opengl_interop_generic_init(struct vlc_gl_interop *interop, bool allow_dr)
if (ret == VLC_SUCCESS)
{
i_chroma = *list;
+ msg_Warn(interop->gl, "direct rendering failed for %4.4s, "
+ "fallback to %4.4s",
+ (const char *)&interop->fmt_in.i_chroma,
+ (const char *)&i_chroma);
goto interop_init;
}
list++;
@@ -790,6 +867,17 @@ interop_init:
};
interop->ops = &ops;
+ switch (interop->texs[0].format)
+ {
+ case GL_RED_INTEGER:
+ case GL_RG_INTEGER:
+ priv->unsigned_sampler = true;
+ break;
+ default:
+ priv->unsigned_sampler = false;
+ break;
+ }
+
if (allow_dr && priv->has_unpack_subimage)
{
/* Ensure we do direct rendering / PBO with OpenGL 3.0 or higher. */
=====================================
modules/video_output/opengl/picture.h
=====================================
@@ -42,6 +42,7 @@ struct vlc_gl_format {
GLsizei tex_heights[PICTURE_PLANE_MAX];
uint32_t formats[PICTURE_PLANE_MAX];
+ bool half_float;
};
/**
=====================================
modules/video_output/opengl/sampler.c
=====================================
@@ -57,6 +57,7 @@ struct vlc_gl_sampler_priv {
} uloc;
bool yuv_color;
+ bool unsigned_sampler;
GLfloat conv_matrix[4*4];
#ifdef HAVE_LIBPLACEBO_GL
@@ -186,6 +187,14 @@ sampler_yuv_base_init(struct vlc_gl_sampler *sampler,
float *matrix = priv->conv_matrix;
init_conv_matrix(matrix, yuv_space, range);
+ /* If using half_float, we multiply the conversion matrix by 255. Reason:
+ * half-float YUV planes store values in [0..1]. Multiplying by 255
+ * compensates for that.
+ */
+ if (sampler->glfmt.half_float)
+ for (int i = 0; i < 4*3; ++i)
+ matrix[i] *= 255;
+
if (desc->pixel_size == 2)
{
if (desc->fcc != VLC_CODEC_P010 && desc->fcc != VLC_CODEC_P012
@@ -541,7 +550,7 @@ GetNames(struct vlc_gl_sampler *sampler, GLenum tex_target,
*texture = has_texture_func ? "texture" : "texture2D";
break;
case GL_TEXTURE_2D:
- *glsl_sampler = "sampler2D";
+ *glsl_sampler = priv->unsigned_sampler ? "usampler2D" : "sampler2D";
*texture = has_texture_func ? "texture" : "texture2D";
break;
case GL_TEXTURE_RECTANGLE:
@@ -880,6 +889,21 @@ opengl_fragment_shader_init(struct vlc_gl_sampler *sampler, bool expose_planes)
unsigned color_count;
if (is_yuv) {
+
+ if (priv->unsigned_sampler)
+ {
+ /* One extra integer -> float step will be needed */
+ for (unsigned i = 0; i < tex_count; ++i)
+ {
+ if (tex_target == GL_TEXTURE_RECTANGLE)
+ ADDF(" uvec4 t%u = %s(Textures[%u], TexSizes[%u] * tex_coords);\n",
+ i, lookup, i, i);
+ else
+ ADDF(" uvec4 t%u = %s(Textures[%u], tex_coords);\n",
+ i, lookup, i);
+ }
+ }
+
ADD(" vec4 pixel = vec4(\n");
color_count = 0;
for (unsigned i = 0; i < tex_count; ++i)
@@ -890,7 +914,13 @@ opengl_fragment_shader_init(struct vlc_gl_sampler *sampler, bool expose_planes)
assert(color_count < PICTURE_PLANE_MAX);
if (i > 0)
ADD(" ,");
- if (tex_target == GL_TEXTURE_RECTANGLE)
+
+ if (priv->unsigned_sampler)
+ {
+ /* Integer -> float */
+ ADDF(" float(t%u.%s) / 65535.0\n", i, swizzle);
+ }
+ else if (tex_target == GL_TEXTURE_RECTANGLE)
{
/* The coordinates are in texels values, not normalized */
ADDF(" %s(Textures[%u], TexSizes[%u] * tex_coords).%s\n", lookup, i, i, swizzle);
@@ -991,9 +1021,30 @@ vlc_gl_sampler_New(struct vlc_gl_t *gl, const struct vlc_gl_api *api,
sampler->shader.extensions = NULL;
sampler->shader.body = NULL;
+ switch (sampler->glfmt.formats[0])
+ {
+ case GL_RED_INTEGER:
+ case GL_RG_INTEGER:
+ priv->unsigned_sampler = true;
+ break;
+ default:
+ priv->unsigned_sampler = false;
+ break;
+ }
+
int glsl_version;
if (api->is_gles) {
- sampler->shader.precision = "precision highp float;\n";
+#define GLES_COMMON_PRECISION \
+ "precision highp float;\n" \
+ "precision highp sampler2D;\n" \
+ "precision highp sampler3D;\n"
+
+ if (priv->unsigned_sampler)
+ sampler->shader.precision = GLES_COMMON_PRECISION
+ "precision highp usampler2D;\n";
+ else
+ sampler->shader.precision = GLES_COMMON_PRECISION;
+
if (api->glsl_version >= 300) {
sampler->shader.version = strdup("#version 300 es\n");
glsl_version = 300;
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/cda249f4ffd150539dfc145b7ee2fcaca7ab67c3...d43e5e029229fef6a6f03c594e9bdcff0d8a6ba4
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/cda249f4ffd150539dfc145b7ee2fcaca7ab67c3...d43e5e029229fef6a6f03c594e9bdcff0d8a6ba4
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list