layer: improve how layer handles Vulkan extensions
[platform/core/uifw/vulkan-wsi-tizen.git] / layer / layer.cpp
1 /*
2  * Copyright (c) 2016-2021 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
29 #include <vulkan/vk_layer.h>
30
31 #include "private_data.hpp"
32 #include "surface_api.hpp"
33 #include "swapchain_api.hpp"
34 #include "util/extension_list.hpp"
35 #include "util/custom_allocator.hpp"
36 #include "wsi/wsi_factory.hpp"
37
38 #define VK_LAYER_API_VERSION VK_MAKE_VERSION(1, 0, VK_HEADER_VERSION)
39
40 namespace layer
41 {
42
43 static const VkLayerProperties global_layer = {
44    "VK_LAYER_window_system_integration", VK_LAYER_API_VERSION, 1, "Window system integration layer",
45 };
46 static const VkExtensionProperties device_extension[] = { { VK_KHR_SWAPCHAIN_EXTENSION_NAME,
47                                                             VK_KHR_SWAPCHAIN_SPEC_VERSION } };
48 static const VkExtensionProperties instance_extension[] = { { VK_KHR_SURFACE_EXTENSION_NAME,
49                                                               VK_KHR_SURFACE_SPEC_VERSION } };
50
51 VKAPI_ATTR VkResult extension_properties(const uint32_t count, const VkExtensionProperties *layer_ext, uint32_t *pCount,
52                                          VkExtensionProperties *pProp)
53 {
54    uint32_t size;
55
56    if (pProp == NULL || layer_ext == NULL)
57    {
58       *pCount = count;
59       return VK_SUCCESS;
60    }
61
62    size = *pCount < count ? *pCount : count;
63    memcpy(pProp, layer_ext, size * sizeof(VkExtensionProperties));
64    *pCount = size;
65    if (size < count)
66    {
67       return VK_INCOMPLETE;
68    }
69
70    return VK_SUCCESS;
71 }
72
73 VKAPI_ATTR VkResult layer_properties(const uint32_t count, const VkLayerProperties *layer_prop, uint32_t *pCount,
74                                      VkLayerProperties *pProp)
75 {
76    uint32_t size;
77
78    if (pProp == NULL || layer_prop == NULL)
79    {
80       *pCount = count;
81       return VK_SUCCESS;
82    }
83
84    size = *pCount < count ? *pCount : count;
85    memcpy(pProp, layer_prop, size * sizeof(VkLayerProperties));
86    *pCount = size;
87    if (size < count)
88    {
89       return VK_INCOMPLETE;
90    }
91
92    return VK_SUCCESS;
93 }
94
95 VKAPI_ATTR VkLayerInstanceCreateInfo *get_chain_info(const VkInstanceCreateInfo *pCreateInfo, VkLayerFunction func)
96 {
97    VkLayerInstanceCreateInfo *chain_info = (VkLayerInstanceCreateInfo *)pCreateInfo->pNext;
98    while (chain_info &&
99           !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO && chain_info->function == func))
100    {
101       chain_info = (VkLayerInstanceCreateInfo *)chain_info->pNext;
102    }
103
104    return chain_info;
105 }
106
107 VKAPI_ATTR VkLayerDeviceCreateInfo *get_chain_info(const VkDeviceCreateInfo *pCreateInfo, VkLayerFunction func)
108 {
109    VkLayerDeviceCreateInfo *chain_info = (VkLayerDeviceCreateInfo *)pCreateInfo->pNext;
110    while (chain_info &&
111           !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO && chain_info->function == func))
112    {
113       chain_info = (VkLayerDeviceCreateInfo *)chain_info->pNext;
114    }
115
116    return chain_info;
117 }
118
119 /* This is where the layer is initialised and the instance dispatch table is constructed. */
120 VKAPI_ATTR VkResult create_instance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
121                                     VkInstance *pInstance)
122 {
123    VkLayerInstanceCreateInfo *layerCreateInfo = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
124    PFN_vkSetInstanceLoaderData loader_callback =
125       get_chain_info(pCreateInfo, VK_LOADER_DATA_CALLBACK)->u.pfnSetInstanceLoaderData;
126
127    if (nullptr == layerCreateInfo || nullptr == layerCreateInfo->u.pLayerInfo)
128    {
129       return VK_ERROR_INITIALIZATION_FAILED;
130    }
131
132    PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
133
134    PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(nullptr, "vkCreateInstance");
135    if (nullptr == fpCreateInstance)
136    {
137       return VK_ERROR_INITIALIZATION_FAILED;
138    }
139
140    /* Advance the link info for the next element on the chain. */
141    layerCreateInfo->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext;
142
143    /* The layer needs some Vulkan 1.1 functionality in order to operate correctly.
144     * We thus change the application info to require this API version, if necessary.
145     * This may have consequences for ICDs whose behaviour depends on apiVersion.
146     */
147    const uint32_t minimum_required_vulkan_version = VK_API_VERSION_1_1;
148    VkApplicationInfo modified_app_info{};
149    if (nullptr != pCreateInfo->pApplicationInfo)
150    {
151       modified_app_info = *pCreateInfo->pApplicationInfo;
152       if (modified_app_info.apiVersion < minimum_required_vulkan_version)
153       {
154          modified_app_info.apiVersion = minimum_required_vulkan_version;
155       }
156    }
157    else
158    {
159       modified_app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
160       modified_app_info.apiVersion = minimum_required_vulkan_version;
161    }
162
163    VkInstanceCreateInfo modified_info = *pCreateInfo;
164    modified_info.pApplicationInfo = &modified_app_info;
165
166    /* Now call create instance on the chain further down the list.
167     * Note that we do not remove the extensions that the layer supports from modified_info.ppEnabledExtensionNames.
168     * Layers have to abide the rule that vkCreateInstance must not generate an error for unrecognized extension names.
169     * Also, the loader filters the extension list to ensure that ICDs do not see extensions that they do not support.
170     */
171    VkResult result;
172    result = fpCreateInstance(&modified_info, pAllocator, pInstance);
173    if (result != VK_SUCCESS)
174    {
175       return result;
176    }
177
178    instance_dispatch_table table;
179    result = table.populate(*pInstance, fpGetInstanceProcAddr);
180    if (result != VK_SUCCESS)
181    {
182       return result;
183    }
184
185    /* Find all the platforms that the layer can handle based on pCreateInfo->ppEnabledExtensionNames. */
186    auto layer_platforms_to_enable = wsi::find_enabled_layer_platforms(pCreateInfo);
187
188    std::unique_ptr<instance_private_data> inst_data{
189       new instance_private_data{table, loader_callback, layer_platforms_to_enable}};
190    instance_private_data::set(*pInstance, std::move(inst_data));
191    return VK_SUCCESS;
192 }
193
194 VKAPI_ATTR VkResult create_device(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
195                                   const VkAllocationCallbacks *pAllocator, VkDevice *pDevice)
196 {
197    VkLayerDeviceCreateInfo *layerCreateInfo = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
198    PFN_vkSetDeviceLoaderData loader_callback =
199       get_chain_info(pCreateInfo, VK_LOADER_DATA_CALLBACK)->u.pfnSetDeviceLoaderData;
200
201    if (nullptr == layerCreateInfo || nullptr == layerCreateInfo->u.pLayerInfo)
202    {
203       return VK_ERROR_INITIALIZATION_FAILED;
204    }
205
206    /* Retrieve the vkGetDeviceProcAddr and the vkCreateDevice function pointers for the next layer in the chain. */
207    PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
208    PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = layerCreateInfo->u.pLayerInfo->pfnNextGetDeviceProcAddr;
209    PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateDevice");
210    if (nullptr == fpCreateDevice)
211    {
212       return VK_ERROR_INITIALIZATION_FAILED;
213    }
214
215    /* Advance the link info for the next element on the chain. */
216    layerCreateInfo->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext;
217
218    /* Copy the extension to a util::extension_list. */
219    util::allocator allocator{pAllocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND};
220    util::extension_list enabled_extensions{allocator};
221    VkResult result;
222    result = enabled_extensions.add(pCreateInfo->ppEnabledExtensionNames, pCreateInfo->enabledExtensionCount);
223    if (result != VK_SUCCESS)
224    {
225       return result;
226    }
227
228    /* Add the extensions required by the platforms that are being enabled in the layer. */
229    auto &inst_data = instance_private_data::get(physicalDevice);
230    const util::wsi_platform_set& enabled_platforms = inst_data.get_enabled_platforms();
231    result = wsi::add_extensions_required_by_layer(physicalDevice, enabled_platforms, enabled_extensions);
232    if (result != VK_SUCCESS)
233    {
234       return result;
235    }
236
237    util::vector<const char *> modified_enabled_extensions{allocator};
238    if (!enabled_extensions.get_extension_strings(modified_enabled_extensions))
239    {
240       return VK_ERROR_OUT_OF_HOST_MEMORY;
241    }
242
243    /* Now call create device on the chain further down the list. */
244    VkDeviceCreateInfo modified_info = *pCreateInfo;
245    modified_info.ppEnabledExtensionNames = modified_enabled_extensions.data();
246    modified_info.enabledExtensionCount = modified_enabled_extensions.size();
247    result = fpCreateDevice(physicalDevice, &modified_info, pAllocator, pDevice);
248    if (result != VK_SUCCESS)
249    {
250       return result;
251    }
252
253    device_dispatch_table table;
254    result = table.populate(*pDevice, fpGetDeviceProcAddr);
255    if (result != VK_SUCCESS)
256    {
257       return result;
258    }
259
260    std::unique_ptr<device_private_data> device{new device_private_data{inst_data, physicalDevice, *pDevice,
261                                                                        table, loader_callback}};
262    device_private_data::set(*pDevice, std::move(device));
263    return VK_SUCCESS;
264 }
265
266 } /* namespace layer */
267
268 extern "C" {
269 VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI_CALL wsi_layer_vkGetDeviceProcAddr(VkDevice device, const char *funcName);
270
271 VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL wsi_layer_vkGetInstanceProcAddr(VkInstance instance,
272                                                                                          const char *funcName);
273
274 /* Clean up the dispatch table for this instance. */
275 VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL wsi_layer_vkDestroyInstance(VkInstance instance,
276                                                                        const VkAllocationCallbacks *pAllocator)
277 {
278    assert(instance);
279    layer::instance_private_data::get(instance).disp.DestroyInstance(instance, pAllocator);
280    layer::instance_private_data::destroy(instance);
281 }
282
283 VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL wsi_layer_vkDestroyDevice(VkDevice device,
284                                                                      const VkAllocationCallbacks *pAllocator)
285 {
286    layer::device_private_data::destroy(device);
287 }
288
289 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL wsi_layer_vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
290                                                                           const VkAllocationCallbacks *pAllocator,
291                                                                           VkInstance *pInstance)
292 {
293    return layer::create_instance(pCreateInfo, pAllocator, pInstance);
294 }
295
296 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL wsi_layer_vkCreateDevice(VkPhysicalDevice physicalDevice,
297                                                                         const VkDeviceCreateInfo *pCreateInfo,
298                                                                         const VkAllocationCallbacks *pAllocator,
299                                                                         VkDevice *pDevice)
300 {
301    return layer::create_device(physicalDevice, pCreateInfo, pAllocator, pDevice);
302 }
303
304 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
305 vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface *pVersionStruct)
306 {
307    assert(pVersionStruct);
308    assert(pVersionStruct->sType == LAYER_NEGOTIATE_INTERFACE_STRUCT);
309
310    /* 2 is the minimum interface version which would utilize this function. */
311    assert(pVersionStruct->loaderLayerInterfaceVersion >= 2);
312
313    /* Set our requested interface version. Set to 2 for now to separate us from newer versions. */
314    pVersionStruct->loaderLayerInterfaceVersion = 2;
315
316    /* Fill in struct values. */
317    pVersionStruct->pfnGetInstanceProcAddr = &wsi_layer_vkGetInstanceProcAddr;
318    pVersionStruct->pfnGetDeviceProcAddr = &wsi_layer_vkGetDeviceProcAddr;
319    pVersionStruct->pfnGetPhysicalDeviceProcAddr = nullptr;
320
321    return VK_SUCCESS;
322 }
323
324 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL wsi_layer_vkEnumerateDeviceExtensionProperties(
325    VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties)
326 {
327    if (pLayerName && !strcmp(pLayerName, layer::global_layer.layerName))
328       return layer::extension_properties(1, layer::device_extension, pCount, pProperties);
329
330    assert(physicalDevice);
331    return layer::instance_private_data::get(physicalDevice)
332       .disp.EnumerateDeviceExtensionProperties(physicalDevice, pLayerName, pCount, pProperties);
333 }
334
335 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL wsi_layer_vkEnumerateInstanceExtensionProperties(
336    const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties)
337 {
338    if (pLayerName && !strcmp(pLayerName, layer::global_layer.layerName))
339       return layer::extension_properties(1, layer::instance_extension, pCount, pProperties);
340
341    return VK_ERROR_LAYER_NOT_PRESENT;
342 }
343
344 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
345 wsi_layer_vkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties)
346 {
347    return layer::layer_properties(1, &layer::global_layer, pCount, pProperties);
348 }
349
350 #define GET_PROC_ADDR(func)      \
351    if (!strcmp(funcName, #func)) \
352       return (PFN_vkVoidFunction)&wsi_layer_##func;
353
354 VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI_CALL wsi_layer_vkGetDeviceProcAddr(VkDevice device, const char *funcName)
355 {
356    GET_PROC_ADDR(vkCreateSwapchainKHR);
357    GET_PROC_ADDR(vkDestroySwapchainKHR);
358    GET_PROC_ADDR(vkGetSwapchainImagesKHR);
359    GET_PROC_ADDR(vkAcquireNextImageKHR);
360    GET_PROC_ADDR(vkQueuePresentKHR);
361
362    return layer::device_private_data::get(device).disp.GetDeviceProcAddr(device, funcName);
363 }
364
365 VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL wsi_layer_vkGetInstanceProcAddr(VkInstance instance,
366                                                                                          const char *funcName)
367 {
368    GET_PROC_ADDR(vkGetDeviceProcAddr);
369    GET_PROC_ADDR(vkGetInstanceProcAddr);
370    GET_PROC_ADDR(vkCreateInstance);
371    GET_PROC_ADDR(vkDestroyInstance);
372    GET_PROC_ADDR(vkCreateDevice);
373    GET_PROC_ADDR(vkDestroyDevice);
374    GET_PROC_ADDR(vkGetPhysicalDeviceSurfaceSupportKHR);
375    GET_PROC_ADDR(vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
376    GET_PROC_ADDR(vkGetPhysicalDeviceSurfaceFormatsKHR);
377    GET_PROC_ADDR(vkGetPhysicalDeviceSurfacePresentModesKHR);
378    GET_PROC_ADDR(vkEnumerateDeviceExtensionProperties);
379    GET_PROC_ADDR(vkEnumerateInstanceExtensionProperties);
380    GET_PROC_ADDR(vkEnumerateInstanceLayerProperties);
381
382    return layer::instance_private_data::get(instance).disp.GetInstanceProcAddr(instance, funcName);
383 }
384 } /* extern "C" */