[Mesa-dev] [PATCH 2/2] radv: define and implement VK_EXT_queue_global_priority

Bas Nieuwenhuizen bas at basnieuwenhuizen.nl
Wed Jan 4 07:22:15 UTC 2017


So two things I'm missing here are advertising the extension and
checking the kernel driver version.

To advertize the extension, an entry needs to be added to the
device_extensions array. However, since that array is const global,
you can't really select on kernel version or such, so you'll probably
need to switch to creating an array on physical device creation or
such.

Another thing is that you'll need to increase the amdgpu driver DRM
version in the kernel, and then check against it in radv, to see if we
can support the feature.



On Wed, Jan 4, 2017 at 3:27 AM, Andres Rodriguez <andresx7 at gmail.com> wrote:
> Add a new extension VK_EXT_queue_global_priority, which allows the
> caller to elevate a queue's priority above all other queues in the
> system.
>
> This extension aims to provide a mechanism for compositors to have
> achieve a guaranteed quality of service, even when the hardware may be
> loaded by a game or application.
> ---
>  docs/specs/VK_EXT_queue_global_priority.txt   | 97 +++++++++++++++++++++++++++
>  include/vulkan/vk_ext_queue_global_priority.h | 72 ++++++++++++++++++++
>  src/amd/vulkan/radv_device.c                  | 31 ++++++++-
>  src/amd/vulkan/radv_private.h                 | 12 ++++
>  src/amd/vulkan/radv_radeon_winsys.h           |  8 ++-
>  src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c | 20 +++++-
>  6 files changed, 234 insertions(+), 6 deletions(-)
>  create mode 100644 docs/specs/VK_EXT_queue_global_priority.txt
>  create mode 100644 include/vulkan/vk_ext_queue_global_priority.h
>
> diff --git a/docs/specs/VK_EXT_queue_global_priority.txt b/docs/specs/VK_EXT_queue_global_priority.txt
> new file mode 100644
> index 0000000..9a6a712
> --- /dev/null
> +++ b/docs/specs/VK_EXT_queue_global_priority.txt
> @@ -0,0 +1,97 @@
> +Name Strings
> +
> +    VK_EXT_queue_global_priority
> +
> +Extension Type
> +
> +    Queue Extension
> +
> +Registered Extension Number
> +
> +    Draft
> +
> +Status
> +
> +    Draft
> +
> +Version
> +
> +    0 (Early Draft)
> +
> +Last Modified Date
> +
> +    See git log.
> +
> +IP Status
> +
> +    No known IP claims.
> +
> +Dependencies
> +
> +    This extension is written against the Vulkan 1.0.32 specification [1].
> +
> +Contributors
> +
> +    Andres Rodriguez, Valve Software <andresr at valvesoftware.com>
> +    Pierre-Loup Griffais, Valve Software <pgriffais at valvesoftware.com>
> +
> +Contact
> +
> +    Andres Rodriguez, Valve Software <andresr at valvesoftware.com>
> +
> +Overview
> +
> +    In Vulkan 1.0.32 users can specify device-scope queue priorities. In
> +       some cases it may be useful to extend this concept to a system-wide scope.
> +
> +       This extension provides a mechanism for caller's to set their system-wide
> +    priority. The default queue priority is VK_QUEUE_GLOBAL_PRIORITY_NORMAL.
> +
> +       TODO: privileges required for priority escalation and note about system
> +    resource starvation.
> +
> +New Object Types
> +
> +    VkQueueGlobalPriorityEXT
> +               VK_STRUCTURE_TYPE_QUEUE_GLOBAL_PRIORITY_EXT
> +
> +New Enum Constants
> +
> +       None
> +
> +New Enums
> +
> +       VkQueueGlobalPriority
> +               VK_QUEUE_GLOBAL_PRIORITY_HIGH
> +               VK_QUEUE_GLOBAL_PRIORITY_NORMAL
> +
> +New Structs
> +
> +       typedef struct VkQueueGlobalPriorityEXT {
> +               VkStructureType                         sType;
> +               void*                                   pNext;
> +               VkQueueGlobalPriority                   priority;
> +       } VkQueueGlobalPriorityEXT;
> +
> +New Functions
> +
> +    None
> +
> +Description
> +
> +    TODO
> +
> +Issues
> +
> +       TODO
> +
> +References
> +
> +    [1]: https://github.com/KhronosGroup/Vulkan-Docs/tree/v1.0-core-20161025
> +
> +Version History
> +
> +    See git log for full history.
> +
> +    - Revision 1, 2017-01-01 (Andres Rodriguez)
> +        - Initial draft
> diff --git a/include/vulkan/vk_ext_queue_global_priority.h b/include/vulkan/vk_ext_queue_global_priority.h
> new file mode 100644
> index 0000000..01c7329
> --- /dev/null
> +++ b/include/vulkan/vk_ext_queue_global_priority.h
> @@ -0,0 +1,72 @@
> +/*
> + * Copyright 2017 Valve Software
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + */
> +
> +#ifndef VK_EXT_QUEUE_GLOBAL_PRIORITY_H_
> +#define VK_EXT_QUEUE_GLOBAL_PRIORITY_H_
> +
> +#include "vulkan.h"
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +/* Draft spec lives at <docs/specs/VK_EXT_queue_global_prioruity.txt>.
> + *
> + * TODO: Discuss with everyone who cares.
> + * TODO: Get a proper VkStructureType
> + * TODO: Finish spec
> + */
> +#define VK_EXT_queue_global_priority
> +#define VK_EXT_queue_global_priotiry_SPEC_VERSION 0 /* experimental */
> +#define VK_EXT_queue_global_priority_EXTENSION_NAME "VK_EXT_queue_global_priority"
> +
> +/** System-wide queue priority
> + *
> + *  High priority queues may starve queues in other processes
> + */
> +typedef enum VkQueueGlobalPriority {
> +    VK_QUEUE_GLOBAL_PRIORITY_HIGH = 1,
> +    VK_QUEUE_GLOBAL_PRIORITY_NORMAL = 2,
> +    VK_QUEUE_GLOBAL_PRIORITY_BEGIN_RANGE = VK_QUEUE_GLOBAL_PRIORITY_HIGH,
> +    VK_QUEUE_GLOBAL_PRIORITY_END_RANGE = VK_QUEUE_GLOBAL_PRIORITY_NORMAL,
> +    VK_QUEUE_GLOBAL_PRIORITY_RANGE_SIZE = (VK_QUEUE_GLOBAL_PRIORITY_HIGH - VK_QUEUE_GLOBAL_PRIORITY_NORMAL + 1),
> +    VK_QUEUE_GLOBAL_PRIORITY_MAX_ENUM = 0x7FFFFFFF
> +} VkQueueGlobalPriority;
> +
> +/* Extends VkDeviceQueueCreateInfo.
> + *
> + * Used to set the global priority for the allocated queue
> + */
> +typedef struct VkQueueGlobalPriorityEXT {
> +    VkStructureType                         sType;
> +    void*                                   pNext;
> +    VkQueueGlobalPriority                   priority;
> +} VkQueueGlobalPriorityEXT;
> +
> +#define VK_STRUCTURE_TYPE_QUEUE_GLOBAL_PRIORITY_EXT (VkStructureType)1000120001
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif
> diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
> index d9f9a2b..9880a5d 100644
> --- a/src/amd/vulkan/radv_device.c
> +++ b/src/amd/vulkan/radv_device.c
> @@ -651,16 +651,41 @@ void radv_GetPhysicalDeviceMemoryProperties(
>         };
>  }
>
> +static enum ctx_priority
> +radv_get_queue_global_priority(VkQueueGlobalPriorityEXT *pObj)
> +{
> +       switch(pObj->priority) {
> +       case VK_QUEUE_GLOBAL_PRIORITY_HIGH:
> +               return CTX_PRIORITY_HIGH;
> +       default:
> +               return CTX_PRIORITY_NORMAL;
> +       }
> +}
> +
>  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 VkDeviceQueueCreateInfo *create_info)
>  {
>         queue->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
>         queue->device = device;
>         queue->queue_family_index = queue_family_index;
>         queue->queue_idx = idx;
> +       queue->priority = CTX_PRIORITY_NORMAL;
> +
> +       radv_foreach_ext_obj(create_info, next_obj) {
> +               switch (next_obj->sType) {
> +               case VK_STRUCTURE_TYPE_QUEUE_GLOBAL_PRIORITY_EXT:
> +                       queue->priority = radv_get_queue_global_priority(
> +                                                                       (VkQueueGlobalPriorityEXT*)next_obj);
> +                       break;
> +               default:
> +                       radv_finishme("Unsupported queue extension VkStructureType %d\n",
> +                                                       next_obj->sType);
> +                       break;
> +               }
> +       }
>
> -       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;
>
> @@ -731,7 +756,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, queue_create);
>                         if (result != VK_SUCCESS)
>                                 goto fail;
>                 }
> diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
> index d316f71..d79ef3a 100644
> --- a/src/amd/vulkan/radv_private.h
> +++ b/src/amd/vulkan/radv_private.h
> @@ -66,6 +66,7 @@ typedef uint32_t xcb_window_t;
>
>  #include <vulkan/vulkan.h>
>  #include <vulkan/vulkan_intel.h>
> +#include <vulkan/vk_ext_queue_global_priority.h>
>  #include <vulkan/vk_icd.h>
>
>  #include "radv_entrypoints.h"
> @@ -457,6 +458,7 @@ struct radv_queue {
>         VK_LOADER_DATA                              _loader_data;
>         struct radv_device *                         device;
>         struct radeon_winsys_ctx                    *hw_ctx;
> +       enum ctx_priority                            priority;
>         int queue_family_index;
>         int queue_idx;
>  };
> @@ -1325,4 +1327,14 @@ RADV_DEFINE_NONDISP_HANDLE_CASTS(radv_shader_module, VkShaderModule)
>                 return (const __VkType *) __radv_obj;                   \
>         }
>
> +/**
> + * Used to iterate over Vk structs that support extension types
> + *
> + * Iterate over the __obj->pNext list, keeping the current object in __varname
> + */
> +#define radv_foreach_ext_obj(__obj, __varname) \
> +               /*Note: Any type with sType/pNext works here*/ \
> +               for ( VkSubmitInfo *__varname = (VkSubmitInfo*)__obj->pNext;\
> +                               __varname != NULL;\
> +                               __varname = (VkSubmitInfo*)__varname->pNext)
>  #endif /* RADV_PRIVATE_H */
> diff --git a/src/amd/vulkan/radv_radeon_winsys.h b/src/amd/vulkan/radv_radeon_winsys.h
> index 4b738b8..3218c87 100644
> --- a/src/amd/vulkan/radv_radeon_winsys.h
> +++ b/src/amd/vulkan/radv_radeon_winsys.h
> @@ -64,6 +64,11 @@ enum ring_type {
>         RING_LAST,
>  };
>
> +enum ctx_priority {
> +       CTX_PRIORITY_HIGH = 0,
> +       CTX_PRIORITY_NORMAL
> +};
> +
>  struct radeon_winsys_cs {
>         unsigned cdw;  /* Number of used dwords. */
>         unsigned max_dw; /* Maximum number of dwords. */
> @@ -284,7 +289,8 @@ struct radeon_winsys {
>
>         void (*buffer_set_metadata)(struct radeon_winsys_bo *bo,
>                                     struct radeon_bo_metadata *md);
> -       struct radeon_winsys_ctx *(*ctx_create)(struct radeon_winsys *ws);
> +       struct radeon_winsys_ctx *(*ctx_create)(struct radeon_winsys *ws,
> +                                                                                       enum 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 b24aa99..585ccf4 100644
> --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c
> +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c
> @@ -775,15 +775,31 @@ static int radv_amdgpu_winsys_cs_submit(struct radeon_winsys_ctx *_ctx,
>         return ret;
>  }
>
> -static struct radeon_winsys_ctx *radv_amdgpu_ctx_create(struct radeon_winsys *_ws)
> +static uint32_t radv_to_amdgpu_priority(enum ctx_priority priority radv_priority)
> +{
> +       switch (radv_priority) {
> +               case AMDGPU_CTX_PRIORITY_HIGH:
> +                       return AMDGPU_CTX_PRIORITY_HIGH;
> +               case AMDGPU_CTX_PRIORITY_NORMAL:
> +                       return AMDGPU_CTX_PRIORITY_NORMAL;
> +               default:
> +                       radv_loge("Invalid radv priority %d\n, defualting to normal", radv_priority);
> +                       return AMDGPU_CTX_PRIORITY_NORMAL;
> +       }
> +}
> +
> +static struct radeon_winsys_ctx *radv_amdgpu_ctx_create(struct radeon_winsys *_ws,
> +                                                                                                               enum 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);
>                 goto error_create;
> --
> 2.9.3
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list