swapchain: Basic swapchain implementation using TPL 51/66051/1
authordeasung.kim <deasung.kim@samsung.com>
Mon, 11 Apr 2016 12:12:26 +0000 (21:12 +0900)
committerTaekyun Kim <tkq.kim@samsung.com>
Fri, 15 Apr 2016 04:47:22 +0000 (13:47 +0900)
Change-Id: I9ac0642ffae0ef5492d4afa74bdbd66ea2f307f3

src/wsi/swapchain.c
src/wsi/wsi.h

index 1474d2b..4309e08 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include "wsi.h"
+#include <string.h>
 
 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;
 }
index 785e46f..d7fffef 100644 (file)
@@ -33,6 +33,7 @@
 #include <tpl.h>
 
 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);