Merge remote-tracking branch 'upstream/sdk-1.1.121' into HEAD
Change-Id: I2816e26a12bcf86799b67f1604ef16b61dc0399f
diff --git a/.appveyor.yml b/.appveyor.yml
index b60097d..65999b7 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -55,7 +55,7 @@
- echo Generating CMake files for %PLATFORM%
- mkdir build
- cd build
- - cmake -A %PLATFORM% -C../external/helper.cmake ..
+ - cmake -A %PLATFORM% -C../external/helper.cmake -DWDK_VERSION=10.0.17763.0 ..
- echo Building platform=%PLATFORM% configuration=%CONFIGURATION%
platform:
diff --git a/BUILD.gn b/BUILD.gn
index 7cef22b..4fe391d 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -59,7 +59,7 @@
"loader/generated",
"loader",
]
- defines = [ "API_NAME=\"Vulkan\"" ] + vulkan_loader_extra_defines
+ defines = [ "API_NAME=\"Vulkan\"" ]
if (is_win) {
cflags = [ "/wd4201" ]
diff --git a/BUILD.md b/BUILD.md
index 026298a..5fc7075 100644
--- a/BUILD.md
+++ b/BUILD.md
@@ -391,8 +391,8 @@
### Linux Development Environment Requirements
This repository has been built and tested on the two most recent Ubuntu LTS
-versions. Currently, the oldest supported version is Ubuntu 14.04, meaning
-that the minimum supported compiler versions are GCC 4.8.2 and Clang 3.4,
+versions. Currently, the oldest supported version is Ubuntu 16.04, meaning
+that the minimum officially supported C++11 compiler version is GCC 5.4.0,
although earlier versions may work. It should be straightforward to adapt this
repository to other Linux distributions.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 85bddd6..81532fd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -31,6 +31,7 @@
if (TARGET Vulkan::Headers)
message(STATUS "Using Vulkan headers from Vulkan::Headers target")
+ get_target_property(VulkanHeaders_INCLUDE_DIRS Vulkan::Headers INTERFACE_INCLUDE_DIRECTORIES)
get_target_property(VulkanRegistry_DIR Vulkan::Registry INTERFACE_INCLUDE_DIRECTORIES)
else()
find_package(VulkanHeaders)
diff --git a/build-gn/secondary/build_overrides/vulkan_loader.gni b/build-gn/secondary/build_overrides/vulkan_loader.gni
index 4b248e2..c826fc1 100644
--- a/build-gn/secondary/build_overrides/vulkan_loader.gni
+++ b/build-gn/secondary/build_overrides/vulkan_loader.gni
@@ -19,6 +19,5 @@
vulkan_gen_subdir = ""
# Vulkan loader build options
-vulkan_loader_extra_defines = []
vulkan_loader_shared = true
diff --git a/cmake/FindWDK.cmake b/cmake/FindWDK.cmake
index 1f8c6f1..5868343 100644
--- a/cmake/FindWDK.cmake
+++ b/cmake/FindWDK.cmake
@@ -41,21 +41,33 @@
# WDK_INCLUDE_DIRS - include directories for the WDK
#
-if(NOT DEFINED WDK_FULL_PATH)
- if(NOT DEFINED WDK_BASE)
+if(DEFINED WDK_FULL_PATH)
+ find_path(WDK_VERSION_INCLUDE_DIR
+ NAMES km/d3dkmthk.h shared/d3dkmdt.h
+ PATHS "${WDK_FULL_PATH}"
+ )
+else()
+ if(NOT DEFINED WDK_BASE AND DEFINED "$ENV{UniversalCRTSdkDir}")
set(WDK_BASE "$ENV{UniversalCRTSdkDir}")
+ elseif(NOT DEFINED WDK_BASE)
+ set(WDK_BASE "C:/Program Files (x86)/Windows Kits/10/")
endif()
- if(NOT DEFINED WDK_VERSION)
- set(WDK_VERSION "$ENV{UCRTVersion}")
- string(REPLACE \\ "" WDK_VERSION "${WDK_VERSION}")
- endif()
- set(WDK_FULL_PATH "${WDK_BASE}/Include/${WDK_VERSION}")
-endif()
-find_path(WDK_VERSION_INCLUDE_DIR
- NAMES km/d3dkmthk.h shared/d3dkmdt.h
- PATHS "${WDK_FULL_PATH}"
-)
+ if(DEFINED WDK_VERSION)
+ set(SUBDIRS "Include/${WDK_VERSION}")
+ else()
+ file(GLOB DIR_LIST RELATIVE "C:/Program Files (x86)/Windows Kits/10/" "C:/Program Files (x86)/Windows Kits/10/Include/*")
+ list(REVERSE DIR_LIST)
+ foreach(DIR IN ITEMS "${DIR_LIST}")
+ set(SUBDIRS "${SUBDIRS}" "${DIR}")
+ endforeach()
+ endif()
+ find_path(WDK_VERSION_INCLUDE_DIR
+ NAMES km/d3dkmthk.h shared/d3dkmdt.h
+ PATHS "${WDK_BASE}"
+ PATH_SUFFIXES ${SUBDIRS}
+ )
+endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(WDK DEFAULT_MSG WDK_VERSION_INCLUDE_DIR)
diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt
index a9401db..f357100 100644
--- a/loader/CMakeLists.txt
+++ b/loader/CMakeLists.txt
@@ -19,6 +19,8 @@
# Check for the existance of the secure_getenv or __secure_getenv commands
include(CheckFunctionExists)
+include(CheckIncludeFile)
+
check_function_exists(secure_getenv HAVE_SECURE_GETENV)
check_function_exists(__secure_getenv HAVE___SECURE_GETENV)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/loader_cmake_config.h.in ${CMAKE_CURRENT_BINARY_DIR}/loader_cmake_config.h)
@@ -146,25 +148,23 @@
set_source_files_properties(${OPT_LOADER_SRCS} PROPERTIES COMPILE_FLAGS -O)
add_custom_target(loader_asm_gen_files) # This causes no assembly files to be generated.
else(UNIX AND NOT APPLE) # i.e.: Linux
- enable_language(ASM-ATT)
- set(CMAKE_ASM-ATT_COMPILE_FLAGS "${CMAKE_ASM-ATT_COMPILE_FLAGS} $ENV{ASFLAGS}")
- set(CMAKE_ASM-ATT_COMPILE_FLAGS "${CMAKE_ASM-ATT_COMPILE_FLAGS} -I\"${CMAKE_CURRENT_BINARY_DIR}\"")
+ enable_language(ASM)
+ set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS}")
- file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/asm_test.asm
+ check_include_file("cet.h" HAVE_CET_H)
+ if(HAVE_CET_H)
+ add_definitions(-DHAVE_CET_H)
+ endif()
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/asm_test.S
".intel_syntax noprefix\n.text\n.global sample\nsample:\nmov ecx, [eax + 16]\n")
- # try_compile uses the C/C++ linker flags even for ASM,
- # while they're not valid for ASM and making linking fail.
- set(TMP_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS})
- set(CMAKE_EXE_LINKER_FLAGS "")
- try_compile(ASSEMBLER_WORKS ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/asm_test.asm)
- set(CMAKE_EXE_LINKER_FLAGS ${TMP_EXE_LINKER_FLAGS})
- file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/asm_test.asm)
+ set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+ try_compile(ASSEMBLER_WORKS ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/asm_test.S)
+ file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/asm_test.S)
if(ASSEMBLER_WORKS)
- set(CMAKE_ASM-ATT_FLAGS "$ENV{ASFLAGS} -I\"${CMAKE_CURRENT_BINARY_DIR}\"")
- set(OPT_LOADER_SRCS ${OPT_LOADER_SRCS} unknown_ext_chain_gas.asm)
+ set(OPT_LOADER_SRCS ${OPT_LOADER_SRCS} unknown_ext_chain_gas.S)
add_executable(asm_offset asm_offset.c)
target_link_libraries(asm_offset Vulkan::Headers)
- add_custom_command(OUTPUT gen_defines.asm DEPENDS asm_offset COMMAND asm_offset GAS)
+ add_custom_command(OUTPUT gen_defines.asm DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/asm_offset COMMAND ${CMAKE_CURRENT_BINARY_DIR}/asm_offset GAS)
add_custom_target(loader_asm_gen_files DEPENDS gen_defines.asm)
else()
message(WARNING "Could not find working x86 GAS assembler\n${ASM_FAILURE_MSG}")
@@ -174,7 +174,7 @@
endif()
if(WIN32)
- add_library(loader-norm OBJECT ${NORMAL_LOADER_SRCS} dirent_on_windows.c)
+ add_library(loader-norm OBJECT ${NORMAL_LOADER_SRCS} dirent_on_windows.c dxgi_loader.c)
target_compile_options(loader-norm PUBLIC "$<$<CONFIG:DEBUG>:${LOCAL_C_FLAGS_DBG}>")
target_compile_options(loader-norm PUBLIC ${MSVC_LOADER_COMPILE_OPTIONS})
target_include_directories(loader-norm PRIVATE "$<TARGET_PROPERTY:Vulkan::Headers,INTERFACE_INCLUDE_DIRECTORIES>")
diff --git a/loader/LoaderAndLayerInterface.md b/loader/LoaderAndLayerInterface.md
index d176dc6..b5828d0 100644
--- a/loader/LoaderAndLayerInterface.md
+++ b/loader/LoaderAndLayerInterface.md
@@ -46,7 +46,7 @@
* [Vulkan Installable Client Driver interface with the loader](#vulkan-installable-client-driver-interface-with-the-loader)
* [ICD Discovery](#icd-discovery)
* [ICD Manifest File Format](#icd-manifest-file-format)
- * [ICD Vulkan Entry Point Discovery](#icd-vulkan-entry point-discovery)
+ * [ICD Vulkan Entry Point Discovery](#icd-vulkan-entry-point-discovery)
* [ICD API Version](#icd-api-version)
* [ICD Unknown Physical Device Extensions](#icd-unknown-physical-device-extensions)
* [ICD Dispatchable Object Creation](#icd-dispatchable-object-creation)
diff --git a/loader/dxgi_loader.c b/loader/dxgi_loader.c
new file mode 100644
index 0000000..c2a3fa5
--- /dev/null
+++ b/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/loader/dxgi_loader.h b/loader/dxgi_loader.h
new file mode 100644
index 0000000..00daf08
--- /dev/null
+++ b/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/loader/generated/vk_dispatch_table_helper.h b/loader/generated/vk_dispatch_table_helper.h
index ebd5a7b..299cb77 100644
--- a/loader/generated/vk_dispatch_table_helper.h
+++ b/loader/generated/vk_dispatch_table_helper.h
@@ -86,6 +86,9 @@
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 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 +182,7 @@
#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) { };
#ifdef VK_USE_PLATFORM_FUCHSIA
static VKAPI_ATTR VkResult VKAPI_CALL StubCreateBufferCollectionFUCHSIA(VkDevice device, const VkBufferCollectionCreateInfoFUCHSIA* pImportInfo, const VkAllocationCallbacks* pAllocator, VkBufferCollectionFUCHSIA* pCollection) { return VK_SUCCESS; };
@@ -452,6 +456,12 @@
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->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");
@@ -634,6 +644,8 @@
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; }
#ifdef VK_USE_PLATFORM_FUCHSIA
diff --git a/loader/generated/vk_layer_dispatch_table.h b/loader/generated/vk_layer_dispatch_table.h
index 54c8658..c45b0e0 100644
--- a/loader/generated/vk_layer_dispatch_table.h
+++ b/loader/generated/vk_layer_dispatch_table.h
@@ -470,6 +470,11 @@
PFN_vkCmdDrawIndirectCountKHR CmdDrawIndirectCountKHR;
PFN_vkCmdDrawIndexedIndirectCountKHR CmdDrawIndexedIndirectCountKHR;
+ // ---- 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 +636,9 @@
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;
diff --git a/loader/generated/vk_loader_extensions.c b/loader/generated/vk_loader_extensions.c
index 08006c9..1fbd17e 100644
--- a/loader/generated/vk_loader_extensions.c
+++ b/loader/generated/vk_loader_extensions.c
@@ -527,6 +527,11 @@
table->CmdDrawIndirectCountKHR = (PFN_vkCmdDrawIndirectCountKHR)gdpa(dev, "vkCmdDrawIndirectCountKHR");
table->CmdDrawIndexedIndirectCountKHR = (PFN_vkCmdDrawIndexedIndirectCountKHR)gdpa(dev, "vkCmdDrawIndexedIndirectCountKHR");
+ // ---- 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 +693,9 @@
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");
@@ -1171,6 +1179,11 @@
if (!strcmp(name, "CmdDrawIndirectCountKHR")) return (void *)table->CmdDrawIndirectCountKHR;
if (!strcmp(name, "CmdDrawIndexedIndirectCountKHR")) return (void *)table->CmdDrawIndexedIndirectCountKHR;
+ // ---- 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;
@@ -1332,6 +1345,9 @@
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;
@@ -1951,6 +1967,36 @@
}
+// ---- 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(
@@ -3154,6 +3200,17 @@
#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(
@@ -3550,6 +3607,20 @@
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;
@@ -4096,6 +4167,12 @@
}
#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;
diff --git a/loader/loader.c b/loader/loader.c
index d19fb4d..57d43b3 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -66,11 +66,12 @@
#include "murmurhash.h"
#if defined(_WIN32)
-#include <Cfgmgr32.h>
+#include <cfgmgr32.h>
#include <initguid.h>
-#include <Devpkey.h>
+#include <devpkey.h>
#include <winternl.h>
#include <d3dkmthk.h>
+#include "dxgi_loader.h"
typedef _Check_return_ NTSTATUS (APIENTRY *PFN_D3DKMTEnumAdapters2)(const D3DKMT_ENUMADAPTERS2*);
typedef _Check_return_ NTSTATUS (APIENTRY *PFN_D3DKMTQueryAdapterInfo)(const D3DKMT_QUERYADAPTERINFO*);
@@ -242,6 +243,10 @@
// Environment variables
#if defined(__linux__) || defined(__APPLE__) || defined(__Fuchsia__)
+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.
@@ -258,7 +263,7 @@
// 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);
#elif defined(__Fuchsia__)
return loader_getenv(name, inst);
#else
@@ -287,6 +292,28 @@
#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;
@@ -313,7 +340,10 @@
}
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);
}
@@ -781,6 +811,49 @@
// 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;
@@ -793,12 +866,25 @@
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;
@@ -833,9 +919,59 @@
*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,
+ "Dropping driver %s as it was not recognized as a known driver", name);
+ continue;
+ }
+
+ 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);
@@ -888,6 +1024,9 @@
}
out:
+ if (is_driver && dxgi_factory != NULL) {
+ dxgi_factory->lpVtbl->Release(dxgi_factory);
+ }
return result;
}
@@ -3706,8 +3845,10 @@
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
}
@@ -3951,7 +4092,6 @@
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.
@@ -3976,6 +4116,7 @@
}
// 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, ®_size);
if ((VK_SUCCESS != reg_result && VK_SUCCESS != regHKR_result) || NULL == search_path) {
@@ -6144,16 +6285,18 @@
// 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);
+ }
}
}
@@ -7105,7 +7248,7 @@
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/loader/unknown_ext_chain_gas.asm b/loader/unknown_ext_chain_gas.S
similarity index 98%
rename from loader/unknown_ext_chain_gas.asm
rename to loader/unknown_ext_chain_gas.S
index aca92ea..f847e14 100644
--- a/loader/unknown_ext_chain_gas.asm
+++ b/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 @@
.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 @@
.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 @@
.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 @@
.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 @@
.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/loader/vk_loader_platform.h b/loader/vk_loader_platform.h
index 7ab99f5..c76fd7e 100644
--- a/loader/vk_loader_platform.h
+++ b/loader/vk_loader_platform.h
@@ -25,7 +25,7 @@
#if defined(_WIN32)
// WinSock2.h must be included *BEFORE* windows.h
-#include <WinSock2.h>
+#include <winsock2.h>
#endif // _WIN32
#if defined(__Fuchsia__)
diff --git a/scripts/known_good.json b/scripts/known_good.json
index 64d3840..28e94ea 100644
--- a/scripts/known_good.json
+++ b/scripts/known_good.json
@@ -6,7 +6,7 @@
"sub_dir" : "Vulkan-Headers",
"build_dir" : "Vulkan-Headers/build",
"install_dir" : "Vulkan-Headers/build/install",
- "commit" : "v1.1.115"
+ "commit" : "v1.1.121"
}
],
"install_names" : {