panvk: Add support for storage buffers

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15248>
This commit is contained in:
Boris Brezillon 2021-09-23 15:13:21 +02:00 committed by Marge Bot
parent 9a20467cf2
commit b05ffc9fec
6 changed files with 83 additions and 7 deletions

View file

@ -100,7 +100,10 @@ panvk_CmdBindDescriptorSets(VkCommandBuffer commandBuffer,
pDynamicOffsets += set->layout->num_dynoffsets;
}
if (set->layout->num_ubos || set->layout->num_dynoffsets)
if (set->layout->num_ssbos)
descriptors_state->dirty |= PANVK_DYNAMIC_SSBO;
if (set->layout->num_ubos || set->layout->num_ssbos || set->layout->num_dynoffsets)
descriptors_state->ubos = 0;
if (set->layout->num_textures)

View file

@ -436,6 +436,7 @@ panvk_descriptor_set_destroy(struct panvk_device *device,
vk_free(&device->vk.alloc, set->textures);
vk_free(&device->vk.alloc, set->samplers);
vk_free(&device->vk.alloc, set->ubos);
vk_free(&device->vk.alloc, set->ssbos);
vk_free(&device->vk.alloc, set->descs);
vk_object_free(&device->vk, NULL, set);
}

View file

@ -345,11 +345,18 @@ struct panvk_descriptor {
};
};
struct panvk_buffer_desc {
struct panvk_buffer *buffer;
VkDeviceSize offset;
VkDeviceSize size;
};
struct panvk_descriptor_set {
struct vk_object_base base;
struct panvk_descriptor_pool *pool;
const struct panvk_descriptor_set_layout *layout;
struct panvk_descriptor *descs;
struct panvk_buffer_desc *ssbos;
void *ubos;
void *samplers;
void *textures;
@ -478,10 +485,12 @@ enum panvk_dynamic_state_bits {
PANVK_DYNAMIC_STENCIL_WRITE_MASK = 1 << 7,
PANVK_DYNAMIC_STENCIL_REFERENCE = 1 << 8,
PANVK_DYNAMIC_DISCARD_RECTANGLE = 1 << 9,
PANVK_DYNAMIC_ALL = (1 << 10) - 1,
PANVK_DYNAMIC_SSBO = 1 << 10,
PANVK_DYNAMIC_ALL = (1 << 11) - 1,
};
struct panvk_descriptor_state {
uint32_t dirty;
struct {
const struct panvk_descriptor_set *set;
struct panfrost_ptr dynoffsets;

View file

@ -293,9 +293,35 @@ panvk_per_arch(cmd_alloc_tls_desc)(struct panvk_cmd_buffer *cmdbuf, bool gfx)
}
}
static void
panvk_sysval_upload_ssbo_info(struct panvk_cmd_buffer *cmdbuf,
unsigned ssbo_id,
struct panvk_cmd_bind_point_state *bind_point_state,
union panvk_sysval_data *data)
{
const struct panvk_pipeline *pipeline = bind_point_state->pipeline;
const struct panvk_descriptor_state *desc_state = &bind_point_state->desc_state;
for (unsigned s = 0; s < pipeline->layout->num_sets; s++) {
unsigned ssbo_offset = pipeline->layout->sets[s].ssbo_offset;
unsigned num_ssbos = pipeline->layout->sets[s].layout->num_ssbos;
const struct panvk_buffer_desc *ssbo = NULL;
if (ssbo_id >= ssbo_offset && ssbo_id < (ssbo_offset + num_ssbos))
ssbo = &desc_state->sets[s].set->ssbos[ssbo_id - ssbo_offset];
if (ssbo) {
data->u64[0] = ssbo->buffer->bo->ptr.gpu + ssbo->offset;
data->u32[2] = ssbo->size == VK_WHOLE_SIZE ? ssbo->buffer->size - ssbo->offset : ssbo->size;
}
}
}
static void
panvk_cmd_upload_sysval(struct panvk_cmd_buffer *cmdbuf,
unsigned id, union panvk_sysval_data *data)
unsigned id,
struct panvk_cmd_bind_point_state *bind_point_state,
union panvk_sysval_data *data)
{
switch (PAN_SYSVAL_TYPE(id)) {
case PAN_SYSVAL_VIEWPORT_SCALE:
@ -311,6 +337,14 @@ panvk_cmd_upload_sysval(struct panvk_cmd_buffer *cmdbuf,
case PAN_SYSVAL_BLEND_CONSTANTS:
memcpy(data->f32, cmdbuf->state.blend.constants, sizeof(data->f32));
break;
case PAN_SYSVAL_SSBO:
/* This won't work with dynamic SSBO indexing. We might want to
* consider storing SSBO mappings in a separate UBO if we need to
* support
* VkPhysicalDeviceVulkan12Features.shaderStorageBufferArrayNonUniformIndexing.
*/
panvk_sysval_upload_ssbo_info(cmdbuf, PAN_SYSVAL_ID(id), bind_point_state, data);
break;
default:
unreachable("Invalid static sysval");
}
@ -326,11 +360,12 @@ panvk_cmd_prepare_sysvals(struct panvk_cmd_buffer *cmdbuf,
if (!pipeline->num_sysvals)
return;
uint32_t dirty = cmdbuf->state.dirty | desc_state->dirty;
for (unsigned i = 0; i < ARRAY_SIZE(desc_state->sysvals); i++) {
unsigned sysval_count = pipeline->sysvals[i].ids.sysval_count;
if (!sysval_count || pipeline->sysvals[i].ubo ||
(desc_state->sysvals[i] &&
!(cmdbuf->state.dirty & pipeline->sysvals[i].dirty_mask)))
(desc_state->sysvals[i] && !(dirty & pipeline->sysvals[i].dirty_mask)))
continue;
struct panfrost_ptr sysvals =
@ -339,7 +374,7 @@ panvk_cmd_prepare_sysvals(struct panvk_cmd_buffer *cmdbuf,
for (unsigned s = 0; s < pipeline->sysvals[i].ids.sysval_count; s++) {
panvk_cmd_upload_sysval(cmdbuf, pipeline->sysvals[i].ids.sysvals[s],
&data[s]);
bind_point_state, &data[s]);
}
desc_state->sysvals[i] = sysvals.gpu;
@ -782,7 +817,7 @@ panvk_per_arch(CmdDraw)(VkCommandBuffer commandBuffer,
}
/* Clear the dirty flags all at once */
cmdbuf->state.dirty = 0;
desc_state->dirty = cmdbuf->state.dirty = 0;
}
VkResult

View file

@ -72,6 +72,14 @@ panvk_per_arch(descriptor_set_create)(struct panvk_device *device,
goto err_free_set;
}
if (layout->num_ssbos) {
set->ssbos = vk_zalloc(&device->vk.alloc,
sizeof(*set->ssbos) * layout->num_ssbos, 8,
VK_OBJECT_TYPE_DESCRIPTOR_SET);
if (!set->ssbos)
goto err_free_set;
}
if (layout->num_samplers) {
set->samplers = vk_zalloc(&device->vk.alloc,
pan_size(SAMPLER) * layout->num_samplers, 8,
@ -106,6 +114,7 @@ panvk_per_arch(descriptor_set_create)(struct panvk_device *device,
err_free_set:
vk_free(&device->vk.alloc, set->textures);
vk_free(&device->vk.alloc, set->samplers);
vk_free(&device->vk.alloc, set->ssbos);
vk_free(&device->vk.alloc, set->ubos);
vk_free(&device->vk.alloc, set->descs);
vk_object_free(&device->vk, NULL, set);
@ -173,6 +182,17 @@ panvk_set_buffer_info_desc(struct panvk_descriptor *desc,
desc->buffer_info.range = pBufferInfo->range;
}
static void
panvk_set_buffer_desc(struct panvk_buffer_desc *bdesc,
const VkDescriptorBufferInfo *pBufferInfo)
{
VK_FROM_HANDLE(panvk_buffer, buffer, pBufferInfo->buffer);
bdesc->buffer = buffer;
bdesc->offset = pBufferInfo->offset;
bdesc->size = pBufferInfo->range;
}
static void
panvk_per_arch(set_ubo_desc)(void *ubo,
const VkDescriptorBufferInfo *pBufferInfo)
@ -284,6 +304,11 @@ panvk_per_arch(write_descriptor_set)(struct panvk_device *dev,
break;
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
for (unsigned i = 0; i < ndescs; i++) {
unsigned ssbo = binding_layout->ssbo_idx + dest_offset + i;
panvk_set_buffer_desc(&set->ssbos[ssbo], &pDescriptorWrite->pBufferInfo[src_offset + i]);
}
break;
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
for (unsigned i = 0; i < ndescs; i++)
panvk_set_buffer_info_desc(&descs[i], &pDescriptorWrite->pBufferInfo[src_offset + i]);

View file

@ -230,6 +230,9 @@ panvk_pipeline_builder_alloc_static_state_bo(struct panvk_pipeline_builder *buil
case PAN_SYSVAL_VIEWPORT_OFFSET:
pipeline->sysvals[i].dirty_mask |= PANVK_DYNAMIC_VIEWPORT;
break;
case PAN_SYSVAL_SSBO:
pipeline->sysvals[i].dirty_mask |= PANVK_DYNAMIC_SSBO;
break;
default:
break;
}