From 6b404d82a01a188add855650cc728eb68e8d869e Mon Sep 17 00:00:00 2001 From: Taekyun Kim Date: Thu, 19 May 2016 17:18:44 +0900 Subject: [PATCH] wsi: Refactoring to support display surface Change-Id: I7be92c8251838995f618f961c9d595cbd77d19d9 --- src/wsi/Makefile.am | 3 +- src/wsi/entry-points.c | 11 ++- src/wsi/extensions.c | 97 +++++++++++++++++++++++++ src/wsi/icd.c | 193 ++++++++++--------------------------------------- src/wsi/swapchain.c | 17 +++-- src/wsi/wsi.h | 43 ++++++----- 6 files changed, 177 insertions(+), 187 deletions(-) create mode 100644 src/wsi/extensions.c diff --git a/src/wsi/Makefile.am b/src/wsi/Makefile.am index 4646ae1..bd8d241 100644 --- a/src/wsi/Makefile.am +++ b/src/wsi/Makefile.am @@ -21,7 +21,8 @@ vulkan_wsi_tizen_la_SOURCES = wsi.h \ swapchain.c \ display.c \ allocator.c \ - icd.c + icd.c \ + extensions.c manifestdir = /etc/vulkan/icd.d manifest_DATA = vulkan-wsi-tizen.json diff --git a/src/wsi/entry-points.c b/src/wsi/entry-points.c index 581fe79..143f2d3 100644 --- a/src/wsi/entry-points.c +++ b/src/wsi/entry-points.c @@ -84,6 +84,7 @@ get_entry_point(const char *name) VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_GetInstanceProcAddr(VkInstance instance, const char *name) { + vk_icd_t *icd = vk_get_icd(); const vk_entry_t *entry = get_entry_point(name); PFN_vkGetInstanceProcAddr gipa; @@ -106,7 +107,7 @@ vk_GetInstanceProcAddr(VkInstance instance, const char *name) } /* TODO: Avoid getting GIPA on the fly. */ - gipa = (PFN_vkGetInstanceProcAddr)vk_icd_get_proc_addr(instance, "vkGetInstanceProcAddr"); + gipa = (PFN_vkGetInstanceProcAddr)icd->get_proc_addr(instance, "vkGetInstanceProcAddr"); return gipa(instance, name); } @@ -114,6 +115,7 @@ vk_GetInstanceProcAddr(VkInstance instance, const char *name) VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_GetDeviceProcAddr(VkDevice device, const char *name) { + vk_icd_t *icd = vk_get_icd(); const vk_entry_t *entry = get_entry_point(name); PFN_vkGetDeviceProcAddr gdpa; @@ -128,7 +130,7 @@ vk_GetDeviceProcAddr(VkDevice device, const char *name) } /* TODO: We are trying to get the most specific device functions here. */ - gdpa = (PFN_vkGetDeviceProcAddr)vk_icd_get_proc_addr(NULL, "vkGetDeviceProcAddr"); + gdpa = (PFN_vkGetDeviceProcAddr)icd->get_proc_addr(NULL, "vkGetDeviceProcAddr"); gdpa = (PFN_vkGetDeviceProcAddr)gdpa(device, "vkGetDeviceProcAddr"); return gdpa(device, name); @@ -138,10 +140,11 @@ vk_GetDeviceProcAddr(VkDevice device, const char *name) VK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance, const char *name) { - const vk_entry_t *entry = get_entry_point(name); + vk_icd_t *icd = vk_get_icd(); + const vk_entry_t *entry = get_entry_point(name); if (entry) return entry->func; - return vk_icd_get_proc_addr(instance, name); + return icd->get_proc_addr(instance, name); } diff --git a/src/wsi/extensions.c b/src/wsi/extensions.c new file mode 100644 index 0000000..e93ad78 --- /dev/null +++ b/src/wsi/extensions.c @@ -0,0 +1,97 @@ +/* + * Copyright © 2016 S-Core Corporation + * Copyright © 2016-2017 Samsung Electronics co., Ltd. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "wsi.h" +#include + +VKAPI_ATTR VkResult VKAPI_CALL +vk_EnumerateInstanceExtensionProperties(const char *layer_name, + uint32_t *count, + VkExtensionProperties *extensions) +{ + vk_icd_t *icd = vk_get_icd(); + + if (!extensions) { + *count = icd->instance_extension_count; + return VK_SUCCESS; + } + + *count = MIN(*count, icd->instance_extension_count); + memcpy(extensions, icd->instance_extensions, *count * sizeof(VkExtensionProperties)); + + if (*count < icd->instance_extension_count) + return VK_INCOMPLETE; + + return VK_SUCCESS; +} + +static const VkExtensionProperties wsi_device_extensions[] = { + { VK_KHR_SWAPCHAIN_EXTENSION_NAME, 67 }, +}; + +VKAPI_ATTR VkResult VKAPI_CALL +vk_EnumerateDeviceExtensionProperties(VkPhysicalDevice pdev, + const char *layer_name, + uint32_t *count, + VkExtensionProperties *extensions) +{ + vk_icd_t *icd = vk_get_icd(); + uint32_t max_ext_count, remaining, copied = 0; + VkResult result; + + result = icd->enum_dev_exts(pdev, layer_name, &max_ext_count, NULL); + VK_CHECK(result == VK_SUCCESS, return VK_ERROR_OUT_OF_HOST_MEMORY, + "vkEnumerateDeviceExtensionProperties() failed.\n"); + + max_ext_count += ARRAY_LENGTH(wsi_device_extensions); + + if (!extensions) { + *count = max_ext_count; + return VK_SUCCESS; + } + + /* Copy ICD extensions and WSI extensions together into the given pointer. */ + + /* Calculate the number of extensions we have to copy. */ + remaining = MIN(*count, max_ext_count); + + /* Copy ICD extensions first. */ + copied = remaining; + result = icd->enum_dev_exts(pdev, layer_name, &copied, extensions); + VK_CHECK(result == VK_SUCCESS || result == VK_INCOMPLETE, return VK_ERROR_OUT_OF_HOST_MEMORY, + "vkEnumerateDeviceExtensionProperties() failed.\n"); + + /* Calculate remaining extensions to copy. */ + remaining = MIN(remaining - copied, ARRAY_LENGTH(wsi_device_extensions)); + memcpy(extensions + copied, wsi_device_extensions, remaining * sizeof(VkExtensionProperties)); + copied += remaining; + + /* Return the number of extensions copied. */ + *count = copied; + + if (*count < max_ext_count) + return VK_INCOMPLETE; + + return VK_SUCCESS; +} diff --git a/src/wsi/icd.c b/src/wsi/icd.c index 146c2ce..7f02a04 100644 --- a/src/wsi/icd.c +++ b/src/wsi/icd.c @@ -27,194 +27,75 @@ #include #include -typedef struct vk_icd vk_icd_t; - -struct vk_icd { - void *lib; - PFN_vkGetInstanceProcAddr gpa; - - PFN_vkEnumerateInstanceExtensionProperties enum_instance_extensions; - PFN_vkEnumerateDeviceExtensionProperties enum_device_extensions; - - uint32_t global_extension_count; - VkExtensionProperties *global_extensions; - - /* WSI-ICD interface. */ - VkImage (*create_presentable_image)(VkDevice device, const VkImageCreateInfo *info, - tbm_surface_h buffer); - VkBool32 (*signal_semaphore)(VkSemaphore semaphore); - VkBool32 (*wait_for_semaphores)(uint32_t count, const VkSemaphore *semaphores); - VkBool32 (*signal_fence)(VkFence fence); - -}; - static vk_icd_t icd; -static const VkExtensionProperties global_extensions[] = { +vk_icd_t * +vk_get_icd(void) +{ + return &icd; +} + +static const VkExtensionProperties wsi_instance_extensions[] = { { VK_KHR_SURFACE_EXTENSION_NAME, 25 }, { VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, 4 }, }; static void __attribute__((constructor)) -icd_init(void) +module_init(void) { - const char *filename; - VkResult res; + const char *filename; uint32_t count; + VkResult res; + PFN_vkEnumerateInstanceExtensionProperties enum_inst_exts; + /* Get env var for ICD path. */ filename = getenv("VK_TIZEN_ICD"); VK_CHECK(filename, return, "No ICD library given.\n"); dlerror(); + /* Open ICD file. */ icd.lib = dlopen(filename, RTLD_LAZY | RTLD_LOCAL); VK_CHECK(icd.lib, return, "dlopen() failed - %s\n", dlerror()); - icd.gpa = dlsym(icd.lib, "vk_icdGetInstanceProcAddr"); - VK_CHECK(icd.gpa, return, "vk_icdGetInstanceProcAddr() not present.\n"); + /* Retrieve our first entry point for vulkan symbols. */ + icd.get_proc_addr = dlsym(icd.lib, "vk_icdGetInstanceProcAddr"); + VK_CHECK(icd.get_proc_addr, return, "vk_icdGetInstanceProcAddr() not present.\n"); - /* Retrieve extension enumeration functions. */ - icd.enum_instance_extensions = (void *)icd.gpa(NULL, "vkEnumerateInstanceExtensionProperties"); - VK_CHECK(icd.enum_instance_extensions, return, - "vkEnumerateInstanceExtensionProperties() not present.\n"); - - icd.enum_device_extensions = (void *)icd.gpa(NULL, "vkEnumerateDeviceExtensionProperties"); - VK_CHECK(icd.enum_device_extensions, return, - "vkEnumerateDeviceExtensionProperties() not present.\n"); - - /* Get ICD global extension count. */ - res = icd.enum_instance_extensions(NULL, &count, NULL); - VK_CHECK(res == VK_SUCCESS, return, "vkEnumerateInstanceExtensionProperties() failed.\n"); - - /* Allocate memory to hold the extensions both for ICD and WSI. */ - icd.global_extensions = - malloc((count + ARRAY_LENGTH(global_extensions)) * sizeof(VkExtensionProperties)); - VK_CHECK(icd.global_extensions, return, "malloc() failed.\n"); - - /* Copy ICD extensions first. */ - res = icd.enum_instance_extensions(NULL, &count, icd.global_extensions); - VK_CHECK(res == VK_SUCCESS, return, "vkEnumerateInstanceExtensionProperties() failed.\n"); - - /* Append WSI extensions. */ - memcpy(icd.global_extensions + count, global_extensions, - ARRAY_LENGTH(global_extensions) * sizeof(VkExtensionProperties)); - - icd.global_extension_count = count + ARRAY_LENGTH(global_extensions); + /* Dispatch device extension enumeration function. */ + icd.enum_dev_exts = (void *)icd.get_proc_addr(NULL, "vkEnumerateDeviceExtensionProperties"); + VK_CHECK(icd.enum_dev_exts, return, "vkEnumerateDeviceExtensionProperties() not present.\n"); + /* Retrieve WSI-ICD interface functions. */ icd.create_presentable_image = dlsym(icd.lib, "vk_create_presentable_image"); icd.signal_semaphore = dlsym(icd.lib, "vk_signal_semaphore"); icd.wait_for_semaphores = dlsym(icd.lib, "vk_wait_for_semaphores"); icd.signal_fence = dlsym(icd.lib, "vk_signal_fence"); -} - -static void __attribute__((destructor)) -icd_fini(void) -{ - if (icd.lib) - dlclose(icd.lib); -} - -PFN_vkVoidFunction -vk_icd_get_proc_addr(VkInstance instance, const char *name) -{ - return icd.gpa(instance, name); -} - -VkImage -vk_icd_create_presentable_image(VkDevice device, - const VkImageCreateInfo *info, - tbm_surface_h surface) -{ - return icd.create_presentable_image(device, info, surface); -} -VkBool32 -vk_icd_signal_semaphore(VkSemaphore semaphore) -{ - return icd.signal_semaphore(semaphore); -} + /* Initialize instance extensions. */ + enum_inst_exts = (void *)icd.get_proc_addr(NULL, "vkEnumerateInstanceExtensionProperties"); + VK_CHECK(enum_inst_exts, return, "vkEnumerateInstanceExtensionProperties() not present.\n"); -VkBool32 -vk_icd_wait_for_semaphores(uint32_t count, const VkSemaphore *semaphores) -{ - return icd.wait_for_semaphores(count, semaphores); -} + res = enum_inst_exts(NULL, &count, NULL); + VK_CHECK(res == VK_SUCCESS, return, "vkEnumerateInstanceExtensionProperties() failed.\n"); -VkBool32 -vk_icd_signal_fence(VkFence fence) -{ - return icd.signal_fence(fence); -} + count += ARRAY_LENGTH(wsi_instance_extensions); -VKAPI_ATTR VkResult VKAPI_CALL -vk_EnumerateInstanceExtensionProperties(const char *layer_name, - uint32_t *count, - VkExtensionProperties *extensions) -{ - if (!extensions) { - *count = icd.global_extension_count; - return VK_SUCCESS; - } + icd.instance_extensions = malloc(count * sizeof(VkExtensionProperties)); + VK_CHECK(icd.instance_extensions, return, "malloc() failed.\n"); - *count = MIN(*count, icd.global_extension_count); - memcpy(extensions, icd.global_extensions, *count * sizeof(VkExtensionProperties)); + res = enum_inst_exts(NULL, &count, icd.instance_extensions); + VK_CHECK(res == VK_SUCCESS, return, "vkEnumerateInstanceExtensionProperties() failed.\n"); - if (*count < icd.global_extension_count) - return VK_INCOMPLETE; + memcpy(icd.instance_extensions + count, wsi_instance_extensions, + ARRAY_LENGTH(wsi_instance_extensions) * sizeof(VkExtensionProperties)); - return VK_SUCCESS; + icd.instance_extension_count = count + ARRAY_LENGTH(wsi_instance_extensions); } -static const VkExtensionProperties device_extensions[] = { - { VK_KHR_SWAPCHAIN_EXTENSION_NAME, 67 }, -}; - -VKAPI_ATTR VkResult VKAPI_CALL -vk_EnumerateDeviceExtensionProperties(VkPhysicalDevice pdev, - const char *layer_name, - uint32_t *count, - VkExtensionProperties *extensions) +static void __attribute__((destructor)) +module_fini(void) { - uint32_t ext_count, copied = 0; - uint32_t icd_count, max_count; - VkResult result; - - result = icd.enum_device_extensions(pdev, layer_name, &icd_count, NULL); - VK_CHECK(result == VK_SUCCESS, return VK_ERROR_OUT_OF_HOST_MEMORY, - "vkEnumerateDeviceExtensionProperties() failed.\n"); - - max_count = icd_count + ARRAY_LENGTH(device_extensions); - - if (!extensions) { - /* Just return the number of enabled extension properties in this case. */ - *count = max_count; - return VK_SUCCESS; - } - - /* We should copy ICD extensions and WSI extensions together into the given pointer. */ - - ext_count = MIN(*count, icd_count); - result = icd.enum_device_extensions(pdev, layer_name, &ext_count, extensions); - VK_CHECK(result == VK_SUCCESS || result == VK_INCOMPLETE, return VK_ERROR_OUT_OF_HOST_MEMORY, - "vkEnumerateDeviceExtensionProperties() failed.\n"); - - /* Advance the destination pointer. */ - extensions += ext_count; - copied += ext_count; - - /* Calculate remaining extensions to copy. */ - ext_count = *count - ext_count; - - if (ext_count > 0) { - ext_count = MIN(ext_count, ARRAY_LENGTH(device_extensions)); - memcpy(extensions, device_extensions, ext_count * sizeof(VkExtensionProperties)); - copied += ext_count; - } - - *count = copied; - - if (*count < max_count) - return VK_INCOMPLETE; - - return VK_SUCCESS; + if (icd.lib) + dlclose(icd.lib); } diff --git a/src/wsi/swapchain.c b/src/wsi/swapchain.c index 763d06a..48734b8 100644 --- a/src/wsi/swapchain.c +++ b/src/wsi/swapchain.c @@ -31,6 +31,7 @@ vk_CreateSwapchainKHR(VkDevice device, const VkAllocationCallbacks *allocator, VkSwapchainKHR *swapchain) { + vk_icd_t *icd = vk_get_icd(); vk_swapchain_t *chain; tbm_format format; tpl_result_t res; @@ -103,7 +104,7 @@ vk_CreateSwapchainKHR(VkDevice device, }; chain->buffers[i].tbm = buffers[i]; - chain->buffers[i].image = vk_icd_create_presentable_image(device, &image_info, buffers[i]); + chain->buffers[i].image = icd->create_presentable_image(device, &image_info, buffers[i]); } chain->buffer_count = buffer_count; @@ -187,12 +188,13 @@ vk_AcquireNextImageKHR(VkDevice device, VkFence fence, uint32_t *image_index) { - /* TODO: apply timeout, semaphore, fence */ - + vk_icd_t *icd = vk_get_icd(); uint32_t i; tbm_surface_h next; vk_swapchain_t *chain = (vk_swapchain_t *)(uintptr_t)swapchain; + /* TODO: timeout */ + next = tpl_surface_dequeue_buffer(chain->tpl_surface); VK_CHECK(next, return VK_ERROR_SURFACE_LOST_KHR, "tpl_surface_dequeue_buffers() failed\n."); @@ -206,10 +208,10 @@ vk_AcquireNextImageKHR(VkDevice device, * wl_buffer.release actually arrives. */ if (fence != VK_NULL_HANDLE) - vk_icd_signal_fence(fence); + icd->signal_fence(fence); if (semaphore != VK_NULL_HANDLE) - vk_icd_signal_semaphore(semaphore); + icd->signal_semaphore(semaphore); return VK_SUCCESS; } @@ -222,9 +224,10 @@ VKAPI_ATTR VkResult VKAPI_CALL vk_QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *info) { - uint32_t i; + vk_icd_t *icd = vk_get_icd(); + uint32_t i; - vk_icd_wait_for_semaphores(info->waitSemaphoreCount, info->pWaitSemaphores); + icd->wait_for_semaphores(info->waitSemaphoreCount, info->pWaitSemaphores); for (i = 0; i < info->swapchainCount; i++) { tpl_result_t res; diff --git a/src/wsi/wsi.h b/src/wsi/wsi.h index 35761c7..d342b25 100644 --- a/src/wsi/wsi.h +++ b/src/wsi/wsi.h @@ -36,6 +36,27 @@ typedef struct vk_surface vk_surface_t; typedef struct vk_swapchain vk_swapchain_t; typedef struct vk_buffer vk_buffer_t; +typedef struct vk_icd vk_icd_t; + +struct vk_icd { + void *lib; + + PFN_vkGetInstanceProcAddr get_proc_addr; + PFN_vkEnumerateDeviceExtensionProperties enum_dev_exts; + + uint32_t instance_extension_count; + VkExtensionProperties *instance_extensions; + + /* WSI-ICD interface. */ + VkImage (*create_presentable_image)(VkDevice device, const VkImageCreateInfo *info, + tbm_surface_h buffer); + VkBool32 (*signal_semaphore)(VkSemaphore semaphore); + VkBool32 (*wait_for_semaphores)(uint32_t count, const VkSemaphore *semaphores); + VkBool32 (*signal_fence)(VkFence fence); +}; + +vk_icd_t * +vk_get_icd(void); struct vk_buffer { tbm_surface_h tbm; @@ -53,9 +74,6 @@ struct vk_swapchain { vk_buffer_t *buffers; }; -VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL -vk_icdGetInstanceProcAddr(VkInstance instance, const char *name); - const VkAllocationCallbacks * vk_get_allocator(void *parent, const VkAllocationCallbacks *allocator); @@ -78,23 +96,10 @@ vk_get_tpl_display(tpl_handle_t native_dpy) return display; }; -PFN_vkVoidFunction -vk_icd_get_proc_addr(VkInstance instance, const char *name); - -VkImage -vk_icd_create_presentable_image(VkDevice device, const VkImageCreateInfo *info, - tbm_surface_h buffer); - -VkBool32 -vk_icd_signal_semaphore(VkSemaphore semaphore); - -VkBool32 -vk_icd_wait_for_semaphores(uint32_t count, const VkSemaphore *semaphores); - -VkBool32 -vk_icd_signal_fence(VkFence fence); - /* Entry point proto types. */ +VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL +vk_icdGetInstanceProcAddr(VkInstance instance, const char *name); + VKAPI_ATTR VkResult VKAPI_CALL vk_GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice pdev, uint32_t queue_family_index, VkSurfaceKHR surface, VkBool32 *supported); -- 2.7.4