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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev