diff --git a/src/virtio/vulkan/vn_device_memory.c b/src/virtio/vulkan/vn_device_memory.c index f61f753fc86..e94f7e34e2c 100644 --- a/src/virtio/vulkan/vn_device_memory.c +++ b/src/virtio/vulkan/vn_device_memory.c @@ -73,7 +73,7 @@ vn_device_memory_wait_alloc(struct vn_device *dev, uint32_t local_data[8]; struct vn_cs_encoder local_enc = VN_CS_ENCODER_INITIALIZER_LOCAL(local_data, sizeof(local_data)); - vn_encode_vkWaitRingSeqnoMESA(&local_enc, 0, dev->instance->ring.id, + vn_encode_vkWaitRingSeqnoMESA(&local_enc, 0, dev->instance->ring.ring->id, mem->bo_ring_seqno); return vn_renderer_submit_simple(dev->renderer, local_data, vn_cs_encoder_get_len(&local_enc)); diff --git a/src/virtio/vulkan/vn_instance.c b/src/virtio/vulkan/vn_instance.c index 87e44086f64..191a0122ab9 100644 --- a/src/virtio/vulkan/vn_instance.c +++ b/src/virtio/vulkan/vn_instance.c @@ -116,19 +116,15 @@ vn_instance_fini_ring(struct vn_instance *instance) { mtx_destroy(&instance->ring.roundtrip_mutex); - vn_cs_encoder_fini(&instance->ring.upload); - uint32_t destroy_ring_data[4]; struct vn_cs_encoder local_enc = VN_CS_ENCODER_INITIALIZER_LOCAL( destroy_ring_data, sizeof(destroy_ring_data)); - vn_encode_vkDestroyRingMESA(&local_enc, 0, instance->ring.id); + vn_encode_vkDestroyRingMESA(&local_enc, 0, instance->ring.ring->id); vn_renderer_submit_simple(instance->renderer, destroy_ring_data, vn_cs_encoder_get_len(&local_enc)); vn_watchdog_fini(&instance->ring.watchdog); - mtx_destroy(&instance->ring.mutex); - vn_ring_destroy(instance->ring.ring); } @@ -144,10 +140,6 @@ vn_instance_init_ring(struct vn_instance *instance) if (!instance->ring.ring) return VK_ERROR_OUT_OF_HOST_MEMORY; - instance->ring.id = (uintptr_t)instance->ring.ring; - - mtx_init(&instance->ring.mutex, mtx_plain); - vn_watchdog_init(&instance->ring.watchdog); const struct VkRingMonitorInfoMESA monitor_info = { @@ -172,13 +164,10 @@ vn_instance_init_ring(struct vn_instance *instance) uint32_t create_ring_data[64]; struct vn_cs_encoder local_enc = VN_CS_ENCODER_INITIALIZER_LOCAL( create_ring_data, sizeof(create_ring_data)); - vn_encode_vkCreateRingMESA(&local_enc, 0, instance->ring.id, &info); + vn_encode_vkCreateRingMESA(&local_enc, 0, instance->ring.ring->id, &info); vn_renderer_submit_simple(instance->renderer, create_ring_data, vn_cs_encoder_get_len(&local_enc)); - vn_cs_encoder_init(&instance->ring.upload, instance, - VN_CS_ENCODER_STORAGE_SHMEM_ARRAY, 1 * 1024 * 1024); - mtx_init(&instance->ring.roundtrip_mutex, mtx_plain); instance->ring.roundtrip_next = 1; @@ -264,8 +253,8 @@ vn_instance_submit_roundtrip(struct vn_instance *instance, mtx_lock(&instance->ring.roundtrip_mutex); const uint64_t seqno = instance->ring.roundtrip_next++; - vn_encode_vkSubmitVirtqueueSeqnoMESA(&local_enc, 0, instance->ring.id, - seqno); + vn_encode_vkSubmitVirtqueueSeqnoMESA(&local_enc, 0, + instance->ring.ring->id, seqno); VkResult result = vn_renderer_submit_simple( instance->renderer, local_data, vn_cs_encoder_get_len(&local_enc)); mtx_unlock(&instance->ring.roundtrip_mutex); @@ -417,7 +406,7 @@ vn_instance_ring_cs_upload_locked(struct vn_instance *instance, const size_t cs_size = cs->total_committed_size; assert(cs_size == vn_cs_encoder_get_len(cs)); - struct vn_cs_encoder *upload = &instance->ring.upload; + struct vn_cs_encoder *upload = &instance->ring.ring->upload; vn_cs_encoder_reset(upload); if (!vn_cs_encoder_reserve(upload, cs_size)) @@ -457,7 +446,8 @@ vn_instance_ring_submit_locked(struct vn_instance *instance, uint32_t notify_ring_data[8]; struct vn_cs_encoder local_enc = VN_CS_ENCODER_INITIALIZER_LOCAL( notify_ring_data, sizeof(notify_ring_data)); - vn_encode_vkNotifyRingMESA(&local_enc, 0, instance->ring.id, seqno, 0); + vn_encode_vkNotifyRingMESA(&local_enc, 0, instance->ring.ring->id, + seqno, 0); vn_renderer_submit_simple(instance->renderer, notify_ring_data, vn_cs_encoder_get_len(&local_enc)); } @@ -474,9 +464,9 @@ VkResult vn_instance_ring_submit(struct vn_instance *instance, const struct vn_cs_encoder *cs) { - mtx_lock(&instance->ring.mutex); + mtx_lock(&instance->ring.ring->mutex); VkResult result = vn_instance_ring_submit_locked(instance, cs, NULL, NULL); - mtx_unlock(&instance->ring.mutex); + mtx_unlock(&instance->ring.ring->mutex); return result; } @@ -518,7 +508,7 @@ vn_instance_submit_command(struct vn_instance *instance, return; } - mtx_lock(&instance->ring.mutex); + mtx_lock(&instance->ring.ring->mutex); if (submit->reply_size) { vn_instance_set_reply_shmem_locked(instance, submit->reply_shmem, reply_offset, submit->reply_size); @@ -527,7 +517,7 @@ vn_instance_submit_command(struct vn_instance *instance, VK_SUCCESS == vn_instance_ring_submit_locked(instance, &submit->command, submit->reply_shmem, &submit->ring_seqno); - mtx_unlock(&instance->ring.mutex); + mtx_unlock(&instance->ring.ring->mutex); if (submit->reply_size) { void *reply_ptr = submit->reply_shmem->mmap_ptr + reply_offset; diff --git a/src/virtio/vulkan/vn_instance.h b/src/virtio/vulkan/vn_instance.h index e1ab750e11a..64aaff069da 100644 --- a/src/virtio/vulkan/vn_instance.h +++ b/src/virtio/vulkan/vn_instance.h @@ -50,10 +50,6 @@ struct vn_instance { struct { struct vn_ring *ring; - uint64_t id; - mtx_t mutex; - - struct vn_cs_encoder upload; /* to synchronize renderer/ring */ mtx_t roundtrip_mutex; diff --git a/src/virtio/vulkan/vn_queue.c b/src/virtio/vulkan/vn_queue.c index e1136660f8b..fc7007d841a 100644 --- a/src/virtio/vulkan/vn_queue.c +++ b/src/virtio/vulkan/vn_queue.c @@ -1044,7 +1044,7 @@ vn_queue_wsi_present(struct vn_queue_submission *submit) struct vn_cs_encoder local_enc = VN_CS_ENCODER_INITIALIZER_LOCAL(local_data, sizeof(local_data)); if (submit->external_payload.ring_seqno_valid) { - vn_encode_vkWaitRingSeqnoMESA(&local_enc, 0, instance->ring.id, + vn_encode_vkWaitRingSeqnoMESA(&local_enc, 0, instance->ring.ring->id, submit->external_payload.ring_seqno); batch.cs_data = local_data; batch.cs_size = vn_cs_encoder_get_len(&local_enc); @@ -1832,7 +1832,8 @@ vn_create_sync_file(struct vn_device *dev, struct vn_cs_encoder local_enc = VN_CS_ENCODER_INITIALIZER_LOCAL(local_data, sizeof(local_data)); if (external_payload->ring_seqno_valid) { - vn_encode_vkWaitRingSeqnoMESA(&local_enc, 0, dev->instance->ring.id, + vn_encode_vkWaitRingSeqnoMESA(&local_enc, 0, + dev->instance->ring.ring->id, external_payload->ring_seqno); batch.cs_data = local_data; batch.cs_size = vn_cs_encoder_get_len(&local_enc); diff --git a/src/virtio/vulkan/vn_ring.c b/src/virtio/vulkan/vn_ring.c index 84c60d83f28..f7129539110 100644 --- a/src/virtio/vulkan/vn_ring.c +++ b/src/virtio/vulkan/vn_ring.c @@ -194,6 +194,8 @@ vn_ring_create(struct vn_instance *instance, if (!ring) return NULL; + ring->id = (uintptr_t)ring; + ring->instance = instance; ring->shmem = vn_renderer_shmem_create(instance->renderer, layout->shmem_size); if (!ring->shmem) { @@ -206,8 +208,6 @@ vn_ring_create(struct vn_instance *instance, void *shared = ring->shmem->mmap_ptr; memset(shared, 0, layout->shmem_size); - ring->instance = instance; - assert(layout->buffer_size && util_is_power_of_two_or_zero(layout->buffer_size)); ring->buffer_size = layout->buffer_size; @@ -219,6 +219,11 @@ vn_ring_create(struct vn_instance *instance, ring->shared.buffer = shared + layout->buffer_offset; ring->shared.extra = shared + layout->extra_offset; + mtx_init(&ring->mutex, mtx_plain); + + vn_cs_encoder_init(&ring->upload, instance, + VN_CS_ENCODER_STORAGE_SHMEM_ARRAY, 1 * 1024 * 1024); + list_inithead(&ring->submits); list_inithead(&ring->free_submits); @@ -239,6 +244,10 @@ vn_ring_destroy(struct vn_ring *ring) &ring->free_submits, head) vk_free(alloc, submit); + vn_cs_encoder_fini(&ring->upload); + + mtx_destroy(&ring->mutex); + vk_free(alloc, ring); } diff --git a/src/virtio/vulkan/vn_ring.h b/src/virtio/vulkan/vn_ring.h index 86b2542edf5..6faf466c59a 100644 --- a/src/virtio/vulkan/vn_ring.h +++ b/src/virtio/vulkan/vn_ring.h @@ -8,6 +8,8 @@ #include "vn_common.h" +#include "vn_cs.h" + /** * A ring is a single-producer and single-consumer circular buffer. The data * in the buffer are produced and consumed in order. An externally-defined @@ -60,6 +62,7 @@ struct vn_ring_submit { }; struct vn_ring { + uint64_t id; struct vn_instance *instance; struct vn_renderer_shmem *shmem; @@ -69,6 +72,15 @@ struct vn_ring { struct vn_ring_shared shared; uint32_t cur; + /* This mutex ensures below: + * - atomic of ring submission + * - reply shmem resource set and ring submission are paired + */ + mtx_t mutex; + + /* used for indirect submission of large command (non-VkCommandBuffer) */ + struct vn_cs_encoder upload; + struct list_head submits; struct list_head free_submits; };