summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndres Rodriguez <[email protected]>2017-10-20 18:02:14 -0400
committerBas Nieuwenhuizen <[email protected]>2017-10-21 01:01:44 +0200
commitfd04f3eb862984b862c35feca78418798512af99 (patch)
tree2be29dff94d3dda9a3017c0dddb61ff44b4a52c6
parent557de3b9ae2e0a1889442bb48f731d69c993a027 (diff)
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 <[email protected]> Reviewed-by: Bas Nieuwenhuizen <[email protected]>
-rw-r--r--src/amd/vulkan/radv_device.c32
-rw-r--r--src/amd/vulkan/radv_private.h1
-rw-r--r--src/amd/vulkan/radv_radeon_winsys.h11
-rw-r--r--src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c26
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;