Vulkan规范:第四章 4.2

来源:互联网 发布:线切割控制编程系统 编辑:程序博客网 时间:2024/05/16 19:38

4.2. 设备

设备对象表示和物理设备之间的一个连接。每一个设备对外暴露一些 队列族,每一个都有一个或多个_队列_。 在一个队列族中的所有队列都支持相同的操作。

如在Physical Devices中所描述的,一个Vulkan应用程序将首先查询 一个系统中所有的物理设备。 每一个物理设备可以被查询它的能力,包含队列和队列族的属性。一旦一个可接受的物理设备被确认了,应用程序将创建对应的 逻辑设备。应用程序必须对每一个使用的物理设备创建单独的逻辑设备。被创建的逻辑设备然后就是和物理设备之间的接口了。

如何遍历一个系统中的物理设备并查询这些物理设备的队列族属性在之前的 Physical Device Enumeration小节讲解过。

4.2.1. 设备创建

逻辑设备通过VkDevice handles表示:

VK_DEFINE_HANDLE(VkDevice)

一个逻辑设备被当作和物理设备的连接被创建。调用下面的命令来创建逻辑设备:

VkResult vkCreateDevice(    VkPhysicalDevice                            physicalDevice,    const VkDeviceCreateInfo*                   pCreateInfo,    const VkAllocationCallbacks*                pAllocator,    VkDevice*                                   pDevice);
  • physicalDevice 必须: 是vkEnumeratePhysicalDevices调用返回的多个队列中的一个的handle(参考 Physical Device Enumeration)。

  • pCreateInfo 是一个指针,指向一个类型为 VkDeviceCreateInfo 的数据结构,包含如何创建设备的信息。

  • pAllocator 控制了CPU端内存分配,如 Memory Allocation 一章所描述。

  • pDevice 指向了创建得到的 VkDevice 的handle。

可以在同一个物理设备上创建多个逻辑设备。因为物理资源的缺乏(和其他错误),逻辑设备的创建可能失败。 如果发生了失败,vkCreateDevice 将返回VK_ERROR_TOO_MANY_OBJECTS

Valid Usage (Implicit)
  • physicalDevice must be a valid VkPhysicalDevice handle

  • pCreateInfo must be a pointer to a valid VkDeviceCreateInfo structure

  • If pAllocator is not NULLpAllocator must be a pointer to a valid VkAllocationCallbacks structure

  • pDevice must be a pointer to a VkDevice handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_INITIALIZATION_FAILED

  • VK_ERROR_EXTENSION_NOT_PRESENT

  • VK_ERROR_FEATURE_NOT_PRESENT

  • VK_ERROR_TOO_MANY_OBJECTS

  • VK_ERROR_DEVICE_LOST

VkDeviceCreateInfo 数据结构定义如下:

typedef struct VkDeviceCreateInfo {    VkStructureType                    sType;    const void*                        pNext;    VkDeviceCreateFlags                flags;    uint32_t                           queueCreateInfoCount;    const VkDeviceQueueCreateInfo*     pQueueCreateInfos;    uint32_t                           enabledLayerCount;    const char* const*                 ppEnabledLayerNames;    uint32_t                           enabledExtensionCount;    const char* const*                 ppEnabledExtensionNames;    const VkPhysicalDeviceFeatures*    pEnabledFeatures;} VkDeviceCreateInfo;
  • sType 是数据结构的类型。

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

  • flags 被保留使用。

  • queueCreateInfoCount 是 pQueueCreateInfos 数组的大小。参考 下面的Queue Creation 一节来获取更多信息。

  • pQueueCreateInfos 是一个指针,指向一个元素类型为 VkDeviceQueueCreateInfo 的数组,描述了 describing the queues that are requested to be created along with the logical device. Refer to the Queue Creation section below for further details.

  • enabledLayerCount 已弃用,被忽略。

  • ppEnabledLayerNames 已弃用,被忽略。参考 Device Layer Deprecation.

  • enabledExtensionCount 是启用的设备拓展的个数。

  • ppEnabledExtensionNames 是一个指针,指向了一个长度为 enabledExtensionCount ,null-terminated UTF-8 字符串, 包含了将对创建的设备所启用的拓展名字。 参考Extensions 一节来获取更多细节。

  • pEnabledFeatures 是 NULL,或者是一个指针,指向一个 VkPhysicalDeviceFeatures 数据结构,其包含了所有将被启用的特征的 boolean标志位。 参考Features 一节获取更多细节。

正确使用
  • The queueFamilyIndex member of any given element of pQueueCreateInfos must be unique within pQueueCreateInfos

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO

  • pNext must be NULL

  • flags must be 0

  • pQueueCreateInfos must be a pointer to an array of queueCreateInfoCount valid VkDeviceQueueCreateInfostructures

  • If enabledLayerCount is not 0ppEnabledLayerNames must be a pointer to an array of enabledLayerCount null-terminated strings

  • If enabledExtensionCount is not 0ppEnabledExtensionNames must be a pointer to an array of enabledExtensionCount null-terminated strings

  • If pEnabledFeatures is not NULLpEnabledFeatures must be a pointer to a valid VkPhysicalDeviceFeaturesstructure

  • queueCreateInfoCount must be greater than 0

