Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 39877506 authored by Ian Elliott's avatar Ian Elliott Committed by Android (Google) Code Review
Browse files

Merge "Initial implementation of VK_KHR_incremental_present."

parents 873228ef cb351137
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -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),
@@ -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)
+69 −1
Original line number Diff line number Diff line
@@ -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) ? &regions[sc] : NULL;
        VkResult swapchain_result = VK_SUCCESS;
        VkResult result;
        int err;
@@ -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) {
@@ -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;
}