本文主要是学习Vulkan Tutorial.pdf文档中的Physical devices and queue families(物理设备和队列系列)部分以及Logical device and queues(逻辑设备与队列)部分。
在通过VkInstance初始化Vulkan库之后,需要在系统中查找并选择支持我们所需功能的图形显卡。
事实上,我们可以选择任意数量的显卡并同时使用。但在这里,只使用第一个适合我们需求的显卡。
我们将添加一个函数pickPhysicalDevice并在initVulkan函数中添加对它的调用。
void initVulkan() {
checkAvailableExtensions();
createInstance();
// 创建DEBUG消息回调
setupDebugMessenger();
// 选择物理设备
pickPhysicalDevice();
}
void pickPhysicalDevice() {
}
最终选择的图形卡将存储在VkPhysicalDevice句柄中,该句柄作为新的类成员添加。
当VkInstance被销毁时,该对象将被隐式销毁,因此我们不需要在清理函数中做任何新的操作。
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
列出物理显卡的过程和列出vulkan扩展的过程类似,首先是获取本机物理显卡的数量:
void pickPhysicalDevice() {
uint32_t deviceCount = 0;
// 首先获取本机物理显卡数量
vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);
// 当然没有GPU时,抛出异常
if (deviceCount == 0) {
throw std::runtime_error("failed to find GPUs with Vulkan support!");
}
std::vector devices(deviceCount);
vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data());
// 遍历所有GPU, 选择合适的使用
for (const auto& device : devices) {
if (isDeviceSuitable(device)) {
physicalDevice = device;
break;
}
}
}
bool isDeviceSuitable(VkPhysicalDevice device) {
// 暂时没什么可以挑剔的,都可以吧
// 其实大部分的机器只会有一个显卡
return true;
}
通过查询细节来评估设备的适用性。
可以使用vkGetPhysicalDeviceProperties查询基本设备属性,如名称,类型和支持的Vulkan版本。
VkPhysicalDeviceProperties deviceProperties;
vkGetPhysicalDeviceProperties(device, &deviceProperties);
使用vkGetPhysicalDeviceFeatures查询对纹理压缩,64位浮点和多视口渲染(对VR有用)等可选功能的支持:
VkPhysicalDeviceFeatures deviceFeatures;
vkGetPhysicalDeviceFeatures(device, &deviceFeatures);
基本操作就是:
举个例子,假设我们的应用程序仅适用于支持几何着色器的专用显卡。 那么isDeviceSuitable函数将如下所示:
bool isDeviceSuitable(VkPhysicalDevice device) {
VkPhysicalDeviceProperties deviceProperties;
VkPhysicalDeviceFeatures deviceFeatures;
vkGetPhysicalDeviceProperties(device, &deviceProperties);
vkGetPhysicalDeviceFeatures(device, &deviceFeatures);
return deviceProperties.deviceType ==
(VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU && deviceFeatures.geometryShader);
}
所有可支持的feature见附录。
根据Vulkan Tutorial文档,有推荐使用评分机制来选择最合适的GPU,这个就见仁见智,看个人喜好,这里就不赘述了。
几乎所有Vulkan中的操作,从绘图到上传纹理,都需要将命令提交到队列中(这一点研究过hwui的童鞋肯定深有体会)。
存在来自不同队列系列的不同类型的队列,并且每个队列族仅允许命令的子集。
例如,可能存在仅允许处理计算命令的队列系列或仅允许与存储器传输相关的命令的队列系列。
所有我们需要检查本机设备支持哪些队列系列,以及哪一个支持我们要使用的命令。
添加一个新函数findQueueFamilies,用于查找我们需要的所有队列系列。
比如查找支持图形命令的队列:
struct QueueFamilyIndices {
// 别忘了添加头文件:including
// optional用途如其名,它可以容纳一个对象值或是为空。
// 典型的应用情景是函数调用时,如需根据条件返回一个对象(有效)或默认对象(无效)
// 若该对象构造成本很高(资源分配等),可用optional返回一个空对象,提高效率。
std::optional graphicsFamily;
bool isComplete() {
return graphicsFamily.has_value();
}
};
QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device) {
QueueFamilyIndices indices;
// 先检查数量
uint32_t queueFamilyCount = 0;
// 使用 vkGetPhysicalDeviceQueueFamilyProperties 检索队列系列是否正是我们需要的:
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr);
// VkQueueFamilyProperties结构包含有关队列系列的一些详细信息
// 包括支持的操作类型以及可基于该系列创建的队列数
std::vector queueFamilies(queueFamilyCount);
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data());
// 比如我们找到一个支持VK_QUEUE_GRAPHICS_BIT的队列系列
int i = 0;
for (const auto& queueFamily : queueFamilies) {
if (queueFamily.queueCount > 0 &&
queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
indices.graphicsFamily = i;
}
if (indices.isComplete()) {
break;
}
i++;
}
return indices;
}
把这个检查加入isDeviceSuitable函数。
现在已经找到合适的物理设备了, 下一步是创建一个与之适配的逻辑设备。
选择要使用的物理设备后,就可以创建一个与之适配的逻辑设备。
逻辑设备创建过程类似于实例创建过程,还需要指定现在要创建的队列(已经查询了哪些队列系列可用)。
并且从同一物理设备可以创建多个逻辑设备。
存储逻辑设备类似物理设备,也是使用句柄:
VkDevice device;
创建逻辑设备也是在结构体中指定一堆细节,其中第一个是VkDeviceQueueCreateInfo。
此结构描述了我们为单个队列系列所需的队列数。
比如创建具有图形功能的队列:
QueueFamilyIndices indices = findQueueFamilies(physicalDevice);
VkDeviceQueueCreateInfo queueCreateInfo = {};
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo.queueFamilyIndex = indices.graphicsFamily.value();
queueCreateInfo.queueCount = 1;
当前可用的驱动程序只允许为每个队列系列创建少量队列,实际上也不需要多个队列。
因为可以在多个线程上创建所有命令缓冲区,然后使用一个低开销调用在主线程上一次性提交。
Vulkan允许为队列分配优先级,以使用介于0.0和1.0之间的浮点数来影响命令缓冲区执行的调度。
即使只有一个队列,也是必需的:
float queuePriority = 1.0f;
queueCreateInfo.pQueuePriorities = &queuePriority;
要指定的下一个信息是我们将要使用的一组设备feature。
这些是在[1.2]中使用vkGetPhysicalDeviceFeatures查询支持的功能,例如几何着色器。
如果不需要任何特殊的东西,可以简单地定义它并默认为VK_FALSE。
但一旦即将开始用Vulkan做更多有趣的事情,就需要设定这个结构了。
VkPhysicalDeviceFeatures deviceFeatures = {};
在VkDeviceQueueCreateInfo和VkPhysicalDeviceFeatures创建完毕后,就可以根据这个创建逻辑设备实例了。
VkDeviceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
// 首先指定VkDeviceQueueCreateInfo
createInfo.pQueueCreateInfos = &queueCreateInfo;
createInfo.queueCreateInfoCount = 1;
// 指定VkPhysicalDeviceFeatures
createInfo.pEnabledFeatures = &deviceFeatures;
其余信息与VkInstanceCreateInfo结构相似,并要求指定扩展(Extensions)和验证层(Validation Layers)。不同之处在于这次是逻辑设备的。
设备特定扩展的其中之一是VK_KHR_swapchain,它允许您将该设备的渲染图像呈现给窗口。
系统中可能存在缺乏此功能的Vulkan设备,比如因为它们仅支持计算操作。
Vulkan的先前实现区分了实例和设备特定的验证层,但现在不做区分了。
也就是说VkDeviceCreateInfo的enabledLayerCount和ppEnabledLayerNames字段在最新实现中可以忽略。
createInfo.enabledExtensionCount = 0;
if (enableValidationLayers) {
createInfo.enabledLayerCount = static_cast(validationLayers.size());
createInfo.ppEnabledLayerNames = validationLayers.data();
} else {
createInfo.enabledLayerCount = 0;
}
类似创建vulkan实例,这里使用 vkCreateDevice 函数创建逻辑设备:
// 调用 vkCreateDevice 创建逻辑设备,别忘了在cleanup函数中销毁
if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) != VK_SUCCESS) {
throw std::runtime_error("failed to create logical device!");
}
队列是与逻辑设备一起自动创建的,下载创建与它们接口的句柄。
使用 VkQueue 来存储队列的句柄,如存储图形队列的句柄:
VkQueue graphicsQueue;
当设备被销毁时,会隐式清除设备队列,因此我们不需要在清理中执行任何操作(vkCreateXXX才需要主动释放哦)。
我们可以使用vkGetDeviceQueue函数来检索每个队列系列的队列句柄。
参数是逻辑设备,队列系列,队列索引和指向存储队列句柄的变量的指针。
因为我们只是从这个系列创建一个队列,所以我们只使用索引0。
vkGetDeviceQueue(device, indices.graphicsFamily.value(), 0, &graphicsQueue);
有了逻辑设备和队列句柄,我们现在可以开始使用显卡来做事了!
准备工作基本完成,后续我们可以设置资源并用窗口显示结果!
这次就不贴代码了。
// 定义在 vulkan_core.h 文件中
typedef 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;
指定对缓冲区的访问是根据缓冲区描述符的范围进行边界检查的(由VkDescriptorBufferInfo::range,VkBufferViewCreateInfo::range或缓冲区的大小确定)。
超出范围访问不得导致应用程序终止,并且着色器加载,存储和原子的效果必须符合与如下相关的行为:
指定当使用VKIndexType为VK_INDEX_TYPE_UINT32时,索引绘制调用支持完整的32位索引范围。
maxDrawIndexedIndexValue是可以使用的最大索引值(除了原始重启索引,当VkIndexType是VK_INDEX_TYPE_UINT32时,它总是2^32-1)。
如果支持此功能,则maxDrawIndexedIndexValue必须为2^32-1; 否则它必须不小于2^24-1。
指定是否可以创建VkImageViewType为VK_IMAGE_VIEW_TYPE_CUBE_ARRAY的图像视图,以及是否可以在着色器代码中使用相应的SampledCubeArray和ImageCubeArray SPIR-V功能。
指定是否每个附件独立控制VkPipelineColorBlendAttachmentState设置。
如果未启用此功能,则所有颜色附件的VkPipelineColorBlendAttachmentState设置必须相同。
如果启用,可以为每个绑定的颜色附件提供不同的VkPipelineColorBlendAttachmentState。
指定是否支持几何着色器。
如果未启用此功能,则不得使用VK_SHADER_STAGE_GEOMETRY_BIT和VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT枚举值。
这还指定着色器模块是否可以声明几何功能。
指定是否支持曲面细分控制和评估着色器。
如果未启用此功能,则不得使用:
这还指定着色器模块是否可以声明Tessellation功能。
指定是否支持样本着色和多重采样插值。
如果未启用此功能,则必须将VkPipelineMultisampleStateCreateInfo结构的sampleShadingEnable成员设置为VK_FALSE,并忽略minSampleShading成员。
这还指定着色器模块是否可以声明SampleRateShading功能。
指定是否支持采用两个源的混合操作。
如果未启用此功能,则不得将:
以上枚举值用作源或目标混合因子。详细信息参阅 vkspec.html: 26.1.2. Dual-Source Blending
指定是否支持逻辑运算。 如果未启用此功能,则必须将VkPipelineColorBlendStateCreateInfo结构的logicOpEnable成员设置为VK_FALSE,并忽略logicOp成员。
指定是否支持多个draw间接。
如果未启用此功能,则vkCmdDrawIndirect和vkCmdDrawIndexedIndirect命令的drawCount参数必须为0或1.
如果不支持此功能,则VkPhysicalDeviceLimits结构的maxDrawIndirectCount(间接绘制调用支持的最大绘制计数)成员也必须为1。
指定间接绘制调用是否支持firstInstance参数。
如果未启用此功能,则提供给vkCmdDrawIndirect和vkCmdDrawIndexedIndirect命令的所有VkDrawIndirectCommand和VkDrawIndexedIndirectCommand结构的firstInstance成员必须为0。
指定是否支持深度Clamp。
如果未启用此功能,则必须将VkPipelineRasterizationStateCreateInfo结构的depthClampEnable成员设置为VK_FALSE。
如果启用,将depthClampEnable设置为VK_TRUE将启用深度Clamp。
指定是否支持深度偏置Clamp。
如果未启用此功能,则必须将VkPipelineRasterizationStateCreateInfo结构的depthBiasClamp成员设置为0.0,除非启用VK_DYNAMIC_STATE_DEPTH_BIAS动态状态,并且必须将vkCmdSetDepthBias的depthBiasClamp参数设置为0.0。
指定是否支持点和线框填充模式。
如果未启用此功能,则VkPipelineRasterizationStateCreateInfo::polygonMode不得使用:
指定是否支持深度边界测试。
如果未启用此功能,则必须将VkPipelineDepthStencilStateCreateInfo结构的depthBoundsTestEnable成员设置为VK_FALSE。 当depthBoundsTestEnable设置为VK_FALSE时,将忽略VkPipelineDepthStencilStateCreateInfo结构的minDepthBounds和maxDepthBounds成员。
指定是否支持宽度不是1.0的行。
如果未启用此功能,则必须将VkPipelineRasterizationStateCreateInfo结构的lineWidth成员设置为1.0,除非启用VK_DYNAMIC_STATE_LINE_WIDTH动态状态,并且必须将vWCmdSetLineWidth的lineWidth参数设置为1.0。
支持此功能时,支持的线宽的范围和粒度分别由VkPhysicalDeviceLimits结构的lineWidthRange和lineWidthGranularity成员指示。
指定是否支持大小大于1.0的点。
如果未启用此功能,则仅支持着色器写入的点大小1.0。 支持的点大小的范围和粒度分别由VkPhysicalDeviceLimits结构的pointSizeRange和pointSizeGranularity成员指示。
指定实现是否能够使用定点颜色的最大可表示alpha值或浮点颜色的1.0替换片段着色器中输出的颜色片段的alpha值。
如果未启用此功能,则必须将VkPipelineMultisampleStateCreateInfo结构的alphaToOneEnable成员设置为VK_FALSE。
否则,将alphaToOneEnable设置为VK_TRUE将启用alpha-to-one行为。
指定是否支持多个Viewport。 如果未启用此功能:
指定是否支持各向异性过滤。
如果未启用此功能,则VkSamplerCreateInfo结构的anisotropyEnable成员必须为VK_FALSE。
指定是否支持所有ETC2和EAC压缩纹理格式。
如果启用此功能,则OptimalTilingFeatures中必须支持:
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT:指定可以从中采样图像视图
VK_FORMAT_FEATURE_BLIT_SRC_BIT:指定图像可用作vkCmdBlitImage命令的srcImage
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT:图像视图可以与采样器一起使用(详细信息 vkspec.html:VkFormatFeatureFlagBits)
以上格式的功能:
要查询其他属性,或者未启用该功能,可以使用vkGetPhysicalDeviceFormatProperties和vkGetPhysicalDeviceImageFormatProperties来检查各个格式的支持属性。
指定是否支持所有ASTC LDR压缩纹理格式。
如果启用此功能,则OptimalTilingFeatures中必须支持:
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
VK_FORMAT_FEATURE_BLIT_SRC_BIT和VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT
以上格式的功能:
要查询其他属性,或者未启用该功能,可以使用vkGetPhysicalDeviceFormatProperties和vkGetPhysicalDeviceImageFormatProperties来检查各个格式的支持属性。
指定是否支持所有BC压缩纹理格式。
如果启用此功能,则OptimalTilingFeatures中必须支持:
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
VK_FORMAT_FEATURE_BLIT_SRC_BIT
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT
以上格式的功能:
要查询其他属性,或者未启用该功能,可以使用vkGetPhysicalDeviceFormatProperties和vkGetPhysicalDeviceImageFormatProperties来检查各个格式的支持属性。
指定是否支持返回实际样本计数的遮挡查询。
通过在VkQueryPoolCreateInfo结构中指定VK_QUERY_TYPE_OCCLUSION的queryType并将其传递给vkCreateQueryPool,可以在VkQueryPool中创建遮挡查询。
如果启用此功能,则此类查询可以将flags参数中的VK_QUERY_CONTROL_PRECISE_BIT启用为vkCmdBeginQuery。
如果不支持此功能,则实现仅支持布尔遮挡查询。传递任何样本时,布尔查询将返回非零结果值,否则返回结果值为零。
启用此功能并设置VK_QUERY_CONTROL_PRECISE_BIT后,遮挡查询将报告传递的实际样本数。
指定是否支持管道统计信息查询。
如果未启用此功能,则无法创建类型为VK_QUERY_TYPE_PIPELINE_STATISTICS的查询,并且无法在VkQueryPoolCreateInfo结构的pipelineStatistics成员中设置任何VkQueryPipelineStatisticFlagBits位。
指定存储缓冲区和图像是否支持顶点,曲面细分和几何着色器阶段中的存储和原子操作。
如果未启用此功能,则着色器模块中这些阶段使用的所有存储器映像,存储纹理缓冲区缓冲区和存储缓冲区变量必须使用NonWritable修饰(或GLSL中的只读内存限定符)进行修饰。
指定存储缓冲区和图像是否支持片段着色器阶段中的存储和原子操作。
如果未启用此功能,则着色器模块中片段阶段使用的所有存储器映像,存储纹理缓冲区缓冲区和存储缓冲区变量必须使用NonWritable修饰(或GLSL中的只读内存限定符)进行修饰。
指定曲面细分控件,曲面细分评估和几何着色器阶段中是否提供PointSize内置修饰。
如果未启用此功能,则不得读取或写入使用PointSize内置修饰的成员,并且从曲面细分或几何着色器写入的所有点的大小均为1.0。
这还指定着色器模块是否可以为曲面细分控制和评估着色器声明TessellationPointSize功能,或者着色器模块是否可以为几何着色器声明GeometryPointSize功能。
支持此功能的实现还必须支持tessellationShader或geometryShader功能中的一个或两个。
指定着色器代码中是否可以使用扩展的图像收集指令集。
如果未启用此功能,则OpImage * Gather指令不支持Offset和ConstOffsets操作数。 这还指定着色器模块是否可以声明ImageGatherExtended功能。
指定着色器代码中是否所有扩展存储器图像格式都可用。
如果启用此功能,则必须在所有扩展格式的optimalTilingFeatures中支持VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT功能。
要查询其他属性,或者未启用该功能,可以使用vkGetPhysicalDeviceFormatProperties和vkGetPhysicalDeviceImageFormatProperties来检查各个格式的支持属性。
指定是否支持多重采样存储映像。
如果未启用此功能,则必须使用等于VK_SAMPLE_COUNT_1_BIT的样本创建使用包含VK_IMAGE_USAGE_STORAGE_BIT的用法创建的图像。
这还指定着色器模块是否可以声明StorageImageMultisample功能。
指定存储图像是否需要在从存储器映像读取时指定格式限定符。
如果未启用此功能,则OpImageRead指令的OpTypeImage不得为Unknown。
这还指定着色器模块是否可以声明StorageImageReadWithoutFormat功能。
指定存储图像是否需要在写入存储图像时指定格式限定符。
如果未启用此功能,则OpImageWrite指令的OpTypeImage不得为Unknown。
这还指定着色器模块是否可以声明StorageImageWriteWithoutFormat功能。
指定是否可以通过着色器代码中的动态统一整数表达式对统一缓冲区的数组建立索引。
如果未启用此功能,则在着色器代码中聚合到数组中时,描述符类型为VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER或VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC的资源必须仅由常量整数表达式编制索引。
这还指定着色器模块是否可以声明UniformBufferArrayDynamicIndexing功能。
指定采样器阵列或采样图像是否可以通过着色器代码中的动态统一整数表达式进行索引。
如果未启用此功能,则在着色器代码中聚合到数组中时,描述符类型为VK_DESCRIPTOR_TYPE_SAMPLER,VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER或VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE的资源必须仅由常量整数表达式编制索引。
这还指定着色器模块是否可以声明SampledImageArrayDynamicIndexing功能。
指定是否可以通过着色器代码中的动态统一整数表达式索引存储缓冲区的数组。
如果未启用此功能,则在着色器代码中聚合到数组中时,描述符类型为VK_DESCRIPTOR_TYPE_STORAGE_BUFFER或VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC的资源必须仅由常量整数表达式编制索引。
这还指定着色器模块是否可以声明StorageBufferArrayDynamicIndexing功能。
指定是否可以通过着色器代码中的动态统一整数表达式索引存储器图像数组。
如果未启用此功能,则在着色器代码中聚合到数组中时,描述符类型为VK_DESCRIPTOR_TYPE_STORAGE_IMAGE的资源必须仅通过常量整数表达式编制索引。
这还指定着色器模块是否可以声明StorageImageArrayDynamicIndexing功能。
指定着色器代码中是否支持ClipDistance。
如果未启用此功能,则不得在着色器模块中读取或写入使用ClipDistance内置装饰的任何成员。
这还指定着色器模块是否可以声明ClipDistance功能。
指定着色器代码中是否支持CullDistance。
如果未启用此功能,则不得在着色器模块中读取或写入使用CullDistance内置装饰的任何成员。
这还指定着色器模块是否可以声明CullDistance功能。
指定着色器代码中是否支持64位浮点(双精度)。
如果未启用此功能,则不得在着色器代码中使用64位浮点类型。
这还指定着色器模块是否可以声明Float64功能。
指定着色器代码中是否支持64位整数(有符号和无符号)。
如果未启用此功能,则不得在着色器代码中使用64位整数类型。
这还指定着色器模块是否可以声明Int64功能。
指定着色器代码中是否支持16位整数(有符号和无符号)。
如果未启用此功能,则不得在着色器代码中使用16位整数类型。
这还指定着色器模块是否可以声明Int16功能。
指定着色器代码是否支持返回资源驻留信息的图像操作。
如果未启用此功能,则不得在着色器代码中使用OpImageSparse *指令。
这还指定着色器模块是否可以声明SparseResidency功能。
该功能至少需要支持一个sparseResidency *功能。
指定着色器代码中是否支持指定最小资源LOD的图像操作。
如果未启用此功能,则不得在着色器代码中使用MinLod图像操作数。
这还指定着色器模块是否可以声明MinLod功能。
指定是否可以在不透明的稀疏块级别而不是在对象级别管理资源内存。
如果未启用此功能,则必须使用vkBindBufferMemory和vkBindImageMemory命令仅基于每个对象绑定资源内存。 在这种情况下,不能分别使用VkBufferCreateInfo和VkImageCreateInfo结构的flags成员中设置的VK_BUFFER_CREATE_SPARSE_BINDING_BIT和VK_IMAGE_CREATE_SPARSE_BINDING_BIT创建缓冲区和映像。 否则,可以按稀疏资源特征中的描述管理资源存储器。
指定设备是否可以访问部分驻留缓冲区。
如果未启用此功能,则不能使用VkBufferCreateInfo结构的flags成员中设置的VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT创建缓冲区。
指定设备是否可以访问每个像素1个样本的部分驻留的2D图像。
如果未启用此功能,则不得使用VkImageCreateInfo结构的flags成员中设置的VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT创建imageType为VK_IMAGE_TYPE_2D且样本设置为VK_SAMPLE_COUNT_1_BIT的图像。
指定设备是否可以访问部分驻留的3D图像。
如果未启用此功能,则不得使用VkImageCreateInfo结构的flags成员中设置的VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT创建imageType为VK_IMAGE_TYPE_3D的映像。
指定物理设备是否可以访问具有每像素2个样本的部分驻留的2D图像。
如果未启用此功能,则不得使用VkImageCreateInfo结构的flags成员中设置的VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT创建imageType为VK_IMAGE_TYPE_2D且样本设置为VK_SAMPLE_COUNT_2_BIT的图像。
指定物理设备是否可以访问每个像素有4个样本的部分驻留的2D图像。
如果未启用此功能,则不得使用VkImageCreateInfo结构的flags成员中设置的VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT创建imageType为VK_IMAGE_TYPE_2D且样本设置为VK_SAMPLE_COUNT_4_BIT的图像。
指定物理设备是否可以访问具有每像素8个样本的部分驻留的2D图像。
如果未启用此功能,则不得使用VkImageCreateInfo结构的flags成员中设置的VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT创建imageType为VK_IMAGE_TYPE_2D且样本设置为VK_SAMPLE_COUNT_8_BIT的图像。
指定物理设备是否可以访问每个像素16个样本的部分驻留的2D图像。
如果未启用此功能,则不得使用VkImageCreateInfo结构的flags成员中设置的VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT创建imageType为VK_IMAGE_TYPE_2D且样本设置为VK_SAMPLE_COUNT_16_BIT的图像。
指定物理设备是否可以正确访问别名到多个位置的数据。
如果未启用此功能,则不得分别在VkBufferCreateInfo和VkImageCreateInfo结构的flags成员中使用VK_BUFFER_CREATE_SPARSE_ALIASED_BIT和VK_IMAGE_CREATE_SPARSE_ALIASED_BIT枚举值。
指定在没有附件的子通行期间将绑定到命令缓冲区的所有管道是否必须具有VkPipelineMultisampleStateCreateInfo::rasterizationSamples的相同值。
如果设置为VK_TRUE,则实现支持不带附件的子通道中的可变多重采样率。
如果设置为VK_FALSE,则绑定在此子通道中的所有管道必须具有相同的多采样率。 但这在子通道使用任何附件的情况下无效。
指定在查询处于活动状态时是否可以执行辅助命令缓冲区。
可以自行下载最新代码制作,也可以直接下载: