From f798513f91884e1ae332a0726d3e1d4cf455abf0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Fri, 8 May 2020 22:05:46 -0400 Subject: [PATCH] nir: add i2imp and u2ump opcodes for conversions to mediump Reviewed-by: Alyssa Rosenzweig Reviewed-by: Rob Clark Part-of: --- src/compiler/nir/nir_opcodes.py | 9 ++++++--- src/compiler/nir/nir_opt_algebraic.py | 18 +++++++++++++++--- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/compiler/nir/nir_opcodes.py b/src/compiler/nir/nir_opcodes.py index 142d7a427d5..6a5d025f636 100644 --- a/src/compiler/nir/nir_opcodes.py +++ b/src/compiler/nir/nir_opcodes.py @@ -100,6 +100,7 @@ tbool16 = "bool16" tbool32 = "bool32" tuint = "uint" tuint8 = "uint8" +tint16 = "int16" tuint16 = "uint16" tfloat16 = "float16" tfloat32 = "float32" @@ -267,11 +268,13 @@ for src_t in [tint, tuint, tfloat, tbool]: dst_bit_size), dst_t + str(dst_bit_size), src_t, conv_expr) -# Special opcode that is the same as f2f16 except that it is safe to remove it -# if the result is immediately converted back to float32 again. This is -# generated as part of the precision lowering pass. mp stands for medium +# Special opcode that is the same as f2f16, i2i16, u2u16 except that it is safe +# to remove it if the result is immediately converted back to 32 bits again. +# This is generated as part of the precision lowering pass. mp stands for medium # precision. unop_numeric_convert("f2fmp", tfloat16, tfloat, opcodes["f2f16"].const_expr) +unop_numeric_convert("i2imp", tint16, tint, opcodes["i2i16"].const_expr) +unop_numeric_convert("u2ump", tuint16, tuint, opcodes["u2u16"].const_expr) # Unary floating-point rounding operations. diff --git a/src/compiler/nir/nir_opt_algebraic.py b/src/compiler/nir/nir_opt_algebraic.py index 44b0ecc2c08..a822813605b 100644 --- a/src/compiler/nir/nir_opt_algebraic.py +++ b/src/compiler/nir/nir_opt_algebraic.py @@ -896,14 +896,24 @@ optimizations.extend([ (('~f2u32', ('i2f', 'a@32')), a), (('~f2u32', ('u2f', 'a@32')), a), - # Conversions from float16 to float32 and back can always be removed + # Conversions from 16 bits to 32 bits and back can always be removed (('f2f16', ('f2f32', 'a@16')), a), (('f2fmp', ('f2f32', 'a@16')), a), + (('i2i16', ('i2i32', 'a@16')), a), + (('i2imp', ('i2i32', 'a@16')), a), + (('u2u16', ('u2u32', 'a@16')), a), + (('u2ump', ('u2u32', 'a@16')), a), (('f2f16', ('b2f32', 'a@1')), ('b2f16', a)), (('f2fmp', ('b2f32', 'a@1')), ('b2f16', a)), - # Conversions to float16 would be lossy so they should only be removed if + (('i2i16', ('b2i32', 'a@1')), ('b2i16', a)), + (('i2imp', ('b2i32', 'a@1')), ('b2i16', a)), + (('u2u16', ('b2i32', 'a@1')), ('b2i16', a)), + (('u2ump', ('b2i32', 'a@1')), ('b2i16', a)), + # Conversions to 16 bits would be lossy so they should only be removed if # the instruction was generated by the precision lowering pass. (('f2f32', ('f2fmp', 'a@32')), a), + (('i2i32', ('i2imp', 'a@32')), a), + (('u2u32', ('u2ump', 'a@32')), a), (('ffloor', 'a(is_integral)'), a), (('fceil', 'a(is_integral)'), a), @@ -1926,10 +1936,12 @@ late_optimizations = [ (('~fadd', ('ffma(is_used_once)', a, b, ('fmul', 'c(is_not_const_and_not_fsign)', 'd(is_not_const_and_not_fsign)') ), 'e(is_not_const)'), ('ffma', a, b, ('ffma', c, d, e)), '(info->stage != MESA_SHADER_VERTEX && info->stage != MESA_SHADER_GEOMETRY) && !options->intel_vec4'), - # Convert f2fmp instructions to concrete f2f16 instructions. At this point + # Convert *2*mp instructions to concrete *2*16 instructions. At this point # any conversions that could have been removed will have been removed in # nir_opt_algebraic so any remaining ones are required. (('f2fmp', a), ('f2f16', a)), + (('i2imp', a), ('i2i16', a)), + (('u2ump', a), ('u2u16', a)), # Section 8.8 (Integer Functions) of the GLSL 4.60 spec says: # -- 2.30.2