summaryrefslogtreecommitdiff
path: root/thirdparty/vulkan/loader
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/vulkan/loader')
-rw-r--r--thirdparty/vulkan/loader/adapters.h80
-rw-r--r--thirdparty/vulkan/loader/dxgi_loader.c23
-rw-r--r--thirdparty/vulkan/loader/dxgi_loader.h8
-rw-r--r--thirdparty/vulkan/loader/extension_manual.c11
-rw-r--r--thirdparty/vulkan/loader/loader.c376
-rw-r--r--thirdparty/vulkan/loader/loader.h3
-rw-r--r--thirdparty/vulkan/loader/unknown_ext_chain_gas.S (renamed from thirdparty/vulkan/loader/unknown_ext_chain_gas.asm)12
-rw-r--r--thirdparty/vulkan/loader/vk_dispatch_table_helper.h21
-rw-r--r--thirdparty/vulkan/loader/vk_layer_dispatch_table.h13
-rw-r--r--thirdparty/vulkan/loader/vk_loader_extensions.c165
-rw-r--r--thirdparty/vulkan/loader/vk_loader_extensions.h1
-rw-r--r--thirdparty/vulkan/loader/vk_loader_platform.h39
-rw-r--r--thirdparty/vulkan/loader/wsi.c91
-rw-r--r--thirdparty/vulkan/loader/wsi.h7
14 files changed, 764 insertions, 86 deletions
diff --git a/thirdparty/vulkan/loader/adapters.h b/thirdparty/vulkan/loader/adapters.h
new file mode 100644
index 0000000000..ef97d66573
--- /dev/null
+++ b/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 <lenny@lunarg.com>
+*/
+
+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;
diff --git a/thirdparty/vulkan/loader/dxgi_loader.c b/thirdparty/vulkan/loader/dxgi_loader.c
new file mode 100644
index 0000000000..c2a3fa5638
--- /dev/null
+++ b/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;
+} \ No newline at end of file
diff --git a/thirdparty/vulkan/loader/dxgi_loader.h b/thirdparty/vulkan/loader/dxgi_loader.h
new file mode 100644
index 0000000000..00daf08ed2
--- /dev/null
+++ b/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 \ No newline at end of file
diff --git a/thirdparty/vulkan/loader/extension_manual.c b/thirdparty/vulkan/loader/extension_manual.c
index 640db2f789..490496d7c7 100644
--- a/thirdparty/vulkan/loader/extension_manual.c
+++ b/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;
diff --git a/thirdparty/vulkan/loader/loader.c b/thirdparty/vulkan/loader/loader.c
index 5e4de5e749..398c44bf9c 100644
--- a/thirdparty/vulkan/loader/loader.c
+++ b/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;
}
diff --git a/thirdparty/vulkan/loader/loader.h b/thirdparty/vulkan/loader/loader.h
index 36f04144bf..8d6b4c454a 100644
--- a/thirdparty/vulkan/loader/loader.h
+++ b/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;
};
diff --git a/thirdparty/vulkan/loader/unknown_ext_chain_gas.asm b/thirdparty/vulkan/loader/unknown_ext_chain_gas.S
index aca92ea5b8..f847e1407d 100644
--- a/thirdparty/vulkan/loader/unknown_ext_chain_gas.asm
+++ b/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
diff --git a/thirdparty/vulkan/loader/vk_dispatch_table_helper.h b/thirdparty/vulkan/loader/vk_dispatch_table_helper.h
index 42e2a0756a..d934798db4 100644
--- a/thirdparty/vulkan/loader/vk_dispatch_table_helper.h
+++ b/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; }
}
diff --git a/thirdparty/vulkan/loader/vk_layer_dispatch_table.h b/thirdparty/vulkan/loader/vk_layer_dispatch_table.h
index 0759f48825..1f0342dc49 100644
--- a/thirdparty/vulkan/loader/vk_layer_dispatch_table.h
+++ b/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;
diff --git a/thirdparty/vulkan/loader/vk_loader_extensions.c b/thirdparty/vulkan/loader/vk_loader_extensions.c
index 80d80e6be6..c7a55cf11a 100644
--- a/thirdparty/vulkan/loader/vk_loader_extensions.c
+++ b/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
}
}
}
diff --git a/thirdparty/vulkan/loader/vk_loader_extensions.h b/thirdparty/vulkan/loader/vk_loader_extensions.h
index 954e77448d..b08af33838 100644
--- a/thirdparty/vulkan/loader/vk_loader_extensions.h
+++ b/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];
};
diff --git a/thirdparty/vulkan/loader/vk_loader_platform.h b/thirdparty/vulkan/loader/vk_loader_platform.h
index e405c21088..2ffda55367 100644
--- a/thirdparty/vulkan/loader/vk_loader_platform.h
+++ b/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
diff --git a/thirdparty/vulkan/loader/wsi.c b/thirdparty/vulkan/loader/wsi.c
index e9f573f072..f8d8e5374c 100644
--- a/thirdparty/vulkan/loader/wsi.c
+++ b/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 <jon@lunarg.com>
* Author: Ian Elliott <ianelliott@google.com>
* Author: Mark Lobodzinski <mark@lunarg.com>
+ * Author: Lenny Komow <lenny@lunarg.com>
*/
#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;
diff --git a/thirdparty/vulkan/loader/wsi.h b/thirdparty/vulkan/loader/wsi.h
index b09f168fda..3e44efa9e9 100644
--- a/thirdparty/vulkan/loader/wsi.h
+++ b/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);