venus: move the rest ring belongings into ring
This change only moves the fields without changing the accessors. It's better to let ring own its own upload cs encoder (which is backed by shmem array) to avoid lock contention between indirect submissions across rings. Signed-off-by: Yiwei Zhang <zzyiwei@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26179>
This commit is contained in:
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user