diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c index 87d01da84e8..c617998cd37 100644 --- a/src/compiler/nir/nir.c +++ b/src/compiler/nir/nir.c @@ -2961,6 +2961,7 @@ nir_chase_binding(nir_src rsrc) res.var = deref->var; res.desc_set = deref->var->data.descriptor_set; res.binding = deref->var->data.binding; + res.resource_type = deref->var->data.resource_type; return res; } else if (deref->deref_type == nir_deref_type_array && is_image) { if (res.num_indices == ARRAY_SIZE(res.indices)) @@ -3051,6 +3052,7 @@ nir_chase_binding(nir_src rsrc) res.success = true; res.desc_set = nir_intrinsic_desc_set(intrin); res.binding = nir_intrinsic_binding(intrin); + res.resource_type = nir_intrinsic_resource_type(intrin); res.num_indices = 1; res.indices[0] = intrin->src[0]; return res; diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index b001ebdece8..463f7c3e97c 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -727,6 +727,9 @@ typedef struct nir_variable { */ unsigned access : 9; + /* NIR resource type bit index that this variable would have. */ + nir_resource_type resource_type; + /** * Descriptor set binding for sampler or UBO. */ @@ -3180,6 +3183,7 @@ typedef struct nir_binding { nir_variable *var; unsigned desc_set; unsigned binding; + unsigned resource_type; unsigned num_indices; nir_src indices[4]; bool read_first_invocation; diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py index 5f7fa047f9b..0f820fef5e4 100644 --- a/src/compiler/nir/nir_intrinsics.py +++ b/src/compiler/nir/nir_intrinsics.py @@ -877,7 +877,7 @@ image("fragment_mask_load_amd", src_comp=[4], dest_comp=1, bit_sizes=[32], flags # corresponds to the tuple (set, binding, index) and computes an index # corresponding to tuple (set, binding, idx + src1). intrinsic("vulkan_resource_index", src_comp=[1], dest_comp=0, - indices=[DESC_SET, BINDING, DESC_TYPE], + indices=[DESC_SET, BINDING, DESC_TYPE, RESOURCE_TYPE], flags=[CAN_ELIMINATE, CAN_REORDER]) intrinsic("vulkan_resource_reindex", src_comp=[0, 1], dest_comp=0, indices=[DESC_TYPE], flags=[CAN_ELIMINATE, CAN_REORDER]) diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c index fe0f8decb7c..94daba8fa6f 100644 --- a/src/compiler/spirv/vtn_variables.c +++ b/src/compiler/spirv/vtn_variables.c @@ -242,6 +242,7 @@ vtn_variable_resource_index(struct vtn_builder *b, struct vtn_variable *var, nir_intrinsic_set_desc_set(instr, var->descriptor_set); nir_intrinsic_set_binding(instr, var->binding); nir_intrinsic_set_desc_type(instr, vk_desc_type_for_mode(b, var->mode)); + nir_intrinsic_set_resource_type(instr, var->var->data.resource_type); nir_address_format addr_format = vtn_mode_to_address_format(b, var->mode); nir_def_init(&instr->instr, &instr->def, @@ -2441,6 +2442,43 @@ vtn_create_variable(struct vtn_builder *b, struct vtn_value *val, /* Propagate access flags from the OpVariable decorations. */ val->pointer->access |= var->access; + switch (without_array->base_type) { + case vtn_base_type_image: + if (glsl_type_is_image(without_array->glsl_image)) { + if (var->access & ACCESS_NON_WRITEABLE) + var->var->data.resource_type = nir_resource_type_read_only_image; + else + var->var->data.resource_type = nir_resource_type_read_write_image; + } else { + var->var->data.resource_type = nir_resource_type_sampled_image; + } + break; + case vtn_base_type_sampler: + var->var->data.resource_type = nir_resource_type_sampler; + break; + case vtn_base_type_sampled_image: + var->var->data.resource_type = nir_resource_type_combined_sampled_image; + break; + case vtn_base_type_accel_struct: + var->var->data.resource_type = nir_resource_type_acceleration_structure; + break; + default: + switch (var->mode) { + case vtn_variable_mode_ubo: + var->var->data.resource_type = nir_resource_type_uniform_buffer; + break; + case vtn_variable_mode_ssbo: + if (var->access & ACCESS_NON_WRITEABLE) + var->var->data.resource_type = nir_resource_type_read_only_storage_buffer; + else + var->var->data.resource_type = nir_resource_type_read_write_storage_buffer; + break; + default: + break; + } + break; + } + if ((var->mode == vtn_variable_mode_input || var->mode == vtn_variable_mode_output) && var->var->members) {