Hello community,

here is the log from the commit of package vulkan-loader for openSUSE:Factory 
checked in at 2020-09-05 23:57:09
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/vulkan-loader (Old)
 and      /work/SRC/openSUSE:Factory/.vulkan-loader.new.3399 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "vulkan-loader"

Sat Sep  5 23:57:09 2020 rev:26 rq:831292 version:1.2.151

Changes:
--------
--- /work/SRC/openSUSE:Factory/vulkan-loader/vulkan-loader.changes      
2020-08-12 10:55:57.784727401 +0200
+++ /work/SRC/openSUSE:Factory/.vulkan-loader.new.3399/vulkan-loader.changes    
2020-09-05 23:57:17.459100263 +0200
@@ -1,0 +2,6 @@
+Wed Aug 19 07:30:26 UTC 2020 - Jan Engelhardt <[email protected]>
+
+- Update to release 1.2.151
+  * Fixed crash in device enumeration
+
+-------------------------------------------------------------------

Old:
----
  v1.2.148.tar.gz

New:
----
  v1.2.151.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ vulkan-loader.spec ++++++
--- /var/tmp/diff_new_pack.sbNyu8/_old  2020-09-05 23:57:20.331101702 +0200
+++ /var/tmp/diff_new_pack.sbNyu8/_new  2020-09-05 23:57:20.335101704 +0200
@@ -18,7 +18,7 @@
 
 %define lname  libvulkan1
 Name:           vulkan-loader
-Version:        1.2.148
+Version:        1.2.151
 Release:        0
 Summary:        Reference ICD loader for Vulkan
 License:        Apache-2.0

++++++ v1.2.148.tar.gz -> v1.2.151.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Vulkan-Loader-1.2.148/.appveyor.yml 
new/Vulkan-Loader-1.2.151/.appveyor.yml
--- old/Vulkan-Loader-1.2.148/.appveyor.yml     2020-07-20 20:36:53.000000000 
+0200
+++ new/Vulkan-Loader-1.2.151/.appveyor.yml     2020-08-17 19:41:19.000000000 
+0200
@@ -12,7 +12,7 @@
 max_jobs: 4
 
 os:
-  - Visual Studio 2015
+  - Visual Studio 2017
 
 environment:
   PYTHON_PATH: "C:/Python35"
@@ -47,7 +47,7 @@
   - echo Generating CMake files for %PLATFORM%
   - mkdir build
   - cd build
-  - cmake -A %PLATFORM% -C../external/helper.cmake ..
+  - cmake -A %PLATFORM% -DCMAKE_SYSTEM_VERSION=10.0.18362 
-C../external/helper.cmake ..
   - echo Building platform=%PLATFORM% configuration=%CONFIGURATION%
 
 platform:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Vulkan-Loader-1.2.148/README.md 
new/Vulkan-Loader-1.2.151/README.md
--- old/Vulkan-Loader-1.2.148/README.md 2020-07-20 20:36:53.000000000 +0200
+++ new/Vulkan-Loader-1.2.151/README.md 2020-08-17 19:41:19.000000000 +0200
@@ -58,8 +58,6 @@
 This work is released as open source under a Apache-style license from Khronos
 including a Khronos copyright.
 
-See COPYRIGHT.txt for a full list of licenses used in this repository.
-
 ## Acknowledgements
 
 While this project has been developed primarily by LunarG, Inc., there are 
many other
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Vulkan-Loader-1.2.148/loader/CMakeLists.txt 
new/Vulkan-Loader-1.2.151/loader/CMakeLists.txt
--- old/Vulkan-Loader-1.2.148/loader/CMakeLists.txt     2020-07-20 
20:36:53.000000000 +0200
+++ new/Vulkan-Loader-1.2.151/loader/CMakeLists.txt     2020-08-17 
19:41:19.000000000 +0200
@@ -183,7 +183,7 @@
 endif()
 
 if(WIN32)
