summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2015-11-22 20:12:17 -0800
committerIan Romanick <ian.d.romanick@intel.com>2018-03-08 15:26:26 -0800
commit70de61594dcf99f24eb31ebf98d62f13e1f44c2e (patch)
treea745f0a99d5626cad6545a0c2598c0d825ff608f
parent54e8d2268de37f320b2d206295d0b519f5be5ab7 (diff)
i965/fs: Add infrastructure for generating CSEL instructions.
v2 (idr): Don't allow CSEL with a non-float src2. v3 (idr): Add CSEL to fs_inst::flags_written. Suggested by Matt. v4 (idr): Only set BRW_ALIGN_16 on Gen < 10 (suggested by Matt). Don't reset the access mode afterwards (suggested by Samuel and Matt). Add support for CSEL not modifying the flags to more places (requested by Matt). Signed-off-by: Kenneth Graunke <kenneth@whitecape.org> Signed-off-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com> [v3] Reviewed-by: Matt Turner <mattst88@gmail.com>
-rw-r--r--src/intel/compiler/brw_disasm.c1
-rw-r--r--src/intel/compiler/brw_eu.h1
-rw-r--r--src/intel/compiler/brw_eu_emit.c1
-rw-r--r--src/intel/compiler/brw_fs.cpp2
-rw-r--r--src/intel/compiler/brw_fs_builder.h22
-rw-r--r--src/intel/compiler/brw_fs_generator.cpp6
-rw-r--r--src/intel/compiler/brw_ir_vec4.h1
-rw-r--r--src/intel/compiler/brw_vec4.cpp1
8 files changed, 34 insertions, 1 deletions
diff --git a/src/intel/compiler/brw_disasm.c b/src/intel/compiler/brw_disasm.c
index a9a108f8ac..5f75c67942 100644
--- a/src/intel/compiler/brw_disasm.c
+++ b/src/intel/compiler/brw_disasm.c
@@ -1508,6 +1508,7 @@ brw_disassemble_inst(FILE *file, const struct gen_device_info *devinfo,
*/
if (brw_inst_cond_modifier(devinfo, inst) &&
(devinfo->gen < 6 || (opcode != BRW_OPCODE_SEL &&
+ opcode != BRW_OPCODE_CSEL &&
opcode != BRW_OPCODE_IF &&
opcode != BRW_OPCODE_WHILE))) {
format(file, ".f%"PRIu64,
diff --git a/src/intel/compiler/brw_eu.h b/src/intel/compiler/brw_eu.h
index a5f28d8fc6..ca72666a55 100644
--- a/src/intel/compiler/brw_eu.h
+++ b/src/intel/compiler/brw_eu.h
@@ -171,6 +171,7 @@ ALU2(SHR)
ALU2(SHL)
ALU1(DIM)
ALU2(ASR)
+ALU3(CSEL)
ALU1(F32TO16)
ALU1(F16TO32)
ALU2(ADD)
diff --git a/src/intel/compiler/brw_eu_emit.c b/src/intel/compiler/brw_eu_emit.c
index f8102e014e..f039af56d0 100644
--- a/src/intel/compiler/brw_eu_emit.c
+++ b/src/intel/compiler/brw_eu_emit.c
@@ -959,6 +959,7 @@ ALU2(SHR)
ALU2(SHL)
ALU1(DIM)
ALU2(ASR)
+ALU3(CSEL)
ALU1(FRC)
ALU1(RNDD)
ALU2(MAC)
diff --git a/src/intel/compiler/brw_fs.cpp b/src/intel/compiler/brw_fs.cpp
index 53ba94cccc..02a8ea0fd9 100644
--- a/src/intel/compiler/brw_fs.cpp
+++ b/src/intel/compiler/brw_fs.cpp
@@ -945,6 +945,7 @@ unsigned
fs_inst::flags_written() const
{
if ((conditional_mod && (opcode != BRW_OPCODE_SEL &&
+ opcode != BRW_OPCODE_CSEL &&
opcode != BRW_OPCODE_IF &&
opcode != BRW_OPCODE_WHILE)) ||
opcode == FS_OPCODE_MOV_DISPATCH_TO_FLAGS ||
@@ -5578,6 +5579,7 @@ fs_visitor::dump_instruction(backend_instruction *be_inst, FILE *file)
fprintf(file, "%s", conditional_modifier[inst->conditional_mod]);
if (!inst->predicate &&
(devinfo->gen < 5 || (inst->opcode != BRW_OPCODE_SEL &&
+ inst->opcode != BRW_OPCODE_CSEL &&
inst->opcode != BRW_OPCODE_IF &&
inst->opcode != BRW_OPCODE_WHILE))) {
fprintf(file, ".f%d.%d", inst->flag_subreg / 2,
diff --git a/src/intel/compiler/brw_fs_builder.h b/src/intel/compiler/brw_fs_builder.h
index cf603b0c86..4203c8c27c 100644
--- a/src/intel/compiler/brw_fs_builder.h
+++ b/src/intel/compiler/brw_fs_builder.h
@@ -567,7 +567,6 @@ namespace brw {
ALU1(BFREV)
ALU1(CBIT)
ALU2(CMPN)
- ALU3(CSEL)
ALU1(DIM)
ALU2(DP2)
ALU2(DP3)
@@ -643,6 +642,27 @@ namespace brw {
}
/**
+ * CSEL: dst = src2 <op> 0.0f ? src0 : src1
+ */
+ instruction *
+ CSEL(const dst_reg &dst, const src_reg &src0, const src_reg &src1,
+ const src_reg &src2, brw_conditional_mod condition) const
+ {
+ /* CSEL only operates on floats, so we can't do integer </<=/>=/>
+ * comparisons. Zero/non-zero (== and !=) comparisons almost work.
+ * 0x80000000 fails because it is -0.0, and -0.0 == 0.0.
+ */
+ assert(src2.type == BRW_REGISTER_TYPE_F);
+
+ return set_condmod(condition,
+ emit(BRW_OPCODE_CSEL,
+ retype(dst, BRW_REGISTER_TYPE_F),
+ retype(src0, BRW_REGISTER_TYPE_F),
+ retype(src1, BRW_REGISTER_TYPE_F),
+ src2));
+ }
+
+ /**
* Emit a linear interpolation instruction.
*/
instruction *
diff --git a/src/intel/compiler/brw_fs_generator.cpp b/src/intel/compiler/brw_fs_generator.cpp
index 5371246fd2..0c85eb8e1e 100644
--- a/src/intel/compiler/brw_fs_generator.cpp
+++ b/src/intel/compiler/brw_fs_generator.cpp
@@ -1975,6 +1975,12 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)
case BRW_OPCODE_SEL:
brw_SEL(p, dst, src[0], src[1]);
break;
+ case BRW_OPCODE_CSEL:
+ assert(devinfo->gen >= 8);
+ if (devinfo->gen < 10)
+ brw_set_default_access_mode(p, BRW_ALIGN_16);
+ brw_CSEL(p, dst, src[0], src[1], src[2]);
+ break;
case BRW_OPCODE_BFREV:
assert(devinfo->gen >= 7);
brw_BFREV(p, retype(dst, BRW_REGISTER_TYPE_UD),
diff --git a/src/intel/compiler/brw_ir_vec4.h b/src/intel/compiler/brw_ir_vec4.h
index a0e6402b0a..cbaff2feff 100644
--- a/src/intel/compiler/brw_ir_vec4.h
+++ b/src/intel/compiler/brw_ir_vec4.h
@@ -329,6 +329,7 @@ public:
bool writes_flag()
{
return (conditional_mod && (opcode != BRW_OPCODE_SEL &&
+ opcode != BRW_OPCODE_CSEL &&
opcode != BRW_OPCODE_IF &&
opcode != BRW_OPCODE_WHILE));
}
diff --git a/src/intel/compiler/brw_vec4.cpp b/src/intel/compiler/brw_vec4.cpp
index ac6b997b66..e4838146ac 100644
--- a/src/intel/compiler/brw_vec4.cpp
+++ b/src/intel/compiler/brw_vec4.cpp
@@ -1557,6 +1557,7 @@ vec4_visitor::dump_instruction(backend_instruction *be_inst, FILE *file)
fprintf(file, "%s", conditional_modifier[inst->conditional_mod]);
if (!inst->predicate &&
(devinfo->gen < 5 || (inst->opcode != BRW_OPCODE_SEL &&
+ inst->opcode != BRW_OPCODE_CSEL &&
inst->opcode != BRW_OPCODE_IF &&
inst->opcode != BRW_OPCODE_WHILE))) {
fprintf(file, ".f%d.%d", inst->flag_subreg / 2, inst->flag_subreg % 2);