diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-05-10 07:06:44 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-05-10 07:06:44 +0000 |
commit | 00d361e7138fec6beeed6a18968d1aecf40e2b86 (patch) | |
tree | 053d3acaad91c69e7ad71b460a591612de7d19c3 /src/venus/vkr_ring.h | |
parent | 6f2f2cb306e21b32e9fe759dd206a5e2a2b312c0 (diff) | |
parent | 95be3cd08d582499c402ff79db4d4093b1b8c780 (diff) | |
download | virglrenderer-00d361e7138fec6beeed6a18968d1aecf40e2b86.tar.gz |
Snap for 8564071 from 95be3cd08d582499c402ff79db4d4093b1b8c780 to mainline-sdkext-releaseaml_sdk_331812000aml_sdk_331811100aml_sdk_331811000aml_sdk_331412000aml_sdk_331410000aml_sdk_331310010aml_sdk_331111000aml_sdk_330810050aml_sdk_330810010android13-mainline-sdkext-release
Change-Id: I129b4e72d8b841253c02fc27ce45a85631227ffe
Diffstat (limited to 'src/venus/vkr_ring.h')
-rw-r--r-- | src/venus/vkr_ring.h | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/src/venus/vkr_ring.h b/src/venus/vkr_ring.h new file mode 100644 index 00000000..8dc83bb5 --- /dev/null +++ b/src/venus/vkr_ring.h @@ -0,0 +1,126 @@ +/* + * Copyright 2021 Google LLC + * SPDX-License-Identifier: MIT + */ + +#ifndef VKR_RING_H +#define VKR_RING_H + +#include "vkr_common.h" + +/* We read from the ring buffer to a temporary buffer for + * virgl_context::submit_cmd. Until that is changed, we want to put a limit + * on the size of the temporary buffer. It also makes no sense to have huge + * rings. + * + * This must not exceed UINT32_MAX because the ring head and tail are 32-bit. + */ +#define VKR_RING_BUFFER_MAX_SIZE (16u * 1024 * 1024) + +/* The layout of a ring in a virgl_resource. This is parsed and discarded by + * vkr_ring_create. + */ +struct vkr_ring_layout { + struct virgl_resource *resource; + + struct vkr_region head; + struct vkr_region tail; + struct vkr_region status; + struct vkr_region buffer; + struct vkr_region extra; +}; + +static_assert(ATOMIC_INT_LOCK_FREE == 2 && sizeof(atomic_uint) == 4, + "vkr_ring_control requires lock-free 32-bit atomic_uint"); + +/* the control region of a ring */ +struct vkr_ring_control { + /* Pointers to ring head, tail, and status. + * + * Clients increment the tail after commands are added. We increment the + * head after commands are executed. The status is updated when there is a + * status change to the ring thread. + */ + volatile atomic_uint *head; + const volatile atomic_uint *tail; + volatile atomic_uint *status; +}; + +/* the buffer region of a ring */ +struct vkr_ring_buffer { + /* the base of the region in the resource */ + int base_iov_index; + size_t base_iov_offset; + + uint32_t size; + uint32_t mask; + + /* The current offset in the buffer region. It is free-running and must be + * masked to be between [0, size). + */ + uint32_t cur; + + /* The current iov and iov offset in the resource. */ + const struct iovec *cur_iov; + int cur_iov_index; + size_t cur_iov_offset; +}; + +/* 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 { + /* used by the caller */ + vkr_object_id id; + struct list_head head; + + /* ring regions */ + struct virgl_resource *resource; + struct vkr_ring_control control; + struct vkr_ring_buffer buffer; + struct vkr_ring_extra extra; + + /* ring thread */ + struct virgl_context *context; + uint64_t idle_timeout; + void *cmd; + + mtx_t mutex; + cnd_t cond; + thrd_t thread; + atomic_bool started; + atomic_bool pending_notify; +}; + +struct vkr_ring * +vkr_ring_create(const struct vkr_ring_layout *layout, + struct virgl_context *ctx, + uint64_t idle_timeout); + +void +vkr_ring_destroy(struct vkr_ring *ring); + +void +vkr_ring_start(struct vkr_ring *ring); + +bool +vkr_ring_stop(struct vkr_ring *ring); + +void +vkr_ring_notify(struct vkr_ring *ring); + +bool +vkr_ring_write_extra(struct vkr_ring *ring, size_t offset, uint32_t val); + +#endif /* VKR_RING_H */ |