选择完物理设备后,我们实际上很难直接跟物理设备进行交互,一般来说我们都是通过创建逻辑设备来处理。
创建逻辑设备的函数接口如下:1
2
3
4
5
6// Provided by VK_VERSION_1_0
VkResult vkCreateDevice(
VkPhysicalDevice physicalDevice,
const VkDeviceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkDevice* pDevice);
physicalDevice 是我们的物理设备
pCreateInfo 是指向创建逻辑设备所需要的的结构体的指针
pAllocator 一般为NULL
pDevice 就是我们创建的逻辑设备
下面我们来看一下VkDeviceCreateInfo结构体的内容1
2
3
4
5
6
7
8
9
10
11
12typedef 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—-这个结构体的类型
flag —- 遗留未来用
pNext—- 结构体的扩展指针,一般位NULL,
queueCreateInfoCount — pQueueCreateInfos数组的个数信息
pQueueCreateInfos — 需要创建的对开列的结构信息
enabledLayerCount—-废弃了
ppEnabledLayerNames — 废弃了
enabledExtensionCount — 设备扩展的个数
ppEnabledExtensionNames —设备扩展的名字
pEnabledFeatures — NULL或者是需要激活的一些设备的功能,这个里面内容很,如下所示:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57typedef struct VkPhysicalDeviceFeatures {
VkBool32 robustBufferAccess;
VkBool32 fullDrawIndexUint32;
VkBool32 imageCubeArray;
VkBool32 independentBlend;
VkBool32 geometryShader;
VkBool32 tessellationShader;
VkBool32 sampleRateShading;
VkBool32 dualSrcBlend;
VkBool32 logicOp;
VkBool32 multiDrawIndirect;
VkBool32 drawIndirectFirstInstance;
VkBool32 depthClamp;
VkBool32 depthBiasClamp;
VkBool32 fillModeNonSolid;
VkBool32 depthBounds;
VkBool32 wideLines;
VkBool32 largePoints;
VkBool32 alphaToOne;
VkBool32 multiViewport;
VkBool32 samplerAnisotropy;
VkBool32 textureCompressionETC2;
VkBool32 textureCompressionASTC_LDR;
VkBool32 textureCompressionBC;
VkBool32 occlusionQueryPrecise;
VkBool32 pipelineStatisticsQuery;
VkBool32 vertexPipelineStoresAndAtomics;
VkBool32 fragmentStoresAndAtomics;
VkBool32 shaderTessellationAndGeometryPointSize;
VkBool32 shaderImageGatherExtended;
VkBool32 shaderStorageImageExtendedFormats;
VkBool32 shaderStorageImageMultisample;
VkBool32 shaderStorageImageReadWithoutFormat;
VkBool32 shaderStorageImageWriteWithoutFormat;
VkBool32 shaderUniformBufferArrayDynamicIndexing;
VkBool32 shaderSampledImageArrayDynamicIndexing;
VkBool32 shaderStorageBufferArrayDynamicIndexing;
VkBool32 shaderStorageImageArrayDynamicIndexing;
VkBool32 shaderClipDistance;
VkBool32 shaderCullDistance;
VkBool32 shaderFloat64;
VkBool32 shaderInt64;
VkBool32 shaderInt16;
VkBool32 shaderResourceResidency;
VkBool32 shaderResourceMinLod;
VkBool32 sparseBinding;
VkBool32 sparseResidencyBuffer;
VkBool32 sparseResidencyImage2D;
VkBool32 sparseResidencyImage3D;
VkBool32 sparseResidency2Samples;
VkBool32 sparseResidency4Samples;
VkBool32 sparseResidency8Samples;
VkBool32 sparseResidency16Samples;
VkBool32 sparseResidencyAliased;
VkBool32 variableMultisampleRate;
VkBool32 inheritedQueries;
} VkPhysicalDeviceFeatures;
而创建队列的结构体如下:1
2
3
4
5
6
7
8typedef struct VkDeviceQueueCreateInfo {
VkStructureType sType;
const void* pNext;
VkDeviceQueueCreateFlags flags;
uint32_t queueFamilyIndex;
uint32_t queueCount;
const float* pQueuePriorities;
} VkDeviceQueueCreateInfo;
sType—-这个结构体的类型
flag —- 遗留未来用
pNext—- 结构体的扩展指针,一般位NULL,
queueFamilyIndex — 从物理设备获取到的队列簇的索引
queueCount — 指定索引的队列簇中的队列的个数
pQueuePriorities — 优先级
通过上面的结构体我们就可以创建出逻辑设备了。
然后我们可以通过下面的函数获取队列的句柄:1
2
3
4
5
6// Provided by VK_VERSION_1_0
void vkGetDeviceQueue(
VkDevice device,
uint32_t queueFamilyIndex,
uint32_t queueIndex,
VkQueue* pQueue);
device — 逻辑设备
queueFamilyIndex — 队列簇索引
queueIndex — 从队列簇中创建的队列的索引,如果创建一个队列,这里就是0。
pQueue — 队列句柄
实际代码如下:1
2vkGetDeviceQueue(device, indices.graphicsFamily.value(), 0, &graphicsQueue);
vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue);