d2cb34f4e5226a300bd01cb39c198286449bfce1
[platform/core/uifw/vulkan-wsi-tizen.git] / layer / layer.cpp
1 /*
2  * Copyright (c) 2016-2020 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
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:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
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
22  * SOFTWARE.
23  */
24
25 #include <cassert>
26 #include <cstdio>
27 #include <cstring>
28 #include <vulkan/vk_layer.h>
29
30 #include "private_data.hpp"
31 #include "surface_api.hpp"
32 #include "swapchain_api.hpp"
33
34 #define VK_LAYER_API_VERSION VK_MAKE_VERSION(1, 0, VK_HEADER_VERSION)
35
36 namespace layer
37 {
38
39 static const VkLayerProperties global_layer = {
40    "VK_LAYER_window_system_integration",
41    VK_LAYER_API_VERSION,
42    1,
43    "Window system integration layer",
44 };
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 } };
49
50 VKAPI_ATTR VkResult extension_properties(const uint32_t count, const VkExtensionProperties *layer_ext, uint32_t *pCount,
51                                          VkExtensionProperties *pProp)
52 {
53    uint32_t size;
54
55    if (pProp == NULL || layer_ext == NULL)
56    {
57       *pCount = count;
58       return VK_SUCCESS;
59    }
60
61    size = *pCount < count ? *pCount : count;
62    memcpy(pProp, layer_ext, size * sizeof(VkExtensionProperties));
63    *pCount = size;
64    if (size < count)
65    {
66       return VK_INCOMPLETE;
67    }
68
69    return VK_SUCCESS;
70 }
71
72 VKAPI_ATTR VkResult layer_properties(const uint32_t count, const VkLayerProperties *layer_prop, uint32_t *pCount,
73                                      VkLayerProperties *pProp)
74 {
75    uint32_t size;
76
77    if (pProp == NULL || layer_prop == NULL)
78    {
79       *pCount = count;
80       return VK_SUCCESS;
81    }
82
83    size = *pCount < count ? *pCount : count;
84    memcpy(pProp, layer_prop, size * sizeof(VkLayerProperties));
85    *pCount = size;
86    if (size < count)
87    {
88       return VK_INCOMPLETE;
89    }
90
91    return VK_SUCCESS;
92 }
93
94 VKAPI_ATTR VkLayerInstanceCreateInfo *get_chain_info(const VkInstanceCreateInfo *pCreateInfo, VkLayerFunction func)
95 {
96    VkLayerInstanceCreateInfo *chain_info = (VkLayerInstanceCreateInfo *)pCreateInfo->pNext;
97    while (chain_info &&
98           !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO && chain_info->function == func))
99    {
100       chain_info = (VkLayerInstanceCreateInfo *)chain_info->pNext;
101    }
102
103    return chain_info;
104 }
105
106 VKAPI_ATTR VkLayerDeviceCreateInfo *get_chain_info(const VkDeviceCreateInfo *pCreateInfo, VkLayerFunction func)
107 {
108    VkLayerDeviceCreateInfo *chain_info = (VkLayerDeviceCreateInfo *)pCreateInfo->pNext;
109    while (chain_info &&
110           !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO && chain_info->function == func))
111    {
112       chain_info = (VkLayerDeviceCreateInfo *)chain_info->pNext;
113    }
114
115    return chain_info;
116 }
117
118 /*
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.
121  */
122 VKAPI_ATTR VkResult create_instance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
123                                     VkInstance *pInstance)
124 {
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;
128
129    if (nullptr == layerCreateInfo || nullptr == layerCreateInfo->u.pLayerInfo)
130    {
131       return VK_ERROR_INITIALIZATION_FAILED;
132    }
133
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)
138    {
139       return VK_ERROR_INITIALIZATION_FAILED;
140    }
141
142    /* Advance the link info for the next element on the chain. */
143    layerCreateInfo->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext;
144
145    /* Now call create instance on the chain further down the list. */
146    VkResult ret = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
147
148    instance_private_data::create(*pInstance, fpGetInstanceProcAddr, loader_callback);
149    return ret;
150 }
151
152 VKAPI_ATTR VkResult create_device(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
153                                   const VkAllocationCallbacks *pAllocator, VkDevice *pDevice)
154 {
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;
158
159    if (nullptr == layerCreateInfo || nullptr == layerCreateInfo->u.pLayerInfo)
160    {
161       return VK_ERROR_INITIALIZATION_FAILED;
162    }
163
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)
169    {
170       return VK_ERROR_INITIALIZATION_FAILED;
171    }
172
173    /* Advance the link info for the next element on the chain. */
174    layerCreateInfo->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext;
175
176    /* Now call create device on the chain further down the list. */
177    VkResult ret = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
178
179    device_private_data::create(*pDevice, fpGetDeviceProcAddr, physicalDevice, loader_callback);
180
181    return ret;
182 }
183
184 } /* namespace layer */
185
186 extern "C"
187 {
188    VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI_CALL
189    wsi_layer_vkGetDeviceProcAddr(VkDevice device, const char *funcName);
190
191    VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
192    wsi_layer_vkGetInstanceProcAddr(VkInstance instance, const char *funcName);
193
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)
197    {
198       assert(instance);
199       layer::instance_private_data::get(layer::get_key(instance))
200       .disp.DestroyInstance(instance, pAllocator);
201
202       layer::instance_private_data::destroy(instance);
203    }
204
205    VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
206    wsi_layer_vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator)
207    {
208       layer::device_private_data::destroy(device);
209    }
210
211    VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
212    wsi_layer_vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance)
213    {
214       return layer::create_instance(pCreateInfo, pAllocator, pInstance);
215    }
216
217    VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
218    wsi_layer_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
219                             const VkAllocationCallbacks *pAllocator, VkDevice *pDevice)
220    {
221       return layer::create_device(physicalDevice, pCreateInfo, pAllocator, pDevice);
222    }
223
224    VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
225    vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface *pVersionStruct)
226    {
227       assert(pVersionStruct);
228       assert(pVersionStruct->sType == LAYER_NEGOTIATE_INTERFACE_STRUCT);
229
230       /* 2 is the minimum interface version which would utilize this function. */
231       assert(pVersionStruct->loaderLayerInterfaceVersion >= 2);
232
233       /* Set our requested interface version. Set to 2 for now to separate us from newer versions. */
234       pVersionStruct->loaderLayerInterfaceVersion = 2;
235
236       /* Fill in struct values. */
237       pVersionStruct->pfnGetInstanceProcAddr = &wsi_layer_vkGetInstanceProcAddr;
238       pVersionStruct->pfnGetDeviceProcAddr = &wsi_layer_vkGetDeviceProcAddr;
239       pVersionStruct->pfnGetPhysicalDeviceProcAddr = nullptr;
240
241       return VK_SUCCESS;
242    }
243
244    VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
245    wsi_layer_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName,
246                                                   uint32_t *pCount, VkExtensionProperties *pProperties)
247    {
248       if (pLayerName && !strcmp(pLayerName, layer::global_layer.layerName))
249          return layer::extension_properties(1, layer::device_extension, pCount, pProperties);
250
251       assert(physicalDevice);
252       return layer::instance_private_data::get(layer::get_key(physicalDevice))
253          .disp.EnumerateDeviceExtensionProperties(physicalDevice, pLayerName, pCount, pProperties);
254    }
255
256    VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
257    wsi_layer_vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties)
258    {
259       if (pLayerName && !strcmp(pLayerName, layer::global_layer.layerName))
260          return layer::extension_properties(1, layer::instance_extension, pCount, pProperties);
261
262       return VK_ERROR_LAYER_NOT_PRESENT;
263    }
264
265    VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
266    wsi_layer_vkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties)
267    {
268       return layer::layer_properties(1, &layer::global_layer, pCount, pProperties);
269    }
270
271    #define GET_PROC_ADDR(func)      \
272    if (!strcmp(funcName, #func)) \
273       return (PFN_vkVoidFunction)&wsi_layer_##func;
274
275    VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI_CALL
276    wsi_layer_vkGetDeviceProcAddr(VkDevice device, const char *funcName)
277    {
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);
283
284       return layer::device_private_data::get(layer::get_key(device)).disp.GetDeviceProcAddr(device, funcName);
285    }
286
287    VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
288    wsi_layer_vkGetInstanceProcAddr(VkInstance instance, const char *funcName)
289    {
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);
303
304       return layer::instance_private_data::get(layer::get_key(instance)).disp.GetInstanceProcAddr(instance, funcName);
305    }
306 } /* extern "C" */