nir: Add per_view attribute to nir_variable
authorCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Tue, 11 Feb 2020 22:41:05 +0000 (14:41 -0800)
committerMarge Bot <eric+marge@anholt.net>
Tue, 7 Apr 2020 17:16:09 +0000 (17:16 +0000)
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 <rafael.antognolli@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/2313>

src/compiler/nir/nir.h
src/compiler/nir/nir_gather_info.c
src/compiler/nir/nir_linking_helpers.c
src/compiler/nir/nir_lower_io_arrays_to_elements.c
src/compiler/nir/nir_lower_io_to_vector.c
src/compiler/nir/nir_print.c
src/compiler/nir/nir_validate.c

index 4d3c0d03ccfd34b29c61fd7512ad4782edb59356..c76d009bf8c6342b219b69fc12840f7d3cee436a 100644 (file)
@@ -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.
        *
index ef5d053c26673ab46b8f987c3a05969f7a1bcacf..e80a65f19fd618dc8333ce476c3f562fde21f600 100644 (file)
@@ -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
index ec1bd77928c254d3b51e84e702128cd6ac6bb97a..d187096cf452eec616da5d2bc20c6a12aba80762 100644 (file)
@@ -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);
       }
index c4c7c5cc9c7cbf432acf85f364b209a2a7040455..e49abefc0d46d7322a3b72b4e14a36c88b1e8f31 100644 (file)
@@ -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))
index 05412e2375de01fdff6d5d708463d7b5e7843a77..f85e53ac75839053470c58a33898e3869cea9a75 100644 (file)
@@ -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;
 
index 41a60aeefa52a54ec3ea352f174c922a2d6e247f..6fc8fc9b5c1d275d37bc5c676d99110b1c1c7405 100644 (file)
@@ -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;
index 3ef4bbcab055fba39507163d2de0719a88364f94..410f5906c0b1aab0d47fa23377259025ea7e80b0 100644 (file)
@@ -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)