device->events.descriptor_set_layout = VK_NULL_HANDLE;
}
+static void
+init_event(struct v3dv_device *device, struct v3dv_event *event, uint32_t index)
+{
+ vk_object_base_init(&device->vk, &event->base, VK_OBJECT_TYPE_EVENT);
+ event->index = index;
+ list_addtail(&event->link, &device->events.free_list);
+}
+
VkResult
v3dv_event_allocate_resources(struct v3dv_device *device)
{
goto fail;
}
- /* List of free event state slots in the BO, 1 byte per slot */
- device->events.desc_count = bo_size;
- device->events.desc =
- vk_alloc2(&device->vk.alloc, NULL,
- device->events.desc_count * sizeof(struct v3dv_event_desc), 8,
- VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
- if (!device->events.desc) {
+ /* Pre-allocate our events, each event requires 1 byte of BO storage */
+ device->events.event_count = bo_size;
+ device->events.events =
+ vk_zalloc2(&device->vk.alloc, NULL,
+ device->events.event_count * sizeof(struct v3dv_event), 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
+ if (!device->events.events) {
result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
goto fail;
}
list_inithead(&device->events.free_list);
- for (int i = 0; i < device->events.desc_count; i++) {
- device->events.desc[i].index = i;
- list_addtail(&device->events.desc[i].link, &device->events.free_list);
- }
+ for (int i = 0; i < device->events.event_count; i++)
+ init_event(device, &device->events.events[i], i);
/* Vulkan buffer for the event state BO */
VkBufferCreateInfo buf_info = {
device->events.bo = NULL;
}
- if (device->events.desc) {
- vk_free2(&device->vk.alloc, NULL, device->events.desc);
- device->events.desc = NULL;
+ if (device->events.events) {
+ vk_free2(&device->vk.alloc, NULL, device->events.events);
+ device->events.events = NULL;
}
if (device->events.mem) {
destroy_event_pipelines(device);
}
-static struct v3dv_event_desc *
-allocate_event_descriptor(struct v3dv_device *device)
+static struct v3dv_event *
+allocate_event(struct v3dv_device *device)
{
mtx_lock(&device->events.lock);
if (list_is_empty(&device->events.free_list)) {
return NULL;
}
- struct v3dv_event_desc *desc =
- list_first_entry(&device->events.free_list, struct v3dv_event_desc, link);
- list_del(&desc->link);
+ struct v3dv_event *event =
+ list_first_entry(&device->events.free_list, struct v3dv_event, link);
+ list_del(&event->link);
mtx_unlock(&device->events.lock);
- return desc;
+ return event;
}
static void
-free_event_descriptor(struct v3dv_device *device, uint32_t index)
+free_event(struct v3dv_device *device, uint32_t index)
{
+ assert(index < device->events.event_count);
mtx_lock(&device->events.lock);
- assert(index < device->events.desc_count);
- list_addtail(&device->events.desc[index].link, &device->events.free_list);
+ list_addtail(&device->events.events[index].link, &device->events.free_list);
mtx_unlock(&device->events.lock);
}
V3DV_FROM_HANDLE(v3dv_device, device, _device);
VkResult result = VK_SUCCESS;
- struct v3dv_event *event =
- vk_object_zalloc(&device->vk, pAllocator, sizeof(*event),
- VK_OBJECT_TYPE_EVENT);
+ struct v3dv_event *event = allocate_event(device);
if (!event) {
- result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
- goto fail;
- }
-
- struct v3dv_event_desc *desc = allocate_event_descriptor(device);
- if (!desc) {
result = vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
goto fail;
}
- event->index = desc->index;
event_set_value(device, event, 0);
*pEvent = v3dv_event_to_handle(event);
return VK_SUCCESS;
if (!event)
return;
- free_event_descriptor(device, event->index);
- vk_object_free(&device->vk, pAllocator, event);
+ free_event(device, event->index);
}
VKAPI_ATTR VkResult VKAPI_CALL
device->events.pipeline_layout,
0, 1, &device->events.descriptor_set, 0, NULL);
- assert(event->index < device->events.desc_count);
+ assert(event->index < device->events.event_count);
uint32_t offset = event->index;
v3dv_CmdPushConstants(commandBuffer,
device->events.pipeline_layout,
device->events.pipeline_layout,
0, 1, &device->events.descriptor_set, 0, NULL);
- assert(event->index < device->events.desc_count);
+ assert(event->index < device->events.event_count);
uint32_t offset = event->index;
v3dv_CmdPushConstants(commandBuffer,
device->events.pipeline_layout,
bool externally_synchronized;
};
-/* This is used to implement a list of free events in the BO we use
- * hold event states. The index here is used to calculate the offset
- * within that BO.
- */
-struct v3dv_event_desc {
- struct list_head link;
- uint32_t index;
-};
-
struct v3dv_device {
struct vk_device vk;
/* BO for the event states: signaled (1) or reset (0) */
struct v3dv_bo *bo;
- /* Events can be created and destroyed. Since we have a dedicated BO for
- * all events we use, we need to keep track of the free slots within that
- * BO. For that we use a free list where we link together available event
- * slots in the form of "descriptors" that include an index (which is
- * basically an offset into the BO that is available).
+ /* We pre-allocate all the events we can fit for the size of the BO we
+ * create to track their states, where each event has an index which is
+ * basically the offset of its state in that BO. We keep a free list with
+ * the pre-allocated events that are available.
*/
- uint32_t desc_count;
- struct v3dv_event_desc *desc;
+ uint32_t event_count;
+ struct v3dv_event *events;
struct list_head free_list;
/* Vulkan resources to access the event BO from shaders. We have a
struct v3dv_event {
struct vk_object_base base;
+ /* Link in the device list of pre-allocated free events */
+ struct list_head link;
+
/* Each event gets a different index, which we use to compute the offset
* in the BO we use to track their state (signaled vs reset).
*/