为什么 VkPhysicalDeviceVulkan{11|12}Properties 不包含 Vulkan 1.2 上的有效数据?



当使用函数时,vkGetPhysicalDeviceProperties2我在pNext链中传递了一个带有VkPhysicalDeviceVulkan11PropertiesVkPhysicalDeviceVulkan12PropertiesVkPhysicalDeviceProperties2结构。但是,调用函数后,只有vkGetPhysicalDeviceProperties2包含有效数据,链中的其他结构包含未定义的数据。

在查看规范时,我注意到有关 Vulkan11 和 Vulkan12 结构应该包含的其他结构的评论。当用相应的"较小"结构替换它们并将它们添加到链中时。我确实得到了有效的数据,这似乎更奇怪,因为我首先看不出是什么阻止了 Vulkan 使用更大的结构。

注: 验证图层是静默的

信息:

  • Vulkan SDK: 1.2.141.0
  • 英伟达驱动程序:446.14
  • GPU GeForce GTX 1060 采用 Max-Q 設計
  • 操作系统: 视窗 10.0.18363
  • 编译器:Microsoft (R( C/C++ 优化编译器版本 19.26.28806 for x64

相关代码:

StaticArray<char const *, 1> const RequiredInstanceLayers{
"VK_LAYER_KHRONOS_validation",
};
StaticArray<char const *, 3> const RequiredInstanceExtensions{
VK_KHR_SURFACE_EXTENSION_NAME,
VK_EXT_DEBUG_UTILS_EXTENSION_NAME,
VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
};
VkApplicationInfo ApplicationInfo;
ApplicationInfo.sType              = VK_STRUCTURE_TYPE_APPLICATION_INFO;
ApplicationInfo.pNext              = nullptr;
ApplicationInfo.pApplicationName   = "Application";
ApplicationInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
ApplicationInfo.pEngineName        = "Engine";
ApplicationInfo.engineVersion      = VK_MAKE_VERSION(1, 0, 0);
ApplicationInfo.apiVersion         = VK_API_VERSION_1_2;
VkInstanceCreateInfo InstanceCreateInfo;
InstanceCreateInfo.sType                   = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
InstanceCreateInfo.pNext                   = nullptr;
InstanceCreateInfo.flags                   = 0;
InstanceCreateInfo.pApplicationInfo        = &ApplicationInfo;
InstanceCreateInfo.enabledLayerCount       = RequiredInstanceLayers.length;
InstanceCreateInfo.ppEnabledLayerNames     = RequiredInstanceLayers.data;
InstanceCreateInfo.enabledExtensionCount   = RequiredInstanceExtensions.length;
InstanceCreateInfo.ppEnabledExtensionNames = RequiredInstanceExtensions.data;
vkCreateInstance(&InstanceCreateInfo, nullptr, &m_instance);
Uint32 physical_device_count;
vkEnumeratePhysicalDevices(m_instance, &physical_device_count, nullptr);
m_available_physical_devices.Create(m_allocator, physical_device_count);
vkEnumeratePhysicalDevices(m_instance, &physical_device_count, m_available_physical_devices.beg);
for (auto it = m_available_physical_devices.beg; it != m_available_physical_devices.end; ++it)
{
{ // Test 1
VkPhysicalDeviceProperties2 Properties2;
VkPhysicalDeviceVulkan11Properties Vulkan11Properties;
VkPhysicalDeviceVulkan12Properties Vulkan12Properties;
Properties2.sType        = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
Vulkan11Properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES;
Vulkan12Properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES;
Properties2.pNext        = &Vulkan11Properties;
Vulkan11Properties.pNext = &Vulkan12Properties;
Vulkan12Properties.pNext = nullptr;
vkGetPhysicalDeviceProperties2(*it, &Properties2); // only Properties2 is filled out
// Vulkan11Properties and Vulkan12Properties contain undefined data
}
{ // Test 2
VkPhysicalDeviceProperties2                   Properties2;
VkPhysicalDeviceDriverProperties              DriverProperties;
VkPhysicalDeviceFloatControlsProperties       FloatControlsProperties;
VkPhysicalDeviceDescriptorIndexingProperties  DescriptorIndexingProperties;
VkPhysicalDeviceDepthStencilResolveProperties DepthStencilResolveProperties;
VkPhysicalDeviceSamplerFilterMinmaxProperties SamplerFilterMinmaxProperties;
VkPhysicalDeviceTimelineSemaphoreProperties   TimelineSemaphoreProperties;
VkPhysicalDeviceIDProperties                  IDProperties;
VkPhysicalDeviceSubgroupProperties            SubgroupProperties;
VkPhysicalDevicePointClippingProperties       PointClippingProperties;
VkPhysicalDeviceMultiviewProperties           MultiviewProperties;
VkPhysicalDeviceProtectedMemoryProperties     ProtectedMemoryProperties;
VkPhysicalDeviceMaintenance3Properties        Maintenance3Properties;
Properties2.sType                   = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
DriverProperties.sType              = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
FloatControlsProperties.sType       = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES;
DescriptorIndexingProperties.sType  = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES;
DepthStencilResolveProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES;
SamplerFilterMinmaxProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES;
TimelineSemaphoreProperties.sType   = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES;
IDProperties.sType                  = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
SubgroupProperties.sType            = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
PointClippingProperties.sType       = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES;
MultiviewProperties.sType           = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES;
ProtectedMemoryProperties.sType     = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES;
Maintenance3Properties.sType        = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES;
Properties2.pNext                   = &DriverProperties;
DriverProperties.pNext              = &FloatControlsProperties;
FloatControlsProperties.pNext       = &DescriptorIndexingProperties;
DescriptorIndexingProperties.pNext  = &DepthStencilResolveProperties;
DepthStencilResolveProperties.pNext = &SamplerFilterMinmaxProperties;
SamplerFilterMinmaxProperties.pNext = &TimelineSemaphoreProperties;
TimelineSemaphoreProperties.pNext   = &IDProperties;
IDProperties.pNext                  = &SubgroupProperties;
SubgroupProperties.pNext            = &PointClippingProperties;
PointClippingProperties.pNext       = &MultiviewProperties;
MultiviewProperties.pNext           = &ProtectedMemoryProperties;
ProtectedMemoryProperties.pNext     = &Maintenance3Properties;
Maintenance3Properties.pNext        = nullptr;
vkGetPhysicalDeviceProperties2(*it, &Properties2); // every structure is filled out
}
}

Nvidia 446.14 驱动程序是 Vulkan 1.1。VkPhysicalDeviceVulkan11PropertiesVkPhysicalDeviceVulkan12Properties都需要Vulkan 1.2。

struct保持不变,因为规范说:

实现的任何组件(加载程序、任何启用的层和驱动程序(都必须跳过链中的任何扩展结构,而不处理(读取sTypepNext成员除外(链中未由该组件支持的核心版本或扩展定义的任何扩展结构。

另一方面,它不是有效的用法:

pNext链中存在的每个结构都必须在运行时由支持的核心版本或启用的扩展定义。

因此,理想情况下,验证层应该抓住这一点。您应该在KhronosGroup/Vulkan-ValidationLayers上报告此问题。问题似乎是层不分青红皂白地检查它是什么版本,以及启用了哪些扩展。

最新更新