From efaaaf45d1ddf0fe34687f2bdf90e2b249743bf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Fri, 21 Feb 2025 10:08:30 +0100 Subject: [PATCH] zink: clean up HelperInvocation code emission With SPIR-V 1.6 OpIsHelperInvocationEXT was effectively replaced with Volatile loads of the HelperInvocation built-in variable. This patch also drops the distinction between is_helper_invocation and load_helper_invocation. Part-of: --- .../drivers/zink/nir_to_spirv/nir_to_spirv.c | 29 +++++++++++++------ .../drivers/zink/nir_to_spirv/spirv_builder.c | 6 ++++ .../drivers/zink/nir_to_spirv/spirv_builder.h | 4 +++ 3 files changed, 30 insertions(+), 9 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 1dce1123006..f92601861f4 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 @@ -39,6 +39,7 @@ struct ntv_context { * variables in the interface. */ bool spirv_1_4_interfaces; + bool have_spirv16; bool explicit_lod; //whether to set lod=0 for texture() @@ -3164,10 +3165,22 @@ emit_vote(struct ntv_context *ctx, nir_intrinsic_instr *intr) static void emit_is_helper_invocation(struct ntv_context *ctx, nir_intrinsic_instr *intr) { - spirv_builder_emit_extension(&ctx->builder, - "SPV_EXT_demote_to_helper_invocation"); - spirv_builder_emit_cap(&ctx->builder, SpvCapabilityDemoteToHelperInvocation); - SpvId result = spirv_is_helper_invocation(&ctx->builder); + SpvId result; + if (!ctx->have_spirv16 && ctx->nir->options->discard_is_demote) { + spirv_builder_emit_extension(&ctx->builder, + "SPV_EXT_demote_to_helper_invocation"); + spirv_builder_emit_cap(&ctx->builder, SpvCapabilityDemoteToHelperInvocation); + result = spirv_is_helper_invocation(&ctx->builder); + } else { + SpvId var_type = spirv_builder_type_bool(&ctx->builder); + if (!ctx->helper_invocation_var) + ctx->helper_invocation_var = create_builtin_var(ctx, var_type, + SpvStorageClassInput, + "gl_HelperInvocation", + SpvBuiltInHelperInvocation); + result = spirv_builder_emit_load_volatile(&ctx->builder, var_type, + ctx->helper_invocation_var); + } store_def(ctx, intr->def.index, result, nir_type_bool); } @@ -3525,8 +3538,9 @@ emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr) ctx->nir->info.stage == MESA_SHADER_GEOMETRY && util_bitcount(ctx->nir->info.gs.active_stream_mask) > 1); break; + case nir_intrinsic_is_helper_invocation: case nir_intrinsic_load_helper_invocation: - emit_load_vec_input(ctx, intr, &ctx->helper_invocation_var, "gl_HelperInvocation", SpvBuiltInHelperInvocation, nir_type_bool); + emit_is_helper_invocation(ctx, intr); break; case nir_intrinsic_load_patch_vertices_in: @@ -3677,10 +3691,6 @@ emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr) emit_is_sparse_texels_resident(ctx, intr); break; - case nir_intrinsic_is_helper_invocation: - emit_is_helper_invocation(ctx, intr); - break; - case nir_intrinsic_ddx: case nir_intrinsic_ddy: case nir_intrinsic_ddx_fine: @@ -4602,6 +4612,7 @@ nir_to_spirv(struct nir_shader *s, const struct zink_shader_info *sinfo, const s ctx.builder.mem_ctx = ctx.mem_ctx; assert(spirv_version >= SPIRV_VERSION(1, 0)); ctx.spirv_1_4_interfaces = spirv_version >= SPIRV_VERSION(1, 4); + ctx.have_spirv16 = spirv_version >= SPIRV_VERSION(1, 6); ctx.bindless_set_idx = sinfo->bindless_set_idx; ctx.glsl_types = _mesa_pointer_hash_table_create(ctx.mem_ctx); 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 4a15137267a..e2a49ee18b9 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c +++ b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c @@ -485,6 +485,12 @@ spirv_builder_emit_load_aligned(struct spirv_builder *b, SpvId result_type, SpvI } } +SpvId +spirv_builder_emit_load_volatile(struct spirv_builder *b, SpvId result_type, SpvId pointer) +{ + return spirv_builder_emit_binop(b, SpvOpLoad, result_type, pointer, SpvMemoryAccessVolatileMask); +} + void spirv_builder_emit_store(struct spirv_builder *b, SpvId pointer, SpvId object) { 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 d3578fa757e..f60a3a26db4 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h +++ b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h @@ -207,6 +207,10 @@ spirv_builder_emit_load(struct spirv_builder *b, SpvId result_type, SpvId spirv_builder_emit_load_aligned(struct spirv_builder *b, SpvId result_type, SpvId pointer, unsigned alignment, bool coherent); + +SpvId +spirv_builder_emit_load_volatile(struct spirv_builder *b, SpvId result_type, SpvId pointer); + void spirv_builder_emit_atomic_store(struct spirv_builder *b, SpvId pointer, SpvScope scope, SpvMemorySemanticsMask semantics, SpvId object);