4. 设备和队列
一旦Vulkan完成初始化,设备和队列是用来和Vulkan实现交互的主要对象。
Vulkan把 physical 和 logical 设备的概念分开了。一个物理设备通常表示单独的一个系统(也许由几个单独的硬件组成一起工作), 个数是有限的。逻辑设备表示从应用程序的角度看设备。
物理设备通过 VkPhysicalDevice
handles表示:
VK_DEFINE_HANDLE(VkPhysicalDevice)
4.1. 物理设备
要从系统中获取表示已安装的物理设备的对象列表,可调用:
VkResult vkEnumeratePhysicalDevices(
VkInstance instance,
uint32_t* pPhysicalDeviceCount,
VkPhysicalDevice* pPhysicalDevices);
-
instance
是一个handle,指向了之前用vkCreateInstance
创建的Vulkan实例。 -
pPhysicalDeviceCount
是一个指针,指向了可用的或者已查询到的物理设备数量的整数,如下面所描述。 -
pPhysicalDevices
要么是NULL
,要么是一个指向VkPhysicalDevice
数组的指针。
如果pPhysicalDevices
为 NULL
,那么可用的物理设备的个数通过pPhysicalDeviceCount
返回。 否则,pPhysicalDeviceCount
必须指向一个用户端设置的、值为pPhysicalDevices
数组大小的变量, 且返回时,变量被覆写为pPhysicalDevices
数组的大小。 如果pPhysicalDeviceCount
比可用的物理设备个数小,最多pPhysicalDeviceCount
被覆盖。 如果pPhysicalDeviceCount
比可用的物理设备个数小,VK_INCOMPLETE
将被返回,表示不是所有可用设备被返回。
要查询一个获取的物理设备的通用属性,调用:
void vkGetPhysicalDeviceProperties(
VkPhysicalDevice physicalDevice,
VkPhysicalDeviceProperties* pProperties);
-
physicalDevice
是将被查询各种属性的物理设备的handle。 -
pProperties
指向一个VkPhysicalDeviceProperties
类型数据结构的实例,将被返回的信息所填充。
VkPhysicalDeviceProperties
数据结构定义如下:
typedef struct VkPhysicalDeviceProperties {
uint32_t apiVersion;
uint32_t driverVersion;
uint32_t vendorID;
uint32_t deviceID;
VkPhysicalDeviceType deviceType;
char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE];
uint8_t pipelineCacheUUID[VK_UUID_SIZE];
VkPhysicalDeviceLimits limits;
VkPhysicalDeviceSparseProperties sparseProperties;
} VkPhysicalDeviceProperties;
-
apiVersion
是设备所支持的Vulkan版本,如API Version Numbers and Semantics 一节所描述的那样被编码. -
driverVersion
是显卡生产商所提供的驱动版本号。 -
vendorID
是物理设备的 vendor (see below) 对应的唯一标识。 -
deviceID
is a 供应商所有设备中此设备的唯一标识。 -
deviceType
一个VkPhysicalDeviceType
,指定了设备的类型。 -
deviceName
是一个以 null 结束的UTF-8字符串,包含了设备的名字。 -
pipelineCacheUUID
是一个大小为VK_UUID_SIZE
的数组,每个元素包含8-bit,表示该设备的唯一编号。 -
limits
是一个VkPhysicalDeviceLimits
数据结构,给出了物理设备特定的物理限制。细节部分请参考Limits 。 -
sparseProperties
是一个VkPhysicalDeviceSparseProperties
数据结构,给出了和物理设备的各种稀疏相关的属性。 细节部分请参考Sparse Properties 。
vendorID
和 deviceID
域可以让应用程序适配硬件的没有通过其他Vulkan查询暴露出来的特性, 这些也可能包括性能分析,硬件勘误,或者其他的特性。在基于PCI的Vulkan实现中,vendorID
和 deviceID
最低6位必须包含 PCI供应商和硬件设备关联的设备ID,剩下的位必须设置为0。 在非PCI实现中,渲染返回什么值可以由操作系统或者平台策略来决定。 其他方面,则由Vulkan实现者根据如下限制条件或者指导意见来自由决定:
-
For purposes of physical device identification, the vendor of a physical device is the entity responsible for the most salient characteristics of the hardware represented by the physical device handle. In the case of a discrete GPU, this should be the GPU chipset vendor. In the case of a GPU or other accelerator integrated into a system-on-chip (SoC), this should be the supplier of the silicon IP used to create the GPU or other accelerator.
-
If the vendor of the physical device has a valid PCI vendor ID issued by PCI-SIG, that ID should be used to construct
vendorID
as described above for PCI-based implementations. Implementations that do not return a PCI vendor ID invendorID
must return a valid Khronos vendor ID, obtained as described in the Vulkan Documentation and Extensions document in the section “Registering a Vendor ID with Khronos”. Khronos vendor IDs are allocated starting at 0x10000, to distinguish them from the PCI vendor ID namespace. -
The vendor of the physical device is responsible for selecting
deviceID
. The value selected should uniquely identify both the device version and any major configuration options (for example, core count in the case of multicore devices). The same device ID should be used for all physical implementations of that device version and configuration. For example, all uses of a specific silicon IP GPU version and configuration should use the same device ID, even if those uses occur in different SoCs.
物理设备的类型为:
typedef enum VkPhysicalDeviceType {
VK_PHYSICAL_DEVICE_TYPE_OTHER = 0,
VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU = 1,
VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU = 2,
VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU = 3,
VK_PHYSICAL_DEVICE_TYPE_CPU = 4,
} VkPhysicalDeviceType;
-
VK_PHYSICAL_DEVICE_TYPE_OTHER
此设备不与其他任何可用的类型匹配。 -
VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU
此设备通常是嵌入式的,或者是集成到CPU内部的。 -
VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU
此设备通常是一个与CPU通过内部总线直接相连的独立设备。 -
VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU
此设备通常是虚拟环境中的一个虚拟节点。 -
VK_PHYSICAL_DEVICE_TYPE_CPU
此设备通常和CPU一样运行在同一个处理器上。
物理设备类型只是提供建议性的信息,并不直接影响系统的操作。 然而,设备类型可能与其他宣称的属性或者系统兼容性 有关,比如有多少个内存堆。
可调用下列命令来查询在物理设备上可用的队列的属性:
void vkGetPhysicalDeviceQueueFamilyProperties(
VkPhysicalDevice physicalDevice,
uint32_t* pQueueFamilyPropertyCount,
VkQueueFamilyProperties* pQueueFamilyProperties);
-
physicalDevice
是将被查询各种属性的物理设备的handle。 -
pQueueFamilyPropertyCount
是一个指针,指向一个和可用的或者查询到的队列族数量相关的整数,如下所描述。 -
pQueueFamilyProperties
是`NULL`,或者是一个指向VkQueueFamilyProperties
类型数组的指针。
如果pQueueFamilyProperties
为`NULL`,那么可用的队列族的数量通过 pQueueFamilyPropertyCount
返回。 否则,pQueueFamilyPropertyCount
必须: 指向一个变量,由用户设置的pQueueFamilyProperties
数组的个数, 返回的时候,这个变量值被 写入到pQueueFamilyProperties
的个数所覆盖。 如果pQueueFamilyPropertyCount
比可用的队列族少,最多有 pQueueFamilyPropertyCount
个数据被写入。
VkQueueFamilyProperties
数据结构定义如下:
typedef struct VkQueueFamilyProperties {
VkQueueFlags queueFlags;
uint32_t queueCount;
uint32_t timestampValidBits;
VkExtent3D minImageTransferGranularity;
} VkQueueFamilyProperties;
-
queueFlags
包含了此队列在队列族中兼容性的标志位。 -
queueCount
是队列族中队列的个数。 -
timestampValidBits
是通过vkCmdWriteTimestamp
写入的时间戳的有效位个数。有效位的范围是 36-64,或者值为0,表示不支持时间戳。 在有效bit位之外的位置被保证都为0。 -
minImageTransferGranularity
是队列族中的队列支持的转移图像的最小粒度。
queueFlags
的标志位如下:
typedef enum VkQueueFlagBits {
VK_QUEUE_GRAPHICS_BIT = 0x00000001,
VK_QUEUE_COMPUTE_BIT = 0x00000002,
VK_QUEUE_TRANSFER_BIT = 0x00000004,
VK_QUEUE_SPARSE_BINDING_BIT = 0x00000008,
} VkQueueFlagBits;
-
if
VK_QUEUE_GRAPHICS_BIT
is set, then the queues in this queue family support graphics operations. -
if
VK_QUEUE_COMPUTE_BIT
is set, then the queues in this queue family support compute operations. -
if
VK_QUEUE_TRANSFER_BIT
is set, then the queues in this queue family support transfer operations. -
if
VK_QUEUE_SPARSE_BINDING_BIT
is set, then the queues in this queue family support sparse memory management operations (see Sparse Resources). If any of the sparse resource features are enabled, then at least one queue family must support this bit.
如果Vulkan实现保留了任何支持图形操作的队列族,那么至少一个物理设备中至少有一个队列族必须都支持图形和计算操作。
注意
All commands that are allowed on a queue that supports transfer operations are also allowed on a queue that supports either graphics or compute operations thus if the capabilities of a queue family include |
更多细节请参考Queues.
The value returned in minImageTransferGranularity
has a unit of compressed texel blocks for images having a block-compressed format, and a unit of texels otherwise.
Possible values of minImageTransferGranularity
are:
-
(0,0,0) which indicates that only whole mip levels must be transferred using the image transfer operations on the corresponding queues. In this case, the following restrictions apply to all offset and extent parameters of image transfer operations:
-
The
x
,y
, andz
members of aVkOffset3D
parameter must always be zero. -
The
width
,height
, anddepth
members of aVkExtent3D
parameter must always match the width, height, and depth of the image subresource corresponding to the parameter, respectively.
-
-
(Ax, Ay, Az) where Ax, Ay, and Az are all integer powers of two. In this case the following restrictions apply to all image transfer operations:
-
x
,y
, andz
of aVkOffset3D
parameter must be integer multiples of Ax, Ay, and Az, respectively. -
width
of aVkExtent3D
parameter must be an integer multiple of Ax, or elsex
+width
must equal the width of the image subresource corresponding to the parameter. -
height
of aVkExtent3D
parameter must be an integer multiple of Ay, or elsey
+height
must equal the height of the image subresource corresponding to the parameter. -
depth
of aVkExtent3D
parameter must be an integer multiple of Az, or elsez
+depth
must equal the depth of the image subresource corresponding to the parameter. -
If the format of the image corresponding to the parameters is one of the block-compressed formats then for the purposes of the above calculations the granularity must be scaled up by the compressed texel block dimensions.
-
Queues supporting graphics and/or compute operations must report (1,1,1) in minImageTransferGranularity
, meaning that there are no additional restrictions on the granularity of image transfer operations for these queues. Other queues supporting image transfer operations are only required to support whole mip level transfers, thus minImageTransferGranularity
for queues belonging to such queue families may be (0,0,0).
Device Memory一节描述了从物理设备中查询出来的内存属性。
对于物理设备特征查询,请参考 Features 一章。