summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Fonseca <[email protected]>2012-02-20 20:49:03 +0000
committerJosé Fonseca <[email protected]>2012-02-21 08:23:20 +0000
commita206c4cd69a881bf3f8d960607d604b6d53e3a26 (patch)
treee1e18c312b31b5615c30af316505a2f993cde919
parentd394bc5853f70f5a2d4c4b396e55b96c1ba63be7 (diff)
gallivm: Fix TGSI_OPCODE_ARR's translation.
Like TGSI_OPCODE_ARL, destination should be an integer. This fixes invalid LLVM IR on an internal state tracker (currently Mesa never emits this opcode). In the future consider making ADDR register also a integer-as-float array, like all other register kinds, or simply replace ADDR & ARR/ARL with integer temp and instructions. Reviewed-by: Dave Airlie <[email protected]>
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c16
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c7
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_info.c1
3 files changed, 22 insertions, 2 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c
index 1390b2e99c5..65c2a6b6be8 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c
@@ -102,8 +102,9 @@ arr_emit(
struct lp_build_tgsi_context * bld_base,
struct lp_build_emit_data * emit_data)
{
- emit_data->output[emit_data->chan] = lp_build_emit_llvm_unary(bld_base,
- TGSI_OPCODE_ROUND, emit_data->args[0]);
+ LLVMValueRef tmp = lp_build_emit_llvm_unary(bld_base, TGSI_OPCODE_ROUND, emit_data->args[0]);
+ emit_data->output[emit_data->chan] = LLVMBuildFPToSI(bld_base->base.gallivm->builder, tmp,
+ bld_base->uint_bld.vec_type, "");
}
/* TGSI_OPCODE_CLAMP */
@@ -820,6 +821,16 @@ arl_emit_cpu(
bld_base->uint_bld.vec_type, "");
}
+/* TGSI_OPCODE_ARR (CPU Only) */
+static void
+arr_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ emit_data->output[emit_data->chan] = lp_build_iround(&bld_base->base, emit_data->args[0]);
+}
+
/* TGSI_OPCODE_CEIL (CPU Only) */
static void
ceil_emit_cpu(
@@ -1166,6 +1177,7 @@ lp_set_default_actions_cpu(
bld_base->op_actions[TGSI_OPCODE_ABS].emit = abs_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_ADD].emit = add_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_ARL].emit = arl_emit_cpu;
+ bld_base->op_actions[TGSI_OPCODE_ARR].emit = arr_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_CEIL].emit = ceil_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_CND].emit = cnd_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_COS].emit = cos_emit_cpu;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index 9a12db7842d..1abee4044d9 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
@@ -1027,6 +1027,8 @@ emit_store_chan(
break;
case TGSI_FILE_ADDRESS:
+ assert(dtype == TGSI_TYPE_SIGNED);
+ assert(LLVMTypeOf(value) == bld_base->base.int_vec_type);
lp_exec_mask_store(&bld->exec_mask, bld_store, pred, value,
bld->addr[reg->Register.Index][chan_index]);
break;
@@ -1377,6 +1379,11 @@ lp_emit_declaration_soa(
break;
case TGSI_FILE_ADDRESS:
+ /* ADDR registers are the only allocated with an integer LLVM IR type,
+ * as they are guaranteed to always have integers.
+ * XXX: Not sure if this exception is worthwhile (or the whole idea of
+ * an ADDR register for that matter).
+ */
assert(idx < LP_MAX_TGSI_ADDRS);
for (i = 0; i < TGSI_NUM_CHANNELS; i++)
bld->addr[idx][i] = lp_build_alloca(gallivm, bld_base->base.int_vec_type, "addr");
diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.c b/src/gallium/auxiliary/tgsi/tgsi_info.c
index a44f48ca881..81df96b3c7a 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_info.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_info.c
@@ -333,6 +333,7 @@ tgsi_opcode_infer_dst_type( uint opcode )
case TGSI_OPCODE_MOD:
case TGSI_OPCODE_UARL:
case TGSI_OPCODE_ARL:
+ case TGSI_OPCODE_ARR:
case TGSI_OPCODE_IABS:
case TGSI_OPCODE_ISSG:
return TGSI_TYPE_SIGNED;