1/*
2 * Copyright 2015-2023 The Khronos Group Inc.
3 * Copyright 2015-2023 Valve Corporation
4 * Copyright 2015-2023 LunarG, Inc.
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8#pragma once
9
10/* Need to define dispatch table
11 * Core struct can then have ptr to dispatch table at the top
12 * Along with object ptrs for current and next OBJ
13 */
14
15#include "vulkan_core.h"
16
17#define MAX_NUM_UNKNOWN_EXTS 250
18
19 // Loader-Layer version negotiation API.  Versions add the following features:
20 //   Versions 0/1 - Initial.  Doesn't support vk_layerGetPhysicalDeviceProcAddr
21 //                  or vk_icdNegotiateLoaderLayerInterfaceVersion.
22 //   Version 2    - Add support for vk_layerGetPhysicalDeviceProcAddr and
23 //                  vk_icdNegotiateLoaderLayerInterfaceVersion.
24#define CURRENT_LOADER_LAYER_INTERFACE_VERSION 2
25#define MIN_SUPPORTED_LOADER_LAYER_INTERFACE_VERSION 1
26
27#define VK_CURRENT_CHAIN_VERSION 1
28
29// Typedef for use in the interfaces below
30typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName);
31
32// Version negotiation values
33typedef enum VkNegotiateLayerStructType {
34    LAYER_NEGOTIATE_UNINTIALIZED = 0,
35    LAYER_NEGOTIATE_INTERFACE_STRUCT = 1,
36} VkNegotiateLayerStructType;
37
38// Version negotiation structures
39typedef struct VkNegotiateLayerInterface {
40    VkNegotiateLayerStructType sType;
41    void *pNext;
42    uint32_t loaderLayerInterfaceVersion;
43    PFN_vkGetInstanceProcAddr pfnGetInstanceProcAddr;
44    PFN_vkGetDeviceProcAddr pfnGetDeviceProcAddr;
45    PFN_GetPhysicalDeviceProcAddr pfnGetPhysicalDeviceProcAddr;
46} VkNegotiateLayerInterface;
47
48// Version negotiation functions
49typedef VkResult (VKAPI_PTR *PFN_vkNegotiateLoaderLayerInterfaceVersion)(VkNegotiateLayerInterface *pVersionStruct);
50
51// Function prototype for unknown physical device extension command
52typedef VkResult(VKAPI_PTR *PFN_PhysDevExt)(VkPhysicalDevice phys_device);
53
54// ------------------------------------------------------------------------------------------------
55// CreateInstance and CreateDevice support structures
56
57/* Sub type of structure for instance and device loader ext of CreateInfo.
58 * When sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO
59 * or sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO
60 * then VkLayerFunction indicates struct type pointed to by pNext
61 */
62typedef enum VkLayerFunction_ {
63    VK_LAYER_LINK_INFO = 0,
64    VK_LOADER_DATA_CALLBACK = 1,
65    VK_LOADER_LAYER_CREATE_DEVICE_CALLBACK = 2,
66    VK_LOADER_FEATURES = 3,
67} VkLayerFunction;
68
69typedef struct VkLayerInstanceLink_ {
70    struct VkLayerInstanceLink_ *pNext;
71    PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr;
72    PFN_GetPhysicalDeviceProcAddr pfnNextGetPhysicalDeviceProcAddr;
73} VkLayerInstanceLink;
74
75/*
76 * When creating the device chain the loader needs to pass
77 * down information about it's device structure needed at
78 * the end of the chain. Passing the data via the
79 * VkLayerDeviceInfo avoids issues with finding the
80 * exact instance being used.
81 */
82typedef struct VkLayerDeviceInfo_ {
83    void *device_info;
84    PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr;
85} VkLayerDeviceInfo;
86
87typedef VkResult (VKAPI_PTR *PFN_vkSetInstanceLoaderData)(VkInstance instance,
88        void *object);
89typedef VkResult (VKAPI_PTR *PFN_vkSetDeviceLoaderData)(VkDevice device,
90        void *object);
91typedef VkResult (VKAPI_PTR *PFN_vkLayerCreateDevice)(VkInstance instance, VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
92						      const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, PFN_vkGetInstanceProcAddr layerGIPA, PFN_vkGetDeviceProcAddr *nextGDPA);
93typedef void (VKAPI_PTR *PFN_vkLayerDestroyDevice)(VkDevice physicalDevice, const VkAllocationCallbacks *pAllocator, PFN_vkDestroyDevice destroyFunction);
94
95typedef enum VkLoaderFeastureFlagBits {
96    VK_LOADER_FEATURE_PHYSICAL_DEVICE_SORTING = 0x00000001,
97} VkLoaderFlagBits;
98typedef VkFlags VkLoaderFeatureFlags;
99
100typedef struct {
101    VkStructureType sType; // VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO
102    const void *pNext;
103    VkLayerFunction function;
104    union {
105        VkLayerInstanceLink *pLayerInfo;
106        PFN_vkSetInstanceLoaderData pfnSetInstanceLoaderData;
107        struct {
108	        PFN_vkLayerCreateDevice pfnLayerCreateDevice;
109	        PFN_vkLayerDestroyDevice pfnLayerDestroyDevice;
110	    } layerDevice;
111        VkLoaderFeatureFlags loaderFeatures;
112    } u;
113} VkLayerInstanceCreateInfo;
114
115typedef struct VkLayerDeviceLink_ {
116    struct VkLayerDeviceLink_ *pNext;
117    PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr;
118    PFN_vkGetDeviceProcAddr pfnNextGetDeviceProcAddr;
119} VkLayerDeviceLink;
120
121typedef struct {
122    VkStructureType sType; // VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO
123    const void *pNext;
124    VkLayerFunction function;
125    union {
126        VkLayerDeviceLink *pLayerInfo;
127        PFN_vkSetDeviceLoaderData pfnSetDeviceLoaderData;
128    } u;
129} VkLayerDeviceCreateInfo;
130
131#ifdef __cplusplus
132extern "C" {
133#endif
134
135VKAPI_ATTR VkResult VKAPI_CALL vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface *pVersionStruct);
136
137typedef enum VkChainType {
138    VK_CHAIN_TYPE_UNKNOWN = 0,
139    VK_CHAIN_TYPE_ENUMERATE_INSTANCE_EXTENSION_PROPERTIES = 1,
140    VK_CHAIN_TYPE_ENUMERATE_INSTANCE_LAYER_PROPERTIES = 2,
141    VK_CHAIN_TYPE_ENUMERATE_INSTANCE_VERSION = 3,
142} VkChainType;
143
144typedef struct VkChainHeader {
145    VkChainType type;
146    uint32_t version;
147    uint32_t size;
148} VkChainHeader;
149
150typedef struct VkEnumerateInstanceExtensionPropertiesChain {
151    VkChainHeader header;
152    VkResult(VKAPI_PTR *pfnNextLayer)(const struct VkEnumerateInstanceExtensionPropertiesChain *, const char *, uint32_t *,
153                                      VkExtensionProperties *);
154    const struct VkEnumerateInstanceExtensionPropertiesChain *pNextLink;
155
156#if defined(__cplusplus)
157    inline VkResult CallDown(const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties) const {
158        return pfnNextLayer(pNextLink, pLayerName, pPropertyCount, pProperties);
159    }
160#endif
161} VkEnumerateInstanceExtensionPropertiesChain;
162
163typedef struct VkEnumerateInstanceLayerPropertiesChain {
164    VkChainHeader header;
165    VkResult(VKAPI_PTR *pfnNextLayer)(const struct VkEnumerateInstanceLayerPropertiesChain *, uint32_t *, VkLayerProperties *);
166    const struct VkEnumerateInstanceLayerPropertiesChain *pNextLink;
167
168#if defined(__cplusplus)
169    inline VkResult CallDown(uint32_t *pPropertyCount, VkLayerProperties *pProperties) const {
170        return pfnNextLayer(pNextLink, pPropertyCount, pProperties);
171    }
172#endif
173} VkEnumerateInstanceLayerPropertiesChain;
174
175typedef struct VkEnumerateInstanceVersionChain {
176    VkChainHeader header;
177    VkResult(VKAPI_PTR *pfnNextLayer)(const struct VkEnumerateInstanceVersionChain *, uint32_t *);
178    const struct VkEnumerateInstanceVersionChain *pNextLink;
179
180#if defined(__cplusplus)
181    inline VkResult CallDown(uint32_t *pApiVersion) const {
182        return pfnNextLayer(pNextLink, pApiVersion);
183    }
184#endif
185} VkEnumerateInstanceVersionChain;
186
187#ifdef __cplusplus
188}
189#endif
190