From acdd12dae3479b88d49e4a449e2c82c6fe45ef57 Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Thu, 1 Nov 2018 22:12:11 +0100 Subject: [PATCH] zink/spirv: implement discard Acked-by: Jordan Justen --- .../drivers/zink/nir_to_spirv/nir_to_spirv.c | 14 ++++++++++++++ .../drivers/zink/nir_to_spirv/spirv_builder.c | 7 +++++++ .../drivers/zink/nir_to_spirv/spirv_builder.h | 2 ++ 3 files changed, 23 insertions(+) diff --git a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c index 9fc7aa94cd2..c4c8da2efa1 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c +++ b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c @@ -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); diff --git a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c index 1a02ab0fe09..8fce21bbc35 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c +++ b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c @@ -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, diff --git a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h index 2fecaf445f2..3cf3d5d3565 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h +++ b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h @@ -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, -- 2.30.2