mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 02:48:06 +02:00
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:
parent
9a20467cf2
commit
b05ffc9fec
6 changed files with 83 additions and 7 deletions
|
|
@ -100,7 +100,10 @@ panvk_CmdBindDescriptorSets(VkCommandBuffer commandBuffer,
|
||||||
pDynamicOffsets += set->layout->num_dynoffsets;
|
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;
|
descriptors_state->ubos = 0;
|
||||||
|
|
||||||
if (set->layout->num_textures)
|
if (set->layout->num_textures)
|
||||||
|
|
|
||||||
|
|
@ -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->textures);
|
||||||
vk_free(&device->vk.alloc, set->samplers);
|
vk_free(&device->vk.alloc, set->samplers);
|
||||||
vk_free(&device->vk.alloc, set->ubos);
|
vk_free(&device->vk.alloc, set->ubos);
|
||||||
|
vk_free(&device->vk.alloc, set->ssbos);
|
||||||
vk_free(&device->vk.alloc, set->descs);
|
vk_free(&device->vk.alloc, set->descs);
|
||||||
vk_object_free(&device->vk, NULL, set);
|
vk_object_free(&device->vk, NULL, set);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -345,11 +345,18 @@ struct panvk_descriptor {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct panvk_buffer_desc {
|
||||||
|
struct panvk_buffer *buffer;
|
||||||
|
VkDeviceSize offset;
|
||||||
|
VkDeviceSize size;
|
||||||
|
};
|
||||||
|
|
||||||
struct panvk_descriptor_set {
|
struct panvk_descriptor_set {
|
||||||
struct vk_object_base base;
|
struct vk_object_base base;
|
||||||
struct panvk_descriptor_pool *pool;
|
struct panvk_descriptor_pool *pool;
|
||||||
const struct panvk_descriptor_set_layout *layout;
|
const struct panvk_descriptor_set_layout *layout;
|
||||||
struct panvk_descriptor *descs;
|
struct panvk_descriptor *descs;
|
||||||
|
struct panvk_buffer_desc *ssbos;
|
||||||
void *ubos;
|
void *ubos;
|
||||||
void *samplers;
|
void *samplers;
|
||||||
void *textures;
|
void *textures;
|
||||||
|
|
@ -478,10 +485,12 @@ enum panvk_dynamic_state_bits {
|
||||||
PANVK_DYNAMIC_STENCIL_WRITE_MASK = 1 << 7,
|
PANVK_DYNAMIC_STENCIL_WRITE_MASK = 1 << 7,
|
||||||
PANVK_DYNAMIC_STENCIL_REFERENCE = 1 << 8,
|
PANVK_DYNAMIC_STENCIL_REFERENCE = 1 << 8,
|
||||||
PANVK_DYNAMIC_DISCARD_RECTANGLE = 1 << 9,
|
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 {
|
struct panvk_descriptor_state {
|
||||||
|
uint32_t dirty;
|
||||||
struct {
|
struct {
|
||||||
const struct panvk_descriptor_set *set;
|
const struct panvk_descriptor_set *set;
|
||||||
struct panfrost_ptr dynoffsets;
|
struct panfrost_ptr dynoffsets;
|
||||||
|
|
|
||||||
|
|
@ -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
|
static void
|
||||||
panvk_cmd_upload_sysval(struct panvk_cmd_buffer *cmdbuf,
|
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)) {
|
switch (PAN_SYSVAL_TYPE(id)) {
|
||||||
case PAN_SYSVAL_VIEWPORT_SCALE:
|
case PAN_SYSVAL_VIEWPORT_SCALE:
|
||||||
|
|
@ -311,6 +337,14 @@ panvk_cmd_upload_sysval(struct panvk_cmd_buffer *cmdbuf,
|
||||||
case PAN_SYSVAL_BLEND_CONSTANTS:
|
case PAN_SYSVAL_BLEND_CONSTANTS:
|
||||||
memcpy(data->f32, cmdbuf->state.blend.constants, sizeof(data->f32));
|
memcpy(data->f32, cmdbuf->state.blend.constants, sizeof(data->f32));
|
||||||
break;
|
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:
|
default:
|
||||||
unreachable("Invalid static sysval");
|
unreachable("Invalid static sysval");
|
||||||
}
|
}
|
||||||
|
|
@ -326,11 +360,12 @@ panvk_cmd_prepare_sysvals(struct panvk_cmd_buffer *cmdbuf,
|
||||||
if (!pipeline->num_sysvals)
|
if (!pipeline->num_sysvals)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
uint32_t dirty = cmdbuf->state.dirty | desc_state->dirty;
|
||||||
|
|
||||||
for (unsigned i = 0; i < ARRAY_SIZE(desc_state->sysvals); i++) {
|
for (unsigned i = 0; i < ARRAY_SIZE(desc_state->sysvals); i++) {
|
||||||
unsigned sysval_count = pipeline->sysvals[i].ids.sysval_count;
|
unsigned sysval_count = pipeline->sysvals[i].ids.sysval_count;
|
||||||
if (!sysval_count || pipeline->sysvals[i].ubo ||
|
if (!sysval_count || pipeline->sysvals[i].ubo ||
|
||||||
(desc_state->sysvals[i] &&
|
(desc_state->sysvals[i] && !(dirty & pipeline->sysvals[i].dirty_mask)))
|
||||||
!(cmdbuf->state.dirty & pipeline->sysvals[i].dirty_mask)))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
struct panfrost_ptr sysvals =
|
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++) {
|
for (unsigned s = 0; s < pipeline->sysvals[i].ids.sysval_count; s++) {
|
||||||
panvk_cmd_upload_sysval(cmdbuf, pipeline->sysvals[i].ids.sysvals[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;
|
desc_state->sysvals[i] = sysvals.gpu;
|
||||||
|
|
@ -782,7 +817,7 @@ panvk_per_arch(CmdDraw)(VkCommandBuffer commandBuffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear the dirty flags all at once */
|
/* Clear the dirty flags all at once */
|
||||||
cmdbuf->state.dirty = 0;
|
desc_state->dirty = cmdbuf->state.dirty = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkResult
|
VkResult
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,14 @@ panvk_per_arch(descriptor_set_create)(struct panvk_device *device,
|
||||||
goto err_free_set;
|
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) {
|
if (layout->num_samplers) {
|
||||||
set->samplers = vk_zalloc(&device->vk.alloc,
|
set->samplers = vk_zalloc(&device->vk.alloc,
|
||||||
pan_size(SAMPLER) * layout->num_samplers, 8,
|
pan_size(SAMPLER) * layout->num_samplers, 8,
|
||||||
|
|
@ -106,6 +114,7 @@ panvk_per_arch(descriptor_set_create)(struct panvk_device *device,
|
||||||
err_free_set:
|
err_free_set:
|
||||||
vk_free(&device->vk.alloc, set->textures);
|
vk_free(&device->vk.alloc, set->textures);
|
||||||
vk_free(&device->vk.alloc, set->samplers);
|
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->ubos);
|
||||||
vk_free(&device->vk.alloc, set->descs);
|
vk_free(&device->vk.alloc, set->descs);
|
||||||
vk_object_free(&device->vk, NULL, set);
|
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;
|
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
|
static void
|
||||||
panvk_per_arch(set_ubo_desc)(void *ubo,
|
panvk_per_arch(set_ubo_desc)(void *ubo,
|
||||||
const VkDescriptorBufferInfo *pBufferInfo)
|
const VkDescriptorBufferInfo *pBufferInfo)
|
||||||
|
|
@ -284,6 +304,11 @@ panvk_per_arch(write_descriptor_set)(struct panvk_device *dev,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
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:
|
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
|
||||||
for (unsigned i = 0; i < ndescs; i++)
|
for (unsigned i = 0; i < ndescs; i++)
|
||||||
panvk_set_buffer_info_desc(&descs[i], &pDescriptorWrite->pBufferInfo[src_offset + i]);
|
panvk_set_buffer_info_desc(&descs[i], &pDescriptorWrite->pBufferInfo[src_offset + i]);
|
||||||
|
|
|
||||||
|
|
@ -230,6 +230,9 @@ panvk_pipeline_builder_alloc_static_state_bo(struct panvk_pipeline_builder *buil
|
||||||
case PAN_SYSVAL_VIEWPORT_OFFSET:
|
case PAN_SYSVAL_VIEWPORT_OFFSET:
|
||||||
pipeline->sysvals[i].dirty_mask |= PANVK_DYNAMIC_VIEWPORT;
|
pipeline->sysvals[i].dirty_mask |= PANVK_DYNAMIC_VIEWPORT;
|
||||||
break;
|
break;
|
||||||
|
case PAN_SYSVAL_SSBO:
|
||||||
|
pipeline->sysvals[i].dirty_mask |= PANVK_DYNAMIC_SSBO;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue