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

Commit efd2b0f1 authored by Trevor Black's avatar Trevor Black Committed by Android (Google) Code Review
Browse files

Merge "Check for USAGE_FRONT_BUFFER after GPDIFP2" into main

parents 052870a1 02926f5c
Loading
Loading
Loading
Loading
+187 −163
Original line number Diff line number Diff line
@@ -1369,8 +1369,111 @@ static VkResult getProducerUsage(const VkDevice& device,
    const VkPhysicalDevice& pdev = GetData(device).driver_physical_device;
    const InstanceData& instance_data = GetData(pdev);
    const InstanceDriverTable& instance_dispatch = instance_data.driver;
    if (!instance_dispatch.GetPhysicalDeviceImageFormatProperties2 &&
            !instance_dispatch.GetPhysicalDeviceImageFormatProperties2KHR) {
    if (instance_dispatch.GetPhysicalDeviceImageFormatProperties2 ||
            instance_dispatch.GetPhysicalDeviceImageFormatProperties2KHR) {
        // Look through the create_info pNext chain passed to createSwapchainKHR
        // for an image compression control struct.
        // if one is found AND the appropriate extensions are enabled, create a
        // VkImageCompressionControlEXT structure to pass on to
        // GetPhysicalDeviceImageFormatProperties2
        void* compression_control_pNext = nullptr;
        VkImageCompressionControlEXT image_compression = {};
        const VkSwapchainCreateInfoKHR* create_infos = create_info;
        while (create_infos->pNext) {
            create_infos = reinterpret_cast<const VkSwapchainCreateInfoKHR*>(create_infos->pNext);
            switch (create_infos->sType) {
                case VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT: {
                    const VkImageCompressionControlEXT* compression_infos =
                        reinterpret_cast<const VkImageCompressionControlEXT*>(create_infos);
                    image_compression = *compression_infos;
                    image_compression.pNext = nullptr;
                    compression_control_pNext = &image_compression;
                } break;
                default:
                    // Ignore all other info structs
                    break;
            }
        }

        // call GetPhysicalDeviceImageFormatProperties2KHR
        VkPhysicalDeviceExternalImageFormatInfo external_image_format_info = {
            .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
            .pNext = compression_control_pNext,
            .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID,
        };

        // AHB does not have an sRGB format so we can't pass it to GPDIFP
        // We need to convert the format to unorm if it is srgb
        VkFormat format = create_info->imageFormat;
        if (format == VK_FORMAT_R8G8B8A8_SRGB) {
            format = VK_FORMAT_R8G8B8A8_UNORM;
        }

        VkPhysicalDeviceImageFormatInfo2 image_format_info = {
            .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
            .pNext = &external_image_format_info,
            .format = format,
            .type = VK_IMAGE_TYPE_2D,
            .tiling = VK_IMAGE_TILING_OPTIMAL,
            .usage = create_info->imageUsage,
            .flags = create_protected_swapchain ? VK_IMAGE_CREATE_PROTECTED_BIT : 0u,
        };

        VkAndroidHardwareBufferUsageANDROID ahb_usage;
        ahb_usage.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID;
        ahb_usage.pNext = nullptr;

        VkImageFormatProperties2 image_format_properties;
        image_format_properties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
        image_format_properties.pNext = &ahb_usage;

        if (instance_dispatch.GetPhysicalDeviceImageFormatProperties2) {
            VkResult result = instance_dispatch.GetPhysicalDeviceImageFormatProperties2(
                pdev, &image_format_info, &image_format_properties);
            if (result != VK_SUCCESS) {
                ALOGE("VkGetPhysicalDeviceImageFormatProperties2 for AHB usage failed: %d", result);
                return VK_ERROR_SURFACE_LOST_KHR;
            }
        }
        else {
            VkResult result = instance_dispatch.GetPhysicalDeviceImageFormatProperties2KHR(
                pdev, &image_format_info,
                &image_format_properties);
            if (result != VK_SUCCESS) {
                ALOGE("VkGetPhysicalDeviceImageFormatProperties2KHR for AHB usage failed: %d",
                    result);
                return VK_ERROR_SURFACE_LOST_KHR;
            }
        }

        // Determine if USAGE_FRONT_BUFFER is needed.
        // GPDIFP2 has no means of using VkSwapchainImageUsageFlagsANDROID when
        // querying for producer_usage. So androidHardwareBufferUsage will not
        // contain USAGE_FRONT_BUFFER. We need to manually check for usage here.
        if (!(swapchain_image_usage & VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID)) {
            *producer_usage = ahb_usage.androidHardwareBufferUsage;
            return VK_SUCCESS;
        }

        // Check if USAGE_FRONT_BUFFER is supported for this swapchain
        AHardwareBuffer_Desc ahb_desc = {
            .width = create_info->imageExtent.width,
            .height = create_info->imageExtent.height,
            .layers = create_info->imageArrayLayers,
            .format = create_info->imageFormat,
            .usage = ahb_usage.androidHardwareBufferUsage | AHARDWAREBUFFER_USAGE_FRONT_BUFFER,
            .stride = 0, // stride is always ignored when calling isSupported()
        };

        // If FRONT_BUFFER is not supported,
        // then we need to call GetSwapchainGrallocUsageXAndroid below
        if (AHardwareBuffer_isSupported(&ahb_desc)) {
            *producer_usage = ahb_usage.androidHardwareBufferUsage;
            *producer_usage |= AHARDWAREBUFFER_USAGE_FRONT_BUFFER;
            return VK_SUCCESS;
        }
    }

    uint64_t native_usage = 0;
    void* usage_info_pNext = nullptr;
    VkResult result;
@@ -1485,85 +1588,6 @@ static VkResult getProducerUsage(const VkDevice& device,
    return VK_SUCCESS;
}

    // Look through the create_info pNext chain passed to createSwapchainKHR
    // for an image compression control struct.
    // if one is found AND the appropriate extensions are enabled, create a
    // VkImageCompressionControlEXT structure to pass on to GetPhysicalDeviceImageFormatProperties2
    void* compression_control_pNext = nullptr;
    VkImageCompressionControlEXT image_compression = {};
    const VkSwapchainCreateInfoKHR* create_infos = create_info;
    while (create_infos->pNext) {
        create_infos = reinterpret_cast<const VkSwapchainCreateInfoKHR*>(create_infos->pNext);
        switch (create_infos->sType) {
            case VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT: {
                const VkImageCompressionControlEXT* compression_infos =
                    reinterpret_cast<const VkImageCompressionControlEXT*>(create_infos);
                image_compression = *compression_infos;
                image_compression.pNext = nullptr;
                compression_control_pNext = &image_compression;
            } break;
            default:
                // Ignore all other info structs
                break;
        }
    }

    // call GetPhysicalDeviceImageFormatProperties2KHR
    VkPhysicalDeviceExternalImageFormatInfo external_image_format_info = {
        .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
        .pNext = compression_control_pNext,
        .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID,
    };

    // AHB does not have an sRGB format so we can't pass it to GPDIFP
    // We need to convert the format to unorm if it is srgb
    VkFormat format = create_info->imageFormat;
    if (format == VK_FORMAT_R8G8B8A8_SRGB) {
        format = VK_FORMAT_R8G8B8A8_UNORM;
    }

    VkPhysicalDeviceImageFormatInfo2 image_format_info = {
        .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
        .pNext = &external_image_format_info,
        .format = format,
        .type = VK_IMAGE_TYPE_2D,
        .tiling = VK_IMAGE_TILING_OPTIMAL,
        .usage = create_info->imageUsage,
        .flags = create_protected_swapchain ? VK_IMAGE_CREATE_PROTECTED_BIT : 0u,
    };

    VkAndroidHardwareBufferUsageANDROID ahb_usage;
    ahb_usage.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID;
    ahb_usage.pNext = nullptr;

    VkImageFormatProperties2 image_format_properties;
    image_format_properties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
    image_format_properties.pNext = &ahb_usage;

    if (instance_dispatch.GetPhysicalDeviceImageFormatProperties2) {
        VkResult result = instance_dispatch.GetPhysicalDeviceImageFormatProperties2(
            pdev, &image_format_info, &image_format_properties);
        if (result != VK_SUCCESS) {
            ALOGE("VkGetPhysicalDeviceImageFormatProperties2 for AHB usage failed: %d", result);
            return VK_ERROR_SURFACE_LOST_KHR;
        }
    }
    else {
        VkResult result = instance_dispatch.GetPhysicalDeviceImageFormatProperties2KHR(
            pdev, &image_format_info,
            &image_format_properties);
        if (result != VK_SUCCESS) {
            ALOGE("VkGetPhysicalDeviceImageFormatProperties2KHR for AHB usage failed: %d",
                result);
            return VK_ERROR_SURFACE_LOST_KHR;
        }
    }

    *producer_usage = ahb_usage.androidHardwareBufferUsage;

    return VK_SUCCESS;
}

VKAPI_ATTR
VkResult CreateSwapchainKHR(VkDevice device,
                            const VkSwapchainCreateInfoKHR* create_info,