@@ -111,17 +111,38 @@ VkLayerDeviceCreateInfo* getChainInfo(const VkDeviceCreateInfo* pCreateInfo)
111111}
112112
113113/* See header for documentation. */
114- PFN_vkVoidFunction getInstanceLayerFunction (const char * name)
114+ std::pair< bool , PFN_vkVoidFunction> getInstanceLayerFunction (const char * name)
115115{
116+ const std::array<const char *, 5 > globalFunctions {
117+ // Supported since Vulkan 1.0
118+ " vkCreateInstance" ,
119+ " vkEnumerateInstanceExtensionProperties" ,
120+ " vkEnumerateInstanceLayerProperties" ,
121+ // Supported since Vulkan 1.1
122+ " vkEnumerateInstanceVersion" ,
123+ // Supported since Vulkan 1.2
124+ " vkGetInstanceProcAddr" ,
125+ };
126+
127+ bool isGlobal {false };
128+ for (const auto * globalName : globalFunctions)
129+ {
130+ if (!strcmp (globalName, name))
131+ {
132+ isGlobal = true ;
133+ break ;
134+ }
135+ }
136+
116137 for (auto & function : instanceIntercepts)
117138 {
118139 if (!strcmp (function.name , name))
119140 {
120- return function.function ;
141+ return {isGlobal, function.function } ;
121142 }
122143 }
123144
124- return nullptr ;
145+ return {isGlobal, nullptr } ;
125146}
126147
127148/* See header for documentation. */
@@ -147,12 +168,14 @@ APIVersion getInstanceAPIVersion(PFN_vkGetInstanceProcAddr fpGetProcAddr)
147168 return { 1, 3 };
148169#endif
149170
171+ // Try to get vkEnumerateInstanceVersion, and assume this is a Vulkan 1.0
172+ // feature level if we don't get it ...
150173 auto fpFunctionRaw = fpGetProcAddr (nullptr , " vkEnumerateInstanceVersion" );
151174 auto fpFunction = reinterpret_cast <PFN_vkEnumerateInstanceVersion>(fpFunctionRaw);
152175 if (!fpFunction)
153176 {
154- LAYER_ERR (" Failed to get vkEnumerateInstanceVersion()" );
155- return {0 , 0 };
177+ LAYER_ERR (" Failed to get vkEnumerateInstanceVersion(), assuming Vulkan 1.0 " );
178+ return {1 , 0 };
156179 }
157180
158181 uint32_t apiVersion = 0 ;
@@ -474,9 +497,18 @@ void enableDeviceVkExtImageCompressionControl(Instance& instance,
474497/* * See Vulkan API for documentation. */
475498PFN_vkVoidFunction layer_vkGetInstanceProcAddr_default (VkInstance instance, const char * pName)
476499{
477- // Only expose functions that the driver exposes to avoid changing
478- // queryable interface behavior seen by the application
479- auto layerFunction = getInstanceLayerFunction (pName);
500+ auto [isGlobal, layerFunction] = getInstanceLayerFunction (pName);
501+
502+ // Global functions must be exposed and do not require the caller to pass
503+ // a valid instance pointer, although it is required to be nullptr in
504+ // Vulkan 1.2.193 or later
505+ if (isGlobal)
506+ {
507+ return layerFunction;
508+ }
509+
510+ // For other functions, only expose functions that the driver exposes to
511+ // avoid changing queryable interface behavior seen by the application
480512 if (instance)
481513 {
482514 std::unique_lock<std::mutex> lock {g_vulkanLock};
0 commit comments