From 5dc85abc4fe0a27beb00ef31bb21b79dbdcfec8d Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Tue, 11 Feb 2020 14:41:05 -0800 Subject: [PATCH] nir: Add per_view attribute to nir_variable If a nir_variable is tagged with per_view, it must be an array with size corresponding to the number of views. For slot-tracking, it is considered to take just the slot for a single element -- drivers will take care of expanding this appropriately. This will be used to implement the ability of having per-view position in a vertex shader in Intel platforms. Acked-by: Rafael Antognolli Part-of: --- src/compiler/nir/nir.h | 6 ++++++ src/compiler/nir/nir_gather_info.c | 15 +++++++++++++++ src/compiler/nir/nir_linking_helpers.c | 13 +++++++------ .../nir/nir_lower_io_arrays_to_elements.c | 4 ++++ src/compiler/nir/nir_lower_io_to_vector.c | 3 +++ src/compiler/nir/nir_print.c | 6 ++++-- src/compiler/nir/nir_validate.c | 3 +++ 7 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 4d3c0d03ccf..c76d009bf8c 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -453,6 +453,12 @@ typedef struct nir_variable { */ unsigned how_declared:2; + /** + * Is this variable per-view? If so, we know it must be an array with + * size corresponding to the number of views. + */ + unsigned per_view:1; + /** * \brief Layout qualifier for gl_FragDepth. * diff --git a/src/compiler/nir/nir_gather_info.c b/src/compiler/nir/nir_gather_info.c index ef5d053c266..e80a65f19fd 100644 --- a/src/compiler/nir/nir_gather_info.c +++ b/src/compiler/nir/nir_gather_info.c @@ -161,6 +161,17 @@ mark_whole_variable(nir_shader *shader, nir_variable *var, type = glsl_get_array_element(type); } + if (var->data.per_view) { + /* TODO: Per view and Per Vertex are not currently used together. When + * they start to be used (e.g. when adding Primitive Replication for GS + * on Intel), verify that "peeling" the type twice is correct. This + * assert ensures we remember it. + */ + assert(!nir_is_per_vertex_io(var, shader->info.stage)); + assert(glsl_type_is_array(type)); + type = glsl_get_array_element(type); + } + const unsigned slots = var->data.compact ? DIV_ROUND_UP(glsl_get_length(type), 4) : glsl_count_attribute_slots(type, false); @@ -209,6 +220,10 @@ try_mask_partial_io(nir_shader *shader, nir_variable *var, type = glsl_get_array_element(type); } + /* Per view variables will be considered as a whole. */ + if (var->data.per_view) + return false; + /* The code below only handles: * * - Indexing into matrices diff --git a/src/compiler/nir/nir_linking_helpers.c b/src/compiler/nir/nir_linking_helpers.c index ec1bd77928c..d187096cf45 100644 --- a/src/compiler/nir/nir_linking_helpers.c +++ b/src/compiler/nir/nir_linking_helpers.c @@ -50,7 +50,7 @@ get_variable_io_mask(nir_variable *var, gl_shader_stage stage) assert(var->data.location >= 0); const struct glsl_type *type = var->type; - if (nir_is_per_vertex_io(var, stage)) { + if (nir_is_per_vertex_io(var, stage) || var->data.per_view) { assert(glsl_type_is_array(type)); type = glsl_get_array_element(type); } @@ -279,7 +279,7 @@ get_unmoveable_components_masks(struct exec_list *var_list, var->data.location - VARYING_SLOT_VAR0 < MAX_VARYINGS_INCL_PATCH) { const struct glsl_type *type = var->type; - if (nir_is_per_vertex_io(var, stage)) { + if (nir_is_per_vertex_io(var, stage) || var->data.per_view) { assert(glsl_type_is_array(type)); type = glsl_get_array_element(type); } @@ -376,7 +376,7 @@ remap_slots_and_components(struct exec_list *var_list, gl_shader_stage stage, var->data.location - VARYING_SLOT_VAR0 < MAX_VARYINGS_INCL_PATCH) { const struct glsl_type *type = var->type; - if (nir_is_per_vertex_io(var, stage)) { + if (nir_is_per_vertex_io(var, stage) || var->data.per_view) { assert(glsl_type_is_array(type)); type = glsl_get_array_element(type); } @@ -500,7 +500,7 @@ gather_varying_component_info(nir_shader *producer, nir_shader *consumer, continue; const struct glsl_type *type = var->type; - if (nir_is_per_vertex_io(var, producer->info.stage)) { + if (nir_is_per_vertex_io(var, producer->info.stage) || var->data.per_view) { assert(glsl_type_is_array(type)); type = glsl_get_array_element(type); } @@ -557,7 +557,8 @@ gather_varying_component_info(nir_shader *producer, nir_shader *consumer, if (!vc_info->initialised) { const struct glsl_type *type = in_var->type; - if (nir_is_per_vertex_io(in_var, consumer->info.stage)) { + if (nir_is_per_vertex_io(in_var, consumer->info.stage) || + in_var->data.per_view) { assert(glsl_type_is_array(type)); type = glsl_get_array_element(type); } @@ -1096,7 +1097,7 @@ nir_assign_io_var_locations(struct exec_list *var_list, unsigned *size, bool last_partial = false; nir_foreach_variable(var, var_list) { const struct glsl_type *type = var->type; - if (nir_is_per_vertex_io(var, stage)) { + if (nir_is_per_vertex_io(var, stage) || var->data.per_view) { assert(glsl_type_is_array(type)); type = glsl_get_array_element(type); } diff --git a/src/compiler/nir/nir_lower_io_arrays_to_elements.c b/src/compiler/nir/nir_lower_io_arrays_to_elements.c index c4c7c5cc9c7..e49abefc0d4 100644 --- a/src/compiler/nir/nir_lower_io_arrays_to_elements.c +++ b/src/compiler/nir/nir_lower_io_arrays_to_elements.c @@ -293,6 +293,10 @@ lower_io_arrays_to_elements(nir_shader *shader, nir_variable_mode mask, if (var->data.compact) continue; + /* Per-view variables are expected to remain arrays. */ + if (var->data.per_view) + continue; + /* Skip indirects */ int loc = var->data.location * 4 + var->data.location_frac; if (BITSET_TEST(indirects, loc)) diff --git a/src/compiler/nir/nir_lower_io_to_vector.c b/src/compiler/nir/nir_lower_io_to_vector.c index 05412e2375d..f85e53ac758 100644 --- a/src/compiler/nir/nir_lower_io_to_vector.c +++ b/src/compiler/nir/nir_lower_io_to_vector.c @@ -84,6 +84,9 @@ variables_can_merge(const nir_shader *shader, if (a->data.compact || b->data.compact) return false; + if (a->data.per_view || b->data.per_view) + return false; + const struct glsl_type *a_type_tail = a->type; const struct glsl_type *b_type_tail = b->type; diff --git a/src/compiler/nir/nir_print.c b/src/compiler/nir/nir_print.c index 41a60aeefa5..6fc8fc9b5c1 100644 --- a/src/compiler/nir/nir_print.c +++ b/src/compiler/nir/nir_print.c @@ -461,8 +461,10 @@ print_var_decl(nir_variable *var, print_state *state) const char *const samp = (var->data.sample) ? "sample " : ""; const char *const patch = (var->data.patch) ? "patch " : ""; const char *const inv = (var->data.invariant) ? "invariant " : ""; - fprintf(fp, "%s%s%s%s%s %s ", - cent, samp, patch, inv, get_variable_mode_str(var->data.mode, false), + 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, + get_variable_mode_str(var->data.mode, false), glsl_interp_mode_name(var->data.interpolation)); enum gl_access_qualifier access = var->data.access; diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c index 3ef4bbcab05..410f5906c0b 100644 --- a/src/compiler/nir/nir_validate.c +++ b/src/compiler/nir/nir_validate.c @@ -1134,6 +1134,9 @@ validate_var_decl(nir_variable *var, nir_variable_mode valid_modes, validate_assert(state, var->members != NULL); } + if (var->data.per_view) + validate_assert(state, glsl_type_is_array(var->type)); + /* * TODO validate some things ir_validate.cpp does (requires more GLSL type * support) -- 2.30.2