From a206c4cd69a881bf3f8d960607d604b6d53e3a26 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 20 Feb 2012 20:49:03 +0000 Subject: [PATCH] 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 --- .../auxiliary/gallivm/lp_bld_tgsi_action.c | 16 ++++++++++++++-- src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 7 +++++++ src/gallium/auxiliary/tgsi/tgsi_info.c | 1 + 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; -- 2.30.2