From b7601dd27eed3348e24486f515e8af0481af5a5a Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Thu, 25 Aug 2022 09:43:06 +0200 Subject: [PATCH] zink: wrap discard in a function This makes discard less weird, and allows us to treat it as control-flow. This makes things less bizarre for drivers. Cc: mesa-stable Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/7070 Reviewed-by: Mike Blumenkrantz Reviewed-by: Jason Ekstrand Part-of: --- .../drivers/zink/nir_to_spirv/nir_to_spirv.c | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) 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 2a3bd81e314..93ec73760a9 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 @@ -107,6 +107,8 @@ struct ntv_context { subgroup_le_mask_var, subgroup_lt_mask_var, subgroup_size_var; + + SpvId discard_func; }; static SpvId @@ -2345,11 +2347,10 @@ emit_load_const(struct ntv_context *ctx, nir_load_const_instr *load_const) 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)); + assert(ctx->discard_func); + SpvId type_void = spirv_builder_type_void(&ctx->builder); + spirv_builder_function_call(&ctx->builder, type_void, + ctx->discard_func, NULL, 0); } static void @@ -4411,6 +4412,19 @@ nir_to_spirv(struct nir_shader *s, const struct zink_shader_info *sinfo, uint32_ spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModeXfb); } + + if (s->info.stage == MESA_SHADER_FRAGMENT && s->info.fs.uses_discard) { + ctx.discard_func = spirv_builder_new_id(&ctx.builder); + spirv_builder_emit_name(&ctx.builder, ctx.discard_func, "discard"); + spirv_builder_function(&ctx.builder, ctx.discard_func, type_void, + SpvFunctionControlMaskNone, + type_void_func); + SpvId label = spirv_builder_new_id(&ctx.builder); + spirv_builder_label(&ctx.builder, label); + spirv_builder_emit_kill(&ctx.builder); + spirv_builder_function_end(&ctx.builder); + } + spirv_builder_function(&ctx.builder, entry_point, type_void, SpvFunctionControlMaskNone, type_void_func);