pvr: Fix descriptor set address calculation

Signed-off-by: Simon Perretta <simon.perretta@imgtec.com>
Acked-by: Frank Binns <frank.binns@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21474>
This commit is contained in:
Simon Perretta 2023-02-15 18:19:59 +00:00 committed by Marge Bot
parent 5287edd6d2
commit 88e42e18d9
3 changed files with 107 additions and 62 deletions

View file

@ -311,6 +311,11 @@ mesa_stage_to_pvr(gl_shader_stage mesa_stage)
unreachable("Unsupported gl_shader_stage.");
}
static bool descriptor_is_dynamic(VkDescriptorType type)
{
return (type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC);
}
static void
trans_nir_intrinsic_load_vulkan_descriptor(rogue_builder *b,
@ -325,12 +330,9 @@ trans_nir_intrinsic_load_vulkan_descriptor(rogue_builder *b,
struct pvr_pipeline_layout *pipeline_layout =
b->shader->ctx->pipeline_layout;
/* Defaults for offline compiler. */
/* TODO: Load these from an offline pipeline description
* if using the offline compiler.
*/
unsigned desc_set_table_sh_reg = 0;
unsigned flat_desc_idx = binding;
unsigned desc_set_table_sh_reg;
unsigned desc_set_offset;
unsigned desc_offset;
if (pipeline_layout) {
/* Fetch shared registers containing descriptor set table address. */
@ -341,26 +343,45 @@ trans_nir_intrinsic_load_vulkan_descriptor(rogue_builder *b,
pipeline_layout->sh_reg_layout_per_stage[pvr_stage]
.descriptor_set_addrs_table.offset;
/* Lookup offsets for descriptor set and descriptor. */
/* Calculate offset for the descriptor set. */
assert(desc_set < pipeline_layout->set_count);
desc_set_offset = desc_set * sizeof(pvr_dev_addr_t); /* Table is an array
of addresses. */
unsigned binding_count =
pipeline_layout->set_layout[desc_set]->binding_count;
assert(binding < binding_count);
const struct pvr_descriptor_set_layout *set_layout =
pipeline_layout->set_layout[desc_set];
const struct pvr_descriptor_set_layout_mem_layout *mem_layout =
&set_layout->memory_layout_in_dwords_per_stage[pvr_stage];
flat_desc_idx = ~0U;
for (unsigned u = 0; u < binding_count; ++u) {
unsigned binding_number =
pipeline_layout->set_layout[desc_set]->bindings[u].binding_number;
/* Calculate offset for the descriptor/binding. */
assert(binding < set_layout->binding_count);
if (binding_number == binding) {
flat_desc_idx = pipeline_layout->set_layout[desc_set]
->bindings[u]
.descriptor_index;
break;
}
}
assert(flat_desc_idx != ~0U);
const struct pvr_descriptor_set_layout_binding *binding_layout =
pvr_get_descriptor_binding(set_layout, binding);
assert(binding_layout);
/* TODO: Handle secondaries. */
/* TODO: Handle bindings having multiple descriptors
* (VkDescriptorSetLayoutBinding->descriptorCount).
*/
if (descriptor_is_dynamic(binding_layout->type))
desc_offset = set_layout->total_size_in_dwords;
else
desc_offset = mem_layout->primary_offset;
desc_offset +=
binding_layout->per_stage_offset_in_dwords[pvr_stage].primary;
desc_offset *= sizeof(uint32_t); /* DWORDs to bytes. */
} else {
/* Dummy defaults for offline compiler. */
/* TODO: Load these from an offline pipeline description
* if using the offline compiler.
*/
desc_set_table_sh_reg = 0;
desc_set_offset = desc_set * sizeof(pvr_dev_addr_t);
desc_offset = binding * sizeof(pvr_dev_addr_t);
}
unsigned desc_set_table_addr_idx = b->shader->ctx->next_ssa_idx++;
@ -384,8 +405,6 @@ trans_nir_intrinsic_load_vulkan_descriptor(rogue_builder *b,
->instr;
rogue_add_instr_comment(instr, "desc_set_table_addr_hi");
/* TODO: Don't add offsets if the descriptor set/flat descriptor is 0. */
/* Offset the descriptor set table address to access the descriptor set. */
unsigned desc_set_table_addr_offset_idx = b->shader->ctx->next_ssa_idx++;
rogue_regarray *desc_set_table_addr_offset_64 =
@ -395,14 +414,27 @@ trans_nir_intrinsic_load_vulkan_descriptor(rogue_builder *b,
rogue_ssa_vec_regarray(b->shader, 1, desc_set_table_addr_offset_idx, 1),
};
unsigned desc_set_table_addr_offset_lo_idx = b->shader->ctx->next_ssa_idx++;
unsigned desc_set_table_addr_offset_hi_idx = b->shader->ctx->next_ssa_idx++;
rogue_reg *desc_set_table_addr_offset_lo =
rogue_ssa_reg(b->shader, desc_set_table_addr_offset_lo_idx);
rogue_reg *desc_set_table_addr_offset_hi =
rogue_ssa_reg(b->shader, desc_set_table_addr_offset_hi_idx);
rogue_MOV(b,
rogue_ref_reg(desc_set_table_addr_offset_lo),
rogue_ref_imm(desc_set_offset));
rogue_MOV(b, rogue_ref_reg(desc_set_table_addr_offset_hi), rogue_ref_imm(0));
rogue_ADD64(b,
rogue_ref_regarray(desc_set_table_addr_offset_2x32[0]),
rogue_ref_regarray(desc_set_table_addr_offset_2x32[1]),
rogue_ref_io(ROGUE_IO_NONE),
rogue_ref_regarray(desc_set_table_addr_2x32[0]),
rogue_ref_regarray(desc_set_table_addr_2x32[1]),
rogue_ref_imm(desc_set * 4), /* TODO: use UMADD64 instead */
rogue_ref_imm(0),
rogue_ref_reg(desc_set_table_addr_offset_lo),
rogue_ref_reg(desc_set_table_addr_offset_hi),
rogue_ref_io(ROGUE_IO_NONE));
unsigned desc_set_addr_idx = b->shader->ctx->next_ssa_idx++;
@ -429,14 +461,27 @@ trans_nir_intrinsic_load_vulkan_descriptor(rogue_builder *b,
rogue_ssa_vec_regarray(b->shader, 1, desc_addr_offset_idx, 1),
};
unsigned desc_addr_offset_lo_idx = b->shader->ctx->next_ssa_idx++;
unsigned desc_addr_offset_hi_idx = b->shader->ctx->next_ssa_idx++;
rogue_reg *desc_addr_offset_val_lo =
rogue_ssa_reg(b->shader, desc_addr_offset_lo_idx);
rogue_reg *desc_addr_offset_val_hi =
rogue_ssa_reg(b->shader, desc_addr_offset_hi_idx);
rogue_MOV(b,
rogue_ref_reg(desc_addr_offset_val_lo),
rogue_ref_imm(desc_offset));
rogue_MOV(b, rogue_ref_reg(desc_addr_offset_val_hi), rogue_ref_imm(0));
rogue_ADD64(b,
rogue_ref_regarray(desc_addr_offset_2x32[0]),
rogue_ref_regarray(desc_addr_offset_2x32[1]),
rogue_ref_io(ROGUE_IO_NONE),
rogue_ref_regarray(desc_set_addr_2x32[0]),
rogue_ref_regarray(desc_set_addr_2x32[1]),
rogue_ref_imm(flat_desc_idx * 4), /* TODO: use UMADD64 instead */
rogue_ref_imm(0),
rogue_ref_reg(desc_addr_offset_val_lo),
rogue_ref_reg(desc_addr_offset_val_hi),
rogue_ref_io(ROGUE_IO_NONE));
unsigned desc_addr_idx = intr->dest.ssa.index;

View file

@ -407,4 +407,38 @@ struct pvr_pipeline_layout {
} per_stage_reg_info[PVR_STAGE_ALLOCATION_COUNT];
};
static int pvr_compare_layout_binding(const void *a, const void *b)
{
uint32_t binding_a;
uint32_t binding_b;
binding_a = ((struct pvr_descriptor_set_layout_binding *)a)->binding_number;
binding_b = ((struct pvr_descriptor_set_layout_binding *)b)->binding_number;
if (binding_a < binding_b)
return -1;
if (binding_a > binding_b)
return 1;
return 0;
}
/* This function does not assume that the binding will always exist for a
* particular binding_num. Caller should check before using the return pointer.
*/
static struct pvr_descriptor_set_layout_binding *
pvr_get_descriptor_binding(const struct pvr_descriptor_set_layout *layout,
const uint32_t binding_num)
{
struct pvr_descriptor_set_layout_binding binding;
binding.binding_number = binding_num;
return bsearch(&binding,
layout->bindings,
layout->binding_count,
sizeof(binding),
pvr_compare_layout_binding);
}
#endif /* PVR_COMMON_H */

View file

@ -1339,40 +1339,6 @@ VkResult pvr_FreeDescriptorSets(VkDevice _device,
return VK_SUCCESS;
}
static int pvr_compare_layout_binding(const void *a, const void *b)
{
uint32_t binding_a;
uint32_t binding_b;
binding_a = ((struct pvr_descriptor_set_layout_binding *)a)->binding_number;
binding_b = ((struct pvr_descriptor_set_layout_binding *)b)->binding_number;
if (binding_a < binding_b)
return -1;
if (binding_a > binding_b)
return 1;
return 0;
}
/* This function does not assume that the binding will always exist for a
* particular binding_num. Caller should check before using the return pointer.
*/
static struct pvr_descriptor_set_layout_binding *
pvr_get_descriptor_binding(const struct pvr_descriptor_set_layout *layout,
const uint32_t binding_num)
{
struct pvr_descriptor_set_layout_binding binding;
binding.binding_number = binding_num;
return bsearch(&binding,
layout->bindings,
layout->binding_count,
sizeof(binding),
pvr_compare_layout_binding);
}
static void pvr_descriptor_update_buffer_info(
const struct pvr_device *device,
const VkWriteDescriptorSet *write_set,