From 72aaa83f4b5ba193cd4570da610893cd7b054332 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 1 Dec 2016 01:52:31 +0000 Subject: [PATCH] radv: add semaphore support Reviewed-by: Bas Nieuwenhuizen --- src/amd/vulkan/radv_device.c | 29 ++++++++---- src/amd/vulkan/radv_radeon_winsys.h | 9 ++++ src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c | 45 +++++++++++++++++-- 3 files changed, 72 insertions(+), 11 deletions(-) diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index fd0ef720d8b..3aac247f8ba 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -857,6 +857,10 @@ VkResult radv_QueueSubmit( } ret = queue->device->ws->cs_submit(ctx, queue->queue_idx, cs_array, pSubmits[i].commandBufferCount, + (struct radeon_winsys_sem **)pSubmits[i].pWaitSemaphores, + pSubmits[i].waitSemaphoreCount, + (struct radeon_winsys_sem **)pSubmits[i].pSignalSemaphores, + pSubmits[i].signalSemaphoreCount, can_patch, base_fence); if (ret) radv_loge("failed to submit CS %d\n", i); @@ -866,7 +870,7 @@ VkResult radv_QueueSubmit( if (fence) { if (!submitCount) ret = queue->device->ws->cs_submit(ctx, queue->queue_idx, &queue->device->empty_cs, - 1, false, base_fence); + 1, NULL, 0, NULL, 0, false, base_fence); fence->submitted = true; } @@ -1270,25 +1274,34 @@ VkResult radv_GetFenceStatus(VkDevice _device, VkFence _fence) // Queue semaphore functions VkResult radv_CreateSemaphore( - VkDevice device, + VkDevice _device, const VkSemaphoreCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSemaphore* pSemaphore) { - /* The DRM execbuffer ioctl always execute in-oder, even between different - * rings. As such, there's nothing to do for the user space semaphore. - */ + RADV_FROM_HANDLE(radv_device, device, _device); + struct radeon_winsys_sem *sem; - *pSemaphore = (VkSemaphore)1; + sem = device->ws->create_sem(device->ws); + if (!sem) + return VK_ERROR_OUT_OF_HOST_MEMORY; + *pSemaphore = (VkSemaphore)sem; return VK_SUCCESS; } void radv_DestroySemaphore( - VkDevice device, - VkSemaphore semaphore, + VkDevice _device, + VkSemaphore _semaphore, const VkAllocationCallbacks* pAllocator) { + RADV_FROM_HANDLE(radv_device, device, _device); + struct radeon_winsys_sem *sem; + if (!_semaphore) + return; + + sem = (struct radeon_winsys_sem *)_semaphore; + device->ws->destroy_sem(sem); } VkResult radv_CreateEvent( diff --git a/src/amd/vulkan/radv_radeon_winsys.h b/src/amd/vulkan/radv_radeon_winsys.h index 38cb4408ff4..4b738b8cf46 100644 --- a/src/amd/vulkan/radv_radeon_winsys.h +++ b/src/amd/vulkan/radv_radeon_winsys.h @@ -253,6 +253,7 @@ struct radeon_bo_metadata { struct radeon_winsys_bo; struct radeon_winsys_fence; +struct radeon_winsys_sem; struct radeon_winsys { void (*destroy)(struct radeon_winsys *ws); @@ -304,6 +305,10 @@ struct radeon_winsys { int queue_index, struct radeon_winsys_cs **cs_array, unsigned cs_count, + struct radeon_winsys_sem **wait_sem, + unsigned wait_sem_count, + struct radeon_winsys_sem **signal_sem, + unsigned signal_sem_count, bool can_patch, struct radeon_winsys_fence *fence); @@ -326,6 +331,10 @@ struct radeon_winsys { struct radeon_winsys_fence *fence, bool absolute, uint64_t timeout); + + struct radeon_winsys_sem *(*create_sem)(struct radeon_winsys *ws); + void (*destroy_sem)(struct radeon_winsys_sem *sem); + }; static inline void radeon_emit(struct radeon_winsys_cs *cs, uint32_t value) diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c index 7337918680f..b24aa997495 100644 --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c @@ -739,20 +739,40 @@ static int radv_amdgpu_winsys_cs_submit(struct radeon_winsys_ctx *_ctx, int queue_idx, struct radeon_winsys_cs **cs_array, unsigned cs_count, + struct radeon_winsys_sem **wait_sem, + unsigned wait_sem_count, + struct radeon_winsys_sem **signal_sem, + unsigned signal_sem_count, bool can_patch, struct radeon_winsys_fence *_fence) { struct radv_amdgpu_cs *cs = radv_amdgpu_cs(cs_array[0]); + struct radv_amdgpu_ctx *ctx = radv_amdgpu_ctx(_ctx); + int ret; + int i; + + for (i = 0; i < wait_sem_count; i++) { + amdgpu_semaphore_handle sem = (amdgpu_semaphore_handle)wait_sem[i]; + amdgpu_cs_wait_semaphore(ctx->ctx, cs->hw_ip, 0, queue_idx, + sem); + } if (!cs->ws->use_ib_bos) { - return radv_amdgpu_winsys_cs_submit_sysmem(_ctx, queue_idx, cs_array, + ret = radv_amdgpu_winsys_cs_submit_sysmem(_ctx, queue_idx, cs_array, cs_count, _fence); } else if (can_patch && cs_count > AMDGPU_CS_MAX_IBS_PER_SUBMIT && false) { - return radv_amdgpu_winsys_cs_submit_chained(_ctx, queue_idx, cs_array, + ret = radv_amdgpu_winsys_cs_submit_chained(_ctx, queue_idx, cs_array, cs_count, _fence); } else { - return radv_amdgpu_winsys_cs_submit_fallback(_ctx, queue_idx, cs_array, + ret = radv_amdgpu_winsys_cs_submit_fallback(_ctx, queue_idx, cs_array, cs_count, _fence); } + + for (i = 0; i < signal_sem_count; i++) { + amdgpu_semaphore_handle sem = (amdgpu_semaphore_handle)signal_sem[i]; + amdgpu_cs_signal_semaphore(ctx->ctx, cs->hw_ip, 0, queue_idx, + sem); + } + return ret; } static struct radeon_winsys_ctx *radv_amdgpu_ctx_create(struct radeon_winsys *_ws) @@ -800,6 +820,23 @@ static bool radv_amdgpu_ctx_wait_idle(struct radeon_winsys_ctx *rwctx, return true; } +static struct radeon_winsys_sem *radv_amdgpu_create_sem(struct radeon_winsys *_ws) +{ + int ret; + amdgpu_semaphore_handle sem; + + ret = amdgpu_cs_create_semaphore(&sem); + if (ret) + return NULL; + return (struct radeon_winsys_sem *)sem; +} + +static void radv_amdgpu_destroy_sem(struct radeon_winsys_sem *_sem) +{ + amdgpu_semaphore_handle sem = (amdgpu_semaphore_handle)_sem; + amdgpu_cs_destroy_semaphore(sem); +} + void radv_amdgpu_cs_init_functions(struct radv_amdgpu_winsys *ws) { ws->base.ctx_create = radv_amdgpu_ctx_create; @@ -815,5 +852,7 @@ void radv_amdgpu_cs_init_functions(struct radv_amdgpu_winsys *ws) ws->base.cs_submit = radv_amdgpu_winsys_cs_submit; ws->base.create_fence = radv_amdgpu_create_fence; ws->base.destroy_fence = radv_amdgpu_destroy_fence; + ws->base.create_sem = radv_amdgpu_create_sem; + ws->base.destroy_sem = radv_amdgpu_destroy_sem; ws->base.fence_wait = radv_amdgpu_fence_wait; } -- 2.30.2