mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 00:49:04 +02:00
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 <jason@jlekstrand.net>
This commit is contained in:
parent
e531b7907a
commit
99b5476d33
2 changed files with 60 additions and 42 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue