gallium: fixup definitions of the rsq and sqrt
authorZack Rusin <zackr@vmware.com>
Thu, 11 Jul 2013 16:16:06 +0000 (12:16 -0400)
committerZack Rusin <zackr@vmware.com>
Fri, 12 Jul 2013 00:19:04 +0000 (20:19 -0400)
GLSL spec says that rsq is undefined for src<=0, but the D3D10
spec says it needs to be a NaN, so lets stop taking an absolute
value of the source which completely breaks that behavior. For
the gl program we can simply insert an extra abs instrunction
which produces the desired behavior there.

Signed-off-by: Zack Rusin <zackr@vmware.com>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c
src/gallium/auxiliary/tgsi/tgsi_exec.c
src/gallium/docs/source/tgsi.rst
src/mesa/state_tracker/st_mesa_to_tgsi.c

index 68bd1243ecedbd8868ddceb3022e691739fc638f..e99c8ef134e560d7c3dbb85bbf2167c295fa33b7 100644 (file)
@@ -633,8 +633,6 @@ rsq_emit(
    struct lp_build_tgsi_context * bld_base,
    struct lp_build_emit_data * emit_data)
 {
-   emit_data->args[0] = lp_build_emit_llvm_unary(bld_base, TGSI_OPCODE_ABS,
-                                               emit_data->args[0]);
    if (bld_base->rsq_action.emit) {
       bld_base->rsq_action.emit(&bld_base->rsq_action, bld_base, emit_data);
    } else {
@@ -1349,9 +1347,6 @@ rcp_emit_cpu(
 }
 
 /* Reciprical squareroot (CPU Only) */
-
-/* This is not the same as TGSI_OPCODE_RSQ, which requres the argument to be
- * greater than or equal to 0 */
 static void
 recip_sqrt_emit_cpu(
    const struct lp_build_tgsi_action * action,
index bed08522fcd34bc43439af17e481df65f1429b1c..1f8e62d6f3eed11e85cade81eae71ff27aa084a8 100644 (file)
@@ -339,20 +339,20 @@ micro_rsq(union tgsi_exec_channel *dst,
    assert(src->f[2] != 0.0f);
    assert(src->f[3] != 0.0f);
 #endif
-   dst->f[0] = 1.0f / sqrtf(fabsf(src->f[0]));
-   dst->f[1] = 1.0f / sqrtf(fabsf(src->f[1]));
-   dst->f[2] = 1.0f / sqrtf(fabsf(src->f[2]));
-   dst->f[3] = 1.0f / sqrtf(fabsf(src->f[3]));
+   dst->f[0] = 1.0f / sqrtf(src->f[0]);
+   dst->f[1] = 1.0f / sqrtf(src->f[1]);
+   dst->f[2] = 1.0f / sqrtf(src->f[2]);
+   dst->f[3] = 1.0f / sqrtf(src->f[3]);
 }
 
 static void
 micro_sqrt(union tgsi_exec_channel *dst,
            const union tgsi_exec_channel *src)
 {
-   dst->f[0] = sqrtf(fabsf(src->f[0]));
-   dst->f[1] = sqrtf(fabsf(src->f[1]));
-   dst->f[2] = sqrtf(fabsf(src->f[2]));
-   dst->f[3] = sqrtf(fabsf(src->f[3]));
+   dst->f[0] = sqrtf(src->f[0]);
+   dst->f[1] = sqrtf(src->f[1]);
+   dst->f[2] = sqrtf(src->f[2]);
+   dst->f[3] = sqrtf(src->f[3]);
 }
 
 static void
index 13daa62ab62c8de30f6202f0254d2be187cc6d25..4d26c465579e24238dfb20b8428a1bb79727b0ba 100644 (file)
@@ -94,16 +94,16 @@ This instruction replicates its result.
 
 .. opcode:: RSQ - Reciprocal Square Root
 
-This instruction replicates its result.
+This instruction replicates its result. The results are undefined for src <= 0.
 
 .. math::
 
-  dst = \frac{1}{\sqrt{|src.x|}}
+  dst = \frac{1}{\sqrt{src.x}}
 
 
 .. opcode:: SQRT - Square Root
 
-This instruction replicates its result.
+This instruction replicates its result. The results are undefined for src < 0.
 
 .. math::
 
index 7f306973f3ddee72a3454382bf0049398ad8e86b..67c6f53f638f8a2ba93b54be24da4566f36badb8 100644 (file)
@@ -615,8 +615,6 @@ translate_opcode( unsigned op )
       return TGSI_OPCODE_RCP;
    case OPCODE_RET:
       return TGSI_OPCODE_RET;
-   case OPCODE_RSQ:
-      return TGSI_OPCODE_RSQ;
    case OPCODE_SCS:
       return TGSI_OPCODE_SCS;
    case OPCODE_SEQ:
@@ -756,6 +754,10 @@ compile_instruction(
       emit_ddy( t, dst[0], &inst->SrcReg[0] );
       break;
 
+   case OPCODE_RSQ:
+      ureg_RSQ( ureg, dst[0], ureg_abs(src[0]) );
+      break;
+
    default:
       ureg_insn( ureg, 
                  translate_opcode( inst->Opcode ),