[Mesa-dev] [PATCH 1/2] r600g: Support I2D/U2D/D2I/D2U

Roland Scheidegger sroland at vmware.com
Thu Sep 10 19:37:21 PDT 2015


Just on a very quick glance, seems somewhat odd this function is named
"cypress" whereas the other 64bit ones are named "cayman".
In any case, saying enabling support for chips which have hative support
isn'quite correct, since there's a couple more which should be able to
do it (rv670, rv770, maybe more) as far as I know (no idea though how
complex it would be to implement, maybe they are missing some things...)

Am 10.09.2015 um 22:00 schrieb Glenn Kennard:
> int <-> float <-> double conversion, matches what the blob does
> 
> Signed-off-by: Glenn Kennard <glenn.kennard at gmail.com>
> ---
>  src/gallium/drivers/r600/r600_shader.c | 95 +++++++++++++++++++++++++++++++---
>  1 file changed, 87 insertions(+), 8 deletions(-)
> 
> diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
> index f2c9e16..1c642fd 100644
> --- a/src/gallium/drivers/r600/r600_shader.c
> +++ b/src/gallium/drivers/r600/r600_shader.c
> @@ -3058,6 +3058,85 @@ static int tgsi_dfracexp(struct r600_shader_ctx *ctx)
>  	return 0;
>  }
>  
> +static int cypress_int_double(struct r600_shader_ctx *ctx)
> +{
> +	struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
> +	struct r600_bytecode_alu alu;
> +	int i, r;
> +	int lasti = tgsi_last_instruction(inst->Dst[0].Register.WriteMask);
> +
> +	if (inst->Instruction.Opcode == TGSI_OPCODE_I2D ||
> +		inst->Instruction.Opcode == TGSI_OPCODE_U2D) {
> +
> +		for (i = 0; i <= (lasti+1)/2; i++) {
> +			memset(&alu, 0, sizeof(struct r600_bytecode_alu));
> +			alu.op = ctx->inst_info->op;
> +
> +			r600_bytecode_src(&alu.src[0], &ctx->src[0], i);
> +			alu.dst.sel = ctx->temp_reg;
> +			alu.dst.chan = i;
> +			alu.dst.write = 1;
> +			alu.last = 1;
> +
> +			r = r600_bytecode_add_alu(ctx->bc, &alu);
> +			if (r)
> +				return r;
> +		}
> +
> +		for (i = 0; i <= lasti; i++) {
> +			memset(&alu, 0, sizeof(struct r600_bytecode_alu));
> +			alu.op = ALU_OP1_FLT32_TO_FLT64;
> +
> +			alu.src[0].chan = i/2;
> +			if (i%2 == 0)
> +				alu.src[0].sel = ctx->temp_reg;
> +			else {
> +				alu.src[0].sel = V_SQ_ALU_SRC_LITERAL;
> +				alu.src[0].value = 0x0;
> +			}
> +			tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst);
> +			alu.last = i == lasti;
> +
> +			r = r600_bytecode_add_alu(ctx->bc, &alu);
> +			if (r)
> +				return r;
> +		}
> +	}
> +	else { // D2I/D2U
> +
> +		for (i = 0; i <= lasti; i++) {
> +			memset(&alu, 0, sizeof(struct r600_bytecode_alu));
> +			alu.op = ALU_OP1_FLT64_TO_FLT32;
> +
> +			r600_bytecode_src(&alu.src[0], &ctx->src[0], fp64_switch(i));
> +			alu.dst.chan = i;
> +			alu.dst.sel = ctx->temp_reg;
> +			alu.dst.write = i%2 == 0;
> +			alu.last = i == lasti;
> +
> +			r = r600_bytecode_add_alu(ctx->bc, &alu);
> +			if (r)
> +				return r;
> +		}
> +
> +		for (i = 0; i <= (lasti+1)/2; i++) {
> +			memset(&alu, 0, sizeof(struct r600_bytecode_alu));
> +			alu.op = ctx->inst_info->op;
> +
> +			alu.src[0].chan = i*2;
> +			alu.src[0].sel = ctx->temp_reg;
> +			tgsi_dst(ctx, &inst->Dst[0], 0, &alu.dst);
> +			alu.last = 1;
> +
> +			r = r600_bytecode_add_alu(ctx->bc, &alu);
> +			if (r)
> +				return r;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>  static int cayman_emit_double_instr(struct r600_shader_ctx *ctx)
>  {
>  	struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
> @@ -8150,10 +8229,10 @@ static const struct r600_shader_tgsi_instruction eg_shader_tgsi_instruction[] =
>  	[TGSI_OPCODE_DFRAC]	= { ALU_OP1_FRACT_64, tgsi_op2_64},
>  	[TGSI_OPCODE_DLDEXP]	= { ALU_OP2_LDEXP_64, tgsi_op2_64},
>  	[TGSI_OPCODE_DFRACEXP]	= { ALU_OP1_FREXP_64, tgsi_dfracexp},
> -	[TGSI_OPCODE_D2I]	= { ALU_OP0_NOP, tgsi_unsupported},
> -	[TGSI_OPCODE_I2D]	= { ALU_OP0_NOP, tgsi_unsupported},
> -	[TGSI_OPCODE_D2U]	= { ALU_OP0_NOP, tgsi_unsupported},
> -	[TGSI_OPCODE_U2D]	= { ALU_OP0_NOP, tgsi_unsupported},
> +	[TGSI_OPCODE_D2I]	= { ALU_OP1_FLT_TO_INT, cypress_int_double},
> +	[TGSI_OPCODE_I2D]	= { ALU_OP1_INT_TO_FLT, cypress_int_double},
> +	[TGSI_OPCODE_D2U]	= { ALU_OP1_FLT_TO_UINT, cypress_int_double},
> +	[TGSI_OPCODE_U2D]	= { ALU_OP1_INT_TO_FLT, cypress_int_double},
>  	[TGSI_OPCODE_DRSQ]	= { ALU_OP2_RECIPSQRT_64, cayman_emit_double_instr},
>  	[TGSI_OPCODE_LAST]	= { ALU_OP0_NOP, tgsi_unsupported},
>  };
> @@ -8372,10 +8451,10 @@ static const struct r600_shader_tgsi_instruction cm_shader_tgsi_instruction[] =
>  	[TGSI_OPCODE_DFRAC]	= { ALU_OP1_FRACT_64, tgsi_op2_64},
>  	[TGSI_OPCODE_DLDEXP]	= { ALU_OP2_LDEXP_64, tgsi_op2_64},
>  	[TGSI_OPCODE_DFRACEXP]	= { ALU_OP1_FREXP_64, tgsi_dfracexp},
> -	[TGSI_OPCODE_D2I]	= { ALU_OP0_NOP, tgsi_unsupported},
> -	[TGSI_OPCODE_I2D]	= { ALU_OP0_NOP, tgsi_unsupported},
> -	[TGSI_OPCODE_D2U]	= { ALU_OP0_NOP, tgsi_unsupported},
> -	[TGSI_OPCODE_U2D]	= { ALU_OP0_NOP, tgsi_unsupported},
> +	[TGSI_OPCODE_D2I]	= { ALU_OP1_FLT_TO_INT, cypress_int_double},
> +	[TGSI_OPCODE_I2D]	= { ALU_OP1_INT_TO_FLT, cypress_int_double},
> +	[TGSI_OPCODE_D2U]	= { ALU_OP1_FLT_TO_UINT, cypress_int_double},
> +	[TGSI_OPCODE_U2D]	= { ALU_OP1_UINT_TO_FLT, cypress_int_double},
>  	[TGSI_OPCODE_DRSQ]	= { ALU_OP2_RECIPSQRT_64, cayman_emit_double_instr},
>  	[TGSI_OPCODE_LAST]	= { ALU_OP0_NOP, tgsi_unsupported},
>  };
> 



More information about the mesa-dev mailing list