gallivm/tgsi: fix src modifier fetching with non-float types.
authorRoland Scheidegger <sroland@vmware.com>
Sat, 16 Feb 2013 01:26:14 +0000 (02:26 +0100)
committerRoland Scheidegger <sroland@vmware.com>
Sat, 16 Feb 2013 01:40:51 +0000 (02:40 +0100)
Need to take the type into account. Also, if we want to allow
mov's with modifiers we need to pick a type (assume float).

v2: don't allow all modifiers on all type, in particular don't allow
absolute on non-float types and don't allow negate on unsigned.
Also treat UADD as signed (despite the name) since it is used
for handling both signed and unsigned integer arguments and otherwise
modifiers don't work.
Also add tgsi docs clarifying this.

Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
src/gallium/auxiliary/gallivm/lp_bld_tgsi.c
src/gallium/auxiliary/tgsi/tgsi_exec.c
src/gallium/auxiliary/tgsi/tgsi_info.c
src/gallium/docs/source/tgsi.rst

index 53c81bd1fc2b51289de20e2dc906f6137c97783e..7255d97943920fae44f23511e7c676b838ef4ade 100644 (file)
@@ -310,11 +310,43 @@ lp_build_emit_fetch(
    }
 
    if (reg->Register.Absolute) {
-      res = lp_build_emit_llvm_unary(bld_base, TGSI_OPCODE_ABS, res);
+      switch (stype) {
+      case TGSI_TYPE_FLOAT:
+      case TGSI_TYPE_DOUBLE:
+      case TGSI_TYPE_UNTYPED:
+          /* modifiers on movs assume data is float */
+         res = lp_build_emit_llvm_unary(bld_base, TGSI_OPCODE_ABS, res);
+         break;
+      case TGSI_TYPE_UNSIGNED:
+      case TGSI_TYPE_SIGNED:
+      case TGSI_TYPE_VOID:
+      default:
+         /* abs modifier is only legal on floating point types */
+         assert(0);
+         break;
+      }
    }
 
    if (reg->Register.Negate) {
-      res = lp_build_negate( &bld_base->base, res );
+      switch (stype) {
+      case TGSI_TYPE_FLOAT:
+      case TGSI_TYPE_UNTYPED:
+         /* modifiers on movs assume data is float */
+         res = lp_build_negate( &bld_base->base, res );
+         break;
+      case TGSI_TYPE_DOUBLE:
+         /* no double build context */
+         assert(0);
+         break;
+      case TGSI_TYPE_SIGNED:
+         res = lp_build_negate( &bld_base->int_bld, res );
+         break;
+      case TGSI_TYPE_UNSIGNED:
+      case TGSI_TYPE_VOID:
+      default:
+         assert(0);
+         break;
+      }
    }
 
    /*
index 03f194209869237d713feb212290b4c8b62dfa98..1099d062dd83709e0a8779bfb2f3df8cb37a7c02 100644 (file)
@@ -4150,7 +4150,7 @@ exec_instruction(
       break;
 
    case TGSI_OPCODE_UADD:
-      exec_vector_binary(mach, inst, micro_uadd, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+      exec_vector_binary(mach, inst, micro_uadd, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
       break;
 
    case TGSI_OPCODE_UDIV:
index f289ebcda5adbdb62a794c634d0430cd11e5783c..9c6fdfcd2780291f79010fedd02ff2144cf1422b 100644 (file)
@@ -277,9 +277,9 @@ tgsi_opcode_infer_src_type( uint opcode )
    case TGSI_OPCODE_AND:
    case TGSI_OPCODE_OR:
    case TGSI_OPCODE_XOR:
+   /* XXX some src args may be signed for SAD ? */
    case TGSI_OPCODE_SAD:
    case TGSI_OPCODE_U2F:
-   case TGSI_OPCODE_UADD:
    case TGSI_OPCODE_UDIV:
    case TGSI_OPCODE_UMOD:
    case TGSI_OPCODE_UMAD:
@@ -310,6 +310,8 @@ tgsi_opcode_infer_src_type( uint opcode )
    case TGSI_OPCODE_IABS:
    case TGSI_OPCODE_ISSG:
    case TGSI_OPCODE_UARL:
+   /* UADD is both signed and unsigned require signed for working modifiers */
+   case TGSI_OPCODE_UADD:
       return TGSI_TYPE_SIGNED;
    default:
       return TGSI_TYPE_FLOAT;
@@ -331,7 +333,6 @@ tgsi_opcode_infer_dst_type( uint opcode )
    case TGSI_OPCODE_OR:
    case TGSI_OPCODE_XOR:
    case TGSI_OPCODE_SAD:
-   case TGSI_OPCODE_UADD:
    case TGSI_OPCODE_UDIV:
    case TGSI_OPCODE_UMOD:
    case TGSI_OPCODE_UMAD:
@@ -362,6 +363,7 @@ tgsi_opcode_infer_dst_type( uint opcode )
    case TGSI_OPCODE_ARR:
    case TGSI_OPCODE_IABS:
    case TGSI_OPCODE_ISSG:
+   case TGSI_OPCODE_UADD:
       return TGSI_TYPE_SIGNED;
    default:
       return TGSI_TYPE_FLOAT;
index dd4c7739f3f4231bd950ca8bf4b84eb34700ab2a..d9a7fe9774a89083b50d0673061fd8ddb008c354 100644 (file)
@@ -23,6 +23,21 @@ When an instruction has a scalar result, the result is usually copied into
 each of the components of *dst*. When this happens, the result is said to be
 *replicated* to *dst*. :opcode:`RCP` is one such instruction.
 
+Modifiers
+^^^^^^^^^^^^^^^
+
+TGSI supports modifiers on inputs (as well as saturate modifier on instructions).
+
+For inputs which have a floating point type, both absolute value and negation
+modifiers are supported (with absolute value being applied first).
+TGSI_OPCODE_MOV is considered to have float input type for applying modifiers.
+
+For inputs which have signed type only the negate modifier is supported. This
+includes instructions which are otherwise ignorant if the type is signed or
+unsigned, such as TGSI_OPCODE_UADD.
+
+For inputs with unsigned type no modifiers are allowed.
+
 Instruction Set
 ---------------