venus: rework vn_instance_submission

The goal is to remove local_cs_data.  To that end, vn_ring_submit is
modified to take a cs than a pointer.

Signed-off-by: Chia-I Wu <olvaffe@gmail.com>
Reviewed-by: Yiwei Zhang <zzyiwei@chromium.org>
Reviewed-by: Ryan Neph <ryanneph@google.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12568>
This commit is contained in:
Chia-I Wu 2021-08-30 09:44:29 -07:00 committed by Marge Bot
parent 862244ccc6
commit eb88c8e1d4
3 changed files with 52 additions and 67 deletions

View File

@ -19,6 +19,8 @@
#include "vn_physical_device.h" #include "vn_physical_device.h"
#include "vn_renderer.h" #include "vn_renderer.h"
#define VN_INSTANCE_RING_DIRECT_THRESHOLD (256)
/* /*
* Instance extensions add instance-level or physical-device-level * Instance extensions add instance-level or physical-device-level
* functionalities. It seems renderer support is either unnecessary or * functionalities. It seems renderer support is either unnecessary or
@ -322,18 +324,24 @@ vn_instance_wait_roundtrip(struct vn_instance *instance,
} }
struct vn_instance_submission { struct vn_instance_submission {
uint32_t local_cs_data[64]; const struct vn_cs_encoder *cs;
void *cs_data;
size_t cs_size;
struct vn_ring_submit *submit; struct vn_ring_submit *submit;
struct {
struct vn_cs_encoder cs;
struct vn_cs_encoder_buffer buffer;
uint32_t data[64];
} indirect;
}; };
static void * static const struct vn_cs_encoder *
vn_instance_submission_indirect_cs(struct vn_instance_submission *submit, vn_instance_submission_get_cs(struct vn_instance_submission *submit,
const struct vn_cs_encoder *cs, const struct vn_cs_encoder *cs,
size_t *cs_size) bool direct)
{ {
if (direct)
return cs;
VkCommandStreamDescriptionMESA local_descs[8]; VkCommandStreamDescriptionMESA local_descs[8];
VkCommandStreamDescriptionMESA *descs = local_descs; VkCommandStreamDescriptionMESA *descs = local_descs;
if (cs->buffer_count > ARRAY_SIZE(local_descs)) { if (cs->buffer_count > ARRAY_SIZE(local_descs)) {
@ -357,47 +365,27 @@ vn_instance_submission_indirect_cs(struct vn_instance_submission *submit,
const size_t exec_size = vn_sizeof_vkExecuteCommandStreamsMESA( const size_t exec_size = vn_sizeof_vkExecuteCommandStreamsMESA(
desc_count, descs, NULL, 0, NULL, 0); desc_count, descs, NULL, 0, NULL, 0);
void *exec_data = submit->local_cs_data; void *exec_data = submit->indirect.data;
if (exec_size > sizeof(submit->local_cs_data)) { if (exec_size > sizeof(submit->indirect.data)) {
exec_data = malloc(exec_size); exec_data = malloc(exec_size);
if (!exec_data) if (!exec_data) {
goto out; if (descs != local_descs)
free(descs);
return NULL;
}
} }
struct vn_cs_encoder local_enc = submit->indirect.buffer = VN_CS_ENCODER_BUFFER_INITIALIZER(exec_data);
VN_CS_ENCODER_INITIALIZER_LOCAL(exec_data, exec_size); submit->indirect.cs =
vn_encode_vkExecuteCommandStreamsMESA(&local_enc, 0, desc_count, descs, VN_CS_ENCODER_INITIALIZER(&submit->indirect.buffer, exec_size);
NULL, 0, NULL, 0); vn_encode_vkExecuteCommandStreamsMESA(&submit->indirect.cs, 0, desc_count,
descs, NULL, 0, NULL, 0);
vn_cs_encoder_commit(&submit->indirect.cs);
*cs_size = vn_cs_encoder_get_len(&local_enc);
out:
if (descs != local_descs) if (descs != local_descs)
free(descs); free(descs);
return exec_data; return &submit->indirect.cs;
}
static void *
vn_instance_submission_direct_cs(struct vn_instance_submission *submit,
const struct vn_cs_encoder *cs,
size_t *cs_size)
{
if (cs->buffer_count == 1) {
*cs_size = cs->buffers[0].committed_size;
return cs->buffers[0].base;
}
assert(vn_cs_encoder_get_len(cs) <= sizeof(submit->local_cs_data));
void *dst = submit->local_cs_data;
for (uint32_t i = 0; i < cs->buffer_count; i++) {
const struct vn_cs_encoder_buffer *buf = &cs->buffers[i];
memcpy(dst, buf->base, buf->committed_size);
dst += buf->committed_size;
}
*cs_size = dst - (void *)submit->local_cs_data;
return submit->local_cs_data;
} }
static struct vn_ring_submit * static struct vn_ring_submit *
@ -428,12 +416,11 @@ vn_instance_submission_get_ring_submit(struct vn_ring *ring,
} }
static void static void
vn_instance_submission_cleanup(struct vn_instance_submission *submit, vn_instance_submission_cleanup(struct vn_instance_submission *submit)
const struct vn_cs_encoder *cs)
{ {
if (submit->cs_data != submit->local_cs_data && if (submit->cs == &submit->indirect.cs &&
submit->cs_data != cs->buffers[0].base) submit->indirect.buffer.base != submit->indirect.data)
free(submit->cs_data); free(submit->indirect.buffer.base);
} }
static VkResult static VkResult
@ -443,20 +430,14 @@ vn_instance_submission_prepare(struct vn_instance_submission *submit,
struct vn_renderer_shmem *extra_shmem, struct vn_renderer_shmem *extra_shmem,
bool direct) bool direct)
{ {
if (direct) { submit->cs = vn_instance_submission_get_cs(submit, cs, direct);
submit->cs_data = if (!submit->cs)
vn_instance_submission_direct_cs(submit, cs, &submit->cs_size);
} else {
submit->cs_data =
vn_instance_submission_indirect_cs(submit, cs, &submit->cs_size);
}
if (!submit->cs_data)
return VK_ERROR_OUT_OF_HOST_MEMORY; return VK_ERROR_OUT_OF_HOST_MEMORY;
submit->submit = submit->submit =
vn_instance_submission_get_ring_submit(ring, cs, extra_shmem, direct); vn_instance_submission_get_ring_submit(ring, cs, extra_shmem, direct);
if (!submit->submit) { if (!submit->submit) {
vn_instance_submission_cleanup(submit, cs); vn_instance_submission_cleanup(submit);
return VK_ERROR_OUT_OF_HOST_MEMORY; return VK_ERROR_OUT_OF_HOST_MEMORY;
} }
@ -466,8 +447,7 @@ vn_instance_submission_prepare(struct vn_instance_submission *submit,
static bool static bool
vn_instance_submission_can_direct(const struct vn_cs_encoder *cs) vn_instance_submission_can_direct(const struct vn_cs_encoder *cs)
{ {
struct vn_instance_submission submit; return vn_cs_encoder_get_len(cs) <= VN_INSTANCE_RING_DIRECT_THRESHOLD;
return vn_cs_encoder_get_len(cs) <= sizeof(submit.local_cs_data);
} }
static struct vn_cs_encoder * static struct vn_cs_encoder *
@ -515,8 +495,7 @@ vn_instance_ring_submit_locked(struct vn_instance *instance,
return result; return result;
uint32_t seqno; uint32_t seqno;
const bool notify = vn_ring_submit(ring, submit.submit, submit.cs_data, const bool notify = vn_ring_submit(ring, submit.submit, submit.cs, &seqno);
submit.cs_size, &seqno);
if (notify) { if (notify) {
uint32_t notify_ring_data[8]; uint32_t notify_ring_data[8];
struct vn_cs_encoder local_enc = VN_CS_ENCODER_INITIALIZER_LOCAL( struct vn_cs_encoder local_enc = VN_CS_ENCODER_INITIALIZER_LOCAL(
@ -526,7 +505,7 @@ vn_instance_ring_submit_locked(struct vn_instance *instance,
vn_cs_encoder_get_len(&local_enc)); vn_cs_encoder_get_len(&local_enc));
} }
vn_instance_submission_cleanup(&submit, cs); vn_instance_submission_cleanup(&submit);
if (ring_seqno) if (ring_seqno)
*ring_seqno = seqno; *ring_seqno = seqno;

View File

@ -5,6 +5,7 @@
#include "vn_ring.h" #include "vn_ring.h"
#include "vn_cs.h"
#include "vn_renderer.h" #include "vn_renderer.h"
/* must be power-of-two */ /* must be power-of-two */
@ -203,12 +204,18 @@ vn_ring_get_submit(struct vn_ring *ring, uint32_t shmem_count)
bool bool
vn_ring_submit(struct vn_ring *ring, vn_ring_submit(struct vn_ring *ring,
struct vn_ring_submit *submit, struct vn_ring_submit *submit,
const void *cs_data, const struct vn_cs_encoder *cs,
uint32_t cs_size,
uint32_t *seqno) uint32_t *seqno)
{ {
const uint32_t cur_seqno = vn_ring_wait_space(ring, cs_size); /* write cs to the ring */
vn_ring_write_buffer(ring, cs_data, cs_size); assert(!vn_cs_encoder_is_empty(cs));
uint32_t cur_seqno;
for (uint32_t i = 0; i < cs->buffer_count; i++) {
const struct vn_cs_encoder_buffer *buf = &cs->buffers[i];
cur_seqno = vn_ring_wait_space(ring, buf->committed_size);
vn_ring_write_buffer(ring, buf->base, buf->committed_size);
}
vn_ring_store_tail(ring); vn_ring_store_tail(ring);
const bool notify = vn_ring_load_status(ring) & VN_RING_STATUS_IDLE; const bool notify = vn_ring_load_status(ring) & VN_RING_STATUS_IDLE;

View File

@ -87,8 +87,7 @@ vn_ring_get_submit(struct vn_ring *ring, uint32_t shmem_count);
bool bool
vn_ring_submit(struct vn_ring *ring, vn_ring_submit(struct vn_ring *ring,
struct vn_ring_submit *submit, struct vn_ring_submit *submit,
const void *cs_data, const struct vn_cs_encoder *cs,
uint32_t cs_size,
uint32_t *seqno); uint32_t *seqno);
void void