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

Andres Rodriguez andresx7 at gmail.com
Wed Jan 4 20:25:53 UTC 2017


Okay, we can definitely do dynamic extension population.

I may have a followup question or two on IRC as I take a look at this.

Regards,
Andres

On 2017-01-04 02:22 AM, Bas Nieuwenhuizen wrote:
> 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