[Mesa-dev] [RFC 02/11] glsl: Add "built-in" function to do neg(fp64)
Ian Romanick
idr at freedesktop.org
Thu Mar 9 19:56:53 UTC 2017
On 03/03/2017 09:13 AM, Ilia Mirkin wrote:
> On Fri, Mar 3, 2017 at 11:57 AM, tournier.elie <tournier.elie at gmail.com> wrote:
>> On 3 March 2017 at 16:29, Ilia Mirkin <imirkin at alum.mit.edu> wrote:
>>> On Fri, Mar 3, 2017 at 11:22 AM, Elie Tournier <tournier.elie at gmail.com> wrote:
>>>> Signed-off-by: Elie Tournier <elie.tournier at collabora.com>
>>>> ---
>>>> src/compiler/glsl/builtin_float64.h | 19 +++++++++++++++++++
>>>> src/compiler/glsl/builtin_functions.cpp | 4 ++++
>>>> src/compiler/glsl/builtin_functions.h | 3 +++
>>>> src/compiler/glsl/float64.glsl | 10 ++++++++++
>>>> 4 files changed, 36 insertions(+)
>>>>
>>>> diff --git a/src/compiler/glsl/builtin_float64.h b/src/compiler/glsl/builtin_float64.h
>>>> index c1ec89d210..6df91e10f5 100644
>>>> --- a/src/compiler/glsl/builtin_float64.h
>>>> +++ b/src/compiler/glsl/builtin_float64.h
>>>> @@ -17,3 +17,22 @@ fabs64(void *mem_ctx, builtin_available_predicate avail)
>>>> sig->replace_parameters(&sig_parameters);
>>>> return sig;
>>>> }
>>>> +ir_function_signature *
>>>> +fneg64(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 r000C = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "a", ir_var_function_in);
>>>> + sig_parameters.push_tail(r000C);
>>>> + body.emit(assign(r000C, bit_xor(swizzle_x(r000C), body.constant(2147483648u)), 0x01));
>>>> +
>>>> + body.emit(ret(r000C));
>>>> +
>>>> + sig->replace_parameters(&sig_parameters);
>>>> + return sig;
>>>> +}
>>>> diff --git a/src/compiler/glsl/builtin_functions.cpp b/src/compiler/glsl/builtin_functions.cpp
>>>> index b0b1781725..a189b84190 100644
>>>> --- a/src/compiler/glsl/builtin_functions.cpp
>>>> +++ b/src/compiler/glsl/builtin_functions.cpp
>>>> @@ -3133,6 +3133,10 @@ builtin_builder::create_builtins()
>>>> generate_ir::fabs64(mem_ctx, integer_functions_supported),
>>>> NULL);
>>>>
>>>> + add_function("__builtin_fneg64",
>>>> + generate_ir::fneg64(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 abe02d97b6..37c6cc33c2 100644
>>>> --- a/src/compiler/glsl/builtin_functions.h
>>>> +++ b/src/compiler/glsl/builtin_functions.h
>>>> @@ -66,6 +66,9 @@ sign64(void *mem_ctx, builtin_available_predicate avail);
>>>> ir_function_signature *
>>>> fabs64(void *mem_ctx, builtin_available_predicate avail);
>>>>
>>>> +ir_function_signature *
>>>> +fneg64(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 b8f0c2e444..82875e9407 100644
>>>> --- a/src/compiler/glsl/float64.glsl
>>>> +++ b/src/compiler/glsl/float64.glsl
>>>> @@ -26,3 +26,13 @@ fabs64( uvec2 a )
>>>> a.x &= 0x7FFFFFFFu;
>>>> return a;
>>>> }
>>>> +
>>>> +/* Negate value of a Float64 :
>>>> + * Toggle the sign bit
>>>> + */
>>>> +uvec2
>>>> +fneg64( uvec2 a )
>>>> +{
>>>> + a.x ^= (1u<<31);
>>>
>>> Is this right for NaN? Presumably neg(NaN) should == NaN.
>>
>> The IEEE 754 standard say :
>>
>> " 6.3 The sign bit
>>
>> When either an input or result is NaN, this standard does not
>> interpret the sign of a NaN. Note, however,
>> that operations on bit strings copy, negate, abs, copySign specify the
>> sign bit of a NaN result,
>> sometimes based upon the sign bit of a NaN operand. The logical
>> predicate totalOrder is also affected by
>> the sign bit of a NaN operand. For all other operations, this standard
>> does not specify the sign bit of a NaN
>> result, even when there is only one input NaN, or when the NaN is
>> produced from an invalid operation. "
>>
>> So neg(NaN) == NaN
>
> Right ... I guess I meant that there's a certain amount of
> normalization that's required to be applied to results of floating
> point operations. I was wondering if the sign bit of a NaN had to be
> cleared, so that it would be in canonical form. (Just like you'd set
> all of the mantissa bits, even though setting any of them results in a
> NaN when exp == 0x7ff.) You've been digging in the FP64 standard a lot
> more than I have, so if you think it's acceptable to have a fp64
> function return a NaN with the sign bit set, that's fine by me.
This would be easy enough to test, and we probably should. We can check
unpackDouble2x32(-packDouble2x32(uvec2_that_is_NAN)) ==
unpackDouble2x32(packDouble2x32(uvec2_that_is_NAN)). We could also
check this on a CPU.
> -ilia
More information about the mesa-dev
mailing list