anv/pipeline: Convert apply_pipeline_layout to deref instructions
authorJason Ekstrand <jason.ekstrand@intel.com>
Fri, 23 Mar 2018 06:25:07 +0000 (23:25 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Sat, 23 Jun 2018 03:54:00 +0000 (20:54 -0700)
Acked-by: Rob Clark <robdclark@gmail.com>
Acked-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Acked-by: Dave Airlie <airlied@redhat.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/intel/vulkan/anv_nir_apply_pipeline_layout.c
src/intel/vulkan/anv_pipeline.c

index 4ef77a0e1510a8a8533baadd005c4bd349919974..37a54b2efff49cd729611e51bf0a61b183b8fe73 100644 (file)
@@ -53,6 +53,24 @@ add_var_binding(struct apply_pipeline_layout_state *state, nir_variable *var)
    add_binding(state, var->data.descriptor_set, var->data.binding);
 }
 
+static void
+add_deref_src_binding(struct apply_pipeline_layout_state *state, nir_src src)
+{
+   nir_deref_instr *deref = nir_src_as_deref(src);
+   add_var_binding(state, nir_deref_instr_get_variable(deref));
+}
+
+static void
+add_tex_src_binding(struct apply_pipeline_layout_state *state,
+                    nir_tex_instr *tex, nir_tex_src_type deref_src_type)
+{
+   int deref_src_idx = nir_tex_instr_src_index(tex, deref_src_type);
+   if (deref_src_idx < 0)
+      return;
+
+   add_deref_src_binding(state, tex->src[deref_src_idx].src);
+}
+
 static void
 get_used_bindings_block(nir_block *block,
                         struct apply_pipeline_layout_state *state)
@@ -67,19 +85,19 @@ get_used_bindings_block(nir_block *block,
                         nir_intrinsic_binding(intrin));
             break;
 
-         case nir_intrinsic_image_var_load:
-         case nir_intrinsic_image_var_store:
-         case nir_intrinsic_image_var_atomic_add:
-         case nir_intrinsic_image_var_atomic_min:
-         case nir_intrinsic_image_var_atomic_max:
-         case nir_intrinsic_image_var_atomic_and:
-         case nir_intrinsic_image_var_atomic_or:
-         case nir_intrinsic_image_var_atomic_xor:
-         case nir_intrinsic_image_var_atomic_exchange:
-         case nir_intrinsic_image_var_atomic_comp_swap:
-         case nir_intrinsic_image_var_size:
-         case nir_intrinsic_image_var_samples:
-            add_var_binding(state, intrin->variables[0]->var);
+         case nir_intrinsic_image_deref_load:
+         case nir_intrinsic_image_deref_store:
+         case nir_intrinsic_image_deref_atomic_add:
+         case nir_intrinsic_image_deref_atomic_min:
+         case nir_intrinsic_image_deref_atomic_max:
+         case nir_intrinsic_image_deref_atomic_and:
+         case nir_intrinsic_image_deref_atomic_or:
+         case nir_intrinsic_image_deref_atomic_xor:
+         case nir_intrinsic_image_deref_atomic_exchange:
+         case nir_intrinsic_image_deref_atomic_comp_swap:
+         case nir_intrinsic_image_deref_size:
+         case nir_intrinsic_image_deref_samples:
+            add_deref_src_binding(state, intrin->src[0]);
             break;
 
          default:
@@ -89,10 +107,8 @@ get_used_bindings_block(nir_block *block,
       }
       case nir_instr_type_tex: {
          nir_tex_instr *tex = nir_instr_as_tex(instr);
-         assert(tex->texture);
-         add_var_binding(state, tex->texture->var);
-         if (tex->sampler)
-            add_var_binding(state, tex->sampler->var);
+         add_tex_src_binding(state, tex, nir_tex_src_texture_deref);
+         add_tex_src_binding(state, tex, nir_tex_src_sampler_deref);
          break;
       }
       default:
@@ -157,18 +173,42 @@ lower_res_reindex_intrinsic(nir_intrinsic_instr *intrin,
 }
 
 static void
