From fd04f3eb862984b862c35feca78418798512af99 Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Fri, 20 Oct 2017 18:02:14 -0400 Subject: [PATCH] radv: Implement VK_EXT_global_priority This extension allows the caller to change a queue's system wide priority. This is useful for applications with specific latency constraints. Signed-off-by: Andres Rodriguez Reviewed-by: Bas Nieuwenhuizen --- src/amd/vulkan/radv_device.c | 32 +++++++++++++++++-- src/amd/vulkan/radv_private.h | 1 + src/amd/vulkan/radv_radeon_winsys.h | 11 ++++++- src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c | 26 ++++++++++++--- 4 files changed, 62 insertions(+), 8 deletions(-) diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index ab7e97b8ba1..307d5579573 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -832,16 +832,40 @@ void radv_GetPhysicalDeviceMemoryProperties2KHR( &pMemoryProperties->memoryProperties); } +static enum radeon_ctx_priority +radv_get_queue_global_priority(const VkDeviceQueueGlobalPriorityCreateInfoEXT *pObj) +{ + /* Default to MEDIUM when a specific global priority isn't requested */ + if (!pObj) + return RADEON_CTX_PRIORITY_MEDIUM; + + switch(pObj->globalPriority) { + case VK_QUEUE_GLOBAL_PRIORITY_REALTIME: + return RADEON_CTX_PRIORITY_REALTIME; + case VK_QUEUE_GLOBAL_PRIORITY_HIGH: + return RADEON_CTX_PRIORITY_HIGH; + case VK_QUEUE_GLOBAL_PRIORITY_MEDIUM: + return RADEON_CTX_PRIORITY_MEDIUM; + case VK_QUEUE_GLOBAL_PRIORITY_LOW: + return RADEON_CTX_PRIORITY_LOW; + default: + unreachable("Illegal global priority value"); + return RADEON_CTX_PRIORITY_INVALID; + } +} + static int radv_queue_init(struct radv_device *device, struct radv_queue *queue, - int queue_family_index, int idx) + int queue_family_index, int idx, + const VkDeviceQueueGlobalPriorityCreateInfoEXT *global_priority) { queue->_loader_data.loaderMagic = ICD_LOADER_MAGIC; queue->device = device; queue->queue_family_index = queue_family_index; queue->queue_idx = idx; + queue->priority = radv_get_queue_global_priority(global_priority); - queue->hw_ctx = device->ws->ctx_create(device->ws); + queue->hw_ctx = device->ws->ctx_create(device->ws, queue->priority); if (!queue->hw_ctx) return VK_ERROR_OUT_OF_HOST_MEMORY; @@ -962,6 +986,8 @@ VkResult radv_CreateDevice( for (unsigned i = 0; i < pCreateInfo->queueCreateInfoCount; i++) { const VkDeviceQueueCreateInfo *queue_create = &pCreateInfo->pQueueCreateInfos[i]; uint32_t qfi = queue_create->queueFamilyIndex; + const VkDeviceQueueGlobalPriorityCreateInfoEXT *global_priority = + vk_find_struct_const(queue_create->pNext, DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT); device->queues[qfi] = vk_alloc(&device->alloc, queue_create->queueCount * sizeof(struct radv_queue), 8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); @@ -975,7 +1001,7 @@ VkResult radv_CreateDevice( device->queue_count[qfi] = queue_create->queueCount; for (unsigned q = 0; q < queue_create->queueCount; q++) { - result = radv_queue_init(device, &device->queues[qfi][q], qfi, q); + result = radv_queue_init(device, &device->queues[qfi][q], qfi, q, global_priority); if (result != VK_SUCCESS) goto fail; } diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index a149f72e612..47a068b5597 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -487,6 +487,7 @@ struct radv_queue { VK_LOADER_DATA _loader_data; struct radv_device * device; struct radeon_winsys_ctx *hw_ctx; + enum radeon_ctx_priority priority; int queue_family_index; int queue_idx; diff --git a/src/amd/vulkan/radv_radeon_winsys.h b/src/amd/vulkan/radv_radeon_winsys.h index 52b55c38e69..328b8a19cc5 100644 --- a/src/amd/vulkan/radv_radeon_winsys.h +++ b/src/amd/vulkan/radv_radeon_winsys.h @@ -70,6 +70,14 @@ enum ring_type { RING_LAST, }; +enum radeon_ctx_priority { + RADEON_CTX_PRIORITY_INVALID = -1, + RADEON_CTX_PRIORITY_LOW = 0, + RADEON_CTX_PRIORITY_MEDIUM, + RADEON_CTX_PRIORITY_HIGH, + RADEON_CTX_PRIORITY_REALTIME, +}; + struct radeon_winsys_cs { unsigned cdw; /* Number of used dwords. */ unsigned max_dw; /* Maximum number of dwords. */ @@ -188,7 +196,8 @@ struct radeon_winsys { void (*buffer_virtual_bind)(struct radeon_winsys_bo *parent, uint64_t offset, uint64_t size, struct radeon_winsys_bo *bo, uint64_t bo_offset); - struct radeon_winsys_ctx *(*ctx_create)(struct radeon_winsys *ws); + struct radeon_winsys_ctx *(*ctx_create)(struct radeon_winsys *ws, + enum radeon_ctx_priority priority); void (*ctx_destroy)(struct radeon_winsys_ctx *ctx); bool (*ctx_wait_idle)(struct radeon_winsys_ctx *ctx, diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c index 53d428681cd..46e5b767033 100644 --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c @@ -951,7 +951,6 @@ static int radv_amdgpu_winsys_cs_submit(struct radeon_winsys_ctx *_ctx, return ret; } - static void *radv_amdgpu_winsys_get_cpu_addr(void *_cs, uint64_t addr) { struct radv_amdgpu_cs *cs = (struct radv_amdgpu_cs *)_cs; @@ -1002,17 +1001,36 @@ static void radv_amdgpu_winsys_cs_dump(struct radeon_winsys_cs *_cs, cs->ws->info.chip_class, radv_amdgpu_winsys_get_cpu_addr, cs); } -static struct radeon_winsys_ctx *radv_amdgpu_ctx_create(struct radeon_winsys *_ws) +static uint32_t radv_to_amdgpu_priority(enum radeon_ctx_priority radv_priority) +{ + switch (radv_priority) { + case RADEON_CTX_PRIORITY_REALTIME: + return AMDGPU_CTX_PRIORITY_VERY_HIGH; + case RADEON_CTX_PRIORITY_HIGH: + return AMDGPU_CTX_PRIORITY_HIGH; + case RADEON_CTX_PRIORITY_MEDIUM: + return AMDGPU_CTX_PRIORITY_NORMAL; + case RADEON_CTX_PRIORITY_LOW: + return AMDGPU_CTX_PRIORITY_LOW; + default: + unreachable("Invalid context priority"); + } +} + +static struct radeon_winsys_ctx *radv_amdgpu_ctx_create(struct radeon_winsys *_ws, + enum radeon_ctx_priority priority) { struct radv_amdgpu_winsys *ws = radv_amdgpu_winsys(_ws); struct radv_amdgpu_ctx *ctx = CALLOC_STRUCT(radv_amdgpu_ctx); + uint32_t amdgpu_priority = radv_to_amdgpu_priority(priority); int r; if (!ctx) return NULL; - r = amdgpu_cs_ctx_create(ws->dev, &ctx->ctx); + + r = amdgpu_cs_ctx_create2(ws->dev, amdgpu_priority, &ctx->ctx); if (r) { - fprintf(stderr, "amdgpu: radv_amdgpu_cs_ctx_create failed. (%i)\n", r); + fprintf(stderr, "amdgpu: radv_amdgpu_cs_ctx_create2 failed. (%i)\n", r); goto error_create; } ctx->ws = ws; -- 2.30.2