Extend api.version_check.entry_points test

This adds a check that verifies that vkGet*ProcAddr returns valid
function pointers for extension functions. The tested extensions are
multi-author extensions that are supported by the device.

Also, the gen_framework.py script is updated to generate
a vkExtensionFunctions.inl file that contains functions of instance
and device extensions.

Affects:

dEQP-VK.api.version_check.entry_points

Components: Vulkan

VK-GL-CTS issue: 1374

Change-Id: Ia66319515300474f5dcbcab6f090ec15a823ca7b
diff --git a/external/vulkancts/framework/vulkan/vkExtensionFunctions.inl b/external/vulkancts/framework/vulkan/vkExtensionFunctions.inl
new file mode 100644
index 0000000..8ed1fae
--- /dev/null
+++ b/external/vulkancts/framework/vulkan/vkExtensionFunctions.inl
@@ -0,0 +1,340 @@
+/* WARNING: This is auto-generated file. Do not modify, since changes will
+ * be lost! Modify the generating script instead.
+ */
+
+void getInstanceExtensionFunctions (::std::string extName, ::std::vector<const char*>& functions)
+{
+	if (extName == "VK_KHR_surface")
+	{
+		functions.push_back("vkDestroySurfaceKHR");
+		functions.push_back("vkGetPhysicalDeviceSurfaceSupportKHR");
+		functions.push_back("vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
+		functions.push_back("vkGetPhysicalDeviceSurfaceFormatsKHR");
+		functions.push_back("vkGetPhysicalDeviceSurfacePresentModesKHR");
+	}
+	else if (extName == "VK_KHR_swapchain")
+		functions.push_back("vkGetPhysicalDevicePresentRectanglesKHR");
+	else if (extName == "VK_KHR_display")
+	{
+		functions.push_back("vkGetPhysicalDeviceDisplayPropertiesKHR");
+		functions.push_back("vkGetPhysicalDeviceDisplayPlanePropertiesKHR");
+		functions.push_back("vkGetDisplayPlaneSupportedDisplaysKHR");
+		functions.push_back("vkGetDisplayModePropertiesKHR");
+		functions.push_back("vkCreateDisplayModeKHR");
+		functions.push_back("vkGetDisplayPlaneCapabilitiesKHR");
+		functions.push_back("vkCreateDisplayPlaneSurfaceKHR");
+	}
+	else if (extName == "VK_KHR_xlib_surface")
+	{
+		functions.push_back("vkCreateXlibSurfaceKHR");
+		functions.push_back("vkGetPhysicalDeviceXlibPresentationSupportKHR");
+	}
+	else if (extName == "VK_KHR_xcb_surface")
+	{
+		functions.push_back("vkCreateXcbSurfaceKHR");
+		functions.push_back("vkGetPhysicalDeviceXcbPresentationSupportKHR");
+	}
+	else if (extName == "VK_KHR_wayland_surface")
+	{
+		functions.push_back("vkCreateWaylandSurfaceKHR");
+		functions.push_back("vkGetPhysicalDeviceWaylandPresentationSupportKHR");
+	}
+	else if (extName == "VK_KHR_mir_surface")
+	{
+		functions.push_back("vkCreateMirSurfaceKHR");
+		functions.push_back("vkGetPhysicalDeviceMirPresentationSupportKHR");
+	}
+	else if (extName == "VK_KHR_android_surface")
+		functions.push_back("vkCreateAndroidSurfaceKHR");
+	else if (extName == "VK_KHR_win32_surface")
+	{
+		functions.push_back("vkCreateWin32SurfaceKHR");
+		functions.push_back("vkGetPhysicalDeviceWin32PresentationSupportKHR");
+	}
+	else if (extName == "VK_KHR_get_physical_device_properties2")
+	{
+		functions.push_back("vkGetPhysicalDeviceFeatures2KHR");
+		functions.push_back("vkGetPhysicalDeviceFormatProperties2KHR");
+		functions.push_back("vkGetPhysicalDeviceImageFormatProperties2KHR");
+		functions.push_back("vkGetPhysicalDeviceMemoryProperties2KHR");
+		functions.push_back("vkGetPhysicalDeviceProperties2KHR");
+		functions.push_back("vkGetPhysicalDeviceQueueFamilyProperties2KHR");
+		functions.push_back("vkGetPhysicalDeviceSparseImageFormatProperties2KHR");
+	}
+	else if (extName == "VK_KHR_device_group_creation")
+		functions.push_back("vkEnumeratePhysicalDeviceGroupsKHR");
+	else if (extName == "VK_KHR_external_memory_capabilities")
+		functions.push_back("vkGetPhysicalDeviceExternalBufferPropertiesKHR");
+	else if (extName == "VK_KHR_external_semaphore_capabilities")
+		functions.push_back("vkGetPhysicalDeviceExternalSemaphorePropertiesKHR");
+	else if (extName == "VK_KHR_external_fence_capabilities")
+		functions.push_back("vkGetPhysicalDeviceExternalFencePropertiesKHR");
+	else if (extName == "VK_KHR_get_surface_capabilities2")
+	{
+		functions.push_back("vkGetPhysicalDeviceSurfaceCapabilities2KHR");
+		functions.push_back("vkGetPhysicalDeviceSurfaceFormats2KHR");
+	}
+	else if (extName == "VK_KHR_get_display_properties2")
+	{
+		functions.push_back("vkGetPhysicalDeviceDisplayProperties2KHR");
+		functions.push_back("vkGetPhysicalDeviceDisplayPlaneProperties2KHR");
+		functions.push_back("vkGetDisplayModeProperties2KHR");
+		functions.push_back("vkGetDisplayPlaneCapabilities2KHR");
+	}
+	else if (extName == "VK_EXT_debug_report")
+	{
+		functions.push_back("vkCreateDebugReportCallbackEXT");
+		functions.push_back("vkDestroyDebugReportCallbackEXT");
+		functions.push_back("vkDebugReportMessageEXT");
+	}
+	else if (extName == "VK_NV_external_memory_capabilities")
+		functions.push_back("vkGetPhysicalDeviceExternalImageFormatPropertiesNV");
+	else if (extName == "VK_NN_vi_surface")
+		functions.push_back("vkCreateViSurfaceNN");
+	else if (extName == "VK_NVX_device_generated_commands")
+		functions.push_back("vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX");
+	else if (extName == "VK_EXT_direct_mode_display")
+		functions.push_back("vkReleaseDisplayEXT");
+	else if (extName == "VK_EXT_acquire_xlib_display")
+	{
+		functions.push_back("vkAcquireXlibDisplayEXT");
+		functions.push_back("vkGetRandROutputDisplayEXT");
+	}
+	else if (extName == "VK_EXT_display_surface_counter")
+		functions.push_back("vkGetPhysicalDeviceSurfaceCapabilities2EXT");
+	else if (extName == "VK_MVK_ios_surface")
+		functions.push_back("vkCreateIOSSurfaceMVK");
+	else if (extName == "VK_MVK_macos_surface")
+		functions.push_back("vkCreateMacOSSurfaceMVK");
+	else if (extName == "VK_EXT_sample_locations")
+		functions.push_back("vkGetPhysicalDeviceMultisamplePropertiesEXT");
+	else
+		DE_ASSERT("Extension name not found");
+}
+
+void getDeviceExtensionFunctions (::std::string extName, ::std::vector<const char*>& functions)
+{
+	if (extName == "VK_KHR_swapchain")
+	{
+		functions.push_back("vkCreateSwapchainKHR");
+		functions.push_back("vkDestroySwapchainKHR");
+		functions.push_back("vkGetSwapchainImagesKHR");
+		functions.push_back("vkAcquireNextImageKHR");
+		functions.push_back("vkQueuePresentKHR");
+		functions.push_back("vkGetDeviceGroupPresentCapabilitiesKHR");
+		functions.push_back("vkGetDeviceGroupSurfacePresentModesKHR");
+		functions.push_back("vkAcquireNextImage2KHR");
+	}
+	else if (extName == "VK_KHR_display_swapchain")
+		functions.push_back("vkCreateSharedSwapchainsKHR");
+	else if (extName == "VK_KHR_device_group")
+	{
+		functions.push_back("vkCmdDispatchBaseKHR");
+		functions.push_back("vkCmdSetDeviceMaskKHR");
+		functions.push_back("vkGetDeviceGroupPeerMemoryFeaturesKHR");
+	}
+	else if (extName == "VK_KHR_maintenance1")
+		functions.push_back("vkTrimCommandPoolKHR");
+	else if (extName == "VK_KHR_external_memory_win32")
+	{
+		functions.push_back("vkGetMemoryWin32HandleKHR");
+		functions.push_back("vkGetMemoryWin32HandlePropertiesKHR");
+	}
+	else if (extName == "VK_KHR_external_memory_fd")
+	{
+		functions.push_back("vkGetMemoryFdKHR");
+		functions.push_back("vkGetMemoryFdPropertiesKHR");
+	}
+	else if (extName == "VK_KHR_external_semaphore_win32")
+	{
+		functions.push_back("vkImportSemaphoreWin32HandleKHR");
+		functions.push_back("vkGetSemaphoreWin32HandleKHR");
+	}
+	else if (extName == "VK_KHR_external_semaphore_fd")
+	{
+		functions.push_back("vkImportSemaphoreFdKHR");
+		functions.push_back("vkGetSemaphoreFdKHR");
+	}
+	else if (extName == "VK_KHR_push_descriptor")
+	{
+		functions.push_back("vkCmdPushDescriptorSetKHR");
+		functions.push_back("vkCmdPushDescriptorSetWithTemplateKHR");
+	}
+	else if (extName == "VK_KHR_descriptor_update_template")
+	{
+		functions.push_back("vkCreateDescriptorUpdateTemplateKHR");
+		functions.push_back("vkDestroyDescriptorUpdateTemplateKHR");
+		functions.push_back("vkUpdateDescriptorSetWithTemplateKHR");
+	}
+	else if (extName == "VK_KHR_create_renderpass2")
+	{
+		functions.push_back("vkCreateRenderPass2KHR");
+		functions.push_back("vkCmdBeginRenderPass2KHR");
+		functions.push_back("vkCmdNextSubpass2KHR");
+		functions.push_back("vkCmdEndRenderPass2KHR");
+	}
+	else if (extName == "VK_KHR_shared_presentable_image")
+		functions.push_back("vkGetSwapchainStatusKHR");
+	else if (extName == "VK_KHR_external_fence_win32")
+	{
+		functions.push_back("vkImportFenceWin32HandleKHR");
+		functions.push_back("vkGetFenceWin32HandleKHR");
+	}
+	else if (extName == "VK_KHR_external_fence_fd")
+	{
+		functions.push_back("vkImportFenceFdKHR");
+		functions.push_back("vkGetFenceFdKHR");
+	}
+	else if (extName == "VK_KHR_get_memory_requirements2")
+	{
+		functions.push_back("vkGetBufferMemoryRequirements2KHR");
+		functions.push_back("vkGetImageMemoryRequirements2KHR");
+		functions.push_back("vkGetImageSparseMemoryRequirements2KHR");
+	}
+	else if (extName == "VK_KHR_sampler_ycbcr_conversion")
+	{
+		functions.push_back("vkCreateSamplerYcbcrConversionKHR");
+		functions.push_back("vkDestroySamplerYcbcrConversionKHR");
+	}
+	else if (extName == "VK_KHR_bind_memory2")
+	{
+		functions.push_back("vkBindBufferMemory2KHR");
+		functions.push_back("vkBindImageMemory2KHR");
+	}
+	else if (extName == "VK_KHR_maintenance3")
+		functions.push_back("vkGetDescriptorSetLayoutSupportKHR");
+	else if (extName == "VK_EXT_debug_marker")
+	{
+		functions.push_back("vkDebugMarkerSetObjectTagEXT");
+		functions.push_back("vkDebugMarkerSetObjectNameEXT");
+		functions.push_back("vkCmdDebugMarkerBeginEXT");
+		functions.push_back("vkCmdDebugMarkerEndEXT");
+		functions.push_back("vkCmdDebugMarkerInsertEXT");
+	}
+	else if (extName == "VK_AMD_draw_indirect_count")
+	{
+		functions.push_back("vkCmdDrawIndirectCountAMD");
+		functions.push_back("vkCmdDrawIndexedIndirectCountAMD");
+	}
+	else if (extName == "VK_KHR_draw_indirect_count")
+	{
+		functions.push_back("vkCmdDrawIndirectCountKHR");
+		functions.push_back("vkCmdDrawIndexedIndirectCountKHR");
+	}
+	else if (extName == "VK_NV_external_memory_win32")
+		functions.push_back("vkGetMemoryWin32HandleNV");
+	else if (extName == "VK_EXT_conditional_rendering")
+	{
+		functions.push_back("vkCmdBeginConditionalRenderingEXT");
+		functions.push_back("vkCmdEndConditionalRenderingEXT");
+	}
+	else if (extName == "VK_NVX_device_generated_commands")
+	{
+		functions.push_back("vkCmdProcessCommandsNVX");
+		functions.push_back("vkCmdReserveSpaceForCommandsNVX");
+		functions.push_back("vkCreateIndirectCommandsLayoutNVX");
+		functions.push_back("vkDestroyIndirectCommandsLayoutNVX");
+		functions.push_back("vkCreateObjectTableNVX");
+		functions.push_back("vkDestroyObjectTableNVX");
+		functions.push_back("vkRegisterObjectsNVX");
+		functions.push_back("vkUnregisterObjectsNVX");
+	}
+	else if (extName == "VK_NV_clip_space_w_scaling")
+		functions.push_back("vkCmdSetViewportWScalingNV");
+	else if (extName == "VK_EXT_display_control")
+	{
+		functions.push_back("vkDisplayPowerControlEXT");
+		functions.push_back("vkRegisterDeviceEventEXT");
+		functions.push_back("vkRegisterDisplayEventEXT");
+		functions.push_back("vkGetSwapchainCounterEXT");
+	}
+	else if (extName == "VK_GOOGLE_display_timing")
+	{
+		functions.push_back("vkGetRefreshCycleDurationGOOGLE");
+		functions.push_back("vkGetPastPresentationTimingGOOGLE");
+	}
+	else if (extName == "VK_EXT_discard_rectangles")
+		functions.push_back("vkCmdSetDiscardRectangleEXT");
+	else if (extName == "VK_EXT_hdr_metadata")
+		functions.push_back("vkSetHdrMetadataEXT");
+	else if (extName == "VK_EXT_sample_locations")
+		functions.push_back("vkCmdSetSampleLocationsEXT");
+	else if (extName == "VK_EXT_validation_cache")
+	{
+		functions.push_back("vkCreateValidationCacheEXT");
+		functions.push_back("vkDestroyValidationCacheEXT");
+		functions.push_back("vkMergeValidationCachesEXT");
+		functions.push_back("vkGetValidationCacheDataEXT");
+	}
+	else if (extName == "VK_ANDROID_external_memory_android_hardware_buffer")
+	{
+		functions.push_back("vkGetMemoryHostPointerPropertiesEXT");
+		functions.push_back("vkGetAndroidHardwareBufferPropertiesANDROID");
+		functions.push_back("vkGetMemoryAndroidHardwareBufferANDROID");
+	}
+	else
+		DE_ASSERT("Extension name not found");
+}
+
+::std::string instanceExtensionNames[] =
+{
+	"VK_KHR_surface",
+	"VK_KHR_display",
+	"VK_KHR_xlib_surface",
+	"VK_KHR_xcb_surface",
+	"VK_KHR_wayland_surface",
+	"VK_KHR_mir_surface",
+	"VK_KHR_android_surface",
+	"VK_KHR_win32_surface",
+	"VK_KHR_get_physical_device_properties2",
+	"VK_KHR_device_group_creation",
+	"VK_KHR_external_memory_capabilities",
+	"VK_KHR_external_semaphore_capabilities",
+	"VK_KHR_external_fence_capabilities",
+	"VK_KHR_get_surface_capabilities2",
+	"VK_KHR_get_display_properties2",
+	"VK_EXT_debug_report",
+	"VK_NV_external_memory_capabilities",
+	"VK_NN_vi_surface",
+	"VK_EXT_direct_mode_display",
+	"VK_EXT_acquire_xlib_display",
+	"VK_EXT_display_surface_counter",
+	"VK_MVK_ios_surface",
+	"VK_MVK_macos_surface"
+};
+
+::std::string deviceExtensionNames[] =
+{
+	"VK_KHR_swapchain",
+	"VK_KHR_display_swapchain",
+	"VK_KHR_device_group",
+	"VK_KHR_maintenance1",
+	"VK_KHR_external_memory_win32",
+	"VK_KHR_external_memory_fd",
+	"VK_KHR_external_semaphore_win32",
+	"VK_KHR_external_semaphore_fd",
+	"VK_KHR_push_descriptor",
+	"VK_KHR_descriptor_update_template",
+	"VK_KHR_create_renderpass2",
+	"VK_KHR_shared_presentable_image",
+	"VK_KHR_external_fence_win32",
+	"VK_KHR_external_fence_fd",
+	"VK_KHR_get_memory_requirements2",
+	"VK_KHR_sampler_ycbcr_conversion",
+	"VK_KHR_bind_memory2",
+	"VK_KHR_maintenance3",
+	"VK_EXT_debug_marker",
+	"VK_AMD_draw_indirect_count",
+	"VK_KHR_draw_indirect_count",
+	"VK_NV_external_memory_win32",
+	"VK_EXT_conditional_rendering",
+	"VK_NVX_device_generated_commands",
+	"VK_NV_clip_space_w_scaling",
+	"VK_EXT_display_control",
+	"VK_GOOGLE_display_timing",
+	"VK_EXT_discard_rectangles",
+	"VK_EXT_hdr_metadata",
+	"VK_EXT_sample_locations",
+	"VK_EXT_validation_cache",
+	"VK_ANDROID_external_memory_android_hardware_buffer"
+};
diff --git a/external/vulkancts/modules/vulkan/api/vktApiVersionCheck.cpp b/external/vulkancts/modules/vulkan/api/vktApiVersionCheck.cpp
index 06b8fb7..174eeb9 100644
--- a/external/vulkancts/modules/vulkan/api/vktApiVersionCheck.cpp
+++ b/external/vulkancts/modules/vulkan/api/vktApiVersionCheck.cpp
@@ -2,7 +2,9 @@
 * Vulkan Conformance Tests
 * ------------------------
 *
-* Copyright (c) 2017 Khronos Group
+*
+* Copyright (c) 2019 Google Inc.
+* Copyright (c) 2019 Khronos Group
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -37,8 +39,9 @@
 #include "vktApiVersionCheck.hpp"
 #include "vktTestCase.hpp"
 
-#include "vkRefUtil.hpp"
 #include "vkDeviceUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkRefUtil.hpp"
 
 #include "deString.h"
 #include "deStringUtil.hpp"
@@ -58,6 +61,7 @@
 namespace
 {
 
+#include "vkExtensionFunctions.inl"
 #include "vkCoreFunctionalities.inl"
 
 class APIVersionTestInstance : public TestInstance
@@ -108,69 +112,117 @@
 	}
 	virtual tcu::TestStatus		iterate						(void)
 	{
-		tcu::TestLog&						log					= m_context.getTestContext().getLog();
-		const vk::Platform&					platform			= m_context.getTestContext().getPlatform().getVulkanPlatform();
-		de::MovePtr<vk::Library>			vkLibrary			= de::MovePtr<vk::Library>(platform.createLibrary());
-		const tcu::FunctionLibrary&			funcLibrary			= vkLibrary->getFunctionLibrary();
-		std::vector<std::string>			empty				= std::vector<std::string>();
-											instance			= createDefaultInstance(m_context.getPlatformInterface(), m_context.getUsedApiVersion(), empty, empty, DE_NULL);
-											device				= createTestDevice(m_context.getPlatformInterface(), m_context.getInstanceInterface(), m_context.getPhysicalDevice());
-											getInstanceProcAddr	= reinterpret_cast<GetInstanceProcAddrFunc>(funcLibrary.getFunction("vkGetInstanceProcAddr"));
-											getDeviceProcAddr	= reinterpret_cast<GetDeviceProcAddrFunc>(getInstanceProcAddr(*instance, "vkGetDeviceProcAddr"));
+		tcu::TestLog&						log				= m_context.getTestContext().getLog();
+		const deUint32						apiVersion		= m_context.getUsedApiVersion();
+		const vk::Platform&					platform		= m_context.getTestContext().getPlatform().getVulkanPlatform();
+		de::MovePtr<vk::Library>			vkLibrary		= de::MovePtr<vk::Library>(platform.createLibrary());
+		const tcu::FunctionLibrary&			funcLibrary		= vkLibrary->getFunctionLibrary();
 
-		deUint32							failsQuantity		= 0u;
+		deUint32							failsQuantity	= 0u;
 
+		// Tests with default instance and device without extensions
 		{
-			ApisMap							functions			= ApisMap();
-			initApisMap(functions);
-			ApisMap::const_iterator			lastGoodVersion		= functions.begin();
-			const ApisMap::const_iterator	versionsEnd			= functions.end();
-			for (ApisMap::const_iterator it = lastGoodVersion; it != versionsEnd; ++it)
+			instance			= createDefaultInstance(m_context.getPlatformInterface(), m_context.getUsedApiVersion());
+			device				= createTestDevice(m_context.getPlatformInterface(), m_context.getInstanceInterface(), m_context.getPhysicalDevice());
+			getInstanceProcAddr	= reinterpret_cast<GetInstanceProcAddrFunc>(funcLibrary.getFunction("vkGetInstanceProcAddr"));
+			getDeviceProcAddr	= reinterpret_cast<GetDeviceProcAddrFunc>(getInstanceProcAddr(*instance, "vkGetDeviceProcAddr"));
+
+			// Check entry points of core functions
 			{
-				if (it->first <= m_context.getUsedApiVersion())
-					lastGoodVersion = it;
+				ApisMap							functions			= ApisMap();
+				initApisMap(functions);
+				ApisMap::const_iterator			lastGoodVersion		= functions.begin();
+				const ApisMap::const_iterator	versionsEnd			= functions.end();
+				for (ApisMap::const_iterator it = lastGoodVersion; it != versionsEnd; ++it)
+				{
+					if (it->first <= m_context.getUsedApiVersion())
+						lastGoodVersion = it;
+				}
+
+				log << tcu::TestLog::Message << "Regular check - tries to get core functions from proper vkGet*ProcAddr." << tcu::TestLog::EndMessage;
+				const char* const				regularResult		= regularCheck(log, failsQuantity, lastGoodVersion->second) ? "Passed" : "Failed";
+				log << tcu::TestLog::Message << regularResult << tcu::TestLog::EndMessage;
+
+				log << tcu::TestLog::Message << "Cross check - tries to get core functions from improper vkGet*ProcAddr." << tcu::TestLog::EndMessage;
+				const char* const				mixupResult			= mixupAddressProcCheck(log, failsQuantity, lastGoodVersion->second) ? "Passed" : "Failed";
+				log << tcu::TestLog::Message << mixupResult << tcu::TestLog::EndMessage;
 			}
 
-			log << tcu::TestLog::Message << "Regular check - tries to get core functions from proper vkGet*ProcAddr." << tcu::TestLog::EndMessage;
-			const char* const				regularResult		= regularCheck(log, failsQuantity, lastGoodVersion->second) ? "Passed" : "Failed";
-			log << tcu::TestLog::Message << regularResult << tcu::TestLog::EndMessage;
-
-			log << tcu::TestLog::Message << "Cross check - tries to get core functions from improper vkGet*ProcAddr." << tcu::TestLog::EndMessage;
-			const char* const				mixupResult			= mixupAddressProcCheck(log, failsQuantity, lastGoodVersion->second) ? "Passed" : "Failed";
-			log << tcu::TestLog::Message << mixupResult << tcu::TestLog::EndMessage;
-		}
-
-		{
-			FunctionInfosList				extFunctions		= FunctionInfosList();
-			extFunctions.push_back(FunctionInfo("vkTrimCommandPoolKHR", FUNCTIONORIGIN_DEVICE));
-			extFunctions.push_back(FunctionInfo("vkCmdPushDescriptorSetKHR", FUNCTIONORIGIN_DEVICE));
-			extFunctions.push_back(FunctionInfo("vkCreateSamplerYcbcrConversionKHR", FUNCTIONORIGIN_DEVICE));
-			extFunctions.push_back(FunctionInfo("vkGetSwapchainStatusKHR", FUNCTIONORIGIN_DEVICE));
-			extFunctions.push_back(FunctionInfo("vkCreateSwapchainKHR", FUNCTIONORIGIN_DEVICE));
-			extFunctions.push_back(FunctionInfo("vkGetImageSparseMemoryRequirements2KHR", FUNCTIONORIGIN_DEVICE));
-			extFunctions.push_back(FunctionInfo("vkBindBufferMemory2KHR", FUNCTIONORIGIN_DEVICE));
-			extFunctions.push_back(FunctionInfo("vkImportFenceWin32HandleKHR", FUNCTIONORIGIN_DEVICE));
-			extFunctions.push_back(FunctionInfo("vkGetBufferMemoryRequirements2KHR", FUNCTIONORIGIN_DEVICE));
-			extFunctions.push_back(FunctionInfo("vkGetImageMemoryRequirements2KHR", FUNCTIONORIGIN_DEVICE));
-
-			log << tcu::TestLog::Message << "Extensions check - tries to get functions of disabled extensions from proper vkGet*ProcAddr." << tcu::TestLog::EndMessage;
-			const char * const				result				= specialCasesCheck(log, failsQuantity, extFunctions) ? "Passed" : "Failed";
-			log << tcu::TestLog::Message << result << tcu::TestLog::EndMessage;
-		}
-
-		{
-			FunctionInfosList				dummyFunctions		= FunctionInfosList();
-			for (deUint32 i = 0; i <= FUNCTIONORIGIN_DEVICE; ++i)
+			// Check function entry points of disabled extesions
 			{
-				const FunctionOrigin origin = static_cast<FunctionOrigin>(i);
-				dummyFunctions.push_back(FunctionInfo("vkSomeName", origin));
-				dummyFunctions.push_back(FunctionInfo("vkNonexistingKHR", origin));
-				dummyFunctions.push_back(FunctionInfo("", origin));
+				FunctionInfosList				extFunctions		= FunctionInfosList();
+				extFunctions.push_back(FunctionInfo("vkTrimCommandPoolKHR", FUNCTIONORIGIN_DEVICE));
+				extFunctions.push_back(FunctionInfo("vkCmdPushDescriptorSetKHR", FUNCTIONORIGIN_DEVICE));
+				extFunctions.push_back(FunctionInfo("vkCreateSamplerYcbcrConversionKHR", FUNCTIONORIGIN_DEVICE));
+				extFunctions.push_back(FunctionInfo("vkGetSwapchainStatusKHR", FUNCTIONORIGIN_DEVICE));
+				extFunctions.push_back(FunctionInfo("vkCreateSwapchainKHR", FUNCTIONORIGIN_DEVICE));
+				extFunctions.push_back(FunctionInfo("vkGetImageSparseMemoryRequirements2KHR", FUNCTIONORIGIN_DEVICE));
+				extFunctions.push_back(FunctionInfo("vkBindBufferMemory2KHR", FUNCTIONORIGIN_DEVICE));
+				extFunctions.push_back(FunctionInfo("vkImportFenceWin32HandleKHR", FUNCTIONORIGIN_DEVICE));
+				extFunctions.push_back(FunctionInfo("vkGetBufferMemoryRequirements2KHR", FUNCTIONORIGIN_DEVICE));
+				extFunctions.push_back(FunctionInfo("vkGetImageMemoryRequirements2KHR", FUNCTIONORIGIN_DEVICE));
+
+				log << tcu::TestLog::Message << "Disabled extensions check - tries to get functions of disabled extensions from proper vkGet*ProcAddr." << tcu::TestLog::EndMessage;
+				const char * const				result				= specialCasesCheck(log, failsQuantity, extFunctions) ? "Passed" : "Failed";
+				log << tcu::TestLog::Message << result << tcu::TestLog::EndMessage;
 			}
 
-			log << tcu::TestLog::Message << "Special check - tries to get some dummy functions from various vkGet*ProcAddr." << tcu::TestLog::EndMessage;
-			const char * const				result				= specialCasesCheck(log, failsQuantity, dummyFunctions) ? "Passed" : "Failed";
-			log << tcu::TestLog::Message << result << tcu::TestLog::EndMessage;
+			// Check special cases
+			{
+				FunctionInfosList				dummyFunctions		= FunctionInfosList();
+				for (deUint32 i = 0; i <= FUNCTIONORIGIN_DEVICE; ++i)
+				{
+					const FunctionOrigin origin = static_cast<FunctionOrigin>(i);
+					dummyFunctions.push_back(FunctionInfo("vkSomeName", origin));
+					dummyFunctions.push_back(FunctionInfo("vkNonexistingKHR", origin));
+					dummyFunctions.push_back(FunctionInfo("", origin));
+				}
+
+				log << tcu::TestLog::Message << "Special check - tries to get some dummy functions from various vkGet*ProcAddr." << tcu::TestLog::EndMessage;
+				const char * const				result				= specialCasesCheck(log, failsQuantity, dummyFunctions) ? "Passed" : "Failed";
+				log << tcu::TestLog::Message << result << tcu::TestLog::EndMessage;
+			}
+		}
+
+		// Tests with instance and device with extensions
+		{
+			instance			= createInstanceWithExtensions(m_context.getPlatformInterface(), m_context.getUsedApiVersion(), getSupportedInstanceExtensions(apiVersion));
+			device				= createTestDevice(m_context.getPlatformInterface(), m_context.getInstanceInterface(), m_context.getPhysicalDevice(), getSupportedDeviceExtensions(apiVersion));
+			getInstanceProcAddr	= reinterpret_cast<GetInstanceProcAddrFunc>(funcLibrary.getFunction("vkGetInstanceProcAddr"));
+			getDeviceProcAddr	= reinterpret_cast<GetDeviceProcAddrFunc>(getInstanceProcAddr(*instance, "vkGetDeviceProcAddr"));
+
+			// Check function entry points of enabled extensions
+			{
+				vector<FunctionInfo>	extFunctions;
+
+				// Add supported instance extension functions
+				for (size_t instanceExtNdx = 0; instanceExtNdx < DE_LENGTH_OF_ARRAY(instanceExtensionNames); instanceExtNdx++)
+				{
+					vector<const char*> instanceExtFunctions;
+
+					if (isSupportedInstanceExt(instanceExtensionNames[instanceExtNdx], apiVersion))
+						getInstanceExtensionFunctions(instanceExtensionNames[instanceExtNdx], instanceExtFunctions);
+
+					for (size_t instanceFuncNdx = 0; instanceFuncNdx < instanceExtFunctions.size(); instanceFuncNdx++)
+						extFunctions.push_back(FunctionInfo(instanceExtFunctions[instanceFuncNdx], FUNCTIONORIGIN_INSTANCE));
+				}
+
+				// Add supported device extension functions
+				for (size_t deviceExtNdx = 0; deviceExtNdx < DE_LENGTH_OF_ARRAY(deviceExtensionNames); deviceExtNdx++)
+				{
+					vector<const char*> deviceExtFunctions;
+
+					if (isSupportedDeviceExt(deviceExtensionNames[deviceExtNdx], apiVersion))
+						getDeviceExtensionFunctions(deviceExtensionNames[deviceExtNdx], deviceExtFunctions);
+
+					for (size_t deviceFuncNdx = 0; deviceFuncNdx < deviceExtFunctions.size(); deviceFuncNdx++)
+						extFunctions.push_back(FunctionInfo(deviceExtFunctions[deviceFuncNdx], FUNCTIONORIGIN_DEVICE));
+				}
+
+				log << tcu::TestLog::Message << "Enabled extensions check - tries to get functions of supported extensions from proper vkGet*ProcAddr." << tcu::TestLog::EndMessage;
+				const char * const		result = regularCheck(log, failsQuantity, extFunctions) ? "Passed" : "Failed";
+				log << tcu::TestLog::Message << result << tcu::TestLog::EndMessage;
+			}
 		}
 
 		if (failsQuantity > 0u)
@@ -204,13 +256,64 @@
 		return 0u;
 	}
 
-	Move<VkDevice> createTestDevice (const PlatformInterface& vkp, const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
+	vector<string> filterMultiAuthorExtensions (vector<VkExtensionProperties> extProperties)
 	{
-		vector<string>				enabledLayers;
-		vector<const char*>			layerPtrs;
+		vector<string>	multiAuthorExtensions;
+		const char*		extensionGroups[] =
+		{
+			"VK_KHR_",
+			"VK_EXT_"
+		};
+
+		for (size_t extNdx = 0; extNdx < extProperties.size(); extNdx++)
+		{
+			for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++)
+			{
+				if (deStringBeginsWith(extProperties[extNdx].extensionName, extensionGroups[extGroupNdx]))
+					multiAuthorExtensions.push_back(extProperties[extNdx].extensionName);
+			}
+		}
+
+		return multiAuthorExtensions;
+	}
+
+	vector<string> getSupportedInstanceExtensions (const deUint32 apiVersion)
+	{
+		vector<VkExtensionProperties>	enumeratedExtensions (enumerateInstanceExtensionProperties(m_context.getPlatformInterface(), DE_NULL));
+		vector<VkExtensionProperties>	supportedExtensions;
+
+		for (size_t extNdx = 0; extNdx < enumeratedExtensions.size(); extNdx++)
+		{
+			if (!isCoreInstanceExtension(apiVersion, enumeratedExtensions[extNdx].extensionName))
+				supportedExtensions.push_back(enumeratedExtensions[extNdx]);
+		}
+
+		return filterMultiAuthorExtensions(supportedExtensions);
+	}
+
+	vector<string> getSupportedDeviceExtensions (const deUint32 apiVersion)
+	{
+		vector<VkExtensionProperties>	enumeratedExtensions (enumerateDeviceExtensionProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), DE_NULL));
+		vector<VkExtensionProperties>	supportedExtensions;
+
+		for (size_t extNdx = 0; extNdx < enumeratedExtensions.size(); extNdx++)
+		{
+			if (!isCoreDeviceExtension(apiVersion, enumeratedExtensions[extNdx].extensionName))
+				supportedExtensions.push_back(enumeratedExtensions[extNdx]);
+		}
+
+		return filterMultiAuthorExtensions(supportedExtensions);
+	}
+
+	Move<VkDevice> createTestDevice (const PlatformInterface& vkp, const InstanceInterface& vki, VkPhysicalDevice physicalDevice, vector<string> extensions = vector<string>())
+	{
 		vector<const char*>			extensionPtrs;
 		const float					queuePriority	= 1.0f;
 		const deUint32				queueIndex		= findQueueFamilyIndex(vki, physicalDevice, VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT);
+
+		for (size_t i = 0; i < extensions.size(); i++)
+			extensionPtrs.push_back(extensions[i].c_str());
+
 		VkDeviceQueueCreateInfo		queueInfo		= {
 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
 			DE_NULL,
@@ -227,10 +330,11 @@
 			&queueInfo,
 			0u,
 			DE_NULL,
-			0u,
-			DE_NULL,
+			(deUint32)extensions.size(),
+			extensions.size() ? &extensionPtrs[0] : DE_NULL,
 			DE_NULL,
 		};
+
 		return vk::createDevice(vkp, *instance, vki, physicalDevice, &deviceInfo);
 	}
 
