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_push_descriptor_set *push_sets[MAX_SETS];
|
||||||
struct panvk_sysvals sysvals;
|
struct panvk_sysvals sysvals;
|
||||||
struct {
|
struct {
|
||||||
struct panvk_buffer_desc ubos[MAX_DYNAMIC_UNIFORM_BUFFERS];
|
struct mali_uniform_buffer_packed ubos[MAX_DYNAMIC_UNIFORM_BUFFERS];
|
||||||
struct panvk_buffer_desc ssbos[MAX_DYNAMIC_STORAGE_BUFFERS];
|
struct panvk_ssbo_addr ssbos[MAX_DYNAMIC_STORAGE_BUFFERS];
|
||||||
} dyn;
|
} dyn;
|
||||||
mali_ptr sysvals_ptr;
|
mali_ptr sysvals_ptr;
|
||||||
mali_ptr ubos;
|
mali_ptr ubos;
|
||||||
|
@@ -64,6 +64,10 @@ unsigned
|
|||||||
panvk_per_arch(pipeline_layout_dyn_desc_ubo_index)(
|
panvk_per_arch(pipeline_layout_dyn_desc_ubo_index)(
|
||||||
const struct panvk_pipeline_layout *layout);
|
const struct panvk_pipeline_layout *layout);
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
panvk_per_arch(pipeline_layout_dyn_ubos_offset)(
|
||||||
|
const struct panvk_pipeline_layout *layout);
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
panvk_per_arch(pipeline_layout_total_ubo_count)(
|
panvk_per_arch(pipeline_layout_total_ubo_count)(
|
||||||
const struct panvk_pipeline_layout *layout);
|
const struct panvk_pipeline_layout *layout);
|
||||||
|
@@ -424,19 +424,9 @@ panvk_cmd_prepare_dyn_ssbos(struct panvk_cmd_buffer *cmdbuf,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
struct panfrost_ptr ssbo_descs = pan_pool_alloc_aligned(
|
struct panfrost_ptr ssbo_descs = pan_pool_alloc_aligned(
|
||||||
&cmdbuf->desc_pool.base,
|
&cmdbuf->desc_pool.base, sizeof(desc_state->dyn.ssbos), 16);
|
||||||
pipeline->layout->num_dyn_ssbos * sizeof(struct panvk_ssbo_addr), 16);
|
|
||||||
|
|
||||||
struct panvk_ssbo_addr *ssbos = ssbo_descs.cpu;
|
memcpy(ssbo_descs.cpu, desc_state->dyn.ssbos, sizeof(desc_state->dyn.ssbos));
|
||||||
|
|
||||||
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),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
desc_state->dyn_desc_ubo = ssbo_descs.gpu;
|
desc_state->dyn_desc_ubo = ssbo_descs.gpu;
|
||||||
}
|
}
|
||||||
@@ -479,32 +469,15 @@ panvk_cmd_prepare_ubos(struct panvk_cmd_buffer *cmdbuf,
|
|||||||
} else {
|
} else {
|
||||||
memcpy(&ubo_descs[ubo_start], set->ubos,
|
memcpy(&ubo_descs[ubo_start], set->ubos,
|
||||||
set_layout->num_ubos * sizeof(*ubo_descs));
|
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) {
|
if (pipeline->layout->num_dyn_ssbos) {
|
||||||
unsigned dyn_desc_ubo =
|
unsigned dyn_desc_ubo =
|
||||||
panvk_per_arch(pipeline_layout_dyn_desc_ubo_index)(pipeline->layout);
|
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
|
VKAPI_ATTR void VKAPI_CALL
|
||||||
panvk_per_arch(CmdBindDescriptorSets)(
|
panvk_per_arch(CmdBindDescriptorSets)(
|
||||||
VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
|
VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
|
||||||
@@ -2078,27 +2107,21 @@ panvk_per_arch(CmdBindDescriptorSets)(
|
|||||||
descriptors_state->sets[idx] = set;
|
descriptors_state->sets[idx] = set;
|
||||||
|
|
||||||
if (set->layout->num_dyn_ssbos || set->layout->num_dyn_ubos) {
|
if (set->layout->num_dyn_ssbos || set->layout->num_dyn_ubos) {
|
||||||
unsigned dyn_ubo_offset = playout->sets[idx].dyn_ubo_offset;
|
unsigned dyn_ubo_slot = playout->sets[idx].dyn_ubo_offset;
|
||||||
unsigned dyn_ssbo_offset = playout->sets[idx].dyn_ssbo_offset;
|
unsigned dyn_ssbo_slot = playout->sets[idx].dyn_ssbo_offset;
|
||||||
|
|
||||||
for (unsigned b = 0; b < set->layout->binding_count; b++) {
|
for (unsigned b = 0; b < set->layout->binding_count; b++) {
|
||||||
for (unsigned e = 0; e < set->layout->bindings[b].array_size; e++) {
|
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 ==
|
if (type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) {
|
||||||
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) {
|
panvk_emit_dyn_ubo(descriptors_state, set, b, e,
|
||||||
bdesc = &descriptors_state->dyn.ubos[dyn_ubo_offset++];
|
pDynamicOffsets[dynoffset_idx++],
|
||||||
*bdesc =
|
dyn_ubo_slot++);
|
||||||
set->dyn_ubos[set->layout->bindings[b].dyn_ubo_idx + e];
|
} else if (type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
|
||||||
} else if (set->layout->bindings[b].type ==
|
panvk_emit_dyn_ssbo(descriptors_state, set, b, e,
|
||||||
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
|
pDynamicOffsets[dynoffset_idx++],
|
||||||
bdesc = &descriptors_state->dyn.ssbos[dyn_ssbo_offset++];
|
dyn_ssbo_slot++);
|
||||||
*bdesc =
|
|
||||||
set->dyn_ssbos[set->layout->bindings[b].dyn_ssbo_idx + e];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bdesc) {
|
|
||||||
bdesc->offset += pDynamicOffsets[dynoffset_idx++];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -160,3 +160,10 @@ panvk_per_arch(pipeline_layout_total_ubo_count)(
|
|||||||
return PANVK_NUM_BUILTIN_UBOS + layout->num_ubos + layout->num_dyn_ubos +
|
return PANVK_NUM_BUILTIN_UBOS + layout->num_ubos + layout->num_dyn_ubos +
|
||||||
(layout->num_dyn_ssbos ? 1 : 0);
|
(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