llvmpipe: Use saturating add/sub for UNORM formats
authorRichard Sandiford <rsandifo@linux.vnet.ibm.com>
Fri, 7 Jun 2013 12:31:58 +0000 (13:31 +0100)
committerAdam Jackson <ajax@redhat.com>
Mon, 10 Jun 2013 20:20:45 +0000 (16:20 -0400)
lp_build_add and lp_build_sub have fallback code for cases
that cannot be handled by known intrinsics.  For UNORM formats,
this code was using modulo rather than saturating arithmetic.

This fixes some rendering issues for a gnome session on System z.
It also fixes various piglit tests on z, such as
spec/ARB_color_buffer_float/GL_RGBA8-render.

The patch deliberately doesn't tackle the more complicated
SNORM case.

Tested against piglit on x86_64 and System z with no regressions.

Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Richard Sandiford <rsandifo@linux.vnet.ibm.com>
src/gallium/auxiliary/gallivm/lp_bld_arit.c

index 3291ec40af59021e3f4a6c1d76f5e0a22148a3dd..08aec799a337e3e6f76c14ad8ee5301b70d69333 100644 (file)
@@ -386,6 +386,10 @@ lp_build_add(struct lp_build_context *bld,
          return lp_build_intrinsic_binary(builder, intrinsic, lp_build_vec_type(bld->gallivm, bld->type), a, b);
    }
 
+   /* TODO: handle signed case */
+   if(type.norm && !type.floating && !type.fixed && !type.sign)
+      a = lp_build_min_simple(bld, a, lp_build_comp(bld, b));
+
    if(LLVMIsConstant(a) && LLVMIsConstant(b))
       if (type.floating)
          res = LLVMConstFAdd(a, b);
@@ -663,6 +667,10 @@ lp_build_sub(struct lp_build_context *bld,
          return lp_build_intrinsic_binary(builder, intrinsic, lp_build_vec_type(bld->gallivm, bld->type), a, b);
    }
 
+   /* TODO: handle signed case */
+   if(type.norm && !type.floating && !type.fixed && !type.sign)
+      a = lp_build_max_simple(bld, a, b);
+
    if(LLVMIsConstant(a) && LLVMIsConstant(b))
       if (type.floating)
          res = LLVMConstFSub(a, b);