From: Kenneth Graunke Date: Fri, 6 Mar 2015 04:39:49 +0000 (-0800) Subject: i965/nir: Resolve source modifiers on Gen8+ logic operations. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a84f66a9b6cf46bb19ca71faca5b1d6d81209caf;p=mesa.git 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 Reviewed-by: Topi Pohjolainen --- diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index d6acc238a1a..428234f7aec 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -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) { diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index 70098d8451a..ec77962dd3d 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -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); diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp index 66f79187b69..a0300aa36d5 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp @@ -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;