Loading vulkan/include/vulkan/vulkan.h +22 −0 Original line number Diff line number Diff line Loading @@ -218,6 +218,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000, VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001, VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV = 1000026002, VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR = 1000084000, VK_STRUCTURE_TYPE_BEGIN_RANGE = VK_STRUCTURE_TYPE_APPLICATION_INFO, VK_STRUCTURE_TYPE_END_RANGE = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO, VK_STRUCTURE_TYPE_RANGE_SIZE = (VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO - VK_STRUCTURE_TYPE_APPLICATION_INFO + 1), Loading Loading @@ -3715,6 +3716,27 @@ VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR( #define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION 1 #define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME "VK_KHR_sampler_mirror_clamp_to_edge" #define VK_KHR_incremental_present 1 #define VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION 1 #define VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME "VK_KHR_incremental_present" typedef struct VkRectLayerKHR { VkOffset2D offset; VkExtent2D extent; uint32_t layer; } VkRectLayerKHR; typedef struct VkPresentRegionKHR { uint32_t rectangleCount; const VkRectLayerKHR* pRectangles; } VkPresentRegionKHR; typedef struct VkPresentRegionsKHR { VkStructureType sType; const void* pNext; uint32_t swapchainCount; const VkPresentRegionKHR* pRegions; } VkPresentRegionsKHR; #define VK_EXT_debug_report 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT) Loading vulkan/libvulkan/swapchain.cpp +69 −1 Original line number Diff line number Diff line Loading @@ -860,17 +860,43 @@ VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) { ALOGV_IF(present_info->sType != VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, "vkQueuePresentKHR: invalid VkPresentInfoKHR structure type %d", present_info->sType); ALOGV_IF(present_info->pNext, "VkPresentInfo::pNext != NULL"); VkDevice device = GetData(queue).driver_device; const auto& dispatch = GetData(queue).driver; VkResult final_result = VK_SUCCESS; // Look at the pNext chain for supported extension structs: const VkPresentRegionsKHR* present_regions = NULL; const VkPresentRegionsKHR* next = reinterpret_cast<const VkPresentRegionsKHR*>(present_info->pNext); while (next) { switch (next->sType) { case VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR: present_regions = next; break; default: ALOGV("QueuePresentKHR ignoring unrecognized pNext->sType = %x", next->sType); break; } next = reinterpret_cast<const VkPresentRegionsKHR*>(next->pNext); } ALOGV_IF( present_regions && present_regions->swapchainCount != present_info->swapchainCount, "VkPresentRegions::swapchainCount != VkPresentInfo::swapchainCount"); const VkPresentRegionKHR* regions = (present_regions) ? present_regions->pRegions : NULL; const VkAllocationCallbacks* allocator = &GetData(device).allocator; android_native_rect_t* rects = NULL; uint32_t nrects = 0; for (uint32_t sc = 0; sc < present_info->swapchainCount; sc++) { Swapchain& swapchain = *SwapchainFromHandle(present_info->pSwapchains[sc]); uint32_t image_idx = present_info->pImageIndices[sc]; Swapchain::Image& img = swapchain.images[image_idx]; const VkPresentRegionKHR* region = (regions) ? ®ions[sc] : NULL; VkResult swapchain_result = VK_SUCCESS; VkResult result; int err; Loading @@ -888,6 +914,45 @@ VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) { present_info->pSwapchains[sc]) { ANativeWindow* window = swapchain.surface.window.get(); if (swapchain_result == VK_SUCCESS) { if (region) { // Process the incremental-present hint for this swapchain: uint32_t rcount = region->rectangleCount; if (rcount > nrects) { android_native_rect_t* new_rects = static_cast<android_native_rect_t*>( allocator->pfnReallocation( allocator->pUserData, rects, sizeof(android_native_rect_t) * rcount, alignof(android_native_rect_t), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)); if (new_rects) { rects = new_rects; nrects = rcount; } else { rcount = 0; // Ignore the hint for this swapchain } } for (uint32_t r = 0; r < rcount; ++r) { if (region->pRectangles[r].layer > 0) { ALOGV( "vkQueuePresentKHR ignoring invalid layer " "(%u); using layer 0 instead", region->pRectangles[r].layer); } int x = region->pRectangles[r].offset.x; int y = region->pRectangles[r].offset.y; int width = static_cast<int>( region->pRectangles[r].extent.width); int height = static_cast<int>( region->pRectangles[r].extent.height); android_native_rect_t* cur_rect = &rects[r]; cur_rect->left = x; cur_rect->top = y + height; cur_rect->right = x + width; cur_rect->bottom = y; } native_window_set_surface_damage(window, rects, rcount); } err = window->queueBuffer(window, img.buffer.get(), fence); // queueBuffer always closes fence, even on error if (err != 0) { Loading Loading @@ -918,6 +983,9 @@ VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) { if (swapchain_result != final_result) final_result = WorstPresentResult(final_result, swapchain_result); } if (rects) { allocator->pfnFree(allocator->pUserData, rects); } return final_result; } Loading Loading
vulkan/include/vulkan/vulkan.h +22 −0 Original line number Diff line number Diff line Loading @@ -218,6 +218,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000, VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001, VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV = 1000026002, VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR = 1000084000, VK_STRUCTURE_TYPE_BEGIN_RANGE = VK_STRUCTURE_TYPE_APPLICATION_INFO, VK_STRUCTURE_TYPE_END_RANGE = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO, VK_STRUCTURE_TYPE_RANGE_SIZE = (VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO - VK_STRUCTURE_TYPE_APPLICATION_INFO + 1), Loading Loading @@ -3715,6 +3716,27 @@ VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR( #define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION 1 #define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME "VK_KHR_sampler_mirror_clamp_to_edge" #define VK_KHR_incremental_present 1 #define VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION 1 #define VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME "VK_KHR_incremental_present" typedef struct VkRectLayerKHR { VkOffset2D offset; VkExtent2D extent; uint32_t layer; } VkRectLayerKHR; typedef struct VkPresentRegionKHR { uint32_t rectangleCount; const VkRectLayerKHR* pRectangles; } VkPresentRegionKHR; typedef struct VkPresentRegionsKHR { VkStructureType sType; const void* pNext; uint32_t swapchainCount; const VkPresentRegionKHR* pRegions; } VkPresentRegionsKHR; #define VK_EXT_debug_report 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT) Loading
vulkan/libvulkan/swapchain.cpp +69 −1 Original line number Diff line number Diff line Loading @@ -860,17 +860,43 @@ VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) { ALOGV_IF(present_info->sType != VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, "vkQueuePresentKHR: invalid VkPresentInfoKHR structure type %d", present_info->sType); ALOGV_IF(present_info->pNext, "VkPresentInfo::pNext != NULL"); VkDevice device = GetData(queue).driver_device; const auto& dispatch = GetData(queue).driver; VkResult final_result = VK_SUCCESS; // Look at the pNext chain for supported extension structs: const VkPresentRegionsKHR* present_regions = NULL; const VkPresentRegionsKHR* next = reinterpret_cast<const VkPresentRegionsKHR*>(present_info->pNext); while (next) { switch (next->sType) { case VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR: present_regions = next; break; default: ALOGV("QueuePresentKHR ignoring unrecognized pNext->sType = %x", next->sType); break; } next = reinterpret_cast<const VkPresentRegionsKHR*>(next->pNext); } ALOGV_IF( present_regions && present_regions->swapchainCount != present_info->swapchainCount, "VkPresentRegions::swapchainCount != VkPresentInfo::swapchainCount"); const VkPresentRegionKHR* regions = (present_regions) ? present_regions->pRegions : NULL; const VkAllocationCallbacks* allocator = &GetData(device).allocator; android_native_rect_t* rects = NULL; uint32_t nrects = 0; for (uint32_t sc = 0; sc < present_info->swapchainCount; sc++) { Swapchain& swapchain = *SwapchainFromHandle(present_info->pSwapchains[sc]); uint32_t image_idx = present_info->pImageIndices[sc]; Swapchain::Image& img = swapchain.images[image_idx]; const VkPresentRegionKHR* region = (regions) ? ®ions[sc] : NULL; VkResult swapchain_result = VK_SUCCESS; VkResult result; int err; Loading @@ -888,6 +914,45 @@ VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) { present_info->pSwapchains[sc]) { ANativeWindow* window = swapchain.surface.window.get(); if (swapchain_result == VK_SUCCESS) { if (region) { // Process the incremental-present hint for this swapchain: uint32_t rcount = region->rectangleCount; if (rcount > nrects) { android_native_rect_t* new_rects = static_cast<android_native_rect_t*>( allocator->pfnReallocation( allocator->pUserData, rects, sizeof(android_native_rect_t) * rcount, alignof(android_native_rect_t), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)); if (new_rects) { rects = new_rects; nrects = rcount; } else { rcount = 0; // Ignore the hint for this swapchain } } for (uint32_t r = 0; r < rcount; ++r) { if (region->pRectangles[r].layer > 0) { ALOGV( "vkQueuePresentKHR ignoring invalid layer " "(%u); using layer 0 instead", region->pRectangles[r].layer); } int x = region->pRectangles[r].offset.x; int y = region->pRectangles[r].offset.y; int width = static_cast<int>( region->pRectangles[r].extent.width); int height = static_cast<int>( region->pRectangles[r].extent.height); android_native_rect_t* cur_rect = &rects[r]; cur_rect->left = x; cur_rect->top = y + height; cur_rect->right = x + width; cur_rect->bottom = y; } native_window_set_surface_damage(window, rects, rcount); } err = window->queueBuffer(window, img.buffer.get(), fence); // queueBuffer always closes fence, even on error if (err != 0) { Loading Loading @@ -918,6 +983,9 @@ VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) { if (swapchain_result != final_result) final_result = WorstPresentResult(final_result, swapchain_result); } if (rects) { allocator->pfnFree(allocator->pUserData, rects); } return final_result; } Loading