From 032b845edf2e008c5bd8a883f295c536a7664081 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Thu, 22 Mar 2018 23:25:07 -0700 Subject: [PATCH] anv/pipeline: Convert apply_pipeline_layout to deref instructions Acked-by: Rob Clark Acked-by: Bas Nieuwenhuizen Acked-by: Dave Airlie Reviewed-by: Kenneth Graunke --- src/intel/vulkan/anv_nir_apply_pipeline_layout.c | 149 ++++++++++++----------- src/intel/vulkan/anv_pipeline.c | 3 - 2 files changed, 78 insertions(+), 74 deletions(-) diff --git a/src/intel/vulkan/anv_nir_apply_pipeline_layout.c b/src/intel/vulkan/anv_nir_apply_pipeline_layout.c index 4ef77a0..37a54b2 100644 --- a/src/intel/vulkan/anv_nir_apply_pipeline_layout.c +++ b/src/intel/vulkan/anv_nir_apply_pipeline_layout.c @@ -54,6 +54,24 @@ add_var_binding(struct apply_pipeline_layout_state *state, nir_variable *var) } 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 diff --git a/src/intel/vulkan/anv_pipeline.c b/src/intel/vulkan/anv_pipeline.c index ef3b4ad..523202c 100644 --- a/src/intel/vulkan/anv_pipeline.c +++ b/src/intel/vulkan/anv_pipeline.c @@ -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) -- 2.7.4