-    add_library(loader-norm OBJECT ${NORMAL_LOADER_SRCS} dirent_on_windows.c 
dxgi_loader.c)
+    add_library(loader-norm OBJECT ${NORMAL_LOADER_SRCS} dirent_on_windows.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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Vulkan-Loader-1.2.148/loader/LoaderAndLayerInterface.md 
new/Vulkan-Loader-1.2.151/loader/LoaderAndLayerInterface.md
--- old/Vulkan-Loader-1.2.148/loader/LoaderAndLayerInterface.md 2020-07-20 
20:36:53.000000000 +0200
+++ new/Vulkan-Loader-1.2.151/loader/LoaderAndLayerInterface.md 2020-08-17 
19:41:19.000000000 +0200
@@ -49,13 +49,14 @@
     * [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)
+    * [Physical Device Sorting](#physical-device-sorting)
     * [ICD Dispatchable Object Creation](#icd-dispatchable-object-creation)
     * [Handling KHR Surface Objects in WSI 
Extensions](#handling-khr-surface-objects-in-wsi-extensions)
     * [Loader and ICD Interface 
Negotiation](#loader-and-icd-interface-negotiation)
 
   * [Table of Debug Environment 
Variables](#table-of-debug-environment-variables)
   * [Glossary of Terms](#glossary-of-terms)
- 
+
 ## Overview
 
 Vulkan is a layered architecture, made up of the following elements:
@@ -191,7 +192,7 @@
  * `vkBeginCommandBuffer`
  * `vkCreateEvent`
 
-You can query Vulkan Device functions using either `vkGetInstanceProcAddr` or 
+You can query Vulkan Device functions using either `vkGetInstanceProcAddr` or
 `vkGetDeviceProcAddr`.  If you choose to use `vkGetInstanceProcAddr`, it will
 have an additional level built into the call chain, which will reduce
 performance slightly.  However, the function pointer returned can be used for
@@ -268,7 +269,7 @@
 
 Device call chains are created at `vkCreateDevice` and are generally simpler
 because they deal with only a single device and the ICD can always be the
-*terminator* of the chain. 
+*terminator* of the chain.
 
 ![Loader Device Call Chain](./images/loader_device_chain_loader.png)
 
@@ -298,7 +299,7 @@
     * [WSI Extensions](#wsi-extensions)
     * [Unknown Extensions](#unknown-extensions)
 
-  
+
 #### Interfacing with Vulkan Functions
 There are several ways you can interface with Vulkan functions through the
 loader.
@@ -369,7 +370,7 @@
 
 The answer comes in how the call chain of Instance functions are implemented
 versus the call chain of a Device functions.  Remember, a [Vulkan Instance is a
-high-level construct used to provide Vulkan system-level 
+high-level construct used to provide Vulkan system-level
 information](#instance-related-objects).
 Because of this, Instance functions need to be broadcast to
 every available ICD on the system.  The following diagram shows an approximate
@@ -692,7 +693,7 @@
 - VK_KHR_swapchain
 - VK_KHR_display
 
-In addition, each of the following OS targets for the loader support 
+In addition, each of the following OS targets for the loader support
 target-specific extensions:
 
 | Windowing System | Extensions available |
@@ -798,9 +799,9 @@
     * [Layer Library API Version 2](#layer-library-api-version-2)
     * [Layer Library API Version 1](#layer-library-api-version-1)
     * [Layer Library API Version 0](#layer-library-api-version-0)
-  
 
- 
+
+
 #### Layer Discovery
 
 As mentioned in the
@@ -1381,7 +1382,7 @@
      pfnNextGetInstanceProcAddr(NULL, "vkCreateInstance").
   - For CreateDevice get the next entity's `vkCreateDevice` by calling the
 "pfnNextGetInstanceProcAddr":
-     pfnNextGetInstanceProcAddr(NULL, "vkCreateDevice").
+     pfnNextGetInstanceProcAddr(instance, "vkCreateDevice"), passing the 
already created instance handle.
   - Advanced the linked list to the next node: pLayerInfo = pLayerInfo->pNext.
   - Call down the chain either `vkCreateDevice` or `vkCreateInstance`
   - Initialize your layer dispatch table by calling the next entity's
@@ -1432,13 +1433,14 @@
 #### Example Code for CreateDevice
 
 ```cpp
-VkResult 
+VkResult
 vkCreateDevice(
         VkPhysicalDevice gpu,
         const VkDeviceCreateInfo *pCreateInfo,
         const VkAllocationCallbacks *pAllocator,
         VkDevice *pDevice)
 {
+    VkInstance instance = GetInstanceFromPhysicalDevice(gpu);
     VkLayerDeviceCreateInfo *chain_info =
         get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
 
@@ -1447,7 +1449,7 @@
     PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr =
         chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
     PFN_vkCreateDevice fpCreateDevice =
-        (PFN_vkCreateDevice)fpGetInstanceProcAddr(NULL, "vkCreateDevice");
+        (PFN_vkCreateDevice)fpGetInstanceProcAddr(instance, "vkCreateDevice");
     if (fpCreateDevice == NULL) {
         return VK_ERROR_INITIALIZATION_FAILED;
     }
@@ -1471,6 +1473,8 @@
     return VK_SUCCESS;
 }
 ```
+In this case the function `GetInstanceFromPhysicalDevice` is called to get the 
instance handle.
+In practice, this would be done by any method a layer chooses to get an 
instance handle from the physical device.
 
 
 #### Meta-layers
@@ -1489,7 +1493,7 @@
  4. The loader will automatically collate all instance and device extensions in
 a meta-layer's component layers, and report them as the meta-layer's properties
 to the application when queried.
- 
+
 Restrictions to defining and using a meta-layer are:
  1. A Meta-layer Manifest file **must** be a properly formatted that contains 
one
 or more component layers.
@@ -1497,7 +1501,7 @@
 be used.
  4. All component layers **must be** at the same Vulkan API major and minor
 version for the meta-layer to be used.
- 
+
 The ordering of a meta-layer's component layers in the instance or device
 call-chain is simple:
   * The first layer listed will be the layer closest to the application.
@@ -1606,7 +1610,7 @@
 ##### Associating Private Data with Vulkan Objects Within a Layer
 
 A layer may want to associate its own private data with one or more Vulkan
-objects.  Two common methods to do this are hash maps and object wrapping. 
+objects.  Two common methods to do this are hash maps and object wrapping.
 
 
 ###### Wrapping
@@ -2310,7 +2314,7 @@
  * "library\_path"
  * "api\_version"
 
- 
+
 ###  ICD Vulkan Entry Point Discovery
 
 The Vulkan symbols exported by an ICD must not clash with the loader's exported
@@ -2327,11 +2331,11 @@
 ```
 
 This function has very similar semantics to `vkGetInstanceProcAddr`.
-`vk_icdGetInstanceProcAddr` returns valid function pointers for all the 
+`vk_icdGetInstanceProcAddr` returns valid function pointers for all the
 global-level and instance-level Vulkan functions, and also for 
`vkGetDeviceProcAddr`.
 Global-level functions are those which contain no dispatchable object as the
 first parameter, such as `vkCreateInstance` and
-`vkEnumerateInstanceExtensionProperties`. The ICD must support querying 
+`vkEnumerateInstanceExtensionProperties`. The ICD must support querying
 global-level entry points by calling `vk_icdGetInstanceProcAddr` with a NULL
 `VkInstance` parameter. Instance-level functions are those that have either
 `VkInstance`, or `VkPhysicalDevice` as the first parameter dispatchable object.
@@ -2345,7 +2349,7 @@
 All other Vulkan entry points must either:
  * NOT be exported directly from the ICD library
  * or NOT use the official Vulkan function names if they are exported
- 
+
 This requirement is for ICD libraries that include other
 functionality (such as OpenGL) and thus could be loaded by the
 application prior to when the Vulkan loader library is loaded by the
@@ -2471,6 +2475,35 @@
 attempting to use the commands.
 
 
+### Physical Device Sorting
+
+When an application selects a GPU to use, it must enumerate physical devices 
or physical device groups.
+These API functions do not specify which order the physical devices or 
physical device groups will be presented in.
+On Windows, the loader will attempt to sort these objects so that the system 
preference will be listed first.
+This mechanism does not force an application to use any particular GPU &mdash; 
it merely changes the order in which they are presented.
+
+This mechanism requires that an ICD implement version 6 of the loader/ICD 
interface.
+Version 6 of this interface defines a new method that the ICD may provide on 
Windows:
+
+```c
+VKAPI_ATTR VkResult VKAPI_CALL 
vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID, 
uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices);
+```
+
+This function takes an adapter LUID as input, and enumerates all Vulkan 
physical devices that are associated with that LUID.
+This works in the same way as other Vulkan enumerations &mdash; if 
`pPhysicalDevices` is `NULL`, then the count will be provided.
+Otherwise, the physical devices associated with the queried adapter will be 
provided.
+The function must provide multiple physical devices when the LUID referes to a 
linked adapter.
+This allows the loader to translate the adapter into Vulkan physical device 
groups.
+
+While the loader attempts to match the system's preference for GPU ordering, 
there are some limitations.
+Because this feature requires a new ICD interface, only physical devices from 
ICDs that support this function will be sorted.
+All unsorted physical devices will be listed at the end of the list, in an 
indeterminate order.
+Furthermore, only physical devices that correspond to an adapter may be sorted.
+This means that a software implementation would likely not be sorted.
+Finally, this API only applies to Windows systems and will only work on 
versions of Windows 10 that support GPU selection through the OS.
+Other platforms may be included in the future, but they will require separate 
platform-specific interfaces.
+
+
 ### ICD Dispatchable Object Creation
 
 As previously covered, the loader requires dispatch tables to be accessible
@@ -2486,7 +2519,7 @@
    pointer.
    * **NOTE:** For any C\++ ICD's that implement VK objects directly as C\++
 classes:
-     * The C\++ compiler may put a vtable at offset zero if your class is 
+     * The C\++ compiler may put a vtable at offset zero if your class is
 non-POD due to the use of a virtual function.
      * In this case use a regular C structure (see below).
   3. The loader checks for a magic value (ICD\_LOADER\_MAGIC) in all the 
created
@@ -2511,7 +2544,7 @@
     return newObj;
 }
 ```
- 
+
 
 ### Handling KHR Surface Objects in WSI Extensions
 
@@ -2639,6 +2672,11 @@
 `vk_icdGetInstanceProcAddr` first, it supports at least version 1.  Otherwise,
 the loader only supports version 0.
 
+##### Loader Version 6 Interface Requirements
+
+Version 6 provides a mechanism to allow the loader to sort physical devices.
+The loader will only attempt to sort physical devices on an ICD if version 6 
of the interface is supported.
+This version provides the `vk_icdEnumerateAdapterPhysicalDevices` function 
defined earlier in this document.
 
 ##### Loader Version 5 Interface Requirements
 
@@ -2763,7 +2801,7 @@
 | VK_LAYER_PATH                     | Override the loader's standard Layer 
library search folders and use the provided delimited folders to search for 
layer Manifest files. | `export VK_LAYER_PATH=<path_a>:<path_b>`<br/><br/>`set 
VK_LAYER_PATH=<path_a>;<path_b>` |
 | VK_LOADER_DISABLE_INST_EXT_FILTER | Disable the filtering out of instance 
extensions that the loader doesn't know about.  This will allow applications to 
enable instance extensions exposed by ICDs but that the loader has no support 
for.  **NOTE:** This may cause the loader or application to crash. |  `export 
VK_LOADER_DISABLE_INST_EXT_FILTER=1`<br/><br/>`set 
VK_LOADER_DISABLE_INST_EXT_FILTER=1` |
 | VK_LOADER_DEBUG                   | Enable loader debug messages.  Options 
are:<br/>- error (only errors)<br/>- warn (warnings and errors)<br/>- info 
(info, warning, and errors)<br/> - debug (debug + all before) <br/> -all 
(report out all messages) | `export VK_LOADER_DEBUG=all`<br/><br/>`set 
VK_LOADER_DEBUG=warn` |
- 
+
 ## Glossary of Terms
 
 | Field Name | Field Value |
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Vulkan-Loader-1.2.148/loader/dxgi_loader.c 
new/Vulkan-Loader-1.2.151/loader/dxgi_loader.c
--- old/Vulkan-Loader-1.2.148/loader/dxgi_loader.c      2020-07-20 
20:36:53.000000000 +0200
+++ new/Vulkan-Loader-1.2.151/loader/dxgi_loader.c      1970-01-01 
01:00:00.000000000 +0100
@@ -1,23 +0,0 @@
-#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;
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Vulkan-Loader-1.2.148/loader/dxgi_loader.h 
new/Vulkan-Loader-1.2.151/loader/dxgi_loader.h
--- old/Vulkan-Loader-1.2.148/loader/dxgi_loader.h      2020-07-20 
20:36:53.000000000 +0200
+++ new/Vulkan-Loader-1.2.151/loader/dxgi_loader.h      1970-01-01 
01:00:00.000000000 +0100
@@ -1,8 +0,0 @@
-#ifndef DXGI_LOADER_H
-#define DXGI_LOADER_H
-
-#include <dxgi1_2.h>
-
-HRESULT dyn_CreateDXGIFactory1(REFIID riid, void **ppFactory);
-
-#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Vulkan-Loader-1.2.148/loader/loader.c 
new/Vulkan-Loader-1.2.151/loader/loader.c
--- old/Vulkan-Loader-1.2.148/loader/loader.c   2020-07-20 20:36:53.000000000 
+0200
+++ new/Vulkan-Loader-1.2.151/loader/loader.c   2020-08-17 19:41:19.000000000 
+0200
@@ -70,8 +70,12 @@
 #include <initguid.h>
 #include <devpkey.h>
 #include <winternl.h>
+#include <strsafe.h>
+#include <dxgi1_6.h>
 #include "adapters.h"
-#include "dxgi_loader.h"
+
+typedef HRESULT (APIENTRY *PFN_CreateDXGIFactory1)(REFIID riid, void 
**ppFactory);
+static PFN_CreateDXGIFactory1 fpCreateDXGIFactory1;
 #endif
 
 // This is a CMake generated file with #defines for any functions/includes
@@ -884,7 +888,7 @@
     }
 
     if (is_driver) {
-        HRESULT hres = dyn_CreateDXGIFactory1(&IID_IDXGIFactory1, 
&dxgi_factory);
+        HRESULT hres = fpCreateDXGIFactory1(&IID_IDXGIFactory1, &dxgi_factory);
         if (hres != S_OK) {
             loader_log(
                 inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
@@ -1962,9 +1966,10 @@
 // Search the source_list for any layer with a name that matches the given 
name and a type
 // that matches the given type.  Add all matching layers to the target_list.
 // Do not add if found loader_layer_properties is already on the target_list.
-void loaderAddLayerNameToList(const struct loader_instance *inst, const char 
*name, const enum layer_type_flags type_flags,
-                              const struct loader_layer_list *source_list, 
struct loader_layer_list *target_list,
-                              struct loader_layer_list *expanded_target_list) {
+VkResult loaderAddLayerNameToList(const struct loader_instance *inst, const 
char *name, const enum layer_type_flags type_flags,
+                                  const struct loader_layer_list *source_list, 
struct loader_layer_list *target_list,
+                                  struct loader_layer_list 
*expanded_target_list) {
+    VkResult res = VK_SUCCESS;
     bool found = false;
     for (uint32_t i = 0; i < source_list->count; i++) {
         struct loader_layer_properties *source_prop = &source_list->list[i];
@@ -1985,9 +1990,17 @@
         }
     }
     if (!found) {
-        loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, 
"loaderAddLayerNameToList: Failed to find layer name %s to activate",
-                   name);
+        if (strcmp(name, "VK_LAYER_LUNARG_standard_validation")) {
+            loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+                       "loaderAddLayerNameToList: Failed to find layer name %s 
to activate", name);
+        } else {
+            res = VK_ERROR_LAYER_NOT_PRESENT;
+            loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+                       "Layer VK_LAYER_LUNARG_standard_validation has been 
changed to VK_LAYER_KHRONOS_validation. Please use the "
+                       "new version of the layer.");
+        }
     }
+    return res;
 }
 
 static VkExtensionProperties *get_extension_property(const char *name, const 
struct loader_extension_list *list) {
@@ -2288,6 +2301,9 @@
     PFN_vkGetInstanceProcAddr fp_get_proc_addr;
     PFN_GetPhysicalDeviceProcAddr fp_get_phys_dev_proc_addr = NULL;
     PFN_vkNegotiateLoaderICDInterfaceVersion fp_negotiate_icd_version;
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+    PFN_vk_icdEnumerateAdapterPhysicalDevices fp_enum_dxgi_adapter_phys_devs = 
NULL;
+#endif
     struct loader_scanned_icd *new_scanned_icd;
     uint32_t interface_vers;
     VkResult res = VK_SUCCESS;
@@ -2374,6 +2390,11 @@
             goto out;
         }
         fp_get_phys_dev_proc_addr = loader_platform_get_proc_address(handle, 
"vk_icdGetPhysicalDeviceProcAddr");
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+        if (interface_vers >= 6) {
+            fp_enum_dxgi_adapter_phys_devs = 
loader_platform_get_proc_address(handle, 
"vk_icdEnumerateAdapterPhysicalDevices");
+        }
+#endif
     }
 
     // check for enough capacity
@@ -2399,6 +2420,9 @@
     new_scanned_icd->GetPhysicalDeviceProcAddr = fp_get_phys_dev_proc_addr;
     new_scanned_icd->EnumerateInstanceExtensionProperties = 
fp_get_inst_ext_props;
     new_scanned_icd->CreateInstance = fp_create_inst;
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+    new_scanned_icd->EnumerateAdapterPhysicalDevices = 
fp_enum_dxgi_adapter_phys_devs;
+#endif
     new_scanned_icd->interface_version = interface_vers;
 
     new_scanned_icd->lib_name = (char *)loader_instance_heap_alloc(inst, 
strlen(filename) + 1, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
@@ -2481,6 +2505,13 @@
     // 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");
+
+    TCHAR systemPath[MAX_PATH] = "";
+    GetSystemDirectory(systemPath, MAX_PATH);
+    StringCchCat(systemPath, MAX_PATH, TEXT("\\dxgi.dll"));
+    HMODULE dxgi_module = LoadLibrary(systemPath);
+    fpCreateDXGIFactory1 = dxgi_module == NULL ? NULL :
+        (PFN_CreateDXGIFactory1)GetProcAddress(dxgi_module, 
"CreateDXGIFactory1");
 #endif
 }
 
@@ -2782,6 +2813,9 @@
             if (prop->blacklist_layer_names != NULL) {
                 loader_instance_heap_free(inst, prop->blacklist_layer_names);
             }
+            if (prop->override_paths != NULL) {
+                loader_instance_heap_free(inst, prop->override_paths);
+            }
 
             // Remove the current invalid meta-layer from the layer list.  Use 
memmove since we are
             // overlapping the source and destination addresses.
@@ -4925,6 +4959,7 @@
             res = loaderAddLayerProperties(inst, instance_layers, json, true, 
file_str);
 
             loader_instance_heap_free(inst, file_str);
+            manifest_files.filename_list[i] = NULL;
             cJSON_Delete(json);
 
             if (VK_ERROR_OUT_OF_HOST_MEMORY == res) {
@@ -4949,6 +4984,11 @@
     if (NULL != override_paths) {
         loader_instance_heap_free(inst, override_paths);
     }
+    for (uint32_t i = 0; i < manifest_files.count; i++) {
+        if (NULL != manifest_files.filename_list[i]) {
+            loader_instance_heap_free(inst, manifest_files.filename_list[i]);
+        }
+    }
     if (NULL != manifest_files.filename_list) {
         loader_instance_heap_free(inst, manifest_files.filename_list);
     }
@@ -5585,9 +5625,11 @@
 
 // Get the layer name(s) from the env_name environment variable. If layer is 
found in
 // search_list then add it to layer_list.  But only add it to layer_list if 
type_flags matches.
-static void loaderAddEnvironmentLayers(struct loader_instance *inst, const 
enum layer_type_flags type_flags, const char *env_name,
-                                       struct loader_layer_list *target_list, 
struct loader_layer_list *expanded_target_list,
-                                       const struct loader_layer_list 
*source_list) {
+static VkResult loaderAddEnvironmentLayers(struct loader_instance *inst, const 
enum layer_type_flags type_flags,
+                                           const char *env_name, struct 
loader_layer_list *target_list,
+                                           struct loader_layer_list 
*expanded_target_list,
+                                           const struct loader_layer_list 
*source_list) {
+    VkResult res = VK_SUCCESS;
     char *next, *name;
     char *layer_env = loader_getenv(env_name, inst);
     if (layer_env == NULL) {
@@ -5601,7 +5643,10 @@
 
     while (name && *name) {
         next = loader_get_next_path(name);
-        loaderAddLayerNameToList(inst, name, type_flags, source_list, 
target_list, expanded_target_list);
+        res = loaderAddLayerNameToList(inst, name, type_flags, source_list, 
target_list, expanded_target_list);
+        if (res != VK_SUCCESS) {
+            goto out;
+        }
         name = next;
     }
 
@@ -5611,7 +5656,7 @@
         loader_free_getenv(layer_env, inst);
     }
 
-    return;
+    return res;
 }
 
 VkResult loaderEnableInstanceLayers(struct loader_instance *inst, const 
VkInstanceCreateInfo *pCreateInfo,
@@ -5640,8 +5685,11 @@
     loaderAddImplicitLayers(inst, &inst->app_activated_layer_list, 
&inst->expanded_activated_layer_list, instance_layers);
 
     // Add any layers specified via environment variable next
-    loaderAddEnvironmentLayers(inst, VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER, 
"VK_INSTANCE_LAYERS", &inst->app_activated_layer_list,
-                               &inst->expanded_activated_layer_list, 
instance_layers);
+    err = loaderAddEnvironmentLayers(inst, VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER, 
"VK_INSTANCE_LAYERS", &inst->app_activated_layer_list,
+                                     &inst->expanded_activated_layer_list, 
instance_layers);
+    if (err != VK_SUCCESS) {
+        goto out;
+    }
 
     // Add layers specified by the application
     err = loaderAddLayerNamesToList(inst, &inst->app_activated_layer_list, 
&inst->expanded_activated_layer_list,
@@ -5663,6 +5711,7 @@
         }
     }
 
+out:
     return err;
 }
 
@@ -5985,28 +6034,46 @@
         }
     }
 
+    VkLoaderFeatureFlags feature_flags = 0;
+#if defined(_WIN32)
+    IDXGIFactory6* dxgi_factory = NULL;
+    HRESULT hres = fpCreateDXGIFactory1(&IID_IDXGIFactory6, &dxgi_factory);
+    if (hres == S_OK) {
+        feature_flags |= VK_LOADER_FEATURE_PHYSICAL_DEVICE_SORTING;
+        dxgi_factory->lpVtbl->Release(dxgi_factory);
+    }
+#endif
+
     PFN_vkCreateInstance fpCreateInstance = 
(PFN_vkCreateInstance)next_gipa(*created_instance, "vkCreateInstance");
     if (fpCreateInstance) {
-        VkLayerInstanceCreateInfo create_info_disp;
-
-        create_info_disp.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
-        create_info_disp.function = VK_LOADER_DATA_CALLBACK;
-
-        create_info_disp.u.pfnSetInstanceLoaderData = vkSetInstanceDispatch;
-
-        create_info_disp.pNext = loader_create_info.pNext;
-        loader_create_info.pNext = &create_info_disp;
-
-        VkLayerInstanceCreateInfo create_info_disp2;
-
-        create_info_disp2.sType = 
VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
-        create_info_disp2.function = VK_LOADER_LAYER_CREATE_DEVICE_CALLBACK;
-
-        create_info_disp2.u.layerDevice.pfnLayerCreateDevice = 
loader_layer_create_device;
-        create_info_disp2.u.layerDevice.pfnLayerDestroyDevice = 
loader_layer_destroy_device;
-
-        create_info_disp2.pNext = loader_create_info.pNext;
-        loader_create_info.pNext = &create_info_disp2;
+        const VkLayerInstanceCreateInfo instance_dispatch = {
+            .sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO,
+            .pNext = loader_create_info.pNext,
+            .function = VK_LOADER_DATA_CALLBACK,
+            .u = {
+                .pfnSetInstanceLoaderData = vkSetInstanceDispatch,
+            },
+        };
+        const VkLayerInstanceCreateInfo device_callback = {
+            .sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO,
+            .pNext = &instance_dispatch,
+            .function = VK_LOADER_LAYER_CREATE_DEVICE_CALLBACK,
+            .u = {
+                .layerDevice = {
+                    .pfnLayerCreateDevice = loader_layer_create_device,
+                    .pfnLayerDestroyDevice = loader_layer_destroy_device,
+                },
+            },
+        };
+        const VkLayerInstanceCreateInfo loader_features = {
+            .sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO,
+            .pNext = &device_callback,
+            .function = VK_LOADER_FEATURES,
+            .u = {
+                .loaderFeatures = feature_flags,
+            },
+        };
+        loader_create_info.pNext = &loader_features;
 
         res = fpCreateInstance(&loader_create_info, pAllocator, 
created_instance);
     } else {
@@ -6247,8 +6314,11 @@
 
     // Build the lists of active layers (including metalayers) and expanded 
layers (with metalayers resolved to their components)
     loaderAddImplicitLayers(inst, &active_layers, &expanded_layers, 
instance_layers);
-    loaderAddEnvironmentLayers(inst, VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER, 
ENABLED_LAYERS_ENV, &active_layers, &expanded_layers,
-                               instance_layers);
+    res = loaderAddEnvironmentLayers(inst, VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER, 
ENABLED_LAYERS_ENV, &active_layers, &expanded_layers,
+                                     instance_layers);
+    if (res != VK_SUCCESS) {
+        goto out;
+    }
     res = loaderAddLayerNamesToList(inst, &active_layers, &expanded_layers, 
pCreateInfo->enabledLayerCount,
                                     pCreateInfo->ppEnabledLayerNames, 
instance_layers);
     if (VK_SUCCESS != res) {
@@ -6980,11 +7050,136 @@
     return res;
 }
 
+struct LoaderSortedPhysicalDevice {
+    uint32_t device_count;
+    VkPhysicalDevice* physical_devices;
+    uint32_t icd_index;
+    struct loader_icd_term* icd_term;
+};
+
+// This function allocates an array in sorted_devices which must be freed by 
the caller if not null
+VkResult ReadSortedPhysicalDevices(struct loader_instance *inst, struct 
LoaderSortedPhysicalDevice **sorted_devices, uint32_t* sorted_count)
+{
+    VkResult res = VK_SUCCESS;
+    uint32_t sorted_alloc = 0;
+    struct loader_icd_term* icd_term = NULL;
+
+#if defined(_WIN32)
+    IDXGIFactory6* dxgi_factory = NULL;
+    HRESULT hres = fpCreateDXGIFactory1(&IID_IDXGIFactory6, &dxgi_factory);
+    if (hres != S_OK) {
+        loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, "Failed to 
create DXGI factory 6. Physical devices will not be sorted");
+    }
+    else {
+        sorted_alloc = 16;
+        *sorted_devices = loader_instance_heap_alloc(inst, sorted_alloc * 
sizeof(struct LoaderSortedPhysicalDevice), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+        if (*sorted_devices == NULL) {
+            res = VK_ERROR_OUT_OF_HOST_MEMORY;
+            goto out;
+        }
+
+        memset(*sorted_devices, 0, sorted_alloc * sizeof(struct 
LoaderSortedPhysicalDevice));
+
+        *sorted_count = 0;
+        for (uint32_t i = 0; ; ++i) {
+            IDXGIAdapter1* adapter;
+            hres = 
dxgi_factory->lpVtbl->EnumAdapterByGpuPreference(dxgi_factory, i, 
DXGI_GPU_PREFERENCE_UNSPECIFIED, &IID_IDXGIAdapter1, &adapter);
+            if (hres == DXGI_ERROR_NOT_FOUND) {
+                break; // No more adapters
+            }
+            else if (hres != S_OK) {
+                loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, "Failed 
to enumerate adapters by GPU preference at index %u. This adapter will not be 
sorted", i);
+                break;
+            }
+
+            DXGI_ADAPTER_DESC1 description;
+            hres = adapter->lpVtbl->GetDesc1(adapter, &description);
+            if (hres != S_OK) {
+                loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, "Failed 
to get adapter LUID index %u. This adapter will not be sorted", i);
+                continue;
+            }
+
+            if (sorted_alloc <= i) {
+                uint32_t old_size = sorted_alloc * sizeof(struct 
LoaderSortedPhysicalDevice);
+                *sorted_devices = loader_instance_heap_realloc(inst, 
*sorted_devices, old_size, 2 * old_size, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+                if (*sorted_devices == NULL) {
+                    adapter->lpVtbl->Release(adapter);
+                    res = VK_ERROR_OUT_OF_HOST_MEMORY;
+                    goto out;
+                }
+                sorted_alloc *= 2;
+            }
+            struct LoaderSortedPhysicalDevice *sorted_array = *sorted_devices;
+            sorted_array[*sorted_count].device_count = 0;
+            sorted_array[*sorted_count].physical_devices = NULL;
+            //*sorted_count = i;
+
+            icd_term = inst->icd_terms;
+            for (uint32_t icd_idx = 0; NULL != icd_term; icd_term = 
icd_term->next, icd_idx++) {
+                // This is the new behavior, which cannot be run unless the 
ICD provides EnumerateAdapterPhysicalDevices
+                if (icd_term->scanned_icd->EnumerateAdapterPhysicalDevices == 
NULL) {
+                    continue;
+                }
+
+                uint32_t count;
+                VkResult vkres = 
icd_term->scanned_icd->EnumerateAdapterPhysicalDevices(icd_term->instance, 
description.AdapterLuid, &count, NULL);
+                if (vkres == VK_ERROR_INCOMPATIBLE_DRIVER) {
+                    continue; // This driver doesn't support the adapter
+                }
+                else if (vkres != VK_SUCCESS) {
+                    loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, 
"Failed to convert DXGI adapter into Vulkan physical device with unexpected 
error code");
+                    continue;
+                }
+
+                // Get the actual physical devices
+                if (0 != count)
+                {
+                    do {
+                        sorted_array[*sorted_count].physical_devices = 
loader_instance_heap_realloc(inst, 
sorted_array[*sorted_count].physical_devices, 
sorted_array[*sorted_count].device_count * sizeof(VkPhysicalDevice), count * 
sizeof(VkPhysicalDevice), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+                        if (sorted_array[*sorted_count].physical_devices == 
NULL) {
+                            res = VK_ERROR_OUT_OF_HOST_MEMORY;
+                            break;
+                        }
+                        sorted_array[*sorted_count].device_count = count;
+                    } while (vkres = 
icd_term->scanned_icd->EnumerateAdapterPhysicalDevices(icd_term->instance, 
description.AdapterLuid, &count, sorted_array[*sorted_count].physical_devices) 
== VK_INCOMPLETE);
+                }
+
+                if (vkres != VK_SUCCESS) {
+                    loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, 
"Failed to convert DXGI adapter into Vulkan physical device");
+                    continue;
+                }
+                else if (res == VK_ERROR_OUT_OF_HOST_MEMORY) {
+                    goto out;
+                }
+                inst->total_gpu_count += 
(sorted_array[*sorted_count].device_count = count);
+                sorted_array[*sorted_count].icd_index = icd_idx;
+                sorted_array[*sorted_count].icd_term = icd_term;
+                ++(*sorted_count);
+            }
+
+            adapter->lpVtbl->Release(adapter);
+        }
+
+        dxgi_factory->lpVtbl->Release(dxgi_factory);
+    }
+
+out:
+#endif
+
+    if (*sorted_count == 0 && *sorted_devices != NULL) {
+        loader_instance_heap_free(inst, *sorted_devices);
+        *sorted_devices = NULL;
+    }
+    return res;
+}
+
 VkResult setupLoaderTermPhysDevs(struct loader_instance *inst) {
     VkResult res = VK_SUCCESS;
     struct loader_icd_term *icd_term;
     struct loader_phys_dev_per_icd *icd_phys_dev_array = NULL;
     struct loader_physical_device_term **new_phys_devs = NULL;
+    struct LoaderSortedPhysicalDevice *sorted_phys_dev_array = NULL;
+    uint32_t sorted_count = 0;
 
     inst->total_gpu_count = 0;
 
@@ -7001,11 +7196,28 @@
         goto out;
     }
     memset(icd_phys_dev_array, 0, sizeof(struct loader_phys_dev_per_icd) * 
inst->total_icd_count);
-    icd_term = inst->icd_terms;
+
+    // Get the physical devices supported by platform sorting mechanism into a 
separate list
+    res = ReadSortedPhysicalDevices(inst, &sorted_phys_dev_array, 
&sorted_count);
+    if (VK_SUCCESS != res) {
+        goto out;
+    }
 
     // For each ICD, query the number of physical devices, and then get an
     // internal value for those physical devices.
+    icd_term = inst->icd_terms;
     for (uint32_t icd_idx = 0; NULL != icd_term; icd_term = icd_term->next, 
icd_idx++) {
+        icd_phys_dev_array[icd_idx].count = 0;
+        icd_phys_dev_array[icd_idx].phys_devs = NULL;
+        icd_phys_dev_array[icd_idx].this_icd_term = NULL;
+
+        // This is the legacy behavior which should be skipped if 
EnumerateAdapterPhysicalDevices is available
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+        if (icd_term->scanned_icd->EnumerateAdapterPhysicalDevices != NULL) {
+            continue;
+        }
+#endif
+
         res = icd_term->dispatch.EnumeratePhysicalDevices(icd_term->instance, 
&icd_phys_dev_array[icd_idx].count, NULL);
         if (VK_SUCCESS != res) {
             loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
@@ -7058,6 +7270,49 @@
 
     // Copy or create everything to fill the new array of physical devices
     uint32_t idx = 0;
+
+#if defined(_WIN32)
+    // Copy over everything found through sorted enumeration
+    for (uint32_t i = 0; i < sorted_count; ++i) {
+        for (uint32_t j = 0; j < sorted_phys_dev_array[i].device_count; ++i) {
+
+            // Check if this physical device is already in the old buffer
+            if (NULL != inst->phys_devs_term) {
+                for (uint32_t old_idx = 0; old_idx < 
inst->phys_dev_count_term; old_idx++) {
+                    if (sorted_phys_dev_array[i].physical_devices[j] == 
inst->phys_devs_term[old_idx]->phys_dev) {
+                        new_phys_devs[idx] = inst->phys_devs_term[old_idx];
+                        break;
+                    }
+                }
+            }
+
+            // If this physical device isn't in the old buffer, then we need 
to create it.
+            if (NULL == new_phys_devs[idx]) {
+                new_phys_devs[idx] = loader_instance_heap_alloc(inst, 
sizeof(struct loader_physical_device_term),
+                    VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+                if (NULL == new_phys_devs[idx]) {
+                    loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+                        "setupLoaderTermPhysDevs:  Failed to allocate "
+                        "physical device terminator object %d",
+                        idx);
+                    inst->total_gpu_count = idx;
+                    res = VK_ERROR_OUT_OF_HOST_MEMORY;
+                    goto out;
+                }
+
+                loader_set_dispatch((void *)new_phys_devs[idx], inst->disp);
+                new_phys_devs[idx]->this_icd_term = 
sorted_phys_dev_array[i].icd_term;
+                new_phys_devs[idx]->icd_index = 
(uint8_t)(sorted_phys_dev_array[i].icd_index);
+                new_phys_devs[idx]->phys_dev = 
sorted_phys_dev_array[i].physical_devices[j];
+            }
+
+            // Increment the count of new physical devices
+            idx++;
+        }
+    }
+#endif
+
+    // Copy over everything found through EnumeratePhysicalDevices
     for (uint32_t icd_idx = 0; icd_idx < inst->total_icd_count; icd_idx++) {
         for (uint32_t pd_idx = 0; pd_idx < icd_phys_dev_array[icd_idx].count; 
pd_idx++) {
             // Check if this physical device is already in the old buffer
@@ -7129,6 +7384,15 @@
         inst->phys_devs_term = new_phys_devs;
     }
 
+    if (sorted_phys_dev_array != NULL) {
+        for (uint32_t i = 0; i < sorted_count; ++i) {
+            if (sorted_phys_dev_array[i].device_count > 0 && 
sorted_phys_dev_array[i].physical_devices != NULL) {
+                loader_instance_heap_free(inst, 
sorted_phys_dev_array[i].physical_devices);
+            }
+        }
+        loader_instance_heap_free(inst, sorted_phys_dev_array);
+    }
+
     return res;
 }
 
@@ -7632,7 +7896,10 @@
     uint32_t cur_icd_group_count = 0;
     VkPhysicalDeviceGroupPropertiesKHR **new_phys_dev_groups = NULL;
     VkPhysicalDeviceGroupPropertiesKHR *local_phys_dev_groups = NULL;
+    bool *local_phys_dev_group_sorted = NULL;
     PFN_vkEnumeratePhysicalDeviceGroups fpEnumeratePhysicalDeviceGroups = NULL;
+    struct LoaderSortedPhysicalDevice* sorted_phys_dev_array = NULL;
+    uint32_t sorted_count = 0;
 
     if (0 == inst->phys_dev_count_term) {
         loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
@@ -7696,7 +7963,8 @@
     // Create a temporary array (on the stack) to keep track of the
     // returned VkPhysicalDevice values.
     local_phys_dev_groups = 
loader_stack_alloc(sizeof(VkPhysicalDeviceGroupProperties) * total_count);
-    if (NULL == local_phys_dev_groups) {
+    local_phys_dev_group_sorted = loader_stack_alloc(sizeof(bool) * 
total_count);
+    if (NULL == local_phys_dev_groups || NULL == local_phys_dev_group_sorted) {
         loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
             "setupLoaderTermPhysDevGroups:  Failed to allocate local "
             "physical device group array of size %d",
@@ -7706,17 +7974,31 @@
     }
     // Initialize the memory to something valid
     memset(local_phys_dev_groups, 0, sizeof(VkPhysicalDeviceGroupProperties) * 
total_count);
+    memset(local_phys_dev_group_sorted, 0, sizeof(bool) * total_count);
     for (uint32_t group = 0; group < total_count; group++) {
         local_phys_dev_groups[group].sType = 
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR;
         local_phys_dev_groups[group].pNext = NULL;
         local_phys_dev_groups[group].subsetAllocation = false;
     }
 
+    // Get the physical devices supported by platform sorting mechanism into a 
separate list
+    res = ReadSortedPhysicalDevices(inst, &sorted_phys_dev_array, 
&sorted_count);
+    if (VK_SUCCESS != res) {
+        goto out;
+    }
+
     cur_icd_group_count = 0;
     icd_term = inst->icd_terms;
     for (uint32_t icd_idx = 0; NULL != icd_term; icd_term = icd_term->next, 
icd_idx++) {
         uint32_t count_this_time = total_count - cur_icd_group_count;
 
+        // Check if this group can be sorted
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+        bool icd_sorted = 
icd_term->scanned_icd->EnumerateAdapterPhysicalDevices != NULL;
+#else
+        bool icd_sorted = false;
+#endif
+
         // Get the function pointer to use to call into the ICD. This could be 
the core or KHR version
         if (inst->enabled_known_extensions.khr_device_group_creation) {
             fpEnumeratePhysicalDeviceGroups = 
icd_term->dispatch.EnumeratePhysicalDeviceGroupsKHR;
@@ -7748,10 +8030,14 @@
             for (uint32_t indiv_gpu = 0; indiv_gpu < count_this_time; 
indiv_gpu++) {
                 local_phys_dev_groups[indiv_gpu + 
cur_icd_group_count].physicalDeviceCount = 1;
                 local_phys_dev_groups[indiv_gpu + 
cur_icd_group_count].physicalDevices[0] = phys_dev_array[indiv_gpu];
+                local_phys_dev_group_sorted[indiv_gpu + cur_icd_group_count] = 
icd_sorted;
             }
 
         } else {
             res = fpEnumeratePhysicalDeviceGroups(icd_term->instance, 
&count_this_time, &local_phys_dev_groups[cur_icd_group_count]);
+            for (uint32_t group = 0; group < count_this_time; ++group) {
+                local_phys_dev_group_sorted[group + cur_icd_group_count] = 
icd_sorted;
+            }
             if (VK_SUCCESS != res) {
                 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                     "setupLoaderTermPhysDevGroups:  Failed during dispatch 
call of "
@@ -7786,8 +8072,87 @@
         }
     }
 
+    uint32_t idx = 0;
+
+#if defined(_WIN32)
+    // Copy over everything found through sorted enumeration
+    for (uint32_t i = 0; i < sorted_count; ++i) {
+
+        // Find the VkPhysicalDeviceGroupProperties object in 
local_phys_dev_groups
+        VkPhysicalDeviceGroupProperties *group_properties = NULL;
+        for (uint32_t group = 0; group < total_count; group++) {
+            if (sorted_phys_dev_array[i].device_count != 
local_phys_dev_groups[group].physicalDeviceCount) {
+                continue;
+            }
+
+            bool match = true;
+            for (uint32_t group_gpu = 0; group_gpu < 
local_phys_dev_groups[group].physicalDeviceCount; group_gpu++) {
+                if (sorted_phys_dev_array[i].physical_devices[group_gpu] != 
((struct loader_physical_device_term*) 
local_phys_dev_groups[group].physicalDevices[group_gpu])->phys_dev) {
+                    match = false;
+                    break;
+                }
+            }
+
+            if (match) {
+                group_properties = &local_phys_dev_groups[group];
+            }
+        }
+
+        // Check if this physical device group with the same contents is 
already in the old buffer
+        for (uint32_t old_idx = 0; old_idx < inst->phys_dev_group_count_term; 
old_idx++) {
+            if (NULL != group_properties && 
group_properties->physicalDeviceCount == 
inst->phys_dev_groups_term[old_idx]->physicalDeviceCount) {
+                bool found_all_gpus = true;
+                for (uint32_t old_gpu = 0; old_gpu < 
inst->phys_dev_groups_term[old_idx]->physicalDeviceCount; old_gpu++) {
+                    bool found_gpu = false;
+                    for (uint32_t new_gpu = 0; new_gpu < 
group_properties->physicalDeviceCount; new_gpu++) {
+                        if (group_properties->physicalDevices[new_gpu] == 
inst->phys_dev_groups_term[old_idx]->physicalDevices[old_gpu]) {
+                            found_gpu = true;
+                            break;
+                        }
+                    }
+
+                    if (!found_gpu) {
+                        found_all_gpus = false;
+                        break;
+                    }
+                }
+                if (!found_all_gpus) {
+                    continue;
+                }
+                else {
+                    new_phys_dev_groups[idx] = 
inst->phys_dev_groups_term[old_idx];
+                    break;
+                }
+            }
+        }
+
+        // If this physical device group isn't in the old buffer, create it
+        if (group_properties != NULL && NULL == new_phys_dev_groups[idx]) {
+            new_phys_dev_groups[idx] = 
(VkPhysicalDeviceGroupPropertiesKHR*)loader_instance_heap_alloc(
+                inst, sizeof(VkPhysicalDeviceGroupPropertiesKHR), 
VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+            if (NULL == new_phys_dev_groups[idx]) {
+                loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+                    "setupLoaderTermPhysDevGroups:  Failed to allocate "
+                    "physical device group Terminator object %d",
+                    idx);
+                total_count = idx;
+                res = VK_ERROR_OUT_OF_HOST_MEMORY;
+                goto out;
+            }
+            memcpy(new_phys_dev_groups[idx], group_properties, 
sizeof(VkPhysicalDeviceGroupPropertiesKHR));
+        }
+
+        ++idx;
+    }
+#endif
+
     // Copy or create everything to fill the new array of physical device 
groups
     for (uint32_t new_idx = 0; new_idx < total_count; new_idx++) {
+        // Skip groups which have been included through sorting
+        if (local_phys_dev_group_sorted[new_idx] || 
local_phys_dev_groups[new_idx].physicalDeviceCount == 0) {
+            continue;
+        }
+
         // Check if this physical device group with the same contents is 
already in the old buffer
         for (uint32_t old_idx = 0; old_idx < inst->phys_dev_group_count_term; 
old_idx++) {
             if (local_phys_dev_groups[new_idx].physicalDeviceCount == 
inst->phys_dev_groups_term[old_idx]->physicalDeviceCount) {
@@ -7809,28 +8174,30 @@
                 if (!found_all_gpus) {
                     continue;
                 } else {
-                    new_phys_dev_groups[new_idx] = 
inst->phys_dev_groups_term[old_idx];
+                    new_phys_dev_groups[idx] = 
inst->phys_dev_groups_term[old_idx];
                     break;
                 }
             }
         }
 
         // If this physical device group isn't in the old buffer, create it
-        if (NULL == new_phys_dev_groups[new_idx]) {
-            new_phys_dev_groups[new_idx] = (VkPhysicalDeviceGroupPropertiesKHR 
*)loader_instance_heap_alloc(
+        if (NULL == new_phys_dev_groups[idx]) {
+            new_phys_dev_groups[idx] = (VkPhysicalDeviceGroupPropertiesKHR 
*)loader_instance_heap_alloc(
                 inst, sizeof(VkPhysicalDeviceGroupPropertiesKHR), 
VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
-            if (NULL == new_phys_dev_groups[new_idx]) {
+            if (NULL == new_phys_dev_groups[idx]) {
                 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                     "setupLoaderTermPhysDevGroups:  Failed to allocate "
                     "physical device group Terminator object %d",
-                    new_idx);
-                total_count = new_idx;
+                    idx);
+                total_count = idx;
                 res = VK_ERROR_OUT_OF_HOST_MEMORY;
                 goto out;
             }
-            memcpy(new_phys_dev_groups[new_idx], 
&local_phys_dev_groups[new_idx],
+            memcpy(new_phys_dev_groups[idx], &local_phys_dev_groups[new_idx],
                 sizeof(VkPhysicalDeviceGroupPropertiesKHR));
         }
+
+        ++idx;
     }
 
 out:
@@ -7867,6 +8234,15 @@
         inst->phys_dev_groups_term = new_phys_dev_groups;
     }
 
+    if (sorted_phys_dev_array != NULL) {
+        for (uint32_t i = 0; i < sorted_count; ++i) {
+            if (sorted_phys_dev_array[i].device_count > 0 && 
sorted_phys_dev_array[i].physical_devices != NULL) {
+                loader_instance_heap_free(inst, 
sorted_phys_dev_array[i].physical_devices);
+            }
+        }
+        loader_instance_heap_free(inst, sorted_phys_dev_array);
+    }
+
     return res;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Vulkan-Loader-1.2.148/loader/loader.h 
new/Vulkan-Loader-1.2.151/loader/loader.h
--- old/Vulkan-Loader-1.2.148/loader/loader.h   2020-07-20 20:36:53.000000000 
+0200
+++ new/Vulkan-Loader-1.2.151/loader/loader.h   2020-08-17 19:41:19.000000000 
+0200
@@ -387,6 +387,9 @@
     PFN_GetPhysicalDeviceProcAddr GetPhysicalDeviceProcAddr;
     PFN_vkCreateInstance CreateInstance;
     PFN_vkEnumerateInstanceExtensionProperties 
EnumerateInstanceExtensionProperties;
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+    PFN_vk_icdEnumerateAdapterPhysicalDevices EnumerateAdapterPhysicalDevices;
+#endif
 };
 
 static inline struct loader_instance *loader_instance(VkInstance instance) { 
return (struct loader_instance *)instance; }
@@ -476,9 +479,9 @@
 void loader_destroy_generic_list(const struct loader_instance *inst, struct 
loader_generic_list *list);
 void loaderDestroyLayerList(const struct loader_instance *inst, struct 
loader_device *device, struct loader_layer_list *layer_list);
 void loaderDeleteLayerListAndProperties(const struct loader_instance *inst, 
struct loader_layer_list *layer_list);
-void loaderAddLayerNameToList(const struct loader_instance *inst, const char 
*name, const enum layer_type_flags type_flags,
-                              const struct loader_layer_list *source_list, 
struct loader_layer_list *target_list,
-                              struct loader_layer_list *expanded_target_list);
+VkResult loaderAddLayerNameToList(const struct loader_instance *inst, const 
char *name, const enum layer_type_flags type_flags,
+                                  const struct loader_layer_list *source_list, 
struct loader_layer_list *target_list,
+                                  struct loader_layer_list 
*expanded_target_list);
 void loader_scanned_icd_clear(const struct loader_instance *inst, struct 
loader_icd_tramp_list *icd_tramp_list);
 VkResult loader_icd_scan(const struct loader_instance *inst, struct 
loader_icd_tramp_list *icd_tramp_list);
 void loaderScanForLayers(struct loader_instance *inst, struct 
loader_layer_list *instance_layers);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Vulkan-Loader-1.2.148/scripts/known_good.json 
new/Vulkan-Loader-1.2.151/scripts/known_good.json
--- old/Vulkan-Loader-1.2.148/scripts/known_good.json   2020-07-20 
20:36:53.000000000 +0200
+++ new/Vulkan-Loader-1.2.151/scripts/known_good.json   2020-08-17 
19:41:19.000000000 +0200
@@ -6,7 +6,7 @@
       "sub_dir" : "Vulkan-Headers",
       "build_dir" : "Vulkan-Headers/build",
       "install_dir" : "Vulkan-Headers/build/install",
-      "commit" : "v1.2.148"
+      "commit" : "v1.2.151"
     }
   ],
   "install_names" : {


Reply via email to