i965/nir: Resolve source modifiers on Gen8+ logic operations.
On Gen8+, AND/OR/XOR/NOT don't support the abs() source modifier, and
negate changes meaning to bitwise-not (~, not -). This isn't what NIR
expects, so we should resolve the source modifers via a MOV.
+30 Piglits (fs-op-bit{and,or,xor}-not-abs-*).
Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
This commit is contained in:
@@ -1561,6 +1561,17 @@ fs_visitor::emit_sampleid_setup()
|
||||
return reg;
|
||||
}
|
||||
|
||||
void
|
||||
fs_visitor::resolve_source_modifiers(fs_reg *src)
|
||||
{
|
||||
if (!src->abs && !src->negate)
|
||||
return;
|
||||
|
||||
fs_reg temp = retype(vgrf(1), src->type);
|
||||
emit(MOV(temp, *src));
|
||||
*src = temp;
|
||||
}
|
||||
|
||||
fs_reg
|
||||
fs_visitor::fix_math_operand(fs_reg src)
|
||||
{
|
||||
|
||||
@@ -299,6 +299,7 @@ public:
|
||||
int texunit);
|
||||
fs_reg emit_mcs_fetch(fs_reg coordinate, int components, fs_reg sampler);
|
||||
void emit_gen6_gather_wa(uint8_t wa, fs_reg dst);
|
||||
void resolve_source_modifiers(fs_reg *src);
|
||||
fs_reg fix_math_operand(fs_reg src);
|
||||
fs_inst *emit_math(enum opcode op, fs_reg dst, fs_reg src0);
|
||||
fs_inst *emit_math(enum opcode op, fs_reg dst, fs_reg src0, fs_reg src1);
|
||||
|
||||
@@ -935,15 +935,30 @@ fs_visitor::nir_emit_alu(nir_alu_instr *instr)
|
||||
break;
|
||||
|
||||
case nir_op_inot:
|
||||
if (brw->gen >= 8) {
|
||||
resolve_source_modifiers(&op[0]);
|
||||
}
|
||||
emit(NOT(result, op[0]));
|
||||
break;
|
||||
case nir_op_ixor:
|
||||
if (brw->gen >= 8) {
|
||||
resolve_source_modifiers(&op[0]);
|
||||
resolve_source_modifiers(&op[1]);
|
||||
}
|
||||
emit(XOR(result, op[0], op[1]));
|
||||
break;
|
||||
case nir_op_ior:
|
||||
if (brw->gen >= 8) {
|
||||
resolve_source_modifiers(&op[0]);
|
||||
resolve_source_modifiers(&op[1]);
|
||||
}
|
||||
emit(OR(result, op[0], op[1]));
|
||||
break;
|
||||
case nir_op_iand:
|
||||
if (brw->gen >= 8) {
|
||||
resolve_source_modifiers(&op[0]);
|
||||
resolve_source_modifiers(&op[1]);
|
||||
}
|
||||
emit(AND(result, op[0], op[1]));
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user