From 8dfc9e22c12ff840510d876b09d7f7163256bb17 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 1 Jun 2018 14:07:15 -0400 Subject: [PATCH] nir: add lowering for gl_HelperInvocation v2: reword comment about lower_helper_invocations to be more clear that it might not work on all hardware v3: add special variant of load_sample_id which does not imply per- sample shading Signed-off-by: Rob Clark --- src/compiler/nir/nir.h | 14 ++++++++++++++ src/compiler/nir/nir_intrinsics.py | 3 +++ src/compiler/nir/nir_lower_system_values.c | 17 +++++++++++++++++ src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c | 1 + src/gallium/drivers/freedreno/ir3/ir3_nir.c | 1 + 5 files changed, 36 insertions(+) diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index d3e63be..3bfe7d7 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -2006,6 +2006,20 @@ typedef struct nir_shader_compiler_options { */ bool lower_base_vertex; + /** + * If enabled, gl_HelperInvocation will be lowered as: + * + * !((1 << sample_id) & sample_mask_in)) + * + * This depends on some possibly hw implementation details, which may + * not be true for all hw. In particular that the FS is only executed + * for covered samples or for helper invocations. So, do not blindly + * enable this option. + * + * Note: See also issue #22 in ARB_shader_image_load_store + */ + bool lower_helper_invocation; + bool lower_cs_local_index_from_id; bool lower_device_index_to_zero; diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py index eaa40e9..d688a57 100644 --- a/src/compiler/nir/nir_intrinsics.py +++ b/src/compiler/nir/nir_intrinsics.py @@ -424,6 +424,9 @@ system_value("instance_id", 1) system_value("base_instance", 1) system_value("draw_id", 1) system_value("sample_id", 1) +# sample_id_no_per_sample is like sample_id but does not imply per- +# sample shading. See the lower_helper_invocation option. +system_value("sample_id_no_per_sample", 1) system_value("sample_pos", 2) system_value("sample_mask_in", 1) system_value("primitive_id", 1) diff --git a/src/compiler/nir/nir_lower_system_values.c b/src/compiler/nir/nir_lower_system_values.c index da04895..2820dcd 100644 --- a/src/compiler/nir/nir_lower_system_values.c +++ b/src/compiler/nir/nir_lower_system_values.c @@ -144,6 +144,23 @@ convert_block(nir_block *block, nir_builder *b) nir_load_first_vertex(b)); break; + case SYSTEM_VALUE_HELPER_INVOCATION: + if (b->shader->options->lower_helper_invocation) { + nir_ssa_def *tmp; + + tmp = nir_ishl(b, + nir_imm_int(b, 1), + nir_load_sample_id_no_per_sample(b)); + + tmp = nir_iand(b, + nir_load_sample_mask_in(b), + tmp); + + sysval = nir_inot(b, nir_i2b(b, tmp)); + } + + break; + case SYSTEM_VALUE_INSTANCE_INDEX: sysval = nir_iadd(b, nir_load_instance_id(b), diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c index 892fb06..9f74fa2 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c @@ -2445,6 +2445,7 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr) dst[0] = ctx->instance_id; break; case nir_intrinsic_load_sample_id: + case nir_intrinsic_load_sample_id_no_per_sample: if (!ctx->samp_id) { ctx->samp_id = create_input(b, 0); ctx->samp_id->regs[0]->flags |= IR3_REG_HALF; diff --git a/src/gallium/drivers/freedreno/ir3/ir3_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_nir.c index 8f46aef..db1d74f 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_nir.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_nir.c @@ -52,6 +52,7 @@ static const nir_shader_compiler_options options = { .lower_extract_byte = true, .lower_extract_word = true, .lower_all_io_to_temps = true, + .lower_helper_invocation = true, }; struct nir_shader * -- 2.7.4