[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