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;
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 =
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;
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;
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 {
}
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)) {
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;
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);
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));
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;
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 */