@@ -238,7 +342,7 @@
 	{
 		log << tcu::TestLog::Message
 			<< "[" << failsQuantity << "] " << functionName << '(' << firstParamName << ", \"" << secondParamName << "\") "
-			<< "returned " << (shouldBeNonNull ? "nullptr" : "non-null") << " should return " << (shouldBeNonNull ? "valid function address" : "nullptr")
+			<< "returned " << (shouldBeNonNull ? "nullptr" : "non-null") << ". Should return " << (shouldBeNonNull ? "valid function address." : "nullptr.")
 			<< tcu::TestLog::EndMessage;
 		++failsQuantity;
 	}
@@ -261,6 +365,20 @@
 			reportFail(log, "vkGetDeviceProcAddr", "device", name, shouldBeNonNull, failsQuantity);
 	}
 
+	deBool isSupportedInstanceExt (const string extName, const deUint32 apiVersion)
+	{
+		const vector<string> supportedInstanceExtensions (getSupportedInstanceExtensions(apiVersion));
+
+		return de::contains(supportedInstanceExtensions.begin(), supportedInstanceExtensions.end(), extName);
+	}
+
+	deBool isSupportedDeviceExt (const string extName, const deUint32 apiVersion)
+	{
+		const vector<string> supportedDeviceExtensions (getSupportedDeviceExtensions(apiVersion));
+
+		return de::contains(supportedDeviceExtensions.begin(), supportedDeviceExtensions.end(), extName);
+	}
+
 	deBool mixupAddressProcCheck (tcu::TestLog& log, deUint32& failsQuantity, const vector<pair<const char*, FunctionOrigin> >& testsArr)
 	{
 		const deUint32 startingQuantity = failsQuantity;
diff --git a/external/vulkancts/scripts/gen_framework.py b/external/vulkancts/scripts/gen_framework.py
index 790e7d8..2a9d889 100644
--- a/external/vulkancts/scripts/gen_framework.py
+++ b/external/vulkancts/scripts/gen_framework.py
@@ -1351,6 +1351,82 @@
 	""] + removeVersionDefines(versionSet)
 	writeInlFile(filename, INL_HEADER, lines)
 
