From 38cadd8b462861e9dac9af8daedf8f268fad920d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Wed, 1 Jul 2020 14:09:32 -0400 Subject: [PATCH] glsl: lower builtins to mediump that always return mediump or lowp Reviewed-by: Alyssa Rosenzweig Part-of: --- src/compiler/glsl/lower_precision.cpp | 26 +++++- .../glsl/tests/lower_precision_test.py | 90 +++++++++++++++++++ 2 files changed, 114 insertions(+), 2 deletions(-) diff --git a/src/compiler/glsl/lower_precision.cpp b/src/compiler/glsl/lower_precision.cpp index f1ac00b2aaf..7fb7257f2ab 100644 --- a/src/compiler/glsl/lower_precision.cpp +++ b/src/compiler/glsl/lower_precision.cpp @@ -408,6 +408,17 @@ find_lowerable_rvalues_visitor::visit_enter(ir_expression *ir) return visit_continue; } +static bool +function_always_returns_mediump_or_lowp(const char *name) +{ + return !strcmp(name, "bitCount") || + !strcmp(name, "findLSB") || + !strcmp(name, "findMSB") || + !strcmp(name, "unpackHalf2x16") || + !strcmp(name, "unpackUnorm4x8") || + !strcmp(name, "unpackSnorm4x8"); +} + static bool is_lowerable_builtin(ir_call *ir, const struct set *lowerable_rvalues) @@ -510,6 +521,11 @@ is_lowerable_builtin(ir_call *ir, check_parameters = 1; } else if (!strcmp(ir->callee_name(), "bitfieldInsert")) { check_parameters = 2; + } if (function_always_returns_mediump_or_lowp(ir->callee_name())) { + /* These only lower the return value. Parameters keep their precision, + * which is preserved in map_builtin. + */ + check_parameters = 0; } foreach_in_list(ir_rvalue, param, &ir->actual_parameters) { @@ -875,8 +891,14 @@ find_precision_visitor::map_builtin(ir_function_signature *sig) ir_function_signature *lowered_sig = sig->clone(lowered_builtin_mem_ctx, clone_ht); - foreach_in_list(ir_variable, param, &lowered_sig->parameters) { - param->data.precision = GLSL_PRECISION_MEDIUM; + /* Functions that always return mediump or lowp should keep their + * parameters intact, because they can be highp. NIR can lower + * the up-conversion for parameters if needed. + */ + if (!function_always_returns_mediump_or_lowp(sig->function_name())) { + foreach_in_list(ir_variable, param, &lowered_sig->parameters) { + param->data.precision = GLSL_PRECISION_MEDIUM; + } } lower_precision(options, &lowered_sig->body); diff --git a/src/compiler/glsl/tests/lower_precision_test.py b/src/compiler/glsl/tests/lower_precision_test.py index 2fc8f1922e7..a6ad9503135 100644 --- a/src/compiler/glsl/tests/lower_precision_test.py +++ b/src/compiler/glsl/tests/lower_precision_test.py @@ -1538,6 +1538,96 @@ TESTS = [ } """, r'expression int16_t bitfield_insert \(expression int16_t'), + Test("bitCount", + """ + #version 310 es + precision mediump float; + precision mediump int; + + uniform highp int val; + out int color; + + void main() + { + color = bitCount(val) + 1; + } + """, + r'expression int16_t \+ \(expression int16_t i2imp \(expression int bit_count \(var_ref val'), + Test("findLSB", + """ + #version 310 es + precision mediump float; + precision mediump int; + + uniform highp int val; + out int color; + + void main() + { + color = findLSB(val) + 1; + } + """, + r'expression int16_t \+ \(expression int16_t i2imp \(expression int find_lsb \(var_ref val'), + Test("findMSB", + """ + #version 310 es + precision mediump float; + precision mediump int; + + uniform highp int val; + out int color; + + void main() + { + color = findMSB(val) + 1; + } + """, + r'expression int16_t \+ \(expression int16_t i2imp \(expression int find_msb \(var_ref val'), + Test("unpackHalf2x16", + """ + #version 310 es + precision mediump float; + precision mediump int; + + uniform highp uint val; + out vec2 color; + + void main() + { + color = unpackHalf2x16(val) + vec2(1.0); + } + """, + r'expression f16vec2 \+ \(expression f16vec2 f2fmp \(expression vec2 unpackHalf2x16 \(var_ref val'), + Test("unpackUnorm4x8", + """ + #version 310 es + precision mediump float; + precision mediump int; + + uniform highp uint val; + out vec4 color; + + void main() + { + color = unpackUnorm4x8(val) + vec4(1.0); + } + """, + r'expression f16vec4 \+ \(expression f16vec4 f2fmp \(expression vec4 unpackUnorm4x8 \(var_ref val'), + Test("unpackSnorm4x8", + """ + #version 310 es + precision mediump float; + precision mediump int; + + uniform highp uint val; + out vec4 color; + + void main() + { + color = unpackSnorm4x8(val) + vec4(1.0); + } + """, + r'expression f16vec4 \+ \(expression f16vec4 f2fmp \(expression vec4 unpackSnorm4x8 \(var_ref val'), ] -- 2.30.2