v3dv/pipeline: lower_image_deref

This is really similar to the existing lower_tex_src_to_offset, but
for now we prefer to keep them independent, just in case we start to
found specific image use-cases as we advance fixing CTS tests.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
This commit is contained in:
Alejandro Piñeiro 2020-06-24 01:55:20 +02:00 committed by Marge Bot
parent 407411036c
commit 42b1cacbc6
1 changed files with 87 additions and 0 deletions

View File

@ -728,6 +728,76 @@ lower_sampler(nir_builder *b, nir_tex_instr *instr,
return true;
}
/* FIXME: really similar to lower_tex_src_to_offset, perhaps refactor? */
static void
lower_image_deref(nir_builder *b,
nir_intrinsic_instr *instr,
struct v3dv_pipeline *pipeline,
const struct v3dv_pipeline_layout *layout)
{
nir_deref_instr *deref = nir_src_as_deref(instr->src[0]);
nir_ssa_def *index = NULL;
unsigned array_elements = 1;
unsigned base_index = 0;
while (deref->deref_type != nir_deref_type_var) {
assert(deref->parent.is_ssa);
nir_deref_instr *parent =
nir_instr_as_deref(deref->parent.ssa->parent_instr);
assert(deref->deref_type == nir_deref_type_array);
if (nir_src_is_const(deref->arr.index) && index == NULL) {
/* We're still building a direct index */
base_index += nir_src_as_uint(deref->arr.index) * array_elements;
} else {
if (index == NULL) {
/* We used to be direct but not anymore */
index = nir_imm_int(b, base_index);
base_index = 0;
}
index = nir_iadd(b, index,
nir_imul(b, nir_imm_int(b, array_elements),
nir_ssa_for_src(b, deref->arr.index, 1)));
}
array_elements *= glsl_get_length(parent->type);
deref = parent;
}
if (index)
index = nir_umin(b, index, nir_imm_int(b, array_elements - 1));
uint32_t set = deref->var->data.descriptor_set;
uint32_t binding = deref->var->data.binding;
struct v3dv_descriptor_set_layout *set_layout = layout->set[set].layout;
struct v3dv_descriptor_set_binding_layout *binding_layout =
&set_layout->binding[binding];
uint32_t array_index = deref->var->data.index + base_index;
assert(binding_layout->type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
int desc_index =
descriptor_map_add(&pipeline->texture_map,
deref->var->data.descriptor_set,
deref->var->data.binding,
array_index,
binding_layout->array_size);
/* We still need to get a combined_index, as we are integrating images with
* the rest of the texture/sampler support
*/
int combined_index =
get_combined_index(pipeline, desc_index, V3DV_NO_SAMPLER_IDX);
index = nir_imm_int(b, combined_index);
nir_rewrite_image_intrinsic(instr, index, false);
}
static bool
lower_intrinsic(nir_builder *b, nir_intrinsic_instr *instr,
struct v3dv_pipeline *pipeline,
@ -752,6 +822,23 @@ lower_intrinsic(nir_builder *b, nir_intrinsic_instr *instr,
lower_vulkan_resource_index(b, instr, pipeline, layout);
return true;
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_imin:
case nir_intrinsic_image_deref_atomic_umin:
case nir_intrinsic_image_deref_atomic_imax:
case nir_intrinsic_image_deref_atomic_umax:
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:
lower_image_deref(b, instr, pipeline, layout);
return true;
default:
return false;
}