From 39f25945311e1385a54ddd17f71f9f6023d97256 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Tue, 25 May 2021 10:30:49 -0500 Subject: [PATCH] anv: Implement VK_EXT_global_priority_query Part-of: --- src/intel/vulkan/anv_device.c | 92 ++++++++++++++++++++++++-------- src/intel/vulkan/anv_gem.c | 4 +- src/intel/vulkan/anv_gem_stubs.c | 2 +- src/intel/vulkan/anv_private.h | 4 +- 4 files changed, 75 insertions(+), 27 deletions(-) diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index 2d35df48aed..d2e79965880 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -256,7 +256,10 @@ get_device_extensions(const struct anv_physical_device *device, .EXT_external_memory_dma_buf = true, .EXT_external_memory_host = true, .EXT_fragment_shader_interlock = device->info.ver >= 9, - .EXT_global_priority = device->has_context_priority, + .EXT_global_priority = device->max_context_priority >= + INTEL_CONTEXT_MEDIUM_PRIORITY, + .EXT_global_priority_query = device->max_context_priority >= + INTEL_CONTEXT_MEDIUM_PRIORITY, .EXT_host_query_reset = true, .EXT_image_robustness = true, .EXT_image_drm_format_modifier = true, @@ -868,7 +871,18 @@ anv_physical_device_try_create(struct anv_instance *instance, device->has_syncobj_wait_available = anv_gem_get_drm_cap(fd, DRM_CAP_SYNCOBJ_TIMELINE) != 0; - device->has_context_priority = anv_gem_has_context_priority(fd); + /* Start with medium; sorted low to high */ + const int priorities[] = { + INTEL_CONTEXT_MEDIUM_PRIORITY, + INTEL_CONTEXT_HIGH_PRIORITY, + INTEL_CONTEXT_REALTIME_PRIORITY, + }; + device->max_context_priority = INT_MIN; + for (unsigned i = 0; i < ARRAY_SIZE(priorities); i++) { + if (!anv_gem_has_context_priority(fd, priorities[i])) + break; + device->max_context_priority = priorities[i]; + } /* Initialize memory regions struct to 0. */ memset(&device->vram, 0, sizeof(device->vram)); @@ -1500,6 +1514,13 @@ void anv_GetPhysicalDeviceFeatures2( break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT: { + VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT *features = + (VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT *)ext; + features->globalPriorityQuery = true; + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR: { VkPhysicalDeviceFragmentShadingRateFeaturesKHR *features = (VkPhysicalDeviceFragmentShadingRateFeaturesKHR *)ext; @@ -2494,6 +2515,23 @@ void anv_GetPhysicalDeviceProperties2( } } +static int +vk_priority_to_gen(int priority) +{ + switch (priority) { + case VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT: + return INTEL_CONTEXT_LOW_PRIORITY; + case VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT: + return INTEL_CONTEXT_MEDIUM_PRIORITY; + case VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT: + return INTEL_CONTEXT_HIGH_PRIORITY; + case VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT: + return INTEL_CONTEXT_REALTIME_PRIORITY; + default: + unreachable("Invalid priority"); + } +} + static const VkQueueFamilyProperties anv_queue_family_properties_template = { .timestampValidBits = 36, /* XXX: Real value here */ @@ -2533,8 +2571,35 @@ void anv_GetPhysicalDeviceQueueFamilyProperties2( p->queueFamilyProperties.queueFlags = queue_family->queueFlags; p->queueFamilyProperties.queueCount = queue_family->queueCount; - vk_foreach_struct(s, p->pNext) { - anv_debug_ignored_stype(s->sType); + vk_foreach_struct(ext, p->pNext) { + switch (ext->sType) { + case VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT: { + VkQueueFamilyGlobalPriorityPropertiesEXT *properties = + (VkQueueFamilyGlobalPriorityPropertiesEXT *)ext; + + /* Deliberately sorted low to high */ + VkQueueGlobalPriorityEXT all_priorities[] = { + VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT, + VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT, + VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT, + VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT, + }; + + uint32_t count = 0; + for (unsigned i = 0; i < ARRAY_SIZE(all_priorities); i++) { + if (vk_priority_to_gen(all_priorities[i]) > + pdevice->max_context_priority) + break; + + properties->priorities[count++] = all_priorities[i]; + } + properties->priorityCount = count; + break; + } + + default: + anv_debug_ignored_stype(ext->sType); + } } } } @@ -2773,23 +2838,6 @@ anv_device_init_trivial_batch(struct anv_device *device) return VK_SUCCESS; } -static int -vk_priority_to_gen(int priority) -{ - switch (priority) { - case VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT: - return INTEL_CONTEXT_LOW_PRIORITY; - case VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT: - return INTEL_CONTEXT_MEDIUM_PRIORITY; - case VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT: - return INTEL_CONTEXT_HIGH_PRIORITY; - case VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT: - return INTEL_CONTEXT_REALTIME_PRIORITY; - default: - unreachable("Invalid priority"); - } -} - static bool get_bo_from_pool(struct intel_batch_decode_bo *ret, struct anv_block_pool *pool, @@ -3087,7 +3135,7 @@ VkResult anv_CreateDevice( * have sufficient privileges. In this scenario VK_ERROR_NOT_PERMITTED_EXT * is returned. */ - if (physical_device->has_context_priority) { + if (physical_device->max_context_priority >= INTEL_CONTEXT_MEDIUM_PRIORITY) { int err = anv_gem_set_context_param(device->fd, device->context_id, I915_CONTEXT_PARAM_PRIORITY, vk_priority_to_gen(priority)); diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c index dd4c860a565..fc0b5364263 100644 --- a/src/intel/vulkan/anv_gem.c +++ b/src/intel/vulkan/anv_gem.c @@ -386,10 +386,10 @@ close_and_return: } bool -anv_gem_has_context_priority(int fd) +anv_gem_has_context_priority(int fd, int priority) { return !anv_gem_set_context_param(fd, 0, I915_CONTEXT_PARAM_PRIORITY, - INTEL_CONTEXT_MEDIUM_PRIORITY); + priority); } int diff --git a/src/intel/vulkan/anv_gem_stubs.c b/src/intel/vulkan/anv_gem_stubs.c index c552b7c6dc2..82107587d59 100644 --- a/src/intel/vulkan/anv_gem_stubs.c +++ b/src/intel/vulkan/anv_gem_stubs.c @@ -174,7 +174,7 @@ anv_gem_get_context_param(int fd, int context, uint32_t param, uint64_t *value) } bool -anv_gem_has_context_priority(int fd) +anv_gem_has_context_priority(int fd, int priority) { unreachable("Unused"); } diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 41cfdef733c..288368b875c 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -893,7 +893,7 @@ struct anv_physical_device { bool has_exec_fence; bool has_syncobj_wait; bool has_syncobj_wait_available; - bool has_context_priority; + int max_context_priority; bool has_context_isolation; bool has_thread_submit; bool has_mmap_offset; @@ -1434,7 +1434,7 @@ int anv_gem_create_context_engines(struct anv_device *device, const struct drm_i915_query_engine_info *info, int num_engines, uint16_t *engine_classes); -bool anv_gem_has_context_priority(int fd); +bool anv_gem_has_context_priority(int fd, int priority); int anv_gem_destroy_context(struct anv_device *device, int context); int anv_gem_set_context_param(int fd, int context, uint32_t param, uint64_t value);