From: Elie Tournier <tournier.e...@gmail.com> v2: use mix Signed-off-by: Elie Tournier <elie.tourn...@collabora.com> --- src/compiler/glsl/builtin_float64.h | 129 ++++++++++++++++++++++++++++++++ src/compiler/glsl/builtin_functions.cpp | 4 + src/compiler/glsl/builtin_functions.h | 3 + src/compiler/glsl/float64.glsl | 23 ++++++ src/compiler/glsl/glcpp/glcpp-parse.y | 1 + 5 files changed, 160 insertions(+)
diff --git a/src/compiler/glsl/builtin_float64.h b/src/compiler/glsl/builtin_float64.h index 8ce2baa..b656fad 100644 --- a/src/compiler/glsl/builtin_float64.h +++ b/src/compiler/glsl/builtin_float64.h @@ -5533,3 +5533,132 @@ fp64_to_int(void *mem_ctx, builtin_available_predicate avail) sig->replace_parameters(&sig_parameters); return sig; } +ir_function_signature * +int_to_fp64(void *mem_ctx, builtin_available_predicate avail) +{ + ir_function_signature *const sig = + new(mem_ctx) ir_function_signature(glsl_type::uvec2_type, avail); + ir_factory body(&sig->body, mem_ctx); + sig->is_defined = true; + + exec_list sig_parameters; + + ir_variable *const r08C0 = new(mem_ctx) ir_variable(glsl_type::int_type, "a", ir_var_function_in); + sig_parameters.push_tail(r08C0); + ir_variable *const r08C1 = body.make_temp(glsl_type::uvec2_type, "return_value"); + ir_variable *const r08C2 = new(mem_ctx) ir_variable(glsl_type::uint_type, "zSign", ir_var_auto); + body.emit(r08C2); + ir_variable *const r08C3 = new(mem_ctx) ir_variable(glsl_type::uint_type, "zFrac1", ir_var_auto); + body.emit(r08C3); + ir_variable *const r08C4 = new(mem_ctx) ir_variable(glsl_type::uint_type, "zFrac0", ir_var_auto); + body.emit(r08C4); + body.emit(assign(r08C4, body.constant(0u), 0x01)); + + body.emit(assign(r08C3, body.constant(0u), 0x01)); + + /* IF CONDITION */ + ir_expression *const r08C6 = equal(r08C0, body.constant(int(0))); + ir_if *f08C5 = new(mem_ctx) ir_if(operand(r08C6).val); + exec_list *const f08C5_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f08C5->then_instructions; + + ir_variable *const r08C7 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "z", ir_var_auto); + body.emit(r08C7); + body.emit(assign(r08C7, body.constant(0u), 0x02)); + + body.emit(assign(r08C7, body.constant(0u), 0x01)); + + body.emit(assign(r08C1, r08C7, 0x03)); + + + /* ELSE INSTRUCTIONS */ + body.instructions = &f08C5->else_instructions; + + ir_expression *const r08C8 = less(r08C0, body.constant(int(0))); + ir_expression *const r08C9 = expr(ir_unop_b2i, r08C8); + body.emit(assign(r08C2, expr(ir_unop_i2u, r08C9), 0x01)); + + ir_variable *const r08CA = body.make_temp(glsl_type::uint_type, "mix_retval"); + ir_expression *const r08CB = less(r08C0, body.constant(int(0))); + ir_expression *const r08CC = neg(r08C0); + ir_expression *const r08CD = expr(ir_unop_i2u, r08CC); + ir_expression *const r08CE = expr(ir_unop_i2u, r08C0); + body.emit(assign(r08CA, expr(ir_triop_csel, r08CB, r08CD, r08CE), 0x01)); + + ir_variable *const r08CF = body.make_temp(glsl_type::int_type, "assignment_tmp"); + ir_expression *const r08D0 = equal(r08CA, body.constant(0u)); + ir_expression *const r08D1 = expr(ir_unop_find_msb, r08CA); + ir_expression *const r08D2 = sub(body.constant(int(31)), r08D1); + ir_expression *const r08D3 = expr(ir_triop_csel, r08D0, body.constant(int(32)), r08D2); + body.emit(assign(r08CF, add(r08D3, body.constant(int(-11))), 0x01)); + + /* IF CONDITION */ + ir_expression *const r08D5 = gequal(r08CF, body.constant(int(0))); + ir_if *f08D4 = new(mem_ctx) ir_if(operand(r08D5).val); + exec_list *const f08D4_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f08D4->then_instructions; + + body.emit(assign(r08C4, lshift(r08CA, r08CF), 0x01)); + + body.emit(assign(r08C3, body.constant(0u), 0x01)); + + + /* ELSE INSTRUCTIONS */ + body.instructions = &f08D4->else_instructions; + + ir_variable *const r08D6 = body.make_temp(glsl_type::int_type, "count"); + body.emit(assign(r08D6, neg(r08CF), 0x01)); + + ir_expression *const r08D7 = equal(r08D6, body.constant(int(0))); + ir_expression *const r08D8 = less(r08D6, body.constant(int(32))); + ir_expression *const r08D9 = rshift(r08CA, r08D6); + ir_expression *const r08DA = expr(ir_triop_csel, r08D8, r08D9, body.constant(0u)); + body.emit(assign(r08C4, expr(ir_triop_csel, r08D7, r08CA, r08DA), 0x01)); + + ir_expression *const r08DB = equal(r08D6, body.constant(int(0))); + ir_expression *const r08DC = less(r08D6, body.constant(int(32))); + ir_expression *const r08DD = neg(r08D6); + ir_expression *const r08DE = bit_and(r08DD, body.constant(int(31))); + ir_expression *const r08DF = lshift(r08CA, r08DE); + ir_expression *const r08E0 = bit_or(r08DF, body.constant(0u)); + ir_expression *const r08E1 = less(r08D6, body.constant(int(64))); + ir_expression *const r08E2 = bit_and(r08D6, body.constant(int(31))); + ir_expression *const r08E3 = rshift(r08CA, r08E2); + ir_expression *const r08E4 = expr(ir_triop_csel, r08E1, r08E3, body.constant(0u)); + ir_expression *const r08E5 = expr(ir_triop_csel, r08DC, r08E0, r08E4); + body.emit(assign(r08C3, expr(ir_triop_csel, r08DB, r08CA, r08E5), 0x01)); + + + body.instructions = f08D4_parent_instructions; + body.emit(f08D4); + + /* END IF */ + + ir_variable *const r08E6 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "z", ir_var_auto); + body.emit(r08E6); + ir_expression *const r08E7 = lshift(r08C2, body.constant(int(31))); + ir_expression *const r08E8 = sub(body.constant(int(1042)), r08CF); + ir_expression *const r08E9 = expr(ir_unop_i2u, r08E8); + ir_expression *const r08EA = lshift(r08E9, body.constant(int(20))); + ir_expression *const r08EB = add(r08E7, r08EA); + body.emit(assign(r08E6, add(r08EB, r08C4), 0x02)); + + body.emit(assign(r08E6, r08C3, 0x01)); + + body.emit(assign(r08C1, r08E6, 0x03)); + + + body.instructions = f08C5_parent_instructions; + body.emit(f08C5); + + /* END IF */ + + body.emit(ret(r08C1)); + + sig->replace_parameters(&sig_parameters); + return sig; +} diff --git a/src/compiler/glsl/builtin_functions.cpp b/src/compiler/glsl/builtin_functions.cpp index 96c3ff2..3c4c8db 100644 --- a/src/compiler/glsl/builtin_functions.cpp +++ b/src/compiler/glsl/builtin_functions.cpp @@ -3382,6 +3382,10 @@ builtin_builder::create_builtins() generate_ir::fp64_to_int(mem_ctx, integer_functions_supported), NULL); + add_function("__builtin_int_to_fp64", + generate_ir::int_to_fp64(mem_ctx, integer_functions_supported), + NULL); + #undef F #undef FI #undef FIUD_VEC diff --git a/src/compiler/glsl/builtin_functions.h b/src/compiler/glsl/builtin_functions.h index 8a7c914..54055e1 100644 --- a/src/compiler/glsl/builtin_functions.h +++ b/src/compiler/glsl/builtin_functions.h @@ -97,6 +97,9 @@ uint_to_fp64(void *mem_ctx, builtin_available_predicate avail); ir_function_signature * fp64_to_int(void *mem_ctx, builtin_available_predicate avail); +ir_function_signature * +int_to_fp64(void *mem_ctx, builtin_available_predicate avail); + } #endif /* BULITIN_FUNCTIONS_H */ diff --git a/src/compiler/glsl/float64.glsl b/src/compiler/glsl/float64.glsl index 557d773..fcc58c1 100644 --- a/src/compiler/glsl/float64.glsl +++ b/src/compiler/glsl/float64.glsl @@ -853,3 +853,26 @@ fp64_to_int(uvec2 a) int nan = mix(0x7FFFFFFF, 0x80000000, bool(aSign)); return mix(z, nan, bool(aSign ^ uint(z < 0)) && bool(z)); } + +/* Returns the result of converting the 32-bit two's complement integer `a' + * to the double-precision floating-point format. The conversion is performed + * according to the IEEE Standard for Floating-Point Arithmetic. + */ +uvec2 +int_to_fp64(int a) +{ + uint zFrac0 = 0u; + uint zFrac1 = 0u; + if (a==0) + return packFloat64(0u, 0, 0u, 0u); + uint zSign = uint(a < 0); + uint absA = mix(uint(a), uint(-a), a < 0); + int shiftCount = countLeadingZeros32(absA) - 11; + if (0 <= shiftCount) { + zFrac0 = absA << shiftCount; + zFrac1 = 0u; + } else { + shift64Right(absA, 0u, -shiftCount, zFrac0, zFrac1); + } + return packFloat64(zSign, 0x412 - shiftCount, zFrac0, zFrac1); +} diff --git a/src/compiler/glsl/glcpp/glcpp-parse.y b/src/compiler/glsl/glcpp/glcpp-parse.y index 3e3b6b7..2c2d2ea 100644 --- a/src/compiler/glsl/glcpp/glcpp-parse.y +++ b/src/compiler/glsl/glcpp/glcpp-parse.y @@ -2378,6 +2378,7 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio add_builtin_define(parser, "__have_builtin_builtin_fp64_to_uint", 1); add_builtin_define(parser, "__have_builtin_builtin_uint_to_fp64", 1); add_builtin_define(parser, "__have_builtin_builtin_fp64_to_int", 1); + add_builtin_define(parser, "__have_builtin_builtin_int_to_fp64", 1); } } -- 2.9.5 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev