Explorar o código

Update Vulkan loader to 1.1.127

bruvzg %!s(int64=6) %!d(string=hai) anos
pai
achega
7bf72ed14e
Modificáronse 31 ficheiros con 1930 adicións e 664 borrados
  1. 1 1
      drivers/vulkan/SCsub
  2. 1 1
      thirdparty/README.md
  3. 9 1
      thirdparty/vulkan/include/vulkan/vk_icd.h
  4. 543 464
      thirdparty/vulkan/include/vulkan/vulkan.hpp
  5. 5 4
      thirdparty/vulkan/include/vulkan/vulkan_android.h
  6. 550 61
      thirdparty/vulkan/include/vulkan/vulkan_core.h
  7. 5 4
      thirdparty/vulkan/include/vulkan/vulkan_fuchsia.h
  8. 5 4
      thirdparty/vulkan/include/vulkan/vulkan_ggp.h
  9. 5 4
      thirdparty/vulkan/include/vulkan/vulkan_ios.h
  10. 5 4
      thirdparty/vulkan/include/vulkan/vulkan_macos.h
  11. 5 4
      thirdparty/vulkan/include/vulkan/vulkan_metal.h
  12. 5 4
      thirdparty/vulkan/include/vulkan/vulkan_vi.h
  13. 5 4
      thirdparty/vulkan/include/vulkan/vulkan_wayland.h
  14. 7 6
      thirdparty/vulkan/include/vulkan/vulkan_win32.h
  15. 5 4
      thirdparty/vulkan/include/vulkan/vulkan_xcb.h
  16. 5 4
      thirdparty/vulkan/include/vulkan/vulkan_xlib.h
  17. 5 4
      thirdparty/vulkan/include/vulkan/vulkan_xlib_xrandr.h
  18. 80 0
      thirdparty/vulkan/loader/adapters.h
  19. 23 0
      thirdparty/vulkan/loader/dxgi_loader.c
  20. 8 0
      thirdparty/vulkan/loader/dxgi_loader.h
  21. 11 0
      thirdparty/vulkan/loader/extension_manual.c
  22. 337 39
      thirdparty/vulkan/loader/loader.c
  23. 3 0
      thirdparty/vulkan/loader/loader.h
  24. 12 0
      thirdparty/vulkan/loader/unknown_ext_chain_gas.S
  25. 21 0
      thirdparty/vulkan/loader/vk_dispatch_table_helper.h
  26. 13 0
      thirdparty/vulkan/loader/vk_layer_dispatch_table.h
  27. 127 38
      thirdparty/vulkan/loader/vk_loader_extensions.c
  28. 0 1
      thirdparty/vulkan/loader/vk_loader_extensions.h
  29. 35 4
      thirdparty/vulkan/loader/vk_loader_platform.h
  30. 87 4
      thirdparty/vulkan/loader/wsi.c
  31. 7 0
      thirdparty/vulkan/loader/wsi.h

+ 1 - 1
drivers/vulkan/SCsub

