sh_lut: emulate texelFetch() on GLSL < 130

The texture-backed LUT accessor is emitted unconditionally as

    #define NAME(pos) (texelFetch(tex, ivec2(pos), 0).x)

but texelFetch() only exists in GLSL 130 / GLSL ES 300 and up. On a legacy
GL 2.x context (GLSL 120) every shader that instantiates a texture LUT fails
to compile:

    ERROR: 0:58: Invalid call of undeclared identifier 'texelFetch'
    Failed compiling/linking GLSL program
    Failed creating pass / Failed rendering image!

In practice this hits pl_shader_dither(): mpv's default dither (fruit/blue
noise) builds a 64x64 LUT, so *every* render pass fails and the window stays
a solid colour. It stayed hidden on GPUs without GL_ARB_texture_rg, because
there sh_lut() cannot allocate the LUT texture at all ("Can't generate LUT:
no compatible methods!") and dithering falls back to the procedural white
noise path. It appears as soon as the GL 2.1 driver does expose r8/r16
(e.g. Intel HD 4000 on macOS 10.15 with a legacy NSOpenGL context).

Fix: when the target is GLSL < 130, emit a nearest-neighbour lookup at
normalized coordinates instead. The LUT dimensions are fixed at shader
generation time, so texel_scale(size, /* normalized */ false) already gives
exactly the (i + 0.5) / size mapping needed to address a texel centre; the
texture is bound with PL_TEX_SAMPLE_NEAREST, so the result is bit-identical
to texelFetch(). This mirrors the structure of the is_linear branch directly
above it. Restricted to PL_VAR_FLOAT LUTs, since integer samplers do not
exist below GLSL 130 anyway.

Generated GLSL, GLSL 120 (dither LUT, 64x64, 1 component):

    #define _7(x) (_9 * (x) + _8)
    #define _a(x) (_c * (x) + _b)
    #define _5(pos) (texture2D(_6, vec2(\
        _7(float(ivec2(pos).x))\
       ,_a(float(ivec2(pos).y))\
      )).x)
    ...
    bias = _5(ivec2(pos * _e));

GLSL >= 130 output is unchanged (still texelFetch).

Verified against libplacebo v7.360.1 by generating the shader with a dummy
GPU pinned to glsl.version = 120 and max_variable_comps = 0 (to force the
texture LUT path); output above. Not upstream-submitted; upstream requires
GL >= 3.0 for the OpenGL backend, so this only matters together with the
GL2 backport patches.

Applies on top of libplacebo-gl2-complete.patch, -osd-crashfix.patch and
-16bit-luminance.patch (and also to a pristine v7.360.1 tree, with offset).

--- a/src/shaders/lut.c
+++ b/src/shaders/lut.c
@@ -651,6 +651,41 @@
                 }
             }
             GLSLH("  ), 0.0).%s)\n", swizzles[params->comps - 1]);
+        } else if (sh_glsl(sh).version < 130 && vartype == PL_VAR_FLOAT) {
+            // texelFetch() requires GLSL 130 / GLSL ES 300. On older versions,
+            // emulate it with a nearest-neighbour lookup at normalized
+            // coordinates: the LUT dimensions are known at shader generation
+            // time, so texel_scale() can map an integer texel index onto the
+            // corresponding texel center statically.
+            static const char *const legacy_tex_fn[] = {
+                "texture1D", "texture2D", "texture3D",
+            };
+
+            PL_DEBUG(sh, "GLSL < 130: emulating texelFetch() for LUT lookup");
+
+            ident_t pos_macros[PL_ARRAY_SIZE(sizes)] = {0};
+            for (int i = 0; i < dims; i++)
+                pos_macros[i] = texel_scale(sh, sizes[i], false);
+
+            GLSLH("#define "$"(pos) (%s("$", %s(\\\n",
+                  name, legacy_tex_fn[texdim - 1], tex,
+                  vartypes[PL_VAR_FLOAT][texdim - 1]);
+
+            for (int i = 0; i < texdim; i++) {
+                char sep = i == 0 ? ' ' : ',';
+                if (pos_macros[i]) {
+                    if (dims > 1) {
+                        GLSLH("   %c"$"(float(%s(pos).%c))\\\n", sep,
+                              pos_macros[i], vartypes[PL_VAR_SINT][dims - 1],
+                              "xyzw"[i]);
+                    } else {
+                        GLSLH("   %c"$"(float(pos))\\\n", sep, pos_macros[i]);
+                    }
+                } else {
+                    GLSLH("   %c%f\\\n", sep, 0.5);
+                }
+            }
+            GLSLH("  )).%s)\n", swizzles[params->comps - 1]);
         } else {
             GLSLH("#define "$"(pos) (texelFetch("$", %s(pos",
                   name, tex, vartypes[PL_VAR_SINT][texdim - 1]);