-lower_tex_deref(nir_tex_instr *tex, nir_deref_var *deref,
-                unsigned *const_index, unsigned array_size,
-                nir_tex_src_type src_type,
+lower_tex_deref(nir_tex_instr *tex, nir_tex_src_type deref_src_type,
+                unsigned *base_index,
                 struct apply_pipeline_layout_state *state)
 {
-   nir_builder *b = &state->builder;
+   int deref_src_idx = nir_tex_instr_src_index(tex, deref_src_type);
+   if (deref_src_idx < 0)
+      return;
+
+   nir_deref_instr *deref = nir_src_as_deref(tex->src[deref_src_idx].src);
+   nir_variable *var = nir_deref_instr_get_variable(deref);
+
+   unsigned set = var->data.descriptor_set;
+   unsigned binding = var->data.binding;
+   unsigned array_size =
+      state->layout->set[set].layout->binding[binding].array_size;
+
+   nir_tex_src_type offset_src_type;
+   if (deref_src_type == nir_tex_src_texture_deref) {
+      offset_src_type = nir_tex_src_texture_offset;
+      *base_index = state->set[set].surface_offsets[binding];
+   } else {
+      assert(deref_src_type == nir_tex_src_sampler_deref);
+      offset_src_type = nir_tex_src_sampler_offset;
+      *base_index = state->set[set].sampler_offsets[binding];
+   }
 
-   if (deref->deref.child) {
-      assert(deref->deref.child->deref_type == nir_deref_type_array);
-      nir_deref_array *deref_array = nir_deref_as_array(deref->deref.child);
+   nir_ssa_def *index = NULL;
+   if (deref->deref_type != nir_deref_type_var) {
+      assert(deref->deref_type == nir_deref_type_array);
+
+      nir_const_value *const_index = nir_src_as_const_value(deref->arr.index);
+      if (const_index) {
+         *base_index += MIN2(const_index->u32[0], array_size - 1);
+      } else {
+         nir_builder *b = &state->builder;
 
-      if (deref_array->deref_array_type == nir_deref_array_type_indirect) {
          /* From VK_KHR_sampler_ycbcr_conversion:
           *
           * If sampler Y’CBCR conversion is enabled, the combined image
@@ -178,32 +218,20 @@ lower_tex_deref(nir_tex_instr *tex, nir_deref_var *deref,
           */
          assert(nir_tex_instr_src_index(tex, nir_tex_src_plane) == -1);
 
-         nir_ssa_def *index =
-            nir_iadd(b, nir_imm_int(b, deref_array->base_offset),
-                        nir_ssa_for_src(b, deref_array->indirect, 1));
+         index = nir_ssa_for_src(b, deref->arr.index, 1);
 
          if (state->add_bounds_checks)
             index = nir_umin(b, index, nir_imm_int(b, array_size - 1));
-
-         nir_tex_instr_add_src(tex, src_type, nir_src_for_ssa(index));
-      } else {
-         *const_index += MIN2(deref_array->base_offset, array_size - 1);
       }
    }
-}
-
-static void
-cleanup_tex_deref(nir_tex_instr *tex, nir_deref_var *deref)
-{
-   if (deref->deref.child == NULL)
-      return;
-
-   nir_deref_array *deref_array = nir_deref_as_array(deref->deref.child);
 
-   if (deref_array->deref_array_type != nir_deref_array_type_indirect)
-      return;
-
-   nir_instr_rewrite_src(&tex->instr, &deref_array->indirect, NIR_SRC_INIT);
+   if (index) {
+      nir_instr_rewrite_src(&tex->instr, &tex->src[deref_src_idx].src,
+                            nir_src_for_ssa(index));
+      tex->src[deref_src_idx].src_type = offset_src_type;
+   } else {
+      nir_tex_instr_remove_src(tex, deref_src_idx);
+   }
 }
 
 static uint32_t
@@ -224,43 +252,22 @@ tex_instr_get_and_remove_plane_src(nir_tex_instr *tex)
 static void
 lower_tex(nir_tex_instr *tex, struct apply_pipeline_layout_state *state)
 {
-   /* No one should have come by and lowered it already */
-   assert(tex->texture);
-
    state->builder.cursor = nir_before_instr(&tex->instr);
 
-   unsigned set = tex->texture->var->data.descriptor_set;
-   unsigned binding = tex->texture->var->data.binding;
-   unsigned array_size =
-      state->layout->set[set].layout->binding[binding].array_size;
    unsigned plane = tex_instr_get_and_remove_plane_src(tex);
 
-   tex->texture_index = state->set[set].surface_offsets[binding];
-   lower_tex_deref(tex, tex->texture, &tex->texture_index, array_size,
-                   nir_tex_src_texture_offset, state);
+   lower_tex_deref(tex, nir_tex_src_texture_deref,
+                   &tex->texture_index, state);
    tex->texture_index += plane;
 
-   if (tex->sampler) {
-      unsigned set = tex->sampler->var->data.descriptor_set;
-      unsigned binding = tex->sampler->var->data.binding;
-      unsigned array_size =
-         state->layout->set[set].layout->binding[binding].array_size;
-      tex->sampler_index = state->set[set].sampler_offsets[binding];
-      lower_tex_deref(tex, tex->sampler, &tex->sampler_index, array_size,
-                      nir_tex_src_sampler_offset, state);
-      tex->sampler_index += plane;
-   }
+   lower_tex_deref(tex, nir_tex_src_sampler_deref,
+                   &tex->sampler_index, state);
+   tex->sampler_index += plane;
 
    /* The backend only ever uses this to mark used surfaces.  We don't care
     * about that little optimization so it just needs to be non-zero.
     */
    tex->texture_array_size = 1;
-
-   cleanup_tex_deref(tex, tex->texture);
-   if (tex->sampler)
-      cleanup_tex_deref(tex, tex->sampler);
-   tex->texture = NULL;
-   tex->sampler = NULL;
 }
 
 static void
index ef3b4add51a9ecebeb03cb864fd4d7481292a5b2..523202cf3d968f7838f5440f4bd6a0239686bc1d 100644 (file)
@@ -420,9 +420,6 @@ anv_pipeline_compile(struct anv_pipeline *pipeline,
 
    NIR_PASS_V(nir, anv_nir_lower_ycbcr_textures, layout);
 
-   NIR_PASS_V(nir, nir_lower_deref_instrs,
-              nir_lower_texture_derefs | nir_lower_image_derefs);
-
    NIR_PASS_V(nir, anv_nir_lower_push_constants);
 
    if (stage != MESA_SHADER_COMPUTE)