+def writeExtensionFunctions (api, filename):
+
+	def isInstanceExtension (ext):
+		if ext.name and ext.functions:
+			if ext.functions[0].getType() == Function.TYPE_INSTANCE:
+				return True
+			else:
+				return False
+
+	def isDeviceExtension (ext):
+		if ext.name and ext.functions:
+			if ext.functions[0].getType() == Function.TYPE_DEVICE:
+				return True
+			else:
+				return False
+
+	def writeExtensionNameArrays ():
+		instanceExtensionNames = []
+		deviceExtensionNames = []
+		for ext in api.extensions:
+			if ext.name and isInstanceExtension(ext):
+				instanceExtensionNames += [ext.name]
+			elif ext.name and isDeviceExtension(ext):
+				deviceExtensionNames += [ext.name]
+		yield '::std::string instanceExtensionNames[] =\n{'
+		for instanceExtName in instanceExtensionNames:
+			if (instanceExtName == instanceExtensionNames[len(instanceExtensionNames) - 1]):
+				yield '\t"%s"' % instanceExtName
+			else:
+				yield '\t"%s",' % instanceExtName
+		yield '};\n'
+		yield '::std::string deviceExtensionNames[] =\n{'
+		for deviceExtName in deviceExtensionNames:
+			if (deviceExtName == deviceExtensionNames[len(deviceExtensionNames) - 1]):
+				yield '\t"%s"' % deviceExtName
+			else:
+				yield '\t"%s",' % deviceExtName
+		yield '};'
+
+	def writeExtensionFunctions (functionType):
+		isFirstWrite = True
+		if functionType == Function.TYPE_INSTANCE:
+			yield 'void getInstanceExtensionFunctions (::std::string extName, ::std::vector<const char*>& functions)\n{'
+		elif functionType == Function.TYPE_DEVICE:
+			yield 'void getDeviceExtensionFunctions (::std::string extName, ::std::vector<const char*>& functions)\n{'
+		for ext in api.extensions:
+			funcNames = []
+			if ext.name:
+				for func in ext.functions:
+					if func.getType() == functionType:
+						funcNames.append(func.name)
+			if (funcNames):
+				yield ('\tif (extName == "%s")' % ext.name) if isFirstWrite else  ('\telse if (extName == "%s")' % ext.name)
+				if (len(funcNames) > 1):
+					yield "\t{"
+				for funcName in funcNames:
+					yield '\t\tfunctions.push_back("%s");' % funcName
+				if (len(funcNames) > 1):
+					yield '\t}'
+				isFirstWrite = False
+		if not isFirstWrite:
+			yield '\telse'
+			yield '\t\tDE_ASSERT("Extension name not found");\n}'
+
+	lines = ['']
+	for line in writeExtensionFunctions(Function.TYPE_INSTANCE):
+		lines += [line]
+	lines += ['']
+	for line in writeExtensionFunctions(Function.TYPE_DEVICE):
+		lines += [line]
+	lines += ['']
+	for line in writeExtensionNameArrays():
+		lines += [line]
+
+	writeInlFile(filename, INL_HEADER, lines)
+
 def writeCoreFunctionalities(api, filename):
 	functionOriginValues = ["FUNCTIONORIGIN_PLATFORM", "FUNCTIONORIGIN_INSTANCE", "FUNCTIONORIGIN_DEVICE"]
 
@@ -1430,3 +1506,4 @@
 	writeTypeUtil				(api, os.path.join(VULKAN_DIR, "vkTypeUtil.inl"))
 	writeSupportedExtenions		(api, os.path.join(VULKAN_DIR, "vkSupportedExtensions.inl"))
 	writeCoreFunctionalities	(api, os.path.join(VULKAN_DIR, "vkCoreFunctionalities.inl"))
+	writeExtensionFunctions		(api, os.path.join(VULKAN_DIR, "vkExtensionFunctions.inl"))