anv: implement VK_EXT_global_priority extension
authorTapani Pälli <tapani.palli@intel.com>
Tue, 23 Jan 2018 12:01:00 +0000 (14:01 +0200)
committerTapani Pälli <tapani.palli@intel.com>
Wed, 28 Feb 2018 12:36:57 +0000 (14:36 +0200)
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 <tapani.palli@intel.com>
Reviewed-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com> (v2)
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> (v2)
Reviewed-by: Emil Velikov <emil.velikov@collabora.com> (v3)
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/intel/vulkan/anv_device.c
src/intel/vulkan/anv_extensions.py
src/intel/vulkan/anv_gem.c
src/intel/vulkan/anv_gem_stubs.c
src/intel/vulkan/anv_private.h

index 8be88acc52c3b7c379022547a4f490e84ead1785..f314d7667d6b8220f87288f249576d46bdae66c4 100644 (file)
@@ -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;
 
index 581921e62a1170e32ed3a986f79e30eae8790379..6194eb0ad621823cc3a487f4065e7c73d682507b 100644 (file)
@@ -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:
index 34c0989108653edd60a31663da905563208d98bd..93072c7d3b87f1acdc84cd1ac313b6d6d51dc801 100644 (file)
@@ -30,6 +30,7 @@
 #include <fcntl.h>
 
 #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)
 {
index 26eb5c8a610b9c90ecb748a14aebdc84f4341b4d..0f4a3f5da00147dd60aaa006f9c0996a59fed9c4 100644 (file)
@@ -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)
 {
index fb4fd19178d162f6a5bf3dd2b8e577066e3eeef4..3a4a80d869939a4d47b8fb13e828020ecaaeef7b 100644 (file)
@@ -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);