2 * Copyright (c) 2016-2020 Arm Limited.
4 * SPDX-License-Identifier: MIT
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 #include <vulkan/vk_layer.h>
30 #include "private_data.hpp"
31 #include "surface_api.hpp"
32 #include "swapchain_api.hpp"
34 #define VK_LAYER_API_VERSION VK_MAKE_VERSION(1, 0, VK_HEADER_VERSION)
39 static const VkLayerProperties global_layer = {
40 "VK_LAYER_window_system_integration",
43 "Window system integration layer",
45 static const VkExtensionProperties device_extension[] = { { VK_KHR_SWAPCHAIN_EXTENSION_NAME,
46 VK_KHR_SWAPCHAIN_SPEC_VERSION } };
47 static const VkExtensionProperties instance_extension[] = { { VK_KHR_SURFACE_EXTENSION_NAME,
48 VK_KHR_SURFACE_SPEC_VERSION } };
50 VKAPI_ATTR VkResult extension_properties(const uint32_t count, const VkExtensionProperties *layer_ext, uint32_t *pCount,
51 VkExtensionProperties *pProp)
55 if (pProp == NULL || layer_ext == NULL)
61 size = *pCount < count ? *pCount : count;
62 memcpy(pProp, layer_ext, size * sizeof(VkExtensionProperties));
72 VKAPI_ATTR VkResult layer_properties(const uint32_t count, const VkLayerProperties *layer_prop, uint32_t *pCount,
73 VkLayerProperties *pProp)
77 if (pProp == NULL || layer_prop == NULL)
83 size = *pCount < count ? *pCount : count;
84 memcpy(pProp, layer_prop, size * sizeof(VkLayerProperties));
94 VKAPI_ATTR VkLayerInstanceCreateInfo *get_chain_info(const VkInstanceCreateInfo *pCreateInfo, VkLayerFunction func)
96 VkLayerInstanceCreateInfo *chain_info = (VkLayerInstanceCreateInfo *)pCreateInfo->pNext;
98 !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO && chain_info->function == func))
100 chain_info = (VkLayerInstanceCreateInfo *)chain_info->pNext;
106 VKAPI_ATTR VkLayerDeviceCreateInfo *get_chain_info(const VkDeviceCreateInfo *pCreateInfo, VkLayerFunction func)
108 VkLayerDeviceCreateInfo *chain_info = (VkLayerDeviceCreateInfo *)pCreateInfo->pNext;
110 !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO && chain_info->function == func))
112 chain_info = (VkLayerDeviceCreateInfo *)chain_info->pNext;
119 * This is where we get our initialisation and construct our dispatch table. All layers must implement the function.
120 * If you wish to intercept any device functions at all you need to implement vkCreateDevice.
122 VKAPI_ATTR VkResult create_instance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
123 VkInstance *pInstance)
125 VkLayerInstanceCreateInfo *layerCreateInfo = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
126 PFN_vkSetInstanceLoaderData loader_callback =
127 get_chain_info(pCreateInfo, VK_LOADER_DATA_CALLBACK)->u.pfnSetInstanceLoaderData;
129 if (nullptr == layerCreateInfo || nullptr == layerCreateInfo->u.pLayerInfo)
131 return VK_ERROR_INITIALIZATION_FAILED;
134 /* Retrieve the vkGetInstanceProcAddr and the vkCreateInstance function pointers for the next layer in the chain. */
135 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
136 PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(nullptr, "vkCreateInstance");
137 if (nullptr == fpCreateInstance)
139 return VK_ERROR_INITIALIZATION_FAILED;
142 /* Advance the link info for the next element on the chain. */
143 layerCreateInfo->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext;
145 /* Now call create instance on the chain further down the list. */
146 VkResult ret = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
148 instance_private_data::create(*pInstance, fpGetInstanceProcAddr, loader_callback);
152 VKAPI_ATTR VkResult create_device(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
153 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice)
155 VkLayerDeviceCreateInfo *layerCreateInfo = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
156 PFN_vkSetDeviceLoaderData loader_callback =
157 get_chain_info(pCreateInfo, VK_LOADER_DATA_CALLBACK)->u.pfnSetDeviceLoaderData;
159 if (nullptr == layerCreateInfo || nullptr == layerCreateInfo->u.pLayerInfo)
161 return VK_ERROR_INITIALIZATION_FAILED;
164 /* Retrieve the vkGetDeviceProcAddr and the vkCreateDevice function pointers for the next layer in the chain. */
165 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
166 PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = layerCreateInfo->u.pLayerInfo->pfnNextGetDeviceProcAddr;
167 PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateDevice");
168 if (nullptr == fpCreateDevice)
170 return VK_ERROR_INITIALIZATION_FAILED;
173 /* Advance the link info for the next element on the chain. */
174 layerCreateInfo->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext;
176 /* Now call create device on the chain further down the list. */
177 VkResult ret = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
179 device_private_data::create(*pDevice, fpGetDeviceProcAddr, physicalDevice, loader_callback);
184 } /* namespace layer */
188 VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI_CALL
189 wsi_layer_vkGetDeviceProcAddr(VkDevice device, const char *funcName);
191 VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
192 wsi_layer_vkGetInstanceProcAddr(VkInstance instance, const char *funcName);
194 /* Clean up the dispatch table for this instance. */
195 VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
196 wsi_layer_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator)
199 layer::instance_private_data::get(layer::get_key(instance))
200 .disp.DestroyInstance(instance, pAllocator);
202 layer::instance_private_data::destroy(instance);
205 VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
206 wsi_layer_vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator)
208 layer::device_private_data::destroy(device);
211 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
212 wsi_layer_vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance)
214 return layer::create_instance(pCreateInfo, pAllocator, pInstance);
217 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
218 wsi_layer_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
219 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice)
221 return layer::create_device(physicalDevice, pCreateInfo, pAllocator, pDevice);
224 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
225 vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface *pVersionStruct)
227 assert(pVersionStruct);
228 assert(pVersionStruct->sType == LAYER_NEGOTIATE_INTERFACE_STRUCT);
230 /* 2 is the minimum interface version which would utilize this function. */
231 assert(pVersionStruct->loaderLayerInterfaceVersion >= 2);
233 /* Set our requested interface version. Set to 2 for now to separate us from newer versions. */
234 pVersionStruct->loaderLayerInterfaceVersion = 2;
236 /* Fill in struct values. */
237 pVersionStruct->pfnGetInstanceProcAddr = &wsi_layer_vkGetInstanceProcAddr;
238 pVersionStruct->pfnGetDeviceProcAddr = &wsi_layer_vkGetDeviceProcAddr;
239 pVersionStruct->pfnGetPhysicalDeviceProcAddr = nullptr;
244 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
245 wsi_layer_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName,
246 uint32_t *pCount, VkExtensionProperties *pProperties)
248 if (pLayerName && !strcmp(pLayerName, layer::global_layer.layerName))
249 return layer::extension_properties(1, layer::device_extension, pCount, pProperties);
251 assert(physicalDevice);
252 return layer::instance_private_data::get(layer::get_key(physicalDevice))
253 .disp.EnumerateDeviceExtensionProperties(physicalDevice, pLayerName, pCount, pProperties);
256 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
257 wsi_layer_vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties)
259 if (pLayerName && !strcmp(pLayerName, layer::global_layer.layerName))
260 return layer::extension_properties(1, layer::instance_extension, pCount, pProperties);
262 return VK_ERROR_LAYER_NOT_PRESENT;
265 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
266 wsi_layer_vkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties)
268 return layer::layer_properties(1, &layer::global_layer, pCount, pProperties);
271 #define GET_PROC_ADDR(func) \
272 if (!strcmp(funcName, #func)) \
273 return (PFN_vkVoidFunction)&wsi_layer_##func;
275 VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI_CALL
276 wsi_layer_vkGetDeviceProcAddr(VkDevice device, const char *funcName)
278 GET_PROC_ADDR(vkCreateSwapchainKHR);
279 GET_PROC_ADDR(vkDestroySwapchainKHR);
280 GET_PROC_ADDR(vkGetSwapchainImagesKHR);
281 GET_PROC_ADDR(vkAcquireNextImageKHR);
282 GET_PROC_ADDR(vkQueuePresentKHR);
284 return layer::device_private_data::get(layer::get_key(device)).disp.GetDeviceProcAddr(device, funcName);
287 VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
288 wsi_layer_vkGetInstanceProcAddr(VkInstance instance, const char *funcName)
290 GET_PROC_ADDR(vkGetDeviceProcAddr);
291 GET_PROC_ADDR(vkGetInstanceProcAddr);
292 GET_PROC_ADDR(vkCreateInstance);
293 GET_PROC_ADDR(vkDestroyInstance);
294 GET_PROC_ADDR(vkCreateDevice);
295 GET_PROC_ADDR(vkDestroyDevice);
296 GET_PROC_ADDR(vkGetPhysicalDeviceSurfaceSupportKHR);
297 GET_PROC_ADDR(vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
298 GET_PROC_ADDR(vkGetPhysicalDeviceSurfaceFormatsKHR);
299 GET_PROC_ADDR(vkGetPhysicalDeviceSurfacePresentModesKHR);
300 GET_PROC_ADDR(vkEnumerateDeviceExtensionProperties);
301 GET_PROC_ADDR(vkEnumerateInstanceExtensionProperties);
302 GET_PROC_ADDR(vkEnumerateInstanceLayerProperties);
304 return layer::instance_private_data::get(layer::get_key(instance)).disp.GetInstanceProcAddr(instance, funcName);