anv: add dynamic buffer offsets support with independent sets
With independent sets, we're not able to compute immediate values for the index at which to read anv_push_constants::dynamic_offsets to get the offset of a dynamic buffer. This is because the pipeline layout may not have all the descriptor set layouts when we compile the shader. To solve that issue, we insert a layer of indirection. This reworks the dynamic buffer offset storage with a 2D array in anv_cmd_pipeline_state : dynamic_offsets[MAX_SETS][MAX_DYN_BUFFERS] When the pipeline or the dynamic buffer offsets are updated, we flatten that array into the anv_push_constants::dynamic_offsets[MAX_DYN_BUFFERS] array. For shaders compiled with independent sets, the bottom 6 bits of element X in anv_push_constants::desc_sets[] is used to specify the base offsets into the anv_push_constants::dynamic_offsets[] for the set X. The computation in the shader is now something like : base_dyn_buffer_set_idx = anv_push_constants::desc_sets[set_idx] & 0x3f dyn_buffer_offset = anv_push_constants::dynamic_offsets[base_dyn_buffer_set_idx + dynamic_buffer_idx] It was suggested by Faith to use a different push constant buffer with dynamic_offsets prepared for each stage when using independent sets instead, but it feels easier to understand this way. And there is some room for optimization if you are set X and that you know all the sets in the range [0, X], then you can still avoid the indirection. Separate push constant allocations per stage do have a CPU cost. Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Reviewed-by: Emma Anholt <emma@anholt.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15637>
This commit is contained in:
committed by
Marge Bot
parent
16c7c37718
commit
0b8a2de2a1
@@ -68,6 +68,7 @@ anv_nir_compute_push_layout(nir_shader *nir,
|
||||
}
|
||||
|
||||
case nir_intrinsic_load_desc_set_address_intel:
|
||||
case nir_intrinsic_load_desc_set_dynamic_index_intel:
|
||||
push_start = MIN2(push_start,
|
||||
offsetof(struct anv_push_constants, desc_sets));
|
||||
push_end = MAX2(push_end, push_start +
|
||||
@@ -171,6 +172,22 @@ anv_nir_compute_push_layout(nir_shader *nir,
|
||||
.base = offsetof(struct anv_push_constants, desc_sets),
|
||||
.range = sizeof_field(struct anv_push_constants, desc_sets),
|
||||
.dest_type = nir_type_uint64);
|
||||
pc_load = nir_iand_imm(b, pc_load, ANV_DESCRIPTOR_SET_ADDRESS_MASK);
|
||||
nir_ssa_def_rewrite_uses(&intrin->dest.ssa, pc_load);
|
||||
break;
|
||||
}
|
||||
|
||||
case nir_intrinsic_load_desc_set_dynamic_index_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);
|
||||
pc_load = nir_i2i32(
|
||||
b,
|
||||
nir_iand_imm(
|
||||
b, pc_load, ANV_DESCRIPTOR_SET_DYNAMIC_INDEX_MASK));
|
||||
nir_ssa_def_rewrite_uses(&intrin->dest.ssa, pc_load);
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user