From 6d8ab53303331a2438ab7c89c94be31c44e70bb1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tapani=20P=C3=A4lli?= Date: Tue, 23 Jan 2018 14:01:00 +0200 Subject: [PATCH] anv: implement VK_EXT_global_priority extension MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit v2: add ANV_CONTEXT_REALTIME_PRIORITY (Chris) use unreachable with unknown priority (Samuel) v3: add stubs in gem_stubs.c (Emil) use priority defines from gen_defines.h v4: cleanup, add anv_gem_set_context_param (Jason) Signed-off-by: Tapani Pälli Reviewed-by: Samuel Iglesias Gonsálvez (v2) Reviewed-by: Chris Wilson (v2) Reviewed-by: Emil Velikov (v3) Reviewed-by: Jason Ekstrand --- src/intel/vulkan/anv_device.c | 44 ++++++++++++++++++++++++++++++ src/intel/vulkan/anv_extensions.py | 2 ++ src/intel/vulkan/anv_gem.c | 32 ++++++++++++++++++++++ src/intel/vulkan/anv_gem_stubs.c | 12 ++++++++ src/intel/vulkan/anv_private.h | 5 ++++ 5 files changed, 95 insertions(+) diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index 8be88acc52c..f314d7667d6 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -37,6 +37,7 @@ #include "util/build_id.h" #include "util/mesa-sha1.h" #include "vk_util.h" +#include "common/gen_defines.h" #include "genxml/gen7_pack.h" @@ -374,6 +375,9 @@ anv_physical_device_init(struct anv_physical_device *device, device->has_syncobj_wait = device->has_syncobj && anv_gem_supports_syncobj_wait(fd); + if (anv_gem_has_context_priority(fd)) + device->has_context_priority = true; + bool swizzled = anv_gem_get_bit6_swizzle(fd, I915_TILING_X); /* Starting with Gen10, the timestamp frequency of the command streamer may @@ -1324,6 +1328,23 @@ anv_device_init_dispatch(struct anv_device *device) } } +static int +vk_priority_to_gen(int priority) +{ + switch (priority) { + case VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT: + return GEN_CONTEXT_LOW_PRIORITY; + case VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT: + return GEN_CONTEXT_MEDIUM_PRIORITY; + case VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT: + return GEN_CONTEXT_HIGH_PRIORITY; + case VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT: + return GEN_CONTEXT_REALTIME_PRIORITY; + default: + unreachable("Invalid priority"); + } +} + VkResult anv_CreateDevice( VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, @@ -1367,6 +1388,15 @@ VkResult anv_CreateDevice( } } + /* Check if client specified queue priority. */ + const VkDeviceQueueGlobalPriorityCreateInfoEXT *queue_priority = + vk_find_struct_const(pCreateInfo->pQueueCreateInfos[0].pNext, + DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT); + + VkQueueGlobalPriorityEXT priority = + queue_priority ? queue_priority->globalPriority : + VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT; + device = vk_alloc2(&physical_device->instance->alloc, pAllocator, sizeof(*device), 8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); @@ -1397,6 +1427,20 @@ VkResult anv_CreateDevice( goto fail_fd; } + /* As per spec, the driver implementation may deny requests to acquire + * a priority above the default priority (MEDIUM) if the caller does not + * have sufficient privileges. In this scenario VK_ERROR_NOT_PERMITTED_EXT + * is returned. + */ + if (physical_device->has_context_priority) { + int err = + anv_gem_set_context_priority(device, vk_priority_to_gen(priority)); + if (err != 0 && priority > VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT) { + result = vk_error(VK_ERROR_NOT_PERMITTED_EXT); + goto fail_fd; + } + } + device->info = physical_device->info; device->isl_dev = physical_device->isl_dev; diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_extensions.py index 581921e62a1..6194eb0ad62 100644 --- a/src/intel/vulkan/anv_extensions.py +++ b/src/intel/vulkan/anv_extensions.py @@ -86,6 +86,8 @@ EXTENSIONS = [ Extension('VK_KHX_multiview', 1, True), Extension('VK_EXT_debug_report', 8, True), Extension('VK_EXT_external_memory_dma_buf', 1, True), + Extension('VK_EXT_global_priority', 1, + 'device->has_context_priority'), ] class VkVersion: diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c index 34c09891086..93072c7d3b8 100644 --- a/src/intel/vulkan/anv_gem.c +++ b/src/intel/vulkan/anv_gem.c @@ -30,6 +30,7 @@ #include #include "anv_private.h" +#include "common/gen_defines.h" static int anv_ioctl(int fd, unsigned long request, void *arg) @@ -302,6 +303,22 @@ close_and_return: return swizzled; } +int +anv_gem_set_context_priority(struct anv_device *device, + int priority) +{ + return anv_gem_set_context_param(device->fd, device->context_id, + I915_CONTEXT_PARAM_PRIORITY, + priority); +} + +bool +anv_gem_has_context_priority(int fd) +{ + return !anv_gem_set_context_param(fd, 0, I915_CONTEXT_PARAM_PRIORITY, + GEN_CONTEXT_MEDIUM_PRIORITY); +} + int anv_gem_create_context(struct anv_device *device) { @@ -324,6 +341,21 @@ anv_gem_destroy_context(struct anv_device *device, int context) return anv_ioctl(device->fd, DRM_IOCTL_I915_GEM_CONTEXT_DESTROY, &destroy); } +int +anv_gem_set_context_param(int fd, int context, uint32_t param, uint64_t value) +{ + struct drm_i915_gem_context_param p = { + .ctx_id = context, + .param = param, + .value = value, + }; + int err = 0; + + if (anv_ioctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &p)) + err = -errno; + return err; +} + int anv_gem_get_context_param(int fd, int context, uint32_t param, uint64_t *value) { diff --git a/src/intel/vulkan/anv_gem_stubs.c b/src/intel/vulkan/anv_gem_stubs.c index 26eb5c8a610..0f4a3f5da00 100644 --- a/src/intel/vulkan/anv_gem_stubs.c +++ b/src/intel/vulkan/anv_gem_stubs.c @@ -146,12 +146,24 @@ anv_gem_destroy_context(struct anv_device *device, int context) unreachable("Unused"); } +int +anv_gem_set_context_param(int fd, int context, uint32_t param, uint64_t value) +{ + unreachable("Unused"); +} + int anv_gem_get_context_param(int fd, int context, uint32_t param, uint64_t *value) { unreachable("Unused"); } +bool +anv_gem_has_context_priority(int fd) +{ + unreachable("Unused"); +} + int anv_gem_get_aperture(int fd, uint64_t *size) { diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index fb4fd19178d..3a4a80d8699 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -770,6 +770,7 @@ struct anv_physical_device { bool has_exec_fence; bool has_syncobj; bool has_syncobj_wait; + bool has_context_priority; struct anv_device_extension_table supported_extensions; @@ -923,7 +924,11 @@ int anv_gem_execbuffer(struct anv_device *device, int anv_gem_set_tiling(struct anv_device *device, uint32_t gem_handle, uint32_t stride, uint32_t tiling); int anv_gem_create_context(struct anv_device *device); +bool anv_gem_has_context_priority(int fd); +int anv_gem_set_context_priority(struct anv_device *device, 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); int anv_gem_get_context_param(int fd, int context, uint32_t param, uint64_t *value); int anv_gem_get_param(int fd, uint32_t param); -- 2.30.2