diff options
author | Francisco Jerez <[email protected]> | 2016-05-17 23:54:25 -0700 |
---|---|---|
committer | Francisco Jerez <[email protected]> | 2016-05-27 23:19:21 -0700 |
commit | 99b5476d33f967ac2a30c3f8f7f958a7169e7123 (patch) | |
tree | ebcce452816e95424dd07983ec24c3e187049ded | |
parent | e531b7907a6a10922e09c42f9c78d3b59beab2b4 (diff) |
i965/fs: Lower math into Gen4-5 send-like instructions in lower_logical_sends.
The benefit is we will be able to use the SIMD lowering pass to unroll
math instructions of unsupported width and then remove some cruft from
the generator.
Reviewed-by: Jason Ekstrand <[email protected]>
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs.cpp | 55 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_builder.h | 47 |
2 files changed, 60 insertions, 42 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index d7ae90a8f04..822d863ab1c 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -4434,6 +4434,36 @@ lower_varying_pull_constant_logical_send(const fs_builder &bld, fs_inst *inst) } } +static void +lower_math_logical_send(const fs_builder &bld, fs_inst *inst) +{ + assert(bld.shader->devinfo->gen < 6); + + inst->base_mrf = 2; + inst->mlen = inst->sources * inst->exec_size / 8; + + if (inst->sources > 1) { + /* From the Ironlake PRM, Volume 4, Part 1, Section 6.1.13 + * "Message Payload": + * + * "Operand0[7]. For the INT DIV functions, this operand is the + * denominator." + * ... + * "Operand1[7]. For the INT DIV functions, this operand is the + * numerator." + */ + const bool is_int_div = inst->opcode != SHADER_OPCODE_POW; + const fs_reg src0 = is_int_div ? inst->src[1] : inst->src[0]; + const fs_reg src1 = is_int_div ? inst->src[0] : inst->src[1]; + + inst->resize_sources(1); + inst->src[0] = src0; + + assert(inst->exec_size == 8); + bld.MOV(fs_reg(MRF, inst->base_mrf + 1, src1.type), src1); + } +} + bool fs_visitor::lower_logical_sends() { @@ -4543,6 +4573,31 @@ fs_visitor::lower_logical_sends() lower_varying_pull_constant_logical_send(ibld, inst); break; + case SHADER_OPCODE_RCP: + case SHADER_OPCODE_RSQ: + case SHADER_OPCODE_SQRT: + case SHADER_OPCODE_EXP2: + case SHADER_OPCODE_LOG2: + case SHADER_OPCODE_SIN: + case SHADER_OPCODE_COS: + case SHADER_OPCODE_POW: + case SHADER_OPCODE_INT_QUOTIENT: + case SHADER_OPCODE_INT_REMAINDER: + /* The math opcodes are overloaded for the send-like and + * expression-like instructions which seems kind of icky. Gen6+ has + * a native (but rather quirky) MATH instruction so we don't need to + * do anything here. On Gen4-5 we'll have to lower the Gen6-like + * logical instructions (which we can easily recognize because they + * have mlen = 0) into send-like virtual instructions. + */ + if (devinfo->gen < 6 && inst->mlen == 0) { + lower_math_logical_send(ibld, inst); + break; + + } else { + continue; + } + default: continue; } diff --git a/src/mesa/drivers/dri/i965/brw_fs_builder.h b/src/mesa/drivers/dri/i965/brw_fs_builder.h index 2087e585b06..b50dda421ae 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_builder.h +++ b/src/mesa/drivers/dri/i965/brw_fs_builder.h @@ -281,9 +281,8 @@ namespace brw { case SHADER_OPCODE_LOG2: case SHADER_OPCODE_SIN: case SHADER_OPCODE_COS: - return fix_math_instruction( - emit(instruction(opcode, dispatch_width(), dst, - fix_math_operand(src0)))); + return emit(instruction(opcode, dispatch_width(), dst, + fix_math_operand(src0))); default: return emit(instruction(opcode, dispatch_width(), dst, src0)); @@ -301,10 +300,9 @@ namespace brw { case SHADER_OPCODE_POW: case SHADER_OPCODE_INT_QUOTIENT: case SHADER_OPCODE_INT_REMAINDER: - return fix_math_instruction( - emit(instruction(opcode, dispatch_width(), dst, - fix_math_operand(src0), - fix_math_operand(src1)))); + return emit(instruction(opcode, dispatch_width(), dst, + fix_math_operand(src0), + fix_math_operand(src1))); default: return emit(instruction(opcode, dispatch_width(), dst, src0, src1)); @@ -640,41 +638,6 @@ namespace brw { } } - /** - * Workaround other weirdness of the math instruction. - */ - instruction * - fix_math_instruction(instruction *inst) const - { - if (shader->devinfo->gen < 6) { - inst->base_mrf = 2; - inst->mlen = inst->sources * dispatch_width() / 8; - - if (inst->sources > 1) { - /* From the Ironlake PRM, Volume 4, Part 1, Section 6.1.13 - * "Message Payload": - * - * "Operand0[7]. For the INT DIV functions, this operand is the - * denominator." - * ... - * "Operand1[7]. For the INT DIV functions, this operand is the - * numerator." - */ - const bool is_int_div = inst->opcode != SHADER_OPCODE_POW; - const fs_reg src0 = is_int_div ? inst->src[1] : inst->src[0]; - const fs_reg src1 = is_int_div ? inst->src[0] : inst->src[1]; - - inst->resize_sources(1); - inst->src[0] = src0; - - at(block, inst).MOV(fs_reg(MRF, inst->base_mrf + 1, src1.type), - src1); - } - } - - return inst; - } - bblock_t *block; exec_node *cursor; |