vkr: introduce vkr_ring_extra

It is used to access the extra region, with iov support.

Signed-off-by: Chia-I Wu <olvaffe@gmail.com>
Reviewed-by: Ryan Neph <ryanneph@google.com>
Reviewed-by: Yiwei Zhang <zzyiwei@chromium.org>
macos/master
Chia-I Wu 3 years ago
parent b06ee74b6c
commit 75a64ef28f
  1. 37
      src/venus/vkr_ring.c
  2. 21
      src/venus/vkr_ring.h

@ -45,6 +45,17 @@ get_resource_pointer(const struct virgl_resource *res, int base_iov_index, size_
return (uint8_t *)iov->iov_base + offset;
}
static void
vkr_ring_init_extra(struct vkr_ring *ring, const struct vkr_ring_layout *layout)
{
struct vkr_ring_extra *extra = &ring->extra;
seek_resource(layout->resource, 0, layout->extra.begin, &extra->base_iov_index,
&extra->base_iov_offset);
extra->region = vkr_region_make_relative(&layout->extra);
}
static void
vkr_ring_init_buffer(struct vkr_ring *ring, const struct vkr_ring_layout *layout)
{
@ -138,14 +149,7 @@ vkr_ring_create(const struct vkr_ring_layout *layout,
}
vkr_ring_init_buffer(ring, layout);
uint8_t *shared = layout->resource->iov[0].iov_base;
#define ring_attach_shared(member) \
ring->shared.member = (void *)(shared + layout->member.begin)
ring_attach_shared(extra);
#undef ring_attach_shared
ring->extra_size = vkr_region_size(&layout->extra);
vkr_ring_init_extra(ring, layout);
ring->cmd = malloc(ring->buffer.size);
if (!ring->cmd) {
@ -323,11 +327,20 @@ vkr_ring_notify(struct vkr_ring *ring)
bool
vkr_ring_write_extra(struct vkr_ring *ring, size_t offset, uint32_t val)
{
if (offset > ring->extra_size || sizeof(val) > ring->extra_size - offset)
return false;
struct vkr_ring_extra *extra = &ring->extra;
if (unlikely(extra->cached_offset != offset || !extra->cached_data)) {
const struct vkr_region access = VKR_REGION_INIT(offset, sizeof(val));
if (!vkr_region_is_valid(&access) || !vkr_region_is_within(&access, &extra->region))
return false;
/* Mesa always sets offset to 0 and the cache hit rate will be 100% */
extra->cached_offset = offset;
extra->cached_data = get_resource_pointer(ring->resource, extra->base_iov_index,
extra->base_iov_offset + offset);
}
volatile atomic_uint *dst = (void *)((uint8_t *)ring->shared.extra + offset);
atomic_store_explicit(dst, val, memory_order_release);
atomic_store_explicit(extra->cached_data, val, memory_order_release);
{
TRACE_SCOPE("ring extra done");

@ -50,8 +50,18 @@ struct vkr_ring_buffer {
const uint8_t *data;
};
struct vkr_ring_shared {
void *extra;
/* the extra region of a ring */
struct vkr_ring_extra {
/* the base of the region in the resource */
int base_iov_index;
size_t base_iov_offset;
/* used for offset validation */
struct vkr_region region;
/* cache the latest offset->pointer result */
size_t cached_offset;
volatile atomic_uint *cached_data;
};
struct vkr_ring {
@ -63,15 +73,12 @@ struct vkr_ring {
struct virgl_resource *resource;
struct vkr_ring_control control;
struct vkr_ring_buffer buffer;
struct vkr_ring_shared shared;
void *cmd;
size_t extra_size;
struct vkr_ring_extra extra;
/* ring thread */
struct virgl_context *context;
uint64_t idle_timeout;
void *cmd;
mtx_t mutex;
cnd_t cond;

Loading…
Cancel
Save