summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2014-05-30 16:41:32 -0700
committerKenneth Graunke <[email protected]>2014-06-02 15:09:30 -0700
commit776ad51165b1f7ee18a9a4cccbed1ce3b2c4fcf9 (patch)
tree2cad3bd54226334a771c8f8a18453f27a0ab480e
parentff340ce3c3326959027d7cb9a611c6fab1d89941 (diff)
i965: Don't use brw_set_conditionalmod in the FS and vec4 compilers.
brw_set_conditionalmod and brw_next_insn work together to set the conditional modifier for the next instruction, then turn it off. The Gen8+ generators don't implement this: we just set it for all future instructions, and whack it for each fs_inst/vec4_instruction. Both approaches work out because we only set conditional_mod on IR instructions like CMP, AND, and so on, which correspond to exactly one assembly instruction. The Gen8 generators would break if we had an IR instruction that generated multiple instructions, and the Gen4-7 EU emit layer would do...something. To safeguard against this, assert that we only generated one instruction if conditional_mod is set, and just set the flag directly on that instruction rather than altering default state. Signed-off-by: Kenneth Graunke <[email protected]> Reviewed-by: Matt Turner <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_generator.cpp12
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_generator.cpp9
2 files changed, 16 insertions, 5 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
index a5be0ec47bf..dd97a2d55e1 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
@@ -1348,6 +1348,7 @@ fs_generator::generate_code(exec_list *instructions,
foreach_list(node, instructions) {
fs_inst *inst = (fs_inst *)node;
struct brw_reg src[3], dst;
+ unsigned int last_insn_offset = p->next_insn_offset;
if (unlikely(debug_flag))
annotate(brw, annotation, cfg, inst, p->next_insn_offset);
@@ -1367,7 +1368,6 @@ fs_generator::generate_code(exec_list *instructions,
}
dst = brw_reg_from_fs_reg(&inst->dst);
- brw_set_conditionalmod(p, inst->conditional_mod);
brw_set_predicate_control(p, inst->predicate);
brw_set_predicate_inverse(p, inst->predicate_inverse);
brw_set_flag_reg(p, 0, inst->flag_subreg);
@@ -1766,6 +1766,16 @@ fs_generator::generate_code(exec_list *instructions,
}
abort();
}
+
+ if (inst->conditional_mod) {
+ /* Set the conditional modifier on the last instruction we generated.
+ * Also, make sure we only emitted one instruction - anything else
+ * doesn't make sense.
+ */
+ assert(p->next_insn_offset == last_insn_offset + 16);
+ struct brw_instruction *last = &p->store[last_insn_offset / 16];
+ last->header.destreg__conditionalmod = inst->conditional_mod;
+ }
}
brw_set_uip_jip(p);
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
index 29ca7602e0b..3844407c203 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
@@ -1290,7 +1290,6 @@ vec4_generator::generate_code(exec_list *instructions,
}
dst = inst->get_dst();
- brw_set_conditionalmod(p, inst->conditional_mod);
brw_set_predicate_control(p, inst->predicate);
brw_set_predicate_inverse(p, inst->predicate_inverse);
brw_set_saturate(p, inst->saturate);
@@ -1301,13 +1300,15 @@ vec4_generator::generate_code(exec_list *instructions,
generate_vec4_instruction(inst, dst, src);
- if (inst->no_dd_clear || inst->no_dd_check) {
+ if (inst->no_dd_clear || inst->no_dd_check || inst->conditional_mod) {
assert(p->nr_insn == pre_emit_nr_insn + 1 ||
- !"no_dd_check or no_dd_clear set for IR emitting more "
- "than 1 instruction");
+ !"conditional_mod, no_dd_check, or no_dd_clear set for IR "
+ "emitting more than 1 instruction");
struct brw_instruction *last = &p->store[pre_emit_nr_insn];
+ if (inst->conditional_mod)
+ last->header.destreg__conditionalmod = inst->conditional_mod;
if (inst->no_dd_clear)
last->header.dependency_control |= BRW_DEPENDENCY_NOTCLEARED;
if (inst->no_dd_check)