[Mesa-dev] [PATCH 7/9] i965: Don't use brw_set_conditionalmod in the FS and vec4 compilers.

Kenneth Graunke kenneth at whitecape.org
Fri May 30 20:09:16 PDT 2014


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 <kenneth at whitecape.org>
---
 src/mesa/drivers/dri/i965/brw_fs_generator.cpp   | 12 +++++++++++-
 src/mesa/drivers/dri/i965/brw_vec4_generator.cpp |  9 +++++----
 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 6ba8bb9..cc6ae00 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 29ca760..3844407 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)
-- 
1.9.3



More information about the mesa-dev mailing list