[Mesa-dev] [PATCH 39/51] intel/compiler/fs: Consider logic ops on 16-bit booleans
Topi Pohjolainen
topi.pohjolainen at gmail.com
Fri Nov 24 12:27:06 UTC 2017
Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
src/intel/compiler/brw_fs_nir.cpp | 70 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 69 insertions(+), 1 deletion(-)
diff --git a/src/intel/compiler/brw_fs_nir.cpp b/src/intel/compiler/brw_fs_nir.cpp
index 2a32b1449a..aff592c354 100644
--- a/src/intel/compiler/brw_fs_nir.cpp
+++ b/src/intel/compiler/brw_fs_nir.cpp
@@ -1662,7 +1662,75 @@ fs_visitor::get_nir_alu_dest(const nir_alu_instr *instr)
* one component per register.
*/
const bool pad_components_to_full_register = true;
- return get_nir_dest(instr->dest.dest, pad_components_to_full_register);
+
+ switch (instr->op) {
+ case nir_op_flt:
+ case nir_op_fge:
+ case nir_op_feq:
+ case nir_op_fne: {
+ assert(instr->dest.dest.is_ssa);
+
+ if (nir_src_bit_size(instr->src[0].src) > 16)
+ return get_nir_dest(instr->dest.dest);
+
+ assert(nir_src_bit_size(instr->src[0].src) == 16 &&
+ nir_src_bit_size(instr->src[1].src) == 16);
+
+ /* Destination type for comparison operations is boolean which NIR
+ * treats as having 32-bit size. If, however, sources are 16-bit
+ * hardware will produce 16-bit result (0xFFFF/0x0000). Therefore set
+ * the destination type accordingly.
+ */
+ nir_ssa_values[instr->dest.dest.ssa.index] =
+ bld.vgrf(BRW_REGISTER_TYPE_HF,
+ instr->dest.dest.ssa.num_components,
+ pad_components_to_full_register);
+ return nir_ssa_values[instr->dest.dest.ssa.index];
+ }
+ case nir_op_inot:
+ case nir_op_ixor:
+ case nir_op_ior:
+ case nir_op_iand: {
+ assert(instr->dest.dest.is_ssa);
+
+ const fs_reg src0 = get_nir_src(instr->src[0].src);
+ const fs_reg src1 = get_nir_src(instr->src[0].src);
+
+ /* TODO: This specifically prepares for mixed precision operations which
+ * in principle shouldn't happen. There is, however, corner case
+ * when this is possible. As NIR doesn't consider how booleans
+ * are produced, we may end up here with one source operand
+ * produced from an operation with 32-bit sources and another from
+ * 16-bits.
+ * This is handled by marking this operation as producing 16-bits
+ * and relying on nir_emit_alu() to adjust the 32-bit source
+ * operand to 16-bits with stride == 2. Recall that 32-bit
+ * booleans are just 0xFFFFFFFF/0x00000000 and it suffices to read
+ * only the lower 16-bits.
+ * WARN: This blindly assumes that mixed precision integer source
+ * operands represent boolean values. There is no way of checking
+ * if that holds.
+ */
+ if (brw_reg_type_to_size(src0.type) > 2 &&
+ brw_reg_type_to_size(src1.type) > 2)
+ return get_nir_dest(instr->dest.dest);
+
+ /* Translation from GLSL to NIR produces logical operations with
+ * integer operands even when operands are booleans. See handling
+ * of ir_binop_bit_*.
+ * As hardware will produce 16-bit results when the sources are 16-bit
+ * set the destination type accordingly.
+ */
+ nir_ssa_values[instr->dest.dest.ssa.index] =
+ bld.vgrf(BRW_REGISTER_TYPE_W,
+ instr->dest.dest.ssa.num_components,
+ pad_components_to_full_register);
+ return nir_ssa_values[instr->dest.dest.ssa.index];
+ }
+ default:
+ return get_nir_dest(instr->dest.dest,
+ pad_components_to_full_register);
+ }
}
fs_reg
--
2.11.0
More information about the mesa-dev
mailing list