From c4802bc44c0625fd3bb8b7da7068ce5673ce3d1e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg=20Kristensen?= Date: Sat, 19 Dec 2015 22:17:19 -0800 Subject: [PATCH] vk/gen8: Implement VkEvent for gen8 We use PIPE_CONTROL for setting and resetting the event from cmd buffers and MI_SEMAPHORE_WAIT in polling mode for waiting on an event. --- src/vulkan/anv_cmd_buffer.c | 28 ------------ src/vulkan/anv_device.c | 82 ++++++++++++++++++++++++++++++------ src/vulkan/anv_private.h | 6 +++ src/vulkan/gen7_cmd_buffer.c | 28 ++++++++++++ src/vulkan/gen8_cmd_buffer.c | 64 ++++++++++++++++++++++++++++ 5 files changed, 166 insertions(+), 42 deletions(-) diff --git a/src/vulkan/anv_cmd_buffer.c b/src/vulkan/anv_cmd_buffer.c index bfe06591d6d..9b54dee96bc 100644 --- a/src/vulkan/anv_cmd_buffer.c +++ b/src/vulkan/anv_cmd_buffer.c @@ -900,34 +900,6 @@ anv_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer, } } -void anv_CmdSetEvent( - VkCommandBuffer commandBuffer, - VkEvent event, - VkPipelineStageFlags stageMask) -{ - stub(); -} - -void anv_CmdResetEvent( - VkCommandBuffer commandBuffer, - VkEvent event, - VkPipelineStageFlags stageMask) -{ - stub(); -} - -void anv_CmdWaitEvents( - VkCommandBuffer commandBuffer, - uint32_t eventCount, - const VkEvent* pEvents, - VkPipelineStageFlags srcStageMask, - VkPipelineStageFlags destStageMask, - uint32_t memBarrierCount, - const void* const* ppMemBarriers) -{ - stub(); -} - struct anv_state anv_cmd_buffer_push_constants(struct anv_cmd_buffer *cmd_buffer, gl_shader_stage stage) diff --git a/src/vulkan/anv_device.c b/src/vulkan/anv_device.c index e276cc0b9c0..746fecb760f 100644 --- a/src/vulkan/anv_device.c +++ b/src/vulkan/anv_device.c @@ -1443,41 +1443,95 @@ void anv_DestroySemaphore( // Event functions VkResult anv_CreateEvent( - VkDevice device, + VkDevice _device, const VkEventCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkEvent* pEvent) { - stub_return(VK_ERROR_INCOMPATIBLE_DRIVER); + ANV_FROM_HANDLE(anv_device, device, _device); + struct anv_state state; + struct anv_event *event; + + assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_EVENT_CREATE_INFO); + + state = anv_state_pool_alloc(&device->dynamic_state_pool, + sizeof(*event), 4); + event = state.map; + event->state = state; + event->semaphore = VK_EVENT_RESET; + + if (!device->info.has_llc) { + /* Make sure the writes we're flushing have landed. */ + __builtin_ia32_sfence(); + __builtin_ia32_clflush(event); + } + + *pEvent = anv_event_to_handle(event); + + return VK_SUCCESS; } void anv_DestroyEvent( - VkDevice device, - VkEvent event, + VkDevice _device, + VkEvent _event, const VkAllocationCallbacks* pAllocator) { - stub(); + ANV_FROM_HANDLE(anv_device, device, _device); + ANV_FROM_HANDLE(anv_event, event, _event); + + anv_state_pool_free(&device->dynamic_state_pool, event->state); } VkResult anv_GetEventStatus( - VkDevice device, - VkEvent event) + VkDevice _device, + VkEvent _event) { - stub_return(VK_ERROR_INCOMPATIBLE_DRIVER); + ANV_FROM_HANDLE(anv_device, device, _device); + ANV_FROM_HANDLE(anv_event, event, _event); + + if (!device->info.has_llc) { + /* Make sure the writes we're flushing have landed. */ + __builtin_ia32_clflush(event); + __builtin_ia32_lfence(); + } + + return event->semaphore; } VkResult anv_SetEvent( - VkDevice device, - VkEvent event) + VkDevice _device, + VkEvent _event) { - stub_return(VK_ERROR_INCOMPATIBLE_DRIVER); + ANV_FROM_HANDLE(anv_device, device, _device); + ANV_FROM_HANDLE(anv_event, event, _event); + + event->semaphore = VK_EVENT_SET; + + if (!device->info.has_llc) { + /* Make sure the writes we're flushing have landed. */ + __builtin_ia32_sfence(); + __builtin_ia32_clflush(event); + } + + return VK_SUCCESS; } VkResult anv_ResetEvent( - VkDevice device, - VkEvent event) + VkDevice _device, + VkEvent _event) { - stub_return(VK_ERROR_INCOMPATIBLE_DRIVER); + ANV_FROM_HANDLE(anv_device, device, _device); + ANV_FROM_HANDLE(anv_event, event, _event); + + event->semaphore = VK_EVENT_RESET; + + if (!device->info.has_llc) { + /* Make sure the writes we're flushing have landed. */ + __builtin_ia32_sfence(); + __builtin_ia32_clflush(event); + } + + return VK_SUCCESS; } // Buffer functions diff --git a/src/vulkan/anv_private.h b/src/vulkan/anv_private.h index a8583c98db4..b632f6e85a9 100644 --- a/src/vulkan/anv_private.h +++ b/src/vulkan/anv_private.h @@ -1208,6 +1208,11 @@ struct anv_fence { bool ready; }; +struct anv_event { + uint32_t semaphore; + struct anv_state state; +}; + struct nir_shader; struct anv_shader_module { @@ -1658,6 +1663,7 @@ ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_set, VkDescriptorSet) ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_set_layout, VkDescriptorSetLayout) ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_device_memory, VkDeviceMemory) ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_fence, VkFence) +ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_event, VkEvent) ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_framebuffer, VkFramebuffer) ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_image, VkImage) ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_image_view, VkImageView); diff --git a/src/vulkan/gen7_cmd_buffer.c b/src/vulkan/gen7_cmd_buffer.c index c31ea338e64..7fdef1027e2 100644 --- a/src/vulkan/gen7_cmd_buffer.c +++ b/src/vulkan/gen7_cmd_buffer.c @@ -856,3 +856,31 @@ void genX(CmdEndRenderPass)( .TextureCacheInvalidationEnable = true, .CommandStreamerStallEnable = true); } + +void genX(CmdSetEvent)( + VkCommandBuffer commandBuffer, + VkEvent event, + VkPipelineStageFlags stageMask) +{ + stub(); +} + +void genX(CmdResetEvent)( + VkCommandBuffer commandBuffer, + VkEvent event, + VkPipelineStageFlags stageMask) +{ + stub(); +} + +void genX(CmdWaitEvents)( + VkCommandBuffer commandBuffer, + uint32_t eventCount, + const VkEvent* pEvents, + VkPipelineStageFlags srcStageMask, + VkPipelineStageFlags destStageMask, + uint32_t memBarrierCount, + const void* const* ppMemBarriers) +{ + stub(); +} diff --git a/src/vulkan/gen8_cmd_buffer.c b/src/vulkan/gen8_cmd_buffer.c index 73d475eae0e..1a1efed670d 100644 --- a/src/vulkan/gen8_cmd_buffer.c +++ b/src/vulkan/gen8_cmd_buffer.c @@ -1035,3 +1035,67 @@ void genX(CmdCopyQueryPoolResults)( dst_offset += destStride; } } + +void genX(CmdSetEvent)( + VkCommandBuffer commandBuffer, + VkEvent _event, + VkPipelineStageFlags stageMask) +{ + ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); + ANV_FROM_HANDLE(anv_event, event, _event); + + anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), + .DestinationAddressType = DAT_PPGTT, + .PostSyncOperation = WriteImmediateData, + .Address = { + &cmd_buffer->device->dynamic_state_block_pool.bo, + event->state.offset + }, + .ImmediateData = VK_EVENT_SET); +} + +void genX(CmdResetEvent)( + VkCommandBuffer commandBuffer, + VkEvent _event, + VkPipelineStageFlags stageMask) +{ + ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); + ANV_FROM_HANDLE(anv_event, event, _event); + + anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), + .DestinationAddressType = DAT_PPGTT, + .PostSyncOperation = WriteImmediateData, + .Address = { + &cmd_buffer->device->dynamic_state_block_pool.bo, + event->state.offset + }, + .ImmediateData = VK_EVENT_RESET); +} + +void genX(CmdWaitEvents)( + VkCommandBuffer commandBuffer, + uint32_t eventCount, + const VkEvent* pEvents, + VkPipelineStageFlags srcStageMask, + VkPipelineStageFlags destStageMask, + uint32_t memBarrierCount, + const void* const* ppMemBarriers) +{ + ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); + for (uint32_t i = 0; i < eventCount; i++) { + ANV_FROM_HANDLE(anv_event, event, pEvents[i]); + + anv_batch_emit(&cmd_buffer->batch, GENX(MI_SEMAPHORE_WAIT), + .WaitMode = PollingMode, + .CompareOperation = SAD_EQUAL_SDD, + .SemaphoreDataDword = VK_EVENT_SET, + .SemaphoreAddress = { + &cmd_buffer->device->dynamic_state_block_pool.bo, + event->state.offset + }); + } + + genX(CmdPipelineBarrier)(commandBuffer, srcStageMask, destStageMask, + false, /* byRegion */ + memBarrierCount, ppMemBarriers); +} -- 2.30.2