@@ -14,7 +14,6 @@ if env['builtin_vulkan']:
     env_thirdparty.disable_warnings()
 
     loader_sources = [
-        "asm_offset.c",
         "cJSON.c",
         "debug_utils.c",
         "dev_ext_trampoline.c",
@@ -29,6 +28,7 @@ if env['builtin_vulkan']:
 
     if env['platform'] == "windows":
         loader_sources.append("dirent_on_windows.c")
+        loader_sources.append("dxgi_loader.c")
         env_thirdparty.AppendUnique(CPPDEFINES=[
             'VK_USE_PLATFORM_WIN32_KHR',
             'VULKAN_NON_CMAKE_BUILD',

+ 1 - 1
thirdparty/README.md

@@ -531,7 +531,7 @@ folder.
 ## vulkan
 
 - Upstream: https://github.com/KhronosGroup/Vulkan-Loader
-- Version: 1.1.113
+- Version: 1.1.127
 - License: Apache 2.0
 
 Unless there is a specific reason to package a more recent version, please stick

+ 9 - 1
thirdparty/vulkan/include/vulkan/vk_icd.h

@@ -89,7 +89,8 @@ typedef enum {
     VK_ICD_WSI_PLATFORM_MACOS,
     VK_ICD_WSI_PLATFORM_IOS,
     VK_ICD_WSI_PLATFORM_DISPLAY,
-    VK_ICD_WSI_PLATFORM_HEADLESS
+    VK_ICD_WSI_PLATFORM_HEADLESS,
+    VK_ICD_WSI_PLATFORM_METAL,
 } VkIcdWsiPlatform;
 
 typedef struct {
@@ -172,4 +173,11 @@ typedef struct {
     VkIcdSurfaceBase base;
 } VkIcdSurfaceHeadless;
 
+#ifdef VK_USE_PLATFORM_METAL_EXT
+typedef struct {
+    VkIcdSurfaceBase base;
+    const CAMetalLayer *pLayer;
+} VkIcdSurfaceMetal;
+#endif // VK_USE_PLATFORM_METAL_EXT
+
 #endif  // VKICD_H

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 543 - 464
thirdparty/vulkan/include/vulkan/vulkan.hpp


+ 5 - 4
thirdparty/vulkan/include/vulkan/vulkan_android.h

@@ -1,10 +1,6 @@
 #ifndef VULKAN_ANDROID_H_
 #define VULKAN_ANDROID_H_ 1
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /*
 ** Copyright (c) 2015-2019 The Khronos Group Inc.
 **
@@ -27,6 +23,11 @@ extern "C" {
 */
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
 
 #define VK_KHR_android_surface 1
 struct ANativeWindow;

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 550 - 61
thirdparty/vulkan/include/vulkan/vulkan_core.h


+ 5 - 4
thirdparty/vulkan/include/vulkan/vulkan_fuchsia.h

@@ -1,10 +1,6 @@
 #ifndef VULKAN_FUCHSIA_H_
 #define VULKAN_FUCHSIA_H_ 1
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /*
 ** Copyright (c) 2015-2019 The Khronos Group Inc.
 **
@@ -27,6 +23,11 @@ extern "C" {
 */
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
 
 #define VK_FUCHSIA_imagepipe_surface 1
 #define VK_FUCHSIA_IMAGEPIPE_SURFACE_SPEC_VERSION 1

+ 5 - 4
thirdparty/vulkan/include/vulkan/vulkan_ggp.h

@@ -1,10 +1,6 @@
 #ifndef VULKAN_GGP_H_
 #define VULKAN_GGP_H_ 1
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /*
 ** Copyright (c) 2015-2019 The Khronos Group Inc.
 **
@@ -27,6 +23,11 @@ extern "C" {
 */
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
 
 #define VK_GGP_stream_descriptor_surface 1
 #define VK_GGP_STREAM_DESCRIPTOR_SURFACE_SPEC_VERSION 1

+ 5 - 4
thirdparty/vulkan/include/vulkan/vulkan_ios.h

@@ -1,10 +1,6 @@
 #ifndef VULKAN_IOS_H_
 #define VULKAN_IOS_H_ 1
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /*
 ** Copyright (c) 2015-2019 The Khronos Group Inc.
 **
@@ -27,6 +23,11 @@ extern "C" {
 */
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
 
 #define VK_MVK_ios_surface 1
 #define VK_MVK_IOS_SURFACE_SPEC_VERSION   2

+ 5 - 4
thirdparty/vulkan/include/vulkan/vulkan_macos.h

@@ -1,10 +1,6 @@
 #ifndef VULKAN_MACOS_H_
 #define VULKAN_MACOS_H_ 1
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /*
 ** Copyright (c) 2015-2019 The Khronos Group Inc.
 **
@@ -27,6 +23,11 @@ extern "C" {
 */
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
 
 #define VK_MVK_macos_surface 1
 #define VK_MVK_MACOS_SURFACE_SPEC_VERSION 2

+ 5 - 4
thirdparty/vulkan/include/vulkan/vulkan_metal.h

@@ -1,10 +1,6 @@
 #ifndef VULKAN_METAL_H_
 #define VULKAN_METAL_H_ 1
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /*
 ** Copyright (c) 2015-2019 The Khronos Group Inc.
 **
@@ -27,6 +23,11 @@ extern "C" {
 */
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
 
 #define VK_EXT_metal_surface 1
 

+ 5 - 4
thirdparty/vulkan/include/vulkan/vulkan_vi.h

@@ -1,10 +1,6 @@
 #ifndef VULKAN_VI_H_
 #define VULKAN_VI_H_ 1
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /*
 ** Copyright (c) 2015-2019 The Khronos Group Inc.
 **
@@ -27,6 +23,11 @@ extern "C" {
 */
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
 
 #define VK_NN_vi_surface 1
 #define VK_NN_VI_SURFACE_SPEC_VERSION     1

+ 5 - 4
thirdparty/vulkan/include/vulkan/vulkan_wayland.h

@@ -1,10 +1,6 @@
 #ifndef VULKAN_WAYLAND_H_
 #define VULKAN_WAYLAND_H_ 1
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /*
 ** Copyright (c) 2015-2019 The Khronos Group Inc.
 **
@@ -27,6 +23,11 @@ extern "C" {
 */
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
 
 #define VK_KHR_wayland_surface 1
 #define VK_KHR_WAYLAND_SURFACE_SPEC_VERSION 6

+ 7 - 6
thirdparty/vulkan/include/vulkan/vulkan_win32.h

@@ -1,10 +1,6 @@
 #ifndef VULKAN_WIN32_H_
 #define VULKAN_WIN32_H_ 1
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /*
 ** Copyright (c) 2015-2019 The Khronos Group Inc.
 **
@@ -27,6 +23,11 @@ extern "C" {
 */
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
 
 #define VK_KHR_win32_surface 1
 #define VK_KHR_WIN32_SURFACE_SPEC_VERSION 6
@@ -246,7 +247,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleNV(
 
 
 #define VK_NV_win32_keyed_mutex 1
-#define VK_NV_WIN32_KEYED_MUTEX_SPEC_VERSION 1
+#define VK_NV_WIN32_KEYED_MUTEX_SPEC_VERSION 2
 #define VK_NV_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_NV_win32_keyed_mutex"
 typedef struct VkWin32KeyedMutexAcquireReleaseInfoNV {
     VkStructureType          sType;
@@ -263,7 +264,7 @@ typedef struct VkWin32KeyedMutexAcquireReleaseInfoNV {
 
 
 #define VK_EXT_full_screen_exclusive 1
-#define VK_EXT_FULL_SCREEN_EXCLUSIVE_SPEC_VERSION 3
+#define VK_EXT_FULL_SCREEN_EXCLUSIVE_SPEC_VERSION 4
 #define VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME "VK_EXT_full_screen_exclusive"
 
 typedef enum VkFullScreenExclusiveEXT {

+ 5 - 4
thirdparty/vulkan/include/vulkan/vulkan_xcb.h

@@ -1,10 +1,6 @@
 #ifndef VULKAN_XCB_H_
 #define VULKAN_XCB_H_ 1
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /*
 ** Copyright (c) 2015-2019 The Khronos Group Inc.
 **
@@ -27,6 +23,11 @@ extern "C" {
 */
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
 
 #define VK_KHR_xcb_surface 1
 #define VK_KHR_XCB_SURFACE_SPEC_VERSION   6

+ 5 - 4
thirdparty/vulkan/include/vulkan/vulkan_xlib.h

@@ -1,10 +1,6 @@
 #ifndef VULKAN_XLIB_H_
 #define VULKAN_XLIB_H_ 1
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /*
 ** Copyright (c) 2015-2019 The Khronos Group Inc.
 **
@@ -27,6 +23,11 @@ extern "C" {
 */
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
 
 #define VK_KHR_xlib_surface 1
 #define VK_KHR_XLIB_SURFACE_SPEC_VERSION  6

+ 5 - 4
thirdparty/vulkan/include/vulkan/vulkan_xlib_xrandr.h

@@ -1,10 +1,6 @@
 #ifndef VULKAN_XLIB_XRANDR_H_
 #define VULKAN_XLIB_XRANDR_H_ 1
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /*
 ** Copyright (c) 2015-2019 The Khronos Group Inc.
 **
@@ -27,6 +23,11 @@ extern "C" {
 */
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
 
 #define VK_EXT_acquire_xlib_display 1
 #define VK_EXT_ACQUIRE_XLIB_DISPLAY_SPEC_VERSION 1

+ 80 - 0
thirdparty/vulkan/loader/adapters.h

@@ -0,0 +1,80 @@
+/*
+* Copyright (c) 2019 The Khronos Group Inc.
+* Copyright (c) 2019 Valve Corporation
+* Copyright (c) 2019 LunarG, Inc.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+* Author: Lenny Komow <[email protected]>
+*/
+
+typedef struct LoaderEnumAdapters2 {
+    ULONG adapter_count;
+    struct {
+        UINT handle;
+        LUID luid;
+        ULONG source_count;
+        BOOL present_move_regions_preferred;
+    } * adapters;
+} LoaderEnumAdapters2;
+
+typedef _Check_return_ NTSTATUS(APIENTRY *PFN_LoaderEnumAdapters2)(const LoaderEnumAdapters2 *);
+
+typedef enum AdapterInfoType {
+    LOADER_QUERY_TYPE_REGISTRY = 48,
+} AdapterInfoType;
+
+typedef struct LoaderQueryAdapterInfo {
+    UINT handle;
+    AdapterInfoType type;
+    VOID *private_data;
+    UINT private_data_size;
+} LoaderQueryAdapterInfo;
+
+typedef _Check_return_ NTSTATUS(APIENTRY *PFN_LoaderQueryAdapterInfo)(const LoaderQueryAdapterInfo *);
+
+typedef enum LoaderQueryRegistryType {
+    LOADER_QUERY_REGISTRY_ADAPTER_KEY = 1,
+} LoaderQueryRegistryType;
+
+typedef enum LoaderQueryRegistryStatus {
+    LOADER_QUERY_REGISTRY_STATUS_SUCCESS = 0,
+    LOADER_QUERY_REGISTRY_STATUS_BUFFER_OVERFLOW = 1,
+} LoaderQueryRegistryStatus;
+
+typedef struct LoaderQueryRegistryFlags {
+    union {
+        struct {
+            UINT translate_path : 1;
+            UINT mutable_value : 1;
+            UINT reserved : 30;
+        };
+        UINT value;
+    };
+} LoaderQueryRegistryFlags;
+
+typedef struct LoaderQueryRegistryInfo {
+    LoaderQueryRegistryType query_type;
+    LoaderQueryRegistryFlags query_flags;
+    WCHAR value_name[MAX_PATH];
+    ULONG value_type;
+    ULONG physical_adapter_index;
+    ULONG output_value_size;
+    LoaderQueryRegistryStatus status;
+    union {
+        DWORD output_dword;
+        UINT64 output_qword;
+        WCHAR output_string[1];
+        BYTE output_binary[1];
+    };
+} LoaderQueryRegistryInfo;

+ 23 - 0
thirdparty/vulkan/loader/dxgi_loader.c

@@ -0,0 +1,23 @@
+#include "dxgi_loader.h"
+
+#include <strsafe.h>
+
+static HMODULE load_dxgi_module() {
+    TCHAR systemPath[MAX_PATH] = "";
+    GetSystemDirectory(systemPath, MAX_PATH);
+    StringCchCat(systemPath, MAX_PATH, TEXT("\\dxgi.dll"));
+
+    return LoadLibrary(systemPath);
+}
+
+typedef HRESULT (APIENTRY *PFN_CreateDXGIFactory1)(REFIID riid, void **ppFactory);
+
+HRESULT dyn_CreateDXGIFactory1(REFIID riid, void **ppFactory) {
+    PFN_CreateDXGIFactory1 fpCreateDXGIFactory1 =
+        (PFN_CreateDXGIFactory1)GetProcAddress(load_dxgi_module(), "CreateDXGIFactory1");
+
+    if (fpCreateDXGIFactory1 != NULL)
+        return fpCreateDXGIFactory1(riid, ppFactory);
+
+    return DXGI_ERROR_NOT_FOUND;
+}

+ 8 - 0
thirdparty/vulkan/loader/dxgi_loader.h

@@ -0,0 +1,8 @@
+#ifndef DXGI_LOADER_H
+#define DXGI_LOADER_H
+
+#include <dxgi1_2.h>
+
+HRESULT dyn_CreateDXGIFactory1(REFIID riid, void **ppFactory);
+
+#endif

+ 11 - 0
thirdparty/vulkan/loader/extension_manual.c

@@ -58,6 +58,17 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2K
     uint8_t icd_index = phys_dev_term->icd_index;
 
     if (icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR != NULL) {
+        VkBaseOutStructure *pNext = (VkBaseOutStructure *)pSurfaceCapabilities->pNext;
+        while (pNext != NULL) {
+            if ((int)pNext->sType == VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR) {
+                // Not all ICDs may be supporting VK_KHR_surface_protected_capabilities
+                // Initialize VkSurfaceProtectedCapabilitiesKHR.supportsProtected to false and
+                // if an ICD supports protected surfaces, it will reset it to true accordingly.
+                ((VkSurfaceProtectedCapabilitiesKHR *)pNext)->supportsProtected = VK_FALSE;
+            }
+            pNext = (VkBaseOutStructure *)pNext->pNext;
+        }
+
         // Pass the call to the driver, possibly unwrapping the ICD surface
         if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
             VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;

+ 337 - 39
thirdparty/vulkan/loader/loader.c

@@ -25,6 +25,12 @@
  *
  */
 
+// This needs to be defined first, or else we'll get redefinitions on NTSTATUS values
+#ifdef _WIN32
+#define UMDF_USING_NTSTATUS
+#include <ntstatus.h>
+#endif
+
 #ifndef _GNU_SOURCE
 #define _GNU_SOURCE
 #endif
@@ -63,6 +69,9 @@
 #include <cfgmgr32.h>
 #include <initguid.h>
 #include <devpkey.h>
+#include <winternl.h>
+#include "adapters.h"
+#include "dxgi_loader.h"
 #endif
 
 // This is a CMake generated file with #defines for any functions/includes
@@ -231,6 +240,10 @@ void *loader_device_heap_realloc(const struct loader_device *device, void *pMemo
 // Environment variables
 #if defined(__linux__) || defined(__APPLE__)
 
+static inline bool IsHighIntegrity() {
+    return geteuid() != getuid() || getegid() != getgid();
+}
+
 static inline char *loader_getenv(const char *name, const struct loader_instance *inst) {
     // No allocation of memory necessary for Linux, but we should at least touch
     // the inst pointer to get rid of compiler warnings.
@@ -247,7 +260,7 @@ static inline char *loader_secure_getenv(const char *name, const struct loader_i
     // that can do damage.
     // This algorithm is derived from glibc code that sets an internal
     // variable (__libc_enable_secure) if the process is running under setuid or setgid.
-    return geteuid() != getuid() || getegid() != getgid() ? NULL : loader_getenv(name, inst);
+    return IsHighIntegrity() ? NULL : loader_getenv(name, inst);
 #else
 // Linux
 #ifdef HAVE_SECURE_GETENV
@@ -274,6 +287,28 @@ static inline void loader_free_getenv(char *val, const struct loader_instance *i
 
 #elif defined(WIN32)
 
+static inline bool IsHighIntegrity() {
+    HANDLE process_token;
+    if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_QUERY_SOURCE, &process_token)) {
+        // Maximum possible size of SID_AND_ATTRIBUTES is maximum size of a SID + size of attributes DWORD.
+        uint8_t mandatory_label_buffer[SECURITY_MAX_SID_SIZE + sizeof(DWORD)];
+        DWORD buffer_size;
+        if (GetTokenInformation(process_token, TokenIntegrityLevel, mandatory_label_buffer, sizeof(mandatory_label_buffer),
+            &buffer_size) != 0) {
+            const TOKEN_MANDATORY_LABEL *mandatory_label = (const TOKEN_MANDATORY_LABEL *)mandatory_label_buffer;
+            const DWORD sub_authority_count = *GetSidSubAuthorityCount(mandatory_label->Label.Sid);
+            const DWORD integrity_level = *GetSidSubAuthority(mandatory_label->Label.Sid, sub_authority_count - 1);
+
+            CloseHandle(process_token);
+            return integrity_level > SECURITY_MANDATORY_MEDIUM_RID;
+        }
+
+        CloseHandle(process_token);
+    }
+
+    return false;
+}
+
 static inline char *loader_getenv(const char *name, const struct loader_instance *inst) {
     char *retVal;
     DWORD valSize;
@@ -300,7 +335,10 @@ static inline char *loader_getenv(const char *name, const struct loader_instance
 }
 
 static inline char *loader_secure_getenv(const char *name, const struct loader_instance *inst) {
-    // No secure version for Windows as far as I know
+    if (IsHighIntegrity()) {
+        return NULL;
+    }
+
     return loader_getenv(name, inst);
 }
 
@@ -486,12 +524,11 @@ VKAPI_ATTR VkResult VKAPI_CALL vkSetDeviceDispatch(VkDevice device, void *object
 static bool loaderAddJsonEntry(const struct loader_instance *inst,
                                char **reg_data,    // list of JSON files
                                PDWORD total_size,  // size of reg_data
-                               LPCTSTR key_name,   // key name - used for debug prints - i.e. VulkanDriverName
+                               LPCSTR key_name,    // key name - used for debug prints - i.e. VulkanDriverName
                                DWORD key_type,     // key data type
                                LPSTR json_path,    // JSON string to add to the list reg_data
                                DWORD json_size,    // size in bytes of json_path
                                VkResult *result) {
-
     // Check for and ignore duplicates.
     if (*reg_data && strstr(*reg_data, json_path)) {
         // Success. The json_path is already in the list.
@@ -542,8 +579,8 @@ static bool loaderAddJsonEntry(const struct loader_instance *inst,
 // This function looks for filename in given device handle, filename is then added to return list
 // function return true if filename was appended to reg_data list
 // If error occures result is updated with failure reason
-bool loaderGetDeviceRegistryEntry(const struct loader_instance *inst, char **reg_data, PDWORD total_size, DEVINST dev_id, LPCTSTR value_name, VkResult *result)
-{
+bool loaderGetDeviceRegistryEntry(const struct loader_instance *inst, char **reg_data, PDWORD total_size, DEVINST dev_id,
+                                  LPCSTR value_name, VkResult *result) {
     HKEY hkrKey = INVALID_HANDLE_VALUE;
     DWORD requiredSize, data_type;
     char *manifest_path = NULL;
@@ -635,7 +672,8 @@ out:
 //
 // *reg_data contains a string list of filenames as pointer.
 // When done using the returned string list, the caller should free the pointer.
-VkResult loaderGetDeviceRegistryFiles(const struct loader_instance *inst, char **reg_data, PDWORD reg_data_size, LPCTSTR value_name) {
+VkResult loaderGetDeviceRegistryFiles(const struct loader_instance *inst, char **reg_data, PDWORD reg_data_size,
+                                      LPCSTR value_name) {
     static const wchar_t *softwareComponentGUID = L"{5c4c3332-344d-483c-8739-259e934c9cc8}";
     static const wchar_t *displayGUID = L"{4d36e968-e325-11ce-bfc1-08002be10318}";
     const ULONG flags = CM_GETIDLIST_FILTER_CLASS | CM_GETIDLIST_FILTER_PRESENT;
@@ -675,7 +713,7 @@ VkResult loaderGetDeviceRegistryFiles(const struct loader_instance *inst, char *
         for (wchar_t *deviceName = pDeviceNames; *deviceName; deviceName += wcslen(deviceName) + 1) {
             CONFIGRET status = CM_Locate_DevNodeW(&devID, deviceName, CM_LOCATE_DEVNODE_NORMAL);
             if (CR_SUCCESS != status) {
-                loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "loaderGetDeviceRegistryFiles: failed to open DevNode %s",
+                loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "loaderGetDeviceRegistryFiles: failed to open DevNode %ls",
                            deviceName);
                 continue;
             }
@@ -684,17 +722,17 @@ VkResult loaderGetDeviceRegistryFiles(const struct loader_instance *inst, char *
 
             if (CR_SUCCESS != status)
             {
-                loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "loaderGetDeviceRegistryFiles: failed to probe device status %s",
+                loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "loaderGetDeviceRegistryFiles: failed to probe device status %ls",
                            deviceName);
                 continue;
             }
             if ((ulStatus & DN_HAS_PROBLEM) && (ulProblem == CM_PROB_NEED_RESTART || ulProblem == DN_NEED_RESTART)) {
                 loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
-                           "loaderGetDeviceRegistryFiles: device %s is pending reboot, skipping ...", deviceName);
+                           "loaderGetDeviceRegistryFiles: device %ls is pending reboot, skipping ...", deviceName);
                 continue;
             }
 
-            loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, "loaderGetDeviceRegistryFiles: opening device %s", deviceName);
+            loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, "loaderGetDeviceRegistryFiles: opening device %ls", deviceName);
 
             if (loaderGetDeviceRegistryEntry(inst, reg_data, reg_data_size, devID, value_name, &result)) {
                 found = true;
@@ -716,7 +754,7 @@ VkResult loaderGetDeviceRegistryFiles(const struct loader_instance *inst, char *
                 CM_Get_Device_IDW(childID, buffer, MAX_DEVICE_ID_LEN, 0);
 
                 loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
-                           "loaderGetDeviceRegistryFiles: Opening child device %d - %s", childID, buffer);
+                           "loaderGetDeviceRegistryFiles: Opening child device %d - %ls", childID, buffer);
 
                 status = CM_Get_DevNode_Registry_PropertyW(childID, CM_DRP_CLASSGUID, NULL, &childGuid, &childGuidSize, 0);
                 if (status != CR_SUCCESS) {
@@ -768,6 +806,49 @@ static char *loader_get_next_path(char *path);
 // When done using the returned string list, the caller should free the pointer.
 VkResult loaderGetRegistryFiles(const struct loader_instance *inst, char *location, bool use_secondary_hive, char **reg_data,
                                 PDWORD reg_data_size) {
+    // This list contains all of the allowed ICDs. This allows us to verify that a device is actually present from the vendor
+    // specified. This does disallow other vendors, but any new driver should use the device-specific registries anyway.
+    static const struct {
+        const char *filename;
+        int vendor_id;
+    } known_drivers[] = {
+#if defined(_WIN64)
+        {
+            .filename = "igvk64.json",
+            .vendor_id = 0x8086,
+        },
+        {
+            .filename = "nv-vk64.json",
+            .vendor_id = 0x10de,
+        },
+        {
+            .filename = "amd-vulkan64.json",
+            .vendor_id = 0x1002,
+        },
+        {
+            .filename = "amdvlk64.json",
+            .vendor_id = 0x1002,
+        },
+#else
+        {
+            .filename = "igvk32.json",
+            .vendor_id = 0x8086,
+        },
+        {
+            .filename = "nv-vk32.json",
+            .vendor_id = 0x10de,
+        },
+        {
+            .filename = "amd-vulkan32.json",
+            .vendor_id = 0x1002,
+        },
+        {
+            .filename = "amdvlk32.json",
+            .vendor_id = 0x1002,
+        },
+#endif
+    };
+
     LONG rtn_value;
     HKEY hive = DEFAULT_VK_REGISTRY_HIVE, key;
     DWORD access_flags;
@@ -780,12 +861,25 @@ VkResult loaderGetRegistryFiles(const struct loader_instance *inst, char *locati
     DWORD value_size = sizeof(value);
     VkResult result = VK_SUCCESS;
     bool found = false;
+    IDXGIFactory1 *dxgi_factory = NULL;
+    bool is_driver = !strcmp(location, VK_DRIVERS_INFO_REGISTRY_LOC);
 
     if (NULL == reg_data) {
         result = VK_ERROR_INITIALIZATION_FAILED;
         goto out;
     }
 
+    if (is_driver) {
+        HRESULT hres = dyn_CreateDXGIFactory1(&IID_IDXGIFactory1, &dxgi_factory);
+        if (hres != S_OK) {
+            loader_log(
+                inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+                "loaderGetRegistryFiles: Failed to create dxgi factory for ICD registry verification. No ICDs will be added from "
+                "legacy registry locations");
+            goto out;
+        }
+    }
+
     while (*loc) {
         next = loader_get_next_path(loc);
         access_flags = KEY_QUERY_VALUE;
@@ -820,9 +914,58 @@ VkResult loaderGetRegistryFiles(const struct loader_instance *inst, char *locati
                         *reg_data = new_ptr;
                         *reg_data_size *= 2;
                     }
+
+                    // We've now found a json file. If this is an ICD, we still need to check if there is actually a device
+                    // that matches this ICD
                     loader_log(
                         inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, "Located json file \"%s\" from registry \"%s\\%s\"", name,
                         hive == DEFAULT_VK_REGISTRY_HIVE ? DEFAULT_VK_REGISTRY_HIVE_STR : SECONDARY_VK_REGISTRY_HIVE_STR, location);
+                    if (is_driver) {
+                        int i;
+                        for (i = 0; i < sizeof(known_drivers) / sizeof(known_drivers[0]); ++i) {
+                            if (!strcmp(name + strlen(name) - strlen(known_drivers[i].filename), known_drivers[i].filename)) {
+                                break;
+                            }
+                        }
+                        if (i == sizeof(known_drivers) / sizeof(known_drivers[0])) {
+                            loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+                                       "Driver %s is not recognized as a known driver. It will be assumed to be active", name);
+                        } else {
+                            bool found_gpu = false;
+                            for (int j = 0;; ++j) {
+                                IDXGIAdapter1 *adapter;
+                                HRESULT hres = dxgi_factory->lpVtbl->EnumAdapters1(dxgi_factory, j, &adapter);
+                                if (hres == DXGI_ERROR_NOT_FOUND) {
+                                    break;
+                                } else if (hres != S_OK) {
+                                    loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+                                               "Failed to enumerate DXGI adapters at index %d. As a result, drivers may be skipped", j);
+                                    continue;
+                                }
+
+                                DXGI_ADAPTER_DESC1 description;
+                                hres = adapter->lpVtbl->GetDesc1(adapter, &description);
+                                if (hres != S_OK) {
+                                    loader_log(
+                                        inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+                                        "Failed to get DXGI adapter information at index %d. As a result, drivers may be skipped", j);
+                                    continue;
+                                }
+
+                                if (description.VendorId == known_drivers[i].vendor_id) {
+                                    found_gpu = true;
+                                    break;
+                                }
+                            }
+
+                            if (!found_gpu) {
+                                loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+                                           "Dropping driver %s as no corresponduing DXGI adapter was found", name);
+                                continue;
+                            }
+                        }
+                    }
+
                     if (strlen(*reg_data) == 0) {
                         // The list is emtpy. Add the first entry.
                         (void)snprintf(*reg_data, name_size + 1, "%s", name);
@@ -856,7 +999,8 @@ VkResult loaderGetRegistryFiles(const struct loader_instance *inst, char *locati
                         }
                     }
                 }
-                name_size = 2048;
+                name_size = sizeof(name);
+                value_size = sizeof(value);
             }
             RegCloseKey(key);
         }
@@ -875,6 +1019,9 @@ VkResult loaderGetRegistryFiles(const struct loader_instance *inst, char *locati
     }
 
 out:
+    if (is_driver && dxgi_factory != NULL) {
+        dxgi_factory->lpVtbl->Release(dxgi_factory);
+    }
 
     return result;
 }
@@ -1635,7 +1782,7 @@ bool loaderImplicitLayerIsEnabled(const struct loader_instance *inst, const stru
         enable = true;
     } else {
         // Otherwise, only enable this layer if the enable environment variable is defined
-        env_value = loader_secure_getenv(prop->enable_env_var.name, inst);
+        env_value = loader_getenv(prop->enable_env_var.name, inst);
         if (env_value && !strcmp(prop->enable_env_var.value, env_value)) {
             enable = true;
         }
@@ -1644,7 +1791,7 @@ bool loaderImplicitLayerIsEnabled(const struct loader_instance *inst, const stru
 
     // The disable_environment has priority over everything else.  If it is defined, the layer is always
     // disabled.
-    env_value = loader_secure_getenv(prop->disable_env_var.name, inst);
+    env_value = loader_getenv(prop->disable_env_var.name, inst);
     if (env_value) {
         enable = false;
     }
@@ -1906,7 +2053,8 @@ struct loader_icd_term *loader_get_icd_and_device(const VkDevice device, struct
             for (struct loader_device *dev = icd_term->logical_device_list; dev; dev = dev->next)
                 // Value comparison of device prevents object wrapping by layers
                 if (loader_get_dispatch(dev->icd_device) == loader_get_dispatch(device) ||
-                    loader_get_dispatch(dev->chain_device) == loader_get_dispatch(device)) {
+                    (dev->chain_device != VK_NULL_HANDLE &&
+                     loader_get_dispatch(dev->chain_device) == loader_get_dispatch(device))) {
                     *found_dev = dev;
                     if (NULL != icd_index) {
                         *icd_index = index;
@@ -2287,6 +2435,12 @@ void loader_initialize(void) {
         .malloc_fn = loader_instance_tls_heap_alloc, .free_fn = loader_instance_tls_heap_free,
     };
     cJSON_InitHooks(&alloc_fns);
+
+#if defined(_WIN32)
+    // This is needed to ensure that newer APIs are available right away
+    // and not after the first call that has been statically linked
+    LoadLibrary("gdi32.dll");
+#endif
 }
 
 struct loader_data_files {
@@ -3685,8 +3839,10 @@ static VkResult ReadDataFilesInSearchPaths(const struct loader_instance *inst, e
             search_path_size += DetermineDataFilePathSize(EXTRASYSCONFDIR, rel_size);
 #endif
             if (is_directory_list) {
-                search_path_size += DetermineDataFilePathSize(xdgdatahome, rel_size);
-                search_path_size += DetermineDataFilePathSize(home_root, rel_size);
+                if (!IsHighIntegrity()) {
+                    search_path_size += DetermineDataFilePathSize(xdgdatahome, rel_size);
+                    search_path_size += DetermineDataFilePathSize(home_root, rel_size);
+                }
             }
 #endif
         }
@@ -3793,26 +3949,168 @@ out:
 }
 
 #ifdef _WIN32
+// Read manifest JSON files uing the Windows driver interface
+static VkResult ReadManifestsFromD3DAdapters(const struct loader_instance *inst, char **reg_data, PDWORD reg_data_size,
+                                             const wchar_t *value_name) {
+    VkResult result = VK_INCOMPLETE;
+    LoaderEnumAdapters2 adapters = {.adapter_count = 0, .adapters = NULL};
+    LoaderQueryRegistryInfo *full_info = NULL;
+    size_t full_info_size = 0;
+    char *json_path = NULL;
+    size_t json_path_size = 0;
+
+    PFN_LoaderEnumAdapters2 fpLoaderEnumAdapters2 =
+        (PFN_LoaderEnumAdapters2)GetProcAddress(GetModuleHandle("gdi32.dll"), "D3DKMTEnumAdapters2");
+    PFN_LoaderQueryAdapterInfo fpLoaderQueryAdapterInfo =
+        (PFN_LoaderQueryAdapterInfo)GetProcAddress(GetModuleHandle("gdi32.dll"), "D3DKMTQueryAdapterInfo");
+    if (fpLoaderEnumAdapters2 == NULL || fpLoaderQueryAdapterInfo == NULL) {
+        result = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto out;
+    }
+
+    // Get all of the adapters
+    NTSTATUS status = fpLoaderEnumAdapters2(&adapters);
+    if (status == STATUS_SUCCESS && adapters.adapter_count > 0) {
+        adapters.adapters = loader_instance_heap_alloc(inst, sizeof(*adapters.adapters) * adapters.adapter_count,
+                                                       VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+        if (adapters.adapters == NULL) {
+            goto out;
+        }
+        status = fpLoaderEnumAdapters2(&adapters);
+    }
+    if (status != STATUS_SUCCESS) {
+        goto out;
+    }
+
+    // If that worked, we need to get the manifest file(s) for each adapter
+    for (ULONG i = 0; i < adapters.adapter_count; ++i) {
+        // The first query should just check if the field exists and how big it is
+        LoaderQueryRegistryInfo filename_info = {
+            .query_type = LOADER_QUERY_REGISTRY_ADAPTER_KEY,
+            .query_flags =
+                {
+                    .translate_path = true,
+                },
+            .value_type = REG_MULTI_SZ,
+            .physical_adapter_index = 0,
+        };
+        wcsncpy(filename_info.value_name, value_name, sizeof(filename_info.value_name) / sizeof(DWORD));
+        LoaderQueryAdapterInfo query_info = {
+            .handle = adapters.adapters[i].handle,
+            .type = LOADER_QUERY_TYPE_REGISTRY,
+            .private_data = &filename_info,
+            .private_data_size = sizeof(filename_info),
+        };
+        status = fpLoaderQueryAdapterInfo(&query_info);
+
+        // This error indicates that the type didn't match, so we'll try a REG_SZ
+        if (status != STATUS_SUCCESS) {
+            filename_info.value_type = REG_SZ;
+            status = fpLoaderQueryAdapterInfo(&query_info);
+        }
+
+        if (status != STATUS_SUCCESS || filename_info.status != LOADER_QUERY_REGISTRY_STATUS_BUFFER_OVERFLOW) {
+            continue;
+        }
+
+        while (status == STATUS_SUCCESS &&
+               ((LoaderQueryRegistryInfo *)query_info.private_data)->status == LOADER_QUERY_REGISTRY_STATUS_BUFFER_OVERFLOW) {
+            bool needs_copy = (full_info == NULL);
+            size_t full_size = sizeof(LoaderQueryRegistryInfo) + filename_info.output_value_size;
+            void *buffer =
+                loader_instance_heap_realloc(inst, full_info, full_info_size, full_size, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+            if (buffer == NULL) {
+                result = VK_ERROR_OUT_OF_HOST_MEMORY;
+                goto out;
+            }
+            full_info = buffer;
+            full_info_size = full_size;
+
+            if (needs_copy) {
+                memcpy(full_info, &filename_info, sizeof(LoaderQueryRegistryInfo));
+            }
+            query_info.private_data = full_info;
+            query_info.private_data_size = (UINT)full_info_size;
+            status = fpLoaderQueryAdapterInfo(&query_info);
+        }
+
+        if (status != STATUS_SUCCESS || full_info->status != LOADER_QUERY_REGISTRY_STATUS_SUCCESS) {
+            goto out;
+        }
+
+        // Convert the wide string to a narrow string
+        void *buffer = loader_instance_heap_realloc(inst, json_path, json_path_size, full_info->output_value_size,
+                                                    VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+        if (buffer == NULL) {
+            result = VK_ERROR_OUT_OF_HOST_MEMORY;
+            goto out;
+        }
+        json_path = buffer;
+        json_path_size = full_info->output_value_size;
+
+        // Iterate over each component string
+        for (const wchar_t *curr_path = full_info->output_string; curr_path[0] != '\0'; curr_path += wcslen(curr_path) + 1) {
+            WideCharToMultiByte(CP_UTF8, 0, curr_path, -1, json_path, (int)json_path_size, NULL, NULL);
+
+            // Add the string to the output list
+            result = VK_SUCCESS;
+            loaderAddJsonEntry(inst, reg_data, reg_data_size, (LPCTSTR)L"EnumAdapters", REG_SZ, json_path,
+                               (DWORD)strlen(json_path) + 1, &result);
+            if (result != VK_SUCCESS) {
+                goto out;
+            }
+
+            // If this is a string and not a multi-string, we don't want to go throught the loop more than once
+            if (full_info->value_type == REG_SZ) {
+                break;
+            }
+        }
+    }
+
+out:
+    if (json_path != NULL) {
+        loader_instance_heap_free(inst, json_path);
+    }
+    if (full_info != NULL) {
+        loader_instance_heap_free(inst, full_info);
+    }
+    if (adapters.adapters != NULL) {
+        loader_instance_heap_free(inst, adapters.adapters);
+    }
+
+    return result;
+}
+
 // Look for data files in the registry.
 static VkResult ReadDataFilesInRegistry(const struct loader_instance *inst, enum loader_data_files_type data_file_type,
                                         bool warn_if_not_present, char *registry_location, struct loader_data_files *out_files) {
     VkResult vk_result = VK_SUCCESS;
     bool is_icd = (data_file_type == LOADER_DATA_FILE_MANIFEST_ICD);
-    bool use_secondary_hive = data_file_type == LOADER_DATA_FILE_MANIFEST_LAYER;
     char *search_path = NULL;
 
     // These calls look at the PNP/Device section of the registry.
     VkResult regHKR_result = VK_SUCCESS;
     DWORD reg_size = 4096;
     if (!strncmp(registry_location, VK_DRIVERS_INFO_REGISTRY_LOC, sizeof(VK_DRIVERS_INFO_REGISTRY_LOC))) {
-        regHKR_result = loaderGetDeviceRegistryFiles(inst, &search_path, &reg_size, LoaderPnpDriverRegistry());
+        // If we're looking for drivers we need to try enumerating adapters
+        regHKR_result = ReadManifestsFromD3DAdapters(inst, &search_path, &reg_size, LoaderPnpDriverRegistryWide());
+        if (regHKR_result == VK_INCOMPLETE) {
+            regHKR_result = loaderGetDeviceRegistryFiles(inst, &search_path, &reg_size, LoaderPnpDriverRegistry());
+        }
     } else if (!strncmp(registry_location, VK_ELAYERS_INFO_REGISTRY_LOC, sizeof(VK_ELAYERS_INFO_REGISTRY_LOC))) {
-        regHKR_result = loaderGetDeviceRegistryFiles(inst, &search_path, &reg_size, LoaderPnpELayerRegistry());
+        regHKR_result = ReadManifestsFromD3DAdapters(inst, &search_path, &reg_size, LoaderPnpELayerRegistryWide());
+        if (regHKR_result == VK_INCOMPLETE) {
+            regHKR_result = loaderGetDeviceRegistryFiles(inst, &search_path, &reg_size, LoaderPnpELayerRegistry());
+        }
     } else if (!strncmp(registry_location, VK_ILAYERS_INFO_REGISTRY_LOC, sizeof(VK_ILAYERS_INFO_REGISTRY_LOC))) {
-        regHKR_result = loaderGetDeviceRegistryFiles(inst, &search_path, &reg_size, LoaderPnpILayerRegistry());
+        regHKR_result = ReadManifestsFromD3DAdapters(inst, &search_path, &reg_size, LoaderPnpILayerRegistryWide());
+        if (regHKR_result == VK_INCOMPLETE) {
+            regHKR_result = loaderGetDeviceRegistryFiles(inst, &search_path, &reg_size, LoaderPnpILayerRegistry());
+        }
     }
 
     // This call looks into the Khronos non-device specific section of the registry.
+    bool use_secondary_hive = (data_file_type == LOADER_DATA_FILE_MANIFEST_LAYER) && (!IsHighIntegrity());
     VkResult reg_result = loaderGetRegistryFiles(inst, registry_location, use_secondary_hive, &search_path, &reg_size);
 
     if ((VK_SUCCESS != reg_result && VK_SUCCESS != regHKR_result) || NULL == search_path) {
@@ -4455,7 +4753,7 @@ void loaderScanForImplicitLayers(struct loader_instance *inst, struct loader_lay
                 continue;
             }
 
-            res = loaderAddLayerProperties(inst, instance_layers, json, false, file_str);
+            res = loaderAddLayerProperties(inst, instance_layers, json, true, file_str);
 
             loader_instance_heap_free(inst, file_str);
             cJSON_Delete(json);
@@ -4470,13 +4768,11 @@ void loaderScanForImplicitLayers(struct loader_instance *inst, struct loader_lay
     // actually present in the available layer list
     VerifyAllMetaLayers(inst, instance_layers, &override_layer_valid);
 
-    if (override_layer_valid) {
-        loaderRemoveLayersInBlacklist(inst, instance_layers);
-        if (NULL != inst) {
+    if (override_layer_valid || implicit_metalayer_present) {
+        loaderRemoveLayersNotInImplicitMetaLayers(inst, instance_layers);
+        if (override_layer_valid && inst != NULL) {
             inst->override_layer_present = true;
         }
-    } else if (implicit_metalayer_present) {
-        loaderRemoveLayersNotInImplicitMetaLayers(inst, instance_layers);
     }
 
 out:
@@ -5098,7 +5394,7 @@ static void loaderAddEnvironmentLayers(struct loader_instance *inst, const enum
                                        struct loader_layer_list *target_list, struct loader_layer_list *expanded_target_list,
                                        const struct loader_layer_list *source_list) {
     char *next, *name;
-    char *layer_env = loader_secure_getenv(env_name, inst);
+    char *layer_env = loader_getenv(env_name, inst);
     if (layer_env == NULL) {
         goto out;
     }
@@ -5981,16 +6277,18 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance(const VkInstanceCreateI
 
         // Get the driver version from vkEnumerateInstanceVersion
         uint32_t icd_version = VK_API_VERSION_1_0;
-        PFN_vkEnumerateInstanceVersion icd_enumerate_instance_version = (PFN_vkEnumerateInstanceVersion)
-            icd_term->scanned_icd->GetInstanceProcAddr(NULL, "vkEnumerateInstanceVersion");
         VkResult icd_result = VK_SUCCESS;
-        if (icd_enumerate_instance_version != NULL) {
-            icd_result = icd_enumerate_instance_version(&icd_version);
-            if (icd_result != VK_SUCCESS) {
-                icd_version = VK_API_VERSION_1_0;
-                loader_log(ptr_instance, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, "terminator_CreateInstance: ICD \"%s\" "
-                    "vkEnumerateInstanceVersion returned error. The ICD will be treated as a 1.0 ICD",
-                    icd_term->scanned_icd->lib_name);
+        if (icd_term->scanned_icd->api_version >= VK_API_VERSION_1_1) {
+            PFN_vkEnumerateInstanceVersion icd_enumerate_instance_version = (PFN_vkEnumerateInstanceVersion)
+                icd_term->scanned_icd->GetInstanceProcAddr(NULL, "vkEnumerateInstanceVersion");
+            if (icd_enumerate_instance_version != NULL) {
+                icd_result = icd_enumerate_instance_version(&icd_version);
+                if (icd_result != VK_SUCCESS) {
+                    icd_version = VK_API_VERSION_1_0;
+                    loader_log(ptr_instance, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, "terminator_CreateInstance: ICD \"%s\" "
+                        "vkEnumerateInstanceVersion returned error. The ICD will be treated as a 1.0 ICD",
+                        icd_term->scanned_icd->lib_name);
+                }
             }
         }
 
@@ -6942,7 +7240,7 @@ VKAPI_ATTR VkResult VKAPI_CALL
 terminator_EnumerateInstanceVersion(const VkEnumerateInstanceVersionChain *chain, uint32_t* pApiVersion) {
     // NOTE: The Vulkan WG doesn't want us checking pApiVersion for NULL, but instead
     // prefers us crashing.
-    *pApiVersion = VK_MAKE_VERSION(loader_major_version, loader_minor_version, 0);
+    *pApiVersion = VK_MAKE_VERSION(loader_major_version, loader_minor_version, VK_HEADER_VERSION);
     return VK_SUCCESS;
 }
 

+ 3 - 0
thirdparty/vulkan/loader/loader.h

@@ -333,6 +333,9 @@ struct loader_instance {
     bool wsi_ios_surface_enabled;
 #endif
     bool wsi_headless_surface_enabled;
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+    bool wsi_metal_surface_enabled;
+#endif
     bool wsi_display_enabled;
     bool wsi_display_props2_enabled;
 };

+ 12 - 0
thirdparty/vulkan/loader/unknown_ext_chain_gas.asm → thirdparty/vulkan/loader/unknown_ext_chain_gas.S

@@ -23,6 +23,12 @@
 # VkPhysicalDevice or a dispatchable object it can unwrap the object, possibly overwriting the wrapped physical device, and then
 # jump to the next function in the call chain
 
+#ifdef HAVE_CET_H
+#include <cet.h>
+#else
+#define _CET_ENDBR
+#endif
+
 .intel_syntax noprefix
 .include "gen_defines.asm"
 
@@ -31,6 +37,7 @@
 .macro PhysDevExtTramp num
 .global vkPhysDevExtTramp\num
 vkPhysDevExtTramp\num:
+    _CET_ENDBR
     mov     rax, [rdi]
     mov     rdi, [rdi + PHYS_DEV_OFFSET_PHYS_DEV_TRAMP]
     jmp     [rax + (PHYS_DEV_OFFSET_INST_DISPATCH + (PTR_SIZE * \num))]
@@ -39,6 +46,7 @@ vkPhysDevExtTramp\num:
 .macro PhysDevExtTermin num
 .global vkPhysDevExtTermin\num
 vkPhysDevExtTermin\num:
+    _CET_ENDBR
     mov     rax, [rdi + ICD_TERM_OFFSET_PHYS_DEV_TERM]                          # Store the loader_icd_term* in rax
     cmp     qword ptr [rax + (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * \num))], 0 # Check if the next function in the chain is NULL
     je      terminError\num                                                     # Go to the error section if it is NULL
@@ -60,6 +68,7 @@ terminError\num:
 .macro DevExtTramp num
 .global vkdev_ext\num
 vkdev_ext\num:
+    _CET_ENDBR
     mov     rax, [rdi]                                                          # Dereference the handle to get the dispatch table
     jmp     [rax + (EXT_OFFSET_DEVICE_DISPATCH + (PTR_SIZE * \num))]            # Jump to the appropriate call chain
 .endm
@@ -69,6 +78,7 @@ vkdev_ext\num:
 .macro PhysDevExtTramp num
 .global vkPhysDevExtTramp\num
 vkPhysDevExtTramp\num:
+    _CET_ENDBR
     mov     eax, [esp + 4]                              # Load the wrapped VkPhysicalDevice into eax
     mov     ecx, [eax + PHYS_DEV_OFFSET_PHYS_DEV_TRAMP] # Load the unwrapped VkPhysicalDevice into ecx
     mov     [esp + 4], ecx                              # Overwrite the wrapped VkPhysicalDevice with the unwrapped one (on the stack)
@@ -79,6 +89,7 @@ vkPhysDevExtTramp\num:
 .macro PhysDevExtTermin num
 .global vkPhysDevExtTermin\num
 vkPhysDevExtTermin\num:
+    _CET_ENDBR
     mov     ecx, [esp + 4]                                                      # Move the wrapped VkPhysicalDevice into ecx
     mov     eax, [ecx + ICD_TERM_OFFSET_PHYS_DEV_TERM]                          # Store the loader_icd_term* in eax
     cmp     dword ptr [eax + (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * \num))], 0 # Check if the next function in the chain is NULL
@@ -102,6 +113,7 @@ terminError\num:
 .macro DevExtTramp num
 .global vkdev_ext\num
 vkdev_ext\num:
+    _CET_ENDBR
     mov     eax, [esp + 4]                                                      # Dereference the handle to get the dispatch table
     jmp     [eax + (EXT_OFFSET_DEVICE_DISPATCH + (PTR_SIZE * \num))]            # Jump to the appropriate call chain
 .endm

+ 21 - 0
thirdparty/vulkan/loader/vk_dispatch_table_helper.h

@@ -86,6 +86,12 @@ static VKAPI_ATTR VkResult VKAPI_CALL StubBindImageMemory2KHR(VkDevice device, u
 static VKAPI_ATTR void VKAPI_CALL StubGetDescriptorSetLayoutSupportKHR(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport) {  };
 static VKAPI_ATTR void VKAPI_CALL StubCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride) {  };
 static VKAPI_ATTR void VKAPI_CALL StubCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride) {  };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetSemaphoreCounterValueKHR(VkDevice device, VkSemaphore semaphore, uint64_t* pValue) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubWaitSemaphoresKHR(VkDevice device, const VkSemaphoreWaitInfoKHR* pWaitInfo, uint64_t timeout) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubSignalSemaphoreKHR(VkDevice device, const VkSemaphoreSignalInfoKHR* pSignalInfo) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetPipelineExecutablePropertiesKHR(VkDevice                        device, const VkPipelineInfoKHR*        pPipelineInfo, uint32_t* pExecutableCount, VkPipelineExecutablePropertiesKHR* pProperties) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetPipelineExecutableStatisticsKHR(VkDevice                        device, const VkPipelineExecutableInfoKHR*  pExecutableInfo, uint32_t* pStatisticCount, VkPipelineExecutableStatisticKHR* pStatistics) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetPipelineExecutableInternalRepresentationsKHR(VkDevice                        device, const VkPipelineExecutableInfoKHR*  pExecutableInfo, uint32_t* pInternalRepresentationCount, VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations) { return VK_SUCCESS; };
 static VKAPI_ATTR VkResult VKAPI_CALL StubDebugMarkerSetObjectTagEXT(VkDevice device, const VkDebugMarkerObjectTagInfoEXT* pTagInfo) { return VK_SUCCESS; };
 static VKAPI_ATTR VkResult VKAPI_CALL StubDebugMarkerSetObjectNameEXT(VkDevice device, const VkDebugMarkerObjectNameInfoEXT* pNameInfo) { return VK_SUCCESS; };
 static VKAPI_ATTR void VKAPI_CALL StubCmdDebugMarkerBeginEXT(VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo) {  };
@@ -179,6 +185,7 @@ static VKAPI_ATTR VkResult VKAPI_CALL StubReleaseFullScreenExclusiveModeEXT(VkDe
 #ifdef VK_USE_PLATFORM_WIN32_KHR
 static VKAPI_ATTR VkResult VKAPI_CALL StubGetDeviceGroupSurfacePresentModes2EXT(VkDevice device, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkDeviceGroupPresentModeFlagsKHR* pModes) { return VK_SUCCESS; };
 #endif // VK_USE_PLATFORM_WIN32_KHR
+static VKAPI_ATTR void VKAPI_CALL StubCmdSetLineStippleEXT(VkCommandBuffer commandBuffer, uint32_t lineStippleFactor, uint16_t lineStipplePattern) {  };
 static VKAPI_ATTR void VKAPI_CALL StubResetQueryPoolEXT(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount) {  };
 
 
@@ -425,6 +432,18 @@ static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDisp
     if (table->CmdDrawIndirectCountKHR == nullptr) { table->CmdDrawIndirectCountKHR = (PFN_vkCmdDrawIndirectCountKHR)StubCmdDrawIndirectCountKHR; }
     table->CmdDrawIndexedIndirectCountKHR = (PFN_vkCmdDrawIndexedIndirectCountKHR) gpa(device, "vkCmdDrawIndexedIndirectCountKHR");
     if (table->CmdDrawIndexedIndirectCountKHR == nullptr) { table->CmdDrawIndexedIndirectCountKHR = (PFN_vkCmdDrawIndexedIndirectCountKHR)StubCmdDrawIndexedIndirectCountKHR; }
+    table->GetSemaphoreCounterValueKHR = (PFN_vkGetSemaphoreCounterValueKHR) gpa(device, "vkGetSemaphoreCounterValueKHR");
+    if (table->GetSemaphoreCounterValueKHR == nullptr) { table->GetSemaphoreCounterValueKHR = (PFN_vkGetSemaphoreCounterValueKHR)StubGetSemaphoreCounterValueKHR; }
+    table->WaitSemaphoresKHR = (PFN_vkWaitSemaphoresKHR) gpa(device, "vkWaitSemaphoresKHR");
+    if (table->WaitSemaphoresKHR == nullptr) { table->WaitSemaphoresKHR = (PFN_vkWaitSemaphoresKHR)StubWaitSemaphoresKHR; }
+    table->SignalSemaphoreKHR = (PFN_vkSignalSemaphoreKHR) gpa(device, "vkSignalSemaphoreKHR");
+    if (table->SignalSemaphoreKHR == nullptr) { table->SignalSemaphoreKHR = (PFN_vkSignalSemaphoreKHR)StubSignalSemaphoreKHR; }
+    table->GetPipelineExecutablePropertiesKHR = (PFN_vkGetPipelineExecutablePropertiesKHR) gpa(device, "vkGetPipelineExecutablePropertiesKHR");
+    if (table->GetPipelineExecutablePropertiesKHR == nullptr) { table->GetPipelineExecutablePropertiesKHR = (PFN_vkGetPipelineExecutablePropertiesKHR)StubGetPipelineExecutablePropertiesKHR; }
+    table->GetPipelineExecutableStatisticsKHR = (PFN_vkGetPipelineExecutableStatisticsKHR) gpa(device, "vkGetPipelineExecutableStatisticsKHR");
+    if (table->GetPipelineExecutableStatisticsKHR == nullptr) { table->GetPipelineExecutableStatisticsKHR = (PFN_vkGetPipelineExecutableStatisticsKHR)StubGetPipelineExecutableStatisticsKHR; }
+    table->GetPipelineExecutableInternalRepresentationsKHR = (PFN_vkGetPipelineExecutableInternalRepresentationsKHR) gpa(device, "vkGetPipelineExecutableInternalRepresentationsKHR");
+    if (table->GetPipelineExecutableInternalRepresentationsKHR == nullptr) { table->GetPipelineExecutableInternalRepresentationsKHR = (PFN_vkGetPipelineExecutableInternalRepresentationsKHR)StubGetPipelineExecutableInternalRepresentationsKHR; }
     table->DebugMarkerSetObjectTagEXT = (PFN_vkDebugMarkerSetObjectTagEXT) gpa(device, "vkDebugMarkerSetObjectTagEXT");
     if (table->DebugMarkerSetObjectTagEXT == nullptr) { table->DebugMarkerSetObjectTagEXT = (PFN_vkDebugMarkerSetObjectTagEXT)StubDebugMarkerSetObjectTagEXT; }
     table->DebugMarkerSetObjectNameEXT = (PFN_vkDebugMarkerSetObjectNameEXT) gpa(device, "vkDebugMarkerSetObjectNameEXT");
@@ -607,6 +626,8 @@ static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDisp
     table->GetDeviceGroupSurfacePresentModes2EXT = (PFN_vkGetDeviceGroupSurfacePresentModes2EXT) gpa(device, "vkGetDeviceGroupSurfacePresentModes2EXT");
     if (table->GetDeviceGroupSurfacePresentModes2EXT == nullptr) { table->GetDeviceGroupSurfacePresentModes2EXT = (PFN_vkGetDeviceGroupSurfacePresentModes2EXT)StubGetDeviceGroupSurfacePresentModes2EXT; }
 #endif // VK_USE_PLATFORM_WIN32_KHR
+    table->CmdSetLineStippleEXT = (PFN_vkCmdSetLineStippleEXT) gpa(device, "vkCmdSetLineStippleEXT");
+    if (table->CmdSetLineStippleEXT == nullptr) { table->CmdSetLineStippleEXT = (PFN_vkCmdSetLineStippleEXT)StubCmdSetLineStippleEXT; }
     table->ResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT) gpa(device, "vkResetQueryPoolEXT");
     if (table->ResetQueryPoolEXT == nullptr) { table->ResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT)StubResetQueryPoolEXT; }
 }

+ 13 - 0
thirdparty/vulkan/loader/vk_layer_dispatch_table.h

@@ -470,6 +470,16 @@ typedef struct VkLayerDispatchTable_ {
     PFN_vkCmdDrawIndirectCountKHR CmdDrawIndirectCountKHR;
     PFN_vkCmdDrawIndexedIndirectCountKHR CmdDrawIndexedIndirectCountKHR;
 
+    // ---- VK_KHR_timeline_semaphore extension commands
+    PFN_vkGetSemaphoreCounterValueKHR GetSemaphoreCounterValueKHR;
+    PFN_vkWaitSemaphoresKHR WaitSemaphoresKHR;
+    PFN_vkSignalSemaphoreKHR SignalSemaphoreKHR;
+
+    // ---- VK_KHR_pipeline_executable_properties extension commands
+    PFN_vkGetPipelineExecutablePropertiesKHR GetPipelineExecutablePropertiesKHR;
+    PFN_vkGetPipelineExecutableStatisticsKHR GetPipelineExecutableStatisticsKHR;
+    PFN_vkGetPipelineExecutableInternalRepresentationsKHR GetPipelineExecutableInternalRepresentationsKHR;
+
     // ---- VK_EXT_debug_marker extension commands
     PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT;
     PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectNameEXT;
@@ -631,6 +641,9 @@ typedef struct VkLayerDispatchTable_ {
     PFN_vkGetDeviceGroupSurfacePresentModes2EXT GetDeviceGroupSurfacePresentModes2EXT;
 #endif // VK_USE_PLATFORM_WIN32_KHR
 
+    // ---- VK_EXT_line_rasterization extension commands
+    PFN_vkCmdSetLineStippleEXT CmdSetLineStippleEXT;
+
     // ---- VK_EXT_host_query_reset extension commands
     PFN_vkResetQueryPoolEXT ResetQueryPoolEXT;
 } VkLayerDispatchTable;

+ 127 - 38
thirdparty/vulkan/loader/vk_loader_extensions.c

@@ -527,6 +527,16 @@ VKAPI_ATTR void VKAPI_CALL loader_init_device_extension_dispatch_table(struct lo
     table->CmdDrawIndirectCountKHR = (PFN_vkCmdDrawIndirectCountKHR)gdpa(dev, "vkCmdDrawIndirectCountKHR");
     table->CmdDrawIndexedIndirectCountKHR = (PFN_vkCmdDrawIndexedIndirectCountKHR)gdpa(dev, "vkCmdDrawIndexedIndirectCountKHR");
 
+    // ---- VK_KHR_timeline_semaphore extension commands
+    table->GetSemaphoreCounterValueKHR = (PFN_vkGetSemaphoreCounterValueKHR)gdpa(dev, "vkGetSemaphoreCounterValueKHR");
+    table->WaitSemaphoresKHR = (PFN_vkWaitSemaphoresKHR)gdpa(dev, "vkWaitSemaphoresKHR");
+    table->SignalSemaphoreKHR = (PFN_vkSignalSemaphoreKHR)gdpa(dev, "vkSignalSemaphoreKHR");
+
+    // ---- VK_KHR_pipeline_executable_properties extension commands
+    table->GetPipelineExecutablePropertiesKHR = (PFN_vkGetPipelineExecutablePropertiesKHR)gdpa(dev, "vkGetPipelineExecutablePropertiesKHR");
+    table->GetPipelineExecutableStatisticsKHR = (PFN_vkGetPipelineExecutableStatisticsKHR)gdpa(dev, "vkGetPipelineExecutableStatisticsKHR");
+    table->GetPipelineExecutableInternalRepresentationsKHR = (PFN_vkGetPipelineExecutableInternalRepresentationsKHR)gdpa(dev, "vkGetPipelineExecutableInternalRepresentationsKHR");
+
     // ---- VK_EXT_debug_marker extension commands
     table->DebugMarkerSetObjectTagEXT = (PFN_vkDebugMarkerSetObjectTagEXT)gdpa(dev, "vkDebugMarkerSetObjectTagEXT");
     table->DebugMarkerSetObjectNameEXT = (PFN_vkDebugMarkerSetObjectNameEXT)gdpa(dev, "vkDebugMarkerSetObjectNameEXT");
@@ -688,6 +698,9 @@ VKAPI_ATTR void VKAPI_CALL loader_init_device_extension_dispatch_table(struct lo
     table->GetDeviceGroupSurfacePresentModes2EXT = (PFN_vkGetDeviceGroupSurfacePresentModes2EXT)gdpa(dev, "vkGetDeviceGroupSurfacePresentModes2EXT");
 #endif // VK_USE_PLATFORM_WIN32_KHR
 
+    // ---- VK_EXT_line_rasterization extension commands
+    table->CmdSetLineStippleEXT = (PFN_vkCmdSetLineStippleEXT)gdpa(dev, "vkCmdSetLineStippleEXT");
+
     // ---- VK_EXT_host_query_reset extension commands
     table->ResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT)gdpa(dev, "vkResetQueryPoolEXT");
 }
@@ -1138,6 +1151,16 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis
     if (!strcmp(name, "CmdDrawIndirectCountKHR")) return (void *)table->CmdDrawIndirectCountKHR;
     if (!strcmp(name, "CmdDrawIndexedIndirectCountKHR")) return (void *)table->CmdDrawIndexedIndirectCountKHR;
 
+    // ---- VK_KHR_timeline_semaphore extension commands
+    if (!strcmp(name, "GetSemaphoreCounterValueKHR")) return (void *)table->GetSemaphoreCounterValueKHR;
+    if (!strcmp(name, "WaitSemaphoresKHR")) return (void *)table->WaitSemaphoresKHR;
+    if (!strcmp(name, "SignalSemaphoreKHR")) return (void *)table->SignalSemaphoreKHR;
+
+    // ---- VK_KHR_pipeline_executable_properties extension commands
+    if (!strcmp(name, "GetPipelineExecutablePropertiesKHR")) return (void *)table->GetPipelineExecutablePropertiesKHR;
+    if (!strcmp(name, "GetPipelineExecutableStatisticsKHR")) return (void *)table->GetPipelineExecutableStatisticsKHR;
+    if (!strcmp(name, "GetPipelineExecutableInternalRepresentationsKHR")) return (void *)table->GetPipelineExecutableInternalRepresentationsKHR;
+
     // ---- VK_EXT_debug_marker extension commands
     if (!strcmp(name, "DebugMarkerSetObjectTagEXT")) return (void *)table->DebugMarkerSetObjectTagEXT;
     if (!strcmp(name, "DebugMarkerSetObjectNameEXT")) return (void *)table->DebugMarkerSetObjectNameEXT;
@@ -1299,6 +1322,9 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis
     if (!strcmp(name, "GetDeviceGroupSurfacePresentModes2EXT")) return (void *)table->GetDeviceGroupSurfacePresentModes2EXT;
 #endif // VK_USE_PLATFORM_WIN32_KHR
 
+    // ---- VK_EXT_line_rasterization extension commands
+    if (!strcmp(name, "CmdSetLineStippleEXT")) return (void *)table->CmdSetLineStippleEXT;
+
     // ---- VK_EXT_host_query_reset extension commands
     if (!strcmp(name, "ResetQueryPoolEXT")) return (void *)table->ResetQueryPoolEXT;
 
@@ -1885,6 +1911,62 @@ VKAPI_ATTR void VKAPI_CALL CmdDrawIndexedIndirectCountKHR(
 }
 
 
+// ---- VK_KHR_timeline_semaphore extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL GetSemaphoreCounterValueKHR(
+    VkDevice                                    device,
+    VkSemaphore                                 semaphore,
+    uint64_t*                                   pValue) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    return disp->GetSemaphoreCounterValueKHR(device, semaphore, pValue);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL WaitSemaphoresKHR(
+    VkDevice                                    device,
+    const VkSemaphoreWaitInfoKHR*               pWaitInfo,
+    uint64_t                                    timeout) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    return disp->WaitSemaphoresKHR(device, pWaitInfo, timeout);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL SignalSemaphoreKHR(
+    VkDevice                                    device,
+    const VkSemaphoreSignalInfoKHR*             pSignalInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    return disp->SignalSemaphoreKHR(device, pSignalInfo);
+}
+
+
+// ---- VK_KHR_pipeline_executable_properties extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPipelineExecutablePropertiesKHR(
+    VkDevice                                    device,
+    const VkPipelineInfoKHR*                    pPipelineInfo,
+    uint32_t*                                   pExecutableCount,
+    VkPipelineExecutablePropertiesKHR*          pProperties) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    return disp->GetPipelineExecutablePropertiesKHR(device, pPipelineInfo, pExecutableCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPipelineExecutableStatisticsKHR(
+    VkDevice                                    device,
+    const VkPipelineExecutableInfoKHR*          pExecutableInfo,
+    uint32_t*                                   pStatisticCount,
+    VkPipelineExecutableStatisticKHR*           pStatistics) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    return disp->GetPipelineExecutableStatisticsKHR(device, pExecutableInfo, pStatisticCount, pStatistics);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPipelineExecutableInternalRepresentationsKHR(
+    VkDevice                                    device,
+    const VkPipelineExecutableInfoKHR*          pExecutableInfo,
+    uint32_t*                                   pInternalRepresentationCount,
+    VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    return disp->GetPipelineExecutableInternalRepresentationsKHR(device, pExecutableInfo, pInternalRepresentationCount, pInternalRepresentations);
+}
+
+
 // ---- VK_EXT_debug_marker extension trampoline/terminators
 
 VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectTagEXT(
@@ -3005,28 +3087,6 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateImagePipeSurfaceFUCHSIA(
 
 #endif // VK_USE_PLATFORM_FUCHSIA
 
-// ---- VK_EXT_metal_surface extension trampoline/terminators
-
-#ifdef VK_USE_PLATFORM_METAL_EXT
-VKAPI_ATTR VkResult VKAPI_CALL CreateMetalSurfaceEXT(
-    VkInstance                                  instance,
-    const VkMetalSurfaceCreateInfoEXT*          pCreateInfo,
-    const VkAllocationCallbacks*                pAllocator,
-    VkSurfaceKHR*                               pSurface) {
-#error("Not implemented. Likely needs to be manually generated!");
-    return disp->CreateMetalSurfaceEXT(instance, pCreateInfo, pAllocator, pSurface);
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMetalSurfaceEXT(
-    VkInstance                                  instance,
-    const VkMetalSurfaceCreateInfoEXT*          pCreateInfo,
-    const VkAllocationCallbacks*                pAllocator,
-    VkSurfaceKHR*                               pSurface) {
-#error("Not implemented. Likely needs to be manually generated!");
-}
-
-#endif // VK_USE_PLATFORM_METAL_EXT
-
 // ---- VK_EXT_buffer_device_address extension trampoline/terminators
 
 VKAPI_ATTR VkDeviceAddress VKAPI_CALL GetBufferDeviceAddressEXT(
@@ -3110,6 +3170,17 @@ VKAPI_ATTR VkResult VKAPI_CALL ReleaseFullScreenExclusiveModeEXT(
 
 #endif // VK_USE_PLATFORM_WIN32_KHR
 
+// ---- VK_EXT_line_rasterization extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdSetLineStippleEXT(
+    VkCommandBuffer                             commandBuffer,
+    uint32_t                                    lineStippleFactor,
+    uint16_t                                    lineStipplePattern) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    disp->CmdSetLineStippleEXT(commandBuffer, lineStippleFactor, lineStipplePattern);
+}
+
+
 // ---- VK_EXT_host_query_reset extension trampoline/terminators
 
 VKAPI_ATTR void VKAPI_CALL ResetQueryPoolEXT(
@@ -3406,6 +3477,34 @@ bool extension_instance_gpa(struct loader_instance *ptr_instance, const char *na
         return true;
     }
 
+    // ---- VK_KHR_timeline_semaphore extension commands
+    if (!strcmp("vkGetSemaphoreCounterValueKHR", name)) {
+        *addr = (void *)GetSemaphoreCounterValueKHR;
+        return true;
+    }
+    if (!strcmp("vkWaitSemaphoresKHR", name)) {
+        *addr = (void *)WaitSemaphoresKHR;
+        return true;
+    }
+    if (!strcmp("vkSignalSemaphoreKHR", name)) {
+        *addr = (void *)SignalSemaphoreKHR;
+        return true;
+    }
+
+    // ---- VK_KHR_pipeline_executable_properties extension commands
+    if (!strcmp("vkGetPipelineExecutablePropertiesKHR", name)) {
+        *addr = (void *)GetPipelineExecutablePropertiesKHR;
+        return true;
+    }
+    if (!strcmp("vkGetPipelineExecutableStatisticsKHR", name)) {
+        *addr = (void *)GetPipelineExecutableStatisticsKHR;
+        return true;
+    }
+    if (!strcmp("vkGetPipelineExecutableInternalRepresentationsKHR", name)) {
+        *addr = (void *)GetPipelineExecutableInternalRepresentationsKHR;
+        return true;
+    }
+
     // ---- VK_EXT_debug_marker extension commands
     if (!strcmp("vkDebugMarkerSetObjectTagEXT", name)) {
         *addr = (void *)DebugMarkerSetObjectTagEXT;
@@ -3908,16 +4007,6 @@ bool extension_instance_gpa(struct loader_instance *ptr_instance, const char *na
     }
 #endif // VK_USE_PLATFORM_FUCHSIA
 
-    // ---- VK_EXT_metal_surface extension commands
-#ifdef VK_USE_PLATFORM_METAL_EXT
-    if (!strcmp("vkCreateMetalSurfaceEXT", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.ext_metal_surface == 1)
-                     ? (void *)CreateMetalSurfaceEXT
-                     : NULL;
-        return true;
-    }
-#endif // VK_USE_PLATFORM_METAL_EXT
-
     // ---- VK_EXT_buffer_device_address extension commands
     if (!strcmp("vkGetBufferDeviceAddressEXT", name)) {
         *addr = (void *)GetBufferDeviceAddressEXT;
@@ -3962,6 +4051,12 @@ bool extension_instance_gpa(struct loader_instance *ptr_instance, const char *na
     }
 #endif // VK_USE_PLATFORM_WIN32_KHR
 
+    // ---- VK_EXT_line_rasterization extension commands
+    if (!strcmp("vkCmdSetLineStippleEXT", name)) {
+        *addr = (void *)CmdSetLineStippleEXT;
+        return true;
+    }
+
     // ---- VK_EXT_host_query_reset extension commands
     if (!strcmp("vkResetQueryPoolEXT", name)) {
         *addr = (void *)ResetQueryPoolEXT;
@@ -4037,12 +4132,6 @@ void extensions_create_instance(struct loader_instance *ptr_instance, const VkIn
         } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME)) {
             ptr_instance->enabled_known_extensions.fuchsia_imagepipe_surface = 1;
 #endif // VK_USE_PLATFORM_FUCHSIA
-
-    // ---- VK_EXT_metal_surface extension commands
-#ifdef VK_USE_PLATFORM_METAL_EXT
-        } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_METAL_SURFACE_EXTENSION_NAME)) {
-            ptr_instance->enabled_known_extensions.ext_metal_surface = 1;
-#endif // VK_USE_PLATFORM_METAL_EXT
         }
     }
 }

+ 0 - 1
thirdparty/vulkan/loader/vk_loader_extensions.h

@@ -437,7 +437,6 @@ union loader_instance_extension_enables {
         uint8_t ext_display_surface_counter : 1;
         uint8_t ext_debug_utils : 1;
         uint8_t fuchsia_imagepipe_surface : 1;
-        uint8_t ext_metal_surface : 1;
     };
     uint64_t padding[4];
 };

+ 35 - 4
thirdparty/vulkan/loader/vk_loader_platform.h

@@ -207,7 +207,12 @@ static inline void loader_platform_thread_cond_broadcast(loader_platform_thread_
 static inline const char *LoaderPnpDriverRegistry() {
     BOOL is_wow;
     IsWow64Process(GetCurrentProcess(), &is_wow);
-    return is_wow ? (API_NAME "DriverNameWow") : (API_NAME "DriverName");
+    return is_wow ? "VulkanDriverNameWow" : "VulkanDriverName";
+}
+static inline const wchar_t *LoaderPnpDriverRegistryWide() {
+    BOOL is_wow;
+    IsWow64Process(GetCurrentProcess(), &is_wow);
+    return is_wow ? L"VulkanDriverNameWow" : L"VulkanDriverName";
 }
 
 // Get the key for the plug 'n play explicit layer registry
@@ -215,15 +220,25 @@ static inline const char *LoaderPnpDriverRegistry() {
 static inline const char *LoaderPnpELayerRegistry() {
     BOOL is_wow;
     IsWow64Process(GetCurrentProcess(), &is_wow);
-    return is_wow ? (API_NAME "ExplicitLayersWow") : (API_NAME "ExplicitLayers");
+    return is_wow ? "VulkanExplicitLayersWow" : "VulkanExplicitLayers";
+}
+static inline const wchar_t *LoaderPnpELayerRegistryWide() {
+    BOOL is_wow;
+    IsWow64Process(GetCurrentProcess(), &is_wow);
+    return is_wow ? L"VulkanExplicitLayersWow" : L"VulkanExplicitLayers";
 }
+
 // Get the key for the plug 'n play implicit layer registry
 // The string returned by this function should NOT be freed
-
 static inline const char *LoaderPnpILayerRegistry() {
     BOOL is_wow;
     IsWow64Process(GetCurrentProcess(), &is_wow);
-    return is_wow ? (API_NAME "ImplicitLayersWow") : (API_NAME "ImplicitLayers");
+    return is_wow ? "VulkanImplicitLayersWow" : "VulkanImplicitLayers";
+}
+static inline const wchar_t *LoaderPnpILayerRegistryWide() {
+    BOOL is_wow;
+    IsWow64Process(GetCurrentProcess(), &is_wow);
+    return is_wow ? L"VulkanImplicitLayersWow" : L"VulkanImplicitLayers";
 }
 #endif
 
@@ -319,7 +334,23 @@ static char *loader_platform_get_proc_address_error(const char *name) {
 
 // Threads:
 typedef HANDLE loader_platform_thread;
+
+// __declspec(thread) is not supported by MinGW compiler (ignored with warning or
+//                    cause erorr depending on compiler switches)
+//
+// __thread should be used instead
+//
+// __MINGW32__ defined for both 32 and 64 bit MinGW compilers, so it is enough to
+// detect any (32 or 64) flawor of MinGW compiler.
+//
+// @note __GNUC__ could be used as a more generic way to detect _any_
+//       GCC[-compitible] compiler on Windows, but this fix was tested
+//       only with MinGW, so keep it explicit at the moment.
+#if defined(__MINGW32__)
+#define THREAD_LOCAL_DECL __thread
+#else
 #define THREAD_LOCAL_DECL __declspec(thread)
+#endif
 
 // The once init functionality is not used when building a DLL on Windows. This is because there is no way to clean up the
 // resources allocated by anything allocated by once init. This isn't a problem for static libraries, but it is for dynamic

+ 87 - 4
thirdparty/vulkan/loader/wsi.c

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2015-2016 The Khronos Group Inc.
- * Copyright (c) 2015-2016 Valve Corporation
- * Copyright (c) 2015-2016 LunarG, Inc.
+ * Copyright (c) 2015-2016, 2019 The Khronos Group Inc.
+ * Copyright (c) 2015-2016, 2019 Valve Corporation
+ * Copyright (c) 2015-2016, 2019 LunarG, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
  * Author: Jon Ashburn <[email protected]>
  * Author: Ian Elliott <[email protected]>
  * Author: Mark Lobodzinski <[email protected]>
+ * Author: Lenny Komow <[email protected]>
  */
 
 #ifndef _GNU_SOURCE
@@ -60,9 +61,11 @@ void wsi_create_instance(struct loader_instance *ptr_instance, const VkInstanceC
 #ifdef VK_USE_PLATFORM_IOS_MVK
     ptr_instance->wsi_ios_surface_enabled = false;
 #endif  // VK_USE_PLATFORM_IOS_MVK
-
     ptr_instance->wsi_display_enabled = false;
     ptr_instance->wsi_display_props2_enabled = false;
+#ifdef VK_USE_PLATFORM_METAL_EXT
+    ptr_instance->wsi_metal_surface_enabled = false;
+#endif // VK_USE_PLATFORM_METAL_EXT
 
     for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0) {
@@ -115,6 +118,12 @@ void wsi_create_instance(struct loader_instance *ptr_instance, const VkInstanceC
             ptr_instance->wsi_headless_surface_enabled = true;
             continue;
         }
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_METAL_SURFACE_EXTENSION_NAME) == 0) {
+            ptr_instance->wsi_metal_surface_enabled = true;
+            continue;
+        }
+#endif
         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_EXTENSION_NAME) == 0) {
             ptr_instance->wsi_display_enabled = true;
             continue;
@@ -1169,6 +1178,72 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateIOSSurfaceMVK(VkInstance instanc
 
 #endif  // VK_USE_PLATFORM_IOS_MVK
 
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateMetalSurfaceEXT(VkInstance instance,
+                                                                     const VkMetalSurfaceCreateInfoEXT *pCreateInfo,
+                                                                     const VkAllocationCallbacks *pAllocator,
+                                                                     VkSurfaceKHR *pSurface) {
+    const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(instance);
+    return disp->CreateMetalSurfaceEXT(instance, pCreateInfo, pAllocator, pSurface);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMetalSurfaceEXT(VkInstance instance, const VkMetalSurfaceCreateInfoEXT *pCreateInfo,
+                                                                const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    VkResult result = VK_SUCCESS;
+    VkIcdSurface *icd_surface = NULL;
+    uint32_t i;
+
+    // First, check to ensure the appropriate extension was enabled:
+    struct loader_instance *ptr_instance = loader_get_instance(instance);
+    if (!ptr_instance->wsi_metal_surface_enabled) {
+        loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+                   "VK_EXT_metal_surface extension not enabled. vkCreateMetalSurfaceEXT will not be executed.\n");
+    }
+
+    // Next, if so, proceed with the implementation of this function:
+    icd_surface = AllocateIcdSurfaceStruct(ptr_instance, sizeof(icd_surface->metal_surf.base), sizeof(icd_surface->metal_surf));
+    if (icd_surface == NULL) {
+        result = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto out;
+    }
+
+    icd_surface->metal_surf.base.platform = VK_ICD_WSI_PLATFORM_METAL;
+    icd_surface->metal_surf.pLayer = pCreateInfo->pLayer;
+
+    // Loop through each ICD and determine if they need to create a surface
+    i = 0;
+    for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, ++i) {
+        if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+            if (icd_term->dispatch.CreateMetalSurfaceEXT != NULL) {
+                result = icd_term->dispatch.CreateMetalSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator,
+                                                                  &icd_surface->real_icd_surfaces[i]);
+                if (result != VK_SUCCESS) {
+                    goto out;
+                }
+            }
+        }
+    }
+    *pSurface = (VkSurfaceKHR)icd_surface;
+
+out:
+    if (result != VK_SUCCESS && icd_surface != NULL) {
+        if (icd_surface->real_icd_surfaces != NULL) {
+            i = 0;
+            for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, ++i) {
+                if (icd_surface->real_icd_surfaces[i] == VK_NULL_HANDLE && icd_term->dispatch.DestroySurfaceKHR != NULL) {
+                    icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, icd_surface->real_icd_surfaces[i], pAllocator);
+                }
+            }
+            loader_instance_heap_free(ptr_instance, icd_surface->real_icd_surfaces);
+        }
+        loader_instance_heap_free(ptr_instance, icd_surface);
+    }
+    return result;
+}
+
+#endif
+
 // Functions for the VK_KHR_display instance extension:
 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
                                                                                      uint32_t *pPropertyCount,
@@ -1882,6 +1957,14 @@ bool wsi_swapchain_instance_gpa(struct loader_instance *ptr_instance, const char
         return true;
     }
 
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+    // Functions for the VK_MVK_macos_surface extension:
+    if (!strcmp("vkCreateMetalSurfaceEXT", name)) {
+        *addr = ptr_instance->wsi_metal_surface_enabled ? (void *)vkCreateMetalSurfaceEXT : NULL;
+        return true;
+    }
+#endif // VK_USE_PLATFORM_METAL_EXT
+
     // Functions for VK_KHR_display extension:
     if (!strcmp("vkGetPhysicalDeviceDisplayPropertiesKHR", name)) {
         *addr = ptr_instance->wsi_display_enabled ? (void *)vkGetPhysicalDeviceDisplayPropertiesKHR : NULL;

+ 7 - 0
thirdparty/vulkan/loader/wsi.h

@@ -42,6 +42,9 @@ typedef struct {
 #ifdef VK_USE_PLATFORM_MACOS_MVK
         VkIcdSurfaceMacOS macos_surf;
 #endif  // VK_USE_PLATFORM_MACOS_MVK
+#ifdef VK_USE_PLATFORM_METAL_EXT
+        VkIcdSurfaceMetal metal_surf;
+#endif // VK_USE_PLATFORM_METAL_EXT
         VkIcdSurfaceDisplay display_surf;
         VkIcdSurfaceHeadless headless_surf;
     };
@@ -126,6 +129,10 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMacOSSurfaceMVK(VkInstance insta
 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateIOSSurfaceMVK(VkInstance instance, const VkIOSSurfaceCreateInfoMVK *pCreateInfo,
                                                               const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
 #endif
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMetalSurfaceEXT(VkInstance instance, const VkMetalSurfaceCreateInfoEXT *pCreateInfo,
+                                                                const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
+#endif
 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
                                                                                 uint32_t *pPropertyCount,
                                                                                 VkDisplayPropertiesKHR *pProperties);

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio