161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young/*
261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young * Copyright (c) 2015-2017 The Khronos Group Inc.
361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young * Copyright (c) 2015-2017 Valve Corporation
461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young * Copyright (c) 2015-2017 LunarG, Inc.
561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young *
661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young * Licensed under the Apache License, Version 2.0 (the "License");
761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young * you may not use this file except in compliance with the License.
861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young * You may obtain a copy of the License at
961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young *
1061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young *     http://www.apache.org/licenses/LICENSE-2.0
1161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young *
1261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young * Unless required by applicable law or agreed to in writing, software
1361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young * distributed under the License is distributed on an "AS IS" BASIS,
1461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young * See the License for the specific language governing permissions and
1661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young * limitations under the License.
1761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young *
1861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young * Author: Mark Young <marky@lunarg.com>
19b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow * Author: Lenny Komow <lenny@lunarg.com>
2061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young */
2161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
2261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young#define _GNU_SOURCE
2361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young#include <stdio.h>
2461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young#include <stdlib.h>
2561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young#include <string.h>
2661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young#include "vk_loader_platform.h"
2761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young#include "loader.h"
2861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young#include "vk_loader_extensions.h"
2961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young#include <vulkan/vk_icd.h>
3061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young#include "wsi.h"
3161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young#include "debug_report.h"
3261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
3361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young// ---- Manually added trampoline/terminator functions
3461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
3561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young// These functions, for whatever reason, require more complex changes than
3661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young// can easily be automatically generated.
3761ff81af2702610eb1121f3a392f4f73d79a3b28Mark YoungVkResult setupLoaderTrampPhysDevGroups(VkInstance instance);
3861ff81af2702610eb1121f3a392f4f73d79a3b28Mark YoungVkResult setupLoaderTermPhysDevGroups(struct loader_instance *inst);
3961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
408f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow// ---- VK_KHX_device_group extension trampoline/terminators
418f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
4261ff81af2702610eb1121f3a392f4f73d79a3b28Mark YoungVKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDeviceGroupsKHX(
4361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    VkInstance instance, uint32_t *pPhysicalDeviceGroupCount,
4461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    VkPhysicalDeviceGroupPropertiesKHX *pPhysicalDeviceGroupProperties) {
4561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    VkResult res = VK_SUCCESS;
4661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    uint32_t count;
4761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    uint32_t i;
4861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    struct loader_instance *inst = NULL;
4961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
5061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    loader_platform_thread_lock_mutex(&loader_lock);
5161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
5261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    inst = loader_get_instance(instance);
5361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    if (NULL == inst) {
5461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        res = VK_ERROR_INITIALIZATION_FAILED;
5561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        goto out;
5661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
5761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
5861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    if (NULL == pPhysicalDeviceGroupCount) {
5961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
6061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   "vkEnumeratePhysicalDeviceGroupsKHX: Received NULL pointer for physical "
6161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   "device group count return value.");
6261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        res = VK_ERROR_INITIALIZATION_FAILED;
6361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        goto out;
6461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
6561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
6661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    VkResult setup_res = setupLoaderTrampPhysDevGroups(instance);
6761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    if (VK_SUCCESS != setup_res) {
6861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        res = setup_res;
6961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        goto out;
7061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
7161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
7261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    count = inst->phys_dev_group_count_tramp;
7361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
7461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // Wrap the PhysDev object for loader usage, return wrapped objects
7561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    if (NULL != pPhysicalDeviceGroupProperties) {
7661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        if (inst->phys_dev_group_count_tramp > *pPhysicalDeviceGroupCount) {
7761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
7861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                       "vkEnumeratePhysicalDeviceGroupsKHX: Trimming device group count down"
7961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                       " by application request from %d to %d physical device groups",
8061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                       inst->phys_dev_group_count_tramp, *pPhysicalDeviceGroupCount);
8161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            count = *pPhysicalDeviceGroupCount;
8261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            res = VK_INCOMPLETE;
8361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        }
8461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        for (i = 0; i < count; i++) {
8561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            memcpy(&pPhysicalDeviceGroupProperties[i], inst->phys_dev_groups_tramp[i],
8661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   sizeof(VkPhysicalDeviceGroupPropertiesKHX));
8761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        }
8861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
8961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
9061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    *pPhysicalDeviceGroupCount = count;
9161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
9261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Youngout:
9361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
9461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    loader_platform_thread_unlock_mutex(&loader_lock);
9561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    return res;
9661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young}
9761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
9861ff81af2702610eb1121f3a392f4f73d79a3b28Mark YoungVKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroupsKHX(
9961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    VkInstance instance, uint32_t *pPhysicalDeviceGroupCount,
10061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    VkPhysicalDeviceGroupPropertiesKHX *pPhysicalDeviceGroupProperties) {
10161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    struct loader_instance *inst = (struct loader_instance *)instance;
10261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    VkResult res = VK_SUCCESS;
10361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
10461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // Always call the setup loader terminator physical device groups because they may
10561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // have changed at any point.
10661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    res = setupLoaderTermPhysDevGroups(inst);
10761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    if (VK_SUCCESS != res) {
10861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        goto out;
10961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
11061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
11161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    uint32_t copy_count = inst->phys_dev_group_count_term;
11261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    if (NULL != pPhysicalDeviceGroupProperties) {
11361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        if (copy_count > *pPhysicalDeviceGroupCount) {
11461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            copy_count = *pPhysicalDeviceGroupCount;
11561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            res = VK_INCOMPLETE;
11661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        }
11761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
11861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        for (uint32_t i = 0; i < copy_count; i++) {
11961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            memcpy(&pPhysicalDeviceGroupProperties[i], inst->phys_dev_groups_term[i],
12061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   sizeof(VkPhysicalDeviceGroupPropertiesKHX));
12161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        }
12261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
12361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
12461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    *pPhysicalDeviceGroupCount = copy_count;
12561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
12661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Youngout:
12761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
12861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    return res;
12961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young}
13061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
1318f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow// ---- VK_NV_external_memory_capabilities extension trampoline/terminators
1328f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
13361ff81af2702610eb1121f3a392f4f73d79a3b28Mark YoungVKAPI_ATTR VkResult VKAPI_CALL
13461ff81af2702610eb1121f3a392f4f73d79a3b28Mark YoungGetPhysicalDeviceExternalImageFormatPropertiesNV(
13561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
13661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags,
13761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    VkExternalMemoryHandleTypeFlagsNV externalHandleType,
13861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties) {
13961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    const VkLayerInstanceDispatchTable *disp;
14061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
14161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    disp = loader_get_instance_layer_dispatch(physicalDevice);
14261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
14361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    return disp->GetPhysicalDeviceExternalImageFormatPropertiesNV(
14461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        unwrapped_phys_dev, format, type, tiling, usage, flags,
14561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        externalHandleType, pExternalImageFormatProperties);
14661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young}
14761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
14861ff81af2702610eb1121f3a392f4f73d79a3b28Mark YoungVKAPI_ATTR VkResult VKAPI_CALL
14961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Youngterminator_GetPhysicalDeviceExternalImageFormatPropertiesNV(
15061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
15161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags,
15261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    VkExternalMemoryHandleTypeFlagsNV externalHandleType,
15361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties) {
15461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    struct loader_physical_device_term *phys_dev_term =
15561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        (struct loader_physical_device_term *)physicalDevice;
15661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
15761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
15861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    if (!icd_term->dispatch.GetPhysicalDeviceExternalImageFormatPropertiesNV) {
15961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        if (externalHandleType) {
16061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            return VK_ERROR_FORMAT_NOT_SUPPORTED;
16161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        }
16261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
16361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        if (!icd_term->dispatch.GetPhysicalDeviceImageFormatProperties) {
16461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            return VK_ERROR_INITIALIZATION_FAILED;
16561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        }
16661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
16761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        pExternalImageFormatProperties->externalMemoryFeatures = 0;
16861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        pExternalImageFormatProperties->exportFromImportedHandleTypes = 0;
16961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        pExternalImageFormatProperties->compatibleHandleTypes = 0;
17061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
17161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        return icd_term->dispatch.GetPhysicalDeviceImageFormatProperties(
17261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            phys_dev_term->phys_dev, format, type, tiling, usage, flags,
17361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            &pExternalImageFormatProperties->imageFormatProperties);
17461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
17561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
17661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    return icd_term->dispatch.GetPhysicalDeviceExternalImageFormatPropertiesNV(
17761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        phys_dev_term->phys_dev, format, type, tiling, usage, flags,
17861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        externalHandleType, pExternalImageFormatProperties);
17961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young}
18061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
181e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow// ---- VK_KHR_get_physical_device_properties2 extension trampoline/terminators
182e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow
183e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny KomowVKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2KHR *pFeatures) {
184e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    const VkLayerInstanceDispatchTable *disp;
185e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
186e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    disp = loader_get_instance_layer_dispatch(physicalDevice);
187e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    disp->GetPhysicalDeviceFeatures2KHR(unwrapped_phys_dev, pFeatures);
188e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow}
189e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow
190e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny KomowVKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice,
191e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow                                                                    VkPhysicalDeviceFeatures2KHR *pFeatures) {
192e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
193e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
194e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow
195e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    if (icd_term->dispatch.GetPhysicalDeviceFeatures2KHR != NULL) {
196b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        // Pass the call to the driver
197e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        icd_term->dispatch.GetPhysicalDeviceFeatures2KHR(phys_dev_term->phys_dev, pFeatures);
198e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    } else {
199b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        // Emulate the call
200e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
201937f415ce70db048caecb63feec00766e161ab0dLenny Komow                   "vkGetPhysicalDeviceFeatures2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceFeatures",
202937f415ce70db048caecb63feec00766e161ab0dLenny Komow                   icd_term->scanned_icd->lib_name);
203b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow
204b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        // Write to the VkPhysicalDeviceFeatures2KHR struct
205e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        icd_term->dispatch.GetPhysicalDeviceFeatures(phys_dev_term->phys_dev, &pFeatures->features);
206b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow
207b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        void *pNext = pFeatures->pNext;
208b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        while (pNext != NULL) {
209b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow            switch (*(VkStructureType *)pNext) {
210b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHX: {
211b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                    // Skip the check if VK_KHX_multiview is enabled because it's a device extension
212b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                    // Write to the VkPhysicalDeviceMultiviewFeaturesKHX struct
213b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                    VkPhysicalDeviceMultiviewFeaturesKHX *multiview_features = pNext;
214b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                    multiview_features->multiview = VK_FALSE;
215b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                    multiview_features->multiviewGeometryShader = VK_FALSE;
216b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                    multiview_features->multiviewTessellationShader = VK_FALSE;
217b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow
218b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                    pNext = multiview_features->pNext;
219b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                    break;
220b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                }
221b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                default: {
222b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                    loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
223b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                               "vkGetPhysicalDeviceFeatures2KHR: Emulation found unrecognized structure type in pFeatures->pNext - "
224b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                               "this struct will be ignored");
225b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow
226b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                    struct VkStructureHeader *header = pNext;
227b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                    pNext = (void *)header->pNext;
228b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                    break;
229b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                }
230b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow            }
231b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        }
232e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    }
233e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow}
234e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow
235e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny KomowVKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice,
236e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow                                                           VkPhysicalDeviceProperties2KHR *pProperties) {
237e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    const VkLayerInstanceDispatchTable *disp;
238e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
239e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    disp = loader_get_instance_layer_dispatch(physicalDevice);
240e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    disp->GetPhysicalDeviceProperties2KHR(unwrapped_phys_dev, pProperties);
241e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow}
242e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow
243e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny KomowVKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice,
244e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow                                                                      VkPhysicalDeviceProperties2KHR *pProperties) {
245e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
246e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
247e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow
248e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    if (icd_term->dispatch.GetPhysicalDeviceProperties2KHR != NULL) {
249b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        // Pass the call to the driver
250e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        icd_term->dispatch.GetPhysicalDeviceProperties2KHR(phys_dev_term->phys_dev, pProperties);
251e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    } else {
252b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        // Emulate the call
253e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
254937f415ce70db048caecb63feec00766e161ab0dLenny Komow                   "vkGetPhysicalDeviceProperties2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceProperties",
255937f415ce70db048caecb63feec00766e161ab0dLenny Komow                   icd_term->scanned_icd->lib_name);
256b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow
257b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        // Write to the VkPhysicalDeviceProperties2KHR struct
258e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        icd_term->dispatch.GetPhysicalDeviceProperties(phys_dev_term->phys_dev, &pProperties->properties);
259b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow
260b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        void *pNext = pProperties->pNext;
261b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        while (pNext != NULL) {
262b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow            switch (*(VkStructureType *)pNext) {
2637e90b4d60997446074136292d3660648bb876391Mark Young                case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR: {
2647e90b4d60997446074136292d3660648bb876391Mark Young                    VkPhysicalDeviceIDPropertiesKHR *id_properties = pNext;
265b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow
2667e90b4d60997446074136292d3660648bb876391Mark Young                    // Verify that "VK_KHR_external_memory_capabilities" is enabled
2677e90b4d60997446074136292d3660648bb876391Mark Young                    if (icd_term->this_instance->enabled_known_extensions.khr_external_memory_capabilities) {
268b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                        loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
269b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                                   "vkGetPhysicalDeviceProperties2KHR: Emulation cannot generate unique IDs for struct "
2707e90b4d60997446074136292d3660648bb876391Mark Young                                   "VkPhysicalDeviceIDPropertiesKHR - setting IDs to zero instead");
271b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow
2727e90b4d60997446074136292d3660648bb876391Mark Young                        // Write to the VkPhysicalDeviceIDPropertiesKHR struct
273b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                        memset(id_properties->deviceUUID, 0, VK_UUID_SIZE);
274b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                        memset(id_properties->driverUUID, 0, VK_UUID_SIZE);
275b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                        id_properties->deviceLUIDValid = VK_FALSE;
276b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                    }
277b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow
278b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                    pNext = id_properties->pNext;
279b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                    break;
280b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                }
281b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                default: {
282b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                    loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
283b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                               "vkGetPhysicalDeviceProperties2KHR: Emulation found unrecognized structure type in "
284b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                               "pProperties->pNext - this struct will be ignored");
285b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow
286b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                    struct VkStructureHeader *header = pNext;
287b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                    pNext = (void *)header->pNext;
288b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                    break;
289b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                }
290b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow            }
291b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        }
292e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    }
293e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow}
294e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow
295e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny KomowVKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFormatProperties2KHR(VkPhysicalDevice physicalDevice, VkFormat format,
296e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow                                                                 VkFormatProperties2KHR *pFormatProperties) {
297e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    const VkLayerInstanceDispatchTable *disp;
298e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
299e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    disp = loader_get_instance_layer_dispatch(physicalDevice);
300e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    disp->GetPhysicalDeviceFormatProperties2KHR(unwrapped_phys_dev, format, pFormatProperties);
301e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow}
302e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow
303e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny KomowVKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFormatProperties2KHR(VkPhysicalDevice physicalDevice, VkFormat format,
304e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow                                                                            VkFormatProperties2KHR *pFormatProperties) {
305e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
306e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
307e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow
308e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    if (icd_term->dispatch.GetPhysicalDeviceFormatProperties2KHR != NULL) {
309b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        // Pass the call to the driver
310e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        icd_term->dispatch.GetPhysicalDeviceFormatProperties2KHR(phys_dev_term->phys_dev, format, pFormatProperties);
311e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    } else {
312b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        // Emulate the call
313937f415ce70db048caecb63feec00766e161ab0dLenny Komow        loader_log(
314937f415ce70db048caecb63feec00766e161ab0dLenny Komow            icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
315937f415ce70db048caecb63feec00766e161ab0dLenny Komow            "vkGetPhysicalDeviceFormatProperties2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceFormatProperties",
316937f415ce70db048caecb63feec00766e161ab0dLenny Komow            icd_term->scanned_icd->lib_name);
317b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow
318b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        // Write to the VkFormatProperties2KHR struct
319b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        icd_term->dispatch.GetPhysicalDeviceFormatProperties(phys_dev_term->phys_dev, format, &pFormatProperties->formatProperties);
320b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow
321e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        if (pFormatProperties->pNext != NULL) {
322e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow            loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
323b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                       "vkGetPhysicalDeviceFormatProperties2KHR: Emulation found unrecognized structure type in "
324b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                       "pFormatProperties->pNext - this struct will be ignored");
325e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        }
326e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    }
327e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow}
328e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow
329e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny KomowVKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceImageFormatProperties2KHR(
330e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo,
331e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    VkImageFormatProperties2KHR *pImageFormatProperties) {
332e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    const VkLayerInstanceDispatchTable *disp;
333e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
334e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    disp = loader_get_instance_layer_dispatch(physicalDevice);
335e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    return disp->GetPhysicalDeviceImageFormatProperties2KHR(unwrapped_phys_dev, pImageFormatInfo, pImageFormatProperties);
336e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow}
337e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow
338e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny KomowVKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceImageFormatProperties2KHR(
339e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo,
340e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    VkImageFormatProperties2KHR *pImageFormatProperties) {
341e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
342e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
343e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow
344e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    if (icd_term->dispatch.GetPhysicalDeviceImageFormatProperties2KHR != NULL) {
345b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        // Pass the call to the driver
346e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        return icd_term->dispatch.GetPhysicalDeviceImageFormatProperties2KHR(phys_dev_term->phys_dev, pImageFormatInfo,
347e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow                                                                             pImageFormatProperties);
348e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    } else {
349b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        // Emulate the call
350e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
351937f415ce70db048caecb63feec00766e161ab0dLenny Komow                   "vkGetPhysicalDeviceImageFormatProperties2KHR: Emulating call in ICD \"%s\" using "
352937f415ce70db048caecb63feec00766e161ab0dLenny Komow                   "vkGetPhysicalDeviceImageFormatProperties",
353937f415ce70db048caecb63feec00766e161ab0dLenny Komow                   icd_term->scanned_icd->lib_name);
354b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow
355b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        // If there is more info in  either pNext, then this is unsupported
356b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        if (pImageFormatInfo->pNext != NULL || pImageFormatProperties->pNext != NULL) {
357b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow            return VK_ERROR_FORMAT_NOT_SUPPORTED;
358e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        }
359b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow
360b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        // Write to the VkImageFormatProperties2KHR struct
361b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        return icd_term->dispatch.GetPhysicalDeviceImageFormatProperties(
362e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow            phys_dev_term->phys_dev, pImageFormatInfo->format, pImageFormatInfo->type, pImageFormatInfo->tiling,
363e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow            pImageFormatInfo->usage, pImageFormatInfo->flags, &pImageFormatProperties->imageFormatProperties);
364e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    }
365e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow}
366e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow
367e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny KomowVKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties2KHR(VkPhysicalDevice physicalDevice,
368e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow                                                                      uint32_t *pQueueFamilyPropertyCount,
369e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow                                                                      VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
370e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    const VkLayerInstanceDispatchTable *disp;
371e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
372e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    disp = loader_get_instance_layer_dispatch(physicalDevice);
373e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    disp->GetPhysicalDeviceQueueFamilyProperties2KHR(unwrapped_phys_dev, pQueueFamilyPropertyCount, pQueueFamilyProperties);
374e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow}
375e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow
376e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny KomowVKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceQueueFamilyProperties2KHR(
377e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
378e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
379e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
380e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow
381e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    if (icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties2KHR != NULL) {
382b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        // Pass the call to the driver
383e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties2KHR(phys_dev_term->phys_dev, pQueueFamilyPropertyCount,
384e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow                                                                      pQueueFamilyProperties);
385e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    } else {
386b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        // Emulate the call
387e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
388937f415ce70db048caecb63feec00766e161ab0dLenny Komow                   "vkGetPhysicalDeviceQueueFamilyProperties2KHR: Emulating call in ICD \"%s\" using "
389937f415ce70db048caecb63feec00766e161ab0dLenny Komow                   "vkGetPhysicalDeviceQueueFamilyProperties",
390937f415ce70db048caecb63feec00766e161ab0dLenny Komow                   icd_term->scanned_icd->lib_name);
391b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow
392b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        if (pQueueFamilyProperties == NULL || *pQueueFamilyPropertyCount == 0) {
393b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow            // Write to pQueueFamilyPropertyCount
394b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow            icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties(phys_dev_term->phys_dev, pQueueFamilyPropertyCount, NULL);
395e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        } else {
396b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow            // Allocate a temporary array for the output of the old function
397b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow            VkQueueFamilyProperties *properties = loader_stack_alloc(*pQueueFamilyPropertyCount * sizeof(VkQueueFamilyProperties));
398b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow            if (properties == NULL) {
399b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                *pQueueFamilyPropertyCount = 0;
400b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                loader_log(
401b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                    icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
402b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                    "vkGetPhysicalDeviceQueueFamilyProperties2KHR: Out of memory - Failed to allocate array for loader emulation.");
403b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                return;
404b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow            }
405b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow
406e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow            icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties(phys_dev_term->phys_dev, pQueueFamilyPropertyCount,
407e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow                                                                      properties);
408e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow            for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; ++i) {
409b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                // Write to the VkQueueFamilyProperties2KHR struct
410b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                memcpy(&pQueueFamilyProperties[i].queueFamilyProperties, &properties[i], sizeof(VkQueueFamilyProperties));
411b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow
412e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow                if (pQueueFamilyProperties[i].pNext != NULL) {
413e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow                    loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
414b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                               "vkGetPhysicalDeviceQueueFamilyProperties2KHR: Emulation found unrecognized structure type in "
415a3d1258f3424cba230c997d46b08072795e204acLenny Komow                               "pQueueFamilyProperties[%d].pNext - this struct will be ignored",
416e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow                               i);
417e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow                }
418e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow            }
419e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        }
420e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    }
421e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow}
422e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow
423e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny KomowVKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceMemoryProperties2KHR(VkPhysicalDevice physicalDevice,
424e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow                                                                 VkPhysicalDeviceMemoryProperties2KHR *pMemoryProperties) {
425e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    const VkLayerInstanceDispatchTable *disp;
426e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
427e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    disp = loader_get_instance_layer_dispatch(physicalDevice);
428e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    disp->GetPhysicalDeviceMemoryProperties2KHR(unwrapped_phys_dev, pMemoryProperties);
429e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow}
430e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow
431e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny KomowVKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceMemoryProperties2KHR(
432e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2KHR *pMemoryProperties) {
433e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
434e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
435e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow
436e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    if (icd_term->dispatch.GetPhysicalDeviceMemoryProperties2KHR != NULL) {
437b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        // Pass the call to the driver
438e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        icd_term->dispatch.GetPhysicalDeviceMemoryProperties2KHR(phys_dev_term->phys_dev, pMemoryProperties);
439e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    } else {
440b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        // Emulate the call
441937f415ce70db048caecb63feec00766e161ab0dLenny Komow        loader_log(
442937f415ce70db048caecb63feec00766e161ab0dLenny Komow            icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
443937f415ce70db048caecb63feec00766e161ab0dLenny Komow            "vkGetPhysicalDeviceMemoryProperties2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceMemoryProperties",
444937f415ce70db048caecb63feec00766e161ab0dLenny Komow            icd_term->scanned_icd->lib_name);
445b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow
446b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        // Write to the VkPhysicalDeviceMemoryProperties2KHR struct
447b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        icd_term->dispatch.GetPhysicalDeviceMemoryProperties(phys_dev_term->phys_dev, &pMemoryProperties->memoryProperties);
448b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow
449b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        if (pMemoryProperties->pNext != NULL) {
450e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow            loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
451b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                       "vkGetPhysicalDeviceMemoryProperties2KHR: Emulation found unrecognized structure type in "
452b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                       "pMemoryProperties->pNext - this struct will be ignored");
453e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        }
454e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    }
455e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow}
456e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow
457e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny KomowVKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceSparseImageFormatProperties2KHR(
458e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2KHR *pFormatInfo, uint32_t *pPropertyCount,
459e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    VkSparseImageFormatProperties2KHR *pProperties) {
460e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    const VkLayerInstanceDispatchTable *disp;
461e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
462e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    disp = loader_get_instance_layer_dispatch(physicalDevice);
463e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    disp->GetPhysicalDeviceSparseImageFormatProperties2KHR(unwrapped_phys_dev, pFormatInfo, pPropertyCount, pProperties);
464e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow}
465e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow
466e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny KomowVKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceSparseImageFormatProperties2KHR(
467e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2KHR *pFormatInfo, uint32_t *pPropertyCount,
468e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    VkSparseImageFormatProperties2KHR *pProperties) {
469e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
470e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
471e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow
472e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    if (icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties2KHR != NULL) {
473b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        // Pass the call to the driver
474e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties2KHR(phys_dev_term->phys_dev, pFormatInfo, pPropertyCount,
475e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow                                                                            pProperties);
476e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    } else {
477b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        // Emulate the call
478e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
479937f415ce70db048caecb63feec00766e161ab0dLenny Komow                   "vkGetPhysicalDeviceSparseImageFormatProperties2KHR: Emulating call in ICD \"%s\" using "
480937f415ce70db048caecb63feec00766e161ab0dLenny Komow                   "vkGetPhysicalDeviceSparseImageFormatProperties",
481937f415ce70db048caecb63feec00766e161ab0dLenny Komow                   icd_term->scanned_icd->lib_name);
482b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow
483e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        if (pFormatInfo->pNext != NULL) {
484e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow            loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
485b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                       "vkGetPhysicalDeviceSparseImageFormatProperties2KHR: Emulation found unrecognized structure type in "
486b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                       "pFormatInfo->pNext - this struct will be ignored");
487e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        }
488b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow
489b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow        if (pProperties == NULL || *pPropertyCount == 0) {
490b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow            // Write to pPropertyCount
491b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow            icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties(
492b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                phys_dev_term->phys_dev, pFormatInfo->format, pFormatInfo->type, pFormatInfo->samples, pFormatInfo->usage,
493b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                pFormatInfo->tiling, pPropertyCount, NULL);
494e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        } else {
495b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow            // Allocate a temporary array for the output of the old function
496b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow            VkSparseImageFormatProperties *properties =
497b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                loader_stack_alloc(*pPropertyCount * sizeof(VkSparseImageMemoryRequirements));
498b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow            if (properties == NULL) {
499b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                *pPropertyCount = 0;
500b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
501b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                           "vkGetPhysicalDeviceSparseImageFormatProperties2KHR: Out of memory - Failed to allocate array for "
502b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                           "loader emulation.");
503b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                return;
504b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow            }
505b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow
506e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow            icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties(
507e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow                phys_dev_term->phys_dev, pFormatInfo->format, pFormatInfo->type, pFormatInfo->samples, pFormatInfo->usage,
508e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow                pFormatInfo->tiling, pPropertyCount, properties);
509e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow            for (uint32_t i = 0; i < *pPropertyCount; ++i) {
510b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                // Write to the VkSparseImageFormatProperties2KHR struct
511b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                memcpy(&pProperties[i].properties, &properties[i], sizeof(VkSparseImageFormatProperties));
512b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow
513e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow                if (pProperties[i].pNext != NULL) {
514e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow                    loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
515b04267ff9d56fc4034a28b88c7082a4ee08caef4Lenny Komow                               "vkGetPhysicalDeviceSparseImageFormatProperties2KHR: Emulation found unrecognized structure type in "
516a3d1258f3424cba230c997d46b08072795e204acLenny Komow                               "pProperties[%d].pNext - this struct will be ignored",
517e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow                               i);
518e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow                }
519e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow            }
520e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow        }
521e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow    }
522e31abc7be348cc06e620ec3f44b6a30a4d3bd841Lenny Komow}
52361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
524a3d1258f3424cba230c997d46b08072795e204acLenny Komow// ---- VK_KHR_get_surface_capabilities2 extension trampoline/terminators
525a3d1258f3424cba230c997d46b08072795e204acLenny Komow
526a3d1258f3424cba230c997d46b08072795e204acLenny KomowVKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,
527a3d1258f3424cba230c997d46b08072795e204acLenny Komow                                                                        const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
528a3d1258f3424cba230c997d46b08072795e204acLenny Komow                                                                        VkSurfaceCapabilities2KHR *pSurfaceCapabilities) {
529a3d1258f3424cba230c997d46b08072795e204acLenny Komow    const VkLayerInstanceDispatchTable *disp;
530a3d1258f3424cba230c997d46b08072795e204acLenny Komow    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
531a3d1258f3424cba230c997d46b08072795e204acLenny Komow    disp = loader_get_instance_layer_dispatch(physicalDevice);
532a3d1258f3424cba230c997d46b08072795e204acLenny Komow    return disp->GetPhysicalDeviceSurfaceCapabilities2KHR(unwrapped_phys_dev, pSurfaceInfo, pSurfaceCapabilities);
533a3d1258f3424cba230c997d46b08072795e204acLenny Komow}
534a3d1258f3424cba230c997d46b08072795e204acLenny Komow
535a3d1258f3424cba230c997d46b08072795e204acLenny KomowVKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2KHR(
536a3d1258f3424cba230c997d46b08072795e204acLenny Komow    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
537a3d1258f3424cba230c997d46b08072795e204acLenny Komow    VkSurfaceCapabilities2KHR *pSurfaceCapabilities) {
538a3d1258f3424cba230c997d46b08072795e204acLenny Komow    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
539a3d1258f3424cba230c997d46b08072795e204acLenny Komow    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
540a3d1258f3424cba230c997d46b08072795e204acLenny Komow
541a3d1258f3424cba230c997d46b08072795e204acLenny Komow    VkIcdSurface *icd_surface = (VkIcdSurface *)(pSurfaceInfo->surface);
542a3d1258f3424cba230c997d46b08072795e204acLenny Komow    uint8_t icd_index = phys_dev_term->icd_index;
543a3d1258f3424cba230c997d46b08072795e204acLenny Komow
544a3d1258f3424cba230c997d46b08072795e204acLenny Komow    if (icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR != NULL) {
545a3d1258f3424cba230c997d46b08072795e204acLenny Komow        // Pass the call to the driver, possibly unwrapping the ICD surface
546a3d1258f3424cba230c997d46b08072795e204acLenny Komow        if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
547a3d1258f3424cba230c997d46b08072795e204acLenny Komow            VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;
548a3d1258f3424cba230c997d46b08072795e204acLenny Komow            info_copy.surface = icd_surface->real_icd_surfaces[icd_index];
549a3d1258f3424cba230c997d46b08072795e204acLenny Komow            return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev_term->phys_dev, &info_copy,
550a3d1258f3424cba230c997d46b08072795e204acLenny Komow                                                                               pSurfaceCapabilities);
551a3d1258f3424cba230c997d46b08072795e204acLenny Komow        } else {
552a3d1258f3424cba230c997d46b08072795e204acLenny Komow            return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev_term->phys_dev, pSurfaceInfo,
553a3d1258f3424cba230c997d46b08072795e204acLenny Komow                                                                               pSurfaceCapabilities);
554a3d1258f3424cba230c997d46b08072795e204acLenny Komow        }
555a3d1258f3424cba230c997d46b08072795e204acLenny Komow    } else {
556a3d1258f3424cba230c997d46b08072795e204acLenny Komow        // Emulate the call
557a3d1258f3424cba230c997d46b08072795e204acLenny Komow        loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
558a3d1258f3424cba230c997d46b08072795e204acLenny Komow                   "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulating call in ICD \"%s\" using "
559a3d1258f3424cba230c997d46b08072795e204acLenny Komow                   "vkGetPhysicalDeviceSurfaceCapabilitiesKHR",
560a3d1258f3424cba230c997d46b08072795e204acLenny Komow                   icd_term->scanned_icd->lib_name);
561a3d1258f3424cba230c997d46b08072795e204acLenny Komow
562a3d1258f3424cba230c997d46b08072795e204acLenny Komow        if (pSurfaceInfo->pNext != NULL) {
563a3d1258f3424cba230c997d46b08072795e204acLenny Komow            loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
564a3d1258f3424cba230c997d46b08072795e204acLenny Komow                       "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulation found unrecognized structure type in "
565a3d1258f3424cba230c997d46b08072795e204acLenny Komow                       "pSurfaceInfo->pNext - this struct will be ignored");
566a3d1258f3424cba230c997d46b08072795e204acLenny Komow        }
567a3d1258f3424cba230c997d46b08072795e204acLenny Komow
568a3d1258f3424cba230c997d46b08072795e204acLenny Komow        // Write to the VkSurfaceCapabilities2KHR struct
569a3d1258f3424cba230c997d46b08072795e204acLenny Komow        VkSurfaceKHR surface = pSurfaceInfo->surface;
570a3d1258f3424cba230c997d46b08072795e204acLenny Komow        if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
571a3d1258f3424cba230c997d46b08072795e204acLenny Komow            surface = icd_surface->real_icd_surfaces[icd_index];
572a3d1258f3424cba230c997d46b08072795e204acLenny Komow        }
573a3d1258f3424cba230c997d46b08072795e204acLenny Komow        VkResult res = icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, surface,
574a3d1258f3424cba230c997d46b08072795e204acLenny Komow                                                                                  &pSurfaceCapabilities->surfaceCapabilities);
575a3d1258f3424cba230c997d46b08072795e204acLenny Komow
576a3d1258f3424cba230c997d46b08072795e204acLenny Komow        if (pSurfaceCapabilities->pNext != NULL) {
577a3d1258f3424cba230c997d46b08072795e204acLenny Komow            loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
578a3d1258f3424cba230c997d46b08072795e204acLenny Komow                       "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulation found unrecognized structure type in "
579a3d1258f3424cba230c997d46b08072795e204acLenny Komow                       "pSurfaceCapabilities->pNext - this struct will be ignored");
580a3d1258f3424cba230c997d46b08072795e204acLenny Komow        }
581a3d1258f3424cba230c997d46b08072795e204acLenny Komow        return res;
582a3d1258f3424cba230c997d46b08072795e204acLenny Komow    }
583a3d1258f3424cba230c997d46b08072795e204acLenny Komow}
584a3d1258f3424cba230c997d46b08072795e204acLenny Komow
585a3d1258f3424cba230c997d46b08072795e204acLenny KomowVKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
586a3d1258f3424cba230c997d46b08072795e204acLenny Komow                                                                   const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
587a3d1258f3424cba230c997d46b08072795e204acLenny Komow                                                                   uint32_t *pSurfaceFormatCount,
588a3d1258f3424cba230c997d46b08072795e204acLenny Komow                                                                   VkSurfaceFormat2KHR *pSurfaceFormats) {
589a3d1258f3424cba230c997d46b08072795e204acLenny Komow    const VkLayerInstanceDispatchTable *disp;
590a3d1258f3424cba230c997d46b08072795e204acLenny Komow    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
591a3d1258f3424cba230c997d46b08072795e204acLenny Komow    disp = loader_get_instance_layer_dispatch(physicalDevice);
592a3d1258f3424cba230c997d46b08072795e204acLenny Komow    return disp->GetPhysicalDeviceSurfaceFormats2KHR(unwrapped_phys_dev, pSurfaceInfo, pSurfaceFormatCount, pSurfaceFormats);
593a3d1258f3424cba230c997d46b08072795e204acLenny Komow}
594a3d1258f3424cba230c997d46b08072795e204acLenny Komow
595a3d1258f3424cba230c997d46b08072795e204acLenny KomowVKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
596a3d1258f3424cba230c997d46b08072795e204acLenny Komow                                                                              const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
597a3d1258f3424cba230c997d46b08072795e204acLenny Komow                                                                              uint32_t *pSurfaceFormatCount,
598a3d1258f3424cba230c997d46b08072795e204acLenny Komow                                                                              VkSurfaceFormat2KHR *pSurfaceFormats) {
599a3d1258f3424cba230c997d46b08072795e204acLenny Komow    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
600a3d1258f3424cba230c997d46b08072795e204acLenny Komow    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
601a3d1258f3424cba230c997d46b08072795e204acLenny Komow
602a3d1258f3424cba230c997d46b08072795e204acLenny Komow    VkIcdSurface *icd_surface = (VkIcdSurface *)(pSurfaceInfo->surface);
603a3d1258f3424cba230c997d46b08072795e204acLenny Komow    uint8_t icd_index = phys_dev_term->icd_index;
604a3d1258f3424cba230c997d46b08072795e204acLenny Komow
605a3d1258f3424cba230c997d46b08072795e204acLenny Komow    if (icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR != NULL) {
606a3d1258f3424cba230c997d46b08072795e204acLenny Komow        // Pass the call to the driver, possibly unwrapping the ICD surface
607a3d1258f3424cba230c997d46b08072795e204acLenny Komow        if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
608a3d1258f3424cba230c997d46b08072795e204acLenny Komow            VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;
609a3d1258f3424cba230c997d46b08072795e204acLenny Komow            info_copy.surface = icd_surface->real_icd_surfaces[icd_index];
610a3d1258f3424cba230c997d46b08072795e204acLenny Komow            return icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR(phys_dev_term->phys_dev, &info_copy, pSurfaceFormatCount,
611a3d1258f3424cba230c997d46b08072795e204acLenny Komow                                                                          pSurfaceFormats);
612a3d1258f3424cba230c997d46b08072795e204acLenny Komow        } else {
613a3d1258f3424cba230c997d46b08072795e204acLenny Komow            return icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR(phys_dev_term->phys_dev, pSurfaceInfo,
614a3d1258f3424cba230c997d46b08072795e204acLenny Komow                                                                          pSurfaceFormatCount, pSurfaceFormats);
615a3d1258f3424cba230c997d46b08072795e204acLenny Komow        }
616a3d1258f3424cba230c997d46b08072795e204acLenny Komow    } else {
617a3d1258f3424cba230c997d46b08072795e204acLenny Komow        // Emulate the call
618a3d1258f3424cba230c997d46b08072795e204acLenny Komow        loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
619a3d1258f3424cba230c997d46b08072795e204acLenny Komow                   "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceSurfaceFormatsKHR",
620a3d1258f3424cba230c997d46b08072795e204acLenny Komow                   icd_term->scanned_icd->lib_name);
621a3d1258f3424cba230c997d46b08072795e204acLenny Komow
622a3d1258f3424cba230c997d46b08072795e204acLenny Komow        if (pSurfaceInfo->pNext != NULL) {
623a3d1258f3424cba230c997d46b08072795e204acLenny Komow            loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
624a3d1258f3424cba230c997d46b08072795e204acLenny Komow                       "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulation found unrecognized structure type in pSurfaceInfo->pNext "
625a3d1258f3424cba230c997d46b08072795e204acLenny Komow                       "- this struct will be ignored");
626a3d1258f3424cba230c997d46b08072795e204acLenny Komow        }
627a3d1258f3424cba230c997d46b08072795e204acLenny Komow
628a3d1258f3424cba230c997d46b08072795e204acLenny Komow        VkSurfaceKHR surface = pSurfaceInfo->surface;
629a3d1258f3424cba230c997d46b08072795e204acLenny Komow        if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
630a3d1258f3424cba230c997d46b08072795e204acLenny Komow            surface = icd_surface->real_icd_surfaces[icd_index];
631a3d1258f3424cba230c997d46b08072795e204acLenny Komow        }
632a3d1258f3424cba230c997d46b08072795e204acLenny Komow
633a3d1258f3424cba230c997d46b08072795e204acLenny Komow        if (*pSurfaceFormatCount == 0 || pSurfaceFormats == NULL) {
634a3d1258f3424cba230c997d46b08072795e204acLenny Komow            // Write to pSurfaceFormatCount
635a3d1258f3424cba230c997d46b08072795e204acLenny Komow            return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface, pSurfaceFormatCount,
636a3d1258f3424cba230c997d46b08072795e204acLenny Komow                                                                         NULL);
637a3d1258f3424cba230c997d46b08072795e204acLenny Komow        } else {
638a3d1258f3424cba230c997d46b08072795e204acLenny Komow            // Allocate a temporary array for the output of the old function
639a3d1258f3424cba230c997d46b08072795e204acLenny Komow            VkSurfaceFormatKHR *formats = loader_stack_alloc(*pSurfaceFormatCount * sizeof(VkSurfaceFormatKHR));
640a3d1258f3424cba230c997d46b08072795e204acLenny Komow            if (formats == NULL) {
641a3d1258f3424cba230c997d46b08072795e204acLenny Komow                return VK_ERROR_OUT_OF_HOST_MEMORY;
642a3d1258f3424cba230c997d46b08072795e204acLenny Komow            }
643a3d1258f3424cba230c997d46b08072795e204acLenny Komow
644a3d1258f3424cba230c997d46b08072795e204acLenny Komow            VkResult res = icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface,
645a3d1258f3424cba230c997d46b08072795e204acLenny Komow                                                                                 pSurfaceFormatCount, formats);
646a3d1258f3424cba230c997d46b08072795e204acLenny Komow            for (uint32_t i = 0; i < *pSurfaceFormatCount; ++i) {
647a3d1258f3424cba230c997d46b08072795e204acLenny Komow                pSurfaceFormats[i].surfaceFormat = formats[i];
648a3d1258f3424cba230c997d46b08072795e204acLenny Komow                if (pSurfaceFormats[i].pNext != NULL) {
649a3d1258f3424cba230c997d46b08072795e204acLenny Komow                    loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
650a3d1258f3424cba230c997d46b08072795e204acLenny Komow                               "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulation found unrecognized structure type in "
651a3d1258f3424cba230c997d46b08072795e204acLenny Komow                               "pSurfaceFormats[%d].pNext - this struct will be ignored",
652a3d1258f3424cba230c997d46b08072795e204acLenny Komow                               i);
653a3d1258f3424cba230c997d46b08072795e204acLenny Komow                }
654a3d1258f3424cba230c997d46b08072795e204acLenny Komow            }
655a3d1258f3424cba230c997d46b08072795e204acLenny Komow            return res;
656a3d1258f3424cba230c997d46b08072795e204acLenny Komow        }
657a3d1258f3424cba230c997d46b08072795e204acLenny Komow    }
658a3d1258f3424cba230c997d46b08072795e204acLenny Komow}
659a3d1258f3424cba230c997d46b08072795e204acLenny Komow
6608f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow// ---- VK_EXT_display_surface_counter extension trampoline/terminators
6618f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
6628f9948a6a70a093efd0de0435c7a75cec0f512feLenny KomowVKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
6638f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow                                                                        VkSurfaceCapabilities2EXT *pSurfaceCapabilities) {
6648f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    const VkLayerInstanceDispatchTable *disp;
6658f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
6668f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    disp = loader_get_instance_layer_dispatch(physicalDevice);
6678f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    return disp->GetPhysicalDeviceSurfaceCapabilities2EXT(unwrapped_phys_dev, surface, pSurfaceCapabilities);
6688f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow}
6698f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
6708f9948a6a70a093efd0de0435c7a75cec0f512feLenny KomowVKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2EXT(
6718f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilities2EXT *pSurfaceCapabilities) {
6728f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
6738f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
6748f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
6758f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);
6768f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    uint8_t icd_index = phys_dev_term->icd_index;
6778f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
6788f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    // Unwrap the surface if needed
6798f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    VkSurfaceKHR unwrapped_surface = surface;
6808f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
6818f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        unwrapped_surface = icd_surface->real_icd_surfaces[icd_index];
6828f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    }
6838f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
6848f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    if (icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2EXT != NULL) {
6858f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        // Pass the call to the driver
6868f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2EXT(phys_dev_term->phys_dev, unwrapped_surface,
6878f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow                                                                           pSurfaceCapabilities);
6888f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    } else {
6898f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        // Emulate the call
6908f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
6918f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow                   "vkGetPhysicalDeviceSurfaceCapabilities2EXT: Emulating call in ICD \"%s\" using "
6928f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow                   "vkGetPhysicalDeviceSurfaceCapabilitiesKHR",
6938f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow                   icd_term->scanned_icd->lib_name);
6948f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
6958f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        VkSurfaceCapabilitiesKHR surface_caps;
6968f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        VkResult res =
6978f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow            icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, unwrapped_surface, &surface_caps);
6988f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        pSurfaceCapabilities->minImageCount = surface_caps.minImageCount;
6998f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        pSurfaceCapabilities->maxImageCount = surface_caps.maxImageCount;
7008f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        pSurfaceCapabilities->currentExtent = surface_caps.currentExtent;
7018f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        pSurfaceCapabilities->minImageExtent = surface_caps.minImageExtent;
7028f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        pSurfaceCapabilities->maxImageExtent = surface_caps.maxImageExtent;
7038f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        pSurfaceCapabilities->maxImageArrayLayers = surface_caps.maxImageArrayLayers;
7048f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        pSurfaceCapabilities->supportedTransforms = surface_caps.supportedTransforms;
7058f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        pSurfaceCapabilities->currentTransform = surface_caps.currentTransform;
7068f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        pSurfaceCapabilities->supportedCompositeAlpha = surface_caps.supportedCompositeAlpha;
7078f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        pSurfaceCapabilities->supportedUsageFlags = surface_caps.supportedUsageFlags;
7088f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        pSurfaceCapabilities->supportedSurfaceCounters = 0;
7098f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
7108f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        if (pSurfaceCapabilities->pNext != NULL) {
7118f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow            loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
7128f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow                       "vkGetPhysicalDeviceSurfaceCapabilities2EXT: Emulation found unrecognized structure type in "
7138f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow                       "pSurfaceCapabilities->pNext - this struct will be ignored");
7148f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        }
7158f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
7168f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        return res;
7178f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    }
7188f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow}
7198f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
7208f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow// ---- VK_EXT_direct_mode_display extension trampoline/terminators
7218f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
7228f9948a6a70a093efd0de0435c7a75cec0f512feLenny KomowVKAPI_ATTR VkResult VKAPI_CALL ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, VkDisplayKHR display) {
7238f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    const VkLayerInstanceDispatchTable *disp;
7248f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
7258f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    disp = loader_get_instance_layer_dispatch(physicalDevice);
7268f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    return disp->ReleaseDisplayEXT(unwrapped_phys_dev, display);
7278f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow}
7288f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
7298f9948a6a70a093efd0de0435c7a75cec0f512feLenny KomowVKAPI_ATTR VkResult VKAPI_CALL terminator_ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, VkDisplayKHR display) {
7308f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
7318f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
7328f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
7338f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    if (icd_term->dispatch.ReleaseDisplayEXT == NULL) {
7348f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
7358f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow                   "ICD \"%s\" associated with VkPhysicalDevice does not support vkReleaseDisplayEXT - Consequently, the call is "
7368f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow                   "invalid because it should not be possible to acquire a display on this device",
7378f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow                   icd_term->scanned_icd->lib_name);
7388f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    }
7398f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    return icd_term->dispatch.ReleaseDisplayEXT(phys_dev_term->phys_dev, display);
7408f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow}
7418f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
7428f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow// ---- VK_EXT_acquire_xlib_display extension trampoline/terminators
7438f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
7448f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
7458f9948a6a70a093efd0de0435c7a75cec0f512feLenny KomowVKAPI_ATTR VkResult VKAPI_CALL AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, VkDisplayKHR display) {
7468f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    const VkLayerInstanceDispatchTable *disp;
7478f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
7488f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    disp = loader_get_instance_layer_dispatch(physicalDevice);
7498f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    return disp->AcquireXlibDisplayEXT(unwrapped_phys_dev, dpy, display);
7508f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow}
7518f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
7528f9948a6a70a093efd0de0435c7a75cec0f512feLenny KomowVKAPI_ATTR VkResult VKAPI_CALL terminator_AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy,
7538f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow                                                                VkDisplayKHR display) {
7548f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
7558f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
7568f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
7578f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    if (icd_term->dispatch.AcquireXlibDisplayEXT != NULL) {
7588f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        // Pass the call to the driver
7598f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        return icd_term->dispatch.AcquireXlibDisplayEXT(phys_dev_term->phys_dev, dpy, display);
7608f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    } else {
7618f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        // Emulate the call
7628f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
7638f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow                   "vkAcquireXLibDisplayEXT: Emulating call in ICD \"%s\" by returning error", icd_term->scanned_icd->lib_name);
7648f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
7658f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        // Fail for the unsupported command
7668f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        return VK_ERROR_INITIALIZATION_FAILED;
7678f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    }
7688f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow}
7698f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
7708f9948a6a70a093efd0de0435c7a75cec0f512feLenny KomowVKAPI_ATTR VkResult VKAPI_CALL GetRandROutputDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, RROutput rrOutput,
7718f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow                                                        VkDisplayKHR *pDisplay) {
7728f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    const VkLayerInstanceDispatchTable *disp;
7738f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
7748f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    disp = loader_get_instance_layer_dispatch(physicalDevice);
7758f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    return disp->GetRandROutputDisplayEXT(unwrapped_phys_dev, dpy, rrOutput, pDisplay);
7768f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow}
7778f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
7788f9948a6a70a093efd0de0435c7a75cec0f512feLenny KomowVKAPI_ATTR VkResult VKAPI_CALL terminator_GetRandROutputDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, RROutput rrOutput,
7798f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow                                                                   VkDisplayKHR *pDisplay) {
7808f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
7818f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
7828f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
7838f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    if (icd_term->dispatch.GetRandROutputDisplayEXT != NULL) {
7848f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        // Pass the call to the driver
7858f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        return icd_term->dispatch.GetRandROutputDisplayEXT(phys_dev_term->phys_dev, dpy, rrOutput, pDisplay);
7868f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    } else {
7878f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        // Emulate the call
7888f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
7898f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow                   "vkGetRandROutputDisplayEXT: Emulating call in ICD \"%s\" by returning null display",
7908f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow                   icd_term->scanned_icd->lib_name);
7918f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
7928f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        // Return a null handle to indicate this can't be done
7938f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        *pDisplay = VK_NULL_HANDLE;
7948f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow        return VK_SUCCESS;
7958f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow    }
7968f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow}
7978f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
7988f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow#endif  // VK_USE_PLATFORM_XLIB_XRANDR_EXT
7998f9948a6a70a093efd0de0435c7a75cec0f512feLenny Komow
8007e90b4d60997446074136292d3660648bb876391Mark Young// ---- VK_KHR_external_memory_capabilities extension trampoline/terminators
8017e90b4d60997446074136292d3660648bb876391Mark Young
8027e90b4d60997446074136292d3660648bb876391Mark YoungVKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceExternalBufferPropertiesKHR(
8037e90b4d60997446074136292d3660648bb876391Mark Young    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfoKHR *pExternalBufferInfo,
8047e90b4d60997446074136292d3660648bb876391Mark Young    VkExternalBufferPropertiesKHR *pExternalBufferProperties) {
8057e90b4d60997446074136292d3660648bb876391Mark Young    const VkLayerInstanceDispatchTable *disp;
8067e90b4d60997446074136292d3660648bb876391Mark Young    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
8077e90b4d60997446074136292d3660648bb876391Mark Young    disp = loader_get_instance_layer_dispatch(physicalDevice);
8087e90b4d60997446074136292d3660648bb876391Mark Young    disp->GetPhysicalDeviceExternalBufferPropertiesKHR(unwrapped_phys_dev, pExternalBufferInfo, pExternalBufferProperties);
8097e90b4d60997446074136292d3660648bb876391Mark Young}
8107e90b4d60997446074136292d3660648bb876391Mark Young
8117e90b4d60997446074136292d3660648bb876391Mark YoungVKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceExternalBufferPropertiesKHR(
8127e90b4d60997446074136292d3660648bb876391Mark Young    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfoKHR *pExternalBufferInfo,
8137e90b4d60997446074136292d3660648bb876391Mark Young    VkExternalBufferPropertiesKHR *pExternalBufferProperties) {
8147e90b4d60997446074136292d3660648bb876391Mark Young    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
8157e90b4d60997446074136292d3660648bb876391Mark Young    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
8167e90b4d60997446074136292d3660648bb876391Mark Young
8177e90b4d60997446074136292d3660648bb876391Mark Young    if (icd_term->dispatch.GetPhysicalDeviceExternalBufferPropertiesKHR) {
8187e90b4d60997446074136292d3660648bb876391Mark Young        // Pass the call to the driver
8197e90b4d60997446074136292d3660648bb876391Mark Young        icd_term->dispatch.GetPhysicalDeviceExternalBufferPropertiesKHR(phys_dev_term->phys_dev, pExternalBufferInfo,
8207e90b4d60997446074136292d3660648bb876391Mark Young                                                                        pExternalBufferProperties);
8217e90b4d60997446074136292d3660648bb876391Mark Young    } else {
8227e90b4d60997446074136292d3660648bb876391Mark Young        // Emulate the call
8237e90b4d60997446074136292d3660648bb876391Mark Young        loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
8247e90b4d60997446074136292d3660648bb876391Mark Young                   "vkGetPhysicalDeviceExternalBufferPropertiesKHR: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name);
8257e90b4d60997446074136292d3660648bb876391Mark Young
8267e90b4d60997446074136292d3660648bb876391Mark Young        if (pExternalBufferInfo->pNext != NULL) {
8277e90b4d60997446074136292d3660648bb876391Mark Young            loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
8287e90b4d60997446074136292d3660648bb876391Mark Young                       "vkGetPhysicalDeviceExternalBufferPropertiesKHR: Emulation found unrecognized structure type in "
8297e90b4d60997446074136292d3660648bb876391Mark Young                       "pExternalBufferInfo->pNext - this struct will be ignored");
8307e90b4d60997446074136292d3660648bb876391Mark Young        }
8317e90b4d60997446074136292d3660648bb876391Mark Young
8327e90b4d60997446074136292d3660648bb876391Mark Young        // Fill in everything being unsupported
8337e90b4d60997446074136292d3660648bb876391Mark Young        memset(&pExternalBufferProperties->externalMemoryProperties, 0, sizeof(VkExternalMemoryPropertiesKHR));
8347e90b4d60997446074136292d3660648bb876391Mark Young
8357e90b4d60997446074136292d3660648bb876391Mark Young        if (pExternalBufferProperties->pNext != NULL) {
8367e90b4d60997446074136292d3660648bb876391Mark Young            loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
8377e90b4d60997446074136292d3660648bb876391Mark Young                       "vkGetPhysicalDeviceExternalBufferPropertiesKHR: Emulation found unrecognized structure type in "
8387e90b4d60997446074136292d3660648bb876391Mark Young                       "pExternalBufferProperties->pNext - this struct will be ignored");
8397e90b4d60997446074136292d3660648bb876391Mark Young        }
8407e90b4d60997446074136292d3660648bb876391Mark Young    }
8417e90b4d60997446074136292d3660648bb876391Mark Young}
8427e90b4d60997446074136292d3660648bb876391Mark Young
8437e90b4d60997446074136292d3660648bb876391Mark Young// ---- VK_KHR_external_semaphore_capabilities extension trampoline/terminators
8447e90b4d60997446074136292d3660648bb876391Mark Young
8457e90b4d60997446074136292d3660648bb876391Mark YoungVKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceExternalSemaphorePropertiesKHR(
8467e90b4d60997446074136292d3660648bb876391Mark Young    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfoKHR *pExternalSemaphoreInfo,
8477e90b4d60997446074136292d3660648bb876391Mark Young    VkExternalSemaphorePropertiesKHR *pExternalSemaphoreProperties) {
8487e90b4d60997446074136292d3660648bb876391Mark Young    const VkLayerInstanceDispatchTable *disp;
8497e90b4d60997446074136292d3660648bb876391Mark Young    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
8507e90b4d60997446074136292d3660648bb876391Mark Young    disp = loader_get_instance_layer_dispatch(physicalDevice);
8517e90b4d60997446074136292d3660648bb876391Mark Young    disp->GetPhysicalDeviceExternalSemaphorePropertiesKHR(unwrapped_phys_dev, pExternalSemaphoreInfo, pExternalSemaphoreProperties);
8527e90b4d60997446074136292d3660648bb876391Mark Young}
8537e90b4d60997446074136292d3660648bb876391Mark Young
8547e90b4d60997446074136292d3660648bb876391Mark YoungVKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceExternalSemaphorePropertiesKHR(
8557e90b4d60997446074136292d3660648bb876391Mark Young    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfoKHR *pExternalSemaphoreInfo,
8567e90b4d60997446074136292d3660648bb876391Mark Young    VkExternalSemaphorePropertiesKHR *pExternalSemaphoreProperties) {
8577e90b4d60997446074136292d3660648bb876391Mark Young    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
8587e90b4d60997446074136292d3660648bb876391Mark Young    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
8597e90b4d60997446074136292d3660648bb876391Mark Young
8607e90b4d60997446074136292d3660648bb876391Mark Young    if (icd_term->dispatch.GetPhysicalDeviceExternalSemaphorePropertiesKHR != NULL) {
8617e90b4d60997446074136292d3660648bb876391Mark Young        // Pass the call to the driver
8627e90b4d60997446074136292d3660648bb876391Mark Young        icd_term->dispatch.GetPhysicalDeviceExternalSemaphorePropertiesKHR(phys_dev_term->phys_dev, pExternalSemaphoreInfo,
8637e90b4d60997446074136292d3660648bb876391Mark Young                                                                           pExternalSemaphoreProperties);
8647e90b4d60997446074136292d3660648bb876391Mark Young    } else {
8657e90b4d60997446074136292d3660648bb876391Mark Young        // Emulate the call
8667e90b4d60997446074136292d3660648bb876391Mark Young        loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
8677e90b4d60997446074136292d3660648bb876391Mark Young                   "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR: Emulating call in ICD \"%s\"",
8687e90b4d60997446074136292d3660648bb876391Mark Young                   icd_term->scanned_icd->lib_name);
8697e90b4d60997446074136292d3660648bb876391Mark Young
8707e90b4d60997446074136292d3660648bb876391Mark Young        if (pExternalSemaphoreInfo->pNext != NULL) {
8717e90b4d60997446074136292d3660648bb876391Mark Young            loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
8727e90b4d60997446074136292d3660648bb876391Mark Young                       "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR: Emulation found unrecognized structure type in "
8737e90b4d60997446074136292d3660648bb876391Mark Young                       "pExternalSemaphoreInfo->pNext - this struct will be ignored");
8747e90b4d60997446074136292d3660648bb876391Mark Young        }
8757e90b4d60997446074136292d3660648bb876391Mark Young
8767e90b4d60997446074136292d3660648bb876391Mark Young        // Fill in everything being unsupported
8777e90b4d60997446074136292d3660648bb876391Mark Young        pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
8787e90b4d60997446074136292d3660648bb876391Mark Young        pExternalSemaphoreProperties->compatibleHandleTypes = 0;
8797e90b4d60997446074136292d3660648bb876391Mark Young        pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
8807e90b4d60997446074136292d3660648bb876391Mark Young
8817e90b4d60997446074136292d3660648bb876391Mark Young        if (pExternalSemaphoreProperties->pNext != NULL) {
8827e90b4d60997446074136292d3660648bb876391Mark Young            loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
8837e90b4d60997446074136292d3660648bb876391Mark Young                       "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR: Emulation found unrecognized structure type in "
8847e90b4d60997446074136292d3660648bb876391Mark Young                       "pExternalSemaphoreProperties->pNext - this struct will be ignored");
8857e90b4d60997446074136292d3660648bb876391Mark Young        }
8867e90b4d60997446074136292d3660648bb876391Mark Young    }
8877e90b4d60997446074136292d3660648bb876391Mark Young}
8887e90b4d60997446074136292d3660648bb876391Mark Young
8897e90b4d60997446074136292d3660648bb876391Mark Young// ---- VK_KHR_external_fence_capabilities extension trampoline/terminators
8907e90b4d60997446074136292d3660648bb876391Mark Young
8917e90b4d60997446074136292d3660648bb876391Mark YoungVKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceExternalFencePropertiesKHR(
8927e90b4d60997446074136292d3660648bb876391Mark Young    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfoKHR *pExternalFenceInfo,
8937e90b4d60997446074136292d3660648bb876391Mark Young    VkExternalFencePropertiesKHR *pExternalFenceProperties) {
8947e90b4d60997446074136292d3660648bb876391Mark Young    const VkLayerInstanceDispatchTable *disp;
8957e90b4d60997446074136292d3660648bb876391Mark Young    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
8967e90b4d60997446074136292d3660648bb876391Mark Young    disp = loader_get_instance_layer_dispatch(physicalDevice);
8977e90b4d60997446074136292d3660648bb876391Mark Young    disp->GetPhysicalDeviceExternalFencePropertiesKHR(unwrapped_phys_dev, pExternalFenceInfo, pExternalFenceProperties);
8987e90b4d60997446074136292d3660648bb876391Mark Young}
8997e90b4d60997446074136292d3660648bb876391Mark Young
9007e90b4d60997446074136292d3660648bb876391Mark YoungVKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceExternalFencePropertiesKHR(
9017e90b4d60997446074136292d3660648bb876391Mark Young    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfoKHR *pExternalFenceInfo,
9027e90b4d60997446074136292d3660648bb876391Mark Young    VkExternalFencePropertiesKHR *pExternalFenceProperties) {
9037e90b4d60997446074136292d3660648bb876391Mark Young    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
9047e90b4d60997446074136292d3660648bb876391Mark Young    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
9057e90b4d60997446074136292d3660648bb876391Mark Young
9067e90b4d60997446074136292d3660648bb876391Mark Young    if (icd_term->dispatch.GetPhysicalDeviceExternalFencePropertiesKHR != NULL) {
9077e90b4d60997446074136292d3660648bb876391Mark Young        // Pass the call to the driver
9087e90b4d60997446074136292d3660648bb876391Mark Young        icd_term->dispatch.GetPhysicalDeviceExternalFencePropertiesKHR(phys_dev_term->phys_dev, pExternalFenceInfo,
9097e90b4d60997446074136292d3660648bb876391Mark Young                                                                       pExternalFenceProperties);
9107e90b4d60997446074136292d3660648bb876391Mark Young    } else {
9117e90b4d60997446074136292d3660648bb876391Mark Young        // Emulate the call
9127e90b4d60997446074136292d3660648bb876391Mark Young        loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
9137e90b4d60997446074136292d3660648bb876391Mark Young                   "vkGetPhysicalDeviceExternalFencePropertiesKHR: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name);
9147e90b4d60997446074136292d3660648bb876391Mark Young
9157e90b4d60997446074136292d3660648bb876391Mark Young        if (pExternalFenceInfo->pNext != NULL) {
9167e90b4d60997446074136292d3660648bb876391Mark Young            loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
9177e90b4d60997446074136292d3660648bb876391Mark Young                       "vkGetPhysicalDeviceExternalFencePropertiesKHR: Emulation found unrecognized structure type in "
9187e90b4d60997446074136292d3660648bb876391Mark Young                       "pExternalFenceInfo->pNext - this struct will be ignored");
9197e90b4d60997446074136292d3660648bb876391Mark Young        }
9207e90b4d60997446074136292d3660648bb876391Mark Young
9217e90b4d60997446074136292d3660648bb876391Mark Young        // Fill in everything being unsupported
9227e90b4d60997446074136292d3660648bb876391Mark Young        pExternalFenceProperties->exportFromImportedHandleTypes = 0;
9237e90b4d60997446074136292d3660648bb876391Mark Young        pExternalFenceProperties->compatibleHandleTypes = 0;
9247e90b4d60997446074136292d3660648bb876391Mark Young        pExternalFenceProperties->externalFenceFeatures = 0;
9257e90b4d60997446074136292d3660648bb876391Mark Young
9267e90b4d60997446074136292d3660648bb876391Mark Young        if (pExternalFenceProperties->pNext != NULL) {
9277e90b4d60997446074136292d3660648bb876391Mark Young            loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
9287e90b4d60997446074136292d3660648bb876391Mark Young                       "vkGetPhysicalDeviceExternalFencePropertiesKHR: Emulation found unrecognized structure type in "
9297e90b4d60997446074136292d3660648bb876391Mark Young                       "pExternalFenceProperties->pNext - this struct will be ignored");
9307e90b4d60997446074136292d3660648bb876391Mark Young        }
9317e90b4d60997446074136292d3660648bb876391Mark Young    }
9327e90b4d60997446074136292d3660648bb876391Mark Young}
9337e90b4d60997446074136292d3660648bb876391Mark Young
934a3d1258f3424cba230c997d46b08072795e204acLenny Komow// ---- Helper functions
935a3d1258f3424cba230c997d46b08072795e204acLenny Komow
93661ff81af2702610eb1121f3a392f4f73d79a3b28Mark YoungVkResult setupLoaderTrampPhysDevGroups(VkInstance instance) {
93761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    VkResult res = VK_SUCCESS;
93861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    struct loader_instance *inst;
93961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    uint32_t total_count = 0;
94061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    VkPhysicalDeviceGroupPropertiesKHX **new_phys_dev_groups = NULL;
94161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    VkPhysicalDeviceGroupPropertiesKHX *local_phys_dev_groups = NULL;
94261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
94361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    inst = loader_get_instance(instance);
94461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    if (NULL == inst) {
94561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        res = VK_ERROR_INITIALIZATION_FAILED;
94661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        goto out;
94761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
94861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
94961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // Setup the trampoline loader physical devices.  This will actually
95061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // call down and setup the terminator loader physical devices during the
95161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // process.
95261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    VkResult setup_res = setupLoaderTrampPhysDevs(instance);
95361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    if (setup_res != VK_SUCCESS && setup_res != VK_INCOMPLETE) {
95461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        res = setup_res;
95561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        goto out;
95661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
95761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
95861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // Query how many physical device groups there
95961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    res = inst->disp->layer_inst_disp.EnumeratePhysicalDeviceGroupsKHX(instance, &total_count, NULL);
96061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    if (res != VK_SUCCESS) {
96161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
96261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   "setupLoaderTrampPhysDevGroups:  Failed during dispatch call of "
96361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   "\'EnumeratePhysicalDeviceGroupsKHX\' to lower layers or "
96461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   "loader to get count.");
96561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        goto out;
96661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
96761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
96861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // Create an array for the new physical device groups, which will be stored
96961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // in the instance for the trampoline code.
97061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    new_phys_dev_groups = (VkPhysicalDeviceGroupPropertiesKHX **)loader_instance_heap_alloc(
97161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        inst, total_count * sizeof(VkPhysicalDeviceGroupPropertiesKHX *), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
97261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    if (NULL == new_phys_dev_groups) {
97361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
97461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   "setupLoaderTrampPhysDevGroups:  Failed to allocate new physical device"
97561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   " group array of size %d",
97661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   total_count);
97761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        res = VK_ERROR_OUT_OF_HOST_MEMORY;
97861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        goto out;
97961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
98061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    memset(new_phys_dev_groups, 0, total_count * sizeof(VkPhysicalDeviceGroupPropertiesKHX *));
98161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
98261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // Create a temporary array (on the stack) to keep track of the
98361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // returned VkPhysicalDevice values.
98461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    local_phys_dev_groups = loader_stack_alloc(sizeof(VkPhysicalDeviceGroupPropertiesKHX) * total_count);
98561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    if (NULL == local_phys_dev_groups) {
98661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
98761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   "setupLoaderTrampPhysDevGroups:  Failed to allocate local "
98861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   "physical device group array of size %d",
98961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   total_count);
99061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        res = VK_ERROR_OUT_OF_HOST_MEMORY;
99161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        goto out;
99261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
99361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // Initialize the memory to something valid
99461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    memset(local_phys_dev_groups, 0, sizeof(VkPhysicalDeviceGroupPropertiesKHX) * total_count);
99561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    for (uint32_t group = 0; group < total_count; group++) {
99661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        local_phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHX;
99761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        local_phys_dev_groups[group].pNext = NULL;
99861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        local_phys_dev_groups[group].subsetAllocation = false;
99961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
100061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
100161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // Call down and get the content
100261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    res = inst->disp->layer_inst_disp.EnumeratePhysicalDeviceGroupsKHX(instance, &total_count, local_phys_dev_groups);
100361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    if (VK_SUCCESS != res) {
100461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
100561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   "setupLoaderTrampPhysDevGroups:  Failed during dispatch call of "
100661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   "\'EnumeratePhysicalDeviceGroupsKHX\' to lower layers or "
100761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   "loader to get content.");
100861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        goto out;
100961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
101061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
101161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // Replace all the physical device IDs with the proper loader values
101261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    for (uint32_t group = 0; group < total_count; group++) {
101361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        for (uint32_t group_gpu = 0; group_gpu < local_phys_dev_groups[group].physicalDeviceCount; group_gpu++) {
101461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            bool found = false;
101561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            for (uint32_t tramp_gpu = 0; tramp_gpu < inst->phys_dev_count_tramp; tramp_gpu++) {
101661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                if (local_phys_dev_groups[group].physicalDevices[group_gpu] == inst->phys_devs_tramp[tramp_gpu]->phys_dev) {
101761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    local_phys_dev_groups[group].physicalDevices[group_gpu] = (VkPhysicalDevice)inst->phys_devs_tramp[tramp_gpu];
101861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    found = true;
101961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    break;
102061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                }
102161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            }
102261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            if (!found) {
102361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
102461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           "setupLoaderTrampPhysDevGroups:  Failed to find GPU %d in group %d"
102561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           " returned by \'EnumeratePhysicalDeviceGroupsKHX\' in list returned"
102661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           " by \'EnumeratePhysicalDevices\'", group_gpu, group);
102761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                res = VK_ERROR_INITIALIZATION_FAILED;
102861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                goto out;
102961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            }
103061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        }
103161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
103261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
103361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // Copy or create everything to fill the new array of physical device groups
103461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    for (uint32_t new_idx = 0; new_idx < total_count; new_idx++) {
103561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        // Check if this physical device group with the same contents is already in the old buffer
103661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        for (uint32_t old_idx = 0; old_idx < inst->phys_dev_group_count_tramp; old_idx++) {
103761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            if (local_phys_dev_groups[new_idx].physicalDeviceCount == inst->phys_dev_groups_tramp[old_idx]->physicalDeviceCount) {
103861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                bool found_all_gpus = true;
103961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                for (uint32_t old_gpu = 0; old_gpu < inst->phys_dev_groups_tramp[old_idx]->physicalDeviceCount; old_gpu++) {
104061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    bool found_gpu = false;
104161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    for (uint32_t new_gpu = 0; new_gpu < local_phys_dev_groups[new_idx].physicalDeviceCount; new_gpu++) {
104261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                        if (local_phys_dev_groups[new_idx].physicalDevices[new_gpu] == inst->phys_dev_groups_tramp[old_idx]->physicalDevices[old_gpu]) {
104361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                            found_gpu = true;
104461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                            break;
104561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                        }
104661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    }
104761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
104861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    if (!found_gpu) {
104961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                        found_all_gpus = false;
105061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                        break;
105161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    }
105261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                }
105361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                if (!found_all_gpus) {
105461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    continue;
105561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                } else {
105661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    new_phys_dev_groups[new_idx] = inst->phys_dev_groups_tramp[old_idx];
105761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    break;
105861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                }
105961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            }
106061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        }
106161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
106261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        // If this physical device group isn't in the old buffer, create it
106361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        if (NULL == new_phys_dev_groups[new_idx]) {
106461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            new_phys_dev_groups[new_idx] = (VkPhysicalDeviceGroupPropertiesKHX *)loader_instance_heap_alloc(
106561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                inst, sizeof(VkPhysicalDeviceGroupPropertiesKHX), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
106661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            if (NULL == new_phys_dev_groups[new_idx]) {
106761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
106861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           "setupLoaderTrampPhysDevGroups:  Failed to allocate "
106961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           "physical device group trampoline object %d",
107061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           new_idx);
107161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                total_count = new_idx;
107261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                res = VK_ERROR_OUT_OF_HOST_MEMORY;
107361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                goto out;
107461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            }
107561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            memcpy(new_phys_dev_groups[new_idx], &local_phys_dev_groups[new_idx],
107661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   sizeof(VkPhysicalDeviceGroupPropertiesKHX));
107761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        }
107861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
107961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
108061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Youngout:
108161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
108261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    if (VK_SUCCESS != res) {
108361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        if (NULL != new_phys_dev_groups) {
108461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            for (uint32_t i = 0; i < total_count; i++) {
108561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                loader_instance_heap_free(inst, new_phys_dev_groups[i]);
108661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            }
108761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            loader_instance_heap_free(inst, new_phys_dev_groups);
108861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        }
108961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        total_count = 0;
109061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    } else {
109161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        // Free everything that didn't carry over to the new array of
109261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        // physical device groups
109361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        if (NULL != inst->phys_dev_groups_tramp) {
109461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            for (uint32_t i = 0; i < inst->phys_dev_group_count_tramp; i++) {
109561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                bool found = false;
109661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                for (uint32_t j = 0; j < total_count; j++) {
109761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    if (inst->phys_dev_groups_tramp[i] == new_phys_dev_groups[j]) {
109861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                        found = true;
109961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                        break;
110061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    }
110161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                }
110261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                if (!found) {
110361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    loader_instance_heap_free(inst, inst->phys_dev_groups_tramp[i]);
110461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                }
110561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            }
110661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            loader_instance_heap_free(inst, inst->phys_dev_groups_tramp);
110761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        }
110861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
110961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        // Swap in the new physical device group list
111061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        inst->phys_dev_group_count_tramp = total_count;
111161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        inst->phys_dev_groups_tramp = new_phys_dev_groups;
111261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
111361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
111461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    return res;
111561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young}
111661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
111761ff81af2702610eb1121f3a392f4f73d79a3b28Mark YoungVkResult setupLoaderTermPhysDevGroups(struct loader_instance *inst) {
111861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    VkResult res = VK_SUCCESS;
111961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    struct loader_icd_term *icd_term;
112061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    uint32_t total_count = 0;
112161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    uint32_t cur_icd_group_count = 0;
112261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    VkPhysicalDeviceGroupPropertiesKHX **new_phys_dev_groups = NULL;
112361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    VkPhysicalDeviceGroupPropertiesKHX *local_phys_dev_groups = NULL;
112461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
112561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    if (0 == inst->phys_dev_count_term) {
112661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
112761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   "setupLoaderTermPhysDevGroups:  Loader failed to setup physical "
112861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   "device terminator info before calling \'EnumeratePhysicalDeviceGroupsKHX\'.");
112961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        assert(false);
113061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        res = VK_ERROR_INITIALIZATION_FAILED;
113161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        goto out;
113261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
113361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
113461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // For each ICD, query the number of physical device groups, and then get an
113561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // internal value for those physical devices.
113661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    icd_term = inst->icd_terms;
113761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    for (uint32_t icd_idx = 0; NULL != icd_term; icd_term = icd_term->next, icd_idx++) {
113861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        cur_icd_group_count = 0;
113961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        if (NULL == icd_term->dispatch.EnumeratePhysicalDeviceGroupsKHX) {
114061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            // Treat each ICD's GPU as it's own group if the extension isn't supported
114161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            res = icd_term->dispatch.EnumeratePhysicalDevices(icd_term->instance, &cur_icd_group_count, NULL);
114261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            if (res != VK_SUCCESS) {
114361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
114461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           "setupLoaderTermPhysDevGroups:  Failed during dispatch call of "
114561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           "\'EnumeratePhysicalDevices\' to ICD %d to get plain phys dev count.",
114661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           icd_idx);
114761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                goto out;
114861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            }
114961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        } else {
115061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            // Query the actual group info
115161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            res = icd_term->dispatch.EnumeratePhysicalDeviceGroupsKHX(icd_term->instance, &cur_icd_group_count, NULL);
115261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            if (res != VK_SUCCESS) {
115361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
115461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           "setupLoaderTermPhysDevGroups:  Failed during dispatch call of "
115561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           "\'EnumeratePhysicalDeviceGroupsKHX\' to ICD %d to get count.",
115661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           icd_idx);
115761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                goto out;
115861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            }
115961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        }
116061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        total_count += cur_icd_group_count;
116161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
116261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
116361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // Create an array for the new physical device groups, which will be stored
116461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // in the instance for the Terminator code.
116561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    new_phys_dev_groups = (VkPhysicalDeviceGroupPropertiesKHX **)loader_instance_heap_alloc(
116661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        inst, total_count * sizeof(VkPhysicalDeviceGroupPropertiesKHX *), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
116761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    if (NULL == new_phys_dev_groups) {
116861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
116961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   "setupLoaderTermPhysDevGroups:  Failed to allocate new physical device"
117061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   " group array of size %d",
117161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   total_count);
117261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        res = VK_ERROR_OUT_OF_HOST_MEMORY;
117361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        goto out;
117461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
117561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    memset(new_phys_dev_groups, 0, total_count * sizeof(VkPhysicalDeviceGroupPropertiesKHX *));
117661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
117761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // Create a temporary array (on the stack) to keep track of the
117861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // returned VkPhysicalDevice values.
117961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    local_phys_dev_groups = loader_stack_alloc(sizeof(VkPhysicalDeviceGroupPropertiesKHX) * total_count);
118061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    if (NULL == local_phys_dev_groups) {
118161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
118261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   "setupLoaderTermPhysDevGroups:  Failed to allocate local "
118361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   "physical device group array of size %d",
118461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   total_count);
118561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        res = VK_ERROR_OUT_OF_HOST_MEMORY;
118661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        goto out;
118761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
118861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // Initialize the memory to something valid
118961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    memset(local_phys_dev_groups, 0, sizeof(VkPhysicalDeviceGroupPropertiesKHX) * total_count);
119061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    for (uint32_t group = 0; group < total_count; group++) {
119161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        local_phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHX;
119261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        local_phys_dev_groups[group].pNext = NULL;
119361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        local_phys_dev_groups[group].subsetAllocation = false;
119461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
119561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
119661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    cur_icd_group_count = 0;
119761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    icd_term = inst->icd_terms;
119861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    for (uint32_t icd_idx = 0; NULL != icd_term; icd_term = icd_term->next, icd_idx++) {
119961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        uint32_t count_this_time = total_count - cur_icd_group_count;
120061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
120161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        if (NULL == icd_term->dispatch.EnumeratePhysicalDeviceGroupsKHX) {
120261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            VkPhysicalDevice* phys_dev_array = loader_stack_alloc(sizeof(VkPhysicalDevice) * count_this_time);
120361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            if (NULL == phys_dev_array) {
120461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
120561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           "setupLoaderTermPhysDevGroups:  Failed to allocate local "
120661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           "physical device array of size %d",
120761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           count_this_time);
120861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                res = VK_ERROR_OUT_OF_HOST_MEMORY;
120961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                goto out;
121061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            }
121161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
121261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            res = icd_term->dispatch.EnumeratePhysicalDevices(icd_term->instance, &count_this_time, phys_dev_array);
121361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            if (res != VK_SUCCESS) {
121461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
121561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           "setupLoaderTermPhysDevGroups:  Failed during dispatch call of "
121661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           "\'EnumeratePhysicalDevices\' to ICD %d to get plain phys dev count.",
121761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           icd_idx);
121861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                goto out;
121961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            }
122061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
122161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            // Add each GPU as it's own group
122261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            for (uint32_t indiv_gpu = 0; indiv_gpu < count_this_time; indiv_gpu++) {
122361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                local_phys_dev_groups[indiv_gpu + cur_icd_group_count].physicalDeviceCount = 1;
122461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                local_phys_dev_groups[indiv_gpu + cur_icd_group_count].physicalDevices[0] = phys_dev_array[indiv_gpu];
122561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            }
122661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
122761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        } else {
122861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            res = icd_term->dispatch.EnumeratePhysicalDeviceGroupsKHX(icd_term->instance, &count_this_time, &local_phys_dev_groups[cur_icd_group_count]);
122961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            if (VK_SUCCESS != res) {
123061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
123161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           "setupLoaderTermPhysDevGroups:  Failed during dispatch call of "
123261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           "\'EnumeratePhysicalDeviceGroupsKHX\' to ICD %d to get content.",
123361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           icd_idx);
123461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                goto out;
123561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            }
123661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        }
123761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
123861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        cur_icd_group_count += count_this_time;
123961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
124061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
124161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // Replace all the physical device IDs with the proper loader values
124261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    for (uint32_t group = 0; group < total_count; group++) {
124361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        for (uint32_t group_gpu = 0; group_gpu < local_phys_dev_groups[group].physicalDeviceCount; group_gpu++) {
124461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            bool found = false;
124561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            for (uint32_t term_gpu = 0; term_gpu < inst->phys_dev_count_term; term_gpu++) {
124661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                if (local_phys_dev_groups[group].physicalDevices[group_gpu] == inst->phys_devs_term[term_gpu]->phys_dev) {
124761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    local_phys_dev_groups[group].physicalDevices[group_gpu] = (VkPhysicalDevice)inst->phys_devs_term[term_gpu];
124861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    found = true;
124961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    break;
125061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                }
125161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            }
125261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            if (!found) {
125361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
125461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           "setupLoaderTermPhysDevGroups:  Failed to find GPU %d in group %d"
125561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           " returned by \'EnumeratePhysicalDeviceGroupsKHX\' in list returned"
125661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           " by \'EnumeratePhysicalDevices\'", group_gpu, group);
125761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                res = VK_ERROR_INITIALIZATION_FAILED;
125861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                goto out;
125961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            }
126061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        }
126161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
126261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
126361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    // Copy or create everything to fill the new array of physical device groups
126461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    for (uint32_t new_idx = 0; new_idx < total_count; new_idx++) {
126561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        // Check if this physical device group with the same contents is already in the old buffer
126661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        for (uint32_t old_idx = 0; old_idx < inst->phys_dev_group_count_term; old_idx++) {
126761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            if (local_phys_dev_groups[new_idx].physicalDeviceCount == inst->phys_dev_groups_term[old_idx]->physicalDeviceCount) {
126861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                bool found_all_gpus = true;
126961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                for (uint32_t old_gpu = 0; old_gpu < inst->phys_dev_groups_term[old_idx]->physicalDeviceCount; old_gpu++) {
127061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    bool found_gpu = false;
127161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    for (uint32_t new_gpu = 0; new_gpu < local_phys_dev_groups[new_idx].physicalDeviceCount; new_gpu++) {
127261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                        if (local_phys_dev_groups[new_idx].physicalDevices[new_gpu] == inst->phys_dev_groups_term[old_idx]->physicalDevices[old_gpu]) {
127361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                            found_gpu = true;
127461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                            break;
127561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                        }
127661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    }
127761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
127861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    if (!found_gpu) {
127961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                        found_all_gpus = false;
128061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                        break;
128161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    }
128261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                }
128361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                if (!found_all_gpus) {
128461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    continue;
128561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                } else {
128661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    new_phys_dev_groups[new_idx] = inst->phys_dev_groups_term[old_idx];
128761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    break;
128861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                }
128961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            }
129061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        }
129161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
129261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        // If this physical device group isn't in the old buffer, create it
129361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        if (NULL == new_phys_dev_groups[new_idx]) {
129461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            new_phys_dev_groups[new_idx] = (VkPhysicalDeviceGroupPropertiesKHX *)loader_instance_heap_alloc(
129561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                inst, sizeof(VkPhysicalDeviceGroupPropertiesKHX), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
129661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            if (NULL == new_phys_dev_groups[new_idx]) {
129761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
129861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           "setupLoaderTermPhysDevGroups:  Failed to allocate "
129961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           "physical device group Terminator object %d",
130061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                           new_idx);
130161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                total_count = new_idx;
130261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                res = VK_ERROR_OUT_OF_HOST_MEMORY;
130361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                goto out;
130461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            }
130561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            memcpy(new_phys_dev_groups[new_idx], &local_phys_dev_groups[new_idx],
130661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                   sizeof(VkPhysicalDeviceGroupPropertiesKHX));
130761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        }
130861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
130961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
131061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Youngout:
131161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
131261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    if (VK_SUCCESS != res) {
131361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        if (NULL != new_phys_dev_groups) {
131461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            for (uint32_t i = 0; i < total_count; i++) {
131561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                loader_instance_heap_free(inst, new_phys_dev_groups[i]);
131661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            }
131761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            loader_instance_heap_free(inst, new_phys_dev_groups);
131861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        }
131961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        total_count = 0;
132061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    } else {
132161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        // Free everything that didn't carry over to the new array of
132261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        // physical device groups
132361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        if (NULL != inst->phys_dev_groups_term) {
132461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            for (uint32_t i = 0; i < inst->phys_dev_group_count_term; i++) {
132561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                bool found = false;
132661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                for (uint32_t j = 0; j < total_count; j++) {
132761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    if (inst->phys_dev_groups_term[i] == new_phys_dev_groups[j]) {
132861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                        found = true;
132961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                        break;
133061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    }
133161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                }
133261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                if (!found) {
133361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                    loader_instance_heap_free(inst, inst->phys_dev_groups_term[i]);
133461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young                }
133561ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            }
133661ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young            loader_instance_heap_free(inst, inst->phys_dev_groups_term);
133761ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        }
133861ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
133961ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        // Swap in the new physical device group list
134061ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        inst->phys_dev_group_count_term = total_count;
134161ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young        inst->phys_dev_groups_term = new_phys_dev_groups;
134261ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    }
134361ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young
134461ff81af2702610eb1121f3a392f4f73d79a3b28Mark Young    return res;
13457e90b4d60997446074136292d3660648bb876391Mark Young}
1346