[Mesa-dev] [PATCH 04/10] i965: Don't convert if/else to conditional adds on Gen6.

Paul Berry stereotype441 at gmail.com
Mon Dec 5 09:40:47 PST 2011


Normally when outputting instructions in SPF (single program flow)
mode, we convert IF and ELSE instructions to conditional ADD
instructions applied to the IP register, since this lets us avoid
having to emit an ENDIF instruction (and, in Gen4, lets us avoid using
up precious space in the MaskStack).

However, according to the SandyBridge PRM (Volume 4 part 2, p79):

   [Errata DevSNB{WA}] - When SPF is ON, IP may not be updated by
   non-flow control instructions.

So we have to disable this optimization on Gen6.

The reason we never noticed this problem before is that so far we
haven't needed to use SPF mode on Gen6.  However, later patches in
this series will introduce a Gen6 GS program which uses SPF mode.
---
 src/mesa/drivers/dri/i965/brw_eu_emit.c |   24 ++++++++++++++++++++++--
 1 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index 9d8c701..a1cd00e 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -1047,7 +1047,19 @@ patch_IF_ELSE(struct brw_compile *p,
 {
    struct intel_context *intel = &p->brw->intel;
 
-   assert(!p->single_program_flow);
+   /* In principle, we shouldn't be patching IF and ELSE instructions in
+    * single program flow mode, because in single program flow mode, we
+    * convert flow control instructions to conditional ADDs that operate on
+    * IP (see brw_ENDIF).
+    *
+    * However, on Gen6, writing to IP doesn't work in single program flow mode
+    * (see the SandyBridge PRM, Volume 4 part 2, p79: "When SPF is ON, IP may
+    * not be updated by non-flow control instructions.").  So we do patch IF
+    * and ELSE instructions in single program flow mode on Gen6.
+    */
+   if (intel->gen != 6)
+      assert(!p->single_program_flow);
+
    assert(if_inst != NULL && if_inst->header.opcode == BRW_OPCODE_IF);
    assert(endif_inst != NULL);
    assert(else_inst == NULL || else_inst->header.opcode == BRW_OPCODE_ELSE);
@@ -1161,7 +1173,15 @@ brw_ENDIF(struct brw_compile *p)
    }
    if_inst = p->if_stack[p->if_stack_depth];
 
-   if (p->single_program_flow) {
+   /* In single program flow mode, we can save some instructions by converting
+    * IF and ELSE to ADD instructions that operate on IP.
+    *
+    * However, on Gen6, writing to IP doesn't work in single program flow mode
+    * (see the SandyBridge PRM, Volume 4 part 2, p79: "When SPF is ON, IP may
+    * not be updated by non-flow control instructions.").  So don't do this
+    * trick on Gen6.
+    */
+   if (intel->gen != 6 && p->single_program_flow) {
       /* ENDIF is useless; don't bother emitting it. */
       convert_IF_ELSE_to_ADD(p, if_inst, else_inst);
       return;
-- 
1.7.6.4



More information about the mesa-dev mailing list