anv/pipeline: Convert apply_pipeline_layout to deref instructions
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>
This commit is contained in:
@@ -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)
|
||||
{
|
||||
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];
|
||||
}
|
||||
|
||||
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->deref.child) {
|
||||
assert(deref->deref.child->deref_type == nir_deref_type_array);
|
||||
nir_deref_array *deref_array = nir_deref_as_array(deref->deref.child);
|
||||
|
||||
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));
|
||||
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 {
|
||||
*const_index += MIN2(deref_array->base_offset, array_size - 1);
|
||||
nir_tex_instr_remove_src(tex, deref_src_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
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
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user