venus: add VN_CS_ENCODER_STORAGE_SHMEM_POOL for VkCommandBuffer

It suballocates from a shmem pool owned by vn_instance.  The goals are
to speed up shmem allocations for VkCommandBuffer and to reduce the
number of BOs.  Both are crucial when shmems are HOST3D BOs, because
they require roundtrips to the renderer to allocate and they take up KVM
memslots.

Signed-off-by: Chia-I Wu <olvaffe@gmail.com>
Reviewed-by: Ryan Neph <ryanneph@google.com>
Reviewed-by: Yiwei Zhang <zzyiwei@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14179>
This commit is contained in:
Chia-I Wu 2021-12-08 15:55:12 -08:00 committed by Marge Bot
parent 487926aa86
commit 7bec2a0b23
5 changed files with 73 additions and 9 deletions

View file

@ -561,7 +561,7 @@ vn_AllocateCommandBuffers(VkDevice device,
cmd->state = VN_COMMAND_BUFFER_STATE_INITIAL;
vn_cs_encoder_init(&cmd->cs, dev->instance,
VN_CS_ENCODER_STORAGE_SHMEM_ARRAY, 16 * 1024);
VN_CS_ENCODER_STORAGE_SHMEM_POOL, 16 * 1024);
VkCommandBuffer cmd_handle = vn_command_buffer_to_handle(cmd);
pCommandBuffers[i] = cmd_handle;

View file

@ -70,6 +70,23 @@ vn_cs_encoder_commit_buffer(struct vn_cs_encoder *enc)
static void
vn_cs_encoder_gc_buffers(struct vn_cs_encoder *enc)
{
/* when the shmem pool is used, no need to cache the shmem in cs */
if (enc->storage_type == VN_CS_ENCODER_STORAGE_SHMEM_POOL) {
for (uint32_t i = 0; i < enc->buffer_count; i++) {
vn_renderer_shmem_unref(enc->instance->renderer,
enc->buffers[i].shmem);
}
enc->buffer_count = 0;
enc->total_committed_size = 0;
enc->current_buffer_size = 0;
enc->cur = NULL;
enc->end = NULL;
return;
}
/* free all but the current buffer */
assert(enc->buffer_count);
struct vn_cs_encoder_buffer *cur_buf =
@ -180,22 +197,37 @@ vn_cs_encoder_reserve_internal(struct vn_cs_encoder *enc, size_t size)
if (likely(enc->buffer_count)) {
vn_cs_encoder_commit_buffer(enc);
/* TODO better strategy to grow buffer size */
const struct vn_cs_encoder_buffer *cur_buf =
&enc->buffers[enc->buffer_count - 1];
if (cur_buf->offset)
buf_size = next_buffer_size(0, enc->current_buffer_size, size);
if (enc->storage_type == VN_CS_ENCODER_STORAGE_SHMEM_ARRAY) {
/* if the current buffer is reused from the last vn_cs_encoder_reset
* (i.e., offset != 0), do not double the size
*
* TODO better strategy to grow buffer size
*/
const struct vn_cs_encoder_buffer *cur_buf =
&enc->buffers[enc->buffer_count - 1];
if (cur_buf->offset)
buf_size = next_buffer_size(0, enc->current_buffer_size, size);
}
}
if (!buf_size) {
/* double the size */
buf_size = next_buffer_size(enc->current_buffer_size,
enc->min_buffer_size, size);
if (!buf_size)
return false;
}
struct vn_renderer_shmem *shmem =
vn_renderer_shmem_create(enc->instance->renderer, buf_size);
struct vn_renderer_shmem *shmem;
size_t buf_offset;
if (enc->storage_type == VN_CS_ENCODER_STORAGE_SHMEM_ARRAY) {
shmem = vn_renderer_shmem_create(enc->instance->renderer, buf_size);
buf_offset = 0;
} else {
assert(enc->storage_type == VN_CS_ENCODER_STORAGE_SHMEM_POOL);
shmem =
vn_instance_cs_shmem_alloc(enc->instance, buf_size, &buf_offset);
}
if (!shmem)
return false;
@ -206,7 +238,8 @@ vn_cs_encoder_reserve_internal(struct vn_cs_encoder *enc, size_t size)
return false;
}
vn_cs_encoder_add_buffer(enc, shmem, 0, shmem->mmap_ptr, buf_size);
vn_cs_encoder_add_buffer(enc, shmem, buf_offset,
shmem->mmap_ptr + buf_offset, buf_size);
enc->current_buffer_size = buf_size;
enc->current_buffer_roundtrip = roundtrip;

View file

@ -40,6 +40,8 @@ enum vn_cs_encoder_storage_type {
VN_CS_ENCODER_STORAGE_POINTER,
/* an array of dynamically allocated shmems */
VN_CS_ENCODER_STORAGE_SHMEM_ARRAY,
/* same as above, but shmems are suballocated from a pool */
VN_CS_ENCODER_STORAGE_SHMEM_POOL,
};
struct vn_cs_encoder_buffer {

View file

@ -711,6 +711,7 @@ vn_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
}
mtx_init(&instance->physical_device.mutex, mtx_plain);
mtx_init(&instance->cs_shmem.mutex, mtx_plain);
if (!vn_icd_supports_api_version(
instance->base.base.app_info.api_version)) {
@ -742,6 +743,9 @@ vn_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
if (result != VK_SUCCESS)
goto fail;
vn_renderer_shmem_pool_init(instance->renderer, &instance->cs_shmem.pool,
8u << 20);
VkInstanceCreateInfo local_create_info = *pCreateInfo;
local_create_info.ppEnabledExtensionNames = NULL;
local_create_info.enabledExtensionCount = 0;
@ -804,6 +808,7 @@ fail:
vn_renderer_destroy(instance->renderer, alloc);
mtx_destroy(&instance->physical_device.mutex);
mtx_destroy(&instance->cs_shmem.mutex);
vn_instance_base_fini(&instance->base);
vk_free(alloc, instance);
@ -832,6 +837,9 @@ vn_DestroyInstance(VkInstance _instance,
vn_call_vkDestroyInstance(instance, _instance, NULL);
vn_renderer_shmem_pool_fini(instance->renderer, &instance->cs_shmem.pool);
mtx_destroy(&instance->cs_shmem.mutex);
uint32_t destroy_ring_data[4];
struct vn_cs_encoder local_enc = VN_CS_ENCODER_INITIALIZER_LOCAL(
destroy_ring_data, sizeof(destroy_ring_data));

View file

@ -70,6 +70,12 @@ struct vn_instance {
uint32_t renderer_api_version;
uint32_t renderer_version;
/* for VN_CS_ENCODER_STORAGE_SHMEM_POOL */
struct {
mtx_t mutex;
struct vn_renderer_shmem_pool pool;
} cs_shmem;
struct {
mtx_t mutex;
bool initialized;
@ -152,4 +158,19 @@ vn_instance_free_command_reply(struct vn_instance *instance,
vn_renderer_shmem_unref(instance->renderer, submit->reply_shmem);
}
static inline struct vn_renderer_shmem *
vn_instance_cs_shmem_alloc(struct vn_instance *instance,
size_t size,
size_t *out_offset)
{
struct vn_renderer_shmem *shmem;
mtx_lock(&instance->cs_shmem.mutex);
shmem = vn_renderer_shmem_pool_alloc(
instance->renderer, &instance->cs_shmem.pool, size, out_offset);
mtx_unlock(&instance->cs_shmem.mutex);
return shmem;
}
#endif /* VN_INSTANCE_H */