Signed-off-by: Elie Tournier <elie.tourn...@collabora.com> --- src/compiler/glsl/builtin_float64.h | 119 ++++++++++++++++++++++++++++++++ src/compiler/glsl/builtin_functions.cpp | 4 ++ src/compiler/glsl/builtin_functions.h | 3 + src/compiler/glsl/float64.glsl | 41 +++++++++++ 4 files changed, 167 insertions(+)
diff --git a/src/compiler/glsl/builtin_float64.h b/src/compiler/glsl/builtin_float64.h index 6df91e10f5..e614374d75 100644 --- a/src/compiler/glsl/builtin_float64.h +++ b/src/compiler/glsl/builtin_float64.h @@ -36,3 +36,122 @@ fneg64(void *mem_ctx, builtin_available_predicate avail) sig->replace_parameters(&sig_parameters); return sig; } +ir_function_signature * +extractFloat64Frac(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 r000D = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "a", ir_var_function_in); + sig_parameters.push_tail(r000D); + ir_variable *const r000E = body.make_temp(glsl_type::uvec2_type, "vec_ctor"); + body.emit(assign(r000E, bit_and(swizzle_x(r000D), body.constant(1048575u)), 0x01)); + + body.emit(assign(r000E, swizzle_y(r000D), 0x02)); + + body.emit(ret(r000E)); + + sig->replace_parameters(&sig_parameters); + return sig; +} +ir_function_signature * +extractFloat64Exp(void *mem_ctx, builtin_available_predicate avail) +{ + ir_function_signature *const sig = + new(mem_ctx) ir_function_signature(glsl_type::uint_type, avail); + ir_factory body(&sig->body, mem_ctx); + sig->is_defined = true; + + exec_list sig_parameters; + + ir_variable *const r000F = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "a", ir_var_function_in); + sig_parameters.push_tail(r000F); + ir_expression *const r0010 = rshift(swizzle_x(r000F), body.constant(int(20))); + ir_expression *const r0011 = bit_and(r0010, body.constant(2047u)); + body.emit(ret(r0011)); + + sig->replace_parameters(&sig_parameters); + return sig; +} +ir_function_signature * +feq64(void *mem_ctx, builtin_available_predicate avail) +{ + ir_function_signature *const sig = + new(mem_ctx) ir_function_signature(glsl_type::bool_type, avail); + ir_factory body(&sig->body, mem_ctx); + sig->is_defined = true; + + exec_list sig_parameters; + + ir_variable *const r0012 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "a", ir_var_function_in); + sig_parameters.push_tail(r0012); + ir_variable *const r0013 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "b", ir_var_function_in); + sig_parameters.push_tail(r0013); + ir_variable *const r0014 = body.make_temp(glsl_type::bool_type, "return_value"); + ir_variable *const r0015 = new(mem_ctx) ir_variable(glsl_type::bool_type, "isbNaN", ir_var_auto); + body.emit(r0015); + ir_variable *const r0016 = new(mem_ctx) ir_variable(glsl_type::bool_type, "isaNaN", ir_var_auto); + body.emit(r0016); + ir_variable *const r0017 = body.make_temp(glsl_type::uvec2_type, "vec_ctor"); + body.emit(assign(r0017, bit_and(swizzle_x(r0012), body.constant(1048575u)), 0x01)); + + body.emit(assign(r0017, swizzle_y(r0012), 0x02)); + + ir_variable *const r0018 = body.make_temp(glsl_type::uvec2_type, "vec_ctor"); + body.emit(assign(r0018, bit_and(swizzle_x(r0013), body.constant(1048575u)), 0x01)); + + body.emit(assign(r0018, swizzle_y(r0013), 0x02)); + + ir_expression *const r0019 = rshift(swizzle_x(r0012), body.constant(int(20))); + ir_expression *const r001A = bit_and(r0019, body.constant(2047u)); + ir_expression *const r001B = equal(r001A, body.constant(2047u)); + ir_expression *const r001C = bit_or(swizzle_x(r0017), swizzle_y(r0012)); + ir_expression *const r001D = nequal(r001C, body.constant(0u)); + body.emit(assign(r0016, logic_and(r001B, r001D), 0x01)); + + ir_expression *const r001E = rshift(swizzle_x(r0013), body.constant(int(20))); + ir_expression *const r001F = bit_and(r001E, body.constant(2047u)); + ir_expression *const r0020 = equal(r001F, body.constant(2047u)); + ir_expression *const r0021 = bit_or(swizzle_x(r0018), swizzle_y(r0013)); + ir_expression *const r0022 = nequal(r0021, body.constant(0u)); + body.emit(assign(r0015, logic_and(r0020, r0022), 0x01)); + + /* IF CONDITION */ + ir_expression *const r0024 = logic_or(r0016, r0015); + ir_if *f0023 = new(mem_ctx) ir_if(operand(r0024).val); + exec_list *const f0023_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f0023->then_instructions; + + body.emit(assign(r0014, body.constant(false), 0x01)); + + + /* ELSE INSTRUCTIONS */ + body.instructions = &f0023->else_instructions; + + ir_expression *const r0025 = equal(swizzle_y(r0012), swizzle_y(r0013)); + ir_expression *const r0026 = equal(swizzle_x(r0012), swizzle_x(r0013)); + ir_expression *const r0027 = equal(swizzle_y(r0012), body.constant(0u)); + ir_expression *const r0028 = bit_or(swizzle_x(r0012), swizzle_x(r0013)); + ir_expression *const r0029 = lshift(r0028, body.constant(int(1))); + ir_expression *const r002A = equal(r0029, body.constant(0u)); + ir_expression *const r002B = logic_and(r0027, r002A); + ir_expression *const r002C = logic_or(r0026, r002B); + body.emit(assign(r0014, logic_and(r0025, r002C), 0x01)); + + + body.instructions = f0023_parent_instructions; + body.emit(f0023); + + /* END IF */ + + body.emit(ret(r0014)); + + sig->replace_parameters(&sig_parameters); + return sig; +} diff --git a/src/compiler/glsl/builtin_functions.cpp b/src/compiler/glsl/builtin_functions.cpp index a189b84190..5e73d2469c 100644 --- a/src/compiler/glsl/builtin_functions.cpp +++ b/src/compiler/glsl/builtin_functions.cpp @@ -3137,6 +3137,10 @@ builtin_builder::create_builtins() generate_ir::fneg64(mem_ctx, integer_functions_supported), NULL); + add_function("__builtin_feq64", + generate_ir::feq64(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 37c6cc33c2..741698dc9e 100644 --- a/src/compiler/glsl/builtin_functions.h +++ b/src/compiler/glsl/builtin_functions.h @@ -69,6 +69,9 @@ fabs64(void *mem_ctx, builtin_available_predicate avail); ir_function_signature * fneg64(void *mem_ctx, builtin_available_predicate avail); +ir_function_signature * +feq64(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 82875e9407..dc7668c18b 100644 --- a/src/compiler/glsl/float64.glsl +++ b/src/compiler/glsl/float64.glsl @@ -36,3 +36,44 @@ fneg64( uvec2 a ) a.x ^= (1u<<31); return a; } + +/* Returns the fraction bits of the double-precision floating-point value `a'.*/ +uvec2 +extractFloat64Frac( uvec2 a ) +{ + return uvec2( a.x & 0x000FFFFFu, a.y ); +} + +/* Returns the exponent bits of the double-precision floating-point value `a'.*/ +uint +extractFloat64Exp( uvec2 a ) +{ + return (a.x>>20) & 0x7FFu; +} + +/* Returns true if the double-precision floating-point value `a' is equal to the + * corresponding value `b', and false otherwise. The comparison is performed + * according to the IEEE Standard for Floating-Point Arithmetic. + */ +bool +feq64( uvec2 a, uvec2 b ) +{ + uvec2 aFrac; + uvec2 bFrac; + bool isaNaN; + bool isbNaN; + + aFrac = extractFloat64Frac( a ); + bFrac = extractFloat64Frac( b ); + isaNaN = ( extractFloat64Exp( a ) == 0x7FFu ) && + ( ( aFrac.x | aFrac.y ) != 0u ); + isbNaN = ( extractFloat64Exp( b ) == 0x7FFu ) && + ( ( bFrac.x | bFrac.y ) != 0u ); + + if ( isaNaN || isbNaN ) { + return false; + } + return ( a.y == b.y ) && + ( ( a.x == b.x ) || + ( ( a.y == 0u ) && ( ( ( a.x | b.x )<<1) == 0u ) ) ); +} -- 2.11.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev