diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c index d6d029ce67b..db7f8c78d85 100644 --- a/src/intel/vulkan/anv_cmd_buffer.c +++ b/src/intel/vulkan/anv_cmd_buffer.c @@ -928,6 +928,25 @@ anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer, VkShaderStageFlags dirty_stages = 0; if (pipe_state->descriptors[set_index] != set) { pipe_state->descriptors[set_index] = set; + + /* Ray-tracing shaders are entirely bindless and so they don't have + * access to HW binding tables. This means that we have to upload the + * descriptor set as an 64-bit address in the push constants. + */ + if (bind_point == VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR) { + struct anv_push_constants *push = &pipe_state->push_constants; + + struct anv_address set_addr = { + .bo = set->pool->bo, + .offset = set->desc_mem.offset, + }; + push->desc_sets[set_index] = anv_address_physical(set_addr); + + anv_reloc_list_add_bo(cmd_buffer->batch.relocs, + cmd_buffer->batch.alloc, + set->pool->bo); + } + dirty_stages |= stages; } diff --git a/src/intel/vulkan/anv_nir_compute_push_layout.c b/src/intel/vulkan/anv_nir_compute_push_layout.c index da19ab39740..526e1a48f0b 100644 --- a/src/intel/vulkan/anv_nir_compute_push_layout.c +++ b/src/intel/vulkan/anv_nir_compute_push_layout.c @@ -26,6 +26,8 @@ #include "compiler/brw_nir.h" #include "util/mesa-sha1.h" +#define sizeof_field(type, field) sizeof(((type *)0)->field) + void anv_nir_compute_push_layout(const struct anv_physical_device *pdevice, bool robust_buffer_access, @@ -65,6 +67,13 @@ anv_nir_compute_push_layout(const struct anv_physical_device *pdevice, break; } + case nir_intrinsic_load_desc_set_address_intel: + push_start = MIN2(push_start, + offsetof(struct anv_push_constants, desc_sets)); + push_end = MAX2(push_end, push_start + + sizeof_field(struct anv_push_constants, desc_sets)); + break; + default: break; } @@ -130,6 +139,9 @@ anv_nir_compute_push_layout(const struct anv_physical_device *pdevice, if (!function->impl) continue; + nir_builder build, *b = &build; + nir_builder_init(b, function->impl); + nir_foreach_block(block, function->impl) { nir_foreach_instr_safe(instr, block) { if (instr->type != nir_instr_type_intrinsic) @@ -144,6 +156,17 @@ anv_nir_compute_push_layout(const struct anv_physical_device *pdevice, push_start); break; + case nir_intrinsic_load_desc_set_address_intel: { + b->cursor = nir_before_instr(&intrin->instr); + nir_ssa_def *pc_load = nir_load_uniform(b, 1, 64, + nir_imul_imm(b, intrin->src[0].ssa, sizeof(uint64_t)), + .base = offsetof(struct anv_push_constants, desc_sets), + .range = sizeof_field(struct anv_push_constants, desc_sets), + .dest_type = nir_type_uint64); + nir_ssa_def_rewrite_uses(&intrin->dest.ssa, pc_load); + break; + } + default: break; } diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 7f454a205f8..42c430a427d 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -2679,6 +2679,9 @@ struct anv_push_constants { /** Pad out to a multiple of 32 bytes */ uint32_t pad[2]; + /* Base addresses for descriptor sets */ + uint64_t desc_sets[MAX_SETS]; + struct { /** Base workgroup ID *