Mesa (master): nir/spirv/cfg: Use a nop intrinsic for tagging the ends of blocks

Jason Ekstrand jekstrand at kemper.freedesktop.org
Mon Oct 3 23:37:31 UTC 2016


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

Author: Jason Ekstrand <jason.ekstrand at intel.com>
Date:   Thu Sep 15 21:12:34 2016 -0700

nir/spirv/cfg: Use a nop intrinsic for tagging the ends of blocks

Previously, we were saving off the last nir_block in a vtn_block before
moving on so that we could find the nir_block again when it came time to
handle phi sources.  Unfortunately, NIR's control flow modification code is
inconsistent when it comes to how it splits blocks so the block pointer we
saved off may point to a block somewhere else in the shader by the time we
get around to handling phi sources.  In order to get around this, we insert
a nop instruction and use that as the logical end of our block.  Since the
control flow manipulation code respects instructions, the nop will keeps
its place like any other instruction and we can easily find the end of our
block when we need it.

This fixes a bug triggered by a couple of vkQuake shaders.

Signed-off-by: Jason Ekstrand <jason at jlekstrand.net>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97233
Cc: "12.0" <mesa-stable at lists.freedesktop.org>
Tested-by: Dave Airlie <airlied at redhat.com>
Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>

---

 src/compiler/spirv/vtn_cfg.c     | 6 ++++--
 src/compiler/spirv/vtn_private.h | 4 ++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/src/compiler/spirv/vtn_cfg.c b/src/compiler/spirv/vtn_cfg.c
index 1c8c4f8..62b9056 100644
--- a/src/compiler/spirv/vtn_cfg.c
+++ b/src/compiler/spirv/vtn_cfg.c
@@ -531,7 +531,7 @@ vtn_handle_phi_second_pass(struct vtn_builder *b, SpvOp opcode,
       struct vtn_block *pred =
          vtn_value(b, w[i + 1], vtn_value_type_block)->block;
 
-      b->nb.cursor = nir_after_block_before_jump(pred->end_block);
+      b->nb.cursor = nir_after_instr(&pred->end_nop->instr);
 
       vtn_local_store(b, src, nir_deref_var_create(b, phi_var));
    }
@@ -589,7 +589,9 @@ vtn_emit_cf_list(struct vtn_builder *b, struct list_head *cf_list,
 
          vtn_foreach_instruction(b, block_start, block_end, handler);
 
-         block->end_block = nir_cursor_current_block(b->nb.cursor);
+         block->end_nop = nir_intrinsic_instr_create(b->nb.shader,
+                                                     nir_intrinsic_nop);
+         nir_builder_instr_insert(&b->nb, &block->end_nop->instr);
 
          if ((*block->branch & SpvOpCodeMask) == SpvOpReturnValue) {
             struct vtn_ssa_value *src = vtn_ssa_value(b, block->branch[1]);
diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h
index 7f5444e..6f34f09 100644
--- a/src/compiler/spirv/vtn_private.h
+++ b/src/compiler/spirv/vtn_private.h
@@ -149,8 +149,8 @@ struct vtn_block {
    /** Points to the switch case started by this block (if any) */
    struct vtn_case *switch_case;
 
-   /** The last block in this SPIR-V block. */
-   nir_block *end_block;
+   /** Every block ends in a nop intrinsic so that we can find it again */
+   nir_intrinsic_instr *end_nop;
 };
 
 struct vtn_function {




More information about the mesa-commit mailing list