diff options
author | Nicolai Hähnle <[email protected]> | 2017-01-19 14:44:24 +0100 |
---|---|---|
committer | Nicolai Hähnle <[email protected]> | 2017-01-23 16:17:12 +0100 |
commit | 488560cfe6ee2206f7a7f894694ebc43b419be61 (patch) | |
tree | 2918581242a812e66b66f9748e3357d77a835cdb /src | |
parent | 76b02d2fe1df5351f67f53d07b37952043f0a84c (diff) |
r600: factor out cayman_emit_unary_double_raw
We will use it for DDIV.
Tested-by: Glenn Kennard <[email protected]>
Tested-by: James Harvey <[email protected]>
Cc: 17.0 <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/drivers/r600/r600_shader.c | 62 |
1 files changed, 42 insertions, 20 deletions
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 7d1452add34..5c4bc91b498 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -4185,42 +4185,64 @@ static int egcm_double_to_int(struct r600_shader_ctx *ctx) return 0; } -static int cayman_emit_double_instr(struct r600_shader_ctx *ctx) +static int cayman_emit_unary_double_raw(struct r600_bytecode *bc, + unsigned op, + int dst_reg, + struct r600_shader_src *src, + bool abs) { - struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; - int i, r; struct r600_bytecode_alu alu; - int last_slot = 3; - int lasti = tgsi_last_instruction(inst->Dst[0].Register.WriteMask); - int t1 = ctx->temp_reg; + const int last_slot = 3; + int r; /* these have to write the result to X/Y by the looks of it */ - for (i = 0 ; i < last_slot; i++) { + for (int i = 0 ; i < last_slot; i++) { memset(&alu, 0, sizeof(struct r600_bytecode_alu)); - alu.op = ctx->inst_info->op; - - /* should only be one src regs */ - assert (inst->Instruction.NumSrcRegs == 1); + alu.op = op; - r600_bytecode_src(&alu.src[0], &ctx->src[0], 1); - r600_bytecode_src(&alu.src[1], &ctx->src[0], 0); + r600_bytecode_src(&alu.src[0], src, 1); + r600_bytecode_src(&alu.src[1], src, 0); - /* RSQ should take the absolute value of src */ - if (ctx->parse.FullToken.FullInstruction.Instruction.Opcode == TGSI_OPCODE_DRSQ || - ctx->parse.FullToken.FullInstruction.Instruction.Opcode == TGSI_OPCODE_DSQRT) { + if (abs) r600_bytecode_src_set_abs(&alu.src[1]); - } - alu.dst.sel = t1; + + alu.dst.sel = dst_reg; alu.dst.chan = i; alu.dst.write = (i == 0 || i == 1); - if (ctx->bc->chip_class != CAYMAN || i == last_slot - 1) + if (bc->chip_class != CAYMAN || i == last_slot - 1) alu.last = 1; - r = r600_bytecode_add_alu(ctx->bc, &alu); + r = r600_bytecode_add_alu(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; + int i, r; + struct r600_bytecode_alu alu; + int lasti = tgsi_last_instruction(inst->Dst[0].Register.WriteMask); + int t1 = ctx->temp_reg; + + /* should only be one src regs */ + assert(inst->Instruction.NumSrcRegs == 1); + + /* only support one double at a time */ + assert(inst->Dst[0].Register.WriteMask == TGSI_WRITEMASK_XY || + inst->Dst[0].Register.WriteMask == TGSI_WRITEMASK_ZW); + + r = cayman_emit_unary_double_raw( + ctx->bc, ctx->inst_info->op, t1, + &ctx->src[0], + ctx->parse.FullToken.FullInstruction.Instruction.Opcode == TGSI_OPCODE_DRSQ || + ctx->parse.FullToken.FullInstruction.Instruction.Opcode == TGSI_OPCODE_DSQRT); + if (r) + return r; + for (i = 0 ; i <= lasti; i++) { if (!(inst->Dst[0].Register.WriteMask & (1 << i))) continue; |