vtn, nir: handle OpImageQueryLevels on images

This is needed for cl_khr_mipmap_image, specifically the OpenCL C
function get_image_num_mip_levels.

Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30834>
This commit is contained in:
Karol Herbst 2024-08-26 01:46:03 +02:00 committed by Marge Bot
parent 260a50add5
commit fc88f04ba1
7 changed files with 27 additions and 11 deletions

View file

@ -559,6 +559,9 @@ visit_intrinsic(nir_intrinsic_instr *instr, struct divergence_state *state)
case nir_intrinsic_load_task_payload:
case nir_intrinsic_load_buffer_amd:
case nir_intrinsic_load_typed_buffer_amd:
case nir_intrinsic_image_levels:
case nir_intrinsic_image_deref_levels:
case nir_intrinsic_bindless_image_levels:
case nir_intrinsic_image_samples:
case nir_intrinsic_image_deref_samples:
case nir_intrinsic_bindless_image_samples:

View file

@ -859,10 +859,13 @@ gather_intrinsic_info(nir_intrinsic_instr *instr, nir_shader *shader,
if (nir_intrinsic_writes_external_memory(instr))
shader->info.writes_memory = true;
if (instr->intrinsic == nir_intrinsic_image_size ||
if (instr->intrinsic == nir_intrinsic_image_levels ||
instr->intrinsic == nir_intrinsic_image_size ||
instr->intrinsic == nir_intrinsic_image_samples ||
instr->intrinsic == nir_intrinsic_image_deref_levels ||
instr->intrinsic == nir_intrinsic_image_deref_size ||
instr->intrinsic == nir_intrinsic_image_deref_samples ||
instr->intrinsic == nir_intrinsic_bindless_image_levels ||
instr->intrinsic == nir_intrinsic_bindless_image_size ||
instr->intrinsic == nir_intrinsic_bindless_image_samples)
shader->info.uses_resource_info_query = true;

View file

@ -747,6 +747,7 @@ image("store", src_comp=[4, 1, 0, 1], extra_indices=[SRC_TYPE])
image("atomic", src_comp=[4, 1, 1], dest_comp=1, extra_indices=[ATOMIC_OP])
image("atomic_swap", src_comp=[4, 1, 1, 1], dest_comp=1, extra_indices=[ATOMIC_OP])
image("size", dest_comp=0, src_comp=[1], flags=[CAN_ELIMINATE, CAN_REORDER])
image("levels", dest_comp=1, flags=[CAN_ELIMINATE, CAN_REORDER])
image("samples", dest_comp=1, flags=[CAN_ELIMINATE, CAN_REORDER])
image("texel_address", dest_comp=1, src_comp=[4, 1],
flags=[CAN_ELIMINATE, CAN_REORDER])

View file

@ -256,6 +256,7 @@ nir_lower_non_uniform_access_impl(nir_function_impl *impl,
case nir_intrinsic_image_store:
case nir_intrinsic_image_atomic:
case nir_intrinsic_image_atomic_swap:
case nir_intrinsic_image_levels:
case nir_intrinsic_image_size:
case nir_intrinsic_image_samples:
case nir_intrinsic_image_samples_identical:
@ -265,6 +266,7 @@ nir_lower_non_uniform_access_impl(nir_function_impl *impl,
case nir_intrinsic_bindless_image_store:
case nir_intrinsic_bindless_image_atomic:
case nir_intrinsic_bindless_image_atomic_swap:
case nir_intrinsic_bindless_image_levels:
case nir_intrinsic_bindless_image_size:
case nir_intrinsic_bindless_image_samples:
case nir_intrinsic_bindless_image_samples_identical:
@ -274,6 +276,7 @@ nir_lower_non_uniform_access_impl(nir_function_impl *impl,
case nir_intrinsic_image_deref_store:
case nir_intrinsic_image_deref_atomic:
case nir_intrinsic_image_deref_atomic_swap:
case nir_intrinsic_image_deref_levels:
case nir_intrinsic_image_deref_size:
case nir_intrinsic_image_deref_samples:
case nir_intrinsic_image_deref_samples_identical:

View file

@ -76,6 +76,7 @@ lower_readonly_image_instr_intrinsic(nir_builder *b, nir_intrinsic_instr *intrin
{
if (intrin->intrinsic != nir_intrinsic_image_deref_load &&
intrin->intrinsic != nir_intrinsic_image_deref_size &&
intrin->intrinsic != nir_intrinsic_image_deref_levels &&
intrin->intrinsic != nir_intrinsic_image_deref_samples)
return false;
@ -115,6 +116,10 @@ lower_readonly_image_instr_intrinsic(nir_builder *b, nir_intrinsic_instr *intrin
texop = nir_texop_txs;
num_srcs = 2;
break;
case nir_intrinsic_image_deref_levels:
texop = nir_texop_query_levels;
num_srcs = 1;
break;
case nir_intrinsic_image_deref_samples:
texop = nir_texop_texture_samples;
num_srcs = 1;
@ -179,6 +184,7 @@ lower_readonly_image_instr_intrinsic(nir_builder *b, nir_intrinsic_instr *intrin
break;
}
case nir_intrinsic_image_deref_levels:
case nir_intrinsic_image_deref_samples:
assert(num_srcs == 1);
tex->dest_type = nir_type_uint32;

View file

@ -219,6 +219,9 @@ can_move_intrinsic(nir_intrinsic_instr *instr, opt_preamble_ctx *ctx)
case nir_intrinsic_load_sample_pos_from_id:
case nir_intrinsic_load_kernel_input:
case nir_intrinsic_load_buffer_amd:
case nir_intrinsic_image_levels:
case nir_intrinsic_image_deref_levels:
case nir_intrinsic_bindless_image_levels:
case nir_intrinsic_image_samples:
case nir_intrinsic_image_deref_samples:
case nir_intrinsic_bindless_image_samples:

View file

@ -3768,17 +3768,11 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
image.lod = vtn_ssa_value(b, w[4])->def;
break;
case SpvOpImageQuerySize:
case SpvOpImageQuerySamples:
res_val = vtn_untyped_value(b, w[3]);
image.image = vtn_get_image(b, w[3], &access);
image.coord = NULL;
image.sample = NULL;
image.lod = NULL;
break;
case SpvOpImageQueryFormat:
case SpvOpImageQueryLevels:
case SpvOpImageQueryOrder:
case SpvOpImageQuerySamples:
case SpvOpImageQuerySize:
res_val = vtn_untyped_value(b, w[3]);
image.image = vtn_get_image(b, w[3], &access);
image.coord = NULL;
@ -3904,6 +3898,7 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
OP(AtomicFMinEXT, atomic)
OP(AtomicFMaxEXT, atomic)
OP(ImageQueryFormat, format)
OP(ImageQueryLevels, levels)
OP(ImageQueryOrder, order)
OP(ImageQuerySamples, samples)
#undef OP
@ -3921,6 +3916,7 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
glsl_sampler_type_is_array(image.image->type));
switch (opcode) {
case SpvOpImageQueryLevels:
case SpvOpImageQuerySamples:
case SpvOpImageQuerySize:
case SpvOpImageQuerySizeLod:
@ -3953,6 +3949,7 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
nir_intrinsic_set_access(intrin, access);
switch (opcode) {
case SpvOpImageQueryLevels:
case SpvOpImageQuerySamples:
case SpvOpImageQueryFormat:
case SpvOpImageQueryOrder:
@ -6176,7 +6173,6 @@ vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
case SpvOpImageDrefGather:
case SpvOpImageSparseDrefGather:
case SpvOpImageQueryLod:
case SpvOpImageQueryLevels:
vtn_handle_texture(b, opcode, w, count);
break;
@ -6189,6 +6185,7 @@ vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
vtn_handle_image(b, opcode, w, count);
break;
case SpvOpImageQueryLevels:
case SpvOpImageQuerySamples:
case SpvOpImageQuerySizeLod:
case SpvOpImageQuerySize: {