anv: Support fetching descriptor addresses from push constants
Bindless shaders don't have binding tables so they have to get at the descriptor sets via a different mechanism. Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8637>
This commit is contained in:
parent
937ffb1af0
commit
379b9bb7b0
|
@ -928,6 +928,25 @@ anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
|
||||||
VkShaderStageFlags dirty_stages = 0;
|
VkShaderStageFlags dirty_stages = 0;
|
||||||
if (pipe_state->descriptors[set_index] != set) {
|
if (pipe_state->descriptors[set_index] != set) {
|
||||||
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;
|
dirty_stages |= stages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#include "compiler/brw_nir.h"
|
#include "compiler/brw_nir.h"
|
||||||
#include "util/mesa-sha1.h"
|
#include "util/mesa-sha1.h"
|
||||||
|
|
||||||
|
#define sizeof_field(type, field) sizeof(((type *)0)->field)
|
||||||
|
|
||||||
void
|
void
|
||||||
anv_nir_compute_push_layout(const struct anv_physical_device *pdevice,
|
anv_nir_compute_push_layout(const struct anv_physical_device *pdevice,
|
||||||
bool robust_buffer_access,
|
bool robust_buffer_access,
|
||||||
|
@ -65,6 +67,13 @@ anv_nir_compute_push_layout(const struct anv_physical_device *pdevice,
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -130,6 +139,9 @@ anv_nir_compute_push_layout(const struct anv_physical_device *pdevice,
|
||||||
if (!function->impl)
|
if (!function->impl)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
nir_builder build, *b = &build;
|
||||||
|
nir_builder_init(b, function->impl);
|
||||||
|
|
||||||
nir_foreach_block(block, function->impl) {
|
nir_foreach_block(block, function->impl) {
|
||||||
nir_foreach_instr_safe(instr, block) {
|
nir_foreach_instr_safe(instr, block) {
|
||||||
if (instr->type != nir_instr_type_intrinsic)
|
if (instr->type != nir_instr_type_intrinsic)
|
||||||
|
@ -144,6 +156,17 @@ anv_nir_compute_push_layout(const struct anv_physical_device *pdevice,
|
||||||
push_start);
|
push_start);
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2679,6 +2679,9 @@ struct anv_push_constants {
|
||||||
/** Pad out to a multiple of 32 bytes */
|
/** Pad out to a multiple of 32 bytes */
|
||||||
uint32_t pad[2];
|
uint32_t pad[2];
|
||||||
|
|
||||||
|
/* Base addresses for descriptor sets */
|
||||||
|
uint64_t desc_sets[MAX_SETS];
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
/** Base workgroup ID
|
/** Base workgroup ID
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue