swapchain.c \
display.c \
allocator.c \
- icd.c
+ icd.c \
+ extensions.c
manifestdir = /etc/vulkan/icd.d
manifest_DATA = vulkan-wsi-tizen.json
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;
}
/* 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);
}
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;
}
/* 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);
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);
}
--- /dev/null
+/*
+ * 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 <string.h>
+
+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;
+}
#include <stdlib.h>
#include <string.h>
-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);
}
const VkAllocationCallbacks *allocator,
VkSwapchainKHR *swapchain)
{
+ vk_icd_t *icd = vk_get_icd();
vk_swapchain_t *chain;
tbm_format format;
tpl_result_t res;
};
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;
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.");
* 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;
}
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;
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;
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);
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);