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 <michael.blumenkrantz@gmail.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18244>
(cherry picked from commit b7601dd27e)
This commit is contained in:
Erik Faye-Lund
2022-08-25 09:43:06 +02:00
committed by Dylan Baker
parent ccac10eb5a
commit 88a188cc39
2 changed files with 20 additions and 6 deletions

View File

@@ -10228,7 +10228,7 @@
"description": "zink: wrap discard in a function",
"nominated": true,
"nomination_type": 0,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": null
},

View File

@@ -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);