From fc88f04ba127551edd5d18d79197caa60781eb3d Mon Sep 17 00:00:00 2001 From: Karol Herbst Date: Mon, 26 Aug 2024 01:46:03 +0200 Subject: [PATCH] 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 Reviewed-by: Jesse Natalie Part-of: --- src/compiler/nir/nir_divergence_analysis.c | 3 +++ src/compiler/nir/nir_gather_info.c | 5 ++++- src/compiler/nir/nir_intrinsics.py | 1 + src/compiler/nir/nir_lower_non_uniform_access.c | 3 +++ .../nir/nir_lower_readonly_images_to_tex.c | 6 ++++++ src/compiler/nir/nir_opt_preamble.c | 3 +++ src/compiler/spirv/spirv_to_nir.c | 17 +++++++---------- 7 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/compiler/nir/nir_divergence_analysis.c b/src/compiler/nir/nir_divergence_analysis.c index 8ebbaf21b6e..a486db7f4ff 100644 --- a/src/compiler/nir/nir_divergence_analysis.c +++ b/src/compiler/nir/nir_divergence_analysis.c @@ -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: diff --git a/src/compiler/nir/nir_gather_info.c b/src/compiler/nir/nir_gather_info.c index a75d7f2930f..5890bca1090 100644 --- a/src/compiler/nir/nir_gather_info.c +++ b/src/compiler/nir/nir_gather_info.c @@ -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; diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py index e0c8115b9a5..dc5b53f0f65 100644 --- a/src/compiler/nir/nir_intrinsics.py +++ b/src/compiler/nir/nir_intrinsics.py @@ -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]) diff --git a/src/compiler/nir/nir_lower_non_uniform_access.c b/src/compiler/nir/nir_lower_non_uniform_access.c index 153337eb150..0f56c33d299 100644 --- a/src/compiler/nir/nir_lower_non_uniform_access.c +++ b/src/compiler/nir/nir_lower_non_uniform_access.c @@ -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: diff --git a/src/compiler/nir/nir_lower_readonly_images_to_tex.c b/src/compiler/nir/nir_lower_readonly_images_to_tex.c index 057bc0c6051..e1d2a997e4f 100644 --- a/src/compiler/nir/nir_lower_readonly_images_to_tex.c +++ b/src/compiler/nir/nir_lower_readonly_images_to_tex.c @@ -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; diff --git a/src/compiler/nir/nir_opt_preamble.c b/src/compiler/nir/nir_opt_preamble.c index b87316c5ed5..8b2cb1e5f05 100644 --- a/src/compiler/nir/nir_opt_preamble.c +++ b/src/compiler/nir/nir_opt_preamble.c @@ -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: diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index 4667534b335..5b9df6ea77b 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -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: {