summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>2021-04-29 11:51:57 -0700
committerMarge Bot <eric+marge@anholt.net>2021-08-28 03:56:42 +0000
commitf95daad3a2c5b04aff0141ee8a7de0036f4ffa6f (patch)
tree1c57410194d3b7fa94e352ca1508616993e686ec
parent927584fa67be1b644321961f32472a6f52b619f3 (diff)
nir: Add a way to identify per-primitive variables
Per-primitive is similar to per-vertex attributes, but applies to all fragments of the primitive without any interpolation involved. Because they are regular input and outputs, keep track in shader_info of which I/O is per-primitive so we can distinguish them after deref lowering. These fields can be used combined with the regular `inputs_read`, `outputs_written` and `outputs_read`. Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Timur Kristóf <timur.kristof@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10600>
-rw-r--r--src/compiler/nir/nir.h6
-rw-r--r--src/compiler/nir/nir_gather_info.c23
-rw-r--r--src/compiler/nir/nir_lower_io.c3
-rw-r--r--src/compiler/nir/nir_print.c5
-rw-r--r--src/compiler/shader_info.h6
5 files changed, 40 insertions, 3 deletions
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index b71b74c1edb..07688b57f9d 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -495,6 +495,12 @@ typedef struct nir_variable {
unsigned per_view:1;
/**
+ * Whether the variable is per-primitive.
+ * Can be use by Mesh Shader outputs and corresponding Fragment Shader inputs.
+ */
+ unsigned per_primitive:1;
+
+ /**
* \brief Layout qualifier for gl_FragDepth. See nir_depth_layout.
*
* This is not equal to \c ir_depth_layout_none if and only if this
diff --git a/src/compiler/nir/nir_gather_info.c b/src/compiler/nir/nir_gather_info.c
index e4f858f46d0..9472f898c06 100644
--- a/src/compiler/nir/nir_gather_info.c
+++ b/src/compiler/nir/nir_gather_info.c
@@ -910,4 +910,27 @@ nir_shader_gather_info(nir_shader *shader, nir_function_impl *entrypoint)
*/
shader->info.fs.uses_sample_shading = true;
}
+
+ shader->info.per_primitive_outputs = 0;
+ if (shader->info.stage == MESA_SHADER_MESH) {
+ nir_foreach_shader_out_variable(var, shader) {
+ if (var->data.per_primitive) {
+ assert(nir_is_arrayed_io(var, shader->info.stage));
+ const unsigned slots =
+ glsl_count_attribute_slots(glsl_get_array_element(var->type), false);
+ shader->info.per_primitive_outputs |= BITFIELD64_RANGE(var->data.location, slots);
+ }
+ }
+ }
+
+ shader->info.per_primitive_inputs = 0;
+ if (shader->info.stage == MESA_SHADER_FRAGMENT) {
+ nir_foreach_shader_in_variable(var, shader) {
+ if (var->data.per_primitive) {
+ const unsigned slots =
+ glsl_count_attribute_slots(var->type, false);
+ shader->info.per_primitive_inputs |= BITFIELD64_RANGE(var->data.location, slots);
+ }
+ }
+ }
}
diff --git a/src/compiler/nir/nir_lower_io.c b/src/compiler/nir/nir_lower_io.c
index f5651d45ed4..71bd31c618b 100644
--- a/src/compiler/nir/nir_lower_io.c
+++ b/src/compiler/nir/nir_lower_io.c
@@ -255,7 +255,8 @@ emit_load(struct lower_io_state *state,
case nir_var_shader_in:
if (nir->info.stage == MESA_SHADER_FRAGMENT &&
nir->options->use_interpolated_input_intrinsics &&
- var->data.interpolation != INTERP_MODE_FLAT) {
+ var->data.interpolation != INTERP_MODE_FLAT &&
+ !var->data.per_primitive) {
if (var->data.interpolation == INTERP_MODE_EXPLICIT) {
assert(array_index != NULL);
op = nir_intrinsic_load_input_vertex;
diff --git a/src/compiler/nir/nir_print.c b/src/compiler/nir/nir_print.c
index b42a21b09bb..f8736b74f4b 100644
--- a/src/compiler/nir/nir_print.c
+++ b/src/compiler/nir/nir_print.c
@@ -489,8 +489,9 @@ print_var_decl(nir_variable *var, print_state *state)
const char *const patch = (var->data.patch) ? "patch " : "";
const char *const inv = (var->data.invariant) ? "invariant " : "";
const char *const per_view = (var->data.per_view) ? "per_view " : "";
- fprintf(fp, "%s%s%s%s%s%s %s ",
- cent, samp, patch, inv, per_view,
+ const char *const per_primitive = (var->data.per_primitive) ? "per_primitive " : "";
+ fprintf(fp, "%s%s%s%s%s%s%s %s ",
+ cent, samp, patch, inv, per_view, per_primitive,
get_variable_mode_str(var->data.mode, false),
glsl_interp_mode_name(var->data.interpolation));
diff --git a/src/compiler/shader_info.h b/src/compiler/shader_info.h
index 6794f3d15a0..b1a5d05b2cd 100644
--- a/src/compiler/shader_info.h
+++ b/src/compiler/shader_info.h
@@ -154,6 +154,12 @@ typedef struct shader_info {
/* Which system values are actually read */
BITSET_DECLARE(system_values_read, SYSTEM_VALUE_MAX);
+ /* Which I/O is per-primitive, for read/written information combine with
+ * the fields above.
+ */
+ uint64_t per_primitive_inputs;
+ uint64_t per_primitive_outputs;
+
/* Which 16-bit inputs and outputs are used corresponding to
* VARYING_SLOT_VARn_16BIT.
*/