Avoid passing unsupported structs in mandatory features test
authorRicardo Garcia <rgarcia@igalia.com>
Mon, 21 Nov 2022 12:41:46 +0000 (13:41 +0100)
committerMatthew Netsch <quic_mnetsch@quicinc.com>
Thu, 1 Dec 2022 23:41:06 +0000 (23:41 +0000)
Before checking mandatory features, the list of available features is
queried from the physical device using a pNext chain. When adding
structures to the chain, the code was not properly verifying the
structure could be used according to the supported extensions and core
Vulkan version.

Affects:
dEQP-VK.info.device_mandatory_features

VK-GL-CTS issue: 4093
Components: Vulkan

Change-Id: I929b4503f7d0a09c513d0638e05ae61b6f70bb77

external/vulkancts/framework/vulkan/generated/vulkan/vkMandatoryFeatures.inl
external/vulkancts/scripts/gen_framework.py

index 893ebf5..9b4d36d 100644 (file)
@@ -3,6 +3,12 @@
  * This file was generated by /scripts/gen_framework.py
  */
 
+bool canUseFeaturesStruct (const vector<VkExtensionProperties>& deviceExtensions, uint32_t usedApiVersion, const char* extension)
+{
+       return (isExtensionStructSupported(deviceExtensions, RequiredExtension(extension))
+                       || isCoreDeviceExtension(usedApiVersion, extension));
+}
+
 bool checkMandatoryFeatures(const vkt::Context& context)
 {
        if (!context.isInstanceFunctionalitySupported("VK_KHR_get_physical_device_properties2"))
@@ -11,6 +17,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        VkPhysicalDevice                                        physicalDevice          = context.getPhysicalDevice();
        const InstanceInterface&                        vki                                     = context.getInstanceInterface();
        const vector<VkExtensionProperties>     deviceExtensions        = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
+       const uint32_t                                          usedApiVersion          = context.getUsedApiVersion();
 
        tcu::TestLog& log = context.getTestContext().getLog();
        vk::VkPhysicalDeviceFeatures2 coreFeatures;
@@ -21,7 +28,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDevice16BitStorageFeatures physicalDevice16BitStorageFeatures;
        deMemset(&physicalDevice16BitStorageFeatures, 0, sizeof(physicalDevice16BitStorageFeatures));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_16bit_storage")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_16bit_storage") )
        {
                physicalDevice16BitStorageFeatures.sType = getStructureType<VkPhysicalDevice16BitStorageFeatures>();
                *nextPtr = &physicalDevice16BitStorageFeatures;
@@ -31,7 +38,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDevice4444FormatsFeaturesEXT physicalDevice4444FormatsFeaturesEXT;
        deMemset(&physicalDevice4444FormatsFeaturesEXT, 0, sizeof(physicalDevice4444FormatsFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_4444_formats")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_4444_formats") )
        {
                physicalDevice4444FormatsFeaturesEXT.sType = getStructureType<VkPhysicalDevice4444FormatsFeaturesEXT>();
                *nextPtr = &physicalDevice4444FormatsFeaturesEXT;
@@ -41,7 +48,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDevice8BitStorageFeatures physicalDevice8BitStorageFeatures;
        deMemset(&physicalDevice8BitStorageFeatures, 0, sizeof(physicalDevice8BitStorageFeatures));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_8bit_storage")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_8bit_storage") )
        {
                physicalDevice8BitStorageFeatures.sType = getStructureType<VkPhysicalDevice8BitStorageFeatures>();
                *nextPtr = &physicalDevice8BitStorageFeatures;
@@ -51,7 +58,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceAccelerationStructureFeaturesKHR physicalDeviceAccelerationStructureFeaturesKHR;
        deMemset(&physicalDeviceAccelerationStructureFeaturesKHR, 0, sizeof(physicalDeviceAccelerationStructureFeaturesKHR));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_acceleration_structure")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_acceleration_structure") )
        {
                physicalDeviceAccelerationStructureFeaturesKHR.sType = getStructureType<VkPhysicalDeviceAccelerationStructureFeaturesKHR>();
                *nextPtr = &physicalDeviceAccelerationStructureFeaturesKHR;
@@ -72,7 +79,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT physicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT;
        deMemset(&physicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT, 0, sizeof(physicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_attachment_feedback_loop_layout")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_attachment_feedback_loop_layout") )
        {
                physicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT.sType = getStructureType<VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT>();
                *nextPtr = &physicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT;
@@ -84,7 +91,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceBorderColorSwizzleFeaturesEXT physicalDeviceBorderColorSwizzleFeaturesEXT;
        deMemset(&physicalDeviceBorderColorSwizzleFeaturesEXT, 0, sizeof(physicalDeviceBorderColorSwizzleFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_border_color_swizzle")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_border_color_swizzle") )
        {
                physicalDeviceBorderColorSwizzleFeaturesEXT.sType = getStructureType<VkPhysicalDeviceBorderColorSwizzleFeaturesEXT>();
                *nextPtr = &physicalDeviceBorderColorSwizzleFeaturesEXT;
@@ -95,7 +102,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceBufferDeviceAddressFeatures physicalDeviceBufferDeviceAddressFeatures;
        deMemset(&physicalDeviceBufferDeviceAddressFeatures, 0, sizeof(physicalDeviceBufferDeviceAddressFeatures));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_buffer_device_address")) || context.contextSupports(vk::ApiVersion(0, 1, 1, 0)) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_buffer_device_address") )
        {
                physicalDeviceBufferDeviceAddressFeatures.sType = getStructureType<VkPhysicalDeviceBufferDeviceAddressFeatures>();
                *nextPtr = &physicalDeviceBufferDeviceAddressFeatures;
@@ -105,7 +112,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceColorWriteEnableFeaturesEXT physicalDeviceColorWriteEnableFeaturesEXT;
        deMemset(&physicalDeviceColorWriteEnableFeaturesEXT, 0, sizeof(physicalDeviceColorWriteEnableFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_color_write_enable")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_color_write_enable") )
        {
                physicalDeviceColorWriteEnableFeaturesEXT.sType = getStructureType<VkPhysicalDeviceColorWriteEnableFeaturesEXT>();
                *nextPtr = &physicalDeviceColorWriteEnableFeaturesEXT;
@@ -115,7 +122,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceConditionalRenderingFeaturesEXT physicalDeviceConditionalRenderingFeaturesEXT;
        deMemset(&physicalDeviceConditionalRenderingFeaturesEXT, 0, sizeof(physicalDeviceConditionalRenderingFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_conditional_rendering")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_conditional_rendering") )
        {
                physicalDeviceConditionalRenderingFeaturesEXT.sType = getStructureType<VkPhysicalDeviceConditionalRenderingFeaturesEXT>();
                *nextPtr = &physicalDeviceConditionalRenderingFeaturesEXT;
@@ -125,7 +132,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceDepthClampZeroOneFeaturesEXT physicalDeviceDepthClampZeroOneFeaturesEXT;
        deMemset(&physicalDeviceDepthClampZeroOneFeaturesEXT, 0, sizeof(physicalDeviceDepthClampZeroOneFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_depth_clamp_zero_one")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_depth_clamp_zero_one") )
        {
                physicalDeviceDepthClampZeroOneFeaturesEXT.sType = getStructureType<VkPhysicalDeviceDepthClampZeroOneFeaturesEXT>();
                *nextPtr = &physicalDeviceDepthClampZeroOneFeaturesEXT;
@@ -135,7 +142,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceDepthClipControlFeaturesEXT physicalDeviceDepthClipControlFeaturesEXT;
        deMemset(&physicalDeviceDepthClipControlFeaturesEXT, 0, sizeof(physicalDeviceDepthClipControlFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_depth_clip_control")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_depth_clip_control") )
        {
                physicalDeviceDepthClipControlFeaturesEXT.sType = getStructureType<VkPhysicalDeviceDepthClipControlFeaturesEXT>();
                *nextPtr = &physicalDeviceDepthClipControlFeaturesEXT;
@@ -145,7 +152,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceDepthClipEnableFeaturesEXT physicalDeviceDepthClipEnableFeaturesEXT;
        deMemset(&physicalDeviceDepthClipEnableFeaturesEXT, 0, sizeof(physicalDeviceDepthClipEnableFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_depth_clip_enable")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_depth_clip_enable") )
        {
                physicalDeviceDepthClipEnableFeaturesEXT.sType = getStructureType<VkPhysicalDeviceDepthClipEnableFeaturesEXT>();
                *nextPtr = &physicalDeviceDepthClipEnableFeaturesEXT;
@@ -165,7 +172,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceDescriptorIndexingFeatures physicalDeviceDescriptorIndexingFeatures;
        deMemset(&physicalDeviceDescriptorIndexingFeatures, 0, sizeof(physicalDeviceDescriptorIndexingFeatures));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_descriptor_indexing")) || context.contextSupports(vk::ApiVersion(0, 1, 1, 0)) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_descriptor_indexing") )
        {
                physicalDeviceDescriptorIndexingFeatures.sType = getStructureType<VkPhysicalDeviceDescriptorIndexingFeatures>();
                *nextPtr = &physicalDeviceDescriptorIndexingFeatures;
@@ -175,7 +182,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceExtendedDynamicState2FeaturesEXT physicalDeviceExtendedDynamicState2FeaturesEXT;
        deMemset(&physicalDeviceExtendedDynamicState2FeaturesEXT, 0, sizeof(physicalDeviceExtendedDynamicState2FeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_extended_dynamic_state2")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_extended_dynamic_state2") )
        {
                physicalDeviceExtendedDynamicState2FeaturesEXT.sType = getStructureType<VkPhysicalDeviceExtendedDynamicState2FeaturesEXT>();
                *nextPtr = &physicalDeviceExtendedDynamicState2FeaturesEXT;
@@ -195,7 +202,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceFragmentDensityMapFeaturesEXT physicalDeviceFragmentDensityMapFeaturesEXT;
        deMemset(&physicalDeviceFragmentDensityMapFeaturesEXT, 0, sizeof(physicalDeviceFragmentDensityMapFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_fragment_density_map")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_fragment_density_map") )
        {
                physicalDeviceFragmentDensityMapFeaturesEXT.sType = getStructureType<VkPhysicalDeviceFragmentDensityMapFeaturesEXT>();
                *nextPtr = &physicalDeviceFragmentDensityMapFeaturesEXT;
@@ -205,7 +212,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT physicalDeviceFragmentShaderInterlockFeaturesEXT;
        deMemset(&physicalDeviceFragmentShaderInterlockFeaturesEXT, 0, sizeof(physicalDeviceFragmentShaderInterlockFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_fragment_shader_interlock")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_fragment_shader_interlock") )
        {
                physicalDeviceFragmentShaderInterlockFeaturesEXT.sType = getStructureType<VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT>();
                *nextPtr = &physicalDeviceFragmentShaderInterlockFeaturesEXT;
@@ -216,7 +223,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceFragmentShadingRateFeaturesKHR physicalDeviceFragmentShadingRateFeaturesKHR;
        deMemset(&physicalDeviceFragmentShadingRateFeaturesKHR, 0, sizeof(physicalDeviceFragmentShadingRateFeaturesKHR));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_fragment_shading_rate")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_fragment_shading_rate") )
        {
                physicalDeviceFragmentShadingRateFeaturesKHR.sType = getStructureType<VkPhysicalDeviceFragmentShadingRateFeaturesKHR>();
                *nextPtr = &physicalDeviceFragmentShadingRateFeaturesKHR;
@@ -227,7 +234,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR physicalDeviceGlobalPriorityQueryFeaturesKHR;
        deMemset(&physicalDeviceGlobalPriorityQueryFeaturesKHR, 0, sizeof(physicalDeviceGlobalPriorityQueryFeaturesKHR));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_global_priority_query")) || isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_global_priority")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_global_priority") || canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_global_priority_query") )
        {
                physicalDeviceGlobalPriorityQueryFeaturesKHR.sType = getStructureType<VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR>();
                *nextPtr = &physicalDeviceGlobalPriorityQueryFeaturesKHR;
@@ -237,7 +244,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceHostQueryResetFeatures physicalDeviceHostQueryResetFeatures;
        deMemset(&physicalDeviceHostQueryResetFeatures, 0, sizeof(physicalDeviceHostQueryResetFeatures));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_host_query_reset")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_host_query_reset") )
        {
                physicalDeviceHostQueryResetFeatures.sType = getStructureType<VkPhysicalDeviceHostQueryResetFeatures>();
                *nextPtr = &physicalDeviceHostQueryResetFeatures;
@@ -248,7 +255,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceImage2DViewOf3DFeaturesEXT physicalDeviceImage2DViewOf3DFeaturesEXT;
        deMemset(&physicalDeviceImage2DViewOf3DFeaturesEXT, 0, sizeof(physicalDeviceImage2DViewOf3DFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_image_2d_view_of_3d")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_image_2d_view_of_3d") )
        {
                physicalDeviceImage2DViewOf3DFeaturesEXT.sType = getStructureType<VkPhysicalDeviceImage2DViewOf3DFeaturesEXT>();
                *nextPtr = &physicalDeviceImage2DViewOf3DFeaturesEXT;
@@ -259,7 +266,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceImageCompressionControlFeaturesEXT physicalDeviceImageCompressionControlFeaturesEXT;
        deMemset(&physicalDeviceImageCompressionControlFeaturesEXT, 0, sizeof(physicalDeviceImageCompressionControlFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_image_compression_control")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_image_compression_control") )
        {
                physicalDeviceImageCompressionControlFeaturesEXT.sType = getStructureType<VkPhysicalDeviceImageCompressionControlFeaturesEXT>();
                *nextPtr = &physicalDeviceImageCompressionControlFeaturesEXT;
@@ -269,7 +276,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT physicalDeviceImageCompressionControlSwapchainFeaturesEXT;
        deMemset(&physicalDeviceImageCompressionControlSwapchainFeaturesEXT, 0, sizeof(physicalDeviceImageCompressionControlSwapchainFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_image_compression_control")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_image_compression_control_swapchain") )
        {
                physicalDeviceImageCompressionControlSwapchainFeaturesEXT.sType = getStructureType<VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT>();
                *nextPtr = &physicalDeviceImageCompressionControlSwapchainFeaturesEXT;
@@ -279,7 +286,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceImagelessFramebufferFeatures physicalDeviceImagelessFramebufferFeatures;
        deMemset(&physicalDeviceImagelessFramebufferFeatures, 0, sizeof(physicalDeviceImagelessFramebufferFeatures));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_imageless_framebuffer")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_imageless_framebuffer") )
        {
                physicalDeviceImagelessFramebufferFeatures.sType = getStructureType<VkPhysicalDeviceImagelessFramebufferFeatures>();
                *nextPtr = &physicalDeviceImagelessFramebufferFeatures;
@@ -289,7 +296,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceIndexTypeUint8FeaturesEXT physicalDeviceIndexTypeUint8FeaturesEXT;
        deMemset(&physicalDeviceIndexTypeUint8FeaturesEXT, 0, sizeof(physicalDeviceIndexTypeUint8FeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_index_type_uint8")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_index_type_uint8") )
        {
                physicalDeviceIndexTypeUint8FeaturesEXT.sType = getStructureType<VkPhysicalDeviceIndexTypeUint8FeaturesEXT>();
                *nextPtr = &physicalDeviceIndexTypeUint8FeaturesEXT;
@@ -299,7 +306,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceInlineUniformBlockFeaturesEXT physicalDeviceInlineUniformBlockFeaturesEXT;
        deMemset(&physicalDeviceInlineUniformBlockFeaturesEXT, 0, sizeof(physicalDeviceInlineUniformBlockFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_inline_uniform_block")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_inline_uniform_block") )
        {
                physicalDeviceInlineUniformBlockFeaturesEXT.sType = getStructureType<VkPhysicalDeviceInlineUniformBlockFeaturesEXT>();
                *nextPtr = &physicalDeviceInlineUniformBlockFeaturesEXT;
@@ -309,7 +316,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceLegacyDitheringFeaturesEXT physicalDeviceLegacyDitheringFeaturesEXT;
        deMemset(&physicalDeviceLegacyDitheringFeaturesEXT, 0, sizeof(physicalDeviceLegacyDitheringFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_legacy_dithering")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_legacy_dithering") )
        {
                physicalDeviceLegacyDitheringFeaturesEXT.sType = getStructureType<VkPhysicalDeviceLegacyDitheringFeaturesEXT>();
                *nextPtr = &physicalDeviceLegacyDitheringFeaturesEXT;
@@ -319,7 +326,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceLineRasterizationFeaturesEXT physicalDeviceLineRasterizationFeaturesEXT;
        deMemset(&physicalDeviceLineRasterizationFeaturesEXT, 0, sizeof(physicalDeviceLineRasterizationFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_line_rasterization")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_line_rasterization") )
        {
                physicalDeviceLineRasterizationFeaturesEXT.sType = getStructureType<VkPhysicalDeviceLineRasterizationFeaturesEXT>();
                *nextPtr = &physicalDeviceLineRasterizationFeaturesEXT;
@@ -329,7 +336,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceMemoryPriorityFeaturesEXT physicalDeviceMemoryPriorityFeaturesEXT;
        deMemset(&physicalDeviceMemoryPriorityFeaturesEXT, 0, sizeof(physicalDeviceMemoryPriorityFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_memory_priority")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_memory_priority") )
        {
                physicalDeviceMemoryPriorityFeaturesEXT.sType = getStructureType<VkPhysicalDeviceMemoryPriorityFeaturesEXT>();
                *nextPtr = &physicalDeviceMemoryPriorityFeaturesEXT;
@@ -340,7 +347,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceMeshShaderFeaturesEXT physicalDeviceMeshShaderFeaturesEXT;
        deMemset(&physicalDeviceMeshShaderFeaturesEXT, 0, sizeof(physicalDeviceMeshShaderFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_mesh_shader")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_mesh_shader") )
        {
                physicalDeviceMeshShaderFeaturesEXT.sType = getStructureType<VkPhysicalDeviceMeshShaderFeaturesEXT>();
                *nextPtr = &physicalDeviceMeshShaderFeaturesEXT;
@@ -351,7 +358,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceMultiDrawFeaturesEXT physicalDeviceMultiDrawFeaturesEXT;
        deMemset(&physicalDeviceMultiDrawFeaturesEXT, 0, sizeof(physicalDeviceMultiDrawFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_multi_draw")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_multi_draw") )
        {
                physicalDeviceMultiDrawFeaturesEXT.sType = getStructureType<VkPhysicalDeviceMultiDrawFeaturesEXT>();
                *nextPtr = &physicalDeviceMultiDrawFeaturesEXT;
@@ -361,7 +368,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT physicalDeviceMultisampledRenderToSingleSampledFeaturesEXT;
        deMemset(&physicalDeviceMultisampledRenderToSingleSampledFeaturesEXT, 0, sizeof(physicalDeviceMultisampledRenderToSingleSampledFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_multisampled_render_to_single_sampled")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_multisampled_render_to_single_sampled") )
        {
                physicalDeviceMultisampledRenderToSingleSampledFeaturesEXT.sType = getStructureType<VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT>();
                *nextPtr = &physicalDeviceMultisampledRenderToSingleSampledFeaturesEXT;
@@ -371,7 +378,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceMultiviewFeatures physicalDeviceMultiviewFeatures;
        deMemset(&physicalDeviceMultiviewFeatures, 0, sizeof(physicalDeviceMultiviewFeatures));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_multiview")) || context.contextSupports(vk::ApiVersion(0, 1, 1, 0)) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_multiview") )
        {
                physicalDeviceMultiviewFeatures.sType = getStructureType<VkPhysicalDeviceMultiviewFeatures>();
                *nextPtr = &physicalDeviceMultiviewFeatures;
@@ -391,7 +398,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE physicalDeviceMutableDescriptorTypeFeaturesVALVE;
        deMemset(&physicalDeviceMutableDescriptorTypeFeaturesVALVE, 0, sizeof(physicalDeviceMutableDescriptorTypeFeaturesVALVE));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_VALVE_mutable_descriptor_type")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_VALVE_mutable_descriptor_type") || canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_mutable_descriptor_type") )
        {
                physicalDeviceMutableDescriptorTypeFeaturesVALVE.sType = getStructureType<VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE>();
                *nextPtr = &physicalDeviceMutableDescriptorTypeFeaturesVALVE;
@@ -402,7 +409,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT physicalDeviceNonSeamlessCubeMapFeaturesEXT;
        deMemset(&physicalDeviceNonSeamlessCubeMapFeaturesEXT, 0, sizeof(physicalDeviceNonSeamlessCubeMapFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_non_seamless_cube_map")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_non_seamless_cube_map") )
        {
                physicalDeviceNonSeamlessCubeMapFeaturesEXT.sType = getStructureType<VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT>();
                *nextPtr = &physicalDeviceNonSeamlessCubeMapFeaturesEXT;
@@ -414,7 +421,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceOpacityMicromapFeaturesEXT physicalDeviceOpacityMicromapFeaturesEXT;
        deMemset(&physicalDeviceOpacityMicromapFeaturesEXT, 0, sizeof(physicalDeviceOpacityMicromapFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_opacity_micromap")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_opacity_micromap") )
        {
                physicalDeviceOpacityMicromapFeaturesEXT.sType = getStructureType<VkPhysicalDeviceOpacityMicromapFeaturesEXT>();
                *nextPtr = &physicalDeviceOpacityMicromapFeaturesEXT;
@@ -426,7 +433,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT physicalDevicePageableDeviceLocalMemoryFeaturesEXT;
        deMemset(&physicalDevicePageableDeviceLocalMemoryFeaturesEXT, 0, sizeof(physicalDevicePageableDeviceLocalMemoryFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_pageable_device_local_memory")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_pageable_device_local_memory") )
        {
                physicalDevicePageableDeviceLocalMemoryFeaturesEXT.sType = getStructureType<VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT>();
                *nextPtr = &physicalDevicePageableDeviceLocalMemoryFeaturesEXT;
@@ -437,7 +444,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDevicePerformanceQueryFeaturesKHR physicalDevicePerformanceQueryFeaturesKHR;
        deMemset(&physicalDevicePerformanceQueryFeaturesKHR, 0, sizeof(physicalDevicePerformanceQueryFeaturesKHR));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_performance_query")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_performance_query") )
        {
                physicalDevicePerformanceQueryFeaturesKHR.sType = getStructureType<VkPhysicalDevicePerformanceQueryFeaturesKHR>();
                *nextPtr = &physicalDevicePerformanceQueryFeaturesKHR;
@@ -447,7 +454,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR physicalDevicePipelineExecutablePropertiesFeaturesKHR;
        deMemset(&physicalDevicePipelineExecutablePropertiesFeaturesKHR, 0, sizeof(physicalDevicePipelineExecutablePropertiesFeaturesKHR));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_pipeline_executable_properties")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_pipeline_executable_properties") )
        {
                physicalDevicePipelineExecutablePropertiesFeaturesKHR.sType = getStructureType<VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR>();
                *nextPtr = &physicalDevicePipelineExecutablePropertiesFeaturesKHR;
@@ -457,7 +464,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDevicePipelineProtectedAccessFeaturesEXT physicalDevicePipelineProtectedAccessFeaturesEXT;
        deMemset(&physicalDevicePipelineProtectedAccessFeaturesEXT, 0, sizeof(physicalDevicePipelineProtectedAccessFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_pipeline_protected_access")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_pipeline_protected_access") )
        {
                physicalDevicePipelineProtectedAccessFeaturesEXT.sType = getStructureType<VkPhysicalDevicePipelineProtectedAccessFeaturesEXT>();
                *nextPtr = &physicalDevicePipelineProtectedAccessFeaturesEXT;
@@ -468,7 +475,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDevicePresentIdFeaturesKHR physicalDevicePresentIdFeaturesKHR;
        deMemset(&physicalDevicePresentIdFeaturesKHR, 0, sizeof(physicalDevicePresentIdFeaturesKHR));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_present_id")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_present_id") )
        {
                physicalDevicePresentIdFeaturesKHR.sType = getStructureType<VkPhysicalDevicePresentIdFeaturesKHR>();
                *nextPtr = &physicalDevicePresentIdFeaturesKHR;
@@ -480,7 +487,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDevicePresentWaitFeaturesKHR physicalDevicePresentWaitFeaturesKHR;
        deMemset(&physicalDevicePresentWaitFeaturesKHR, 0, sizeof(physicalDevicePresentWaitFeaturesKHR));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_present_wait")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_present_wait") )
        {
                physicalDevicePresentWaitFeaturesKHR.sType = getStructureType<VkPhysicalDevicePresentWaitFeaturesKHR>();
                *nextPtr = &physicalDevicePresentWaitFeaturesKHR;
@@ -492,7 +499,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT physicalDevicePrimitiveTopologyListRestartFeaturesEXT;
        deMemset(&physicalDevicePrimitiveTopologyListRestartFeaturesEXT, 0, sizeof(physicalDevicePrimitiveTopologyListRestartFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_primitive_topology_list_restart")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_primitive_topology_list_restart") )
        {
                physicalDevicePrimitiveTopologyListRestartFeaturesEXT.sType = getStructureType<VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT>();
                *nextPtr = &physicalDevicePrimitiveTopologyListRestartFeaturesEXT;
@@ -503,7 +510,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceRayQueryFeaturesKHR physicalDeviceRayQueryFeaturesKHR;
        deMemset(&physicalDeviceRayQueryFeaturesKHR, 0, sizeof(physicalDeviceRayQueryFeaturesKHR));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_ray_query")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_ray_query") )
        {
                physicalDeviceRayQueryFeaturesKHR.sType = getStructureType<VkPhysicalDeviceRayQueryFeaturesKHR>();
                *nextPtr = &physicalDeviceRayQueryFeaturesKHR;
@@ -513,7 +520,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceRayTracingMaintenance1FeaturesKHR physicalDeviceRayTracingMaintenance1FeaturesKHR;
        deMemset(&physicalDeviceRayTracingMaintenance1FeaturesKHR, 0, sizeof(physicalDeviceRayTracingMaintenance1FeaturesKHR));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_ray_tracing_maintenance1")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_ray_tracing_maintenance1") )
        {
                physicalDeviceRayTracingMaintenance1FeaturesKHR.sType = getStructureType<VkPhysicalDeviceRayTracingMaintenance1FeaturesKHR>();
                *nextPtr = &physicalDeviceRayTracingMaintenance1FeaturesKHR;
@@ -523,7 +530,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceRayTracingPipelineFeaturesKHR physicalDeviceRayTracingPipelineFeaturesKHR;
        deMemset(&physicalDeviceRayTracingPipelineFeaturesKHR, 0, sizeof(physicalDeviceRayTracingPipelineFeaturesKHR));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_ray_tracing_pipeline")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_ray_tracing_pipeline") )
        {
                physicalDeviceRayTracingPipelineFeaturesKHR.sType = getStructureType<VkPhysicalDeviceRayTracingPipelineFeaturesKHR>();
                *nextPtr = &physicalDeviceRayTracingPipelineFeaturesKHR;
@@ -533,7 +540,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceSamplerYcbcrConversionFeaturesKHR physicalDeviceSamplerYcbcrConversionFeaturesKHR;
        deMemset(&physicalDeviceSamplerYcbcrConversionFeaturesKHR, 0, sizeof(physicalDeviceSamplerYcbcrConversionFeaturesKHR));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_sampler_ycbcr_conversion")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_sampler_ycbcr_conversion") )
        {
                physicalDeviceSamplerYcbcrConversionFeaturesKHR.sType = getStructureType<VkPhysicalDeviceSamplerYcbcrConversionFeaturesKHR>();
                *nextPtr = &physicalDeviceSamplerYcbcrConversionFeaturesKHR;
@@ -543,7 +550,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceScalarBlockLayoutFeatures physicalDeviceScalarBlockLayoutFeatures;
        deMemset(&physicalDeviceScalarBlockLayoutFeatures, 0, sizeof(physicalDeviceScalarBlockLayoutFeatures));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_scalar_block_layout")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_scalar_block_layout") )
        {
                physicalDeviceScalarBlockLayoutFeatures.sType = getStructureType<VkPhysicalDeviceScalarBlockLayoutFeatures>();
                *nextPtr = &physicalDeviceScalarBlockLayoutFeatures;
@@ -553,7 +560,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures physicalDeviceSeparateDepthStencilLayoutsFeatures;
        deMemset(&physicalDeviceSeparateDepthStencilLayoutsFeatures, 0, sizeof(physicalDeviceSeparateDepthStencilLayoutsFeatures));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_separate_depth_stencil_layouts")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_separate_depth_stencil_layouts") )
        {
                physicalDeviceSeparateDepthStencilLayoutsFeatures.sType = getStructureType<VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures>();
                *nextPtr = &physicalDeviceSeparateDepthStencilLayoutsFeatures;
@@ -564,7 +571,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT physicalDeviceShaderAtomicFloat2FeaturesEXT;
        deMemset(&physicalDeviceShaderAtomicFloat2FeaturesEXT, 0, sizeof(physicalDeviceShaderAtomicFloat2FeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_shader_atomic_float2")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_shader_atomic_float2") )
        {
                physicalDeviceShaderAtomicFloat2FeaturesEXT.sType = getStructureType<VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT>();
                *nextPtr = &physicalDeviceShaderAtomicFloat2FeaturesEXT;
@@ -575,7 +582,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceShaderAtomicFloatFeaturesEXT physicalDeviceShaderAtomicFloatFeaturesEXT;
        deMemset(&physicalDeviceShaderAtomicFloatFeaturesEXT, 0, sizeof(physicalDeviceShaderAtomicFloatFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_shader_atomic_float")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_shader_atomic_float") )
        {
                physicalDeviceShaderAtomicFloatFeaturesEXT.sType = getStructureType<VkPhysicalDeviceShaderAtomicFloatFeaturesEXT>();
                *nextPtr = &physicalDeviceShaderAtomicFloatFeaturesEXT;
@@ -585,7 +592,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceShaderAtomicInt64Features physicalDeviceShaderAtomicInt64Features;
        deMemset(&physicalDeviceShaderAtomicInt64Features, 0, sizeof(physicalDeviceShaderAtomicInt64Features));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_shader_atomic_int64")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_shader_atomic_int64") )
        {
                physicalDeviceShaderAtomicInt64Features.sType = getStructureType<VkPhysicalDeviceShaderAtomicInt64Features>();
                *nextPtr = &physicalDeviceShaderAtomicInt64Features;
@@ -595,7 +602,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceShaderClockFeaturesKHR physicalDeviceShaderClockFeaturesKHR;
        deMemset(&physicalDeviceShaderClockFeaturesKHR, 0, sizeof(physicalDeviceShaderClockFeaturesKHR));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_shader_clock")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_shader_clock") )
        {
                physicalDeviceShaderClockFeaturesKHR.sType = getStructureType<VkPhysicalDeviceShaderClockFeaturesKHR>();
                *nextPtr = &physicalDeviceShaderClockFeaturesKHR;
@@ -605,7 +612,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT physicalDeviceShaderDemoteToHelperInvocationFeaturesEXT;
        deMemset(&physicalDeviceShaderDemoteToHelperInvocationFeaturesEXT, 0, sizeof(physicalDeviceShaderDemoteToHelperInvocationFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_shader_demote_to_helper_invocation")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_shader_demote_to_helper_invocation") )
        {
                physicalDeviceShaderDemoteToHelperInvocationFeaturesEXT.sType = getStructureType<VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT>();
                *nextPtr = &physicalDeviceShaderDemoteToHelperInvocationFeaturesEXT;
@@ -615,7 +622,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD physicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD;
        deMemset(&physicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD, 0, sizeof(physicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_AMD_shader_early_and_late_fragment_tests")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_AMD_shader_early_and_late_fragment_tests") )
        {
                physicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD.sType = getStructureType<VkPhysicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD>();
                *nextPtr = &physicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD;
@@ -625,7 +632,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceShaderFloat16Int8Features physicalDeviceShaderFloat16Int8Features;
        deMemset(&physicalDeviceShaderFloat16Int8Features, 0, sizeof(physicalDeviceShaderFloat16Int8Features));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_shader_float16_int8")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_shader_float16_int8") )
        {
                physicalDeviceShaderFloat16Int8Features.sType = getStructureType<VkPhysicalDeviceShaderFloat16Int8Features>();
                *nextPtr = &physicalDeviceShaderFloat16Int8Features;
@@ -635,7 +642,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT physicalDeviceShaderImageAtomicInt64FeaturesEXT;
        deMemset(&physicalDeviceShaderImageAtomicInt64FeaturesEXT, 0, sizeof(physicalDeviceShaderImageAtomicInt64FeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_shader_image_atomic_int64")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_shader_image_atomic_int64") )
        {
                physicalDeviceShaderImageAtomicInt64FeaturesEXT.sType = getStructureType<VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT>();
                *nextPtr = &physicalDeviceShaderImageAtomicInt64FeaturesEXT;
@@ -646,7 +653,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR physicalDeviceShaderIntegerDotProductFeaturesKHR;
        deMemset(&physicalDeviceShaderIntegerDotProductFeaturesKHR, 0, sizeof(physicalDeviceShaderIntegerDotProductFeaturesKHR));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_shader_integer_dot_product")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_shader_integer_dot_product") )
        {
                physicalDeviceShaderIntegerDotProductFeaturesKHR.sType = getStructureType<VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR>();
                *nextPtr = &physicalDeviceShaderIntegerDotProductFeaturesKHR;
@@ -657,7 +664,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT physicalDeviceShaderModuleIdentifierFeaturesEXT;
        deMemset(&physicalDeviceShaderModuleIdentifierFeaturesEXT, 0, sizeof(physicalDeviceShaderModuleIdentifierFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_shader_module_identifier")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_shader_module_identifier") )
        {
                physicalDeviceShaderModuleIdentifierFeaturesEXT.sType = getStructureType<VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT>();
                *nextPtr = &physicalDeviceShaderModuleIdentifierFeaturesEXT;
@@ -667,7 +674,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures physicalDeviceShaderSubgroupExtendedTypesFeatures;
        deMemset(&physicalDeviceShaderSubgroupExtendedTypesFeatures, 0, sizeof(physicalDeviceShaderSubgroupExtendedTypesFeatures));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_shader_subgroup_extended_types")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_shader_subgroup_extended_types") )
        {
                physicalDeviceShaderSubgroupExtendedTypesFeatures.sType = getStructureType<VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures>();
                *nextPtr = &physicalDeviceShaderSubgroupExtendedTypesFeatures;
@@ -677,7 +684,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR physicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR;
        deMemset(&physicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR, 0, sizeof(physicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_shader_subgroup_uniform_control_flow")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_shader_subgroup_uniform_control_flow") )
        {
                physicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR.sType = getStructureType<VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR>();
                *nextPtr = &physicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR;
@@ -687,7 +694,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR physicalDeviceShaderTerminateInvocationFeaturesKHR;
        deMemset(&physicalDeviceShaderTerminateInvocationFeaturesKHR, 0, sizeof(physicalDeviceShaderTerminateInvocationFeaturesKHR));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_shader_terminate_invocation")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_shader_terminate_invocation") )
        {
                physicalDeviceShaderTerminateInvocationFeaturesKHR.sType = getStructureType<VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR>();
                *nextPtr = &physicalDeviceShaderTerminateInvocationFeaturesKHR;
@@ -697,7 +704,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceSubgroupSizeControlFeaturesEXT physicalDeviceSubgroupSizeControlFeaturesEXT;
        deMemset(&physicalDeviceSubgroupSizeControlFeaturesEXT, 0, sizeof(physicalDeviceSubgroupSizeControlFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_subgroup_size_control")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_subgroup_size_control") )
        {
                physicalDeviceSubgroupSizeControlFeaturesEXT.sType = getStructureType<VkPhysicalDeviceSubgroupSizeControlFeaturesEXT>();
                *nextPtr = &physicalDeviceSubgroupSizeControlFeaturesEXT;
@@ -707,7 +714,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceSubpassMergeFeedbackFeaturesEXT physicalDeviceSubpassMergeFeedbackFeaturesEXT;
        deMemset(&physicalDeviceSubpassMergeFeedbackFeaturesEXT, 0, sizeof(physicalDeviceSubpassMergeFeedbackFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_subpass_merge_feedback")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_subpass_merge_feedback") )
        {
                physicalDeviceSubpassMergeFeedbackFeaturesEXT.sType = getStructureType<VkPhysicalDeviceSubpassMergeFeedbackFeaturesEXT>();
                *nextPtr = &physicalDeviceSubpassMergeFeedbackFeaturesEXT;
@@ -717,7 +724,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceSynchronization2FeaturesKHR physicalDeviceSynchronization2FeaturesKHR;
        deMemset(&physicalDeviceSynchronization2FeaturesKHR, 0, sizeof(physicalDeviceSynchronization2FeaturesKHR));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_synchronization2")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_synchronization2") )
        {
                physicalDeviceSynchronization2FeaturesKHR.sType = getStructureType<VkPhysicalDeviceSynchronization2FeaturesKHR>();
                *nextPtr = &physicalDeviceSynchronization2FeaturesKHR;
@@ -727,7 +734,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT physicalDeviceTexelBufferAlignmentFeaturesEXT;
        deMemset(&physicalDeviceTexelBufferAlignmentFeaturesEXT, 0, sizeof(physicalDeviceTexelBufferAlignmentFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_texel_buffer_alignment")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_texel_buffer_alignment") )
        {
                physicalDeviceTexelBufferAlignmentFeaturesEXT.sType = getStructureType<VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT>();
                *nextPtr = &physicalDeviceTexelBufferAlignmentFeaturesEXT;
@@ -737,7 +744,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT physicalDeviceTextureCompressionASTCHDRFeaturesEXT;
        deMemset(&physicalDeviceTextureCompressionASTCHDRFeaturesEXT, 0, sizeof(physicalDeviceTextureCompressionASTCHDRFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_texture_compression_astc_hdr")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_texture_compression_astc_hdr") )
        {
                physicalDeviceTextureCompressionASTCHDRFeaturesEXT.sType = getStructureType<VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT>();
                *nextPtr = &physicalDeviceTextureCompressionASTCHDRFeaturesEXT;
@@ -748,7 +755,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceTimelineSemaphoreFeatures physicalDeviceTimelineSemaphoreFeatures;
        deMemset(&physicalDeviceTimelineSemaphoreFeatures, 0, sizeof(physicalDeviceTimelineSemaphoreFeatures));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_timeline_semaphore")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_timeline_semaphore") )
        {
                physicalDeviceTimelineSemaphoreFeatures.sType = getStructureType<VkPhysicalDeviceTimelineSemaphoreFeatures>();
                *nextPtr = &physicalDeviceTimelineSemaphoreFeatures;
@@ -759,7 +766,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceTransformFeedbackFeaturesEXT physicalDeviceTransformFeedbackFeaturesEXT;
        deMemset(&physicalDeviceTransformFeedbackFeaturesEXT, 0, sizeof(physicalDeviceTransformFeedbackFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_transform_feedback")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_transform_feedback") )
        {
                physicalDeviceTransformFeedbackFeaturesEXT.sType = getStructureType<VkPhysicalDeviceTransformFeedbackFeaturesEXT>();
                *nextPtr = &physicalDeviceTransformFeedbackFeaturesEXT;
@@ -769,7 +776,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceUniformBufferStandardLayoutFeatures physicalDeviceUniformBufferStandardLayoutFeatures;
        deMemset(&physicalDeviceUniformBufferStandardLayoutFeatures, 0, sizeof(physicalDeviceUniformBufferStandardLayoutFeatures));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_uniform_buffer_standard_layout")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_uniform_buffer_standard_layout") )
        {
                physicalDeviceUniformBufferStandardLayoutFeatures.sType = getStructureType<VkPhysicalDeviceUniformBufferStandardLayoutFeatures>();
                *nextPtr = &physicalDeviceUniformBufferStandardLayoutFeatures;
@@ -779,7 +786,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceVariablePointersFeatures physicalDeviceVariablePointersFeatures;
        deMemset(&physicalDeviceVariablePointersFeatures, 0, sizeof(physicalDeviceVariablePointersFeatures));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_variable_pointers")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_variable_pointers") )
        {
                physicalDeviceVariablePointersFeatures.sType = getStructureType<VkPhysicalDeviceVariablePointersFeatures>();
                *nextPtr = &physicalDeviceVariablePointersFeatures;
@@ -789,7 +796,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT physicalDeviceVertexAttributeDivisorFeaturesEXT;
        deMemset(&physicalDeviceVertexAttributeDivisorFeaturesEXT, 0, sizeof(physicalDeviceVertexAttributeDivisorFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_vertex_attribute_divisor")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_vertex_attribute_divisor") )
        {
                physicalDeviceVertexAttributeDivisorFeaturesEXT.sType = getStructureType<VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT>();
                *nextPtr = &physicalDeviceVertexAttributeDivisorFeaturesEXT;
@@ -799,7 +806,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT physicalDeviceVertexInputDynamicStateFeaturesEXT;
        deMemset(&physicalDeviceVertexInputDynamicStateFeaturesEXT, 0, sizeof(physicalDeviceVertexInputDynamicStateFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_vertex_input_dynamic_state")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_vertex_input_dynamic_state") )
        {
                physicalDeviceVertexInputDynamicStateFeaturesEXT.sType = getStructureType<VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT>();
                *nextPtr = &physicalDeviceVertexInputDynamicStateFeaturesEXT;
@@ -843,7 +850,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceVulkanMemoryModelFeatures physicalDeviceVulkanMemoryModelFeatures;
        deMemset(&physicalDeviceVulkanMemoryModelFeatures, 0, sizeof(physicalDeviceVulkanMemoryModelFeatures));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_vulkan_memory_model")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_vulkan_memory_model") )
        {
                physicalDeviceVulkanMemoryModelFeatures.sType = getStructureType<VkPhysicalDeviceVulkanMemoryModelFeatures>();
                *nextPtr = &physicalDeviceVulkanMemoryModelFeatures;
@@ -853,7 +860,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR physicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR;
        deMemset(&physicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR, 0, sizeof(physicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_workgroup_memory_explicit_layout")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_workgroup_memory_explicit_layout") )
        {
                physicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR.sType = getStructureType<VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR>();
                *nextPtr = &physicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR;
@@ -863,7 +870,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT physicalDeviceYcbcr2Plane444FormatsFeaturesEXT;
        deMemset(&physicalDeviceYcbcr2Plane444FormatsFeaturesEXT, 0, sizeof(physicalDeviceYcbcr2Plane444FormatsFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_ycbcr_2plane_444_formats")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_ycbcr_2plane_444_formats") )
        {
                physicalDeviceYcbcr2Plane444FormatsFeaturesEXT.sType = getStructureType<VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT>();
                *nextPtr = &physicalDeviceYcbcr2Plane444FormatsFeaturesEXT;
@@ -873,7 +880,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceYcbcrImageArraysFeaturesEXT physicalDeviceYcbcrImageArraysFeaturesEXT;
        deMemset(&physicalDeviceYcbcrImageArraysFeaturesEXT, 0, sizeof(physicalDeviceYcbcrImageArraysFeaturesEXT));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_ycbcr_image_arrays")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_EXT_ycbcr_image_arrays") )
        {
                physicalDeviceYcbcrImageArraysFeaturesEXT.sType = getStructureType<VkPhysicalDeviceYcbcrImageArraysFeaturesEXT>();
                *nextPtr = &physicalDeviceYcbcrImageArraysFeaturesEXT;
@@ -883,7 +890,7 @@ bool checkMandatoryFeatures(const vkt::Context& context)
        vk::VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR physicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR;
        deMemset(&physicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR, 0, sizeof(physicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR));
 
-       if ( isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_KHR_zero_initialize_workgroup_memory")) )
+       if ( canUseFeaturesStruct(deviceExtensions, usedApiVersion, "VK_KHR_zero_initialize_workgroup_memory") )
        {
                physicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR.sType = getStructureType<VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR>();
                *nextPtr = &physicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR;
index 0eec9ee..8e9ba28 100755 (executable)
@@ -2652,6 +2652,7 @@ def writeMandatoryFeatures(api, filename):
 
        dictStructs = {}
        dictData = []
+       usedFeatureStructs = {}
        for _, data in api.additionalExtensionData:
                if 'mandatory_features' not in data.keys():
                        continue
@@ -2674,6 +2675,7 @@ def writeMandatoryFeatures(api, filename):
 
                                if structure == 'VkPhysicalDeviceFeatures':
                                        continue
+
                                # if structure is not in dict construct name of variable and add is as a first item
                                if (structure not in dictStructs):
                                        dictStructs[structure] = ([structure[2:3].lower() + structure[3:]], mandatory_variant)
@@ -2681,14 +2683,28 @@ def writeMandatoryFeatures(api, filename):
                                if requirements and (requirements[0] not in dictStructs[structure][0]):
                                        dictStructs[structure][0].append(requirements[0])
 
+                               usedFeatureStructs[structure] = []
+
+                               if requirements:
+                                       for req in requirements:
+                                               if '.' in req:
+                                                       reqStruct = 'Vk' + req[0].upper() + req[1:]
+                                                       usedFeatureStructs[reqStruct] = []
 
-       stream.extend(['bool checkMandatoryFeatures(const vkt::Context& context)\n{',
+       stream.extend(['bool canUseFeaturesStruct (const vector<VkExtensionProperties>& deviceExtensions, uint32_t usedApiVersion, const char* extension)',
+                                  '{',
+                                  '\treturn (isExtensionStructSupported(deviceExtensions, RequiredExtension(extension))',
+                                  '\t\t\t|| isCoreDeviceExtension(usedApiVersion, extension));',
+                                  '}',
+                                  '',
+                                  'bool checkMandatoryFeatures(const vkt::Context& context)\n{',
                                   '\tif (!context.isInstanceFunctionalitySupported("VK_KHR_get_physical_device_properties2"))',
                                   '\t\tTCU_THROW(NotSupportedError, "Extension VK_KHR_get_physical_device_properties2 is not present");',
                                   '',
                                   '\tVkPhysicalDevice\t\t\t\t\tphysicalDevice\t\t= context.getPhysicalDevice();',
                                   '\tconst InstanceInterface&\t\t\tvki\t\t\t\t\t= context.getInstanceInterface();',
                                   '\tconst vector<VkExtensionProperties>\tdeviceExtensions\t= enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);',
+                                  '\tconst uint32_t\t\t\t\t\t\tusedApiVersion\t\t= context.getUsedApiVersion();',
                                   '',
                                   '\ttcu::TestLog& log = context.getTestContext().getLog();',
                                   '\tvk::VkPhysicalDeviceFeatures2 coreFeatures;',
@@ -2697,43 +2713,76 @@ def writeMandatoryFeatures(api, filename):
                                   '\tvoid** nextPtr = &coreFeatures.pNext;',
                                   ''])
 
-       listStruct = sorted(dictStructs.items(), key=lambda tup: tup[0]) # sort to have same results for py2 and py3
-       apiStruct       = list( filter(lambda x : structInAPI(x[0]), listStruct)) # remove items not defined in current A
+       # Find the extensions that added the required feature structs.
+       class StructFoundContinue(Exception):
+               pass
 
-       for k, v in apiStruct:
+       for usedStruct in usedFeatureStructs:
+               for compType in api.compositeTypes:
+                       nameList = [compType.name] + compType.aliasList
+                       if usedStruct in nameList:
+                               # Found the official name list for the struct.
+                               for extension in api.extensions:
+                                       try:
+                                               for requirement in extension.requirementsList:
+                                                       for extensionStructure in requirement.newTypes:
+                                                               if extensionStructure.name in nameList:
+                                                                       # Found extension for the struct.
+                                                                       usedFeatureStructs[usedStruct].append(extension.name)
+                                                                       raise StructFoundContinue
+                                       except StructFoundContinue:
+                                               pass
+
+       structList = sorted(usedFeatureStructs.items(), key=lambda tup: tup[0]) # sort to have same results for py2 and py3
+       apiStructs = list( filter(lambda x : structInAPI(x[0]), structList)) # remove items not defined in current API
+
+       for structName, extensions in apiStructs:
                metaCondition = ''
-               if v[1] != '':
-                       metaCondition = metaCondition + ' || defined(CTS_USES_' + v[1][0].upper() + ')'
-                       stream.extend(['#if ' + metaCondition[4:]])
-               if (v[0][1].startswith("ApiVersion")):
-                       cond = '\tif (context.contextSupports(vk::' + v[0][1] + '))'
-               else:
-                       cond = '\tif (vk::isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "' + v[0][1] + '"))'
-               stream.extend(['\tvk::' + k + ' ' + v[0][0]+ ';',
-                                       '\tdeMemset(&' + v[0][0] + ', 0, sizeof(' + v[0][0] + '));',
+               if structName in dictStructs:
+                       mandatoryVariantList = dictStructs[structName][1]
+                       if len(mandatoryVariantList) > 0:
+                               mandatoryVariant = mandatoryVariantList[0]
+                               metaCondition = 'defined(CTS_USES_' + mandatoryVariant.upper() + ')'
+                               stream.append('#if ' + metaCondition)
+
+               # The variable name will be the structure name without the Vk prefix and starting in lowercase.
+               newVar = structName[2].lower() + structName[3:]
+
+               stream.extend(['\tvk::' + structName + ' ' + newVar + ';',
+                                       '\tdeMemset(&' + newVar + ', 0, sizeof(' + newVar + '));',
                                        ''])
-               reqs = v[0][1:]
-               if len(reqs) > 0 :
-                       cond = 'if ( '
-                       for i, req in enumerate(reqs) :
-                               if (req.startswith("ApiVersion")):
-                                       cond = cond + 'context.contextSupports(vk::' + req + ')'
-                               else:
-                                       cond = cond + 'isExtensionStructSupported(deviceExtensions, RequiredExtension("' + req + '"))'
-                               if i+1 < len(reqs) :
-                                       cond = cond + ' || '
-                       cond = cond + ' )'
-                       stream.append('\t' + cond)
+
+               if len(extensions) > 0:
+                       canUseCond = '\tif ('
+                       for (i, extName) in enumerate(extensions):
+                               canUseCond += ' ' if i == 0 else ' || '
+                               canUseCond += 'canUseFeaturesStruct(deviceExtensions, usedApiVersion, "' + extName + '")'
+                       canUseCond += ' )'
+                       stream.append(canUseCond)
+               else:
+                       #reqs = v[0][1:]
+                       if structName in dictStructs:
+                               reqs = dictStructs[structName][0][1:]
+                               cond = 'if ( '
+                               for i, req in enumerate(reqs):
+                                       if i > 0:
+                                               cond = cond + ' || '
+                                       if (req.startswith("ApiVersion")):
+                                               cond = cond + 'context.contextSupports(vk::' + req + ')'
+                               cond = cond + ' )'
+                               stream.append('\t' + cond)
+
                stream.extend(['\t{',
-                                          '\t\t' + v[0][0] + '.sType = getStructureType<' + k + '>();',
-                                          '\t\t*nextPtr = &' + v[0][0] + ';',
-                                          '\t\tnextPtr  = &' + v[0][0] + '.pNext;',
+                                          '\t\t' + newVar + '.sType = getStructureType<' + structName + '>();',
+                                          '\t\t*nextPtr = &' + newVar + ';',
+                                          '\t\tnextPtr  = &' + newVar + '.pNext;',
                                           '\t}'])
-               if metaCondition != '':
-                       stream.extend(['#endif // ' + metaCondition[4:],
-                                                 ''])
-               else:
-                       stream.extend([''])
+
+               if len(metaCondition) > 0:
+                       stream.append('#endif // ' + metaCondition)
+
+               stream.append('')
+
        stream.extend(['\tcontext.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &coreFeatures);',
                                   '\tbool result = true;',
                                   ''])
@@ -2946,6 +2995,7 @@ if __name__ == "__main__":
                # was saved as gen_framework_sc (it still parses vulkan_sc_core.h)
                os.chdir(os.path.dirname(__file__))
                pythonExecutable = sys.executable or "python"
+               print("Executing gen_framework_sc.py")
                execute([pythonExecutable, "gen_framework_sc.py", "--api", "SC"])
                exit (0)