From d6afbcb800458418c3fc2bf18b6e16f2a065db49 Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Wed, 26 Feb 2020 09:36:27 +0100 Subject: [PATCH] v3dv: implement host-side event handling functions I am not quite certain that this is the way to go though. Here, we are expecting that the GPU can set/reset the event inside a command buffer as a 1x1 pixel clear for example, however, there is still the question of how we get to implement the command buffer wait on an event, since reading the docs I haven't found any such functionality to be available. We could think of implementing this by splitting the command buffer into multiple jobs at the wait command, and then using a separate thread for job submissions that would poll the event UBO before sending it to the kernel, but that looks like a bit of a kludge. Part-of: --- src/broadcom/vulkan/v3dv_device.c | 72 ++++++++++++++++++++++++++++++++++++++ src/broadcom/vulkan/v3dv_private.h | 5 +++ 2 files changed, 77 insertions(+) diff --git a/src/broadcom/vulkan/v3dv_device.c b/src/broadcom/vulkan/v3dv_device.c index 7ba9ed7..57acb1b 100644 --- a/src/broadcom/vulkan/v3dv_device.c +++ b/src/broadcom/vulkan/v3dv_device.c @@ -1821,3 +1821,75 @@ v3dv_GetMemoryFdKHR(VkDevice _device, return VK_SUCCESS; } + +VkResult +v3dv_CreateEvent(VkDevice _device, + const VkEventCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkEvent *pEvent) +{ + V3DV_FROM_HANDLE(v3dv_device, device, _device); + struct v3dv_event *event = + vk_alloc2(&device->alloc, pAllocator, sizeof(*event), 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!event) + return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); + + event->bo = v3dv_bo_alloc(device, 4096, "Event BO"); + if (!event->bo) + goto fail_alloc; + + bool ok = v3dv_bo_map(device, event->bo, 4096); + if (!ok) + goto fail_map; + + /* Events are created in the unsignaled state */ + *((uint32_t *) event->bo->map) = 0; + *pEvent = v3dv_event_to_handle(event); + + return VK_SUCCESS; + +fail_map: + v3dv_bo_free(device, event->bo); +fail_alloc: + vk_free2(&device->alloc, pAllocator, event); + return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY); +} + +void +v3dv_DestroyEvent(VkDevice _device, + VkEvent _event, + const VkAllocationCallbacks *pAllocator) +{ + V3DV_FROM_HANDLE(v3dv_device, device, _device); + V3DV_FROM_HANDLE(v3dv_event, event, _event); + + if (!event) + return; + + v3dv_bo_free(device, event->bo); + vk_free2(&device->alloc, pAllocator, event); +} + +VkResult +v3dv_GetEventStatus(VkDevice _device, VkEvent _event) +{ + V3DV_FROM_HANDLE(v3dv_event, event, _event); + return *((uint32_t *) event->bo->map) == 1 ? VK_EVENT_SET : VK_EVENT_RESET; +} + +VkResult +v3dv_SetEvent(VkDevice _device, VkEvent _event) +{ + V3DV_FROM_HANDLE(v3dv_event, event, _event); + *((uint32_t *) event->bo->map) = 1; + return VK_SUCCESS; +} + +VkResult +v3dv_ResetEvent(VkDevice _device, VkEvent _event) +{ + V3DV_FROM_HANDLE(v3dv_event, event, _event); + *((uint32_t *) event->bo->map) = 0; + return VK_SUCCESS; +} diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index 1eb6de4..943c4e0 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -655,6 +655,10 @@ struct v3dv_fence { int32_t fd; }; +struct v3dv_event { + struct v3dv_bo *bo; +}; + struct v3dv_shader_module { unsigned char sha1[20]; uint32_t size; @@ -1019,6 +1023,7 @@ V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_device_memory, VkDeviceMemory) V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_descriptor_pool, VkDescriptorPool) V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_descriptor_set, VkDescriptorSet) V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_descriptor_set_layout, VkDescriptorSetLayout) +V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_event, VkEvent) V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_fence, VkFence) V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_framebuffer, VkFramebuffer) V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_image, VkImage) -- 2.7.4