glsl: lower samplers with highp coordinates correctly
authorMarek Olšák <marek.olsak@amd.com>
Sun, 10 May 2020 22:00:55 +0000 (18:00 -0400)
committerMarge Bot <eric+marge@anholt.net>
Tue, 2 Jun 2020 20:01:18 +0000 (20:01 +0000)
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Reviewed-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5002>

src/compiler/glsl/lower_precision.cpp
src/compiler/glsl/tests/lower_precision_test.py

index faa990703e6d38422f640f4232222ce439dbd589..11ae598920c2aa0a946a3dbb4fd9b3aae875fbe8 100644 (file)
@@ -449,6 +449,24 @@ is_lowerable_builtin(ir_call *ir,
          return desc->channel[i].size <= 10; /* unorm/snorm */
    }
 
+   /* Handle special calls. */
+   if (ir->callee->is_builtin() && ir->actual_parameters.length()) {
+      ir_rvalue *param = (ir_rvalue*)ir->actual_parameters.get_head();
+      ir_variable *var = param->variable_referenced();
+
+      /* Handle builtin wrappers around ir_texture opcodes. These wrappers will
+       * be inlined by lower_precision() if we return true here, so that we can
+       * get to ir_texture later and do proper lowering.
+       *
+       * We should lower the type of the return value if the sampler type
+       * uses lower precision. The function parameters don't matter.
+       */
+      if (var && var->type->without_array()->is_sampler()) {
+         return var->data.precision == GLSL_PRECISION_MEDIUM ||
+                var->data.precision == GLSL_PRECISION_LOW;
+      }
+   }
+
    if (!ir->callee->is_builtin())
       return false;
 
index 45175262878f4061d5af25d1693b46ee7abff284..65f3e25b0d743f4f4c8aae997a06bd95d5f83e7a 100644 (file)
@@ -921,12 +921,33 @@ TESTS = [
          }
          """,
          r'\(expression +uint +/'),
+    Test("f32 sampler array",
+         """
+         #version 320 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform sampler2D tex[2];
+         // highp shouldn't affect the return value of texture2D
+         uniform highp vec2 coord;
+         uniform float divisor;
+         uniform int index;
+
+         out highp vec4 color;
+
+         void main()
+         {
+                 color = texture2D(tex[index], coord) / divisor;
+         }
+         """,
+         r'\(expression +f16vec4 +/.*\(tex +f16vec4 +'),
     Test("f32 texture sample",
          """
          precision mediump float;
 
          uniform sampler2D tex;
-         uniform vec2 coord;
+         // highp shouldn't affect the return value of texture2D
+         uniform highp vec2 coord;
          uniform float divisor;
 
          void main()
@@ -942,7 +963,8 @@ TESTS = [
          precision mediump int;
 
          uniform mediump isampler2D tex;
-         uniform vec2 coord;
+         // highp shouldn't affect the return value of texture
+         uniform highp vec2 coord;
          uniform int divisor;
 
          out highp ivec4 color;
@@ -960,7 +982,8 @@ TESTS = [
          precision mediump int;
 
          uniform mediump usampler2D tex;
-         uniform vec2 coord;
+         // highp shouldn't affect the return value of texture
+         uniform highp vec2 coord;
          uniform uint divisor;
 
          out highp uvec4 color;
@@ -996,7 +1019,8 @@ TESTS = [
          precision mediump int;
 
          layout(rgba16f) readonly uniform mediump image2D img;
-         uniform ivec2 coord;
+         // highp shouldn't affect the return value of imageLoad
+         uniform highp ivec2 coord;
          uniform float divisor;
 
          out highp vec4 color;
@@ -1014,7 +1038,8 @@ TESTS = [
          precision mediump int;
 
          layout(rgba16i) readonly uniform mediump iimage2D img;
-         uniform ivec2 coord;
+         // highp shouldn't affect the return value of imageLoad
+         uniform highp ivec2 coord;
          uniform int divisor;
 
          out highp ivec4 color;
@@ -1032,7 +1057,8 @@ TESTS = [
          precision mediump int;
 
          layout(rgba16ui) readonly uniform mediump uimage2D img;
-         uniform ivec2 coord;
+         // highp shouldn't affect the return value of imageLoad
+         uniform highp ivec2 coord;
          uniform uint divisor;
 
          out highp uvec4 color;