[Mesa-dev] [PATCH] mesa: Add abs input modifier to base for POW in ffvertex_prog

Ilia Mirkin imirkin at alum.mit.edu
Thu Oct 1 12:45:03 PDT 2015


On Thu, Oct 1, 2015 at 8:36 AM, Daniel Scharrer <daniel at constexpr.org> wrote:
> The result of POW for a negative base is undefined. Even when the result
> is multiplied by zero (which is the case here whenever the base is
> negative), the Inf and NaNs can propagate past that.
>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=91342
> Signed-off-by: Daniel Scharrer <daniel at constexpr.org>
> Cc: "10.6 11.0" <mesa-stable at lists.freedesktop.org>

Reviewed-by: Ilia Mirkin <imirkin at alum.mit.edu>

This also fixes the trace in question on nouveau (tested with a
GK208). Nice find! I did some digging in the ARB_vertex_program spec,
and it explicitly says that LG2(negative) is undefined, and that POW
can be expressed as EX2 + LG2, so the compilers are well within their
right to compile the program as they have been.

Let me know if you need me to push this out for you.

  -ilia

> ---
>  src/mesa/main/ffvertex_prog.c | 17 ++++++++++++++---
>  1 file changed, 14 insertions(+), 3 deletions(-)
>
> diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c
> index 95b428d..a6183b4 100644
> --- a/src/mesa/main/ffvertex_prog.c
> +++ b/src/mesa/main/ffvertex_prog.c
> @@ -293,9 +293,10 @@ struct ureg {
>     GLuint file:4;
>     GLint idx:9;      /* relative addressing may be negative */
>                       /* sizeof(idx) should == sizeof(prog_src_reg::Index) */
> +   GLuint abs:1;
>     GLuint negate:1;
>     GLuint swz:12;
> -   GLuint pad:6;
> +   GLuint pad:5;
>  };
>
>
> @@ -324,6 +325,7 @@ static const struct ureg undef = {
>     0,
>     0,
>     0,
> +   0,
>     0
>  };
>
> @@ -342,6 +344,7 @@ static struct ureg make_ureg(GLuint file, GLint idx)
>     struct ureg reg;
>     reg.file = file;
>     reg.idx = idx;
> +   reg.abs = 0;
>     reg.negate = 0;
>     reg.swz = SWIZZLE_NOOP;
>     reg.pad = 0;
> @@ -350,6 +353,14 @@ static struct ureg make_ureg(GLuint file, GLint idx)
>
>
>
> +static struct ureg absolute( struct ureg reg )
> +{
> +   reg.abs = 1;
> +   reg.negate = 0;
> +   return reg;
> +}
> +
> +
>  static struct ureg negate( struct ureg reg )
>  {
>     reg.negate ^= 1;
> @@ -526,8 +537,8 @@ static void emit_arg( struct prog_src_register *src,
>     src->File = reg.file;
>     src->Index = reg.idx;
>     src->Swizzle = reg.swz;
> +   src->Abs = reg.abs;
>     src->Negate = reg.negate ? NEGATE_XYZW : NEGATE_NONE;
> -   src->Abs = 0;
>     src->RelAddr = 0;
>     /* Check that bitfield sizes aren't exceeded */
>     assert(src->Index == reg.idx);
> @@ -953,7 +964,7 @@ static struct ureg calculate_light_attenuation( struct tnl_program *p,
>
>        emit_op2(p, OPCODE_DP3, spot, 0, negate(VPpli), spot_dir_norm);
>        emit_op2(p, OPCODE_SLT, slt, 0, swizzle1(spot_dir_norm,W), spot);
> -      emit_op2(p, OPCODE_POW, spot, 0, spot, swizzle1(attenuation, W));
> +      emit_op2(p, OPCODE_POW, spot, 0, absolute(spot), swizzle1(attenuation, W));
>        emit_op2(p, OPCODE_MUL, att, 0, slt, spot);
>
>        release_temp(p, spot);
> --
> 2.6.0
>
> _______________________________________________
> 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