[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