From: Marek Olšák Date: Sat, 9 May 2020 02:42:43 +0000 (-0400) Subject: glsl: lower mediump integer types to int16 and uint16 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6fe20ebaaa933ddd17b655e61ba3fe3d358b8513;p=mesa.git glsl: lower mediump integer types to int16 and uint16 Reviewed-by: Alyssa Rosenzweig Reviewed-by: Rob Clark Part-of: --- diff --git a/src/compiler/glsl/glsl_parser_extras.cpp b/src/compiler/glsl/glsl_parser_extras.cpp index e610fda002c..c0f116b8fb4 100644 --- a/src/compiler/glsl/glsl_parser_extras.cpp +++ b/src/compiler/glsl/glsl_parser_extras.cpp @@ -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); diff --git a/src/compiler/glsl/ir_optimization.h b/src/compiler/glsl/ir_optimization.h index 23365df10a3..0274ad260da 100644 --- a/src/compiler/glsl/ir_optimization.h +++ b/src/compiler/glsl/ir_optimization.h @@ -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 */ diff --git a/src/compiler/glsl/lower_precision.cpp b/src/compiler/glsl/lower_precision.cpp index 9ba1efafa01..44cc7969204 100644 --- a/src/compiler/glsl/lower_precision.cpp +++ b/src/compiler/glsl/lower_precision.cpp @@ -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 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; 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); diff --git a/src/compiler/glsl/standalone.cpp b/src/compiler/glsl/standalone.cpp index 9a7f7d58ed6..02f019e0bde 100644 --- a/src/compiler/glsl/standalone.cpp +++ b/src/compiler/glsl/standalone.cpp @@ -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; } } diff --git a/src/compiler/glsl/tests/lower_precision_test.py b/src/compiler/glsl/tests/lower_precision_test.py index 6d6e1271711..0934e61e4ab 100644 --- a/src/compiler/glsl/tests/lower_precision_test.py +++ b/src/compiler/glsl/tests/lower_precision_test.py @@ -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 diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 2fa06e7a570..5eb4ba625d4 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -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. diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index f13ded7c19d..ca0e5db30d6 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -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); }