From a694215abcbba2e00f95a6b89ab9e5582c774821 Mon Sep 17 00:00:00 2001 From: Harsh Aggarwal Date: Tue, 31 Jul 2018 16:28:31 +0530 Subject: [PATCH] spec: Add support for VK_KHR_incremental_present Change-Id: Ida4de95e016dcc6c3148cc5376cec0d1b73c3d0e --- src/wsi/extensions.c | 1 + src/wsi/swapchain.c | 17 ++++++++++++++++- src/wsi/swapchain_tdm.c | 4 +++- src/wsi/swapchain_tpl.c | 42 ++++++++++++++++++++++++++++++++++++++++-- src/wsi/wsi.h | 5 ++++- 5 files changed, 64 insertions(+), 5 deletions(-) diff --git a/src/wsi/extensions.c b/src/wsi/extensions.c index 921e786..78e938b 100644 --- a/src/wsi/extensions.c +++ b/src/wsi/extensions.c @@ -48,6 +48,7 @@ vk_EnumerateInstanceExtensionProperties(const char *layer_name, static const VkExtensionProperties wsi_device_extensions[] = { { VK_KHR_SWAPCHAIN_EXTENSION_NAME, 67 }, + { VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME, 1 }, }; VKAPI_ATTR VkResult VKAPI_CALL diff --git a/src/wsi/swapchain.c b/src/wsi/swapchain.c index 20ec874..a51b560 100644 --- a/src/wsi/swapchain.c +++ b/src/wsi/swapchain.c @@ -325,6 +325,8 @@ vk_QueuePresentKHR(VkQueue queue, uint32_t i; vk_icd_t *icd = vk_get_icd(); VkResult res = VK_SUCCESS; + VkPresentRegionsKHR *region_info = NULL; + const VkPresentRegionKHR *regions = NULL; for (i = 0; i < info->swapchainCount; i++) { int sync_fd = -1; @@ -338,8 +340,21 @@ vk_QueuePresentKHR(VkQueue queue, if (res != VK_SUCCESS) VK_ERROR("Failed to queue_signal_release_image. res(%d)", res); + + region_info = info->pNext; + if (region_info) { + if (VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR != region_info->sType || region_info->swapchainCount <= 0) { + VK_ERROR("issue in using extension (%s)", VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME); + res = VK_ERROR_DEVICE_LOST;//TODO return proper error code + } + + if (VK_SUCCESS == res) { + regions = region_info->pRegions; + } + + } res = chain->present_image(queue, chain, - chain->buffers[info->pImageIndices[i]].tbm, sync_fd); + chain->buffers[info->pImageIndices[i]].tbm, sync_fd, regions ? regions->rectangleCount : 0, regions ? regions->pRectangles : NULL); if (info->pResults != NULL) info->pResults[i] = res; diff --git a/src/wsi/swapchain_tdm.c b/src/wsi/swapchain_tdm.c index a785275..42b8f35 100644 --- a/src/wsi/swapchain_tdm.c +++ b/src/wsi/swapchain_tdm.c @@ -89,7 +89,9 @@ static VkResult swapchain_tdm_queue_present_image(VkQueue queue, vk_swapchain_t *chain, tbm_surface_h tbm_surface, - int sync_fd) + int sync_fd, + int num_rects, + const VkRectLayerKHR *rects) { tbm_surface_queue_error_e tsq_err; tdm_error tdm_err; diff --git a/src/wsi/swapchain_tpl.c b/src/wsi/swapchain_tpl.c index d2d3bcd..708b21e 100644 --- a/src/wsi/swapchain_tpl.c +++ b/src/wsi/swapchain_tpl.c @@ -35,14 +35,22 @@ struct vk_swapchain_tpl { tbm_surface_h *buffers; }; +struct swap_region +{ + int num_rects; + int *rects; +}; static VkResult swapchain_tpl_queue_present_image(VkQueue queue, vk_swapchain_t *chain, tbm_surface_h tbm_surface, - int sync_fd) + int sync_fd, + int num_rects, + const VkRectLayerKHR *rects) { tpl_result_t res; vk_swapchain_tpl_t *swapchain_tpl = chain->backend_data; + struct swap_region *region = NULL; if (chain->is_retired == VK_TRUE) { res = tpl_surface_cancel_dequeued_buffer(swapchain_tpl->tpl_surface, tbm_surface); @@ -53,13 +61,43 @@ swapchain_tpl_queue_present_image(VkQueue queue, return VK_ERROR_OUT_OF_DATE_KHR; } + if (num_rects >= 1) { + region = (struct swap_region *)malloc(sizeof(struct swap_region)); + if (!region) + { + VK_ERROR("Failed to allocate swap_region"); + return VK_ERROR_DEVICE_LOST; + } + + region->num_rects = num_rects; + + region->rects = (int *)malloc(sizeof(int) * 4 * num_rects); + if (!region->rects) + { + VK_ERROR("Failed to allocate swap_region->rects."); + free(region); + return VK_ERROR_DEVICE_LOST; + } + + for (int i = 0; i < num_rects; i++) { + VkRectLayerKHR *pRects = &rects[i]; + //copy first 4 ints from VkRectLayerKHR + memcpy((char *)region->rects + sizeof(int)*4*i, (char *)pRects, sizeof(int) * 4); + } + + } res = tpl_surface_enqueue_buffer_with_damage_and_sync(swapchain_tpl->tpl_surface, - tbm_surface, 0, NULL, sync_fd); + tbm_surface, region ? region->num_rects : 0, region ? region->rects : NULL, sync_fd); if (res == TPL_ERROR_NONE && chain->oldSwapchain != VK_NULL_HANDLE) { chain->oldSwapchain->is_retired = VK_TRUE; chain->oldSwapchain = VK_NULL_HANDLE; } + if (region) { + if (region->rects) free(region->rects); + + free(region); + } return res == TPL_ERROR_NONE ? VK_SUCCESS : VK_ERROR_DEVICE_LOST; } diff --git a/src/wsi/wsi.h b/src/wsi/wsi.h index 961abef..67c22b6 100644 --- a/src/wsi/wsi.h +++ b/src/wsi/wsi.h @@ -138,7 +138,10 @@ struct vk_swapchain { VkResult (*present_image)(VkQueue, vk_swapchain_t *, tbm_surface_h, - int); /* sync fd */ + int,/* sync fd */ + int, + const VkRectLayerKHR * + ); void (*deinit) (VkDevice, vk_swapchain_t *); -- 2.7.4