[Mesa-dev] [PATCH v4] anv: implement VK_EXT_global_priority extension
Tapani Pälli
tapani.palli at intel.com
Tue Feb 27 08:14:55 UTC 2018
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 at intel.com>
Reviewed-by: Samuel Iglesias Gonsálvez <siglesias at igalia.com> (v2)
Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk> (v2)
Reviewed-by: Emil Velikov <emil.velikov at collabora.com> (v3)
Signed-off-by: Tapani Pälli <tapani.palli at intel.com>
---
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 a83b7a39f6..417969110b 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"
@@ -366,6 +367,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
@@ -1316,6 +1320,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,
@@ -1359,6 +1380,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);
@@ -1388,6 +1418,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 581921e62a..6194eb0ad6 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 34c0989108..93072c7d3b 100644
--- a/src/intel/vulkan/anv_gem.c
+++ b/src/intel/vulkan/anv_gem.c
@@ -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)
{
diff --git a/src/intel/vulkan/anv_gem_stubs.c b/src/intel/vulkan/anv_gem_stubs.c
index 26eb5c8a61..0f4a3f5da0 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 104b28ee5d..0be815d995 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -769,6 +769,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;
@@ -921,7 +922,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.14.3
More information about the mesa-dev
mailing list