glsl: lower mediump integer types to int16 and uint16
authorMarek Olšák <marek.olsak@amd.com>
Sat, 9 May 2020 02:42:43 +0000 (22:42 -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/glsl_parser_extras.cpp
src/compiler/glsl/ir_optimization.h
src/compiler/glsl/lower_precision.cpp
src/compiler/glsl/standalone.cpp
src/compiler/glsl/tests/lower_precision_test.py
src/mesa/main/mtypes.h
src/mesa/state_tracker/st_extensions.c

index e610fda002c979b1a77354b2c4c3ff557b4880e3..c0f116b8fb4fe19263b313de9fea9b7259a91f48 100644 (file)
@@ -2246,8 +2246,8 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader,
       &ctx->Const.ShaderCompilerOptions[shader->Stage];
 
    if (!state->error && !shader->ir->is_empty()) {
-      if (options->LowerPrecision)
-         lower_precision(shader->ir);
+      if (options->LowerPrecisionFloat16 || options->LowerPrecisionInt16)
+         lower_precision(options, shader->ir);
       lower_builtins(shader->ir);
       assign_subroutine_indexes(state);
       lower_subroutine(shader->ir, state);
index 23365df10a38a71a4bf7ff2be1fe60b750de67a6..0274ad260dae34083f8a7f4d3b84546a610fda81 100644 (file)
@@ -188,6 +188,7 @@ ir_variable *compare_index_block(ir_builder::ir_factory &body,
 bool lower_64bit_integer_instructions(exec_list *instructions,
                                       unsigned what_to_lower);
 
-bool lower_precision(exec_list *instructions);
+bool lower_precision(const struct gl_shader_compiler_options *options,
+                     exec_list *instructions);
 
 #endif /* GLSL_IR_OPTIMIZATION_H */
index 9ba1efafa01c92f8aaa61d5fbea595d4d74888b8..44cc7969204d784a9d38c1d5fd7f13d5e753657c 100644 (file)
@@ -26,6 +26,7 @@
  */
 
 #include "main/macros.h"
+#include "main/mtypes.h"
 #include "compiler/glsl_types.h"
 #include "ir.h"
 #include "ir_builder.h"
@@ -40,7 +41,7 @@ namespace {
 
 class find_precision_visitor : public ir_rvalue_enter_visitor {
 public:
-   find_precision_visitor();
+   find_precision_visitor(const struct gl_shader_compiler_options *options);
    ~find_precision_visitor();
 
    virtual void handle_rvalue(ir_rvalue **rvalue);
@@ -67,6 +68,8 @@ public:
    struct hash_table *clone_ht;
 
    void *lowered_builtin_mem_ctx;
+
+   const struct gl_shader_compiler_options *options;
 };
 
 class find_lowerable_rvalues_visitor : public ir_hierarchical_visitor {
@@ -102,7 +105,9 @@ public:
       std::vector<ir_instruction *> lowerable_children;
    };
 
-   find_lowerable_rvalues_visitor(struct set *result);
+   find_lowerable_rvalues_visitor(struct set *result,
+                                  const struct gl_shader_compiler_options *options);
+   bool can_lower_type(const glsl_type *type) const;
 
    static void stack_enter(class ir_instruction *ir, void *data);
    static void stack_leave(class ir_instruction *ir, void *data);
@@ -118,14 +123,15 @@ public:
    virtual ir_visitor_status visit_leave(ir_assignment *ir);
    virtual ir_visitor_status visit_leave(ir_call *ir);
 
-   static can_lower_state handle_precision(const glsl_type *type,
-                                           int precision);
+   can_lower_state handle_precision(const glsl_type *type,
+                                    int precision) const;
 
    static parent_relation get_parent_relation(ir_instruction *parent,
                                               ir_instruction *child);
 
    std::vector<stack_entry> stack;
    struct set *lowerable_rvalues;
+   const struct gl_shader_compiler_options *options;
 
    void pop_stack_entry();
    void add_lowerable_children(const stack_entry &entry);
@@ -142,7 +148,7 @@ public:
 };
 
 bool
-can_lower_type(const glsl_type *type)
+find_lowerable_rvalues_visitor::can_lower_type(const glsl_type *type) const
 {
    /* Don’t lower any expressions involving non-float types except bool and
     * texture samplers. This will rule out operations that change the type such
@@ -152,19 +158,30 @@ can_lower_type(const glsl_type *type)
     */
 
    switch (type->base_type) {
-   case GLSL_TYPE_FLOAT:
+   /* TODO: should we do anything for these two with regard to Int16 vs FP16
+    * support?
+    */
    case GLSL_TYPE_BOOL:
    case GLSL_TYPE_SAMPLER:
       return true;
 
+   case GLSL_TYPE_FLOAT:
+      return options->LowerPrecisionFloat16;
+
+   case GLSL_TYPE_UINT:
+   case GLSL_TYPE_INT:
+      return options->LowerPrecisionInt16;
+
    default:
       return false;
    }
 }
 
-find_lowerable_rvalues_visitor::find_lowerable_rvalues_visitor(struct set *res)
+find_lowerable_rvalues_visitor::find_lowerable_rvalues_visitor(struct set *res,
+                                 const struct gl_shader_compiler_options *opts)
 {
    lowerable_rvalues = res;
+   options = opts;
    callback_enter = stack_enter;
    callback_leave = stack_leave;
    data_enter = this;
@@ -270,7 +287,7 @@ find_lowerable_rvalues_visitor::stack_leave(class ir_instruction *ir,
 
 enum find_lowerable_rvalues_visitor::can_lower_state
 find_lowerable_rvalues_visitor::handle_precision(const glsl_type *type,
-                                                 int precision)
+                                                 int precision) const
 {
    if (!can_lower_type(type))
       return CANT_LOWER;
@@ -484,10 +501,11 @@ find_lowerable_rvalues_visitor::visit_leave(ir_assignment *ir)
 }
 
 void
-find_lowerable_rvalues(exec_list *instructions,
+find_lowerable_rvalues(const struct gl_shader_compiler_options *options,
+                       exec_list *instructions,
                        struct set *result)
 {
-   find_lowerable_rvalues_visitor v(result);
+   find_lowerable_rvalues_visitor v(result, options);
 
    visit_list_elements(&v, instructions);
 
@@ -495,12 +513,50 @@ find_lowerable_rvalues(exec_list *instructions,
 }
 
 static ir_rvalue *
-convert_precision(int op, ir_rvalue *ir)
+convert_precision(glsl_base_type type, bool up, ir_rvalue *ir)
 {
-   unsigned base_type = (op == ir_unop_f2fmp ?
-                        GLSL_TYPE_FLOAT16 : GLSL_TYPE_FLOAT);
+   unsigned new_type, op;
+
+   if (up) {
+      switch (type) {
+      case GLSL_TYPE_FLOAT16:
+         new_type = GLSL_TYPE_FLOAT;
+         op = ir_unop_f162f;
+         break;
+      case GLSL_TYPE_INT16:
+         new_type = GLSL_TYPE_INT;
+         op = ir_unop_i2i;
+         break;
+      case GLSL_TYPE_UINT16:
+         new_type = GLSL_TYPE_UINT;
+         op = ir_unop_u2u;
+         break;
+      default:
+         unreachable("invalid type");
+         return NULL;
+      }
+   } else {
+      switch (type) {
+      case GLSL_TYPE_FLOAT:
+         new_type = GLSL_TYPE_FLOAT16;
+         op = ir_unop_f2fmp;
+         break;
+      case GLSL_TYPE_INT:
+         new_type = GLSL_TYPE_INT16;
+         op = ir_unop_i2imp;
+         break;
+      case GLSL_TYPE_UINT:
+         new_type = GLSL_TYPE_UINT16;
+         op = ir_unop_u2ump;
+         break;
+      default:
+         unreachable("invalid type");
+         return NULL;
+      }
+   }
+
    const glsl_type *desired_type;
-   desired_type = glsl_type::get_instance(base_type,
+   desired_type = glsl_type::get_instance(new_type,
                              ir->type->vector_elements,
                              ir->type->matrix_columns);
 
@@ -508,6 +564,22 @@ convert_precision(int op, ir_rvalue *ir)
    return new(mem_ctx) ir_expression(op, desired_type, ir, NULL);
 }
 
+static glsl_base_type
+lower_type(glsl_base_type type)
+{
+   switch (type) {
+   case GLSL_TYPE_FLOAT:
+      return GLSL_TYPE_FLOAT16;
+   case GLSL_TYPE_INT:
+      return GLSL_TYPE_INT16;
+   case GLSL_TYPE_UINT:
+      return GLSL_TYPE_UINT16;
+   default:
+      unreachable("invalid type");
+      return GLSL_TYPE_ERROR;;
+   }
+}
+
 void
 lower_precision_visitor::handle_rvalue(ir_rvalue **rvalue)
 {
@@ -518,9 +590,11 @@ lower_precision_visitor::handle_rvalue(ir_rvalue **rvalue)
 
    if (ir->as_dereference()) {
       if (!ir->type->is_boolean())
-         *rvalue = convert_precision(ir_unop_f2fmp, ir);
-   } else if (ir->type->is_float()) {
-      ir->type = glsl_type::get_instance(GLSL_TYPE_FLOAT16,
+         *rvalue = convert_precision(ir->type->base_type, false, ir);
+   } else if (ir->type->base_type == GLSL_TYPE_FLOAT ||
+              ir->type->base_type == GLSL_TYPE_INT ||
+              ir->type->base_type == GLSL_TYPE_UINT) {
+      ir->type = glsl_type::get_instance(lower_type(ir->type->base_type),
                                          ir->type->vector_elements,
                                          ir->type->matrix_columns,
                                          ir->type->explicit_stride,
@@ -531,8 +605,18 @@ lower_precision_visitor::handle_rvalue(ir_rvalue **rvalue)
       if (const_ir) {
          ir_constant_data value;
 
-         for (unsigned i = 0; i < ARRAY_SIZE(value.f16); i++)
-            value.f16[i] = _mesa_float_to_half(const_ir->value.f[i]);
+         if (ir->type->base_type == GLSL_TYPE_FLOAT16) {
+            for (unsigned i = 0; i < ARRAY_SIZE(value.f16); i++)
+               value.f16[i] = _mesa_float_to_half(const_ir->value.f[i]);
+         } else if (ir->type->base_type == GLSL_TYPE_INT16) {
+            for (unsigned i = 0; i < ARRAY_SIZE(value.i16); i++)
+               value.i16[i] = const_ir->value.i[i];
+         } else if (ir->type->base_type == GLSL_TYPE_UINT16) {
+            for (unsigned i = 0; i < ARRAY_SIZE(value.u16); i++)
+               value.u16[i] = const_ir->value.u[i];
+         } else {
+            unreachable("invalid type");
+         }
 
          const_ir->value = value;
       }
@@ -586,6 +670,10 @@ lower_precision_visitor::visit_leave(ir_expression *ir)
    case ir_unop_f2b:
       ir->operation = ir_unop_f162b;
       break;
+   case ir_unop_b2i:
+   case ir_unop_i2b:
+      /* Nothing to do - they both support int16. */
+      break;
    default:
       break;
    }
@@ -599,7 +687,7 @@ find_precision_visitor::handle_rvalue(ir_rvalue **rvalue)
    /* Checking the precision of rvalue can be lowered first throughout
     * find_lowerable_rvalues_visitor.
     * Once it found the precision of rvalue can be lowered, then we can
-    * add conversion f2fmp through lower_precision_visitor.
+    * add conversion f2fmp, etc. through lower_precision_visitor.
     */
    if (*rvalue == NULL)
       return;
@@ -629,7 +717,7 @@ find_precision_visitor::handle_rvalue(ir_rvalue **rvalue)
     * converted to bool
     */
    if ((*rvalue)->type->base_type != GLSL_TYPE_BOOL)
-      *rvalue = convert_precision(ir_unop_f162f, *rvalue);
+      *rvalue = convert_precision((*rvalue)->type->base_type, true, *rvalue);
 
    progress = true;
 }
@@ -679,7 +767,7 @@ find_precision_visitor::map_builtin(ir_function_signature *sig)
       param->data.precision = GLSL_PRECISION_MEDIUM;
    }
 
-   lower_precision(&lowered_sig->body);
+   lower_precision(options, &lowered_sig->body);
 
    _mesa_hash_table_clear(clone_ht, NULL);
 
@@ -688,12 +776,13 @@ find_precision_visitor::map_builtin(ir_function_signature *sig)
    return lowered_sig;
 }
 
-find_precision_visitor::find_precision_visitor()
+find_precision_visitor::find_precision_visitor(const struct gl_shader_compiler_options *options)
    : progress(false),
      lowerable_rvalues(_mesa_pointer_set_create(NULL)),
      lowered_builtins(NULL),
      clone_ht(NULL),
-     lowered_builtin_mem_ctx(NULL)
+     lowered_builtin_mem_ctx(NULL),
+     options(options)
 {
 }
 
@@ -711,11 +800,12 @@ find_precision_visitor::~find_precision_visitor()
 }
 
 bool
-lower_precision(exec_list *instructions)
+lower_precision(const struct gl_shader_compiler_options *options,
+                exec_list *instructions)
 {
-   find_precision_visitor v;
+   find_precision_visitor v(options);
 
-   find_lowerable_rvalues(instructions, v.lowerable_rvalues);
+   find_lowerable_rvalues(options, instructions, v.lowerable_rvalues);
 
    visit_list_elements(&v, instructions);
 
index 9a7f7d58ed6fcf4909d33a94a5a68732c133d984..02f019e0bde280f983b802bc883fba020a4a6f1e 100644 (file)
@@ -438,7 +438,8 @@ standalone_compile_shader(const struct standalone_options *_options,
       for (unsigned i = MESA_SHADER_VERTEX; i <= MESA_SHADER_FRAGMENT; i++) {
          struct gl_shader_compiler_options *options =
             &ctx->Const.ShaderCompilerOptions[i];
-         options->LowerPrecision = true;
+         options->LowerPrecisionFloat16 = true;
+         options->LowerPrecisionInt16 = true;
       }
    }
 
index 6d6e127171141f266113fcb23371c7ddf4f05cc8..0934e61e4ab7d3b88234c128c5fdd12e015cacec 100644 (file)
@@ -31,7 +31,7 @@ Test = namedtuple("Test", "name source match_re")
 
 
 TESTS = [
-    Test("simple division",
+    Test("f32 simple division",
          """
          uniform mediump float a, b;
 
@@ -41,6 +41,36 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t +/'),
+    Test("i32 simple division",
+         """
+         #version 300 es
+         precision mediump float;
+         precision mediump int;
+         uniform mediump int a, b;
+
+         out vec4 color;
+
+         void main()
+         {
+                 color = vec4(a / b);
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("u32 simple division",
+         """
+         #version 300 es
+         precision mediump float;
+         precision mediump int;
+         uniform mediump uint a, b;
+
+         out vec4 color;
+
+         void main()
+         {
+                 color = vec4(a / b);
+         }
+         """,
+         r'\(expression +uint16_t +/'),
     Test("dot",
          """
          uniform mediump vec2 a, b;
@@ -51,7 +81,7 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t +dot\b'),
-    Test("array with const index",
+    Test("f32 array with const index",
          """
          precision mediump float;
 
@@ -63,7 +93,39 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t +/'),
-    Test("array with uniform index",
+    Test("i32 array with const index",
+         """
+         #version 300 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform int in_simple[2];
+
+         out vec4 color;
+
+         void main()
+         {
+                 color = vec4(in_simple[0] / in_simple[1]);
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("u32 array with const index",
+         """
+         #version 300 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint in_simple[2];
+
+         out vec4 color;
+
+         void main()
+         {
+                 color = vec4(in_simple[0] / in_simple[1]);
+         }
+         """,
+         r'\(expression +uint16_t +/'),
+    Test("f32 array with uniform index",
          """
          precision mediump float;
 
@@ -76,7 +138,41 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t +/'),
-    Test("array-of-array with const index",
+    Test("i32 array with uniform index",
+         """
+         #version 300 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform int in_simple[2];
+         uniform int i0, i1;
+
+         out vec4 color;
+
+         void main()
+         {
+                 color = vec4(in_simple[i0] / in_simple[i1]);
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("u32 array with uniform index",
+         """
+         #version 300 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint in_simple[2];
+         uniform int i0, i1;
+
+         out vec4 color;
+
+         void main()
+         {
+                 color = vec4(in_simple[i0] / in_simple[i1]);
+         }
+         """,
+         r'\(expression +uint16_t +/'),
+    Test("f32 array-of-array with const index",
          """
          #version 310 es
          precision mediump float;
@@ -91,7 +187,39 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t +/'),
-    Test("array-of-array with uniform index",
+    Test("i32 array-of-array with const index",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform int in_aoa[2][2];
+
+         layout(location = 0) out highp int out_color;
+
+         void main()
+         {
+                 out_color = in_aoa[0][0] / in_aoa[1][1];
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("u32 array-of-array with const index",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint in_aoa[2][2];
+
+         layout(location = 0) out highp uint out_color;
+
+         void main()
+         {
+                 out_color = in_aoa[0][0] / in_aoa[1][1];
+         }
+         """,
+         r'\(expression +uint16_t +/'),
+    Test("f32 array-of-array with uniform index",
          """
          #version 310 es
          precision mediump float;
@@ -107,7 +235,41 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t +/'),
-    Test("array index",
+    Test("i32 array-of-array with uniform index",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform int in_aoa[2][2];
+         uniform int i0, i1;
+
+         layout(location = 0) out highp int out_color;
+
+         void main()
+         {
+                 out_color = in_aoa[i0][i0] / in_aoa[i1][i1];
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("u32 array-of-array with uniform index",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint in_aoa[2][2];
+         uniform int i0, i1;
+
+         layout(location = 0) out highp uint out_color;
+
+         void main()
+         {
+                 out_color = in_aoa[i0][i0] / in_aoa[i1][i1];
+         }
+         """,
+         r'\(expression +uint16_t +/'),
+    Test("f32 array index",
          """
          uniform mediump float a, b;
          uniform mediump float values[2];
@@ -118,7 +280,24 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t +/'),
-    Test("function",
+    Test("i32 array index",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform mediump int a, b;
+         uniform mediump int values[2];
+
+         out highp int color;
+
+         void main()
+         {
+                 color = values[a / b];
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("f32 function",
          """
          precision mediump float;
 
@@ -142,7 +321,63 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t +/'),
-    Test("function mediump args",
+    Test("i32 function",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform int a, b;
+
+         mediump int
+         get_a()
+         {
+                 return a;
+         }
+
+         int
+         get_b()
+         {
+                 return b;
+         }
+
+         out highp int color;
+
+         void main()
+         {
+                 color = get_a() / get_b();
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("u32 function",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint a, b;
+
+         mediump uint
+         get_a()
+         {
+                 return a;
+         }
+
+         uint
+         get_b()
+         {
+                 return b;
+         }
+
+         out highp uint color;
+
+         void main()
+         {
+                 color = get_a() / get_b();
+         }
+         """,
+         r'\(expression +uint16_t +/'),
+    Test("f32 function mediump args",
          """
          precision mediump float;
 
@@ -160,7 +395,51 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t +/'),
-    Test("function highp args",
+    Test("i32 function mediump args",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform int a, b;
+
+         mediump int
+         do_div(int x, int y)
+         {
+                 return x / y;
+         }
+
+         out highp int color;
+
+         void main()
+         {
+                 color = do_div(a, b);
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("u32 function mediump args",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint a, b;
+
+         mediump uint
+         do_div(uint x, uint y)
+         {
+                 return x / y;
+         }
+
+         out highp uint color;
+
+         void main()
+         {
+                 color = do_div(a, b);
+         }
+         """,
+         r'\(expression +uint16_t +/'),
+    Test("f32 function highp args",
          """
          precision mediump float;
 
@@ -178,7 +457,51 @@ TESTS = [
          }
          """,
          r'\(expression +float +/'),
-    Test("function inout different precision highp",
+    Test("i32 function highp args",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform int a, b;
+
+         mediump int
+         do_div(highp int x, highp int y)
+         {
+                 return x / y;
+         }
+
+         out highp int color;
+
+         void main()
+         {
+                  color = do_div(a, b);
+         }
+         """,
+         r'\(expression +int +/'),
+    Test("u32 function highp args",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint a, b;
+
+         mediump uint
+         do_div(highp uint x, highp uint y)
+         {
+                 return x / y;
+         }
+
+         out highp uint color;
+
+         void main()
+         {
+                  color = do_div(a, b);
+         }
+         """,
+         r'\(expression +uint +/'),
+    Test("f32 function inout different precision highp",
          """
          uniform mediump float a, b;
 
@@ -196,7 +519,49 @@ TESTS = [
          }
          """,
          r'\(expression +float +/'),
-    Test("function inout different precision mediump",
+    Test("i32 function inout different precision highp",
+         """
+         #version 310 es
+         uniform mediump int a, b;
+
+         void
+         do_div(inout highp int x, highp int y)
+         {
+                 x = x / y;
+         }
+
+         out mediump int color;
+
+         void main()
+         {
+                 mediump int temp = a;
+                 do_div(temp, b);
+                 color = temp;
+         }
+         """,
+         r'\(expression +int +/'),
+    Test("u32 function inout different precision highp",
+         """
+         #version 310 es
+         uniform mediump uint a, b;
+
+         void
+         do_div(inout highp uint x, highp uint y)
+         {
+                 x = x / y;
+         }
+
+         out mediump uint color;
+
+         void main()
+         {
+                 mediump uint temp = a;
+                 do_div(temp, b);
+                 color = temp;
+         }
+         """,
+         r'\(expression +uint +/'),
+    Test("f32 function inout different precision mediump",
          """
          uniform highp float a, b;
 
@@ -214,7 +579,49 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t +/'),
-    Test("if",
+    Test("i32 function inout different precision mediump",
+         """
+         #version 310 es
+         uniform highp int a, b;
+
+         out highp int color;
+
+         void
+         do_div(inout mediump int x, mediump int y)
+         {
+                 x = x / y;
+         }
+
+         void main()
+         {
+                 highp int temp = a;
+                 do_div(temp, b);
+                 color = temp;
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("u32 function inout different precision mediump",
+         """
+         #version 310 es
+         uniform highp uint a, b;
+
+         out highp uint color;
+
+         void
+         do_div(inout mediump uint x, mediump uint y)
+         {
+                 x = x / y;
+         }
+
+         void main()
+         {
+                 highp uint temp = a;
+                 do_div(temp, b);
+                 color = temp;
+         }
+         """,
+         r'\(expression +uint16_t +/'),
+    Test("f32 if",
          """
          precision mediump float;
 
@@ -230,6 +637,46 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t +/'),
+    Test("i32 if",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform int a, b;
+
+         out vec4 color;
+
+         void
+         main()
+         {
+                 if (a / b < 10)
+                         color = vec4(0.0, 1.0, 0.0, 1.0);
+                 else
+                         color = vec4(1.0, 0.0, 0.0, 1.0);
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("u32 if",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint a, b;
+
+         out vec4 color;
+
+         void
+         main()
+         {
+                 if (a / b < 10u)
+                         color = vec4(0.0, 1.0, 0.0, 1.0);
+                 else
+                         color = vec4(1.0, 0.0, 0.0, 1.0);
+         }
+         """,
+         r'\(expression +uint16_t +/'),
     Test("matrix",
          """
          precision mediump float;
@@ -243,7 +690,7 @@ TESTS = [
          }
          """,
          r'\(expression +f16vec2 \*.*\bf16mat2\b'),
-    Test("simple struct deref",
+    Test("f32 simple struct deref",
          """
          precision mediump float;
 
@@ -259,7 +706,47 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t +/'),
-    Test("embedded struct deref",
+    Test("i32 simple struct deref",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         struct simple {
+                 int a, b;
+         };
+
+         uniform simple in_simple;
+
+         out highp int color;
+
+         void main()
+         {
+                 color = in_simple.a / in_simple.b;
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("u32 simple struct deref",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         struct simple {
+                 uint a, b;
+         };
+
+         uniform simple in_simple;
+
+         out highp uint color;
+
+         void main()
+         {
+                 color = in_simple.a / in_simple.b;
+         }
+         """,
+         r'\(expression +uint16_t +/'),
+    Test("f32 embedded struct deref",
          """
          precision mediump float;
 
@@ -279,7 +766,55 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t +/'),
-    Test("arrayed struct deref",
+    Test("i32 embedded struct deref",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         struct simple {
+                 int a, b;
+         };
+
+         struct embedded {
+                 simple a, b;
+         };
+
+         uniform embedded in_embedded;
+
+         out highp int color;
+
+         void main()
+         {
+                 color = in_embedded.a.a / in_embedded.b.b;
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("u32 embedded struct deref",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         struct simple {
+                 uint a, b;
+         };
+
+         struct embedded {
+                 simple a, b;
+         };
+
+         uniform embedded in_embedded;
+
+         out highp uint color;
+
+         void main()
+         {
+                 color = in_embedded.a.a / in_embedded.b.b;
+         }
+         """,
+         r'\(expression +uint16_t +/'),
+    Test("f32 arrayed struct deref",
          """
          precision mediump float;
 
@@ -299,7 +834,55 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t +/'),
-    Test("mixed precision not lowered",
+    Test("i32 arrayed struct deref",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         struct simple {
+                 int a, b;
+         };
+
+         struct arrayed {
+                 simple a[2];
+         };
+
+         uniform arrayed in_arrayed;
+
+         out highp int color;
+
+         void main()
+         {
+                 color = in_arrayed.a[0].a / in_arrayed.a[1].b;
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("u32 arrayed struct deref",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         struct simple {
+                 uint a, b;
+         };
+
+         struct arrayed {
+                 simple a[2];
+         };
+
+         uniform arrayed in_arrayed;
+
+         out highp uint color;
+
+         void main()
+         {
+                 color = in_arrayed.a[0].a / in_arrayed.a[1].b;
+         }
+         """,
+         r'\(expression +uint16_t +/'),
+    Test("f32 mixed precision not lowered",
          """
          uniform mediump float a;
          uniform highp float b;
@@ -310,7 +893,35 @@ TESTS = [
          }
          """,
          r'\(expression +float +/'),
-    Test("texture sample",
+    Test("i32 mixed precision not lowered",
+         """
+         #version 310 es
+         uniform mediump int a;
+         uniform highp int b;
+
+         out mediump int color;
+
+         void main()
+         {
+                 color = a / b;
+         }
+         """,
+         r'\(expression +int +/'),
+    Test("u32 mixed precision not lowered",
+         """
+         #version 310 es
+         uniform mediump uint a;
+         uniform highp uint b;
+
+         out mediump uint color;
+
+         void main()
+         {
+                 color = a / b;
+         }
+         """,
+         r'\(expression +uint +/'),
+    Test("f32 texture sample",
          """
          precision mediump float;
 
@@ -323,8 +934,44 @@ TESTS = [
                  gl_FragColor = texture2D(tex, coord) / divisor;
          }
          """,
-         r'\(expression +f16vec4 +/'),
-    Test("expression in lvalue",
+         r'\(expression +f16vec4 +/.*\(tex +f16vec4 +'),
+    Test("i32 texture sample",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform mediump isampler2D tex;
+         uniform vec2 coord;
+         uniform int divisor;
+
+         out highp ivec4 color;
+
+         void main()
+         {
+                 color = texture(tex, coord) / divisor;
+         }
+         """,
+         r'\(expression +i16vec4 +/.*\(tex +i16vec4 +'),
+    Test("u32 texture sample",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform mediump usampler2D tex;
+         uniform vec2 coord;
+         uniform uint divisor;
+
+         out highp uvec4 color;
+
+         void main()
+         {
+                 color = texture(tex, coord) / divisor;
+         }
+         """,
+         r'\(expression +u16vec4 +/.*\(tex +u16vec4 +'),
+    Test("f32 expression in lvalue",
          """
          uniform mediump float a, b;
 
@@ -335,7 +982,24 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t +/'),
-    Test("builtin with const arg",
+    Test("i32 expression in lvalue",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform mediump int a, b;
+
+         out vec4 color;
+
+         void main()
+         {
+                 color = vec4(1.0);
+                 color[a / b] = 0.5;
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("f32 builtin with const arg",
          """
          uniform mediump float a;
 
@@ -345,6 +1009,32 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t min'),
+    Test("i32 builtin with const arg",
+         """
+         #version 310 es
+         uniform mediump int a;
+
+         out highp int color;
+
+         void main()
+         {
+                 color = min(a, 3);
+         }
+         """,
+         r'\(expression +int16_t min'),
+    Test("u32 builtin with const arg",
+         """
+         #version 310 es
+         uniform mediump uint a;
+
+         out highp uint color;
+
+         void main()
+         {
+                 color = min(a, 3u);
+         }
+         """,
+         r'\(expression +uint16_t min'),
 ]
 
 
@@ -364,6 +1054,7 @@ def run_test(standalone_compiler, test):
     ir = compile_shader(standalone_compiler, test.source)
 
     if re.search(test.match_re, ir) is None:
+        print(ir)
         return False
 
     return True
index 2fa06e7a5705467f4f3cedb6f96bdd2506b0efe7..5eb4ba625d45f13aaf65ee81d1687bff81984b24 100644 (file)
@@ -3206,7 +3206,8 @@ struct gl_shader_compiler_options
     * If we can lower the precision of variables based on precision
     * qualifiers
     */
-   GLboolean LowerPrecision;
+   GLboolean LowerPrecisionFloat16;
+   GLboolean LowerPrecisionInt16;
 
    /**
     * \name Forms of indirect addressing the driver cannot do.
index f13ded7c19d94b988fcbfe85994270b1e58131c7..ca0e5db30d6ed92e87e62bfd958d08b41f5f5237 100644 (file)
@@ -343,7 +343,7 @@ void st_init_limits(struct pipe_screen *screen,
       /* Initialize lower precision shader compiler option based on
        * the value of PIPE_SHADER_CAP_FP16.
        */
-      options->LowerPrecision =
+      options->LowerPrecisionFloat16 =
          screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_FP16);
    }