radv: add semaphore support
authorDave Airlie <airlied@redhat.com>
Thu, 1 Dec 2016 01:52:31 +0000 (01:52 +0000)
committerBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Sun, 18 Dec 2016 19:52:26 +0000 (20:52 +0100)
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
src/amd/vulkan/radv_device.c
src/amd/vulkan/radv_radeon_winsys.h
src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c

index fd0ef720d8b2172722d5b46f1c9b8eae1161f7d4..3aac247f8ba36be4c34168a736da8f0525890ac7 100644 (file)
@@ -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(
index 38cb4408ff479059129536b3f6d121bec76cfe7f..4b738b8cf4607072f9941a47080ba467b153321c 100644 (file)
@@ -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)
index 7337918680f3b7139b7ff9cb484581b68f861e7a..b24aa997495f23f4a3bd75534b3c307e059c1ce9 100644 (file)
@@ -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;
 }