When using the function vkGetPhysicalDeviceProperties2 I pass a VkPhysicalDeviceProperties2 struct with a VkPhysicalDeviceVulkan11Properties and VkPhysicalDeviceVulkan12Properties in the pNext chain. However, after calling the function, only the vkGetPhysicalDeviceProperties2 contains valid data, the other structures in the chain contain undefined data.
When reviewing the spec, I noticed the comment about other structures Vulkan11 and Vulkan12 structures are supposed to encompass. When replacing them with their corresponding "smaller" structures and adding them to the chain. I do get valid data, which seems even stranger since I don't see what's preventing Vulkan from using the larger structures in the first place.
Note: Validation layers are silent
Info:
- Vulkan SDK: 1.2.141.0
- Nvidia Driver: 446.14
- GPU GeForce GTX 1060 with Max-Q Design
- OS: Windows 10.0.18363
- Compiler: Microsoft (R) C/C++ Optimizing Compiler Version 19.26.28806 for x64
Relevant Code:
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
}
}