mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-30 14:20:11 +01:00
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:
parent
5287edd6d2
commit
88e42e18d9
3 changed files with 107 additions and 62 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue