aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/nir/nir.h14
-rw-r--r--src/compiler/nir/nir_intrinsics.py3
-rw-r--r--src/compiler/nir/nir_lower_system_values.c17
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c1
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_nir.c1
5 files changed, 36 insertions, 0 deletions
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index d3e63be091f..3bfe7d7f7bf 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 eaa40e95acc..d688a57181b 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 da04895d66c..2820dcd1b3c 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 892fb061442..9f74fa2530a 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 8f46aef14e4..db1d74fdee7 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 *