[Mesa-dev] [PATCH 24/53] st/nine: Handle RSQ special cases

Marek Olšák maraeo at gmail.com
Mon Jan 12 10:47:33 PST 2015


No, TGSI documentation doesn't specify anything AFAIK, but we can
adopt rules from other APIs.

The problem is that OpenGL and DX10 aren't the same and OpenGL doesn't
say much about NaNs. For example, the DX10 "SNE" instructions are
unordered while others are ordered, but OpenGL doesn't specify this,
so the instinct says they are all ordered.

The other problem is that the GLSL compiler performs code
transformations which are incorrect with NaNs. For example, 0*x is
replaced by 0 during compilation.

Since the Unreal Engine doesn't really work with NaNs, I think we have
no other choice than to turn them off. The problem might be in the
GLSL compiler, in the GLSL->TGSI translation, in our LLVM backend, or
even in the Unreal Engine itself.

Marek

On Mon, Jan 12, 2015 at 5:27 PM, Tom Stellard <tom at stellard.net> wrote:
> On Thu, Jan 08, 2015 at 01:46:32PM +0100, Marek Olšák wrote:
>> On Wed, Jan 7, 2015 at 7:09 PM, Ilia Mirkin <imirkin at alum.mit.edu> wrote:
>> > On Wed, Jan 7, 2015 at 11:36 AM, Axel Davy <axel.davy at ens.fr> wrote:
>> >> We should use the absolute value of the input as input to ureg_RSQ.
>> >>
>> >> Moreover, an input of 0.0 should return FLT_MAX.
>> >>
>> >> Reviewed-by: David Heidelberg <david at ixit.cz>
>> >> Signed-off-by: Axel Davy <axel.davy at ens.fr>
>> >>
>> >> Cc: "10.4" <mesa-stable at lists.freedesktop.org>
>> >> ---
>> >>  src/gallium/state_trackers/nine/nine_shader.c | 13 ++++++++++++-
>> >>  1 file changed, 12 insertions(+), 1 deletion(-)
>> >>
>> >> diff --git a/src/gallium/state_trackers/nine/nine_shader.c b/src/gallium/state_trackers/nine/nine_shader.c
>> >> index da77da5..4dee5f5 100644
>> >> --- a/src/gallium/state_trackers/nine/nine_shader.c
>> >> +++ b/src/gallium/state_trackers/nine/nine_shader.c
>> >> @@ -1957,6 +1957,17 @@ DECL_SPECIAL(POW)
>> >>      return D3D_OK;
>> >>  }
>> >>
>> >> +DECL_SPECIAL(RSQ)
>> >> +{
>> >> +    struct ureg_program *ureg = tx->ureg;
>> >> +    struct ureg_dst dst = tx_dst_param(tx, &tx->insn.dst[0]);
>> >> +    struct ureg_src src = tx_src_param(tx, &tx->insn.src[0]);
>> >> +    struct ureg_dst tmp = tx_scratch(tx);
>> >> +    ureg_RSQ(ureg, tmp, ureg_abs(src));
>> >> +    ureg_MIN(ureg, dst, ureg_imm1f(ureg, FLT_MAX), ureg_src(tmp));
>> >
>> > When would this MIN not return the value in tmp? In the description
>> > you say that RSQ(0.0) should return FLT_MAX... is the theory that
>> > MIN(NaN, FLT_MAX) == FLT_MAX? Is RSQ(0) in tgsi defined to return NaN?
>>
>> No, because legacy versions of MIN and MAX aren't commutative. To
>> clarify this more, the legacy versions of MIN/MAX return x if either
>> operand is NaN (non-commutative), while DX10 versions return the one
>> that isn't NaN (commutative). For compatibility with the legacy
>> versions, the FLT_MAX constant must be in x.
>>
>
> Is it documented anywhere how min/max and other tgsi comparison instructions
> are supposed to handle NaN and +-inf?  If not, we really need to get this
> documented somewhere.
>
> -Tom
>
>> Marek
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list