[Mesa-dev] [PATCH 15/23] radv: add semaphore support

Bas Nieuwenhuizen bas at basnieuwenhuizen.nl
Sun Dec 18 18:59:29 UTC 2016


From: Dave Airlie <airlied at redhat.com>

Reviewed-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
---
 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 fd0ef720d8..3aac247f8b 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 38cb4408ff..4b738b8cf4 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 7337918680..b24aa99749 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.11.0



More information about the mesa-dev mailing list