From 8d28bf812fbb6e5a76c2fc3cb1b5466e248a4cdb Mon Sep 17 00:00:00 2001 From: "deasung.kim" Date: Mon, 11 Apr 2016 21:12:26 +0900 Subject: [PATCH] swapchain: Basic swapchain implementation using TPL Change-Id: I9ac0642ffae0ef5492d4afa74bdbd66ea2f307f3 --- src/wsi/swapchain.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++--- src/wsi/wsi.h | 9 ++++ 2 files changed, 119 insertions(+), 5 deletions(-) diff --git a/src/wsi/swapchain.c b/src/wsi/swapchain.c index 1474d2b..4309e08 100644 --- a/src/wsi/swapchain.c +++ b/src/wsi/swapchain.c @@ -23,6 +23,7 @@ */ #include "wsi.h" +#include VKAPI_ATTR VkResult VKAPI_CALL vk_CreateSwapchainKHR(VkDevice device, @@ -30,8 +31,43 @@ vk_CreateSwapchainKHR(VkDevice device, const VkAllocationCallbacks *allocator, VkSwapchainKHR *swapchain) { - /* TODO: */ + vk_swapchain_t *chain; + vk_surface_t *sfc; + tbm_format format; + tpl_result_t res; + + switch (info->imageFormat) { + case VK_FORMAT_R8G8B8_SRGB: + format = TBM_FORMAT_XRGB8888; + break; + case VK_FORMAT_R8G8B8A8_SRGB: + format = TBM_FORMAT_ARGB8888; + break; + default: + format = TBM_FORMAT_ARGB8888; + } + + allocator = vk_get_allocator(device, allocator); + + chain = vk_alloc(allocator, sizeof(vk_swapchain_t), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + VK_CHECK(chain, return VK_ERROR_OUT_OF_HOST_MEMORY, "swapchain vk_alloc() failed.\n"); + + memset(chain, 0x00, sizeof(vk_swapchain_t)); + + sfc = (vk_surface_t *)info->surface; + res = tpl_surface_create_swapchain(sfc->tpl.surface, format, info->imageExtent.width, + info->imageExtent.height, info->minImageCount); + VK_CHECK(res == TPL_ERROR_NONE, goto error, "tpl_surface_create_swapchain() failed.\n"); + + chain->allocator = *allocator; + chain->vk_surface = sfc; + + *swapchain = (VkSwapchainKHR)chain; return VK_SUCCESS; + +error: + vk_free(allocator, chain); + return VK_ERROR_DEVICE_LOST; } VKAPI_ATTR VkResult VKAPI_CALL @@ -50,7 +86,12 @@ vk_DestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *allocator) { - /* TODO: */ + vk_swapchain_t *chain = (vk_swapchain_t *)swapchain; + + tpl_surface_destroy_swapchain(chain->vk_surface->tpl.surface); + free(chain->buffers); + + vk_free(&chain->allocator, chain); } VKAPI_ATTR VkResult VKAPI_CALL @@ -59,7 +100,31 @@ vk_GetSwapchainImagesKHR(VkDevice device, uint32_t *image_count, VkImage *images) { - /* TODO: */ + vk_swapchain_t *chain = (vk_swapchain_t *)swapchain; + + if (chain->buffer_count == 0) { + tpl_result_t res =tpl_surface_get_swapchain_buffers(chain->vk_surface->tpl.surface, + &chain->buffers, &chain->buffer_count); + VK_CHECK(res == TPL_ERROR_NONE, return VK_ERROR_SURFACE_LOST_KHR, + "tpl_surface_get_swapchain_buffers() failed\n."); + } + + if (images) { + int32_t i; + for (i = 0; i < (int32_t)*image_count && i < chain->buffer_count; i++) { + /* TODO: tbm_surface_h to VkImage */ + images[i] = (VkImage)chain->buffers[i]; + } + + *image_count = i; + + if (i < chain->buffer_count) + return VK_INCOMPLETE; + + } else { + *image_count = chain->buffer_count; + } + return VK_SUCCESS; } @@ -71,7 +136,29 @@ vk_AcquireNextImageKHR(VkDevice device, VkFence fence, uint32_t *image_index) { - /* TODO: */ + /* TODO: apply timeout, semaphore, fence */ + + int i; + tbm_surface_h next; + vk_swapchain_t *chain = (vk_swapchain_t *)swapchain; + + next = tpl_surface_dequeue_buffer(chain->vk_surface->tpl.surface); + VK_CHECK(next, return VK_ERROR_SURFACE_LOST_KHR, + "tpl_surface_get_swapchain_buffers() failed\n."); + + for (i = 0; i < chain->buffer_count; i++) { + if (next == chain->buffers[chain->buffer_index]) + break; + + if (++chain->buffer_index == chain->buffer_count) + chain->buffer_index = 0; + } + + VK_CHECK(i == chain->buffer_count, return VK_ERROR_SURFACE_LOST_KHR, + "tpl_surface_get_swapchain_buffers() return new buffer[%p]\n.", next); + + *image_index = chain->buffer_index; + return VK_SUCCESS; } @@ -79,6 +166,24 @@ VKAPI_ATTR VkResult VKAPI_CALL vk_QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *info) { - /* TODO: */ + uint32_t i; + uint32_t buf_index; + vk_swapchain_t *chain; + tpl_result_t res; + + for (i = 0; i < info->swapchainCount; i++) { + chain = (vk_swapchain_t *)info->pSwapchains[i]; + buf_index = info->pImageIndices[i]; + + res = tpl_surface_enqueue_buffer(chain->vk_surface->tpl.surface, + chain->buffers[buf_index]); + + if (info->pResults != NULL) { + if (res != TPL_ERROR_NONE) + info->pResults[i] = VK_ERROR_DEVICE_LOST; + else + info->pResults[i] = VK_SUCCESS; + } + } return VK_SUCCESS; } diff --git a/src/wsi/wsi.h b/src/wsi/wsi.h index 785e46f..d7fffef 100644 --- a/src/wsi/wsi.h +++ b/src/wsi/wsi.h @@ -33,6 +33,7 @@ #include typedef struct vk_surface vk_surface_t; +typedef struct vk_swapchain vk_swapchain_t; struct vk_surface { union { @@ -60,6 +61,14 @@ struct vk_surface { } tpl; }; +struct vk_swapchain { + vk_surface_t *vk_surface; + VkAllocationCallbacks allocator; + tbm_surface_h *buffers; + int buffer_index; + int buffer_count; +}; + VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance, const char *name); -- 2.7.4