Vulkan规范:第四章 4.3

4.3. 队列

4.3.1. 队列族的属性

如之前的Physical Device Enumeration一节讲过,vkGetPhysicalDeviceQueueFamilyProperties 命令是用来获取设备所支持的队列族的属性的。

vkGetPhysicalDeviceQueueFamilyProperties返回的pQueueFamilyProperties数组的每一个索引描述了 物理设备上唯一的队列族。 这些索引被用来创建队列,它们通过下节Queue Creation 讲解的VkDeviceQueueCreateInfo类型数据 直接对应着传递给 vkCreateDevice命令的 queueFamilyIndex

同一个物理设备上的队列族的分组取决于Vulkan实现。

注意

可以假定一个物理设备会把能力匹配的所有队列分组到一个族。 然而,这是对Vulkan实现的一个推荐,很可能,物理设备可能会返回两个拥有相同能力的族。

一旦应用程序以它想用的族来确定了物理设备,它将结合逻辑设备来创建这些队列。 这在下节讲述。

4.3.2. 创建队列

创建一个逻辑设备也会创建该设备相关的队列。需要创建的队列通过传递给vkCreateDevice 的参数pQueueCreateInfos的一系列VkDeviceQueueCreateInfo类型数据描述。

队列通过VkQueue handles表示:

VK_DEFINE_HANDLE(VkQueue)

VkDeviceQueueCreateInfo 数据结构定义如下:

typedef struct VkDeviceQueueCreateInfo {
    VkStructureType             sType;
    const void*                 pNext;
    VkDeviceQueueCreateFlags    flags;
    uint32_t                    queueFamilyIndex;
    uint32_t                    queueCount;
    const float*                pQueuePriorities;
} VkDeviceQueueCreateInfo;
  • sType 是数据结构的类型。

  • pNext 是 NULL 或者一个指向拓展特定的数据结构。

  • flags 被保留使用。

  • queueFamilyIndex 是一个无符号整形数字,表示在此设备上创建的队列族的索引。 这个索引对应着 vkGetPhysicalDeviceQueueFamilyProperties返回的pQueueFamilyProperties 数组中的元素的索引。

  • queueCount 是一个无符号整形数字,指定了 queueFamilyIndex表示的队列族中的队列个数。

  • pQueuePriorities 是一个元素为归一化浮点数的数组,大小为queueCount,指定了提交到已创建队列的任务的优先级。 参考Queue Priority 以获取更多信息。

正确使用
  • queueFamilyIndex must be less than pQueueFamilyPropertyCount returned byvkGetPhysicalDeviceQueueFamilyProperties

  • queueCount must be less than or equal to the queueCount member of the VkQueueFamilyProperties structure, as returned by vkGetPhysicalDeviceQueueFamilyProperties in the pQueueFamilyProperties[queueFamilyIndex]

  • Each element of pQueuePriorities must be between 0.0 and 1.0 inclusive

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO

  • pNext must be NULL

  • flags must be 0

  • pQueuePriorities must be a pointer to an array of queueCount float values

  • queueCount must be greater than 0

可调用如下命令来获取一个队列的handle:

void vkGetDeviceQueue(
    VkDevice                                    device,
    uint32_t                                    queueFamilyIndex,
    uint32_t                                    queueIndex,
    VkQueue*                                    pQueue);
  • device 是拥有该队列的逻辑设备。

  • queueFamilyIndex 是队列所属的队列族的索引。

  • queueIndex 是需要获取的队列在队列族中的索引。

  • pQueue 是一个指针,指向了VkQueue 对象,它将被获取到的队列的handle所覆盖。

正确使用
  • queueFamilyIndex must be one of the queue family indices specified when device was created, via theVkDeviceQueueCreateInfo structure

  • queueIndex must be less than the number of queues created for the specified queue family index when device was created, via the queueCount member of the VkDeviceQueueCreateInfo structure

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • pQueue must be a pointer to a VkQueue handle

4.3.3. 队列族索引

队列族索引在Vulkan中多处被使用,它可以把操作和特定的队列族绑定起来。

当通过vkGetDeviceQueue获取到一个队列的handle时,队列族的索引被用来选择从哪个队列族中获取队列handle(上上节所述)。

当创建VkCommandPool 对象时(参考 Command Pools),一个队列族索引通过 VkCommandPoolCreateInfo 数据结构指定。 从缓存池中获取的命令缓冲区 只能提交到对应着此队列族的队列上。

当创建 VkImage (参考 Images) 和 VkBuffer (参考 Buffers) 资源时,一系列的队列族被包含到VkImageCreateInfo 和VkBufferCreateInfo 数据结构中,来指定可以访问到这些资源的队列族。

当插入一个VkBufferMemoryBarrier 或 VkImageMemoryBarrier (see 事件) 时,一个源和目标队列族索引被指定来允许把缓冲区或图像转移到另外一个队列族。 参考 Resource Sharing 一节以获取细节。

4.3.4. 队列优先级

每一个队列都被分配了一个优先级,在创建设备过程中VkDeviceQueueCreateInfo的数据结构中设置的。 每一个队列的优先级是一个归一化的浮点值,在0.0和1.0之间,然后有Vulkan实现转换到离散的的优先级级别。 高的值表示更高的优先级,0.0表示最低的优先级,1.0表示最高。一个设备内,拥有高优先级的队列将会比 优先级低的队列获得更多的处理时间。Vulkan实现不保证相同优先级的队列的排序或者调度, 不管explicit synchronization primitives中已定义的限制如何。 Vulkan实现不保证不同设备之间的队列要如何安排优先级。

一个Vulkan实现也许允许更高优先级的队列会让同一个设备上的低优先级的队列挨饿,直到自己完成所有命令的执行。 队列优先级的关系必须不能导致另外一个设备上的队列暂停工作。

没有任何明确的保证高优先级的队列比低优先级的队列接受更多的处理时间和服务质量。

4.3.5. 队列提交

通过_队列提交_命令,如vkQueueSubmit,工作就被提交到队列了。队列提交命令定义了一系列的需要 物理设备执行的_队列操作_,包括使用信号量和栅栏来同步。

提交命令接受目标设备为参数,零个或者多个_batches_的任务,和一个可选的栅栏来激发任务完成的信号。 每一个批次由三个部分组成:

  1. Zero or more semaphores to wait on before execution of the rest of the batch.

  2. Zero or more work items to execute.

    • If present, these describe a queue operation matching the work described.

  3. Zero or more semaphores to signal upon completion of the work items.

If a fence is present in a queue submission, it describes a fence signal operation.

通过一个队列提交命令描述的所有任务必须在命令返回前提交到队列。

稀疏内存绑定

在Vulkan里,可以稀疏的绑定内存到缓冲区或者图像,这点在前面的Sparse Resource一章讲过。 稀疏内存绑定是一个队列操作。包含VK_QUEUE_SPARSE_BINDING_BIT标志的队列必须能支持在设备上 映射虚拟地址到物理地址。这将导致设备上映射表的更新。这个更新必须让队列保持同步,以避免在图形命令执行期间 损坏page table映射。通过在队列上绑定稀疏内存,所有依赖于被更新的绑定的命令在绑定更新之后同步的执行。 查看 Synchronization and Cache Control 一章可知如何实现同步。

4.3.6. 队列销毁

队列和vkCreateDevice创建的逻辑设备一同被创建。当调用vkDestroyDevice后,和逻辑设备关联的所有队列都被销毁了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值