4.2.2. 使用设备

下面是如何使用 VkDevice 的上层列表,还有详细信息的参考点:

  • 创建队列。 请参考下面的Queues 一节来获取更多细节。

  • 创建并跟踪各种同步对象。 参考 Synchronization and Cache Control 来获取更多细节。

  • 分配,释放和管理内存。 参考 Memory Allocation 和 Resource Creation 以获取更多细节。

  • 创建和销毁命令缓冲区、命令缓存池。 参考 Command Buffers 以获取更多细节。

  • 创建,销毁和管理图形状态。 参考 Pipelines 和 Resource Descriptors还有其他的小节,以获取更多细节。

4.2.3. 设备丢失

逻辑设备可能因为硬件错误、执行超时、电源管理事件和平台某些事件而丢失。这会导致待执行的命令执行失败和硬件资源损坏。 当发生这种情况时,某些命令会返回name:VK_ERROR_DEVICE_LOST(参考Error Codes)。 发生了这种情况后,逻辑设备被认为已经丢失了。 不可能重置逻辑设备到非丢失状态,然而,这个丢失状态只是针对逻辑设备而言的,对应的物理设备(VkPhysicalDevice)可能不受影响。 一些情况下,物理设备也可能丢失,尝试创建逻辑设备会失败,返回VK_ERROR_DEVICE_LOST。这通常意味着潜在的硬件问题,或者和 CPU端的连接问题。 如果物理设备没有被丢失,在它上面一个新的逻辑设备成功的被创建了,物理设备一定是非丢失状态。

注意

同时,逻辑设备丢失是可恢复的,物理设备丢失的情况下,除非系统中有另外未受影响的物理设备,否则应用程序不可能会恢复。 错误大体上是信息性的,试图通知用户他们的硬件可能产生了错误或连接不良,应该自己调查一下。一些情况下,物理设备丢失可能导致 其他严重的问题,比如操作系统崩溃,这样的话Vulkan API就不会给出原因了。

注意

应用程序导致的未知行为可能导致设备丢失。然而,这些未定义行为也会导致进程内存损坏,此时就不能保证API对象,包括 VkPhysicalDevice 或者VkInstance仍然是有效的,或者是可恢复的。

当设备丢失了,它的子对象并没有隐式的被销毁,它们的handle仍然有效。这些对象必须要在他们父对象 或者设备被销毁之前被销毁(参考 Object Lifetime 小节 )。 使用vkMapMemory把设备内存映射到CPU端寻址空间的内存依然有效,对于被映射区域的CPU端内存访问仍然是有效的,但是内存内容是未定义的。 仍然可以对设备和它的子对象调用任何API命令。

一旦设备丢失,命令执行可能失败:,返回VkResult 的命令有可能: 返回VK_ERROR_DEVICE_LOST。 不允许运行时错误的命令有可能仍然正常使用中,有可能的话,仍返回有效的数据。

Commands that wait indefinitely for device execution (namely vkDeviceWaitIdlevkQueueWaitIdlevkWaitForFences with a maximum timeout, and vkGetQueryPoolResults with the VK_QUERY_RESULT_WAIT_BIT bit set in flagsmust return in finite time even in the case of a lost device, and return either VK_SUCCESS or VK_ERROR_DEVICE_LOST. For any command that may return VK_ERROR_DEVICE_LOST, for the purpose of determining whether a command buffer is pending execution, or whether resources are considered in-use by the device, a return value of VK_ERROR_DEVICE_LOST is equivalent to VK_SUCCESS.

editing-note

TODO (piman) - I do not think we are very clear about what “in-use by the device” means.

4.2.4. 设备销毁

可调用如下命令来销毁设备:

void vkDestroyDevice(    VkDevice                                    device,    const VkAllocationCallbacks*                pAllocator);
  • device 是需要被销毁的逻辑设备。

  • pAllocator 控制CPU内存分配,如 Memory Allocation 一章讲解。

为了保证在设备上没有正在进行的工作,vkDeviceWaitIdle 可以: 用来守护设备的销毁。 在销毁设备之前,应用程序需要负责销毁/释放从该设备上创建出来的Vulkan对象(使用vkCreate* 、vkAllocate* 等命令并以该device作为第一个参数)。

注意

The lifetime of each of these objects is bound by the lifetime of the VkDevice object. Therefore, to avoid resource leaks, it is critical that an application explicitly free all of these resources prior to callingvkDestroyDevice.

正确使用
  • All child objects created on device must have been destroyed prior to destroying device

  • If VkAllocationCallbacks were provided when device was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when device was created, pAllocator must be NULL

Valid Usage (Implicit)
  • If device is not NULLdevice must be a valid VkDevice handle

  • If pAllocator is not NULLpAllocator must be a pointer to a valid VkAllocationCallbacks structure

Host Synchronization
  • Host access to device must be externally synchronized

原创粉丝点击