panvk: Prepare dynamic buffer descriptors at bind time
We don't need to stop the panvk_buffer_desc objects to then emit the UBOs/SSBOs descriptors at draw/dispatch time. We can simply prepare them at bind time and cache the result, to make the draw/dispatch preparation a simple memcpy. Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Mary Guillemard <mary.guillemard@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28399>
This commit is contained in:

committed by
Marge Bot

parent
a603c66659
commit
9c553bda9c
@@ -94,8 +94,8 @@ struct panvk_descriptor_state {
|
||||
struct panvk_push_descriptor_set *push_sets[MAX_SETS];
|
||||
struct panvk_sysvals sysvals;
|
||||
struct {
|
||||
struct panvk_buffer_desc ubos[MAX_DYNAMIC_UNIFORM_BUFFERS];
|
||||
struct panvk_buffer_desc ssbos[MAX_DYNAMIC_STORAGE_BUFFERS];
|
||||
struct mali_uniform_buffer_packed ubos[MAX_DYNAMIC_UNIFORM_BUFFERS];
|
||||
struct panvk_ssbo_addr ssbos[MAX_DYNAMIC_STORAGE_BUFFERS];
|
||||
} dyn;
|
||||
mali_ptr sysvals_ptr;
|
||||
mali_ptr ubos;
|
||||
|
@@ -64,6 +64,10 @@ unsigned
|
||||
panvk_per_arch(pipeline_layout_dyn_desc_ubo_index)(
|
||||
const struct panvk_pipeline_layout *layout);
|
||||
|
||||
unsigned
|
||||
panvk_per_arch(pipeline_layout_dyn_ubos_offset)(
|
||||
const struct panvk_pipeline_layout *layout);
|
||||
|
||||
unsigned
|
||||
panvk_per_arch(pipeline_layout_total_ubo_count)(
|
||||
const struct panvk_pipeline_layout *layout);
|
||||
|
@@ -424,19 +424,9 @@ panvk_cmd_prepare_dyn_ssbos(struct panvk_cmd_buffer *cmdbuf,
|
||||
return;
|
||||
|
||||
struct panfrost_ptr ssbo_descs = pan_pool_alloc_aligned(
|
||||
&cmdbuf->desc_pool.base,
|
||||
pipeline->layout->num_dyn_ssbos * sizeof(struct panvk_ssbo_addr), 16);
|
||||
&cmdbuf->desc_pool.base, sizeof(desc_state->dyn.ssbos), 16);
|
||||
|
||||
struct panvk_ssbo_addr *ssbos = ssbo_descs.cpu;
|
||||
|
||||
for (uint32_t i = 0; i < pipeline->layout->num_dyn_ssbos; i++) {
|
||||
const struct panvk_buffer_desc *bdesc = &desc_state->dyn.ssbos[i];
|
||||
|
||||
ssbos[i] = (struct panvk_ssbo_addr){
|
||||
.base_addr = panvk_buffer_gpu_ptr(bdesc->buffer, bdesc->offset),
|
||||
.size = panvk_buffer_range(bdesc->buffer, bdesc->offset, bdesc->size),
|
||||
};
|
||||
}
|
||||
memcpy(ssbo_descs.cpu, desc_state->dyn.ssbos, sizeof(desc_state->dyn.ssbos));
|
||||
|
||||
desc_state->dyn_desc_ubo = ssbo_descs.gpu;
|
||||
}
|
||||
@@ -479,32 +469,15 @@ panvk_cmd_prepare_ubos(struct panvk_cmd_buffer *cmdbuf,
|
||||
} else {
|
||||
memcpy(&ubo_descs[ubo_start], set->ubos,
|
||||
set_layout->num_ubos * sizeof(*ubo_descs));
|
||||
|
||||
unsigned dyn_ubo_start = panvk_per_arch(pipeline_layout_ubo_start)(
|
||||
pipeline->layout, s, true);
|
||||
|
||||
for (unsigned i = 0; i < set_layout->num_dyn_ubos; i++) {
|
||||
const unsigned ubo_idx =
|
||||
pipeline->layout->sets[s].dyn_ubo_offset + i;
|
||||
const struct panvk_buffer_desc *bdesc =
|
||||
&desc_state->dyn.ubos[ubo_idx];
|
||||
|
||||
mali_ptr address =
|
||||
panvk_buffer_gpu_ptr(bdesc->buffer, bdesc->offset);
|
||||
size_t size =
|
||||
panvk_buffer_range(bdesc->buffer, bdesc->offset, bdesc->size);
|
||||
if (size) {
|
||||
pan_pack(&ubo_descs[dyn_ubo_start + i], UNIFORM_BUFFER, cfg) {
|
||||
cfg.pointer = address;
|
||||
cfg.entries = DIV_ROUND_UP(size, 16);
|
||||
}
|
||||
} else {
|
||||
memset(&ubo_descs[dyn_ubo_start + i], 0, sizeof(*ubo_descs));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned dyn_ubos_offset =
|
||||
panvk_per_arch(pipeline_layout_dyn_ubos_offset)(pipeline->layout);
|
||||
|
||||
memcpy(&ubo_descs[dyn_ubos_offset], desc_state->dyn.ubos,
|
||||
pipeline->layout->num_dyn_ubos * sizeof(*ubo_descs));
|
||||
|
||||
if (pipeline->layout->num_dyn_ssbos) {
|
||||
unsigned dyn_desc_ubo =
|
||||
panvk_per_arch(pipeline_layout_dyn_desc_ubo_index)(pipeline->layout);
|
||||
@@ -2057,6 +2030,62 @@ panvk_per_arch(CmdBindIndexBuffer)(VkCommandBuffer commandBuffer,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
panvk_emit_dyn_ubo(struct panvk_descriptor_state *desc_state,
|
||||
const struct panvk_descriptor_set *desc_set,
|
||||
unsigned binding, unsigned array_idx, uint32_t dyn_offset,
|
||||
unsigned dyn_ubo_slot)
|
||||
{
|
||||
struct mali_uniform_buffer_packed *ubo = &desc_state->dyn.ubos[dyn_ubo_slot];
|
||||
const struct panvk_descriptor_set_layout *slayout = desc_set->layout;
|
||||
VkDescriptorType type = slayout->bindings[binding].type;
|
||||
|
||||
assert(type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC);
|
||||
assert(dyn_ubo_slot < ARRAY_SIZE(desc_state->dyn.ubos));
|
||||
|
||||
const unsigned dyn_ubo_idx = slayout->bindings[binding].dyn_ubo_idx;
|
||||
const struct panvk_buffer_desc *bdesc =
|
||||
&desc_set->dyn_ubos[dyn_ubo_idx + array_idx];
|
||||
mali_ptr address =
|
||||
panvk_buffer_gpu_ptr(bdesc->buffer, bdesc->offset + dyn_offset);
|
||||
size_t size = panvk_buffer_range(bdesc->buffer,
|
||||
bdesc->offset + dyn_offset, bdesc->size);
|
||||
|
||||
if (size) {
|
||||
pan_pack(ubo, UNIFORM_BUFFER, cfg) {
|
||||
cfg.pointer = address;
|
||||
cfg.entries = DIV_ROUND_UP(size, 16);
|
||||
}
|
||||
} else {
|
||||
memset(ubo, 0, sizeof(*ubo));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
panvk_emit_dyn_ssbo(struct panvk_descriptor_state *desc_state,
|
||||
const struct panvk_descriptor_set *desc_set,
|
||||
unsigned binding, unsigned array_idx, uint32_t dyn_offset,
|
||||
unsigned dyn_ssbo_slot)
|
||||
{
|
||||
struct panvk_ssbo_addr *ssbo = &desc_state->dyn.ssbos[dyn_ssbo_slot];
|
||||
const struct panvk_descriptor_set_layout *slayout = desc_set->layout;
|
||||
VkDescriptorType type = slayout->bindings[binding].type;
|
||||
|
||||
assert(type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC);
|
||||
assert(dyn_ssbo_slot < ARRAY_SIZE(desc_state->dyn.ssbos));
|
||||
|
||||
const unsigned dyn_ssbo_idx = slayout->bindings[binding].dyn_ssbo_idx;
|
||||
const struct panvk_buffer_desc *bdesc =
|
||||
&desc_set->dyn_ssbos[dyn_ssbo_idx + array_idx];
|
||||
|
||||
*ssbo = (struct panvk_ssbo_addr) {
|
||||
.base_addr =
|
||||
panvk_buffer_gpu_ptr(bdesc->buffer, bdesc->offset + dyn_offset),
|
||||
.size = panvk_buffer_range(bdesc->buffer, bdesc->offset + dyn_offset,
|
||||
bdesc->size),
|
||||
};
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
panvk_per_arch(CmdBindDescriptorSets)(
|
||||
VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
|
||||
@@ -2078,27 +2107,21 @@ panvk_per_arch(CmdBindDescriptorSets)(
|
||||
descriptors_state->sets[idx] = set;
|
||||
|
||||
if (set->layout->num_dyn_ssbos || set->layout->num_dyn_ubos) {
|
||||
unsigned dyn_ubo_offset = playout->sets[idx].dyn_ubo_offset;
|
||||
unsigned dyn_ssbo_offset = playout->sets[idx].dyn_ssbo_offset;
|
||||
unsigned dyn_ubo_slot = playout->sets[idx].dyn_ubo_offset;
|
||||
unsigned dyn_ssbo_slot = playout->sets[idx].dyn_ssbo_offset;
|
||||
|
||||
for (unsigned b = 0; b < set->layout->binding_count; b++) {
|
||||
for (unsigned e = 0; e < set->layout->bindings[b].array_size; e++) {
|
||||
struct panvk_buffer_desc *bdesc = NULL;
|
||||
VkDescriptorType type = set->layout->bindings[b].type;
|
||||
|
||||
if (set->layout->bindings[b].type ==
|
||||
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) {
|
||||
bdesc = &descriptors_state->dyn.ubos[dyn_ubo_offset++];
|
||||
*bdesc =
|
||||
set->dyn_ubos[set->layout->bindings[b].dyn_ubo_idx + e];
|
||||
} else if (set->layout->bindings[b].type ==
|
||||
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
|
||||
bdesc = &descriptors_state->dyn.ssbos[dyn_ssbo_offset++];
|
||||
*bdesc =
|
||||
set->dyn_ssbos[set->layout->bindings[b].dyn_ssbo_idx + e];
|
||||
}
|
||||
|
||||
if (bdesc) {
|
||||
bdesc->offset += pDynamicOffsets[dynoffset_idx++];
|
||||
if (type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) {
|
||||
panvk_emit_dyn_ubo(descriptors_state, set, b, e,
|
||||
pDynamicOffsets[dynoffset_idx++],
|
||||
dyn_ubo_slot++);
|
||||
} else if (type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
|
||||
panvk_emit_dyn_ssbo(descriptors_state, set, b, e,
|
||||
pDynamicOffsets[dynoffset_idx++],
|
||||
dyn_ssbo_slot++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -160,3 +160,10 @@ panvk_per_arch(pipeline_layout_total_ubo_count)(
|
||||
return PANVK_NUM_BUILTIN_UBOS + layout->num_ubos + layout->num_dyn_ubos +
|
||||
(layout->num_dyn_ssbos ? 1 : 0);
|
||||
}
|
||||
|
||||
unsigned
|
||||
panvk_per_arch(pipeline_layout_dyn_ubos_offset)(
|
||||
const struct panvk_pipeline_layout *layout)
|
||||
{
|
||||
return PANVK_NUM_BUILTIN_UBOS + layout->num_ubos;
|
||||
}
|
||||
|
Reference in New Issue
Block a user