Mesa (master): i965: Only convert if/else to conditional adds prior to Gen6 .

Paul Berry stereotype441 at kemper.freedesktop.org
Thu Dec 8 00:42:08 UTC 2011


Module: Mesa
Branch: master
Commit: dabe15da4f81546b5c9fca8c208d31bfe98ada9f
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=dabe15da4f81546b5c9fca8c208d31bfe98ada9f

Author: Paul Berry <stereotype441 at gmail.com>
Date:   Thu Nov 24 21:41:07 2011 -0800

i965: Only convert if/else to conditional adds prior to Gen6.

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.  On platforms prior to Gen6,
flow control instructions cause an implied thread switch, so this is a
significant savings.

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.

On later platforms, there is no significant benefit to converting flow
control instructions to ADDs, so for the sake of consistency, this
patch disables the optimization on later platforms too.

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.

Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>

---

 src/mesa/drivers/dri/i965/brw_eu_emit.c |   30 ++++++++++++++++++++++++++++--
 1 files changed, 28 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..a46a81b 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -1047,7 +1047,21 @@ patch_IF_ELSE(struct brw_compile *p,
 {
    struct intel_context *intel = &p->brw->intel;
 
-   assert(!p->single_program_flow);
+   /* We shouldn't be patching IF and ELSE instructions in single program flow
+    * mode when gen < 6, because in single program flow mode on those
+    * platforms, 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.").  And on later
+    * platforms, there is no significant benefit to converting control flow
+    * instructions to conditional ADDs.  So we do patch IF and ELSE
+    * instructions in single program flow mode on those platforms.
+    */
+   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 +1175,19 @@ 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 express IF and ELSE instructions
+    * equivalently as ADD instructions that operate on IP.  On platforms prior
+    * to Gen6, flow control instructions cause an implied thread switch, so
+    * this is a significant savings.
+    *
+    * 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.").  And on later
+    * platforms, there is no significant benefit to converting control flow
+    * instructions to conditional ADDs.  So we only do this trick on Gen4 and
+    * Gen5.
+    */
+   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;




More information about the mesa-commit mailing list