zink/spirv: implement discard
authorErik Faye-Lund <erik.faye-lund@collabora.com>
Thu, 1 Nov 2018 21:12:11 +0000 (22:12 +0100)
committerErik Faye-Lund <erik.faye-lund@collabora.com>
Mon, 28 Oct 2019 08:51:43 +0000 (08:51 +0000)
Acked-by: Jordan Justen <jordan.l.justen@intel.com>
src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c
src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c
src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h

index 9fc7aa94cd2e485ed373276843d79b569ae05efc..c4c8da2efa1b62fe205ccd7ee1d489622265f026 100644 (file)
@@ -1021,6 +1021,16 @@ emit_store_output(struct ntv_context *ctx, nir_intrinsic_instr *intr)
       unreachable("output-addressing not yet supported");
 }
 
+static void
+emit_discard(struct ntv_context *ctx, nir_intrinsic_instr *intr)
+{
+   assert(ctx->block_started);
+   spirv_builder_emit_kill(&ctx->builder);
+   /* discard is weird in NIR, so let's just create an unreachable block after
+      it and hope that the vulkan driver will DCE any instructinos in it. */
+   spirv_builder_label(&ctx->builder, spirv_builder_new_id(&ctx->builder));
+}
+
 static void
 emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
 {
@@ -1037,6 +1047,10 @@ emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
       emit_store_output(ctx, intr);
       break;
 
+   case nir_intrinsic_discard:
+      emit_discard(ctx, intr);
+      break;
+
    default:
       fprintf(stderr, "emit_intrinsic: not implemented (%s)\n",
               nir_intrinsic_infos[intr->intrinsic].name);
index 1a02ab0fe097bb94905f656da6b4e6584700d1ac..8fce21bbc356bc7c2d8cf1abd59713e832acc336 100644 (file)
@@ -487,6 +487,13 @@ spirv_builder_set_phi_operand(struct spirv_builder *b, size_t position,
    b->instructions.words[position + index * 2 + 1] = parent;
 }
 
+void
+spirv_builder_emit_kill(struct spirv_builder *b)
+{
+   spirv_buffer_prepare(&b->instructions, 1);
+   spirv_buffer_emit_word(&b->instructions, SpvOpKill | (1 << 16));
+}
+
 SpvId
 spirv_builder_emit_image_sample_implicit_lod(struct spirv_builder *b,
                                              SpvId result_type,
index 2fecaf445f27d44a867078091d1a25a3caea29bc..3cf3d5d3565d824bbe2387e9141b9822b98b4ed5 100644 (file)
@@ -194,6 +194,8 @@ void
 spirv_builder_set_phi_operand(struct spirv_builder *b, size_t position,
                               size_t index, SpvId variable, SpvId parent);
 
+void
+spirv_builder_emit_kill(struct spirv_builder *b);
 
 SpvId
 spirv_builder_emit_image_sample_implicit_lod(struct spirv_builder *b,