//
// Copyright 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// vk_renderer.cpp:
//    Implements the class methods for Renderer.
//

#ifdef UNSAFE_BUFFERS_BUILD
#    pragma allow_unsafe_buffers
#endif

#include "libANGLE/renderer/vulkan/vk_renderer.h"

// Placing this first seems to solve an intellisense bug.
#include "libANGLE/angletypes.h"
#include "libANGLE/renderer/vulkan/vk_utils.h"

#include <EGL/eglext.h>
#include <fstream>

#include "common/debug.h"
#include "common/platform.h"
#include "common/system_utils.h"
#include "common/vulkan/libvulkan_loader.h"
#include "common/vulkan/vulkan_icd.h"
#include "gpu_info_util/SystemInfo_vulkan.h"
#include "libANGLE/Context.h"
#include "libANGLE/Display.h"
#include "libANGLE/renderer/driver_utils.h"
#include "libANGLE/renderer/vulkan/CompilerVk.h"
#include "libANGLE/renderer/vulkan/ContextVk.h"
#include "libANGLE/renderer/vulkan/DisplayVk.h"
#include "libANGLE/renderer/vulkan/FramebufferVk.h"
#include "libANGLE/renderer/vulkan/ProgramVk.h"
#include "libANGLE/renderer/vulkan/SyncVk.h"
#include "libANGLE/renderer/vulkan/VertexArrayVk.h"
#include "libANGLE/renderer/vulkan/vk_caps_utils.h"
#include "libANGLE/renderer/vulkan/vk_format_utils.h"
#include "libANGLE/renderer/vulkan/vk_resource.h"
#include "libANGLE/trace.h"
#include "platform/PlatformMethods.h"
#include "vulkan/vulkan_core.h"

// Consts
namespace
{
#if defined(ANGLE_PLATFORM_ANDROID)
constexpr const char *kDefaultPipelineCacheGraphDumpPath = "/data/local/tmp/angle_dumps/";
#else
constexpr const char *kDefaultPipelineCacheGraphDumpPath = "";
#endif  // ANGLE_PLATFORM_ANDROID

constexpr VkFormatFeatureFlags kInvalidFormatFeatureFlags = static_cast<VkFormatFeatureFlags>(-1);

#if defined(ANGLE_EXPOSE_NON_CONFORMANT_EXTENSIONS_AND_VERSIONS)
constexpr bool kExposeNonConformantExtensionsAndVersions = true;
#else
constexpr bool kExposeNonConformantExtensionsAndVersions = false;
#endif

#if defined(ANGLE_ENABLE_CRC_FOR_PIPELINE_CACHE)
constexpr bool kEnableCRCForPipelineCache = true;
#else
constexpr bool kEnableCRCForPipelineCache = false;
#endif

#if defined(ANGLE_ENABLE_VULKAN_API_DUMP_LAYER)
constexpr bool kEnableVulkanAPIDumpLayer = true;
#else
constexpr bool kEnableVulkanAPIDumpLayer = false;
#endif

#if defined(ANGLE_OPENCL_COMPUTE_ONLY_PIPE)
constexpr bool kUseComputeOnlyQueue = true;
#else
constexpr bool kUseComputeOnlyQueue = false;
#endif

}  // anonymous namespace

namespace rx
{
namespace
{
constexpr angle::PackedEnumMap<QueueSubmitReason, const char *> kQueueSubmitReason = {{
    {QueueSubmitReason::EGLBindTexImage, "Queue submission imminent due to eglBindTexImage()"},
    {QueueSubmitReason::EGLSwapBuffers, "Queue submission imminent due to eglSwapBuffers()"},
    {QueueSubmitReason::EGLWaitClient, "Queue submission imminent due to eglWaitClient()"},
    {QueueSubmitReason::DeferredFlush, "Queue submission imminent due to deferred flushing"},
    {QueueSubmitReason::GLFinish, "Queue submission imminent due to glFinish()"},
    {QueueSubmitReason::GLFlush, "Queue submission imminent due to glFlush()"},
    {QueueSubmitReason::GLReadPixels, "Queue submission imminent due to glReadPixels()"},
    {QueueSubmitReason::AcquireNextImage, "Queue submission imminent due to acquiring next image"},
    {QueueSubmitReason::ContextChange, "Queue submission imminent due to context change"},
    {QueueSubmitReason::ContextDestruction, "Queue submission imminent due to context destruction"},
    {QueueSubmitReason::ContextPriorityChange,
     "Queue submission imminent due to context priority change"},
    {QueueSubmitReason::SurfaceUnMakeCurrent,
     "Queue submission imminent due to unmaking current on surface"},
    {QueueSubmitReason::CopyBufferToImageOneOff,
     "Queue submission imminent after one-off copying buffer to image"},
    {QueueSubmitReason::CopyBufferToSurfaceImage,
     "Queue submission imminent after copying buffer to surface image"},
    {QueueSubmitReason::CopySurfaceImageToBuffer,
     "Queue submission imminent after copying surface image to buffer"},
    {QueueSubmitReason::ForeignImageRelease,
     "Queue submission imminent due to releasing foreign image"},
    {QueueSubmitReason::ImageUseThenReleaseToExternal,
     "Queue submission imminent due to image used in render pass being released"},
    {QueueSubmitReason::TextureReformatToRenderable,
     "Queue submission imminent due to reformatting texture to a renderable fallback"},
    {QueueSubmitReason::CopyTextureOnCPU,
     "Queue submission imminent due to fallback to CPU when copying texture"},
    {QueueSubmitReason::GenerateMipmapOnCPU,
     "Queue submission imminent due to fallback to CPU when generating mipmaps"},
    {QueueSubmitReason::ExternalSemaphoreSignal,
     "Queue submission imminent due to external semaphore signal"},
    {QueueSubmitReason::GetQueryResult, "Queue submission imminent after getting query result"},
    {QueueSubmitReason::GetTimestamp, "Queue submission imminent after getting the timestamp"},
    {QueueSubmitReason::SyncCPUGPUTime,
     "Queue submission imminent due to synchronizing CPU and GPU time"},
    {QueueSubmitReason::SyncObjectInit, "Queue submission imminent after initializing sync object"},
    {QueueSubmitReason::SyncObjectClientWait,
     "Queue submission imminent due to sync object client wait"},
    {QueueSubmitReason::SyncObjectWithFdInit,
     "Queue submission imminent due to inserting sync object with file descriptor"},
    {QueueSubmitReason::DeviceLocalBufferMap,
     "Queue submission imminent due to mapping device local buffer"},
    {QueueSubmitReason::BufferWriteThenMap,
     "Queue submission imminent due to mapping buffer being written to by render pass"},
    {QueueSubmitReason::BufferInUseWhenSynchronizedMap,
     "Queue submission imminent due to mapping buffer in use by GPU without "
     "GL_MAP_UNSYNCHRONIZED_BIT"},
    {QueueSubmitReason::WaitSemaphore, "Queue submission imminent after waiting for semaphore"},
    {QueueSubmitReason::ExcessivePendingGarbage,
     "Queue submission imminent due to exceeding pending garbage memory size threshold"},
    {QueueSubmitReason::OutOfMemory,
     "Queue submission imminent due to context finish to mitigate running out of device memory"},
    {QueueSubmitReason::RenderPassCountLimitReached,
     "Queue submission imminent due to exceeding the threshold for render pass command count"},
    {QueueSubmitReason::RenderPassCommandLimitReached,
     "Queue submission imminent due to exceeding write command limit at draw time"},
    {QueueSubmitReason::BufferToImageUpdateLimitReached,
     "Queue submission imminent due to exceeding buffer-to-image update size limit"},
    {QueueSubmitReason::ForceSubmitStagedTexture,
     "Queue submission imminent due to staged texture updates"},
    {QueueSubmitReason::InitializeMemory, "Queue submission imminent due to initializing memory"},
}};
}  // namespace

std::ostream &operator<<(std::ostream &os, const QueueSubmitReason reason)
{
    os << kQueueSubmitReason[reason];
    return os;
}

namespace vk
{
namespace
{
constexpr uint32_t kMinDefaultUniformBufferSize = 16 * 1024u;
// This size is picked based on experience. Majority of devices support 64K
// maxUniformBufferSize. Since this is per context buffer, a bigger buffer size reduces the
// number of descriptor set allocations, so we picked the maxUniformBufferSize that most
// devices supports. It may need further tuning based on specific device needs and balance
// between performance and memory usage.
constexpr uint32_t kPreferredDefaultUniformBufferSize = 64 * 1024u;

// The limit below is used to avoid allocating too many device memory handles. If the device has an
// allocation count limit less than or equal to this threshold, the initial size for the dynamic
// buffers will be larger.
constexpr size_t kAllocationCountThresholdForDynamicVertexDataSize = 4096;

// Maximum size to use VMA image suballocation. Any allocation greater than or equal to this
// value will use a dedicated VkDeviceMemory.
constexpr size_t kImageSizeThresholdForDedicatedMemoryAllocation = 8 * 1024 * 1024;

// Maximum size for an allocated memory for a single object.
constexpr VkDeviceSize kMemoryAllocationSizeLimit = 1 * 1024 * 1024 * 1024;

// Pipeline cache header version. It should be incremented any time there is an update to the cache
// header or data structure.
constexpr uint32_t kPipelineCacheVersion = 3;

// Update the pipeline cache every this many swaps.
constexpr uint32_t kPipelineCacheVkUpdatePeriod = 60;

// Per the Vulkan specification, ANGLE must indicate the highest version of Vulkan functionality
// that it uses.  The Vulkan validation layers will issue messages for any core functionality that
// requires a higher version.
//
// ANGLE specifically limits its core version to Vulkan 1.1 and relies on availability of
// extensions.  While implementations are not required to expose an extension that is promoted to
// later versions, they always do so in practice.  Avoiding later core versions helps keep the
// initialization logic simpler.
constexpr uint32_t kPreferredVulkanAPIVersion = VK_API_VERSION_1_1;

bool IsVulkan11(uint32_t apiVersion)
{
    return apiVersion >= VK_API_VERSION_1_1;
}

bool IsRADV(uint32_t vendorId, uint32_t driverId, const char *deviceName)
{
    // Check against RADV driver id first.
    if (driverId == VK_DRIVER_ID_MESA_RADV)
    {
        return true;
    }

    // Otherwise, look for RADV in the device name.  This works for both RADV
    // and Venus-over-RADV.
    return IsAMD(vendorId) && strstr(deviceName, "RADV") != nullptr;
}

bool IsMesaPanVK(uint32_t driverId)
{
    // rely on VkDriverId alone to identify MESA PanVK driver
    return driverId == VK_DRIVER_ID_MESA_PANVK;
}

bool IsQualcommOpenSource(uint32_t vendorId, uint32_t driverId, const char *deviceName)
{
    if (!IsQualcomm(vendorId))
    {
        return false;
    }

    // Where driver id is available, distinguish by driver id:
    if (driverId != 0)
    {
        return driverId != VK_DRIVER_ID_QUALCOMM_PROPRIETARY;
    }

    // Otherwise, look for Venus or Turnip in the device name.
    return strstr(deviceName, "Venus") != nullptr || strstr(deviceName, "Turnip") != nullptr;
}

bool IsXclipse()
{
    if (!IsAndroid())
    {
        return false;
    }

    std::string modelName;
    if (!angle::android::GetSystemProperty(angle::android::kModelSystemPropertyName, &modelName))
    {
        return 0;
    }

    // Improve this when more Xclipse devices are available
    return strstr(modelName.c_str(), "SM-S901B") != nullptr ||
           strstr(modelName.c_str(), "SM-S926B") != nullptr;
}

bool StrLess(const char *a, const char *b)
{
    return strcmp(a, b) < 0;
}

bool ExtensionFound(const char *needle, const vk::ExtensionNameList &haystack)
{
    // NOTE: The list must be sorted.
    return std::binary_search(haystack.begin(), haystack.end(), needle, StrLess);
}

VkResult VerifyExtensionsPresent(const vk::ExtensionNameList &haystack,
                                 const vk::ExtensionNameList &needles)
{
    // NOTE: The lists must be sorted.
    if (std::includes(haystack.begin(), haystack.end(), needles.begin(), needles.end(), StrLess))
    {
        return VK_SUCCESS;
    }
    for (const char *needle : needles)
    {
        if (!ExtensionFound(needle, haystack))
        {
            ERR() << "Extension not supported: " << needle;
        }
    }
    return VK_ERROR_EXTENSION_NOT_PRESENT;
}

// Array of Validation error/warning messages that will be ignored, should include bugID
constexpr const char *kSkippedMessages[] = {
    // http://anglebug.com/42266825
    "Undefined-Value-ShaderOutputNotConsumed",
    "Undefined-Value-ShaderInputNotProduced",
    // ANGLE sets gl_Layer when the framebuffer is not layered, but VVL does not see that.  When
    // layered, if gl_Layer is out of bounds, the results are undefined in both GL and Vulkan.
    // http://anglebug.com/372390039
    "Undefined-Layer-Written",
    // http://anglebug.com/42263850
    "VUID-vkCmdDraw-magFilter-04553",
    "VUID-vkCmdDrawIndexed-magFilter-04553",
    // http://anglebug.com/42265014
    "vkEnumeratePhysicalDevices: One or more layers modified physical devices",
    // http://anglebug.com/42265797
    "VUID-vkCmdBindVertexBuffers2-pStrides-06209",
    // http://anglebug.com/42266199
    "VUID-vkDestroySemaphore-semaphore-01137",
    "VUID-vkDestroySemaphore-semaphore-05149",
    // http://anglebug.com/42266819
    "VUID-vkCmdDraw-None-09000",
    "VUID-vkCmdDrawIndexed-None-09002",
    // http://anglebug.com/40644894
    "VUID-VkDescriptorImageInfo-imageView-06711",
    "VUID-VkDescriptorImageInfo-descriptorType-06713",
    // http://crbug.com/1412096
    "VUID-VkImageCreateInfo-pNext-00990",
    // http://anglebug.com/42266565
    "VUID-VkGraphicsPipelineCreateInfo-Input-07904",
    "VUID-VkGraphicsPipelineCreateInfo-Input-07905",
    "VUID-vkCmdDrawIndexed-None-07835",
    "VUID-VkGraphicsPipelineCreateInfo-Input-08733",
    "VUID-vkCmdDraw-Input-08734",
    // https://anglebug.com/42266639
    "VUID-VkVertexInputBindingDivisorDescriptionKHR-divisor-01870",
    "VUID-VkVertexInputBindingDivisorDescription-divisor-01870",
    // https://anglebug.com/42265766
    "VUID-vkCmdBlitImage-srcImage-00240",
    // https://anglebug.com/42266678
    // VVL bug: https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/7858
    "VUID-vkCmdDraw-None-08608",
    "VUID-vkCmdDrawIndexed-None-08608",
    "VUID-vkCmdDraw-None-07843",
    "VUID-vkCmdDrawIndexed-None-07843",
    "VUID-vkCmdDraw-None-07844",
    "VUID-vkCmdDrawIndexed-None-07844",
    "VUID-vkCmdDraw-None-07847",
    "VUID-vkCmdDrawIndexed-None-07847",
    // Invalid feedback loop caused by the application
    "VUID-vkCmdDraw-None-09000",
    "VUID-vkCmdDrawIndexed-None-09000",
    "VUID-vkCmdDraw-None-09002",
    "VUID-vkCmdDrawIndexed-None-09002",
    "VUID-vkCmdDraw-None-09003",
    "VUID-vkCmdDrawIndexed-None-09003",
    // https://anglebug.com/42266764
    "VUID-VkDescriptorImageInfo-imageView-07796",
    // https://issuetracker.google.com/303441816
    "VUID-VkRenderPassBeginInfo-renderPass-00904",
    // http://anglebug.com/42266888
    "VUID-VkMemoryAllocateInfo-allocationSize-01742",
    "VUID-VkMemoryDedicatedAllocateInfo-image-01878",
    // http://anglebug.com/42266890
    "VUID-vkCmdDraw-pNext-09461",
    // http://anglebug.com/42266893
    "VUID-VkImportMemoryFdInfoKHR-handleType-00667",
    // http://anglebug.com/42266904
    "VUID-VkImportMemoryWin32HandleInfoKHR-handleType-00658",
    // https://anglebug.com/42266947
    "VUID-VkPipelineVertexInputStateCreateInfo-pNext-pNext",
    // https://issuetracker.google.com/319228278
    "VUID-vkCmdDrawIndexed-format-07753",
    "VUID-vkCmdDraw-format-07753",
    "Undefined-Value-ShaderFragmentOutputMismatch",
    // https://anglebug.com/336652255
    "VUID-vkCmdDraw-None-09600",
    // https://issuetracker.google.com/336847261
    "VUID-VkImageCreateInfo-pNext-02397",
    "VUID-vkCmdDraw-None-06550",
    // https://anglebug.com/345304850
    "WARNING-Shader-OutputNotConsumed",
    // https://anglebug.com/383311444
    "VUID-vkCmdDraw-None-09462",
    // https://anglebug.com/394598758
    "VUID-vkBindBufferMemory-size-01037",
    // https://anglebug.com/443133082
    "VUID-vkCmdDraw-None-09549",
    // https://anglebug.com/470128354
    "VUID-vkCmdEndQuery-None-07007",
    // https://anglebug.com/475549551
    "VUID-VkGraphicsPipelineCreateInfo-renderPass-09652",
    // https://anglebug.com/512394647
    "VUID-VkImageCreateInfo-imageCreateMaxMipLevels-02251",
};

// Validation messages that should be ignored only when VK_EXT_primitive_topology_list_restart is
// not present.
constexpr const char *kNoListRestartSkippedMessages[] = {
    // http://anglebug.com/42262476
    "VUID-VkPipelineInputAssemblyStateCreateInfo-topology-06252",
};

// Validation messages that should be ignored only when VK_KHR_maintenance5 is not present.
constexpr const char *kNoMaintenance5SkippedMessages[] = {
    // https://anglebug.com/42266575#comment4
    "VUID-VkBufferViewCreateInfo-format-08779",
    // https://anglebug.com/42266675
    "VUID-VkGraphicsPipelineCreateInfo-topology-08773",
    "VUID-vkCmdDraw-primitiveTopology-10748",
    "VUID-vkCmdDrawIndexed-primitiveTopology-10748",
    "VUID-vkCmdDrawIndirect-primitiveTopology-10748",
    "VUID-vkCmdDrawIndexedIndirect-primitiveTopology-10748",
};

// Validation messages that should be ignored only when VK_KHR_maintenance9 is not present.
constexpr const char *kNoMaintenance9SkippedMessages[] = {
    // http://issuetracker.google.com/429339330
    "WARNING-VkImageSubresourceRange-layerCount-compatibility",
};

// Validation messages that should be ignored only when VK_KHR_swapchain_maintenance1 is not
// present.
constexpr const char *kNoSwapchainMaintenance1SkippedMessages[] = {
    // Without VK_KHR_swapchain_maintenance1, there is technically no correct way to know when a
    // VkSwapchainKHR can be destroyed.  If vkDeviceWaitIdle() is called, that's blessed as "good
    // enough", but ANGLE does not call that function.  With VK_KHR_swapchain_maintenance1, the last
    // present's fence is appropriately waited on.  This technicality with older drivers is ignored.
    // See https://gitlab.khronos.org/vulkan/vulkan/-/issues/4761
    "VUID-vkDestroySwapchainKHR-swapchain-01282",
};

// Validation messages that should be ignored only when preferBGR565ToRGB565 is enabled.
constexpr const char *kPreferBGR565SkippedMessages[] = {
    // http://anglebug.com/42264464
    "VUID-VkSamplerCustomBorderColorCreateInfoEXT-format-04015",
};

// Validation messages that should be ignored only when exposeNonConformantExtensionsAndVersions is
// enabled on certain test platforms.
constexpr const char *kExposeNonConformantSkippedMessages[] = {
    // http://issuetracker.google.com/376899587
    "VUID-VkSwapchainCreateInfoKHR-presentMode-01427",
};

// When using Vulkan secondary command buffers, the command buffer is begun with the current
// framebuffer specified in pInheritanceInfo::framebuffer.  If the framebuffer is multisampled
// and is resolved, an optimization would change the framebuffer to add the resolve target and
// use a subpass resolve operation instead.  The following error complains that the framebuffer
// used to start the render pass and the one specified in pInheritanceInfo::framebuffer must be
// equal, which is not true in that case.  In practice, this is benign, as the part of the
// framebuffer that's accessed by the command buffer is identically laid out.
// http://anglebug.com/42265307
constexpr const char *kSkippedMessagesWithRenderPassObjectsAndVulkanSCB[] = {
    "VUID-vkCmdExecuteCommands-pCommandBuffers-00099",
};

// When MSRTSS-rendering to a cubemap, ANGLE queries support without using the CUBE_COMPATIBLE
// create flag because otherwise Vulkan requires that the driver returns VK_SAMPLE_COUNT_1_BIT.  VVL
// doesn't do this however, so it complains that multisampling is not supported.
constexpr const char *kSkippedMessagesWithMSRTSSWithoutDynamicRendering[] = {
    "VUID-VkFramebufferCreateInfo-samples-07009",
    "VUID-VkRenderPassAttachmentBeginInfo-pAttachments-07010",
};

// VVL bugs with dynamic rendering
constexpr const char *kSkippedMessagesWithDynamicRendering[] = {
    // https://anglebug.com/42266678
    // VVL bugs with rasterizer discard:
    // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/7858
    "VUID-vkCmdDraw-dynamicRenderingUnusedAttachments-08914",
    "VUID-vkCmdDraw-dynamicRenderingUnusedAttachments-08917",
    "VUID-vkCmdDrawIndexed-dynamicRenderingUnusedAttachments-08914",
    "VUID-vkCmdDrawIndexed-dynamicRenderingUnusedAttachments-08917",
    "VUID-vkCmdDraw-pDepthAttachment-08964",
    "VUID-vkCmdDraw-pStencilAttachment-08965",
    "VUID-vkCmdDrawIndexed-pDepthAttachment-08964",
    "VUID-vkCmdDrawIndexed-pStencilAttachment-08965",
    "VUID-vkCmdDraw-None-07843",
    "VUID-vkCmdDraw-None-07844",
    "VUID-vkCmdDraw-None-07847",
    "VUID-vkCmdDrawIndexed-None-07843",
    "VUID-vkCmdDrawIndexed-None-07844",
    "VUID-vkCmdDrawIndexed-None-07847",
    "VUID-vkCmdDraw-multisampledRenderToSingleSampled-07285",
    "VUID-vkCmdDraw-multisampledRenderToSingleSampled-07286",
    "VUID-vkCmdDraw-multisampledRenderToSingleSampled-07287",
    "VUID-vkCmdDrawIndexed-multisampledRenderToSingleSampled-07285",
    "VUID-vkCmdDrawIndexed-multisampledRenderToSingleSampled-07286",
    "VUID-vkCmdDrawIndexed-multisampledRenderToSingleSampled-07287",
};

// Some syncval errors are resolved in the presence of the NONE load or store render pass ops.  For
// those, ANGLE makes no further attempt to resolve them and expects vendor support for the
// extensions instead.  The list of skipped messages is split based on this support.
constexpr vk::SkippedSyncvalMessage kSkippedSyncvalMessages[] = {
    // https://issuetracker.google.com/316337308
    // DifferentStencilMasksTest.DrawWithSameEffectiveMask/ES2_Vulkan_SwiftShader
    // VulkanPerformanceCounterTest.NewTextureDoesNotBreakRenderPass for both depth and stencil
    // Hit in the asphalt_9
    // http://anglebug.com/42265363
    // dead_by_daylight
    // From: TraceTest.diablo_immortal http://anglebug.com/42266309 (Linux AMD)
    {"SYNC-HAZARD-WRITE-AFTER-WRITE",
     false,
     {
         "message_type = BeginRenderingError",
         "access = "
         "VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT(VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_"
         "BIT)",
         "prior_access = SYNC_IMAGE_LAYOUT_TRANSITION",
         "command = vkCmdBeginRenderingKHR",
         "prior_command = vkCmdPipelineBarrier",
         "load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE",
     }},
    {"SYNC-HAZARD-WRITE-AFTER-WRITE",
     false,
     {
         "message_type = RenderPassLoadOpError",
         "access = "
         "VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT(VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_"
         "BIT)",
         "prior_access = SYNC_IMAGE_LAYOUT_TRANSITION",
         "command = vkCmdBeginRenderPass",
         "prior_command = vkCmdPipelineBarrier",
         "load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE",
     }},
    // http://anglebug.com/42265427
    // From: TraceTest.blade_and_soul_revolution
    // FramebufferFetchES31.ReopenRenderPass/ES3_1_Vulkan
    {"SYNC-HAZARD-READ-AFTER-WRITE",
     true,
     {
         "message_type = RenderPassLoadOpError",
         "access = "
         "VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT(VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT)",
         "prior_access = SYNC_IMAGE_LAYOUT_TRANSITION",
         "command = vkCmdBeginRenderPass",
         "prior_command = vkCmdEndRenderPass",
         "load_op = VK_ATTACHMENT_LOAD_OP_LOAD",
     }},
    // http://anglebug.com/42265363
    // http://anglebug.com/415382790
    {"SYNC-HAZARD-WRITE-AFTER-WRITE",
     true,
     {
         "message_type = RenderPassLayoutTransitionError",
         "access = SYNC_IMAGE_LAYOUT_TRANSITION",
         "prior_access = "
         "VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT(VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT)",
         "command = vkCmdBeginRenderPass",
         "prior_command = vkCmdEndRenderPass",
         "old_layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL",
         "new_layout = VK_IMAGE_LAYOUT_GENERAL",
     }},
    // http://anglebug.com/415383266
    {"SYNC-HAZARD-WRITE-AFTER-WRITE",
     true,
     {
         "message_type = RenderPassLayoutTransitionError",
         "access = SYNC_IMAGE_LAYOUT_TRANSITION",
         "prior_access = "
         "VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT(VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT)",
         "command = vkCmdBeginRenderPass",
         "prior_command = vkCmdDrawIndexed",
         "old_layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL",
         "new_layout = VK_IMAGE_LAYOUT_GENERAL",
     }},
    // http://anglebug.com/399191283
    {"SYNC-HAZARD-WRITE-AFTER-WRITE",
     false,
     {"message_type = BeginRenderingError",
      "access = "
      "VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT(VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_"
      "BIT)",
      "prior_access = SYNC_IMAGE_LAYOUT_TRANSITION", "prior_command = vkCmdPipelineBarrier",
      "command = vkCmdBeginRenderingKHR", "load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE"}},
    // https://anglebug.com/400789178, prior_command could be vkCmdEndRenderPass or
    // vkCmdEndRenderingKHR
    {"SYNC-HAZARD-WRITE-AFTER-WRITE",
     false,
     {"message_type = ImageBarrierError", "hazard_type = WRITE_AFTER_WRITE",
      "access = SYNC_IMAGE_LAYOUT_TRANSITION",
      "prior_access = "
      "VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT(VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT)",
      "command = vkCmdPipelineBarrier", "prior_command = vkCmdEndRender"}},
    // https://anglebug.com/400789178
    {"SYNC-HAZARD-WRITE-AFTER-WRITE",
     false,
     {"message_type = RenderPassAttachmentError", "hazard_type = WRITE_AFTER_WRITE",
      "access = "
      "VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT(VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT)",
      "prior_access = SYNC_IMAGE_LAYOUT_TRANSITION", "command = vkCmdDrawIndexed",
      "prior_command = vkCmdEndRenderPass"}},
    // False positive: https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/10667
    {"SYNC-HAZARD-WRITE-AFTER-READ",
     false,
     {"message_type = DynamicRenderingAttachmentError", "hazard_type = WRITE_AFTER_READ",
      "access = "
      "VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT(VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT)",
      "prior_access = VK_PIPELINE_STAGE_2_BLIT_BIT(VK_ACCESS_2_TRANSFER_READ_BIT)",
      "command = vkCmdDraw", "prior_command = vkCmdBlitImage"}},
    // https://anglebug.com/456785955
    {"SYNC-HAZARD-WRITE-AFTER-WRITE",
     false,
     {"hazard_type = WRITE_AFTER_WRITE",
      "access = "
      "VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT(VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_"
      "BIT)",
      "prior_access = "
      "VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT(VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT)",
      "command = vkCmdBeginRender", "prior_command = vkCmdEndRender",
      "load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE"}},
    {"SYNC-HAZARD-READ-AFTER-WRITE",
     false,
     {"message_type = RenderPassLoadOpError", "hazard_type = READ_AFTER_WRITE",
      "access = "
      "VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT(VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT)",
      "prior_access = "
      "VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT(VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT)",
      "command = vkCmdBeginRenderPass", "prior_command = vkCmdEndRenderPass",
      "load_op = VK_ATTACHMENT_LOAD_OP_LOAD"}}};

// Messages that should not be generated if the feature to force-enable providing the size pointer
// to vkCmdBindVertexBuffers2() is disabled.
constexpr vk::SkippedSyncvalMessage kSkippedSyncvalMessagesWithoutForcedSizePointer[] = {
    // From: TraceTest.special_forces_group_2 http://anglebug.com/42264123
    // http://anglebug.com/397775556
    // From: TraceTest.life_is_strange http://anglebug.com/42266180 (Linux AMD)
    // From: TraceTest.diablo_immortal http://anglebug.com/42266309 (Linux AMD)
    {"SYNC-HAZARD-READ-AFTER-WRITE",
     false,
     {
         "message_type = BufferError",
         "access = "
         "VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT(VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT)",
         "prior_access = "
         "VK_PIPELINE_STAGE_2_COPY_BIT(VK_ACCESS_2_TRANSFER_WRITE_BIT)",
         "command = vkCmdDrawIndexed",
         "prior_command = vkCmdCopyBuffer",
     }},
    // http://anglebug.com/394598470
    {"SYNC-HAZARD-WRITE-AFTER-READ",
     false,
     {
         "message_type = BufferCopyError",
         "access = VK_PIPELINE_STAGE_2_COPY_BIT(VK_ACCESS_2_TRANSFER_WRITE_BIT)",
         "prior_access = "
         "VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT(VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT)",
         "command = vkCmdCopyBuffer",
         "prior_command = vkCmdDrawIndexed",
     }},
    // https://anglebug.com/443095908
    {"SYNC-HAZARD-WRITE-AFTER-READ",
     false,
     {"message_type = BufferCopyError", "hazard_type = WRITE_AFTER_READ",
      "access = "
      "VK_PIPELINE_STAGE_2_COPY_BIT(VK_ACCESS_2_TRANSFER_WRITE_BIT)",
      "prior_access = "
      "VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT(VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT)",
      "command = vkCmdCopyImageToBuffer", "prior_command = vkCmdDraw"}},
    {"SYNC-HAZARD-WRITE-AFTER-READ",
     false,
     {"message_type = BufferCopyError", "hazard_type = WRITE_AFTER_READ",
      "access = "
      "VK_PIPELINE_STAGE_2_COPY_BIT(VK_ACCESS_2_TRANSFER_WRITE_BIT)",
      "prior_access = "
      "VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT(VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT)",
      "command = vkCmdCopyImageToBuffer", "prior_command = vkCmdDrawIndexed"}},
    {"SYNC-HAZARD-WRITE-AFTER-READ",
     false,
     {"message_type = SubmitTimeError", "hazard_type = WRITE_AFTER_READ",
      "prior_access = "
      "VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT(VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT)",
      "read_barriers = 0", "command = vkCmdCopyImageToBuffer", "prior_command = vkCmdDrawIndexed"}},
};

// Messages that shouldn't be generated if both loadOp=NONE and storeOp=NONE are supported,
// otherwise they are expected.
constexpr vk::SkippedSyncvalMessage kSkippedSyncvalMessagesWithoutLoadStoreOpNone[] = {
    // This error is generated for multiple reasons:
    //
    // - http://anglebug.com/42264926
    //
    // Observed on AMD when running the following test:
    //
    //     dEQP-GLES2.functional.shaders.builtin_variable.pointcoord
    {"SYNC-HAZARD-WRITE-AFTER-WRITE",
     false,
     {
         "message_type = BeginRenderingError",
         "hazard_type = WRITE_AFTER_WRITE",
         "access = "
         "VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT(VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_"
         "BIT)",
         "prior_access = SYNC_IMAGE_LAYOUT_TRANSITION",
         "write_barriers = "
         "VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT|VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT("
         "VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT)",
         "command = vkCmdBeginRenderingKHR",
         "prior_command = vkCmdPipelineBarrier",
         "load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE",
     }},
    // Observed on SwiftShader when running the following tests:
    //
    //     dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgb8
    //     TraceTest.life_is_strange
    {"SYNC-HAZARD-WRITE-AFTER-WRITE",
     false,
     {
         "message_type = ImageBarrierError",
         "hazard_type = WRITE_AFTER_WRITE",
         "access = SYNC_IMAGE_LAYOUT_TRANSITION",
         "prior_access = "
         "VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT(VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_"
         "BIT)",
         "write_barriers = 0",
         "command = vkCmdPipelineBarrier",
         "prior_command = vkCmdEndRenderingKHR",
     }},
    // Observed on SwiftShader when running the following tests:
    //
    //     ReadOnlyFeedbackLoopTest.ReadOnlyDepthFeedbackLoopDrawThenDepthStencilClear/ES3_Vulkan_SwiftShader
    //     VulkanPerformanceCounterTest.ClearColorBufferAndReadOnlyDepthStencilUsesSingleRenderPass*
    //     VulkanPerformanceCounterTest.ReadOnlyDepthStencilFeedbackLoopUsesSingleRenderPass/ES3_Vulkan_SwiftShader_PreferMonolithicPipelinesOverLibraries_NoMergeProgramPipelineCachesToGlobalCache
    {"SYNC-HAZARD-WRITE-AFTER-WRITE",
     false,
     {
         "message_type = ImageBarrierError",
         "hazard_type = WRITE_AFTER_WRITE",
         "access = SYNC_IMAGE_LAYOUT_TRANSITION",
         "prior_access = "
         "VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT(VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_"
         "BIT)",
         "write_barriers = 0",
         "command = vkCmdWaitEvents",
         "prior_command = vkCmdEndRenderingKHR",
     }},
    // Observed on old drivers without dynamic rendering and no support for the S8 format when
    // running the following test:
    //
    //     ClearTextureEXTTest.StencilTexture/ES3_Vulkan
    //
    // In this case ANGLE uses LOAD_OP_DONT_CARE and STORE_OP_DONT_CARE for the emulated depth
    // channel.
    //
    // Similarly, in the following test:
    //
    //     TraceTest.scary_teacher_3d
    //
    // LOAD_OP_LOAD and STORE_OP_STORE are used to preserve the depth channel without the NONE ops.
    {"SYNC-HAZARD-WRITE-AFTER-WRITE",
     false,
     {
         "message_type = RenderPassStoreOpError",
         "hazard_type = WRITE_AFTER_WRITE",
         "access = "
         "VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT(VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_"
         "BIT)",
         "prior_access = SYNC_IMAGE_LAYOUT_TRANSITION",
         "write_barriers = "
         "VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT|VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT("
         "VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT)",
         "command = vkCmdEndRenderPass",
         "prior_command = vkCmdPipelineBarrier",
         "store_op = VK_ATTACHMENT_STORE_OP_DONT_CARE",
     }},
    {"SYNC-HAZARD-WRITE-AFTER-WRITE",
     false,
     {
         "message_type = RenderPassStoreOpError",
         "hazard_type = WRITE_AFTER_WRITE",
         "access = "
         "VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT(VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_"
         "BIT)",
         "prior_access = SYNC_IMAGE_LAYOUT_TRANSITION",
         "write_barriers = "
         "VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT|VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT|VK_"
         "PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT(VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT)",
         "command = vkCmdEndRenderPass",
         "prior_command = vkCmdPipelineBarrier",
         "store_op = VK_ATTACHMENT_STORE_OP_STORE",
     }},
};

// Messages that are only generated with MSRTT emulation.  Some of these are syncval bugs (discussed
// in https://gitlab.khronos.org/vulkan/vulkan/-/issues/3840)
constexpr vk::SkippedSyncvalMessage kSkippedSyncvalMessagesWithMSRTTEmulation[] = {
    // Unknown whether ANGLE or syncval bug.
    // To repro: see http://anglebug.com/40644740#comment69
    {"SYNC-HAZARD-WRITE-AFTER-WRITE",
     false,
     // TODO: it seems if this filter is removed then the error will be
     // intersepted by a different filter. Investigate the nature of the
     // error if necessary how to improve its detection.
     {
         "message_type = RenderPassLayoutTransitionError",
         "access = SYNC_IMAGE_LAYOUT_TRANSITION",
         "prior_access = "
         "VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT(VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT)",
         "command = vkCmdBeginRenderPass",
         "prior_command = vkCmdEndRenderPass",
         "old_layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL",
         "new_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL",
     }},
    // Unknown whether ANGLE or syncval bug.  See http://anglebug.com/495832130
    {"SYNC-HAZARD-WRITE-AFTER-WRITE",
     false,
     {
         "message_type = ImageSubresourceRangeError",
         "access = VK_PIPELINE_STAGE_2_CLEAR_BIT(VK_ACCESS_2_TRANSFER_WRITE_BIT)",
         "prior_access = "
         "VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT(VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_"
         "BIT)",
         "command = vkCmdClearDepthStencilImage",
         "prior_command = vkCmdNextSubpass",
     }},
    // When one aspect of depth/stencil is LOAD and the other is DONT_CARE and the image is
    // previously initialized, the transfer->depth_stencil barrier's dst access does not include
    // DEPTH_STENCIL_WRITE correctly.  See
    // MSRTTES3Test.RenderToTextureDepthOnly/ES3_1_Vulkan_SwiftShader_EnableMultisampledRenderToTexture_RobustResourceInit
    // for example.
    {"SYNC-HAZARD-WRITE-AFTER-WRITE",
     false,
     {
         "message_type = RenderPassLoadOpError",
         "access = "
         "VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT(VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_"
         "BIT)",
         "prior_access = VK_PIPELINE_STAGE_2_CLEAR_BIT(VK_ACCESS_2_TRANSFER_WRITE_BIT)",
         "command = vkCmdBeginRenderPass",
         "prior_command = vkCmdClearDepthStencilImage",
     }},
};

enum class DebugMessageReport
{
    Ignore,
    Print,
};

bool IsMessageInSkipList(const char *messageId,
                         const char *message,
                         const char *const skippedList[],
                         size_t skippedListSize)
{
    for (size_t index = 0; index < skippedListSize; ++index)
    {
        if (strstr(messageId, skippedList[index]) != nullptr)
        {
            return true;
        }
        if (strstr(message, skippedList[index]) != nullptr)
        {
            return true;
        }
    }

    return false;
}

bool SyncvalMessageMatchesSkip(const char *messageId,
                               const char *message,
                               const vk::SkippedSyncvalMessage &skip)
{
    // TODO(http://anglebug.com/391284743): Ongoing transition: textual matches -> extraProperties.
    // The skip should include at least one extraProperty
    ASSERT(skip.extraProperties[0]);

    if (strstr(messageId, skip.messageId) == nullptr)
    {
        return false;
    }
    // Check that all extraProperties entries are present in the message
    bool mismatch = false;
    for (uint32_t i = 0; i < kMaxSyncValExtraProperties; i++)
    {
        if (skip.extraProperties[i] == nullptr)
        {
            break;
        }
        if (strstr(message, skip.extraProperties[i]) == nullptr)
        {
            mismatch = true;
            break;
        }
    }
    return !mismatch;
}

// Suppress validation errors that are known.  Returns DebugMessageReport::Ignore in that case.
DebugMessageReport ShouldReportDebugMessage(Renderer *renderer,
                                            const char *messageId,
                                            const char *message)
{
    if (message == nullptr || messageId == nullptr)
    {
        return DebugMessageReport::Print;
    }

    // Check with non-syncval messages:
    const std::vector<const char *> &skippedMessages = renderer->getSkippedValidationMessages();
    if (IsMessageInSkipList(messageId, message, skippedMessages.data(), skippedMessages.size()))
    {
        return DebugMessageReport::Ignore;
    }

    // Then check with syncval messages:
    const bool isColorFramebufferFetchUsed = renderer->isColorFramebufferFetchUsed();

    for (const vk::SkippedSyncvalMessage &skip : renderer->getSkippedSyncvalMessages())
    {
        if (!SyncvalMessageMatchesSkip(messageId, message, skip))
        {
            continue;
        }

        if (skip.isDueToNonConformantCoherentColorFramebufferFetch)
        {
            // If the error is due to exposing coherent framebuffer fetch (without
            // VK_EXT_rasterization_order_attachment_access), but framebuffer fetch has not been
            // used by the application, report it.
            //
            // Note that currently syncval doesn't support the
            // VK_EXT_rasterization_order_attachment_access extension, so the syncval messages would
            // continue to be produced despite the extension.
            constexpr bool kSyncValSupportsRasterizationOrderExtension = false;
            const bool hasRasterizationOrderExtension =
                renderer->getFeatures().supportsRasterizationOrderAttachmentAccess.enabled &&
                kSyncValSupportsRasterizationOrderExtension;
            if (!isColorFramebufferFetchUsed || hasRasterizationOrderExtension)
            {
                return DebugMessageReport::Print;
            }
        }

        // Ignore the message as it matched one the the skips
        return DebugMessageReport::Ignore;
    }

    // Message didn't match any skips, report
    return DebugMessageReport::Print;
}

const char *GetVkObjectTypeName(VkObjectType type)
{
    switch (type)
    {
        case VK_OBJECT_TYPE_UNKNOWN:
            return "Unknown";
        case VK_OBJECT_TYPE_INSTANCE:
            return "Instance";
        case VK_OBJECT_TYPE_PHYSICAL_DEVICE:
            return "Physical Device";
        case VK_OBJECT_TYPE_DEVICE:
            return "Device";
        case VK_OBJECT_TYPE_QUEUE:
            return "Queue";
        case VK_OBJECT_TYPE_SEMAPHORE:
            return "Semaphore";
        case VK_OBJECT_TYPE_COMMAND_BUFFER:
            return "Command Buffer";
        case VK_OBJECT_TYPE_FENCE:
            return "Fence";
        case VK_OBJECT_TYPE_DEVICE_MEMORY:
            return "Device Memory";
        case VK_OBJECT_TYPE_BUFFER:
            return "Buffer";
        case VK_OBJECT_TYPE_IMAGE:
            return "Image";
        case VK_OBJECT_TYPE_EVENT:
            return "Event";
        case VK_OBJECT_TYPE_QUERY_POOL:
            return "Query Pool";
        case VK_OBJECT_TYPE_BUFFER_VIEW:
            return "Buffer View";
        case VK_OBJECT_TYPE_IMAGE_VIEW:
            return "Image View";
        case VK_OBJECT_TYPE_SHADER_MODULE:
            return "Shader Module";
        case VK_OBJECT_TYPE_PIPELINE_CACHE:
            return "Pipeline Cache";
        case VK_OBJECT_TYPE_PIPELINE_LAYOUT:
            return "Pipeline Layout";
        case VK_OBJECT_TYPE_RENDER_PASS:
            return "Render Pass";
        case VK_OBJECT_TYPE_PIPELINE:
            return "Pipeline";
        case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT:
            return "Descriptor Set Layout";
        case VK_OBJECT_TYPE_SAMPLER:
            return "Sampler";
        case VK_OBJECT_TYPE_DESCRIPTOR_POOL:
            return "Descriptor Pool";
        case VK_OBJECT_TYPE_DESCRIPTOR_SET:
            return "Descriptor Set";
        case VK_OBJECT_TYPE_FRAMEBUFFER:
            return "Framebuffer";
        case VK_OBJECT_TYPE_COMMAND_POOL:
            return "Command Pool";
        case VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION:
            return "Sampler YCbCr Conversion";
        case VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE:
            return "Descriptor Update Template";
        case VK_OBJECT_TYPE_SURFACE_KHR:
            return "Surface";
        case VK_OBJECT_TYPE_SWAPCHAIN_KHR:
            return "Swapchain";
        case VK_OBJECT_TYPE_DISPLAY_KHR:
            return "Display";
        case VK_OBJECT_TYPE_DISPLAY_MODE_KHR:
            return "Display Mode";
        case VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV:
            return "Indirect Commands Layout";
        case VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT:
            return "Debug Utils Messenger";
        case VK_OBJECT_TYPE_VALIDATION_CACHE_EXT:
            return "Validation Cache";
        case VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV:
            return "Acceleration Structure";
        default:
            return "<Unrecognized>";
    }
}

VKAPI_ATTR VkBool32 VKAPI_CALL
DebugUtilsMessenger(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
                    VkDebugUtilsMessageTypeFlagsEXT messageTypes,
                    const VkDebugUtilsMessengerCallbackDataEXT *callbackData,
                    void *userData)
{
    Renderer *renderer = static_cast<Renderer *>(userData);

    // VUID-VkDebugUtilsMessengerCallbackDataEXT-pMessage-parameter
    // pMessage must be a null-terminated UTF-8 string
    ASSERT(callbackData->pMessage != nullptr);

    // See if it's an issue we are aware of and don't want to be spammed about.
    // Always report the debug message if message ID is missing
    if (callbackData->pMessageIdName != nullptr &&
        ShouldReportDebugMessage(renderer, callbackData->pMessageIdName, callbackData->pMessage) ==
            DebugMessageReport::Ignore)
    {
        return VK_FALSE;
    }

    std::ostringstream log;
    if (callbackData->pMessageIdName != nullptr)
    {
        log << "[ " << callbackData->pMessageIdName << " ] ";
    }
    log << callbackData->pMessage << std::endl;

    // Aesthetic value based on length of the function name, line number, etc.
    constexpr size_t kStartIndent = 28;

    // Output the debug marker hierarchy under which this error has occurred.
    size_t indent = kStartIndent;
    if (callbackData->queueLabelCount > 0)
    {
        log << std::string(indent++, ' ') << "<Queue Label Hierarchy:>" << std::endl;
        for (uint32_t i = 0; i < callbackData->queueLabelCount; ++i)
        {
            log << std::string(indent++, ' ') << callbackData->pQueueLabels[i].pLabelName
                << std::endl;
        }
    }
    if (callbackData->cmdBufLabelCount > 0)
    {
        log << std::string(indent++, ' ') << "<Command Buffer Label Hierarchy:>" << std::endl;
        for (uint32_t i = 0; i < callbackData->cmdBufLabelCount; ++i)
        {
            log << std::string(indent++, ' ') << callbackData->pCmdBufLabels[i].pLabelName
                << std::endl;
        }
    }
    // Output the objects involved in this error message.
    if (callbackData->objectCount > 0)
    {
        for (uint32_t i = 0; i < callbackData->objectCount; ++i)
        {
            const char *objectName = callbackData->pObjects[i].pObjectName;
            const char *objectType = GetVkObjectTypeName(callbackData->pObjects[i].objectType);
            uint64_t objectHandle  = callbackData->pObjects[i].objectHandle;
            log << std::string(indent, ' ') << "Object: ";
            if (objectHandle == 0)
            {
                log << "VK_NULL_HANDLE";
            }
            else
            {
                log << "0x" << std::hex << objectHandle << std::dec;
            }
            log << " (type = " << objectType << "(" << callbackData->pObjects[i].objectType << "))";
            if (objectName)
            {
                log << " [" << objectName << "]";
            }
            log << std::endl;
        }
    }

    bool isError    = (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) != 0;
    std::string msg = log.str();

    if (isError)
    {
        ERR() << msg;
    }
    else
    {
        WARN() << msg;
    }

    return VK_FALSE;
}

VKAPI_ATTR void VKAPI_CALL
MemoryReportCallback(const VkDeviceMemoryReportCallbackDataEXT *callbackData, void *userData)
{
    Renderer *renderer = static_cast<Renderer *>(userData);
    renderer->processMemoryReportCallback(*callbackData);
}

gl::Version LimitVersionTo(const gl::Version &current, const gl::Version &lower)
{
    return std::min(current, lower);
}

[[maybe_unused]] bool FencePropertiesCompatibleWithAndroid(
    const VkExternalFenceProperties &externalFenceProperties)
{
    // handleType here is the external fence type -
    // we want type compatible with creating and export/dup() Android FD

    // Imported handleType that can be exported - need for vkGetFenceFdKHR()
    if ((externalFenceProperties.exportFromImportedHandleTypes &
         VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR) == 0)
    {
        return false;
    }

    // HandleTypes which can be specified at creating a fence
    if ((externalFenceProperties.compatibleHandleTypes &
         VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR) == 0)
    {
        return false;
    }

    constexpr VkExternalFenceFeatureFlags kFeatureFlags =
        (VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT_KHR |
         VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT_KHR);
    if ((externalFenceProperties.externalFenceFeatures & kFeatureFlags) != kFeatureFlags)
    {
        return false;
    }

    return true;
}

[[maybe_unused]] bool SemaphorePropertiesCompatibleWithAndroid(
    const VkExternalSemaphoreProperties &externalSemaphoreProperties)
{
    // handleType here is the external semaphore type -
    // we want type compatible with importing an Android FD

    constexpr VkExternalSemaphoreFeatureFlags kFeatureFlags =
        (VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR);
    if ((externalSemaphoreProperties.externalSemaphoreFeatures & kFeatureFlags) != kFeatureFlags)
    {
        return false;
    }

    return true;
}

// Exclude memory type indices that include the host-visible bit from VMA image suballocation.
uint32_t GetMemoryTypeBitsExcludingHostVisible(Renderer *renderer,
                                               VkMemoryPropertyFlags propertyFlags,
                                               uint32_t availableMemoryTypeBits)
{
    const vk::MemoryProperties &memoryProperties = renderer->getMemoryProperties();
    ASSERT(memoryProperties.getMemoryTypeCount() <= 32);
    uint32_t memoryTypeBitsOut = availableMemoryTypeBits;

    // For best allocation results, the memory type indices that include the host-visible flag bit
    // are removed.
    for (size_t memoryIndex : angle::BitSet<32>(availableMemoryTypeBits))
    {
        VkMemoryPropertyFlags memoryFlags =
            memoryProperties.getMemoryType(static_cast<uint32_t>(memoryIndex)).propertyFlags;
        if ((memoryFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)
        {
            memoryTypeBitsOut &= ~(angle::Bit<uint32_t>(memoryIndex));
            continue;
        }

        // If the protected bit is not required, all memory type indices with this bit should be
        // ignored.
        if ((memoryFlags & ~propertyFlags & VK_MEMORY_PROPERTY_PROTECTED_BIT) != 0)
        {
            memoryTypeBitsOut &= ~(angle::Bit<uint32_t>(memoryIndex));
        }
    }

    return memoryTypeBitsOut;
}

// Header data type used for the pipeline cache.
ANGLE_ENABLE_STRUCT_PADDING_WARNINGS

class CacheDataHeader
{
  public:
    void setData(uint32_t compressedDataCRC,
                 uint32_t cacheDataSize,
                 size_t numChunks,
                 size_t chunkIndex,
                 uint32_t chunkCRC)
    {
        mVersion           = kPipelineCacheVersion;
        mCompressedDataCRC = compressedDataCRC;
        mCacheDataSize     = cacheDataSize;
        SetBitField(mNumChunks, numChunks);
        SetBitField(mChunkIndex, chunkIndex);
        mChunkCRC = chunkCRC;
    }

    void getData(uint32_t *versionOut,
                 uint32_t *compressedDataCRCOut,
                 uint32_t *cacheDataSizeOut,
                 size_t *numChunksOut,
                 size_t *chunkIndexOut,
                 uint32_t *chunkCRCOut) const
    {
        *versionOut           = mVersion;
        *compressedDataCRCOut = mCompressedDataCRC;
        *cacheDataSizeOut     = mCacheDataSize;
        *numChunksOut         = static_cast<size_t>(mNumChunks);
        *chunkIndexOut        = static_cast<size_t>(mChunkIndex);
        *chunkCRCOut          = mChunkCRC;
    }

  private:
    // For pipeline cache, the values stored in key data has the following order:
    // {headerVersion, compressedDataCRC, originalCacheSize, numChunks, chunkIndex, chunkCRC;
    // chunkCompressedData}. The header values are used to validate the data. For example, if the
    // original and compressed sizes are 70000 bytes (68k) and 68841 bytes (67k), the compressed
    // data will be divided into two chunks: {ver,crc0,70000,2,0;34421 bytes} and
    // {ver,crc1,70000,2,1;34420 bytes}.
    // The version is used to keep track of the cache format. Please note that kPipelineCacheVersion
    // must be incremented by 1 in case of any updates to the cache header or data structure. While
    // it is possible to modify the fields in the header, it is recommended to keep the version on
    // top and the same size unless absolutely necessary.

    uint32_t mVersion;
    uint32_t mCompressedDataCRC;
    uint32_t mCacheDataSize;
    uint16_t mNumChunks;
    uint16_t mChunkIndex;
    uint32_t mChunkCRC;
};

ANGLE_DISABLE_STRUCT_PADDING_WARNINGS

// Pack header data for the pipeline cache key data.
void PackHeaderDataForPipelineCache(uint32_t compressedDataCRC,
                                    uint32_t cacheDataSize,
                                    size_t numChunks,
                                    size_t chunkIndex,
                                    uint32_t chunkCRC,
                                    CacheDataHeader *dataOut)
{
    dataOut->setData(compressedDataCRC, cacheDataSize, numChunks, chunkIndex, chunkCRC);
}

// Unpack header data from the pipeline cache key data.
void UnpackHeaderDataForPipelineCache(CacheDataHeader *data,
                                      uint32_t *versionOut,
                                      uint32_t *compressedDataCRCOut,
                                      uint32_t *cacheDataSizeOut,
                                      size_t *numChunksOut,
                                      size_t *chunkIndexOut,
                                      uint32_t *chunkCRCOut)
{
    data->getData(versionOut, compressedDataCRCOut, cacheDataSizeOut, numChunksOut, chunkIndexOut,
                  chunkCRCOut);
}

void ComputePipelineCacheVkChunkKey(const VkPhysicalDeviceProperties &physicalDeviceProperties,
                                    const size_t slotIndex,
                                    const size_t chunkIndex,
                                    angle::BlobCacheKey *hashOut)
{
    angle::BlobCacheHasher hasher;
    hasher.Init();

    // Start with the name
    const char *pipelineCacheName = "ANGLE Pipeline Cache: ";
    hasher.Update(pipelineCacheName, strlen(pipelineCacheName));

    // Add the pipeline cache UUID to make sure the blob cache always gives a compatible pipeline
    // cache. pipelineCacheUUID is a uint8_t[VK_UUID_SIZE]
    hasher.Update(&physicalDeviceProperties.pipelineCacheUUID, VK_UUID_SIZE);

    // Add the vendor and device id too for good measure.
    angle::UpdateHashWithValue(hasher, physicalDeviceProperties.vendorID);
    angle::UpdateHashWithValue(hasher, physicalDeviceProperties.deviceID);

    // Add slotIndex and chunkIndex to generate unique keys.
    angle::UpdateHashWithValue(hasher, slotIndex);
    angle::UpdateHashWithValue(hasher, chunkIndex);

    ASSERT(hashOut);
    hasher.Final();
    memcpy(hashOut->data(), hasher.Digest(), angle::kBlobCacheKeyLength);
}

struct PipelineCacheVkChunkInfo
{
    const uint8_t *data;
    size_t dataSize;
    uint32_t crc;
    angle::BlobCacheKey cacheHash;
};

// Enough to store 32M data using 64K chunks.
constexpr size_t kFastPipelineCacheVkChunkInfosSize = 512;
using PipelineCacheVkChunkInfos =
    angle::FastVector<PipelineCacheVkChunkInfo, kFastPipelineCacheVkChunkInfosSize>;

PipelineCacheVkChunkInfos GetPipelineCacheVkChunkInfos(Renderer *renderer,
                                                       const angle::MemoryBuffer &compressedData,
                                                       const size_t numChunks,
                                                       const size_t chunkSize,
                                                       const size_t slotIndex);

// Returns the number of stored chunks.  "lastNumStoredChunks" is the number of chunks,
// stored in the last call.  If it is positive, function will only restore missing chunks.
size_t StorePipelineCacheVkChunks(vk::GlobalOps *globalOps,
                                  Renderer *renderer,
                                  const size_t lastNumStoredChunks,
                                  const PipelineCacheVkChunkInfos &chunkInfos,
                                  const size_t cacheDataSize,
                                  angle::MemoryBuffer *scratchBuffer);

// Erasing is done by writing 1/0-sized chunks starting from the startChunk.
void ErasePipelineCacheVkChunks(vk::GlobalOps *globalOps,
                                Renderer *renderer,
                                const size_t startChunk,
                                const size_t numChunks,
                                const size_t slotIndex,
                                angle::MemoryBuffer *scratchBuffer);

void CompressAndStorePipelineCacheVk(vk::GlobalOps *globalOps,
                                     Renderer *renderer,
                                     const std::vector<uint8_t> &cacheData,
                                     const size_t maxTotalSize)
{
    // Though the pipeline cache will be compressed and divided into several chunks to store in blob
    // cache, the largest total size of blob cache is only 2M in android now, so there is no use to
    // handle big pipeline cache when android will reject it finally.
    if (cacheData.size() >= maxTotalSize)
    {
        static bool warned = false;
        if (!warned)
        {
            // TODO: handle the big pipeline cache. http://anglebug.com/42263322
            WARN() << "Skip syncing pipeline cache data when it's larger than maxTotalSize. "
                      "(this message will no longer repeat)";
            warned = true;
        }
        return;
    }

    // To make it possible to store more pipeline cache data, compress the whole pipelineCache.
    angle::MemoryBuffer compressedData;

    if (!angle::CompressBlob(cacheData.size(), cacheData.data(), &compressedData))
    {
        WARN() << "Skip syncing pipeline cache data as it failed compression.";
        return;
    }

    // If the size of compressedData is larger than (kMaxBlobCacheSize - sizeof(numChunks)),
    // the pipelineCache still can't be stored in blob cache. Divide the large compressed
    // pipelineCache into several parts to store separately. There is no function to
    // query the limit size in android.
    constexpr size_t kMaxBlobCacheSize = 64 * 1024;

    const size_t numChunks = UnsignedCeilDivide(static_cast<unsigned int>(compressedData.size()),
                                                kMaxBlobCacheSize - sizeof(CacheDataHeader));
    ASSERT(numChunks <= UINT16_MAX);
    const size_t chunkSize = UnsignedCeilDivide(static_cast<unsigned int>(compressedData.size()),
                                                static_cast<unsigned int>(numChunks));

    angle::MemoryBuffer scratchBuffer;
    if (!scratchBuffer.resize(sizeof(CacheDataHeader) + chunkSize))
    {
        WARN() << "Skip syncing pipeline cache data due to out of memory.";
        return;
    }

    size_t previousSlotIndex = 0;
    const size_t slotIndex   = renderer->getNextPipelineCacheBlobCacheSlotIndex(&previousSlotIndex);
    const size_t previousNumChunks = renderer->updatePipelineCacheChunkCount(numChunks);
    const bool isSlotChanged       = (slotIndex != previousSlotIndex);

    PipelineCacheVkChunkInfos chunkInfos =
        GetPipelineCacheVkChunkInfos(renderer, compressedData, numChunks, chunkSize, slotIndex);

    // Store all chunks without checking if they already exist (because they can't).
    size_t numStoredChunks = StorePipelineCacheVkChunks(globalOps, renderer, 0, chunkInfos,
                                                        cacheData.size(), &scratchBuffer);
    ASSERT(numStoredChunks == numChunks);

    // Erase all chunks from the previous slot or any trailing chunks from the current slot.
    ASSERT(renderer->getFeatures().useDualPipelineBlobCacheSlots.enabled == isSlotChanged);
    if (isSlotChanged || previousNumChunks > numChunks)
    {
        const size_t startChunk = isSlotChanged ? 0 : numChunks;
        ErasePipelineCacheVkChunks(globalOps, renderer, startChunk, previousNumChunks,
                                   previousSlotIndex, &scratchBuffer);
    }

    if (!renderer->getFeatures().verifyPipelineCacheInBlobCache.enabled)
    {
        // No need to verify and restore possibly evicted chunks.
        return;
    }

    // Verify and restore possibly evicted chunks.
    do
    {
        const size_t lastNumStoredChunks = numStoredChunks;
        numStoredChunks = StorePipelineCacheVkChunks(globalOps, renderer, lastNumStoredChunks,
                                                     chunkInfos, cacheData.size(), &scratchBuffer);
        // Number of stored chunks must decrease so the loop can eventually exit.
        ASSERT(numStoredChunks < lastNumStoredChunks);

        // If blob cache evicts old items first, any possibly evicted chunks in the first call,
        // should have been restored in the above call without triggering another eviction, so no
        // need to continue the loop.
    } while (!renderer->getFeatures().hasBlobCacheThatEvictsOldItemsFirst.enabled &&
             numStoredChunks > 0);
}

PipelineCacheVkChunkInfos GetPipelineCacheVkChunkInfos(Renderer *renderer,
                                                       const angle::MemoryBuffer &compressedData,
                                                       const size_t numChunks,
                                                       const size_t chunkSize,
                                                       const size_t slotIndex)
{
    const VkPhysicalDeviceProperties &physicalDeviceProperties =
        renderer->getPhysicalDeviceProperties();

    PipelineCacheVkChunkInfos chunkInfos(numChunks);
    uint32_t chunkCrc = kEnableCRCForPipelineCache ? angle::InitCRC32() : 0;

    for (size_t chunkIndex = 0; chunkIndex < numChunks; ++chunkIndex)
    {
        const size_t compressedOffset = chunkIndex * chunkSize;
        const uint8_t *data           = compressedData.data() + compressedOffset;
        const size_t dataSize = std::min(chunkSize, compressedData.size() - compressedOffset);

        // Create unique hash key.
        angle::BlobCacheKey cacheHash;
        ComputePipelineCacheVkChunkKey(physicalDeviceProperties, slotIndex, chunkIndex, &cacheHash);

        if (kEnableCRCForPipelineCache)
        {
            // Generate running CRC. Last chunk will have CRC of the entire data.
            chunkCrc = angle::UpdateCRC32(chunkCrc, data, dataSize);
        }

        chunkInfos[chunkIndex] = PipelineCacheVkChunkInfo{data, dataSize, chunkCrc, cacheHash};
    }

    return chunkInfos;
}

size_t StorePipelineCacheVkChunks(vk::GlobalOps *globalOps,
                                  Renderer *renderer,
                                  const size_t lastNumStoredChunks,
                                  const PipelineCacheVkChunkInfos &chunkInfos,
                                  const size_t cacheDataSize,
                                  angle::MemoryBuffer *scratchBuffer)
{
    // Store chunks in revers order, so when 0 chunk is available - all chunks are available.

    angle::FastVector<bool, kFastPipelineCacheVkChunkInfosSize> isMissing;
    size_t numChunksToStore = chunkInfos.size();

    // Need to check existing chunks if this is not the first time this function is called.
    if (lastNumStoredChunks > 0)
    {
        isMissing.resize(chunkInfos.size());
        numChunksToStore = 0;

        // Defer storing chunks until all missing chunks are found to avoid unnecessary stores.
        size_t chunkIndex = chunkInfos.size();
        while (chunkIndex > 0)
        {
            --chunkIndex;
            const PipelineCacheVkChunkInfo &chunkInfo = chunkInfos[chunkIndex];

            angle::BlobCacheValue value;
            if (globalOps->getBlob(chunkInfo.cacheHash, &value) &&
                value.size() == sizeof(CacheDataHeader) + chunkInfo.dataSize)
            {
                if (renderer->getFeatures().hasBlobCacheThatEvictsOldItemsFirst.enabled)
                {
                    // No need to check next chunks, since they are newer than the current and
                    // should also be present.
                    break;
                }
                continue;
            }

            isMissing[chunkIndex] = true;
            ++numChunksToStore;

            if (numChunksToStore == lastNumStoredChunks)
            {
                // No need to restore missing chunks, since new number is already same as was stored
                // last time.
                static bool warned = false;
                if (!warned)
                {
                    WARN() << "Skip syncing pipeline cache data due to not able to store "
                           << numChunksToStore << " chunks (out of " << chunkInfos.size()
                           << ") into the blob cache. (this message will no longer repeat)";
                    warned = true;
                }
                return 0;
            }
        }

        if (numChunksToStore == 0)
        {
            return 0;
        }
    }

    // Now store/restore chunks.

    // Last chunk have CRC of the entire data.
    const uint32_t compressedDataCRC = chunkInfos.back().crc;

    ASSERT(scratchBuffer != nullptr);
    angle::MemoryBuffer &keyData = *scratchBuffer;

    size_t chunkIndex = chunkInfos.size();
    while (chunkIndex > 0)
    {
        --chunkIndex;
        if (lastNumStoredChunks > 0 && !isMissing[chunkIndex])
        {
            // Skip restoring chunk if it is not missing.
            continue;
        }
        const PipelineCacheVkChunkInfo &chunkInfo = chunkInfos[chunkIndex];

        // Add the header data, followed by the compressed data.
        ASSERT(cacheDataSize <= UINT32_MAX);
        CacheDataHeader headerData = {};
        PackHeaderDataForPipelineCache(compressedDataCRC, static_cast<uint32_t>(cacheDataSize),
                                       chunkInfos.size(), chunkIndex, chunkInfo.crc, &headerData);
        keyData.setSize(sizeof(CacheDataHeader) + chunkInfo.dataSize);
        memcpy(keyData.data(), &headerData, sizeof(CacheDataHeader));
        memcpy(keyData.data() + sizeof(CacheDataHeader), chunkInfo.data, chunkInfo.dataSize);

        globalOps->putBlob(chunkInfo.cacheHash, keyData);
    }

    return numChunksToStore;
}

void ErasePipelineCacheVkChunks(vk::GlobalOps *globalOps,
                                Renderer *renderer,
                                const size_t startChunk,
                                const size_t numChunks,
                                const size_t slotIndex,
                                angle::MemoryBuffer *scratchBuffer)
{
    const VkPhysicalDeviceProperties &physicalDeviceProperties =
        renderer->getPhysicalDeviceProperties();

    ASSERT(scratchBuffer != nullptr);
    angle::MemoryBuffer &keyData = *scratchBuffer;

    keyData.setSize(
        renderer->getFeatures().useEmptyBlobsToEraseOldPipelineCacheFromBlobCache.enabled ? 0 : 1);

    // Fill data (if any) with zeroes for security.
    memset(keyData.data(), 0, keyData.size());

    for (size_t chunkIndex = startChunk; chunkIndex < numChunks; ++chunkIndex)
    {
        egl::BlobCache::Key chunkCacheHash;
        ComputePipelineCacheVkChunkKey(physicalDeviceProperties, slotIndex, chunkIndex,
                                       &chunkCacheHash);
        globalOps->putBlob(chunkCacheHash, keyData);
    }
}

class CompressAndStorePipelineCacheTask : public angle::Closure
{
  public:
    CompressAndStorePipelineCacheTask(vk::GlobalOps *globalOps,
                                      Renderer *renderer,
                                      std::vector<uint8_t> &&cacheData,
                                      size_t kMaxTotalSize)
        : mGlobalOps(globalOps),
          mRenderer(renderer),
          mCacheData(std::move(cacheData)),
          mMaxTotalSize(kMaxTotalSize)
    {}

    void operator()() override
    {
        ANGLE_TRACE_EVENT0("gpu.angle", "CompressAndStorePipelineCacheVk");
        CompressAndStorePipelineCacheVk(mGlobalOps, mRenderer, mCacheData, mMaxTotalSize);
    }

  private:
    vk::GlobalOps *mGlobalOps;
    Renderer *mRenderer;
    std::vector<uint8_t> mCacheData;
    size_t mMaxTotalSize;
};

angle::Result GetAndDecompressPipelineCacheVk(vk::ErrorContext *context,
                                              vk::GlobalOps *globalOps,
                                              angle::MemoryBuffer *uncompressedData,
                                              bool *success)
{
    // Make sure that the bool output is initialized to false.
    *success = false;

    Renderer *renderer = context->getRenderer();

    const VkPhysicalDeviceProperties &physicalDeviceProperties =
        renderer->getPhysicalDeviceProperties();

    const size_t firstSlotIndex = renderer->getNextPipelineCacheBlobCacheSlotIndex(nullptr);
    size_t slotIndex            = firstSlotIndex;

    angle::BlobCacheKey chunkCacheHash;
    angle::BlobCacheValue keyData;

    // Iterate over available slots until data is found (only expected single slot with data).
    while (true)
    {
        // Compute the hash key of chunkIndex 0 and find the first cache data in blob cache.
        ComputePipelineCacheVkChunkKey(physicalDeviceProperties, slotIndex, 0, &chunkCacheHash);

        if (globalOps->getBlob(chunkCacheHash, &keyData) &&
            keyData.size() >= sizeof(CacheDataHeader))
        {
            // Found slot with data.
            break;
        }
        // Nothing in the cache for current slotIndex.

        slotIndex = renderer->getNextPipelineCacheBlobCacheSlotIndex(nullptr);
        if (slotIndex == firstSlotIndex)
        {
            // Nothing in all slots.
            return angle::Result::Continue;
        }
        // Try next slot.
    }

    // Get the number of chunks and other values from the header for data validation.
    uint32_t cacheVersion;
    uint32_t compressedDataCRC;
    uint32_t uncompressedCacheDataSize;
    size_t numChunks;
    size_t chunkIndex0;
    uint32_t chunkCRC;

    CacheDataHeader headerData = {};
    memcpy(&headerData, keyData.data(), sizeof(CacheDataHeader));
    UnpackHeaderDataForPipelineCache(&headerData, &cacheVersion, &compressedDataCRC,
                                     &uncompressedCacheDataSize, &numChunks, &chunkIndex0,
                                     &chunkCRC);
    if (cacheVersion == kPipelineCacheVersion)
    {
        // The data must not contain corruption.
        if (chunkIndex0 != 0 || numChunks == 0 || uncompressedCacheDataSize == 0)
        {
            FATAL() << "Unexpected values while unpacking chunk index 0: " << "cacheVersion = "
                    << cacheVersion << ", chunkIndex = " << chunkIndex0
                    << ", numChunks = " << numChunks
                    << ", uncompressedCacheDataSize = " << uncompressedCacheDataSize;
        }
    }
    else
    {
        WARN() << "Change in cache header version detected: " << "newVersion = "
               << kPipelineCacheVersion << ", existingVersion = " << cacheVersion;

        return angle::Result::Continue;
    }

    renderer->updatePipelineCacheChunkCount(numChunks);

    size_t chunkSize      = keyData.size() - sizeof(CacheDataHeader);
    size_t compressedSize = 0;

    uint32_t computedChunkCRC = kEnableCRCForPipelineCache ? angle::InitCRC32() : 0;

    // Allocate enough memory.
    angle::MemoryBuffer compressedData;
    ANGLE_VK_CHECK(context, compressedData.resize(chunkSize * numChunks),
                   VK_ERROR_INITIALIZATION_FAILED);

    // To combine the parts of the pipelineCache data.
    for (size_t chunkIndex = 0; chunkIndex < numChunks; ++chunkIndex)
    {
        // Avoid processing 0 chunk again.
        if (chunkIndex > 0)
        {
            // Get the unique key by chunkIndex.
            ComputePipelineCacheVkChunkKey(physicalDeviceProperties, slotIndex, chunkIndex,
                                           &chunkCacheHash);

            if (!globalOps->getBlob(chunkCacheHash, &keyData) ||
                keyData.size() < sizeof(CacheDataHeader))
            {
                // Can't find every part of the cache data.
                WARN() << "Failed to get pipeline cache chunk " << chunkIndex << " of "
                       << numChunks;
                return angle::Result::Continue;
            }

            // Validate the header values and ensure there is enough space to store.
            uint32_t checkCacheVersion;
            uint32_t checkCompressedDataCRC;
            uint32_t checkUncompressedCacheDataSize;
            size_t checkNumChunks;
            size_t checkChunkIndex;

            memcpy(&headerData, keyData.data(), sizeof(CacheDataHeader));
            UnpackHeaderDataForPipelineCache(
                &headerData, &checkCacheVersion, &checkCompressedDataCRC,
                &checkUncompressedCacheDataSize, &checkNumChunks, &checkChunkIndex, &chunkCRC);

            chunkSize = keyData.size() - sizeof(CacheDataHeader);
            bool isHeaderDataCorrupted =
                (checkCacheVersion != cacheVersion) || (checkNumChunks != numChunks) ||
                (checkUncompressedCacheDataSize != uncompressedCacheDataSize) ||
                (checkCompressedDataCRC != compressedDataCRC) || (checkChunkIndex != chunkIndex) ||
                (compressedData.size() < compressedSize + chunkSize);
            if (isHeaderDataCorrupted)
            {
                WARN() << "Pipeline cache chunk header corrupted or old chunk: "
                       << "checkCacheVersion = " << checkCacheVersion
                       << ", cacheVersion = " << cacheVersion
                       << ", checkNumChunks = " << checkNumChunks << ", numChunks = " << numChunks
                       << ", checkUncompressedCacheDataSize = " << checkUncompressedCacheDataSize
                       << ", uncompressedCacheDataSize = " << uncompressedCacheDataSize
                       << ", checkCompressedDataCRC = " << checkCompressedDataCRC
                       << ", compressedDataCRC = " << compressedDataCRC
                       << ", checkChunkIndex = " << checkChunkIndex
                       << ", chunkIndex = " << chunkIndex
                       << ", compressedData.size() = " << compressedData.size()
                       << ", (compressedSize + chunkSize) = " << (compressedSize + chunkSize);
                return angle::Result::Continue;
            }
        }

        // CRC of the chunk should match the values in the header.
        if (kEnableCRCForPipelineCache)
        {
            computedChunkCRC = angle::UpdateCRC32(
                computedChunkCRC, keyData.data() + sizeof(CacheDataHeader), chunkSize);
            if (computedChunkCRC != chunkCRC)
            {
                if (chunkCRC == 0)
                {
                    // This could be due to the cache being populated before
                    // kEnableCRCForPipelineCache was enabled.
                    WARN() << "Expected chunk CRC = " << chunkCRC
                           << ", Actual chunk CRC = " << computedChunkCRC;
                    return angle::Result::Continue;
                }

                // If the expected CRC is non-zero and does not match the actual CRC from the data,
                // there has been an unexpected data corruption.
                ERR() << "Expected chunk CRC = " << chunkCRC
                      << ", Actual chunk CRC = " << computedChunkCRC;

                ERR() << "Data extracted from the cache headers: " << std::hex
                      << ", compressedDataCRC = 0x" << compressedDataCRC << "numChunks = 0x"
                      << numChunks << ", uncompressedCacheDataSize = 0x"
                      << uncompressedCacheDataSize;

                FATAL() << "CRC check failed; possible pipeline cache data corruption.";
                return angle::Result::Stop;
            }
        }

        memcpy(compressedData.data() + compressedSize, keyData.data() + sizeof(CacheDataHeader),
               chunkSize);
        compressedSize += chunkSize;
    }

    // CRC for compressed data and size for decompressed data should match the values in the header.
    if (kEnableCRCForPipelineCache)
    {
        // Last chunk have CRC of the entire data.
        uint32_t computedCompressedDataCRC = computedChunkCRC;
        // Per chunk CRC check must handle any data corruption.  Assert is possible only if header
        // was incorrectly written in the first place (bug in the code), or all chunks headers were
        // corrupted in the exact same way, which is almost impossible.
        ASSERT(computedCompressedDataCRC == compressedDataCRC);
    }

    ANGLE_VK_CHECK(context,
                   angle::DecompressBlob(compressedData.data(), compressedSize,
                                         uncompressedCacheDataSize, uncompressedData),
                   VK_ERROR_INITIALIZATION_FAILED);

    if (uncompressedData->size() != uncompressedCacheDataSize)
    {
        WARN() << "Expected uncompressed size = " << uncompressedCacheDataSize
               << ", Actual uncompressed size = " << uncompressedData->size();
        return angle::Result::Continue;
    }

    *success = true;
    return angle::Result::Continue;
}

// Environment variable (and associated Android property) to enable Vulkan debug-utils markers
constexpr char kEnableDebugMarkersVarName[]      = "ANGLE_ENABLE_DEBUG_MARKERS";
constexpr char kEnableDebugMarkersPropertyName[] = "debug.angle.markers";

ANGLE_INLINE gl::ShadingRate GetShadingRateEXTFromVkExtent(const VkExtent2D &extent)
{
    if (extent.width == 1)
    {
        if (extent.height == 1)
        {
            return gl::ShadingRate::_1x1;
        }
        else if (extent.height == 2)
        {
            return gl::ShadingRate::_1x2;
        }
        else if (extent.height == 4)
        {
            return gl::ShadingRate::_1x4;
        }
    }
    else if (extent.width == 2)
    {
        if (extent.height == 1)
        {
            return gl::ShadingRate::_2x1;
        }
        else if (extent.height == 2)
        {
            return gl::ShadingRate::_2x2;
        }
        else if (extent.height == 4)
        {
            return gl::ShadingRate::_2x4;
        }
    }
    else if (extent.width == 4)
    {
        if (extent.height == 1)
        {
            return gl::ShadingRate::_4x1;
        }
        else if (extent.height == 2)
        {
            return gl::ShadingRate::_4x2;
        }
        else if (extent.height == 4)
        {
            return gl::ShadingRate::_4x4;
        }
    }

    return gl::ShadingRate::Undefined;
}

void DumpPipelineCacheGraph(Renderer *renderer, const std::ostringstream &graph)
{
    std::string dumpPath = renderer->getPipelineCacheGraphDumpPath();
    if (dumpPath.size() == 0)
    {
        WARN() << "No path supplied for pipeline cache graph dump!";
        return;
    }

    static std::atomic<uint32_t> sContextIndex(0);
    std::string filename = dumpPath;
    filename += angle::GetExecutableName();
    filename += std::to_string(sContextIndex.fetch_add(1));
    filename += ".dump";

    INFO() << "Dumping pipeline cache transition graph to: \"" << filename << "\"";

    std::ofstream out = std::ofstream(filename, std::ofstream::binary);
    if (!out.is_open())
    {
        ERR() << "Failed to open \"" << filename << "\"";
    }

    out << "digraph {\n" << " node [shape=box";
    if (renderer->getFeatures().supportsPipelineCreationFeedback.enabled)
    {
        out << ",color=green";
    }
    out << "]\n";
    out << graph.str();
    out << "}\n";
    out.close();
}

bool CanSupportMSRTSSForRGBA8(Renderer *renderer)
{
    // The support is checked for a basic 2D texture.
    constexpr VkImageUsageFlags kImageUsageFlags = vk::kImageUsageTransferBits |
                                                   VK_IMAGE_USAGE_SAMPLED_BIT |
                                                   VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    VkImageCreateFlags imageCreateFlags =
        GetMinimalImageCreateFlags(renderer, gl::TextureType::_2D, kImageUsageFlags) |
        VK_IMAGE_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT;

    bool supportsMSRTTUsageRGBA8 = vk::ImageHelper::FormatSupportsUsage(
        renderer, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
        kImageUsageFlags, imageCreateFlags, nullptr, nullptr,
        vk::ImageHelper::FormatSupportCheck::RequireMultisampling);
    bool supportsMSRTTUsageRGBA8SRGB = vk::ImageHelper::FormatSupportsUsage(
        renderer, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
        kImageUsageFlags, imageCreateFlags, nullptr, nullptr,
        vk::ImageHelper::FormatSupportCheck::RequireMultisampling);

    return supportsMSRTTUsageRGBA8 && supportsMSRTTUsageRGBA8SRGB;
}

VkResult RetrieveDeviceLostInfoFromDevice(VkDevice device,
                                          VkPhysicalDeviceFaultFeaturesEXT faultFeatures)
{
    // For VkDeviceFaultAddressTypeEXT in VK_EXT_device_fault
    constexpr const char *kDeviceFaultAddressTypeMessage[] = {
        "None",
        "InvalidRead",
        "InvalidWrite",
        "InvalidExecute",
        "InstructionPointerUnknown",
        "InstructionPointerInvalid",
        "InstructionPointerFault",
    };

    // At first, the data regarding the number of faults is collected, so the proper allocations can
    // be made to store the incoming data.
    VkDeviceFaultCountsEXT faultCounts = {};
    faultCounts.sType                  = VK_STRUCTURE_TYPE_DEVICE_FAULT_COUNTS_EXT;

    VkResult result = VK_CALL(vkGetDeviceFaultInfoEXT, device, &faultCounts, nullptr);
    if (result != VK_SUCCESS)
    {
        return result;
    }

    VkDeviceFaultInfoEXT faultInfos = {};
    faultInfos.sType                = VK_STRUCTURE_TYPE_DEVICE_FAULT_INFO_EXT;

    std::vector<VkDeviceFaultAddressInfoEXT> addressInfos(faultCounts.addressInfoCount);
    faultInfos.pAddressInfos = addressInfos.data();

    std::vector<VkDeviceFaultVendorInfoEXT> vendorInfos(faultCounts.vendorInfoCount);
    faultInfos.pVendorInfos = vendorInfos.data();

    // The vendor binary data will be logged in chunks of 4 bytes.
    uint32_t vendorBinaryDataChunkCount =
        (static_cast<uint32_t>(faultCounts.vendorBinarySize) + 3) / 4;
    std::vector<uint32_t> vendorBinaryDataChunks(vendorBinaryDataChunkCount, 0);
    faultInfos.pVendorBinaryData = vendorBinaryDataChunks.data();

    result = VK_CALL(vkGetDeviceFaultInfoEXT, device, &faultCounts, &faultInfos);
    if (result != VK_SUCCESS)
    {
        return result;
    }

    // Collect the fault information from the device.
    std::stringstream faultString;
    faultString << "Fault description: <" << faultInfos.description << ">" << std::endl;

    for (auto &addressFault : addressInfos)
    {
        // Based on the spec, The address precision is a power of two, and shows the lower and upper
        // address ranges where the error could be:
        // - lowerAddress = (reportedAddress & ~(addressPrecision - 1))
        // - upperAddress = (reportedAddress |  (addressPrecision - 1))
        // For example, if the reported address is 0x12345 and the precision is 16, it shows that
        // the address could be between 0x12340 and 0x1234F.
        faultString << "--> Address fault reported at 0x" << std::hex
                    << addressFault.reportedAddress << " | Precision range: 0x"
                    << addressFault.addressPrecision << " (" << std::dec
                    << std::log2(addressFault.addressPrecision) << " bits) | Operation: "
                    << kDeviceFaultAddressTypeMessage[addressFault.addressType] << std::endl;
    }

    for (auto &vendorFault : vendorInfos)
    {
        faultString << "--> Vendor-specific fault reported (Code " << std::dec
                    << vendorFault.vendorFaultCode << "): <" << vendorFault.description
                    << "> | Fault Data: 0x" << std::hex << vendorFault.vendorFaultData << std::endl;
    }

    if (faultFeatures.deviceFaultVendorBinary)
    {
        // The binary data must start with the header in the format of the following type:
        // - VkDeviceFaultVendorBinaryHeaderVersionOneEXT (56 bytes)
        faultString << "--> Vendor-specific binary crash dump (" << faultCounts.vendorBinarySize
                    << " bytes, in hex):" << std::endl;

        constexpr uint32_t kVendorBinaryDataChunksPerLine = 8;
        for (uint32_t i = 0; i < vendorBinaryDataChunkCount; i++)
        {
            faultString << "0x" << std::hex << std::setw(8) << std::setfill('0')
                        << vendorBinaryDataChunks[i]
                        << ((i + 1) % kVendorBinaryDataChunksPerLine != 0 ? " " : "\n");
        }
        faultString << std::endl;
    }
    else
    {
        faultString << "--> Vendor-specific binary crash dump not available." << std::endl;
    }

    // Output the log stream.
    WARN() << faultString.str();
    return VK_SUCCESS;
}
}  // namespace

// OneOffCommandPool implementation.
OneOffCommandPool::OneOffCommandPool() : mProtectionType(vk::ProtectionType::InvalidEnum) {}

void OneOffCommandPool::init(vk::ProtectionType protectionType)
{
    ASSERT(!mCommandPool.valid());
    mProtectionType = protectionType;
}

void OneOffCommandPool::destroy(VkDevice device)
{
    std::unique_lock<angle::SimpleMutex> lock(mMutex);
    for (PendingOneOffCommands &pending : mPendingCommands)
    {
        pending.commandBuffer.releaseHandle();
    }
    mCommandPool.destroy(device);
    mProtectionType = vk::ProtectionType::InvalidEnum;
}

angle::Result OneOffCommandPool::getCommandBuffer(vk::ErrorContext *context,
                                                  vk::ScopedPrimaryCommandBuffer *commandBufferOut)
{
    std::unique_lock<angle::SimpleMutex> lock(mMutex);

    if (!mPendingCommands.empty() &&
        context->getRenderer()->hasResourceUseFinished(mPendingCommands.front().use))
    {
        commandBufferOut->assign(std::move(lock),
                                 std::move(mPendingCommands.front().commandBuffer));
        mPendingCommands.pop_front();
        // No need to explicitly call reset() on |commandBufferOut|, since the begin() call below
        // will do it implicitly.
    }
    else
    {
        if (!mCommandPool.valid())
        {
            VkCommandPoolCreateInfo createInfo = {};
            createInfo.sType                   = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
            createInfo.flags                   = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT |
                                                 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
            ASSERT(mProtectionType == vk::ProtectionType::Unprotected ||
                   mProtectionType == vk::ProtectionType::Protected);
            if (mProtectionType == vk::ProtectionType::Protected)
            {
                createInfo.flags |= VK_COMMAND_POOL_CREATE_PROTECTED_BIT;
            }
            createInfo.queueFamilyIndex = context->getRenderer()->getQueueFamilyIndex();
            ANGLE_VK_TRY(context, mCommandPool.init(context->getDevice(), createInfo));
        }

        VkCommandBufferAllocateInfo allocInfo = {};
        allocInfo.sType                       = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
        allocInfo.level                       = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
        allocInfo.commandBufferCount          = 1;
        allocInfo.commandPool                 = mCommandPool.getHandle();

        PrimaryCommandBuffer newCommandBuffer;
        ANGLE_VK_TRY(context, newCommandBuffer.init(context->getDevice(), allocInfo));
        commandBufferOut->assign(std::move(lock), std::move(newCommandBuffer));
    }

    VkCommandBufferBeginInfo beginInfo = {};
    beginInfo.sType                    = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
    beginInfo.flags                    = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
    beginInfo.pInheritanceInfo         = nullptr;
    ANGLE_VK_TRY(context, commandBufferOut->get().begin(beginInfo));

    return angle::Result::Continue;
}

void OneOffCommandPool::releaseCommandBuffer(const QueueSerial &submitQueueSerial,
                                             vk::PrimaryCommandBuffer &&primary)
{
    std::unique_lock<angle::SimpleMutex> lock(mMutex);
    mPendingCommands.push_back({vk::ResourceUse(submitQueueSerial), std::move(primary)});
}

// Renderer implementation.
Renderer::Renderer()
    : mGlobalOps(nullptr),
      mLibVulkanLibrary(nullptr),
      mCapsInitialized(false),
      mInstanceVersion(0),
      mDeviceVersion(0),
      mInstance(VK_NULL_HANDLE),
      mEnableValidationLayers(false),
      mEnableDebugUtils(false),
      mAngleDebuggerMode(false),
      mEnabledICD(angle::vk::ICD::Default),
      mDebugUtilsMessenger(VK_NULL_HANDLE),
      mPhysicalDevice(VK_NULL_HANDLE),
      mPhysicalDeviceProperties(mPhysicalDeviceProperties2.properties),
      mCurrentQueueFamilyIndex(std::numeric_limits<uint32_t>::max()),
      mMaxVertexAttribDivisor(1),
      mMaxVertexAttribStride(0),
      mMaxColorInputAttachmentCount(0),
      mDefaultUniformBufferSize(kPreferredDefaultUniformBufferSize),
      mDevice(VK_NULL_HANDLE),
      mDeviceLost(false),
      mStagingBufferAlignment(1),
      mHostVisibleVertexConversionBufferMemoryTypeIndex(kInvalidMemoryTypeIndex),
      mDeviceLocalVertexConversionBufferMemoryTypeIndex(kInvalidMemoryTypeIndex),
      mVertexConversionBufferAlignment(1),
      mCurrentPipelineCacheBlobCacheSlotIndex(0),
      mPipelineCacheChunkCount(0),
      mPipelineCacheVkUpdateTimeout(kPipelineCacheVkUpdatePeriod),
      mPipelineCacheSizeAtLastSync(0),
      mPipelineCacheInitialized(false),
      mIsColorFramebufferFetchCoherent(false),
      mIsColorFramebufferFetchUsed(false),
      mCleanUpThread(this, &mCommandQueue),
      mSupportedBufferWritePipelineStageMask(0),
      mSupportedVulkanShaderStageMask(0),
      mMemoryAllocationTracker(MemoryAllocationTracker(this)),
      mMaxMemoryAllocationSize(0),
      mMaxBufferMemorySizeLimit(0),
      mMinRPWriteCommandCountToEarlySubmit(UINT32_MAX)
{
    VkFormatProperties invalid = {0, 0, kInvalidFormatFeatureFlags};
    mFormatProperties.fill(invalid);
    mStagingBufferMemoryTypeIndex.fill(kInvalidMemoryTypeIndex);

    // We currently don't have any big-endian devices in the list of supported platforms.  There are
    // a number of places in the Vulkan backend that make this assumption.  This assertion is made
    // early to fail immediately on big-endian platforms.
    ASSERT(IsLittleEndian());

    mDumpPipelineCacheGraph =
        (angle::GetEnvironmentVarOrAndroidProperty("ANGLE_DUMP_PIPELINE_CACHE_GRAPH",
                                                   "angle.dump_pipeline_cache_graph") == "1");

    mPipelineCacheGraphDumpPath = angle::GetEnvironmentVarOrAndroidProperty(
        "ANGLE_PIPELINE_CACHE_GRAPH_DUMP_PATH", "angle.pipeline_cache_graph_dump_path");
    if (mPipelineCacheGraphDumpPath.size() == 0)
    {
        mPipelineCacheGraphDumpPath = kDefaultPipelineCacheGraphDumpPath;
    }
}

Renderer::~Renderer() {}

bool Renderer::hasSharedGarbage()
{
    return !mSharedGarbageList.empty() || !mSuballocationGarbageList.empty();
}

void Renderer::onDestroy(vk::ErrorContext *context)
{
    if (isDeviceLost())
    {
        handleDeviceLost();
    }

    (void)(finishResourceUse(context, mSubmittedResourceUse));

    if (mPlaceHolderDescriptorSetLayout)
    {
        ASSERT(mPlaceHolderDescriptorSetLayout.unique());
        mPlaceHolderDescriptorSetLayout.reset();
    }

    mCleanUpThread.destroy(context);
    mCommandQueue.destroy(context);

    // mCommandQueue.destroy should already set "last completed" serials to infinite.
    cleanupGarbage(nullptr);
    ASSERT(!hasSharedGarbage());
    ASSERT(mOrphanedBufferBlockList.empty());
    mSamplerCache.destroy(this);
    mYuvConversionCache.destroy(this);

    mRefCountedEventRecycler.destroy(mDevice);

    for (OneOffCommandPool &oneOffCommandPool : mOneOffCommandPoolMap)
    {
        oneOffCommandPool.destroy(mDevice);
    }

    mPipelineCacheInitialized = false;
    mPipelineCache.destroy(mDevice);

    mVkFormatDescriptorCountMap.clear();

    mOutsideRenderPassCommandBufferRecycler.onDestroy();
    mRenderPassCommandBufferRecycler.onDestroy();

    mImageMemorySuballocator.destroy(this);
    mAllocator.destroy();

    // When the renderer is being destroyed, it is possible to check if all the allocated memory
    // throughout the execution has been freed.
    mMemoryAllocationTracker.onDestroy();

    if (mDevice)
    {
        VK_CALL(vkDestroyDevice, mDevice, nullptr);
        mDevice = VK_NULL_HANDLE;
    }

    if (mDebugUtilsMessenger)
    {
        VK_CALL(vkDestroyDebugUtilsMessengerEXT, mInstance, mDebugUtilsMessenger, nullptr);
    }

    logCacheStats();

    if (mInstance)
    {
        VK_CALL(vkDestroyInstance, mInstance, nullptr);
        mInstance = VK_NULL_HANDLE;
    }

    if (mCompressEvent)
    {
        mCompressEvent->wait();
        mCompressEvent.reset();
    }

    mMemoryProperties.destroy();
    mPhysicalDevice = VK_NULL_HANDLE;

    mEnabledInstanceExtensions.clear();
    mEnabledDeviceExtensions.clear();

    ASSERT(!hasSharedGarbage());

    if (mLibVulkanLibrary)
    {
        angle::CloseSystemLibrary(mLibVulkanLibrary);
        mLibVulkanLibrary = nullptr;
    }

    if (!mPipelineCacheGraph.str().empty())
    {
        DumpPipelineCacheGraph(this, mPipelineCacheGraph);
    }
}

VkResult Renderer::retrieveDeviceLostDetails() const
{
    if (!getFeatures().supportsDeviceFault.enabled)
    {
        return VK_SUCCESS;
    }
    return RetrieveDeviceLostInfoFromDevice(mDevice, mFaultFeatures);
}

void Renderer::notifyDeviceLost()
{
    mDeviceLost.store(true, std::memory_order_relaxed);
    mGlobalOps->notifyDeviceLost();
}

bool Renderer::isDeviceLost() const
{
    return mDeviceLost.load(std::memory_order_relaxed);
}

angle::Result Renderer::enableInstanceExtensions(vk::ErrorContext *context,
                                                 const VulkanLayerVector &enabledInstanceLayerNames,
                                                 const char *wsiExtension,
                                                 UseVulkanSwapchain useVulkanSwapchain,
                                                 bool canLoadDebugUtils)
{
    // Enumerate instance extensions that are provided by the vulkan implementation and implicit
    // layers.
    uint32_t instanceExtensionCount = 0;
    {
        ANGLE_SCOPED_DISABLE_LSAN();
        ANGLE_SCOPED_DISABLE_MSAN();
        ANGLE_VK_TRY(context, VK_CALL(vkEnumerateInstanceExtensionProperties, nullptr,
                                      &instanceExtensionCount, nullptr));
    }

    std::vector<VkExtensionProperties> instanceExtensionProps(instanceExtensionCount);
    if (instanceExtensionCount > 0)
    {
        ANGLE_SCOPED_DISABLE_LSAN();
        ANGLE_SCOPED_DISABLE_MSAN();
        ANGLE_VK_TRY(context, VK_CALL(vkEnumerateInstanceExtensionProperties, nullptr,
                                      &instanceExtensionCount, instanceExtensionProps.data()));
        // In case fewer items were returned than requested, resize instanceExtensionProps to the
        // number of extensions returned (i.e. instanceExtensionCount).
        instanceExtensionProps.resize(instanceExtensionCount);
    }

    // Enumerate instance extensions that are provided by explicit layers.
    for (const char *layerName : enabledInstanceLayerNames)
    {
        uint32_t previousExtensionCount      = static_cast<uint32_t>(instanceExtensionProps.size());
        uint32_t instanceLayerExtensionCount = 0;
        {
            ANGLE_SCOPED_DISABLE_LSAN();
            ANGLE_SCOPED_DISABLE_MSAN();
            ANGLE_VK_TRY(context, VK_CALL(vkEnumerateInstanceExtensionProperties, layerName,
                                          &instanceLayerExtensionCount, nullptr));
        }
        instanceExtensionProps.resize(previousExtensionCount + instanceLayerExtensionCount);
        {
            ANGLE_SCOPED_DISABLE_LSAN();
            ANGLE_SCOPED_DISABLE_MSAN();
            ANGLE_VK_TRY(context, VK_CALL(vkEnumerateInstanceExtensionProperties, layerName,
                                          &instanceLayerExtensionCount,
                                          instanceExtensionProps.data() + previousExtensionCount));
        }
        // In case fewer items were returned than requested, resize instanceExtensionProps to the
        // number of extensions returned (i.e. instanceLayerExtensionCount).
        instanceExtensionProps.resize(previousExtensionCount + instanceLayerExtensionCount);
    }

    // Get the list of instance extensions that are available.
    vk::ExtensionNameList instanceExtensionNames;
    if (!instanceExtensionProps.empty())
    {
        for (const VkExtensionProperties &i : instanceExtensionProps)
        {
            instanceExtensionNames.push_back(i.extensionName);
        }
        std::sort(instanceExtensionNames.begin(), instanceExtensionNames.end(), StrLess);
    }

    // Set ANGLE features that depend on instance extensions
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsSurfaceCapabilities2Extension,
        ExtensionFound(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, instanceExtensionNames) &&
            useVulkanSwapchain == UseVulkanSwapchain::Yes);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsSurfaceProtectedCapabilitiesExtension,
                            ExtensionFound(VK_KHR_SURFACE_PROTECTED_CAPABILITIES_EXTENSION_NAME,
                                           instanceExtensionNames) &&
                                useVulkanSwapchain == UseVulkanSwapchain::Yes);

    const bool isSamsungDeviceWithSurfacelessQueryBug = IsXclipse() && GetAndroidSDKVersion() < 36;

    // TODO: Validation layer has a bug when vkGetPhysicalDeviceSurfaceFormats2KHR is called
    // on Mock ICD with surface handle set as VK_NULL_HANDLE. http://anglebug.com/42266098
    // b/267953710: VK_GOOGLE_surfaceless_query isn't working on some Samsung Xclipse builds with
    // Android API level below 36.
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsSurfacelessQueryExtension,
        ExtensionFound(VK_GOOGLE_SURFACELESS_QUERY_EXTENSION_NAME, instanceExtensionNames) &&
            useVulkanSwapchain == UseVulkanSwapchain::Yes && !isMockICDEnabled() &&
            !isSamsungDeviceWithSurfacelessQueryBug);

    // VK_KHR_external_fence_capabilities and VK_KHR_extenral_semaphore_capabilities are promoted to
    // core in Vulkan 1.1
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsExternalFenceCapabilities, true);
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsExternalSemaphoreCapabilities, true);

    // On macOS, there is no native Vulkan driver, so we need to enable the
    // portability enumeration extension to allow use of MoltenVK.
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsPortabilityEnumeration,
        ExtensionFound(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, instanceExtensionNames));

    ANGLE_FEATURE_CONDITION(&mFeatures, enablePortabilityEnumeration,
                            mFeatures.supportsPortabilityEnumeration.enabled && IsApple());

    // Enable extensions that could be used
    if (useVulkanSwapchain == UseVulkanSwapchain::Yes)
    {
        mEnabledInstanceExtensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
        if (ExtensionFound(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME, instanceExtensionNames))
        {
            mEnabledInstanceExtensions.push_back(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME);
        }

        const bool hasSurfaceMaintenance1EXT =
            ExtensionFound(VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME, instanceExtensionNames);
        const bool hasSurfaceMaintenance1KHR =
            ExtensionFound(VK_KHR_SURFACE_MAINTENANCE_1_EXTENSION_NAME, instanceExtensionNames);

        ANGLE_FEATURE_CONDITION(
            &mFeatures, supportsSurfaceMaintenance1,
            !isMockICDEnabled() && (hasSurfaceMaintenance1KHR || hasSurfaceMaintenance1EXT));

        if (mFeatures.supportsSurfaceMaintenance1.enabled)
        {
            if (hasSurfaceMaintenance1KHR)
            {
                mEnabledInstanceExtensions.push_back(VK_KHR_SURFACE_MAINTENANCE_1_EXTENSION_NAME);
            }
            if (hasSurfaceMaintenance1EXT)
            {
                mEnabledInstanceExtensions.push_back(VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME);
            }
        }
    }

    if (wsiExtension)
    {
        mEnabledInstanceExtensions.push_back(wsiExtension);
    }

    mEnableDebugUtils = canLoadDebugUtils && mEnableValidationLayers &&
                        ExtensionFound(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, instanceExtensionNames);

    if (mEnableDebugUtils)
    {
        mEnabledInstanceExtensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
    }

    if (mFeatures.supportsSurfaceCapabilities2Extension.enabled)
    {
        mEnabledInstanceExtensions.push_back(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME);
    }

    if (mFeatures.supportsSurfaceProtectedCapabilitiesExtension.enabled)
    {
        mEnabledInstanceExtensions.push_back(VK_KHR_SURFACE_PROTECTED_CAPABILITIES_EXTENSION_NAME);
    }

    if (mFeatures.supportsSurfacelessQueryExtension.enabled)
    {
        mEnabledInstanceExtensions.push_back(VK_GOOGLE_SURFACELESS_QUERY_EXTENSION_NAME);
    }

    if (mFeatures.enablePortabilityEnumeration.enabled)
    {
        mEnabledInstanceExtensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
    }

    // Verify the required extensions are in the extension names set. Fail if not.
    std::sort(mEnabledInstanceExtensions.begin(), mEnabledInstanceExtensions.end(), StrLess);
    ANGLE_VK_TRY(context,
                 VerifyExtensionsPresent(instanceExtensionNames, mEnabledInstanceExtensions));

    return angle::Result::Continue;
}

angle::Result Renderer::initialize(vk::ErrorContext *context,
                                   vk::GlobalOps *globalOps,
                                   angle::vk::ICD desiredICD,
                                   uint32_t preferredVendorId,
                                   uint32_t preferredDeviceId,
                                   const uint8_t *preferredDeviceUuid,
                                   const uint8_t *preferredDriverUuid,
                                   VkDriverId preferredDriverId,
                                   UseDebugLayers useDebugLayers,
                                   const char *wsiExtension,
                                   const char *wsiLayer,
                                   angle::NativeWindowSystem nativeWindowSystem,
                                   const angle::FeatureOverrides &featureOverrides)
{
    const std::string enableVulkanApiPerfCountersProp = angle::GetEnvironmentVarOrAndroidProperty(
        "ANGLE_ENABLE_VULKAN_API_PERF_COUNTERS", "debug.angle.enable_vulkan_api_perf_counters");
    if (enableVulkanApiPerfCountersProp == "1")
    {
        vk::ScopedVulkanApiPerfTimer::TryEnable();
    }

    bool canLoadDebugUtils = true;
#if defined(ANGLE_SHARED_LIBVULKAN)
    {
        ANGLE_SCOPED_DISABLE_MSAN();
        mLibVulkanLibrary = angle::vk::OpenLibVulkan();
        ANGLE_VK_CHECK(context, mLibVulkanLibrary, VK_ERROR_INITIALIZATION_FAILED);

        PFN_vkGetInstanceProcAddr vulkanLoaderGetInstanceProcAddr =
            reinterpret_cast<PFN_vkGetInstanceProcAddr>(
                angle::GetLibrarySymbol(mLibVulkanLibrary, "vkGetInstanceProcAddr"));

        // Set all vk* function ptrs
        VK_CALL(volkInitializeCustom, vulkanLoaderGetInstanceProcAddr);

        uint32_t ver = VK_CALL(volkGetInstanceVersion);
        if (!IsAndroid() && ver < VK_MAKE_API_VERSION(0, 1, 1, 91))
        {
            // http://crbug.com/1205999 - non-Android Vulkan Loader versions before 1.1.91 have a
            // bug which prevents loading VK_EXT_debug_utils function pointers.
            canLoadDebugUtils = false;
        }
    }
#endif  // defined(ANGLE_SHARED_LIBVULKAN)

    mGlobalOps = globalOps;

    // While the validation layer is loaded by default whenever present, apidump layer
    // activation is controlled by an environment variable/android property allowing
    // the two layers to be controlled independently.
    bool enableApiDumpLayer =
        kEnableVulkanAPIDumpLayer && angle::GetEnvironmentVarOrAndroidProperty(
                                         "ANGLE_ENABLE_VULKAN_API_DUMP_LAYER",
                                         "debug.angle.enable_vulkan_api_dump_layer") == "1";

    bool loadLayers = (useDebugLayers != UseDebugLayers::No) || enableApiDumpLayer;
    angle::vk::ScopedVkLoaderEnvironment scopedEnvironment(loadLayers, desiredICD);
    bool debugLayersLoaded  = scopedEnvironment.canEnableDebugLayers();
    mEnableValidationLayers = debugLayersLoaded;
    enableApiDumpLayer      = enableApiDumpLayer && debugLayersLoaded;
    mEnabledICD             = scopedEnvironment.getEnabledICD();

    // Gather global layer properties.
    uint32_t instanceLayerCount = 0;
    {
        ANGLE_SCOPED_DISABLE_LSAN();
        ANGLE_SCOPED_DISABLE_MSAN();
        ANGLE_VK_TRY(context,
                     VK_CALL(vkEnumerateInstanceLayerProperties, &instanceLayerCount, nullptr));
    }

    std::vector<VkLayerProperties> instanceLayerProps(instanceLayerCount);
    if (instanceLayerCount > 0)
    {
        ANGLE_SCOPED_DISABLE_LSAN();
        ANGLE_SCOPED_DISABLE_MSAN();
        ANGLE_VK_TRY(context, VK_CALL(vkEnumerateInstanceLayerProperties, &instanceLayerCount,
                                      instanceLayerProps.data()));
    }

    mEnabledInstanceLayerNames.clear();

    if (enableApiDumpLayer)
    {
        mEnabledInstanceLayerNames.push_back("VK_LAYER_LUNARG_api_dump");
    }

    if (mEnableValidationLayers)
    {
        const bool layersRequested = useDebugLayers == UseDebugLayers::Yes;
        mEnableValidationLayers = GetAvailableValidationLayers(instanceLayerProps, layersRequested,
                                                               &mEnabledInstanceLayerNames);
    }

    if (wsiLayer != nullptr)
    {
        mEnabledInstanceLayerNames.push_back(wsiLayer);
    }

    auto enumerateInstanceVersion = reinterpret_cast<PFN_vkEnumerateInstanceVersion>(
        VK_CALL(vkGetInstanceProcAddr, nullptr, "vkEnumerateInstanceVersion"));

    uint32_t highestApiVersion = mInstanceVersion = VK_API_VERSION_1_0;
    if (enumerateInstanceVersion)
    {
        {
            ANGLE_SCOPED_DISABLE_LSAN();
            ANGLE_SCOPED_DISABLE_MSAN();
            ANGLE_VK_TRY(context, VK_CALL_WITH_API(VulkanApiFunction::vkEnumerateInstanceVersion,
                                                   enumerateInstanceVersion(&mInstanceVersion)));
        }

        if (IsVulkan11(mInstanceVersion))
        {
            // This is the highest version of core Vulkan functionality that ANGLE uses.  Per the
            // Vulkan spec, the application is allowed to specify a higher version than supported by
            // the instance.  ANGLE still respects the *device's* version.
            highestApiVersion = kPreferredVulkanAPIVersion;
        }
    }

    if (mInstanceVersion < angle::vk::kMinimumVulkanAPIVersion)
    {
        WARN() << "ANGLE Requires a minimum Vulkan instance version of 1.1";
        ANGLE_VK_TRY(context, VK_ERROR_INCOMPATIBLE_DRIVER);
    }

    const UseVulkanSwapchain useVulkanSwapchain = wsiExtension != nullptr || wsiLayer != nullptr
                                                      ? UseVulkanSwapchain::Yes
                                                      : UseVulkanSwapchain::No;
    ANGLE_TRY(enableInstanceExtensions(context, mEnabledInstanceLayerNames, wsiExtension,
                                       useVulkanSwapchain, canLoadDebugUtils));

    const std::string appName = angle::GetExecutableName();

    mApplicationInfo                    = {};
    mApplicationInfo.sType              = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    mApplicationInfo.pApplicationName   = appName.c_str();
    mApplicationInfo.applicationVersion = 1;
    mApplicationInfo.pEngineName        = "ANGLE";
    mApplicationInfo.engineVersion      = 1;
    mApplicationInfo.apiVersion         = highestApiVersion;

    VkInstanceCreateInfo instanceInfo = {};
    instanceInfo.sType                = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    instanceInfo.flags                = 0;
    instanceInfo.pApplicationInfo     = &mApplicationInfo;

    // Enable requested layers and extensions.
    instanceInfo.enabledExtensionCount = static_cast<uint32_t>(mEnabledInstanceExtensions.size());
    instanceInfo.ppEnabledExtensionNames =
        mEnabledInstanceExtensions.empty() ? nullptr : mEnabledInstanceExtensions.data();

    instanceInfo.enabledLayerCount   = static_cast<uint32_t>(mEnabledInstanceLayerNames.size());
    instanceInfo.ppEnabledLayerNames = mEnabledInstanceLayerNames.data();

    // On macOS, there is no native Vulkan driver, so we need to enable the
    // portability enumeration extension to allow use of MoltenVK.
    if (mFeatures.enablePortabilityEnumeration.enabled)
    {
        instanceInfo.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
    }

    // Fine grain control of validation layer features
    const char *name                     = "VK_LAYER_KHRONOS_validation";
    const VkBool32 setting_validate_core = VK_TRUE;
    // SyncVal is very slow (https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/7285)
    // for VkEvent which causes a few tests fail on the bots. Disable syncVal if VkEvent is enabled
    // for now.
    const VkBool32 setting_validate_sync = IsAndroid() ? VK_FALSE : VK_TRUE;
    const VkBool32 setting_thread_safety = VK_TRUE;
    // http://anglebug.com/42265520 - Shader validation caching is broken on Android
    const VkBool32 setting_check_shaders = IsAndroid() ? VK_FALSE : VK_TRUE;
    // http://b/316013423 Disable QueueSubmit Synchronization Validation. Lots of failures and some
    // test timeout due to https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/7285
    const VkBool32 setting_syncval_submit_time_validation   = VK_FALSE;
    const VkBool32 setting_syncval_message_extra_properties = VK_TRUE;
    const VkLayerSettingEXT layerSettings[]                 = {
        {name, "validate_core", VK_LAYER_SETTING_TYPE_BOOL32_EXT, 1, &setting_validate_core},
        {name, "validate_sync", VK_LAYER_SETTING_TYPE_BOOL32_EXT, 1, &setting_validate_sync},
        {name, "thread_safety", VK_LAYER_SETTING_TYPE_BOOL32_EXT, 1, &setting_thread_safety},
        {name, "check_shaders", VK_LAYER_SETTING_TYPE_BOOL32_EXT, 1, &setting_check_shaders},
        {name, "syncval_submit_time_validation", VK_LAYER_SETTING_TYPE_BOOL32_EXT, 1,
         &setting_syncval_submit_time_validation},
        {name, "syncval_message_extra_properties", VK_LAYER_SETTING_TYPE_BOOL32_EXT, 1,
         &setting_syncval_message_extra_properties},
    };
    VkLayerSettingsCreateInfoEXT layerSettingsCreateInfo = {
        VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT, nullptr,
        static_cast<uint32_t>(std::size(layerSettings)), layerSettings};
    if (mEnableValidationLayers)
    {
        vk::AddToPNextChain(&instanceInfo, &layerSettingsCreateInfo);
    }

    {
        ANGLE_SCOPED_DISABLE_MSAN();
        ANGLE_VK_TRY(context, VK_CALL(vkCreateInstance, &instanceInfo, nullptr, &mInstance));
#if defined(ANGLE_SHARED_LIBVULKAN)
        // Load volk if we are linking dynamically
        VK_CALL(volkLoadInstance, mInstance);
#endif  // defined(ANGLE_SHARED_LIBVULKAN)

        // For promoted extensions, initialize their entry points from the core version.
        initializeInstanceExtensionEntryPointsFromCore();
    }

    if (mEnableDebugUtils)
    {
        // Use the newer EXT_debug_utils if it exists.
#if !defined(ANGLE_SHARED_LIBVULKAN)
        InitDebugUtilsEXTFunctions(mInstance);
#endif  // !defined(ANGLE_SHARED_LIBVULKAN)

        // Create the messenger callback.
        VkDebugUtilsMessengerCreateInfoEXT messengerInfo = {};

        constexpr VkDebugUtilsMessageSeverityFlagsEXT kSeveritiesToLog =
            VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT |
            VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;

        constexpr VkDebugUtilsMessageTypeFlagsEXT kMessagesToLog =
            VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
            VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
            VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;

        messengerInfo.sType           = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
        messengerInfo.messageSeverity = kSeveritiesToLog;
        messengerInfo.messageType     = kMessagesToLog;
        messengerInfo.pfnUserCallback = &DebugUtilsMessenger;
        messengerInfo.pUserData       = this;

        ANGLE_VK_TRY(context, VK_CALL(vkCreateDebugUtilsMessengerEXT, mInstance, &messengerInfo,
                                      nullptr, &mDebugUtilsMessenger));
    }

    uint32_t physicalDeviceCount = 0;
    ANGLE_VK_TRY(context,
                 VK_CALL(vkEnumeratePhysicalDevices, mInstance, &physicalDeviceCount, nullptr));
    ANGLE_VK_CHECK(context, physicalDeviceCount > 0, VK_ERROR_INITIALIZATION_FAILED);

    std::vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
    ANGLE_VK_TRY(context, VK_CALL(vkEnumeratePhysicalDevices, mInstance, &physicalDeviceCount,
                                  physicalDevices.data()));
    VK_CALL_WITH_API(
        VulkanApiFunction::vkGetPhysicalDeviceProperties2,
        ChoosePhysicalDevice(vkGetPhysicalDeviceProperties2, physicalDevices, mEnabledICD,
                             preferredVendorId, preferredDeviceId, preferredDeviceUuid,
                             preferredDriverUuid, preferredDriverId, &mPhysicalDevice,
                             &mPhysicalDeviceProperties2, &mPhysicalDeviceIDProperties,
                             &mDriverProperties));

    // The device version that is assumed by ANGLE is the minimum of the actual device version and
    // the highest it's allowed to use.
    mDeviceVersion = std::min(mPhysicalDeviceProperties.apiVersion, highestApiVersion);

    if (mDeviceVersion < angle::vk::kMinimumVulkanAPIVersion)
    {
        WARN() << "ANGLE Requires a minimum Vulkan device version of 1.1";
        ANGLE_VK_TRY(context, VK_ERROR_INCOMPATIBLE_DRIVER);
    }

    mGarbageCollectionFlushThreshold =
        static_cast<uint32_t>(mPhysicalDeviceProperties.limits.maxMemoryAllocationCount *
                              kPercentMaxMemoryAllocationCount);
    VK_CALL(vkGetPhysicalDeviceFeatures, mPhysicalDevice, &mPhysicalDeviceFeatures);

    // Ensure we can find a graphics queue family.
    uint32_t queueFamilyCount = 0;
    VK_CALL(vkGetPhysicalDeviceQueueFamilyProperties, mPhysicalDevice, &queueFamilyCount, nullptr);

    ANGLE_VK_CHECK(context, queueFamilyCount > 0, VK_ERROR_INITIALIZATION_FAILED);

    mQueueFamilyProperties2.resize(queueFamilyCount);
    for (uint32_t i = 0; i < queueFamilyCount; i++)
    {
        mQueueFamilyProperties2[i]       = {};
        mQueueFamilyProperties2[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
    }

    // Query all supported global priorities if supported.
    std::vector<VkQueueFamilyGlobalPriorityProperties> globalPriorityProperties;
    if (mFeatures.supportsGlobalPriority.enabled)
    {
        globalPriorityProperties.resize(queueFamilyCount);
        for (uint32_t i = 0; i < queueFamilyCount; i++)
        {
            globalPriorityProperties[i] = {};
            globalPriorityProperties[i].sType =
                VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES;
            vk::AddToPNextChain(&mQueueFamilyProperties2[i], &globalPriorityProperties[i]);
        }
    }

    VK_CALL(vkGetPhysicalDeviceQueueFamilyProperties2, mPhysicalDevice, &queueFamilyCount,
            mQueueFamilyProperties2.data());

    uint32_t queueFamilyMatchCount = 0;

    VkQueueFlags queueFamilyBits = VK_QUEUE_FLAG_BITS_MAX_ENUM;
    uint32_t firstQueueFamily    = QueueFamily::kInvalidIndex;

    // If this is compute client, give preference to compute only queue (if not available fall back
    // to default queue)
    if (nativeWindowSystem == angle::NativeWindowSystem::NullCompute && kUseComputeOnlyQueue)
    {
        queueFamilyBits = VK_QUEUE_COMPUTE_BIT;
        firstQueueFamily =
            QueueFamily::FindIndex(mQueueFamilyProperties2, queueFamilyBits, VK_QUEUE_PROTECTED_BIT,
                                   VK_QUEUE_GRAPHICS_BIT, &queueFamilyMatchCount);

        if (queueFamilyMatchCount == 0)
        {
            INFO() << "Compute Only queue is not supported by the device, falling back to default "
                      "Graphics|Compute queue";
        }
    }
    if (queueFamilyMatchCount == 0)
    {
        queueFamilyBits = VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT;
        firstQueueFamily =
            QueueFamily::FindIndex(mQueueFamilyProperties2, queueFamilyBits, VK_QUEUE_PROTECTED_BIT,
                                   0, &queueFamilyMatchCount);
    }

    ANGLE_VK_CHECK(context,
                   queueFamilyMatchCount > 0 && firstQueueFamily != QueueFamily::kInvalidIndex,
                   VK_ERROR_INITIALIZATION_FAILED);

    VkQueueGlobalPriority globalPriority = VK_QUEUE_GLOBAL_PRIORITY_MEDIUM;
    if (mFeatures.supportsGlobalPriority.enabled &&
        HasRequiredGlobalPriority(globalPriorityProperties[firstQueueFamily],
                                  VK_QUEUE_GLOBAL_PRIORITY_REALTIME))
    {
        // Realtime global priority is supported, so we can use it in
        // queueGlobalPriorityCreateInfo
        globalPriority = VK_QUEUE_GLOBAL_PRIORITY_REALTIME;
    }

    // Store the physical device memory properties so we can find the right memory pools.
    mMemoryProperties.init(mPhysicalDevice);
    ANGLE_VK_CHECK(context, mMemoryProperties.getMemoryTypeCount() > 0,
                   VK_ERROR_INITIALIZATION_FAILED);

    // The counters for the memory allocation tracker should be initialized.
    // Each memory allocation could be made in one of the available memory heaps. We initialize
    // the per-heap memory allocation trackers for MemoryAllocationType objects here, after
    // mMemoryProperties has been set up.
    mMemoryAllocationTracker.initMemoryTrackers();

    // Determine the threshold for pending garbage sizes.
    calculatePendingGarbageSizeLimit();

    ANGLE_TRY(setupDevice(context, featureOverrides, useVulkanSwapchain, nativeWindowSystem));

    // If only one queue family, that's the only choice and the device is initialize with that.
    // If there is more than one queue, we still create the device with the first queue family
    // and hope for the best.  We cannot wait for a window surface to know which supports
    // present because of EGL_KHR_surfaceless_context or simply pbuffers.  So far, only MoltenVk
    // seems to expose multiple queue families, and using the first queue family is fine with
    // it.
    ANGLE_TRY(createDeviceAndQueue(context, firstQueueFamily, globalPriority));

    // Initialize the format table.
    mFormatTable.initialize(this, &mNativeTextureCaps);

    // Null terminate the extension list returned for EGL_VULKAN_INSTANCE_EXTENSIONS_ANGLE.
    mEnabledInstanceExtensions.push_back(nullptr);

    for (vk::ProtectionType protectionType : angle::AllEnums<vk::ProtectionType>())
    {
        mOneOffCommandPoolMap[protectionType].init(protectionType);
    }

    // Initialize place holder descriptor set layout for empty DescriptorSetLayoutDesc
    ASSERT(!mPlaceHolderDescriptorSetLayout);
    VkDescriptorSetLayoutCreateInfo createInfo = {};
    createInfo.sType        = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
    createInfo.flags        = 0;
    createInfo.bindingCount = 0;
    createInfo.pBindings    = nullptr;

    mPlaceHolderDescriptorSetLayout = vk::DescriptorSetLayoutPtr::MakeShared(context->getDevice());
    ANGLE_VK_TRY(context, mPlaceHolderDescriptorSetLayout->init(context->getDevice(), createInfo));
    ASSERT(mPlaceHolderDescriptorSetLayout->valid());

    return angle::Result::Continue;
}

angle::Result Renderer::initializeMemoryAllocator(vk::ErrorContext *context)
{
    mTileMemoyTypeIndex = kInvalidMemoryTypeIndex;
    if (mFeatures.supportsTileMemoryHeap.enabled)
    {
        mTileMemoyTypeIndex = mMemoryProperties.findTileMemoryTypeIndex();
        ASSERT(mTileMemoyTypeIndex != kInvalidMemoryTypeIndex);
    }

    // The preferred heap block size was picked by looking at memory usage of
    // Android apps. The allocator will start making blocks at 1/8 the max size
    // and builds up block size as needed before capping at the max set here.
    mPreferredLargeHeapBlockSize = 8 * 1024 * 1024;

    // The first allocated buffer block from an empty buffer pool has a smaller size in order to
    // reduce the memory footprint.
    mPreferredInitialBufferBlockSize = 1 * 1024 * 1024;
    ASSERT(mPreferredInitialBufferBlockSize <= mPreferredLargeHeapBlockSize);

    // Create VMA allocator
    ANGLE_VK_TRY(context,
                 mAllocator.init(mPhysicalDevice, mDevice, mInstance, mApplicationInfo.apiVersion,
                                 mPreferredLargeHeapBlockSize));

    // Figure out the alignment for default buffer allocations
    VkBufferCreateInfo createInfo    = {};
    createInfo.sType                 = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
    createInfo.flags                 = 0;
    createInfo.size                  = 4096;
    createInfo.usage                 = GetDefaultBufferUsageFlags(this);
    createInfo.sharingMode           = VK_SHARING_MODE_EXCLUSIVE;
    createInfo.queueFamilyIndexCount = 0;
    createInfo.pQueueFamilyIndices   = nullptr;

    vk::DeviceScoped<vk::Buffer> tempBuffer(mDevice);
    tempBuffer.get().init(mDevice, createInfo);

    VkMemoryRequirements defaultBufferMemoryRequirements;
    tempBuffer.get().getMemoryRequirements(mDevice, &defaultBufferMemoryRequirements);
    ASSERT(gl::isPow2(defaultBufferMemoryRequirements.alignment));

    const VkPhysicalDeviceLimits &limitsVk = getPhysicalDeviceProperties().limits;
    ASSERT(gl::isPow2(limitsVk.minUniformBufferOffsetAlignment));
    ASSERT(gl::isPow2(limitsVk.minStorageBufferOffsetAlignment));
    ASSERT(gl::isPow2(limitsVk.minTexelBufferOffsetAlignment));
    ASSERT(gl::isPow2(limitsVk.minMemoryMapAlignment));

    mDefaultBufferAlignment =
        std::max({static_cast<size_t>(limitsVk.minUniformBufferOffsetAlignment),
                  static_cast<size_t>(limitsVk.minStorageBufferOffsetAlignment),
                  static_cast<size_t>(limitsVk.minTexelBufferOffsetAlignment),
                  static_cast<size_t>(limitsVk.minMemoryMapAlignment),
                  static_cast<size_t>(defaultBufferMemoryRequirements.alignment)});

    // Initialize staging buffer memory type index and alignment.
    // These buffers will only be used as transfer sources or transfer targets.
    createInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
    VkMemoryPropertyFlags requiredFlags, preferredFlags;
    bool persistentlyMapped = mFeatures.persistentlyMappedBuffers.enabled;

    // Uncached coherent staging buffer.
    requiredFlags  = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
    preferredFlags = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
    ANGLE_VK_TRY(context,
                 mAllocator.findMemoryTypeIndexForBufferInfo(
                     createInfo, requiredFlags, preferredFlags, persistentlyMapped,
                     &mStagingBufferMemoryTypeIndex[vk::MemoryCoherency::UnCachedCoherent]));
    ASSERT(mStagingBufferMemoryTypeIndex[vk::MemoryCoherency::UnCachedCoherent] !=
           kInvalidMemoryTypeIndex);

    // Cached coherent staging buffer.  Note coherent is preferred but not required, which means we
    // may get non-coherent memory type.
    requiredFlags   = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
    preferredFlags  = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
    VkResult result = mAllocator.findMemoryTypeIndexForBufferInfo(
        createInfo, requiredFlags, preferredFlags, persistentlyMapped,
        &mStagingBufferMemoryTypeIndex[vk::MemoryCoherency::CachedPreferCoherent]);
    if (result == VK_SUCCESS)
    {
        ASSERT(mStagingBufferMemoryTypeIndex[vk::MemoryCoherency::CachedPreferCoherent] !=
               kInvalidMemoryTypeIndex);
    }
    else
    {
        // Android studio may not expose host cached memory pool. Fall back to host uncached.
        mStagingBufferMemoryTypeIndex[vk::MemoryCoherency::CachedPreferCoherent] =
            mStagingBufferMemoryTypeIndex[vk::MemoryCoherency::UnCachedCoherent];
    }

    // Cached Non-coherent staging buffer
    requiredFlags  = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
    preferredFlags = 0;
    result         = mAllocator.findMemoryTypeIndexForBufferInfo(
        createInfo, requiredFlags, preferredFlags, persistentlyMapped,
        &mStagingBufferMemoryTypeIndex[vk::MemoryCoherency::CachedNonCoherent]);
    if (result == VK_SUCCESS)
    {
        ASSERT(mStagingBufferMemoryTypeIndex[vk::MemoryCoherency::CachedNonCoherent] !=
               kInvalidMemoryTypeIndex);
    }
    else
    {
        // Android studio may not expose host cached memory pool. Fall back to host uncached.
        mStagingBufferMemoryTypeIndex[vk::MemoryCoherency::CachedNonCoherent] =
            mStagingBufferMemoryTypeIndex[vk::MemoryCoherency::UnCachedCoherent];
    }

    // Alignment
    mStagingBufferAlignment =
        static_cast<size_t>(mPhysicalDeviceProperties.limits.minMemoryMapAlignment);
    ASSERT(gl::isPow2(mPhysicalDeviceProperties.limits.nonCoherentAtomSize));
    ASSERT(gl::isPow2(mPhysicalDeviceProperties.limits.optimalBufferCopyOffsetAlignment));
    // Usually minTexelBufferOffsetAlignment is much smaller than  nonCoherentAtomSize
    ASSERT(gl::isPow2(mPhysicalDeviceProperties.limits.minTexelBufferOffsetAlignment));
    mStagingBufferAlignment = std::max(
        {mStagingBufferAlignment,
         static_cast<size_t>(mPhysicalDeviceProperties.limits.optimalBufferCopyOffsetAlignment),
         static_cast<size_t>(mPhysicalDeviceProperties.limits.nonCoherentAtomSize),
         static_cast<size_t>(mPhysicalDeviceProperties.limits.minTexelBufferOffsetAlignment)});
    ASSERT(gl::isPow2(mStagingBufferAlignment));

    // Device local vertex conversion buffer
    createInfo.usage = vk::kVertexBufferUsageFlags;
    requiredFlags    = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
    preferredFlags   = 0;
    ANGLE_VK_TRY(context, mAllocator.findMemoryTypeIndexForBufferInfo(
                              createInfo, requiredFlags, preferredFlags, persistentlyMapped,
                              &mDeviceLocalVertexConversionBufferMemoryTypeIndex));
    ASSERT(mDeviceLocalVertexConversionBufferMemoryTypeIndex != kInvalidMemoryTypeIndex);

    // Host visible and non-coherent vertex conversion buffer, which is the same as non-coherent
    // staging buffer
    mHostVisibleVertexConversionBufferMemoryTypeIndex =
        mStagingBufferMemoryTypeIndex[vk::MemoryCoherency::CachedNonCoherent];

    // We may use compute shader to do conversion, so we must meet
    // minStorageBufferOffsetAlignment requirement as well. Also take into account non-coherent
    // alignment requirements.
    mVertexConversionBufferAlignment = std::max(
        {vk::kVertexBufferAlignment,
         static_cast<size_t>(mPhysicalDeviceProperties.limits.minStorageBufferOffsetAlignment),
         static_cast<size_t>(mPhysicalDeviceProperties.limits.nonCoherentAtomSize),
         static_cast<size_t>(defaultBufferMemoryRequirements.alignment)});
    ASSERT(gl::isPow2(mVertexConversionBufferAlignment));

    return angle::Result::Continue;
}

// The following features and properties are not promoted to any core Vulkan versions (up to Vulkan
// 1.4):
//
// - VK_EXT_provoking_vertex:                          provokingVertexLast (feature)
// - VK_EXT_transform_feedback:                        transformFeedback (feature),
//                                                     geometryStreams (feature)
// - VK_EXT_device_memory_report:                      deviceMemoryReport (feature)
// - VK_EXT_multisampled_render_to_single_sampled:     multisampledRenderToSingleSampled (feature)
// - VK_EXT_image_2d_view_of_3d:                       image2DViewOf3D (feature)
//                                                     sampler2DViewOf3D (feature)
// - VK_EXT_custom_border_color:                       customBorderColors (feature)
//                                                     customBorderColorWithoutFormat (feature)
// - VK_KHR_depth_clamp_zero_one or
//   VK_EXT_depth_clamp_zero_one:                      depthClampZeroOne (feature)
// - VK_EXT_depth_clip_control:                        depthClipControl (feature)
// - VK_EXT_primitives_generated_query:                primitivesGeneratedQuery (feature),
//                                                     primitivesGeneratedQueryWithRasterizerDiscard
//                                                                                        (property)
// - VK_EXT_primitive_topology_list_restart:           primitiveTopologyListRestart (feature)
// - VK_EXT_graphics_pipeline_library:                 graphicsPipelineLibrary (feature),
//                                                     graphicsPipelineLibraryFastLinking (property)
// - VK_KHR_fragment_shading_rate:                     pipelineFragmentShadingRate (feature)
// - VK_EXT_fragment_shader_interlock:                 fragmentShaderPixelInterlock (feature)
// - VK_EXT_pipeline_robustness:                       pipelineRobustness (feature)
// - VK_EXT_pipeline_protected_access:                 pipelineProtectedAccess (feature)
// - VK_EXT_rasterization_order_attachment_access or
//   VK_ARM_rasterization_order_attachment_access:     rasterizationOrderColorAttachmentAccess
//                                                                                   (feature)
//                                                     rasterizationOrderDepthAttachmentAccess
//                                                                                   (feature)
//                                                     rasterizationOrderStencilAttachmentAccess
//                                                                                   (feature)
// - VK_KHR_swapchain_maintenance1 or
//   VK_EXT_swapchain_maintenance1:                    swapchainMaintenance1 (feature)
// - VK_EXT_legacy_dithering:                          supportsLegacyDithering (feature)
// - VK_EXT_physical_device_drm:                       hasPrimary (property),
//                                                     hasRender (property)
// - VK_ANDROID_external_format_resolve:               externalFormatResolve (feature)
// - VK_EXT_vertex_input_dynamic_state:                vertexInputDynamicState (feature)
// - VK_EXT_shader_atomic_float                        shaderImageFloat32Atomics (feature)
// - VK_EXT_image_compression_control                  imageCompressionControl (feature)
// - VK_EXT_image_compression_control_swapchain        imageCompressionControlSwapchain (feature)
// - VK_EXT_device_fault                               deviceFault (feature),
//                                                     deviceFaultVendorBinary (feature)
// - VK_EXT_astc_decode_mode                           decodeModeSharedExponent (feature)
// - VK_KHR_unified_image_layouts                      unifiedImageLayouts (feature)
// - VK_EXT_external_memory_host                       minImportedHostPointerAlignment (property)
// - VK_QCOM_tile_memory_heap                          tileMemoryHeapFeatures (feature)
//                                                     tileMemoryHeapProperties (property)
// - VK_EXT_texture_compression_astc_3d                textureCompressionASTC_3D (feature)
// - VK_AMD_shader_core_properties
//

void Renderer::appendDeviceExtensionFeaturesNotPromoted(
    const vk::ExtensionNameList &deviceExtensionNames,
    VkPhysicalDeviceFeatures2KHR *deviceFeatures,
    VkPhysicalDeviceProperties2 *deviceProperties)
{
    if (ExtensionFound(VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mProvokingVertexFeatures);
    }

    if (ExtensionFound(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mTransformFeedbackFeatures);
    }

    if (ExtensionFound(VK_EXT_DEVICE_MEMORY_REPORT_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mMemoryReportFeatures);
    }

    if (ExtensionFound(VK_EXT_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_EXTENSION_NAME,
                       deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mMultisampledRenderToSingleSampledFeatures);
    }

    if (ExtensionFound(VK_EXT_IMAGE_2D_VIEW_OF_3D_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mImage2dViewOf3dFeatures);
    }

    if (ExtensionFound(VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mCustomBorderColorFeatures);
    }

    if (ExtensionFound(VK_KHR_DEPTH_CLAMP_ZERO_ONE_EXTENSION_NAME, deviceExtensionNames) ||
        ExtensionFound(VK_EXT_DEPTH_CLAMP_ZERO_ONE_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mDepthClampZeroOneFeatures);
    }

    if (ExtensionFound(VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mDepthClipControlFeatures);
    }

    if (ExtensionFound(VK_EXT_PRIMITIVES_GENERATED_QUERY_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mPrimitivesGeneratedQueryFeatures);
    }

    if (ExtensionFound(VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mPrimitiveTopologyListRestartFeatures);
    }

    if (ExtensionFound(VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mGraphicsPipelineLibraryFeatures);
        vk::AddToPNextChain(deviceProperties, &mGraphicsPipelineLibraryProperties);
    }

    if (ExtensionFound(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mFragmentShadingRateFeatures);
        vk::AddToPNextChain(deviceProperties, &mFragmentShadingRateProperties);
    }

    if (ExtensionFound(VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mFragmentShaderInterlockFeatures);
    }

    if (ExtensionFound(VK_EXT_PIPELINE_ROBUSTNESS_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mPipelineRobustnessFeatures);
    }

    if (ExtensionFound(VK_EXT_PIPELINE_PROTECTED_ACCESS_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mPipelineProtectedAccessFeatures);
    }

    // The EXT and ARM versions are interchangeable. The structs and enums alias each other.
    if (ExtensionFound(VK_EXT_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME,
                       deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mRasterizationOrderAttachmentAccessFeatures);
    }
    else if (ExtensionFound(VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME,
                            deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mRasterizationOrderAttachmentAccessFeatures);
    }

    if (ExtensionFound(VK_EXT_SHADER_ATOMIC_FLOAT_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mShaderAtomicFloatFeatures);
    }

    if (ExtensionFound(VK_KHR_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME, deviceExtensionNames) ||
        ExtensionFound(VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mSwapchainMaintenance1Features);
    }

    if (ExtensionFound(VK_EXT_LEGACY_DITHERING_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mDitheringFeatures);
    }

    if (ExtensionFound(VK_EXT_PHYSICAL_DEVICE_DRM_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceProperties, &mDrmProperties);
    }

    if (ExtensionFound(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mVertexInputDynamicStateFeatures);
    }

#if defined(ANGLE_PLATFORM_ANDROID)
    if (ExtensionFound(VK_ANDROID_EXTERNAL_FORMAT_RESOLVE_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mExternalFormatResolveFeatures);
        vk::AddToPNextChain(deviceProperties, &mExternalFormatResolveProperties);
    }
#endif

    if (ExtensionFound(VK_KHR_UNIFIED_IMAGE_LAYOUTS_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mUnifiedImageLayoutsFeatures);
    }

    if (ExtensionFound(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mBlendOperationAdvancedFeatures);
    }

    if (ExtensionFound(VK_EXT_IMAGE_COMPRESSION_CONTROL_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mImageCompressionControlFeatures);
    }
    if (ExtensionFound(VK_EXT_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_EXTENSION_NAME,
                       deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mImageCompressionControlSwapchainFeatures);
    }
    if (ExtensionFound(VK_EXT_DEVICE_FAULT_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mFaultFeatures);
    }
    if (ExtensionFound(VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mPhysicalDeviceAstcDecodeFeatures);
    }
    if (ExtensionFound(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceProperties, &mExternalMemoryHostProperties);
    }
    if (ExtensionFound(VK_EXT_TEXTURE_COMPRESSION_ASTC_3D_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mTextureCompressionASTC3DFeatures);
    }

    if (ExtensionFound(VK_QCOM_TILE_MEMORY_HEAP_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mTileMemoryHeapFeatures);
        vk::AddToPNextChain(deviceProperties, &mTileMemoryHeapProperties);
    }

    if (ExtensionFound(VK_AMD_SHADER_CORE_PROPERTIES_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceProperties, &mShaderCorePropertiesAMD);
    }
}

// The following features and properties used by ANGLE have been promoted to Vulkan 1.1:
//
// - (unpublished VK_KHR_subgroup):         supportedStages (property),
//                                          supportedOperations (property)
// - (unpublished VK_KHR_protected_memory): protectedMemory (feature)
// - VK_KHR_sampler_ycbcr_conversion:       samplerYcbcrConversion (feature)
// - VK_KHR_multiview:                      multiview (feature),
//                                          maxMultiviewViewCount (property)
// - VK_KHR_16bit_storage:                  storageBuffer16BitAccess (feature)
//                                          uniformAndStorageBuffer16BitAccess (feature)
//                                          storagePushConstant16 (feature)
//                                          storageInputOutput16 (feature)
// - VK_KHR_variable_pointers:              variablePointers (feature)
//                                          variablePointersStorageBuffer (feature)
//
//
// Note that subgroup and protected memory features and properties came from unpublished extensions
// and are core in Vulkan 1.1.
//
void Renderer::appendDeviceExtensionFeaturesPromotedTo11(
    const vk::ExtensionNameList &deviceExtensionNames,
    VkPhysicalDeviceFeatures2KHR *deviceFeatures,
    VkPhysicalDeviceProperties2 *deviceProperties)
{
    vk::AddToPNextChain(deviceProperties, &mSubgroupProperties);
    vk::AddToPNextChain(deviceFeatures, &mProtectedMemoryFeatures);
    vk::AddToPNextChain(deviceFeatures, &mSamplerYcbcrConversionFeatures);
    vk::AddToPNextChain(deviceFeatures, &mMultiviewFeatures);
    vk::AddToPNextChain(deviceProperties, &mMultiviewProperties);
    vk::AddToPNextChain(deviceFeatures, &m16BitStorageFeatures);
    vk::AddToPNextChain(deviceFeatures, &mVariablePointersFeatures);
    vk::AddToPNextChain(deviceProperties, &mMaintenance3Properties);
}

// The following features and properties used by ANGLE have been promoted to Vulkan 1.2:
//
// - VK_KHR_shader_float16_int8:            shaderFloat16 (feature),
//                                          shaderInt8 (feature)
// - VK_KHR_depth_stencil_resolve:          supportedDepthResolveModes (property),
//                                          independentResolveNone (property)
// - VK_KHR_driver_properties:              driverName (property),
//                                          driverID (property)
// - VK_KHR_shader_subgroup_extended_types: shaderSubgroupExtendedTypes (feature)
// - VK_EXT_host_query_reset:               hostQueryReset (feature)
// - VK_KHR_imageless_framebuffer:          imagelessFramebuffer (feature)
// - VK_KHR_timeline_semaphore:             timelineSemaphore (feature)
// - VK_KHR_8bit_storage                    storageBuffer8BitAccess (feature)
//                                          uniformAndStorageBuffer8BitAccess (feature)
//                                          storagePushConstant8 (feature)
// - VK_KHR_shader_float_controls           shaderRoundingModeRTEFloat16 (property)
//                                          shaderRoundingModeRTEFloat32 (property)
//                                          shaderRoundingModeRTEFloat64 (property)
//                                          shaderRoundingModeRTZFloat16 (property)
//                                          shaderRoundingModeRTZFloat32 (property)
//                                          shaderRoundingModeRTZFloat64 (property)
//                                          shaderDenormPreserveFloat16 (property)
//                                          shaderDenormPreserveFloat16 (property)
//                                          shaderDenormPreserveFloat16 (property)
//                                          shaderDenormFlushToZeroFloat16 (property)
//                                          shaderDenormFlushToZeroFloat32 (property)
//                                          shaderDenormFlushToZeroFloat64 (property)
//                                          shaderSignedZeroInfNanPreserveFloat16 (property)
//                                          shaderSignedZeroInfNanPreserveFloat32 (property)
//                                          shaderSignedZeroInfNanPreserveFloat64 (property)
// - VK_KHR_uniform_buffer_standard_layout: uniformBufferStandardLayout (feature)
// - VK_KHR_buffer_device_address:          bufferDeviceAddress (feature)
// - VK_KHR_shader_atomic_int64:            shaderBufferInt64Atomics (feature)
//                                          shaderSharedInt64Atomics (feature)
//
// Note that supportedDepthResolveModes is used just to check if the property struct is populated.
// ANGLE always uses VK_RESOLVE_MODE_SAMPLE_ZERO_BIT for both depth and stencil, and support for
// this bit is mandatory as long as the extension (or Vulkan 1.2) exists.
//
void Renderer::appendDeviceExtensionFeaturesPromotedTo12(
    const vk::ExtensionNameList &deviceExtensionNames,
    VkPhysicalDeviceFeatures2KHR *deviceFeatures,
    VkPhysicalDeviceProperties2 *deviceProperties)
{
    if (ExtensionFound(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceProperties, &mFloatControlProperties);
    }

    if (ExtensionFound(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mShaderFloat16Int8Features);
    }

    if (ExtensionFound(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceProperties, &mDepthStencilResolveProperties);
    }

    if (ExtensionFound(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceProperties, &mDriverProperties);
    }

    if (ExtensionFound(VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mSubgroupExtendedTypesFeatures);
    }

    if (ExtensionFound(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mHostQueryResetFeatures);
    }

    if (ExtensionFound(VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mImagelessFramebufferFeatures);
    }

    if (ExtensionFound(VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mTimelineSemaphoreFeatures);
    }

    if (ExtensionFound(VK_KHR_8BIT_STORAGE_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &m8BitStorageFeatures);
    }

    if (ExtensionFound(VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mUniformBufferStandardLayoutFeatures);
    }

    if (ExtensionFound(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mBufferDeviceAddressFeatures);
    }

    if (ExtensionFound(VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mShaderAtomicInt64Features);
    }
}

// The following features and properties used by ANGLE have been promoted to Vulkan 1.3:
//
// - VK_EXT_extended_dynamic_state:             extendedDynamicState (feature)
// - VK_EXT_extended_dynamic_state2:            extendedDynamicState2 (feature),
//                                              extendedDynamicState2LogicOp (feature)
// - VK_KHR_synchronization2:                   synchronization2 (feature)
// - VK_KHR_dynamic_rendering:                  dynamicRendering (feature)
// - VK_KHR_maintenance5:                       maintenance5 (feature)
// - VK_EXT_texture_compression_astc_hdr:       textureCompressionASTC_HDR(feature)
// - VK_KHR_shader_integer_dot_product:         shaderIntegerDotProduct (feature)
// - VK_EXT_shader_demote_to_helper_invocation: shaderDemoteToHelperInvocation (feature)
//
// Note that VK_EXT_extended_dynamic_state2 is partially promoted to Vulkan 1.3.  If ANGLE creates a
// Vulkan 1.3 device, it would still need to enable this extension separately for
// extendedDynamicState2LogicOp.
//
void Renderer::appendDeviceExtensionFeaturesPromotedTo13(
    const vk::ExtensionNameList &deviceExtensionNames,
    VkPhysicalDeviceFeatures2KHR *deviceFeatures,
    VkPhysicalDeviceProperties2 *deviceProperties)
{
    if (ExtensionFound(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mExtendedDynamicStateFeatures);
    }

    if (ExtensionFound(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mExtendedDynamicState2Features);
    }

    if (ExtensionFound(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mSynchronization2Features);
    }

    if (ExtensionFound(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mDynamicRenderingFeatures);
    }

    if (ExtensionFound(VK_KHR_MAINTENANCE_5_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mMaintenance5Features);
    }

    if (ExtensionFound(VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mTextureCompressionASTCHDRFeatures);
    }

    if (ExtensionFound(VK_KHR_SHADER_INTEGER_DOT_PRODUCT_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mShaderIntegerDotProductFeatures);
        vk::AddToPNextChain(deviceProperties, &mShaderIntegerDotProductProperties);
    }

    if (ExtensionFound(VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME,
                       deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mShaderDemoteToHelperInvocationFeatures);
    }
}

// The following features and properties used by ANGLE have been promoted to Vulkan 1.4:
//
// - VK_KHR_line_rasterization or
//   VK_EXT_line_rasterization:                        bresenhamLines (feature)
// - VK_KHR_vertex_attribute_divisor or
//   VK_EXT_vertex_attribute_divisor:                  vertexAttributeInstanceRateDivisor (feature),
//                                                     maxVertexAttribDivisor (property)
// - VK_KHR_index_type_uint8 or
//   VK_EXT_index_type_uint8:                          indexTypeUint8 (feature)
// - VK_KHR_global_priority                            globalPriorityQuery (feature)
// - VK_KHR_dynamic_rendering_local_read:              dynamicRenderingLocalRead (feature)
// - VK_EXT_host_image_copy:                           hostImageCopy (feature),
//                                                     pCopySrcLayouts (property),
//                                                     pCopyDstLayouts (property),
//                                                     identicalMemoryTypeRequirements (property)
//
void Renderer::appendDeviceExtensionFeaturesPromotedTo14(
    const vk::ExtensionNameList &deviceExtensionNames,
    VkPhysicalDeviceFeatures2KHR *deviceFeatures,
    VkPhysicalDeviceProperties2 *deviceProperties)
{
    if (ExtensionFound(VK_KHR_LINE_RASTERIZATION_EXTENSION_NAME, deviceExtensionNames) ||
        ExtensionFound(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mLineRasterizationFeatures);
    }

    const bool hasVertexAttributeDivisorKHR =
        ExtensionFound(VK_KHR_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, deviceExtensionNames);
    const bool hasVertexAttributeDivisorEXT =
        ExtensionFound(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, deviceExtensionNames);
    if (hasVertexAttributeDivisorKHR || hasVertexAttributeDivisorEXT)
    {
        vk::AddToPNextChain(deviceFeatures, &mVertexAttributeDivisorFeatures);
        // VK_KHR_vertex_attribute_divisor is used by default, but it has an extra property
        // |supportsNonZeroFirstInstance| that ANGLE needs to be true.  The EXT version doesn't have
        // this property and is required to support the functionality.  Both properties are queried,
        // and if the KHR extension does not support this functionality, ANGLE falls back to the EXT
        // version.
        if (hasVertexAttributeDivisorKHR)
        {
            vk::AddToPNextChain(deviceProperties, &mVertexAttributeDivisorProperties);
        }
        if (hasVertexAttributeDivisorEXT)
        {
            vk::AddToPNextChain(deviceProperties, &mVertexAttributeDivisorPropertiesEXT);
        }
    }

    if (ExtensionFound(VK_KHR_INDEX_TYPE_UINT8_EXTENSION_NAME, deviceExtensionNames) ||
        ExtensionFound(VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mIndexTypeUint8Features);
    }

    if (ExtensionFound(VK_KHR_GLOBAL_PRIORITY_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mPhysicalDeviceGlobalPriorityQueryFeatures);
    }

    if (ExtensionFound(VK_KHR_DYNAMIC_RENDERING_LOCAL_READ_EXTENSION_NAME, deviceExtensionNames))
    {
        vk::AddToPNextChain(deviceFeatures, &mDynamicRenderingLocalReadFeatures);
    }

    if (ExtensionFound(VK_EXT_HOST_IMAGE_COPY_EXTENSION_NAME, deviceExtensionNames))
    {
        // VkPhysicalDeviceHostImageCopyProperties has a count + array query.  Typically, that
        // requires getting the properties once with a nullptr array, to get the count, and then
        // again with an array of that size.  For simplicity, ANGLE just uses an array that's big
        // enough.  If that array goes terribly large in the future, ANGLE may lose knowledge of
        // some likely esoteric layouts, which doesn't really matter.
        constexpr uint32_t kMaxLayoutCount = 50;
        mHostImageCopySrcLayoutsStorage.resize(kMaxLayoutCount, VK_IMAGE_LAYOUT_UNDEFINED);
        mHostImageCopyDstLayoutsStorage.resize(kMaxLayoutCount, VK_IMAGE_LAYOUT_UNDEFINED);
        mHostImageCopyProperties.copySrcLayoutCount = kMaxLayoutCount;
        mHostImageCopyProperties.copyDstLayoutCount = kMaxLayoutCount;
        mHostImageCopyProperties.pCopySrcLayouts    = mHostImageCopySrcLayoutsStorage.data();
        mHostImageCopyProperties.pCopyDstLayouts    = mHostImageCopyDstLayoutsStorage.data();

        vk::AddToPNextChain(deviceFeatures, &mHostImageCopyFeatures);
        vk::AddToPNextChain(deviceProperties, &mHostImageCopyProperties);
    }
}

void Renderer::queryDeviceExtensionFeatures(const vk::ExtensionNameList &deviceExtensionNames)
{
    // Default initialize all extension features to false.
    mLineRasterizationFeatures = {};
    mLineRasterizationFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES;

    mProvokingVertexFeatures = {};
    mProvokingVertexFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT;

    mVertexAttributeDivisorFeatures = {};
    mVertexAttributeDivisorFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES;

    mVertexAttributeDivisorProperties = {};
    mVertexAttributeDivisorProperties.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES;

    // Note: VkPhysicalDeviceVertexAttributeDivisorProperties is different from the EXT version.
    mVertexAttributeDivisorPropertiesEXT = {};
    mVertexAttributeDivisorPropertiesEXT.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT;

    mTransformFeedbackFeatures = {};
    mTransformFeedbackFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT;

    mIndexTypeUint8Features       = {};
    mIndexTypeUint8Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES;

    mSubgroupProperties       = {};
    mSubgroupProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;

    mSubgroupExtendedTypesFeatures = {};
    mSubgroupExtendedTypesFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES;

    mMemoryReportFeatures = {};
    mMemoryReportFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT;

    mShaderFloat16Int8Features = {};
    mShaderFloat16Int8Features.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES;

    mDepthStencilResolveProperties = {};
    mDepthStencilResolveProperties.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES;

    mCustomBorderColorFeatures = {};
    mCustomBorderColorFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT;

    mMultisampledRenderToSingleSampledFeatures = {};
    mMultisampledRenderToSingleSampledFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_FEATURES_EXT;

    mImage2dViewOf3dFeatures = {};
    mImage2dViewOf3dFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT;

    mMultiviewFeatures       = {};
    mMultiviewFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES;

    mMultiviewProperties       = {};
    mMultiviewProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES;

    mMaintenance3Properties       = {};
    mMaintenance3Properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES;

    mFaultFeatures       = {};
    mFaultFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT;

    mDriverProperties       = {};
    mDriverProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;

    mSamplerYcbcrConversionFeatures = {};
    mSamplerYcbcrConversionFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;

    mProtectedMemoryFeatures       = {};
    mProtectedMemoryFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES;

    mHostQueryResetFeatures       = {};
    mHostQueryResetFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT;

    mDepthClampZeroOneFeatures = {};
    mDepthClampZeroOneFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLAMP_ZERO_ONE_FEATURES_KHR;

    mDepthClipControlFeatures = {};
    mDepthClipControlFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT;

    mPrimitivesGeneratedQueryFeatures = {};
    mPrimitivesGeneratedQueryFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT;

    mPrimitiveTopologyListRestartFeatures = {};
    mPrimitiveTopologyListRestartFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT;

    mExtendedDynamicStateFeatures = {};
    mExtendedDynamicStateFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT;

    mExtendedDynamicState2Features = {};
    mExtendedDynamicState2Features.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT;

    mGraphicsPipelineLibraryFeatures = {};
    mGraphicsPipelineLibraryFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT;

    mGraphicsPipelineLibraryProperties = {};
    mGraphicsPipelineLibraryProperties.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_PROPERTIES_EXT;

    mVertexInputDynamicStateFeatures = {};
    mVertexInputDynamicStateFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT;

    mDynamicRenderingFeatures = {};
    mDynamicRenderingFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR;

    mDynamicRenderingLocalReadFeatures = {};
    mDynamicRenderingLocalReadFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_LOCAL_READ_FEATURES_KHR;

    mFragmentShadingRateFeatures = {};
    mFragmentShadingRateFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR;

    mFragmentShadingRateProperties = {};
    mFragmentShadingRateProperties.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR;

    mFragmentShaderInterlockFeatures = {};
    mFragmentShaderInterlockFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT;

    mImagelessFramebufferFeatures = {};
    mImagelessFramebufferFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR;

    mPipelineRobustnessFeatures = {};
    mPipelineRobustnessFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_FEATURES_EXT;

    mPipelineProtectedAccessFeatures = {};
    mPipelineProtectedAccessFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROTECTED_ACCESS_FEATURES_EXT;

    mRasterizationOrderAttachmentAccessFeatures = {};
    mRasterizationOrderAttachmentAccessFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT;

    mMaintenance5Features       = {};
    mMaintenance5Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_5_FEATURES_KHR;

    mShaderAtomicFloatFeatures = {};
    mShaderAtomicFloatFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT;

    mSwapchainMaintenance1Features = {};
    mSwapchainMaintenance1Features.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_KHR;

    mDitheringFeatures       = {};
    mDitheringFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_DITHERING_FEATURES_EXT;

    mDrmProperties       = {};
    mDrmProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT;

    mTimelineSemaphoreFeatures = {};
    mTimelineSemaphoreFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR;

    mHostImageCopyFeatures       = {};
    mHostImageCopyFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES;

    mHostImageCopyProperties       = {};
    mHostImageCopyProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_PROPERTIES;

    m8BitStorageFeatures       = {};
    m8BitStorageFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR;

    m16BitStorageFeatures       = {};
    m16BitStorageFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR;

    mSynchronization2Features       = {};
    mSynchronization2Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES;

    mBlendOperationAdvancedFeatures = {};
    mBlendOperationAdvancedFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT;

    mVariablePointersFeatures = {};
    mVariablePointersFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR;

    // Rounding and denormal caps from VK_KHR_float_controls_properties
    mFloatControlProperties       = {};
    mFloatControlProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES;

    mImageCompressionControlFeatures = {};
    mImageCompressionControlFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT;

    mImageCompressionControlSwapchainFeatures = {};
    mImageCompressionControlSwapchainFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT;

    mTextureCompressionASTCHDRFeatures = {};
    mTextureCompressionASTCHDRFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES;

    mUniformBufferStandardLayoutFeatures = {};
    mUniformBufferStandardLayoutFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES;

    mPhysicalDeviceAstcDecodeFeatures = {};
    mPhysicalDeviceAstcDecodeFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT;

    mUnifiedImageLayoutsFeatures = {};
    mUnifiedImageLayoutsFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFIED_IMAGE_LAYOUTS_FEATURES_KHR;

    mShaderIntegerDotProductFeatures = {};
    mShaderIntegerDotProductFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES;

    mShaderIntegerDotProductProperties = {};
    mShaderIntegerDotProductProperties.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES;

    mShaderDemoteToHelperInvocationFeatures = {};
    mShaderDemoteToHelperInvocationFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES;

    mPhysicalDeviceGlobalPriorityQueryFeatures = {};
    mPhysicalDeviceGlobalPriorityQueryFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES;

    mExternalMemoryHostProperties = {};
    mExternalMemoryHostProperties.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT;

    mBufferDeviceAddressFeatures = {};
    mBufferDeviceAddressFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES;

    mShaderAtomicInt64Features = {};
    mShaderAtomicInt64Features.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES;

    mTextureCompressionASTC3DFeatures = {};
    mTextureCompressionASTC3DFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_3D_FEATURES_EXT;

#if defined(ANGLE_PLATFORM_ANDROID)
    mExternalFormatResolveFeatures = {};
    mExternalFormatResolveFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FORMAT_RESOLVE_FEATURES_ANDROID;

    mExternalFormatResolveProperties = {};
    mExternalFormatResolveProperties.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FORMAT_RESOLVE_PROPERTIES_ANDROID;
#endif

    mTileMemoryHeapFeatures = {};
    mTileMemoryHeapFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_MEMORY_HEAP_FEATURES_QCOM;
    mTileMemoryHeapProperties = {};
    mTileMemoryHeapProperties.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_MEMORY_HEAP_PROPERTIES_QCOM;

    mShaderCorePropertiesAMD       = {};
    mShaderCorePropertiesAMD.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD;

    // Query features and properties.
    VkPhysicalDeviceFeatures2KHR deviceFeatures = {};
    deviceFeatures.sType                        = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;

    VkPhysicalDeviceProperties2 deviceProperties = {};
    deviceProperties.sType                       = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;

    appendDeviceExtensionFeaturesNotPromoted(deviceExtensionNames, &deviceFeatures,
                                             &deviceProperties);
    appendDeviceExtensionFeaturesPromotedTo11(deviceExtensionNames, &deviceFeatures,
                                              &deviceProperties);
    appendDeviceExtensionFeaturesPromotedTo12(deviceExtensionNames, &deviceFeatures,
                                              &deviceProperties);
    appendDeviceExtensionFeaturesPromotedTo13(deviceExtensionNames, &deviceFeatures,
                                              &deviceProperties);
    appendDeviceExtensionFeaturesPromotedTo14(deviceExtensionNames, &deviceFeatures,
                                              &deviceProperties);

    static_assert(GetPerfCounterGroup(VulkanApiFunction::vkGetPhysicalDeviceFeatures2) ==
                  GetPerfCounterGroup(VulkanApiFunction::vkGetPhysicalDeviceProperties2));
    VK_CALL_WITH_GROUP(GetPerfCounterGroup(VulkanApiFunction::vkGetPhysicalDeviceFeatures2),
                       (vkGetPhysicalDeviceFeatures2(mPhysicalDevice, &deviceFeatures),
                        vkGetPhysicalDeviceProperties2(mPhysicalDevice, &deviceProperties)));

    // Clean up pNext chains
    mLineRasterizationFeatures.pNext                  = nullptr;
    mMemoryReportFeatures.pNext                       = nullptr;
    mProvokingVertexFeatures.pNext                    = nullptr;
    mVertexAttributeDivisorFeatures.pNext             = nullptr;
    mVertexAttributeDivisorProperties.pNext           = nullptr;
    mVertexAttributeDivisorPropertiesEXT.pNext        = nullptr;
    mTransformFeedbackFeatures.pNext                  = nullptr;
    mIndexTypeUint8Features.pNext                     = nullptr;
    mSubgroupProperties.pNext                         = nullptr;
    mSubgroupExtendedTypesFeatures.pNext              = nullptr;
    mCustomBorderColorFeatures.pNext                  = nullptr;
    mShaderFloat16Int8Features.pNext                  = nullptr;
    mDepthStencilResolveProperties.pNext              = nullptr;
    mMultisampledRenderToSingleSampledFeatures.pNext  = nullptr;
    mImage2dViewOf3dFeatures.pNext                    = nullptr;
    mMultiviewFeatures.pNext                          = nullptr;
    mMultiviewProperties.pNext                        = nullptr;
    mDriverProperties.pNext                           = nullptr;
    mSamplerYcbcrConversionFeatures.pNext             = nullptr;
    mProtectedMemoryFeatures.pNext                    = nullptr;
    mHostQueryResetFeatures.pNext                     = nullptr;
    mDepthClampZeroOneFeatures.pNext                  = nullptr;
    mDepthClipControlFeatures.pNext                   = nullptr;
    mPrimitivesGeneratedQueryFeatures.pNext           = nullptr;
    mPrimitiveTopologyListRestartFeatures.pNext       = nullptr;
    mExtendedDynamicStateFeatures.pNext               = nullptr;
    mExtendedDynamicState2Features.pNext              = nullptr;
    mGraphicsPipelineLibraryFeatures.pNext            = nullptr;
    mGraphicsPipelineLibraryProperties.pNext          = nullptr;
    mVertexInputDynamicStateFeatures.pNext            = nullptr;
    mDynamicRenderingFeatures.pNext                   = nullptr;
    mDynamicRenderingLocalReadFeatures.pNext          = nullptr;
    mFragmentShadingRateFeatures.pNext                = nullptr;
    mFragmentShaderInterlockFeatures.pNext            = nullptr;
    mImagelessFramebufferFeatures.pNext               = nullptr;
    mPipelineRobustnessFeatures.pNext                 = nullptr;
    mPipelineProtectedAccessFeatures.pNext            = nullptr;
    mRasterizationOrderAttachmentAccessFeatures.pNext = nullptr;
    mShaderAtomicFloatFeatures.pNext                  = nullptr;
    mMaintenance5Features.pNext                       = nullptr;
    mSwapchainMaintenance1Features.pNext              = nullptr;
    mDitheringFeatures.pNext                          = nullptr;
    mDrmProperties.pNext                              = nullptr;
    mTimelineSemaphoreFeatures.pNext                  = nullptr;
    mHostImageCopyFeatures.pNext                      = nullptr;
    mHostImageCopyProperties.pNext                    = nullptr;
    m8BitStorageFeatures.pNext                        = nullptr;
    m16BitStorageFeatures.pNext                       = nullptr;
    mSynchronization2Features.pNext                   = nullptr;
    mBlendOperationAdvancedFeatures.pNext             = nullptr;
    mVariablePointersFeatures.pNext                   = nullptr;
    mFloatControlProperties.pNext                     = nullptr;
    mImageCompressionControlFeatures.pNext            = nullptr;
    mImageCompressionControlSwapchainFeatures.pNext   = nullptr;
    mTextureCompressionASTCHDRFeatures.pNext          = nullptr;
    mUniformBufferStandardLayoutFeatures.pNext        = nullptr;
    mMaintenance3Properties.pNext                     = nullptr;
    mFaultFeatures.pNext                              = nullptr;
    mPhysicalDeviceAstcDecodeFeatures.pNext           = nullptr;
    mUnifiedImageLayoutsFeatures.pNext                = nullptr;
    mShaderIntegerDotProductFeatures.pNext            = nullptr;
    mShaderIntegerDotProductProperties.pNext          = nullptr;
    mShaderDemoteToHelperInvocationFeatures.pNext     = nullptr;
    mPhysicalDeviceGlobalPriorityQueryFeatures.pNext  = nullptr;
    mExternalMemoryHostProperties.pNext               = nullptr;
    mBufferDeviceAddressFeatures.pNext                = nullptr;
    mShaderAtomicInt64Features.pNext                  = nullptr;
    mTextureCompressionASTC3DFeatures.pNext           = nullptr;
#if defined(ANGLE_PLATFORM_ANDROID)
    mExternalFormatResolveFeatures.pNext   = nullptr;
    mExternalFormatResolveProperties.pNext = nullptr;
#endif
    mTileMemoryHeapFeatures.pNext   = nullptr;
    mTileMemoryHeapProperties.pNext = nullptr;
    mShaderCorePropertiesAMD.pNext  = nullptr;
}

// See comment above appendDeviceExtensionFeaturesNotPromoted.  Additional extensions are enabled
// here which don't have feature structs:
//
// - VK_KHR_shared_presentable_image
// - VK_EXT_device_memory_report
// - VK_EXT_memory_budget
// - VK_KHR_incremental_present
// - VK_EXT_queue_family_foreign
// - VK_ANDROID_external_memory_android_hardware_buffer
// - VK_KHR_external_memory_fd
// - VK_KHR_external_memory_fuchsia
// - VK_KHR_external_semaphore_fd
// - VK_KHR_external_fence_fd
// - VK_FUCHSIA_external_semaphore
// - VK_EXT_shader_stencil_export
// - VK_GOOGLE_display_timing
// - VK_EXT_external_memory_dma_buf
// - VK_EXT_image_drm_format_modifier
// - VK_EXT_blend_operation_advanced
// - VK_EXT_full_screen_exclusive
// - VK_EXT_image_compression_control
// - VK_EXT_image_compression_control_swapchain
// - VK_AMD_shader_core_properties
//
void Renderer::enableDeviceExtensionsNotPromoted(const vk::ExtensionNameList &deviceExtensionNames)
{
    if (mFeatures.supportsSharedPresentableImageExtension.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME);
    }

    if (mFeatures.supportsDepthClampZeroOne.enabled)
    {
        const bool hasKHR =
            ExtensionFound(VK_KHR_DEPTH_CLAMP_ZERO_ONE_EXTENSION_NAME, deviceExtensionNames);
        mEnabledDeviceExtensions.push_back(hasKHR ? VK_KHR_DEPTH_CLAMP_ZERO_ONE_EXTENSION_NAME
                                                  : VK_EXT_DEPTH_CLAMP_ZERO_ONE_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mDepthClampZeroOneFeatures);
    }

    if (mFeatures.supportsMemoryBudget.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME);
    }

    if (mFeatures.supportsIncrementalPresent.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME);
    }

#if defined(ANGLE_PLATFORM_ANDROID)
    if (mFeatures.supportsAndroidHardwareBuffer.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
        mEnabledDeviceExtensions.push_back(
            VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
    }
#else
    ASSERT(!mFeatures.supportsAndroidHardwareBuffer.enabled);
#endif

    if (mFeatures.supportsExternalMemoryFd.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
    }

    if (mFeatures.supportsExternalMemoryFuchsia.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME);
    }

    if (mFeatures.supportsExternalSemaphoreFd.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME);
    }

    if (mFeatures.supportsExternalFenceFd.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME);
    }

    if (mFeatures.supportsExternalSemaphoreFuchsia.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
    }

    if (mFeatures.supportsShaderStencilExport.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME);
    }

    if (mFeatures.supportsTimestampSurfaceAttribute.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME);
    }

    if (mFeatures.provokingVertex.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mProvokingVertexFeatures);
    }

    if (mFeatures.supportsTransformFeedbackExtension.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mTransformFeedbackFeatures);
    }

    if (mFeatures.supportsCustomBorderColor.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mCustomBorderColorFeatures);
    }

    if (mFeatures.supportsMultisampledRenderToSingleSampled.enabled)
    {
        mEnabledDeviceExtensions.push_back(
            VK_EXT_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mMultisampledRenderToSingleSampledFeatures);
    }

    if (mFeatures.logMemoryReportCallbacks.enabled || mFeatures.logMemoryReportStats.enabled)
    {
        ASSERT(mMemoryReportFeatures.deviceMemoryReport);
        mEnabledDeviceExtensions.push_back(VK_EXT_DEVICE_MEMORY_REPORT_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mMemoryReportFeatures);
    }

    if (mFeatures.supportsExternalMemoryDmaBuf.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME);
    }

    if (mFeatures.supportsImageDrmFormatModifier.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME);
    }

    if (mFeatures.supportsExternalMemoryHost.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME);
    }

    if (mFeatures.supportsDepthClipControl.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mDepthClipControlFeatures);
    }

    if (mFeatures.supportsPrimitivesGeneratedQuery.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_PRIMITIVES_GENERATED_QUERY_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mPrimitivesGeneratedQueryFeatures);
    }

    if (mFeatures.supportsPrimitiveTopologyListRestart.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mPrimitiveTopologyListRestartFeatures);
    }

    if (mFeatures.supportsBlendOperationAdvanced.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mBlendOperationAdvancedFeatures);
    }

    if (mFeatures.supportsGraphicsPipelineLibrary.enabled)
    {
        // VK_EXT_graphics_pipeline_library requires VK_KHR_pipeline_library
        ASSERT(ExtensionFound(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME, deviceExtensionNames));
        mEnabledDeviceExtensions.push_back(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME);

        mEnabledDeviceExtensions.push_back(VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mGraphicsPipelineLibraryFeatures);
    }

    if (mFeatures.supportsFragmentShadingRate.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mFragmentShadingRateFeatures);
    }

    if (mFeatures.supportsFragmentShaderPixelInterlock.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mFragmentShaderInterlockFeatures);
    }

    if (mFeatures.supportsPipelineRobustness.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_PIPELINE_ROBUSTNESS_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mPipelineRobustnessFeatures);
    }

    if (mFeatures.supportsPipelineProtectedAccess.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_PIPELINE_PROTECTED_ACCESS_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mPipelineProtectedAccessFeatures);
    }

    if (mFeatures.supportsRasterizationOrderAttachmentAccess.enabled)
    {
        if (ExtensionFound(VK_EXT_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME,
                           deviceExtensionNames))
        {
            mEnabledDeviceExtensions.push_back(
                VK_EXT_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME);
        }
        else
        {
            ASSERT(ExtensionFound(VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME,
                                  deviceExtensionNames));
            mEnabledDeviceExtensions.push_back(
                VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME);
        }
        vk::AddToPNextChain(&mEnabledFeatures, &mRasterizationOrderAttachmentAccessFeatures);
    }

    if (!mFeatures.emulateR32fImageAtomicExchange.enabled)
    {
        ASSERT(ExtensionFound(VK_EXT_SHADER_ATOMIC_FLOAT_EXTENSION_NAME, deviceExtensionNames));
        mEnabledDeviceExtensions.push_back(VK_EXT_SHADER_ATOMIC_FLOAT_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mShaderAtomicFloatFeatures);
    }

    if (mFeatures.supportsImage2dViewOf3d.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_IMAGE_2D_VIEW_OF_3D_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mImage2dViewOf3dFeatures);
    }

    if (mFeatures.supportsSwapchainMaintenance1.enabled)
    {
        const bool hasKHR =
            ExtensionFound(VK_KHR_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME, deviceExtensionNames);
        mEnabledDeviceExtensions.push_back(hasKHR ? VK_KHR_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME
                                                  : VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mSwapchainMaintenance1Features);
    }

    if (mFeatures.supportsLegacyDithering.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_LEGACY_DITHERING_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mDitheringFeatures);
    }

    if (getFeatures().supportsVertexInputDynamicState.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mVertexInputDynamicStateFeatures);
    }

    if (getFeatures().supportsUnifiedImageLayouts.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_UNIFIED_IMAGE_LAYOUTS_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mUnifiedImageLayoutsFeatures);
    }

    if (getFeatures().supportsImageCompressionControl.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_IMAGE_COMPRESSION_CONTROL_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mImageCompressionControlFeatures);
    }

    if (getFeatures().supportsImageCompressionControlSwapchain.enabled)
    {
        mEnabledDeviceExtensions.push_back(
            VK_EXT_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mImageCompressionControlSwapchainFeatures);
    }

    if (mFeatures.supportsSwapchainMutableFormat.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME);
    }

    if (mFeatures.supportsDeviceFault.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_DEVICE_FAULT_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mFaultFeatures);
    }

    if (mFeatures.supportsAstcDecodeMode.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mPhysicalDeviceAstcDecodeFeatures);
    }

    if (mFeatures.supportsAstc3d.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_TEXTURE_COMPRESSION_ASTC_3D_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mTextureCompressionASTC3DFeatures);
    }

#if defined(ANGLE_PLATFORM_WINDOWS)
    // We only need the VK_EXT_full_screen_exclusive extension if we are opting
    // out of it via VK_FULL_SCREEN_EXCLUSIVE_DISALLOWED_EXT (i.e. working
    // around driver bugs).
    if (getFeatures().supportsFullScreenExclusive.enabled &&
        getFeatures().forceDisableFullScreenExclusive.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME);
    }
#endif

#if defined(ANGLE_PLATFORM_ANDROID)
    if (mFeatures.supportsExternalFormatResolve.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_ANDROID_EXTERNAL_FORMAT_RESOLVE_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mExternalFormatResolveFeatures);
    }
#endif

    if (getFeatures().supportsTileMemoryHeap.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_QCOM_TILE_MEMORY_HEAP_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mTileMemoryHeapFeatures);
    }

    if (getFeatures().supportsAmdShaderCoreProperties.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_AMD_SHADER_CORE_PROPERTIES_EXTENSION_NAME);
    }
}

// See comment above appendDeviceExtensionFeaturesPromotedTo11.
void Renderer::enableDeviceExtensionsPromotedTo11(const vk::ExtensionNameList &deviceExtensionNames)
{
    // OVR_multiview disallows multiview with geometry and tessellation, so don't request these
    // features.
    mMultiviewFeatures.multiviewGeometryShader     = VK_FALSE;
    mMultiviewFeatures.multiviewTessellationShader = VK_FALSE;

    if (mFeatures.supportsMultiview.enabled)
    {
        vk::AddToPNextChain(&mEnabledFeatures, &mMultiviewFeatures);
    }

    if (mFeatures.supportsYUVSamplerConversion.enabled)
    {
        vk::AddToPNextChain(&mEnabledFeatures, &mSamplerYcbcrConversionFeatures);
    }

    if (mFeatures.supportsProtectedMemory.enabled)
    {
        vk::AddToPNextChain(&mEnabledFeatures, &mProtectedMemoryFeatures);
    }

    if (mFeatures.supports16BitStorageBuffer.enabled ||
        mFeatures.supports16BitUniformAndStorageBuffer.enabled ||
        mFeatures.supports16BitPushConstant.enabled || mFeatures.supports16BitInputOutput.enabled)
    {
        vk::AddToPNextChain(&mEnabledFeatures, &m16BitStorageFeatures);
    }

    vk::AddToPNextChain(&mEnabledFeatures, &mVariablePointersFeatures);
}

// See comment above appendDeviceExtensionFeaturesPromotedTo12.  Additional extensions are enabled
// here which don't have feature structs:
//
// - VK_KHR_create_renderpass2
// - VK_KHR_image_format_list
// - VK_KHR_shader_float_controls
// - VK_KHR_spirv_1_4
// - VK_KHR_sampler_mirror_clamp_to_edge
// - VK_KHR_depth_stencil_resolve
// - VK_KHR_buffer_device_address
//
void Renderer::enableDeviceExtensionsPromotedTo12(const vk::ExtensionNameList &deviceExtensionNames)
{
    if (mFeatures.supportsRenderpass2.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME);
    }

    if (mFeatures.supportsImageFormatList.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME);
    }

    // There are several FP related modes defined as properties from
    // VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION, and there could be a scenario where the extension is
    // supported but none of the modes are supported. Here we enable the extension if it is found.
    if (ExtensionFound(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME, deviceExtensionNames))
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME);
    }

    if (mFeatures.supportsSPIRV14.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_SPIRV_1_4_EXTENSION_NAME);
    }

    if (mFeatures.supportsSamplerMirrorClampToEdge.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME);
    }

    if (mFeatures.supportsDepthStencilResolve.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME);
    }

    if (mFeatures.allowGenerateMipmapWithCompute.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mSubgroupExtendedTypesFeatures);
    }

    if (mFeatures.supportsShaderFloat16.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mShaderFloat16Int8Features);
    }

    if (mFeatures.supportsHostQueryReset.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mHostQueryResetFeatures);
    }

    if (mFeatures.supportsImagelessFramebuffer.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mImagelessFramebufferFeatures);
    }

    if (mFeatures.supportsTimelineSemaphore.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mTimelineSemaphoreFeatures);
    }

    if (mFeatures.supports8BitStorageBuffer.enabled ||
        mFeatures.supports8BitUniformAndStorageBuffer.enabled ||
        mFeatures.supports8BitPushConstant.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_8BIT_STORAGE_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &m8BitStorageFeatures);
    }
    if (mFeatures.supportsUniformBufferStandardLayout.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mUniformBufferStandardLayoutFeatures);
    }
    if (mFeatures.supportsBufferDeviceAddress.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mBufferDeviceAddressFeatures);
    }
    if (mFeatures.supportsShaderAtomicInt64.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mShaderAtomicInt64Features);
    }
}

// See comment above appendDeviceExtensionFeaturesPromotedTo13.  Additional extensions are enabled
// here which don't have feature structs:
//
// - VK_KHR_format_feature_flags2
//
void Renderer::enableDeviceExtensionsPromotedTo13(const vk::ExtensionNameList &deviceExtensionNames)
{
    if (mFeatures.supportsPipelineCreationFeedback.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME);
    }

    if (mFeatures.supportsExtendedDynamicState.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mExtendedDynamicStateFeatures);
    }

    if (mFeatures.supportsExtendedDynamicState2.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mExtendedDynamicState2Features);
    }

    if (mFeatures.supportsSynchronization2.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mSynchronization2Features);
    }

    if (getFeatures().supportsDynamicRendering.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mDynamicRenderingFeatures);
    }

    if (getFeatures().supportsMaintenance5.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_MAINTENANCE_5_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mMaintenance5Features);
    }

    if (mFeatures.supportsFormatFeatureFlags2.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME);
    }

    if (getFeatures().supportsTextureCompressionAstcHdr.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mTextureCompressionASTCHDRFeatures);
    }

    if (mFeatures.supportsShaderIntegerDotProduct.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_SHADER_INTEGER_DOT_PRODUCT_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mShaderIntegerDotProductFeatures);
    }

    if (mFeatures.supportsShaderDemoteToHelperInvocation.enabled)
    {
        mEnabledDeviceExtensions.push_back(
            VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mShaderDemoteToHelperInvocationFeatures);
    }
}

// See comment above appendDeviceExtensionFeaturesPromotedTo14.  Additional extensions are enabled
// here which don't have feature structs:
//
// - VK_KHR_load_store_op_none
// - VK_EXT_load_store_op_none
// - VK_QCOM_render_pass_store_ops
//
void Renderer::enableDeviceExtensionsPromotedTo14(const vk::ExtensionNameList &deviceExtensionNames)
{
    if (mFeatures.bresenhamLineRasterization.enabled)
    {
        const bool hasKHR =
            ExtensionFound(VK_KHR_LINE_RASTERIZATION_EXTENSION_NAME, deviceExtensionNames);
        mEnabledDeviceExtensions.push_back(hasKHR ? VK_KHR_LINE_RASTERIZATION_EXTENSION_NAME
                                                  : VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mLineRasterizationFeatures);
    }

    if (mVertexAttributeDivisorFeatures.vertexAttributeInstanceRateDivisor)
    {
        // If KHR doesn't advertise support for supportsNonZeroFirstInstance, fall back to EXT where
        // it is implicitly supported.
        const bool hasKHR =
            ExtensionFound(VK_KHR_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, deviceExtensionNames) &&
            mVertexAttributeDivisorProperties.supportsNonZeroFirstInstance;
        const bool hasEXT =
            ExtensionFound(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, deviceExtensionNames);

        // If only KHR is available, but it doesn't support supportsNonZeroFirstInstance, it's as if
        // neither extension is available.
        if (hasKHR || hasEXT)
        {
            mEnabledDeviceExtensions.push_back(
                hasKHR ? VK_KHR_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME
                       : VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME);
            vk::AddToPNextChain(&mEnabledFeatures, &mVertexAttributeDivisorFeatures);

            mMaxVertexAttribDivisor =
                hasKHR ? mVertexAttributeDivisorProperties.maxVertexAttribDivisor
                       : mVertexAttributeDivisorPropertiesEXT.maxVertexAttribDivisor;
            // We only store 8 bit divisor in GraphicsPipelineDesc so capping value & we emulate if
            // exceeded
            mMaxVertexAttribDivisor =
                std::min(mMaxVertexAttribDivisor,
                         static_cast<uint32_t>(std::numeric_limits<uint8_t>::max()));
        }
    }

    if (mFeatures.supportsIndexTypeUint8.enabled)
    {
        const bool hasKHR =
            ExtensionFound(VK_KHR_INDEX_TYPE_UINT8_EXTENSION_NAME, deviceExtensionNames);
        mEnabledDeviceExtensions.push_back(hasKHR ? VK_KHR_INDEX_TYPE_UINT8_EXTENSION_NAME
                                                  : VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mIndexTypeUint8Features);
    }

    if (mFeatures.supportsGlobalPriority.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_GLOBAL_PRIORITY_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mPhysicalDeviceGlobalPriorityQueryFeatures);
    }

    if (getFeatures().supportsDynamicRenderingLocalRead.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_DYNAMIC_RENDERING_LOCAL_READ_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mDynamicRenderingLocalReadFeatures);
    }

    if (mFeatures.supportsHostImageCopy.enabled)
    {
        // VK_EXT_host_image_copy requires VK_KHR_copy_commands2 and VK_KHR_format_feature_flags2.
        // VK_KHR_format_feature_flags2 is enabled separately.
        ASSERT(ExtensionFound(VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME, deviceExtensionNames));
        ASSERT(ExtensionFound(VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME, deviceExtensionNames));
        mEnabledDeviceExtensions.push_back(VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME);

        mEnabledDeviceExtensions.push_back(VK_EXT_HOST_IMAGE_COPY_EXTENSION_NAME);
        vk::AddToPNextChain(&mEnabledFeatures, &mHostImageCopyFeatures);
    }

    if (mFeatures.supportsRenderPassLoadStoreOpNone.enabled)
    {
        const bool hasKHR =
            ExtensionFound(VK_KHR_LOAD_STORE_OP_NONE_EXTENSION_NAME, deviceExtensionNames);
        mEnabledDeviceExtensions.push_back(hasKHR ? VK_KHR_LOAD_STORE_OP_NONE_EXTENSION_NAME
                                                  : VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME);
    }
    else if (mFeatures.supportsRenderPassStoreOpNone.enabled)
    {
        mEnabledDeviceExtensions.push_back(VK_QCOM_RENDER_PASS_STORE_OPS_EXTENSION_NAME);
    }
}

angle::Result Renderer::enableDeviceExtensions(vk::ErrorContext *context,
                                               const angle::FeatureOverrides &featureOverrides,
                                               UseVulkanSwapchain useVulkanSwapchain,
                                               angle::NativeWindowSystem nativeWindowSystem)
{
    // Enumerate device extensions that are provided by the vulkan
    // implementation and implicit layers.
    uint32_t deviceExtensionCount = 0;
    ANGLE_VK_TRY(context, VK_CALL(vkEnumerateDeviceExtensionProperties, mPhysicalDevice, nullptr,
                                  &deviceExtensionCount, nullptr));

    // Work-around a race condition in the Android platform during Android start-up, that can cause
    // the second call to vkEnumerateDeviceExtensionProperties to have an additional extension.  In
    // that case, the second call will return VK_INCOMPLETE.  To work-around that, add 1 to
    // deviceExtensionCount and ask for one more extension property than the first call said there
    // were.  See: http://anglebug.com/42265209 and internal-to-Google bug: b/206733351.
    deviceExtensionCount++;
    std::vector<VkExtensionProperties> deviceExtensionProps(deviceExtensionCount);
    ANGLE_VK_TRY(context, VK_CALL(vkEnumerateDeviceExtensionProperties, mPhysicalDevice, nullptr,
                                  &deviceExtensionCount, deviceExtensionProps.data()));
    // In case fewer items were returned than requested, resize deviceExtensionProps to the number
    // of extensions returned (i.e. deviceExtensionCount).  See: b/208937840
    deviceExtensionProps.resize(deviceExtensionCount);

    // Enumerate device extensions that are provided by explicit layers.
    for (const char *layerName : mEnabledInstanceLayerNames)
    {
        uint32_t previousExtensionCount    = static_cast<uint32_t>(deviceExtensionProps.size());
        uint32_t deviceLayerExtensionCount = 0;
        ANGLE_VK_TRY(context, VK_CALL(vkEnumerateDeviceExtensionProperties, mPhysicalDevice,
                                      layerName, &deviceLayerExtensionCount, nullptr));
        deviceExtensionProps.resize(previousExtensionCount + deviceLayerExtensionCount);
        ANGLE_VK_TRY(context, VK_CALL(vkEnumerateDeviceExtensionProperties, mPhysicalDevice,
                                      layerName, &deviceLayerExtensionCount,
                                      deviceExtensionProps.data() + previousExtensionCount));
        // In case fewer items were returned than requested, resize deviceExtensionProps to the
        // number of extensions returned (i.e. deviceLayerExtensionCount).
        deviceExtensionProps.resize(previousExtensionCount + deviceLayerExtensionCount);
    }

    // Get the list of device extensions that are available.
    vk::ExtensionNameList deviceExtensionNames;
    if (!deviceExtensionProps.empty())
    {
        ASSERT(deviceExtensionNames.size() <= deviceExtensionProps.size());
        for (const VkExtensionProperties &prop : deviceExtensionProps)
        {
            deviceExtensionNames.push_back(prop.extensionName);

            if (strcmp(prop.extensionName, VK_EXT_LEGACY_DITHERING_EXTENSION_NAME) == 0)
            {
                mLegacyDitheringVersion = prop.specVersion;
            }
        }
        std::sort(deviceExtensionNames.begin(), deviceExtensionNames.end(), StrLess);
    }

    if (useVulkanSwapchain == UseVulkanSwapchain::Yes)
    {
        mEnabledDeviceExtensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
    }

    // Query extensions and their features.
    queryDeviceExtensionFeatures(deviceExtensionNames);

    // Initialize features and workarounds.
    initFeatures(deviceExtensionNames, featureOverrides, useVulkanSwapchain, nativeWindowSystem);
    if (mGlobalOps->getFrontendApi() == GlobalOps::Api::OpenCL)
    {
        initOpenCLFeatures(deviceExtensionNames, featureOverrides);
    }

    // Enable extensions that could be used
    enableDeviceExtensionsNotPromoted(deviceExtensionNames);
    enableDeviceExtensionsPromotedTo11(deviceExtensionNames);
    enableDeviceExtensionsPromotedTo12(deviceExtensionNames);
    enableDeviceExtensionsPromotedTo13(deviceExtensionNames);
    enableDeviceExtensionsPromotedTo14(deviceExtensionNames);

    std::sort(mEnabledDeviceExtensions.begin(), mEnabledDeviceExtensions.end(), StrLess);
    ANGLE_VK_TRY(context, VerifyExtensionsPresent(deviceExtensionNames, mEnabledDeviceExtensions));

    return angle::Result::Continue;
}

void Renderer::initDeviceExtensionEntryPoints()
{
#if !defined(ANGLE_SHARED_LIBVULKAN)
    // Device entry points
    if (mFeatures.supportsTransformFeedbackExtension.enabled)
    {
        InitTransformFeedbackEXTFunctions(mDevice);
    }
    if (getFeatures().supportsLogicOpDynamicState.enabled)
    {
        // VK_EXT_extended_dynamic_state2 is only partially core in Vulkan 1.3.  If the logicOp
        // dynamic state (only from the extension) is used, need to load the entry points from the
        // extension
        InitExtendedDynamicState2EXTFunctions(mDevice);
    }
    if (mFeatures.supportsFragmentShadingRate.enabled)
    {
        InitFragmentShadingRateKHRDeviceFunction(mDevice);
    }
    if (mFeatures.supportsTimestampSurfaceAttribute.enabled)
    {
        InitGetPastPresentationTimingGoogleFunction(mDevice);
    }
    if (mFeatures.supportsHostImageCopy.enabled)
    {
        InitHostImageCopyFunctions(mDevice);
    }
    if (mFeatures.supportsImageCompressionControl.enabled)
    {
        InitImageCompressionControlFunctions(mDevice);
    }
    if (mFeatures.supportsVertexInputDynamicState.enabled)
    {
        InitVertexInputDynamicStateEXTFunctions(mDevice);
    }
    if (mFeatures.supportsDynamicRenderingLocalRead.enabled)
    {
        InitDynamicRenderingLocalReadFunctions(mDevice);
    }
    if (mFeatures.supportsExternalSemaphoreFd.enabled ||
        mFeatures.supportsExternalSemaphoreFuchsia.enabled)
    {
        InitExternalSemaphoreFdFunctions(mDevice);
    }

    if (mFeatures.supportsExternalFenceFd.enabled)
    {
        InitExternalFenceFdFunctions(mDevice);
    }

#    if defined(ANGLE_PLATFORM_ANDROID)
    if (mFeatures.supportsAndroidHardwareBuffer.enabled)
    {
        InitExternalMemoryHardwareBufferANDROIDFunctions(mDevice);
    }
#    endif
    if (mFeatures.supportsSynchronization2.enabled)
    {
        InitSynchronization2Functions(mDevice);
    }
    if (mFeatures.supportsDeviceFault.enabled)
    {
        InitDeviceFaultFunctions(mDevice);
    }
    if (mFeatures.supportsMaintenance5.enabled)
    {
        InitMaintenance5Functions(mDevice);
    }
    if (mFeatures.supportsTileMemoryHeap.enabled)
    {
        InitTileMemoryHeapFunctions(mDevice);
    }
    // Extensions promoted to Vulkan 1.2
    {
        if (mFeatures.supportsHostQueryReset.enabled)
        {
            InitHostQueryResetFunctions(mDevice);
        }
        if (mFeatures.supportsRenderpass2.enabled)
        {
            InitRenderPass2KHRFunctions(mDevice);
        }
        if (mFeatures.supportsBufferDeviceAddress.enabled)
        {
            InitBufferDeviceAddressFunctions(mDevice);
        }
    }
    // Extensions promoted to Vulkan 1.3
    {
        if (mFeatures.supportsExtendedDynamicState.enabled)
        {
            InitExtendedDynamicStateEXTFunctions(mDevice);
        }
        if (mFeatures.supportsExtendedDynamicState2.enabled)
        {
            InitExtendedDynamicState2EXTFunctions(mDevice);
        }
        if (mFeatures.supportsDynamicRendering.enabled)
        {
            InitDynamicRenderingFunctions(mDevice);
        }
    }
#endif  // !defined(ANGLE_SHARED_LIBVULKAN)

    // For promoted extensions, initialize their entry points from the core version.
    initializeDeviceExtensionEntryPointsFromCore();
}

angle::Result Renderer::setupDevice(vk::ErrorContext *context,
                                    const angle::FeatureOverrides &featureOverrides,
                                    UseVulkanSwapchain useVulkanSwapchain,
                                    angle::NativeWindowSystem nativeWindowSystem)
{
    uint32_t deviceLayerCount = 0;
    ANGLE_VK_TRY(context, VK_CALL(vkEnumerateDeviceLayerProperties, mPhysicalDevice,
                                  &deviceLayerCount, nullptr));

    std::vector<VkLayerProperties> deviceLayerProps(deviceLayerCount);
    ANGLE_VK_TRY(context, VK_CALL(vkEnumerateDeviceLayerProperties, mPhysicalDevice,
                                  &deviceLayerCount, deviceLayerProps.data()));

    mEnabledFeatures       = {};
    mEnabledFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;

    ANGLE_TRY(
        enableDeviceExtensions(context, featureOverrides, useVulkanSwapchain, nativeWindowSystem));

    // Used to support cubemap array:
    mEnabledFeatures.features.imageCubeArray = mFeatures.supportsImageCubeArray.enabled;
    // Used to support framebuffers with multiple attachments:
    mEnabledFeatures.features.independentBlend = mPhysicalDeviceFeatures.independentBlend;
    // Used to support multi_draw_indirect
    mEnabledFeatures.features.multiDrawIndirect = mPhysicalDeviceFeatures.multiDrawIndirect;
    mEnabledFeatures.features.drawIndirectFirstInstance =
        mPhysicalDeviceFeatures.drawIndirectFirstInstance;
    // Used to support robust buffer access, if VK_EXT_pipeline_robustness is not supported.
    if (!mFeatures.supportsPipelineRobustness.enabled)
    {
        mEnabledFeatures.features.robustBufferAccess = mPhysicalDeviceFeatures.robustBufferAccess;
    }
    // Used to support Anisotropic filtering:
    mEnabledFeatures.features.samplerAnisotropy = mPhysicalDeviceFeatures.samplerAnisotropy;
    // Used to support wide lines:
    mEnabledFeatures.features.wideLines = mPhysicalDeviceFeatures.wideLines;
    // Used to emulate transform feedback:
    mEnabledFeatures.features.vertexPipelineStoresAndAtomics =
        mPhysicalDeviceFeatures.vertexPipelineStoresAndAtomics;
    // Used to implement storage buffers and images in the fragment shader:
    mEnabledFeatures.features.fragmentStoresAndAtomics =
        mPhysicalDeviceFeatures.fragmentStoresAndAtomics;
    // Used to emulate the primitives generated query:
    mEnabledFeatures.features.pipelineStatisticsQuery =
        !mFeatures.supportsPrimitivesGeneratedQuery.enabled &&
        mFeatures.supportsPipelineStatisticsQuery.enabled;
    // Used to support geometry shaders:
    mEnabledFeatures.features.geometryShader = mPhysicalDeviceFeatures.geometryShader;
    // Used to support EXT/OES_gpu_shader5:
    mEnabledFeatures.features.shaderImageGatherExtended =
        mPhysicalDeviceFeatures.shaderImageGatherExtended;
    // Used to support EXT/OES_gpu_shader5:
    mEnabledFeatures.features.shaderUniformBufferArrayDynamicIndexing =
        mPhysicalDeviceFeatures.shaderUniformBufferArrayDynamicIndexing;
    mEnabledFeatures.features.shaderSampledImageArrayDynamicIndexing =
        mPhysicalDeviceFeatures.shaderSampledImageArrayDynamicIndexing;
    // Used to support APPLE_clip_distance
    mEnabledFeatures.features.shaderClipDistance = mPhysicalDeviceFeatures.shaderClipDistance;
    // Used to support OES_sample_shading
    mEnabledFeatures.features.sampleRateShading = mPhysicalDeviceFeatures.sampleRateShading;
    // Used to support EXT_depth_clamp and depth clears through draw calls
    mEnabledFeatures.features.depthClamp = mPhysicalDeviceFeatures.depthClamp;
    // Used to support EXT_polygon_offset_clamp
    mEnabledFeatures.features.depthBiasClamp = mPhysicalDeviceFeatures.depthBiasClamp;
    // Used to support NV_polygon_mode / ANGLE_polygon_mode
    mEnabledFeatures.features.fillModeNonSolid = mPhysicalDeviceFeatures.fillModeNonSolid;
    // Used to support EXT_clip_cull_distance
    mEnabledFeatures.features.shaderCullDistance = mPhysicalDeviceFeatures.shaderCullDistance;
    // Used to support tessellation Shader:
    mEnabledFeatures.features.tessellationShader = mPhysicalDeviceFeatures.tessellationShader;
    // Used to support EXT_blend_func_extended
    mEnabledFeatures.features.dualSrcBlend = mPhysicalDeviceFeatures.dualSrcBlend;
    // Used to support ANGLE_logic_op and GLES1
    mEnabledFeatures.features.logicOp = mPhysicalDeviceFeatures.logicOp;
    // Used to support EXT_multisample_compatibility
    mEnabledFeatures.features.alphaToOne = mPhysicalDeviceFeatures.alphaToOne;
    // Used to support 16bit-integers in shader code
    mEnabledFeatures.features.shaderInt16 = mPhysicalDeviceFeatures.shaderInt16;
    // Used to support 64bit-integers in shader code
    mEnabledFeatures.features.shaderInt64 = mPhysicalDeviceFeatures.shaderInt64;
    // Used to support 64bit-floats in shader code
    mEnabledFeatures.features.shaderFloat64 =
        mFeatures.supportsShaderFloat64.enabled && mPhysicalDeviceFeatures.shaderFloat64 == VK_TRUE;

    if (!vk::OutsideRenderPassCommandBuffer::ExecutesInline() ||
        !vk::RenderPassCommandBuffer::ExecutesInline())
    {
        mEnabledFeatures.features.inheritedQueries = mPhysicalDeviceFeatures.inheritedQueries;
    }

    return angle::Result::Continue;
}

angle::Result Renderer::createDeviceAndQueue(vk::ErrorContext *context,
                                             uint32_t queueFamilyIndex,
                                             VkQueueGlobalPriority globalPriority)
{
    mCurrentQueueFamilyIndex = queueFamilyIndex;

    vk::QueueFamily queueFamily;
    queueFamily.initialize(mQueueFamilyProperties2[queueFamilyIndex].queueFamilyProperties,
                           queueFamilyIndex);
    ANGLE_VK_CHECK(context, queueFamily.getDeviceQueueCount() > 0, VK_ERROR_INITIALIZATION_FAILED);

    // We enable protected context only if both supportsProtectedMemory and device also supports
    // protected. There are cases we have to disable supportsProtectedMemory feature due to driver
    // bugs.
    bool enableProtectedContent =
        queueFamily.supportsProtected() && mFeatures.supportsProtectedMemory.enabled;

    uint32_t queueCount = std::min(queueFamily.getDeviceQueueCount(),
                                   static_cast<uint32_t>(egl::ContextPriority::EnumCount));

    // We use VK_QUEUE_GLOBAL_PRIORITY_REALTIME only if queueCount >=3
    if (globalPriority == VK_QUEUE_GLOBAL_PRIORITY_REALTIME && queueCount < 3)
    {
        globalPriority = VK_QUEUE_GLOBAL_PRIORITY_MEDIUM;
    }

    uint32_t queueCreateInfoCount                                          = 1;
    VkDeviceQueueCreateInfo queueCreateInfo[3]                             = {};
    VkDeviceQueueGlobalPriorityCreateInfo queueGlobalPriorityCreateInfo[3] = {};

    // If global priority is supported, we split queueCreateInfo into three groups so that the
    // middle group uses VK_QUEUE_GLOBAL_PRIORITY_REALTIME.
    if (globalPriority == VK_QUEUE_GLOBAL_PRIORITY_REALTIME)
    {
        ASSERT(mFeatures.supportsGlobalPriority.enabled);
        ASSERT(queueCount >= 3);

        // queueCreateInfo[0] is for Medium and High
        queueCreateInfo[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
        queueCreateInfo[0].flags =
            enableProtectedContent ? VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT : 0;
        queueCreateInfo[0].queueFamilyIndex = queueFamilyIndex;
        queueCreateInfo[0].queueCount       = 2;
        queueCreateInfo[0].pQueuePriorities = &vk::QueueFamily::kQueuePriorities[0];
        queueGlobalPriorityCreateInfo[0].sType =
            VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO;
        queueGlobalPriorityCreateInfo[0].globalPriority = VK_QUEUE_GLOBAL_PRIORITY_MEDIUM;
        vk::AddToPNextChain(&queueCreateInfo[0], &queueGlobalPriorityCreateInfo[0]);

        ASSERT(vk::QueueFamily::kQueuePriorities[2] == QueueFamily::kQueuePriorityRealtime);
        // queueCreateInfo[1] is for Realtime
        queueCreateInfo[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
        queueCreateInfo[1].flags =
            enableProtectedContent ? VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT : 0;
        queueCreateInfo[1].queueFamilyIndex = queueFamilyIndex;
        queueCreateInfo[1].queueCount       = 1;
        queueCreateInfo[1].pQueuePriorities = &vk::QueueFamily::kQueuePriorities[2];
        queueGlobalPriorityCreateInfo[1].sType =
            VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO;
        queueGlobalPriorityCreateInfo[1].globalPriority = VK_QUEUE_GLOBAL_PRIORITY_REALTIME;
        vk::AddToPNextChain(&queueCreateInfo[1], &queueGlobalPriorityCreateInfo[1]);
        queueCreateInfoCount++;

        if (queueCount == 4)
        {
            // queueCreateInfo[2] is for Low
            queueCreateInfo[2].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
            queueCreateInfo[2].flags =
                enableProtectedContent ? VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT : 0;
            queueCreateInfo[2].queueFamilyIndex = queueFamilyIndex;
            queueCreateInfo[2].queueCount       = 1;
            queueCreateInfo[2].pQueuePriorities = &vk::QueueFamily::kQueuePriorities[3];
            queueGlobalPriorityCreateInfo[2].sType =
                VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO;
            queueGlobalPriorityCreateInfo[2].globalPriority = VK_QUEUE_GLOBAL_PRIORITY_MEDIUM;
            vk::AddToPNextChain(&queueCreateInfo[2], &queueGlobalPriorityCreateInfo[2]);
            queueCreateInfoCount++;
        }
    }
    else
    {
        queueCreateInfo[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
        queueCreateInfo[0].flags =
            enableProtectedContent ? VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT : 0;
        queueCreateInfo[0].queueFamilyIndex = queueFamilyIndex;
        queueCreateInfo[0].queueCount       = queueCount;
        queueCreateInfo[0].pQueuePriorities = vk::QueueFamily::kQueuePriorities.data();
    }

    // Setup device initialization struct
    VkDeviceCreateInfo createInfo    = {};
    createInfo.sType                 = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
    createInfo.flags                 = 0;
    createInfo.queueCreateInfoCount  = queueCreateInfoCount;
    createInfo.pQueueCreateInfos     = queueCreateInfo;
    createInfo.enabledExtensionCount = static_cast<uint32_t>(mEnabledDeviceExtensions.size());
    createInfo.ppEnabledExtensionNames =
        mEnabledDeviceExtensions.empty() ? nullptr : mEnabledDeviceExtensions.data();
    mEnabledDeviceExtensions.push_back(nullptr);

    // Enable core features without assuming VkPhysicalDeviceFeatures2KHR is accepted in the
    // pNext chain of VkDeviceCreateInfo.
    createInfo.pEnabledFeatures = &mEnabledFeatures.features;

    // Append the feature structs chain to the end of createInfo structs chain.
    if (mEnabledFeatures.pNext)
    {
        vk::AppendToPNextChain(&createInfo, mEnabledFeatures.pNext);
    }

    if (mFeatures.logMemoryReportCallbacks.enabled || mFeatures.logMemoryReportStats.enabled)
    {
        ASSERT(mMemoryReportFeatures.deviceMemoryReport);

        mMemoryReportCallback       = {};
        mMemoryReportCallback.sType = VK_STRUCTURE_TYPE_DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT;
        mMemoryReportCallback.pfnUserCallback = &MemoryReportCallback;
        mMemoryReportCallback.pUserData       = this;
        vk::AddToPNextChain(&createInfo, &mMemoryReportCallback);
    }

    // Create the list of expected VVL messages to suppress.  Done before creating the device, as it
    // may also generate messages.
    initializeValidationMessageSuppressions();

    ANGLE_VK_TRY(context, VK_CALL(vkCreateDevice, mPhysicalDevice, &createInfo, nullptr, &mDevice));
#if defined(ANGLE_SHARED_LIBVULKAN)
    // Load volk if we are loading dynamically
    VK_CALL(volkLoadDevice, mDevice);
#endif  // defined(ANGLE_SHARED_LIBVULKAN)

    initDeviceExtensionEntryPoints();

    ANGLE_TRY(mCommandQueue.init(context, queueFamily, enableProtectedContent, queueCount));
    ANGLE_TRY(mCleanUpThread.init());

    if (mFeatures.forceMaxUniformBufferSize16KB.enabled)
    {
        mDefaultUniformBufferSize = kMinDefaultUniformBufferSize;
    }
    // Cap it with the driver limit
    mDefaultUniformBufferSize = std::min(
        mDefaultUniformBufferSize, getPhysicalDeviceProperties().limits.maxUniformBufferRange);

    // Vulkan pipeline cache will be initialized lazily in ensurePipelineCacheInitialized() method.
    ASSERT(!mPipelineCacheInitialized);
    ASSERT(!mPipelineCache.valid());

    // Track the set of supported pipeline stages.  This is used when issuing image layout
    // transitions that cover many stages (such as AllGraphicsReadOnly) to mask out unsupported
    // stages, which avoids enumerating every possible combination of stages in the layouts.
    VkPipelineStageFlags unsupportedStages = 0;
    mSupportedVulkanShaderStageMask =
        VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
    mSupportedBufferWritePipelineStageMask =
        VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
        VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;

    if (!mPhysicalDeviceFeatures.tessellationShader)
    {
        unsupportedStages |= VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT |
                             VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT;
    }
    else
    {
        mSupportedVulkanShaderStageMask |=
            VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
        mSupportedBufferWritePipelineStageMask |=
            VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT |
            VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT;
    }
    if (!mPhysicalDeviceFeatures.geometryShader)
    {
        unsupportedStages |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
    }
    else
    {
        mSupportedVulkanShaderStageMask |= VK_SHADER_STAGE_GEOMETRY_BIT;
        mSupportedBufferWritePipelineStageMask |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
    }

    if (getFeatures().supportsTransformFeedbackExtension.enabled)
    {
        mSupportedBufferWritePipelineStageMask |= VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT;
    }

    // Initialize the barrierData tables by removing unsupported pipeline stage bits
    InitializeEventStageToVkPipelineStageFlagsMap(&mEventStageToPipelineStageFlagsMap,
                                                  ~unsupportedStages);
    InitializeImageLayoutAndMemoryBarrierDataMap(
        getFeatures(), &mImageLayoutAndMemoryBarrierDataMap, ~unsupportedStages);

    ANGLE_TRY(initializeMemoryAllocator(context));

    // Log the memory heap stats when the device has been initialized (when debugging).
    mMemoryAllocationTracker.onDeviceInit();

    // Synchronize the Vulkan pipeline cache to the blob cache every frame
    if (mFeatures.syncPipelineCacheToBlobCacheEveryFrame.enabled)
    {
        mPipelineCacheVkUpdateTimeout = 1;
    }

    return angle::Result::Continue;
}

void Renderer::calculatePendingGarbageSizeLimit()
{
    // To find the threshold, we want the memory heap that has the largest size among other heaps.
    VkPhysicalDeviceMemoryProperties memoryProperties;
    VK_CALL(vkGetPhysicalDeviceMemoryProperties, mPhysicalDevice, &memoryProperties);
    ASSERT(memoryProperties.memoryHeapCount > 0);

    VkDeviceSize maxHeapSize = memoryProperties.memoryHeaps[0].size;
    for (size_t i = 0; i < memoryProperties.memoryHeapCount; i++)
    {
        VkDeviceSize heapSize = memoryProperties.memoryHeaps[i].size;
        if (maxHeapSize < heapSize)
        {
            maxHeapSize = heapSize;
        }
    }

    // We set the limit to a portion of the heap size we found.
    constexpr float kGarbageSizeLimitCoefficient = 0.2f;
    mPendingGarbageSizeLimit =
        static_cast<VkDeviceSize>(maxHeapSize * kGarbageSizeLimitCoefficient);
}

void Renderer::initializeValidationMessageSuppressions()
{
    // Build the list of validation errors that are currently expected and should be skipped.
    mSkippedValidationMessages.insert(mSkippedValidationMessages.end(), kSkippedMessages,
                                      kSkippedMessages + ArraySize(kSkippedMessages));
    if (!getFeatures().supportsPrimitiveTopologyListRestart.enabled)
    {
        mSkippedValidationMessages.insert(
            mSkippedValidationMessages.end(), kNoListRestartSkippedMessages,
            kNoListRestartSkippedMessages + ArraySize(kNoListRestartSkippedMessages));
    }

    if (getFeatures().exposeES32ForTesting.enabled)
    {
        mSkippedValidationMessages.insert(
            mSkippedValidationMessages.end(), kExposeNonConformantSkippedMessages,
            kExposeNonConformantSkippedMessages + ArraySize(kExposeNonConformantSkippedMessages));
    }

    if (!getFeatures().supportsMaintenance5.enabled)
    {
        mSkippedValidationMessages.insert(
            mSkippedValidationMessages.end(), kNoMaintenance5SkippedMessages,
            kNoMaintenance5SkippedMessages + ArraySize(kNoMaintenance5SkippedMessages));
    }

    if (!getFeatures().supportsMaintenance9.enabled)
    {
        mSkippedValidationMessages.insert(
            mSkippedValidationMessages.end(), kNoMaintenance9SkippedMessages,
            kNoMaintenance9SkippedMessages + ArraySize(kNoMaintenance9SkippedMessages));
    }

    if (!getFeatures().supportsSwapchainMaintenance1.enabled)
    {
        mSkippedValidationMessages.insert(mSkippedValidationMessages.end(),
                                          kNoSwapchainMaintenance1SkippedMessages,
                                          kNoSwapchainMaintenance1SkippedMessages +
                                              ArraySize(kNoSwapchainMaintenance1SkippedMessages));
    }

    if (getFeatures().preferBGR565ToRGB565.enabled)
    {
        mSkippedValidationMessages.insert(
            mSkippedValidationMessages.end(), kPreferBGR565SkippedMessages,
            kPreferBGR565SkippedMessages + ArraySize(kPreferBGR565SkippedMessages));
    }

    if (!getFeatures().preferDynamicRendering.enabled &&
        !vk::RenderPassCommandBuffer::ExecutesInline())
    {
        mSkippedValidationMessages.insert(
            mSkippedValidationMessages.end(), kSkippedMessagesWithRenderPassObjectsAndVulkanSCB,
            kSkippedMessagesWithRenderPassObjectsAndVulkanSCB +
                ArraySize(kSkippedMessagesWithRenderPassObjectsAndVulkanSCB));
    }

    if (!getFeatures().preferDynamicRendering.enabled &&
        getFeatures().supportsMultisampledRenderToSingleSampled.enabled)
    {
        mSkippedValidationMessages.insert(
            mSkippedValidationMessages.end(), kSkippedMessagesWithMSRTSSWithoutDynamicRendering,
            kSkippedMessagesWithMSRTSSWithoutDynamicRendering +
                ArraySize(kSkippedMessagesWithMSRTSSWithoutDynamicRendering));
    }

    if (getFeatures().preferDynamicRendering.enabled)
    {
        mSkippedValidationMessages.insert(
            mSkippedValidationMessages.end(), kSkippedMessagesWithDynamicRendering,
            kSkippedMessagesWithDynamicRendering + ArraySize(kSkippedMessagesWithDynamicRendering));
    }

    // Build the list of syncval errors that are currently expected and should be skipped.
    mSkippedSyncvalMessages.insert(mSkippedSyncvalMessages.end(), kSkippedSyncvalMessages,
                                   kSkippedSyncvalMessages + ArraySize(kSkippedSyncvalMessages));
    if (!getFeatures().forceSizePointerForBoundVertexBuffers.enabled)
    {
        mSkippedSyncvalMessages.insert(
            mSkippedSyncvalMessages.end(), kSkippedSyncvalMessagesWithoutForcedSizePointer,
            kSkippedSyncvalMessagesWithoutForcedSizePointer +
                ArraySize(kSkippedSyncvalMessagesWithoutForcedSizePointer));
    }
    if (!getFeatures().supportsRenderPassLoadStoreOpNone.enabled)
    {
        mSkippedSyncvalMessages.insert(
            mSkippedSyncvalMessages.end(), kSkippedSyncvalMessagesWithoutLoadStoreOpNone,
            kSkippedSyncvalMessagesWithoutLoadStoreOpNone +
                ArraySize(kSkippedSyncvalMessagesWithoutLoadStoreOpNone));
    }
    if (getFeatures().enableMultisampledRenderToTexture.enabled &&
        !getFeatures().supportsMultisampledRenderToSingleSampled.enabled)
    {
        mSkippedSyncvalMessages.insert(mSkippedSyncvalMessages.end(),
                                       kSkippedSyncvalMessagesWithMSRTTEmulation,
                                       kSkippedSyncvalMessagesWithMSRTTEmulation +
                                           ArraySize(kSkippedSyncvalMessagesWithMSRTTEmulation));
    }
}

angle::Result Renderer::checkQueueForSurfacePresent(vk::ErrorContext *context,
                                                    VkSurfaceKHR surface,
                                                    bool *supportedOut)
{
    // We've already initialized a device, and can't re-create it unless it's never been used.
    // If recreation is ever necessary, it should be able to deal with contexts currently running in
    // other threads using the existing queue.  For example, multiple contexts (not in a share
    // group) may be currently recording commands and rendering to pbuffers or using
    // EGL_KHR_surfaceless_context.
    ASSERT(mDevice != VK_NULL_HANDLE);
    ASSERT(mCurrentQueueFamilyIndex != std::numeric_limits<uint32_t>::max());

    // Check if the current device supports present on this surface.
    VkBool32 supportsPresent = VK_FALSE;
    ANGLE_VK_TRY(context, VK_CALL(vkGetPhysicalDeviceSurfaceSupportKHR, mPhysicalDevice,
                                  mCurrentQueueFamilyIndex, surface, &supportsPresent));

    *supportedOut = supportsPresent == VK_TRUE;
    return angle::Result::Continue;
}

std::string Renderer::getVendorString() const
{
    return GetVendorString(mPhysicalDeviceProperties.vendorID);
}

std::string Renderer::getRendererDescription() const
{
    std::stringstream strstr;

    uint32_t apiVersion = mPhysicalDeviceProperties.apiVersion;

    strstr << "Vulkan ";
    strstr << VK_API_VERSION_MAJOR(apiVersion) << ".";
    strstr << VK_API_VERSION_MINOR(apiVersion) << ".";
    strstr << VK_API_VERSION_PATCH(apiVersion);

    strstr << " (";

    // In the case of NVIDIA, deviceName does not necessarily contain "NVIDIA". Add "NVIDIA" so that
    // Vulkan end2end tests can be selectively disabled on NVIDIA. TODO(jmadill): should not be
    // needed after http://anglebug.com/40096421 is fixed and end2end_tests use more sophisticated
    // driver detection.
    if (mPhysicalDeviceProperties.vendorID == VENDOR_ID_NVIDIA)
    {
        strstr << GetVendorString(mPhysicalDeviceProperties.vendorID) << " ";
    }

    strstr << mPhysicalDeviceProperties.deviceName;
    strstr << " (" << gl::FmtHex(mPhysicalDeviceProperties.deviceID) << ")";

    strstr << ")";

    return strstr.str();
}

std::string Renderer::getVersionString(bool includeFullVersion) const
{
    std::stringstream strstr;

    uint32_t driverVersion = mPhysicalDeviceProperties.driverVersion;
    std::string driverName = std::string(mDriverProperties.driverName);

    if (!driverName.empty())
    {
        strstr << driverName;
    }
    else
    {
        strstr << GetVendorString(mPhysicalDeviceProperties.vendorID);
    }

    if (includeFullVersion)
    {
        strstr << "-";

        if (mPhysicalDeviceProperties.vendorID == VENDOR_ID_NVIDIA)
        {
            strstr << ANGLE_VK_VERSION_MAJOR_NVIDIA(driverVersion) << ".";
            strstr << ANGLE_VK_VERSION_MINOR_NVIDIA(driverVersion) << ".";
            strstr << ANGLE_VK_VERSION_SUB_MINOR_NVIDIA(driverVersion) << ".";
            strstr << ANGLE_VK_VERSION_PATCH_NVIDIA(driverVersion);
        }
        else if (mPhysicalDeviceProperties.vendorID == VENDOR_ID_INTEL && IsWindows())
        {
            strstr << ANGLE_VK_VERSION_MAJOR_WIN_INTEL(driverVersion) << ".";
            strstr << ANGLE_VK_VERSION_MINOR_WIN_INTEL(driverVersion);
        }
        // The major version for the new QCOM drivers seems to be 512, which results in a major
        // version of 0 and a non-zero variant field when using the VK_API_VERSION_x macros.
        // Therefore, the version string is updated to show the correct major version.
        else if (mPhysicalDeviceProperties.vendorID == VENDOR_ID_QUALCOMM &&
                 !IsQualcommOpenSource(mPhysicalDeviceProperties.vendorID,
                                       mDriverProperties.driverID,
                                       mPhysicalDeviceProperties.deviceName))
        {
            strstr << (512 | VK_API_VERSION_MAJOR(driverVersion)) << ".";
            strstr << VK_API_VERSION_MINOR(driverVersion) << ".";
            strstr << VK_API_VERSION_PATCH(driverVersion);
        }
        // All other drivers use the Vulkan standard
        else
        {
            strstr << VK_API_VERSION_MAJOR(driverVersion) << ".";
            strstr << VK_API_VERSION_MINOR(driverVersion) << ".";
            strstr << VK_API_VERSION_PATCH(driverVersion);
        }
    }

    return strstr.str();
}

gl::Version Renderer::getMaxSupportedESVersion() const
{
    // Current highest supported version
    gl::Version maxVersion = gl::Version(3, 2);

    // Early out without downgrading ES version if mock ICD enabled.
    // Mock ICD doesn't expose sufficient capabilities yet.
    // https://github.com/KhronosGroup/Vulkan-Tools/issues/84
    if (isMockICDEnabled())
    {
        return maxVersion;
    }

    ensureCapsInitialized();

    // Limit to ES3.1 if there are any blockers for 3.2.
    if (mFeatures.exposeES32ForTesting.enabled)
    {
        return maxVersion;
    }
    if (!CanSupportGLES32(mNativeExtensions))
    {
        maxVersion = LimitVersionTo(maxVersion, {3, 1});
    }

    // Limit to ES3.0 if there are any blockers for 3.1.

    // ES3.1 requires at least one atomic counter buffer and four storage buffers in compute.
    // Atomic counter buffers are emulated with storage buffers.  For simplicity, we always support
    // either none or IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFERS atomic counter buffers.  So if
    // Vulkan doesn't support at least that many storage buffers in compute, we don't support 3.1.
    const uint32_t kMinimumStorageBuffersForES31 =
        gl::limits::kMinimumComputeStorageBuffers +
        gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS;
    if (mPhysicalDeviceProperties.limits.maxPerStageDescriptorStorageBuffers <
        kMinimumStorageBuffersForES31)
    {
        maxVersion = LimitVersionTo(maxVersion, {3, 0});
    }

    // ES3.1 requires at least a maximum offset of at least 2047.
    // If the Vulkan implementation can't support that, we cannot support 3.1.
    if (mPhysicalDeviceProperties.limits.maxVertexInputAttributeOffset < 2047)
    {
        maxVersion = LimitVersionTo(maxVersion, {3, 0});
    }

    // SSO is in ES3.1 core, so we have to cap to ES3.0 for SSO disablement.
    if (mFeatures.disableSeparateShaderObjects.enabled)
    {
        maxVersion = LimitVersionTo(maxVersion, {3, 0});
    }

    // Limit to ES2.0 if there are any blockers for 3.0.

    // VK_EXT_provoking_vertex is required for flat shading.
    if (!mFeatures.provokingVertex.enabled)
    {
        maxVersion = LimitVersionTo(maxVersion, {2, 0});
    }

    // Multisample textures (ES3.1) and multisample renderbuffers (ES3.0) require the Vulkan driver
    // to support the standard sample locations (in order to pass dEQP tests that check these
    // locations).  If the Vulkan implementation can't support that, we cannot support 3.0/3.1.
    if (mPhysicalDeviceProperties.limits.standardSampleLocations != VK_TRUE)
    {
        maxVersion = LimitVersionTo(maxVersion, {2, 0});
    }

    // If independentBlend is not supported, we can't have a mix of has-alpha and emulated-alpha
    // render targets in a framebuffer.  We also cannot perform masked clears of multiple render
    // targets.
    if (!mPhysicalDeviceFeatures.independentBlend)
    {
        maxVersion = LimitVersionTo(maxVersion, {2, 0});
    }

    // If the Vulkan transform feedback extension is not present, we use an emulation path that
    // requires the vertexPipelineStoresAndAtomics feature. Without the extension or this feature,
    // we can't currently support transform feedback.
    if (!vk::CanSupportTransformFeedbackExtension(mTransformFeedbackFeatures) &&
        !vk::CanSupportTransformFeedbackEmulation(mPhysicalDeviceFeatures))
    {
        maxVersion = LimitVersionTo(maxVersion, {2, 0});
    }

    // Limit to GLES 2.0 if maxPerStageDescriptorUniformBuffers is too low.
    // Table 6.31 MAX_VERTEX_UNIFORM_BLOCKS minimum value = 12
    // Table 6.32 MAX_FRAGMENT_UNIFORM_BLOCKS minimum value = 12
    // NOTE: We reserve some uniform buffers for emulation, so use the NativeCaps which takes this
    // into account, rather than the physical device maxPerStageDescriptorUniformBuffers limits.
    for (gl::ShaderType shaderType : gl::AllShaderTypes())
    {
        if (static_cast<GLuint>(getNativeCaps().maxShaderUniformBlocks[shaderType]) <
            gl::limits::kMinimumShaderUniformBlocks)
        {
            maxVersion = LimitVersionTo(maxVersion, {2, 0});
        }
    }

    // Limit to GLES 2.0 if maxVertexOutputComponents is too low.
    // Table 6.31 MAX VERTEX OUTPUT COMPONENTS minimum value = 64
    // NOTE: We reserve some vertex output components for emulation, so use the NativeCaps which
    // takes this into account, rather than the physical device maxVertexOutputComponents limits.
    if (static_cast<GLuint>(getNativeCaps().maxVertexOutputComponents) <
        gl::limits::kMinimumVertexOutputComponents)
    {
        maxVersion = LimitVersionTo(maxVersion, {2, 0});
    }

    // Verify minimum requirements of ANGLE:
    //
    // - VK_KHR_image_format_list
    //
    if (!mFeatures.supportsImageFormatList.enabled)
    {
        WARN() << "Vulkan device does not meet ANGLE's minimum requirements";
        WARN() << "  Missing VK_KHR_image_format_list";
        maxVersion = LimitVersionTo(maxVersion, {0, 0});
    }

    return maxVersion;
}

gl::Version Renderer::getMaxConformantESVersion() const
{
    return getMaxSupportedESVersion();
}

uint32_t Renderer::getDeviceVersion() const
{
    return mDeviceVersion == 0 ? mInstanceVersion : mDeviceVersion;
}

void Renderer::queryAndCacheFragmentShadingRates()
{
    // Init required functions
#if !defined(ANGLE_SHARED_LIBVULKAN)
    InitFragmentShadingRateKHRInstanceFunction(mInstance);
#endif  // !defined(ANGLE_SHARED_LIBVULKAN)
    ASSERT(vkGetPhysicalDeviceFragmentShadingRatesKHR);

    // Query number of supported shading rates first
    uint32_t shadingRatesCount = 0;
    VkResult result = VK_CALL(vkGetPhysicalDeviceFragmentShadingRatesKHR, mPhysicalDevice,
                              &shadingRatesCount, nullptr);
    ASSERT(result == VK_SUCCESS);
    ASSERT(shadingRatesCount > 0);

    std::vector<VkPhysicalDeviceFragmentShadingRateKHR> shadingRates(
        shadingRatesCount,
        {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR, nullptr, 0, {0, 0}});

    // Query supported shading rates
    result = VK_CALL(vkGetPhysicalDeviceFragmentShadingRatesKHR, mPhysicalDevice,
                     &shadingRatesCount, shadingRates.data());
    ASSERT(result == VK_SUCCESS);

    // Cache supported fragment shading rates
    mSupportedFragmentShadingRatesEXT.reset();
    mSupportedFragmentShadingRateEXTSampleCounts.fill(0u);
    for (const VkPhysicalDeviceFragmentShadingRateKHR &shadingRate : shadingRates)
    {
        if (shadingRate.sampleCounts == 0)
        {
            continue;
        }
        const gl::ShadingRate rate = GetShadingRateEXTFromVkExtent(shadingRate.fragmentSize);
        mSupportedFragmentShadingRatesEXT.set(rate);
        mSupportedFragmentShadingRateEXTSampleCounts[rate] =
            static_cast<uint16_t>(shadingRate.sampleCounts);
    }
}

bool Renderer::canSupportFragmentShadingRate() const
{
    // VK_KHR_create_renderpass2 is required for VK_KHR_fragment_shading_rate
    if (!mFeatures.supportsRenderpass2.enabled)
    {
        return false;
    }

    // Device needs to support VK_KHR_fragment_shading_rate and specifically
    // pipeline fragment shading rate.
    if (mFragmentShadingRateFeatures.pipelineFragmentShadingRate != VK_TRUE)
    {
        return false;
    }

    ASSERT(mSupportedFragmentShadingRatesEXT.any());

    // To implement GL_EXT_fragment_shading_rate and GL_QCOM_shading_rate extension
    // the Vulkan ICD needs to support at least the following shading rates
    // VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT    {1, 1}
    // VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT    {1, 2}
    // VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT    {2, 1}
    // VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT    {2, 2}
    constexpr VkSampleCountFlags krequiredSampleCounts =
        VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT;

    return (mSupportedFragmentShadingRateEXTSampleCounts[gl::ShadingRate::_1x1] &
            krequiredSampleCounts) == krequiredSampleCounts &&
           (mSupportedFragmentShadingRateEXTSampleCounts[gl::ShadingRate::_1x2] &
            krequiredSampleCounts) == krequiredSampleCounts &&
           (mSupportedFragmentShadingRateEXTSampleCounts[gl::ShadingRate::_2x1] &
            krequiredSampleCounts) == krequiredSampleCounts &&
           (mSupportedFragmentShadingRateEXTSampleCounts[gl::ShadingRate::_2x2] &
            krequiredSampleCounts) == krequiredSampleCounts;
}

bool Renderer::canSupportFoveatedRendering() const
{
    // Device needs to support attachment fragment shading rate.
    if (mFragmentShadingRateFeatures.attachmentFragmentShadingRate != VK_TRUE)
    {
        return false;
    }

    ASSERT(mSupportedFragmentShadingRatesEXT.any());
    ASSERT(!mSupportedFragmentShadingRateEXTSampleCounts.empty());

    // To implement QCOM foveated rendering extensions the Vulkan ICD needs to support all sample
    // count bits listed in VkPhysicalDeviceLimits::framebufferColorSampleCounts for these shading
    // rates -
    //     {1, 1}
    //     {1, 2}
    //     {2, 1}
    //     {2, 2}
    VkSampleCountFlags framebufferSampleCounts =
        getPhysicalDeviceProperties().limits.framebufferColorSampleCounts &
        vk_gl::kSupportedSampleCounts;

    return (mSupportedFragmentShadingRateEXTSampleCounts[gl::ShadingRate::_1x1] &
            framebufferSampleCounts) == framebufferSampleCounts &&
           (mSupportedFragmentShadingRateEXTSampleCounts[gl::ShadingRate::_1x2] &
            framebufferSampleCounts) == framebufferSampleCounts &&
           (mSupportedFragmentShadingRateEXTSampleCounts[gl::ShadingRate::_2x1] &
            framebufferSampleCounts) == framebufferSampleCounts &&
           (mSupportedFragmentShadingRateEXTSampleCounts[gl::ShadingRate::_2x2] &
            framebufferSampleCounts) == framebufferSampleCounts;
}

bool CanSupportAstcHdr3D(const Renderer *renderer)
{
    // New formats added in VK_EXT_texture_compression_astc_hdr
    std::vector<VkFormat> astcHdrFormats = {
        VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT, VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT,
        VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT,  VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT,
        VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT, VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT,
        VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT,   VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT,
        VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT,   VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT,
        VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT,   VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT,
        VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT,   VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT};

    for (VkFormat format : astcHdrFormats)
    {
        // If any ASTC HDR format does not support 3D, return false
        if (false == vk::ImageHelper::FormatSupportsUsage(
                         renderer, format, VK_IMAGE_TYPE_3D, VK_IMAGE_TILING_OPTIMAL,
                         VK_IMAGE_USAGE_SAMPLED_BIT, 0, nullptr, nullptr,
                         vk::ImageHelper::FormatSupportCheck::OnlyQuerySuccess))
        {
            return false;
        }
    }

    return true;
}

bool Renderer::supportsAstcHdr() const
{
    // When determining whether we support this, have to check for both the Vulkan
    // feaure and explicity check for 3D texture types.  The latter could be emulated
    // in the future. (http://anglebug.com/416095435)
    return getFeatures().supportsTextureCompressionAstcHdr.enabled &&
           getFeatures().supportsAstcHdr3dTextures.enabled;
}

bool Renderer::canPreferDeviceLocalMemoryHostVisible(VkPhysicalDeviceType deviceType)
{
    if (deviceType == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU)
    {
        const vk::MemoryProperties &memoryProperties = getMemoryProperties();
        static constexpr VkMemoryPropertyFlags kHostVisiableDeviceLocalFlags =
            VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
        VkDeviceSize minHostVisiableDeviceLocalHeapSize = std::numeric_limits<VkDeviceSize>::max();
        VkDeviceSize maxDeviceLocalHeapSize             = 0;
        for (uint32_t i = 0; i < memoryProperties.getMemoryTypeCount(); ++i)
        {
            if ((memoryProperties.getMemoryType(i).propertyFlags &
                 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0)
            {
                maxDeviceLocalHeapSize =
                    std::max(maxDeviceLocalHeapSize, memoryProperties.getHeapSizeForMemoryType(i));
            }
            if ((memoryProperties.getMemoryType(i).propertyFlags & kHostVisiableDeviceLocalFlags) ==
                kHostVisiableDeviceLocalFlags)
            {
                minHostVisiableDeviceLocalHeapSize =
                    std::min(minHostVisiableDeviceLocalHeapSize,
                             memoryProperties.getHeapSizeForMemoryType(i));
            }
        }
        return minHostVisiableDeviceLocalHeapSize != std::numeric_limits<VkDeviceSize>::max() &&
               minHostVisiableDeviceLocalHeapSize >=
                   static_cast<VkDeviceSize>(maxDeviceLocalHeapSize * 0.8);
    }
    return deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
}

void Renderer::initFeatures(const vk::ExtensionNameList &deviceExtensionNames,
                            const angle::FeatureOverrides &featureOverrides,
                            UseVulkanSwapchain useVulkanSwapchain,
                            angle::NativeWindowSystem nativeWindowSystem)
{
    // App based feature overrides.
    appBasedFeatureOverrides(deviceExtensionNames);

    ApplyFeatureOverrides(&mFeatures, featureOverrides);

    if (featureOverrides.allDisabled)
    {
        return;
    }

    const bool isAMD      = IsAMD(mPhysicalDeviceProperties.vendorID);
    const bool isApple    = IsAppleGPU(mPhysicalDeviceProperties.vendorID);
    const bool isARM      = IsARM(mPhysicalDeviceProperties.vendorID);
    const bool isIntel    = IsIntel(mPhysicalDeviceProperties.vendorID);
    const bool isNvidia   = IsNvidia(mPhysicalDeviceProperties.vendorID);
    const bool isPowerVR  = IsPowerVR(mPhysicalDeviceProperties.vendorID);
    const bool isQualcomm = IsQualcomm(mPhysicalDeviceProperties.vendorID);
    const bool isBroadcom = IsBroadcom(mPhysicalDeviceProperties.vendorID);
    const bool isSamsung  = IsSamsung(mPhysicalDeviceProperties.vendorID);
    const bool isSwiftShader =
        IsSwiftshader(mPhysicalDeviceProperties.vendorID, mPhysicalDeviceProperties.deviceID);
    const bool isLavapipe =
        IsLavapipe(mPhysicalDeviceProperties.vendorID, mPhysicalDeviceProperties.deviceID);
    const bool isSoftwareRenderer = isSwiftShader || isLavapipe;

    const bool isGalaxyS23 =
        IsGalaxyS23(mPhysicalDeviceProperties.vendorID, mPhysicalDeviceProperties.deviceID);

    // Distinguish between the open source and proprietary Qualcomm drivers
    const bool isQualcommOpenSource =
        IsQualcommOpenSource(mPhysicalDeviceProperties.vendorID, mDriverProperties.driverID,
                             mPhysicalDeviceProperties.deviceName);
    const bool isQualcommProprietary = isQualcomm && !isQualcommOpenSource;

    // Distinguish between the ARM proprietary driver and the Mesa open source driver
    const bool isMesaPanVK      = IsMesaPanVK(mDriverProperties.driverID);
    const bool isARMProprietary = isARM && !isMesaPanVK;

    // Lacking other explicit ways to tell if mali GPU is job manager based or command stream front
    // end based, we use maxDrawIndirectCount as equivalent since all JM based has
    // maxDrawIndirectCount==1 and all CSF based has maxDrawIndirectCount>1.
    bool isMaliJobManagerBasedGPU =
        isARM && getPhysicalDeviceProperties().limits.maxDrawIndirectCount <= 1;

    // Distinguish between the mesa and proprietary drivers
    const bool isRADV = IsRADV(mPhysicalDeviceProperties.vendorID, mDriverProperties.driverID,
                               mPhysicalDeviceProperties.deviceName);

    angle::VersionInfo driverVersion = {};
    if (isARMProprietary)
    {
        driverVersion = angle::ParseArmVulkanDriverVersion(mPhysicalDeviceProperties.driverVersion);
    }
    else if (isQualcommProprietary)
    {
        driverVersion =
            angle::ParseQualcommVulkanDriverVersion(mPhysicalDeviceProperties.driverVersion);
    }
    else if (isNvidia)
    {
        driverVersion =
            angle::ParseNvidiaVulkanDriverVersion(mPhysicalDeviceProperties.driverVersion);
    }
    else if (IsLinux() && (isIntel || isRADV))
    {
        driverVersion =
            angle::ParseMesaVulkanDriverVersion(mPhysicalDeviceProperties.driverVersion);
    }
    else if (IsWindows() && isIntel)
    {
        driverVersion =
            angle::ParseIntelWindowsVulkanDriverVersion(mPhysicalDeviceProperties.driverVersion);
    }
    else if (isAMD && !isRADV)
    {
        driverVersion = angle::ParseAMDVulkanDriverVersion(mPhysicalDeviceProperties.driverVersion);
    }
    else if (isSamsung)
    {
        driverVersion =
            angle::ParseSamsungVulkanDriverVersion(mPhysicalDeviceProperties.driverVersion);
    }

    INFO() << "driverVersion: " << driverVersion.major << "." << driverVersion.minor << "."
           << driverVersion.subMinor << "." << driverVersion.patch;

    // Classify devices based on general architecture:
    //
    // - IMR (Immediate-Mode Rendering) devices generally progress through draw calls once and use
    //   the main GPU memory (accessed through caches) to store intermediate rendering results.
    // - TBR (Tile-Based Rendering) devices issue a pre-rendering geometry pass, then run through
    //   draw calls once per tile and store intermediate rendering results on the tile cache.
    //
    // Due to these key architectural differences, some operations improve performance on one while
    // deteriorating performance on the other.  ANGLE will accordingly make some decisions based on
    // the device architecture for optimal performance on both.
    const bool isImmediateModeRenderer =
        isNvidia || isAMD || isIntel || isSamsung || isSoftwareRenderer;
    const bool isTileBasedRenderer = isARM || isPowerVR || isQualcomm || isBroadcom || isApple;

    // Make sure all known architectures are accounted for.
    if (!isImmediateModeRenderer && !isTileBasedRenderer && !isMockICDEnabled())
    {
        WARN() << "Unknown GPU architecture";
    }

    ANGLE_FEATURE_CONDITION(&mFeatures, appendAliasedMemoryDecorations, true);

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsSharedPresentableImageExtension,
        ExtensionFound(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, deviceExtensionNames));

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsGetMemoryRequirements2, true);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsBindMemory2, true);

    ANGLE_FEATURE_CONDITION(&mFeatures, bresenhamLineRasterization,
                            mLineRasterizationFeatures.bresenhamLines == VK_TRUE);

    ANGLE_FEATURE_CONDITION(&mFeatures, provokingVertex,
                            mProvokingVertexFeatures.provokingVertexLast == VK_TRUE);

    // http://b/208458772. ARM proprietary driver supports this protected memory extension but we
    // are seeing excessive load/store unit activity when this extension is enabled, even if not
    // been used. Disable this extension on older ARM platforms that don't support
    // VK_EXT_pipeline_protected_access.
    // http://anglebug.com/42266183
    //
    // http://b/381285096. On Intel platforms, we want to prevent protected
    // queues being used as we cannot handle the teardown scenario if PXP termination occurs.
    // http://b/512497379. We cannot handle teardown in Android on Intel either so it is left
    // disabled there to avoid app compat issues until TODO: http://b/540469298
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsProtectedMemory,
        mProtectedMemoryFeatures.protectedMemory == VK_TRUE &&
            (!isARMProprietary ||
             mPipelineProtectedAccessFeatures.pipelineProtectedAccess == VK_TRUE) &&
            !isIntel);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsHostQueryReset,
                            mHostQueryResetFeatures.hostQueryReset == VK_TRUE);
    // Avoid any inefficiency that may be caused by host image copy by default.  To be experimented
    // with to see on which hardware VkHostImageCopyDevicePerformanceQueryEXT::optimalDeviceAccess
    // is really performing as well as
    // VkHostImageCopyDevicePerformanceQueryEXT::identicalMemoryLayout.
    ANGLE_FEATURE_CONDITION(&mFeatures, allowHostImageCopyDespiteNonIdenticalLayout, false);

    // Force host image copy for textures with luminance/alpha formats.  This disables framebuffer
    // compression (but these formats are not renderable), and the benefits of host image copy
    // outweigh framebuffer compression on sampled textures on the following GPUs:
    //
    // - ARM
    ANGLE_FEATURE_CONDITION(&mFeatures, forceHostImageCopyForLuma, isARM);

    // VK_EXT_pipeline_creation_feedback is promoted to core in Vulkan 1.3.
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsPipelineCreationFeedback,
        ExtensionFound(VK_EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME, deviceExtensionNames));

    // Note: Protected Swapchains is not determined until we have a VkSurface to query.
    // So here vendors should indicate support so that protected_content extension
    // is enabled.
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsSurfaceProtectedSwapchains, IsAndroid());

    // Work around incorrect NVIDIA point size range clamping.
    // http://anglebug.com/40644663#comment11
    // Clamp if driver version is:
    //   < 430 on Windows
    //   < 421 otherwise
    ANGLE_FEATURE_CONDITION(
        &mFeatures, clampPointSize,
        isNvidia && driverVersion < angle::VersionTriple(IsWindows() ? 430 : 421, 0, 0));

    // Affecting Nvidia drivers 535 through 551.
    ANGLE_FEATURE_CONDITION(&mFeatures, avoidOpSelectWithMismatchingRelaxedPrecision,
                            isNvidia && (driverVersion >= angle::VersionTriple(535, 0, 0) &&
                                         driverVersion < angle::VersionTriple(552, 0, 0)));

    // Affecting Linux/Intel (unknown range).
    ANGLE_FEATURE_CONDITION(&mFeatures, wrapSwitchInIfTrue, isIntel && IsLinux());

    // Vulkan implementations are not required to clamp gl_FragDepth to [0, 1] by default.
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsDepthClampZeroOne,
                            mDepthClampZeroOneFeatures.depthClampZeroOne == VK_TRUE);

    ANGLE_FEATURE_CONDITION(&mFeatures, clampFragDepth,
                            isNvidia && !mFeatures.supportsDepthClampZeroOne.enabled);

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsRenderpass2,
        ExtensionFound(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME, deviceExtensionNames));

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsIncrementalPresent,
        ExtensionFound(VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME, deviceExtensionNames));

#if defined(ANGLE_PLATFORM_ANDROID)
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsAndroidHardwareBuffer,
        IsAndroid() &&
            ExtensionFound(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME,
                           deviceExtensionNames) &&
            ExtensionFound(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME, deviceExtensionNames));
#endif

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsExternalMemoryFd,
        ExtensionFound(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, deviceExtensionNames));

#if defined(ANGLE_PLATFORM_WINDOWS)
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsFullScreenExclusive,
        ExtensionFound(VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME, deviceExtensionNames));

    // On Windows+AMD, drivers before version 0x800106 (2.0.262) would
    // implicitly enable VK_EXT_full_screen_exclusive and start returning
    // extension-specific error codes in swapchain functions. Since the
    // extension was not enabled by ANGLE, it was impossible to handle these
    // error codes correctly. On these earlier drivers, we want to explicitly
    // enable the extension and opt out of it to avoid seeing those error codes
    // entirely.
    ANGLE_FEATURE_CONDITION(&mFeatures, forceDisableFullScreenExclusive,
                            isAMD && driverVersion < angle::VersionTriple(2, 0, 262));
#endif

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsExternalMemoryFuchsia,
        ExtensionFound(VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME, deviceExtensionNames));

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsExternalSemaphoreFd,
        ExtensionFound(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, deviceExtensionNames));

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsExternalSemaphoreFuchsia,
        ExtensionFound(VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME, deviceExtensionNames));

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsExternalFenceFd,
        ExtensionFound(VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME, deviceExtensionNames));

#if defined(ANGLE_PLATFORM_ANDROID) || defined(ANGLE_PLATFORM_LINUX)
    if (mFeatures.supportsExternalFenceCapabilities.enabled &&
        mFeatures.supportsExternalSemaphoreCapabilities.enabled)
    {
        VkExternalFenceProperties externalFenceProperties = {};
        externalFenceProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES;

        VkPhysicalDeviceExternalFenceInfo externalFenceInfo = {};
        externalFenceInfo.sType      = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO;
        externalFenceInfo.handleType = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR;

        VK_CALL(vkGetPhysicalDeviceExternalFenceProperties, mPhysicalDevice, &externalFenceInfo,
                &externalFenceProperties);

        VkExternalSemaphoreProperties externalSemaphoreProperties = {};
        externalSemaphoreProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES;

        VkPhysicalDeviceExternalSemaphoreInfo externalSemaphoreInfo = {};
        externalSemaphoreInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO;
        externalSemaphoreInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR;

        VK_CALL(vkGetPhysicalDeviceExternalSemaphoreProperties, mPhysicalDevice,
                &externalSemaphoreInfo, &externalSemaphoreProperties);

        // There's a spec gap in eglDupNativeFenceFDANDROID and Vulkan SYNC_FD
        // fence/semaphore export, where the former treats -1 as an error while
        // the latter considers -1 as a valid return for signaled payload. ANGLE
        // relies on the implementation defined behavior that most hw Vulkan
        // drivers would return a valid sync file there, which isn't possible
        // for Lavapipe sw implementation especially since sw sync has been an
        // obsolete option both on Android and upstream Linux. So workaround to
        // disable EGL_ANDROID_native_fence_sync for Lavapipe.
        ANGLE_FEATURE_CONDITION(
            &mFeatures, supportsAndroidNativeFenceSync,
            (mFeatures.supportsExternalFenceFd.enabled &&
             FencePropertiesCompatibleWithAndroid(externalFenceProperties) &&
             mFeatures.supportsExternalSemaphoreFd.enabled &&
             SemaphorePropertiesCompatibleWithAndroid(externalSemaphoreProperties) && !isLavapipe));
    }
    else
    {
        ANGLE_FEATURE_CONDITION(&mFeatures, supportsAndroidNativeFenceSync,
                                (mFeatures.supportsExternalFenceFd.enabled &&
                                 mFeatures.supportsExternalSemaphoreFd.enabled));
    }
#endif  // defined(ANGLE_PLATFORM_ANDROID) || defined(ANGLE_PLATFORM_LINUX)

    // Disabled on SwiftShader due to http://crbug.com/40942995
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsShaderStencilExport,
        ExtensionFound(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, deviceExtensionNames) &&
            !isSwiftShader);

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsRenderPassLoadStoreOpNone,
        ExtensionFound(VK_KHR_LOAD_STORE_OP_NONE_EXTENSION_NAME, deviceExtensionNames) ||
            ExtensionFound(VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME, deviceExtensionNames));

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsRenderPassStoreOpNone,
        !mFeatures.supportsRenderPassLoadStoreOpNone.enabled &&
            ExtensionFound(VK_QCOM_RENDER_PASS_STORE_OPS_EXTENSION_NAME, deviceExtensionNames));

    ANGLE_FEATURE_CONDITION(&mFeatures, disallowMixedDepthStencilLoadOpNoneAndLoad,
                            isARMProprietary && driverVersion < angle::VersionTriple(38, 1, 0));

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsDepthClipControl,
                            mDepthClipControlFeatures.depthClipControl == VK_TRUE);

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsPrimitiveTopologyListRestart,
        mPrimitiveTopologyListRestartFeatures.primitiveTopologyListRestart == VK_TRUE);

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsBlendOperationAdvanced,
        ExtensionFound(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, deviceExtensionNames));

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsFormatFeatureFlags2,
        ExtensionFound(VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME, deviceExtensionNames));

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsTransformFeedbackExtension,
                            vk::CanSupportTransformFeedbackExtension(mTransformFeedbackFeatures));

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsGeometryStreamsCapability,
                            mFeatures.supportsTransformFeedbackExtension.enabled &&
                                mTransformFeedbackFeatures.geometryStreams == VK_TRUE);

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsPrimitivesGeneratedQuery,
        mFeatures.supportsTransformFeedbackExtension.enabled &&
            mPrimitivesGeneratedQueryFeatures.primitivesGeneratedQuery == VK_TRUE);

    ANGLE_FEATURE_CONDITION(&mFeatures, emulateTransformFeedback,
                            !mFeatures.supportsTransformFeedbackExtension.enabled &&
                                vk::CanSupportTransformFeedbackEmulation(mPhysicalDeviceFeatures));

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsIndexTypeUint8,
                            mIndexTypeUint8Features.indexTypeUint8 == VK_TRUE);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsDepthStencilResolve,
                            mFeatures.supportsRenderpass2.enabled &&
                                mDepthStencilResolveProperties.supportedDepthResolveModes != 0);
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsDepthStencilIndependentResolveNone,
                            mFeatures.supportsDepthStencilResolve.enabled &&
                                mDepthStencilResolveProperties.independentResolveNone);
    // Disable optimizing depth/stencil resolve through glBlitFramebuffer for buggy drivers:
    //
    // - Nvidia: http://anglebug.com/42267095
    // - Pixel4: http://anglebug.com/42267096
    //
    ANGLE_FEATURE_CONDITION(&mFeatures, disableDepthStencilResolveThroughAttachment,
                            isNvidia || isQualcommProprietary);

    // MSRTSS is disabled if the driver does not support it for RGBA8 and RGBA8_SRGB.
    // This is used to filter out known drivers where support for sRGB formats are missing.
    //
    // Qualcomm driver 512.821 is known to have rendering bugs with this extension.
    // http://crbug.com/413427770
    //
    // Lavapipe currently crashes in SysUI on Android 16 when ANGLE uses MSRTSS.
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsMultisampledRenderToSingleSampled,
        mMultisampledRenderToSingleSampledFeatures.multisampledRenderToSingleSampled == VK_TRUE &&
            mFeatures.supportsRenderpass2.enabled &&
            mFeatures.supportsDepthStencilResolve.enabled && CanSupportMSRTSSForRGBA8(this) &&
            !(isQualcommProprietary && driverVersion < angle::VersionTriple(512, 822, 0)) &&
            !isLavapipe);

    // Preferring the MSRTSS flag is for texture initialization. If the MSRTSS is not used at first,
    // it will be used (if available) when recreating the image if it is bound to an MSRTT
    // framebuffer.
    ANGLE_FEATURE_CONDITION(
        &mFeatures, preferMSRTSSFlagByDefault,
        mFeatures.supportsMultisampledRenderToSingleSampled.enabled && !isMesaPanVK &&
            (isARMProprietary ||
             isQualcommProprietary && driverVersion >= angle::VersionTriple(512, 777, 0)));

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsImage2dViewOf3d,
                            mImage2dViewOf3dFeatures.image2DViewOf3D == VK_TRUE);

    // Note: sampler2DViewOf3D is only useful for supporting EGL_KHR_gl_texture_3D_image.  If the
    // VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT added to 3D images measurable hurts sampling
    // performance, it might be better to remove support for EGL_KHR_gl_texture_3D_image in favor of
    // faster 3D images.
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsSampler2dViewOf3d,
                            mFeatures.supportsImage2dViewOf3d.enabled &&
                                mImage2dViewOf3dFeatures.sampler2DViewOf3D == VK_TRUE);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsMultiview, mMultiviewFeatures.multiview == VK_TRUE);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsMultiviewMultisampleRenderToTexture,
                            mFeatures.supportsMultisampledRenderToSingleSampled.enabled &&
                                mFeatures.supportsMultiview.enabled);

    // VK_EXT_device_fault can provide more information when the device is lost.
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsDeviceFault,
        ExtensionFound(VK_EXT_DEVICE_FAULT_EXTENSION_NAME, deviceExtensionNames) &&
            mFaultFeatures.deviceFault == VK_TRUE);

    // TODO: http://anglebug.com/42264464 - drop dependency on customBorderColorWithoutFormat.
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsCustomBorderColor,
        mCustomBorderColorFeatures.customBorderColors == VK_TRUE &&
            mCustomBorderColorFeatures.customBorderColorWithoutFormat == VK_TRUE);

    // If format is undefined, the borderColor is VK_BORDER_COLOR_INT_CUSTOM_EXT, and the sampler is
    // used with an image with a stencil format, then the implementation must source the custom
    // border color from either the first or second components of the borderColor, although it is
    // recommended to source it from the first component.
    ANGLE_FEATURE_CONDITION(&mFeatures, usesSecondComponentForStencilBorderColor,
                            mFeatures.supportsCustomBorderColor.enabled && isQualcommProprietary);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsMultiDrawIndirect,
                            mPhysicalDeviceFeatures.multiDrawIndirect == VK_TRUE);

    // The |WindowSurfaceVk::getWindowVisibility| method must be implemented.
    // When enabled, surface will be resized only if window is visible.
    // Notes:
    // - Enable for NVIDIA on Linux X11 because of the possible driver bug, when acquire next image
    //   continuously returns OUT_OF_DATE if recreate the swapchain while window is not visible
    //   (http://anglebug.com/397848903).
    ANGLE_FEATURE_CONDITION(&mFeatures, avoidInvisibleWindowSwapchainRecreate,
                            (isNvidia && nativeWindowSystem == angle::NativeWindowSystem::X11));

    ANGLE_FEATURE_CONDITION(&mFeatures, padBuffersToMaxVertexAttribStride, isAMD || isSamsung);
    mMaxVertexAttribStride =
        mFeatures.padBuffersToMaxVertexAttribStride.enabled
            ? std::min(static_cast<uint32_t>(gl::limits::kMaxVertexAttribStride),
                       mPhysicalDeviceProperties.limits.maxVertexInputBindingStride)
            : 0;

    // Although the maximum memory allocation size for a single object can be derived from the
    // Vulkan driver, it could still be too large for common use (e.g., ~4GB on some platforms) and
    // increase the risk of overflow if the object dimensions used for size calculations are 32-bit.
    // The limit can be restricted to a specific fixed value to reduce this risk.
    mMaxMemoryAllocationSize =
        std::min(mMaintenance3Properties.maxMemoryAllocationSize, kMemoryAllocationSizeLimit);

    // The limits related to buffer size should also take the max memory allocation size and padding
    // (if applicable) into account.
    mMaxBufferMemorySizeLimit = mMaxMemoryAllocationSize - mMaxVertexAttribStride;

    ANGLE_FEATURE_CONDITION(&mFeatures, forceD16TexFilter, IsAndroid() && isQualcommProprietary);

    // Allocation sanitization disabled by default because of a heavyweight implementation
    // that can cause OOM and timeouts.
    ANGLE_FEATURE_CONDITION(&mFeatures, allocateNonZeroMemory, false);

    // ARM proprietary driver does buffer copy on geometry pipeline, which may create a GPU pipeline
    // bubble that prevents vertex shader to overlap with fragment shader on job manager based
    // architecture. For now we always choose CPU to do copy on ARM job manager based GPU.
    // http://issuetracker.google.com/200067929 - ARM
    // http://issuetracker.google.com/477725737 - Qualcomm
    // http://issuetracker.google.com/485970552 - PowerVR
    ANGLE_FEATURE_CONDITION(&mFeatures, preferCPUForBufferSubData,
                            isARMProprietary || isQualcommProprietary || isPowerVR);

    // Prefer GPU for glCopyBufferSubData dirty region buffer update on ARM devices.
    ANGLE_FEATURE_CONDITION(&mFeatures, preferGPUForCopyBufferSubData, isARMProprietary);

    // On android, we usually are GPU limited, we try to use CPU to do data copy when other
    // conditions are the same. Set to zero will use GPU to do copy. This is subject to further
    // tuning for each platform https://issuetracker.google.com/201826021
    mMaxCopyBytesUsingCPUWhenPreservingBufferData =
        IsAndroid() ? std::numeric_limits<uint32_t>::max() : 0;

    ANGLE_FEATURE_CONDITION(&mFeatures, persistentlyMappedBuffers, true);

    ANGLE_FEATURE_CONDITION(&mFeatures, logMemoryReportCallbacks, false);
    ANGLE_FEATURE_CONDITION(&mFeatures, logMemoryReportStats, false);

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsExternalMemoryDmaBuf,
        ExtensionFound(VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME, deviceExtensionNames));

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsImageDrmFormatModifier,
        ExtensionFound(VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME, deviceExtensionNames));

    ANGLE_FEATURE_CONDITION(&mFeatures, enablePrecisionQualifiers, true);

    // http://anglebug.com/42265957
    ANGLE_FEATURE_CONDITION(&mFeatures, varyingsRequireMatchingPrecisionInSpirv,
                            isPowerVR || isSamsung);

    // IMR devices are less sensitive to the src/dst stage masks in barriers, and behave more
    // efficiently when all barriers are aggregated, rather than individually and precisely
    // specified.
    ANGLE_FEATURE_CONDITION(&mFeatures, preferAggregateBarrierCalls, isImmediateModeRenderer);

    // For IMR devices, it's more efficient to ignore invalidate of framebuffer attachments with
    // emulated formats that have extra channels.  For TBR devices, the invalidate will be followed
    // by a clear to retain valid values in said extra channels.
    ANGLE_FEATURE_CONDITION(&mFeatures, preferSkippingInvalidateForEmulatedFormats,
                            isImmediateModeRenderer);

    ANGLE_FEATURE_CONDITION(&mFeatures, asyncGarbageCleanup, true);
    // reset sometimes gets blocked by mutex lock inside vulkan driver and runs in small core while
    // main thread gets blocked by command pool lock. FOr now dont call reset in garbage clean up
    // thread on ARM proprietary driver.
    ANGLE_FEATURE_CONDITION(&mFeatures, asyncCommandBufferReset,
                            mFeatures.asyncGarbageCleanup.enabled && !isARMProprietary);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsYUVSamplerConversion,
                            mSamplerYcbcrConversionFeatures.samplerYcbcrConversion != VK_FALSE);

    ANGLE_FEATURE_CONDITION(&mFeatures, preferCachedNoncoherentForDynamicStreamBufferUsage,
                            IsMeteorLake(mPhysicalDeviceProperties.deviceID));

    // The compute shader used to generate mipmaps needs -
    // 1. subgroup quad operations in compute shader stage.
    // 2. subgroup operations that can use extended types.
    // 3. 256-wide workgroup.
    //
    // Furthermore, VK_IMAGE_USAGE_STORAGE_BIT is detrimental to performance on many platforms, on
    // which this path is not enabled.  Platforms that are known to have better performance with
    // this path are:
    //
    // - AMD
    // - Nvidia
    // - Samsung
    //
    // Additionally, this path is disabled on buggy drivers:
    //
    // - AMD/Windows: Unfortunately the trybots use ancient AMD cards and drivers.
    const bool supportsSubgroupQuadOpsInComputeShader =
        (mSubgroupProperties.supportedStages & VK_SHADER_STAGE_COMPUTE_BIT) &&
        (mSubgroupProperties.supportedOperations & VK_SUBGROUP_FEATURE_QUAD_BIT);

    const uint32_t maxComputeWorkGroupInvocations =
        mPhysicalDeviceProperties.limits.maxComputeWorkGroupInvocations;

    ANGLE_FEATURE_CONDITION(&mFeatures, allowGenerateMipmapWithCompute,
                            supportsSubgroupQuadOpsInComputeShader &&
                                mSubgroupExtendedTypesFeatures.shaderSubgroupExtendedTypes &&
                                maxComputeWorkGroupInvocations >= 256 &&
                                ((isAMD && !IsWindows()) || isNvidia || isSamsung));

    bool isAdreno540 = mPhysicalDeviceProperties.deviceID == angle::kDeviceID_Adreno540;
    ANGLE_FEATURE_CONDITION(&mFeatures, forceMaxUniformBufferSize16KB,
                            isQualcommProprietary && isAdreno540);

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsImageFormatList,
        ExtensionFound(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME, deviceExtensionNames));

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsSwapchainMutableFormat,
        useVulkanSwapchain == UseVulkanSwapchain::Yes &&
            mFeatures.supportsImageFormatList.enabled &&
            ExtensionFound(VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME, deviceExtensionNames));

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsSamplerMirrorClampToEdge,
        ExtensionFound(VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME, deviceExtensionNames));

    // Emulation of GL_EXT_multisampled_render_to_texture is only really useful on tiling hardware,
    // but is exposed on any configuration deployed on Android, such as Samsung's AMD-based GPU.
    //
    // During testing, it was also discovered that emulation triggers bugs on some platforms:
    //
    // - Swiftshader:
    //   * Failure on mac: http://anglebug.com/40644747
    //   * OOM: http://crbug.com/1263046
    // - Intel on windows: http://anglebug.com/42263602
    // - AMD on windows: http://crbug.com/1132366
    // - Old ARM proprietary drivers on Android fail multiple tests, though newer drivers don't
    //   (although they support MSRTSS and emulation is unnecessary)
    //
    ANGLE_FEATURE_CONDITION(&mFeatures, allowMultisampledRenderToTextureEmulation,
                            (isTileBasedRenderer && !isARMProprietary) || isSamsung);
    ANGLE_FEATURE_CONDITION(&mFeatures, enableMultisampledRenderToTexture,
                            mFeatures.supportsMultisampledRenderToSingleSampled.enabled ||
                                (mFeatures.supportsDepthStencilResolve.enabled &&
                                 mFeatures.allowMultisampledRenderToTextureEmulation.enabled));

    // Currently we enable cube map arrays based on the imageCubeArray Vk feature.
    // TODO: Check device caps for full cube map array support. http://anglebug.com/42263705
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsImageCubeArray,
                            mPhysicalDeviceFeatures.imageCubeArray == VK_TRUE);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsPipelineStatisticsQuery,
                            mPhysicalDeviceFeatures.pipelineStatisticsQuery == VK_TRUE);

    ANGLE_FEATURE_CONDITION(
        &mFeatures, allowPipelineStatisticsForPrimitivesGeneratedQuery,
        mFeatures.supportsPipelineStatisticsQuery.enabled && (isSamsung || isQualcommProprietary));

    ANGLE_FEATURE_CONDITION(&mFeatures, destroyOldSwapchainInSharedPresentMode, IsAndroid());

    // vkCmdClearAttachments races with draw calls on Qualcomm hardware as observed on Pixel2 and
    // Pixel4.  https://issuetracker.google.com/issues/166809097
    ANGLE_FEATURE_CONDITION(
        &mFeatures, preferDrawClearOverVkCmdClearAttachments,
        isQualcommProprietary && driverVersion < angle::VersionTriple(512, 762, 12));

    // R32F imageAtomicExchange emulation is done if shaderImageFloat32Atomics feature is not
    // supported.
    ANGLE_FEATURE_CONDITION(&mFeatures, emulateR32fImageAtomicExchange,
                            mShaderAtomicFloatFeatures.shaderImageFloat32Atomics != VK_TRUE);

    // Whether non-conformant configurations and extensions should be exposed.
    ANGLE_FEATURE_CONDITION(&mFeatures, exposeNonConformantExtensionsAndVersions,
                            kExposeNonConformantExtensionsAndVersions);

    // http://issuetracker.google.com/376899587
    // Currently some testing platforms do not fully support ES 3.2 due to lack of certain features
    // or extensions. For the purpose of testing coverage, we would still enable ES 3.2 on these
    // platforms. However, once a listed test platform is updated to a version that does support
    // ES 3.2, it should be unlisted.
    ANGLE_FEATURE_CONDITION(&mFeatures, exposeES32ForTesting,
                            mFeatures.exposeNonConformantExtensionsAndVersions.enabled &&
                                (isSoftwareRenderer || (IsWindows() && isIntel)));

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsMemoryBudget,
        ExtensionFound(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, deviceExtensionNames));

    // TODO: Delete these two feature flags (https://issuetracker.google.com/422507974). More
    // frequent submission may help benchmark score improvement, and in certain cases helps real
    // performance as well (for things like bufferSubData able to go down faster path), but it
    // increases power consumption by keeping GPU powered up longer for real world applications that
    // runs in vsync mode. For now the feature is just disabled so that people can still do
    // comparison if needed. They should be deleted in future.
    ANGLE_FEATURE_CONDITION(&mFeatures, preferSubmitAtFBOBoundary, false);
    // This is relevant only if preferSubmitAtFBOBoundary is enabled
    ANGLE_FEATURE_CONDITION(&mFeatures, forceSubmitExceptionsAtFBOBoundary,
                            mFeatures.preferSubmitAtFBOBoundary.enabled && !isQualcommProprietary);

    // The number of minimum write commands in the command buffer to trigger one submission of
    // pending commands at draw call time
    if (isARMProprietary)
    {
        mMinRPWriteCommandCountToEarlySubmit = 128;
    }

    // In order to support immutable samplers tied to external formats, we need to overallocate
    // descriptor counts for such immutable samplers
    ANGLE_FEATURE_CONDITION(&mFeatures, useMultipleDescriptorsForExternalFormats, true);

    // http://anglebug.com/42265147
    // When creating a surface with the format GL_RGB8, override the format to be GL_RGBA8, since
    // Android prevents creating swapchain images with VK_FORMAT_R8G8B8_UNORM.
    // Do this for all platforms, since few (none?) IHVs support 24-bit formats with their HW
    // natively anyway.
    ANGLE_FEATURE_CONDITION(&mFeatures, overrideSurfaceFormatRGB8ToRGBA8, true);

    // We set the following when there is color framebuffer fetch:
    //
    // - VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT
    // - VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_EXT
    //
    // and the following with depth/stencil framebuffer fetch:
    //
    // - VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT
    // -
    // VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT
    //
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsRasterizationOrderAttachmentAccess,
        mRasterizationOrderAttachmentAccessFeatures.rasterizationOrderColorAttachmentAccess ==
            VK_TRUE);

    ANGLE_FEATURE_CONDITION(
        &mFeatures, addFramebufferFetchBarrierOnUseMidRenderPass,
        mFeatures.supportsRasterizationOrderAttachmentAccess.enabled && isQualcomm);

    // The VK_EXT_surface_maintenance1 and VK_EXT_swapchain_maintenance1 extensions are used for a
    // variety of improvements:
    //
    // - Recycling present semaphores
    // - Avoiding swapchain recreation when present modes change
    // - Amortizing the cost of memory allocation for swapchain creation over multiple frames
    //
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsSwapchainMaintenance1,
                            mSwapchainMaintenance1Features.swapchainMaintenance1 == VK_TRUE &&
                                useVulkanSwapchain == UseVulkanSwapchain::Yes);

    // ANI crashes on NVIDIA/Wayland on a swapchain with deferred memory allocation.
    // http://anglebug.com/499347835
    // Keyed on the window system this display resolved to, so it covers the
    // Wayland WSI exactly and leaves XWayland's xcb swapchains alone.
    ANGLE_FEATURE_CONDITION(
        &mFeatures, swapchainDeferredMemoryAllocation,
        mFeatures.supportsSwapchainMaintenance1.enabled &&
            !(nativeWindowSystem == angle::NativeWindowSystem::Wayland && isNvidia));

    // The VK_EXT_legacy_dithering extension enables dithering support without emulation
    // Disable the usage of VK_EXT_legacy_dithering on ARM until the driver bug
    // http://issuetracker.google.com/293136916, http://issuetracker.google.com/292282210 are fixed.
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsLegacyDithering,
                            mDitheringFeatures.legacyDithering == VK_TRUE);

    // Applications on Android have come to rely on hardware dithering, and visually regress without
    // it.  On desktop GPUs, OpenGL's dithering is a no-op.  The following setting mimics that
    // behavior.  Dithering is also currently not enabled on SwiftShader, but can be as needed
    // (which would require Chromium and Capture/Replay test expectations updates).
    ANGLE_FEATURE_CONDITION(&mFeatures, emulateDithering,
                            IsAndroid() && !mFeatures.supportsLegacyDithering.enabled);

    // Enable additional blend factors when dithering for Samsung
    ANGLE_FEATURE_CONDITION(&mFeatures, enableAdditionalBlendFactorsForDithering, isSamsung);

    ANGLE_FEATURE_CONDITION(&mFeatures, adjustClearColorPrecision,
                            IsAndroid() && mFeatures.supportsLegacyDithering.enabled &&
                                isARMProprietary && driverVersion < angle::VersionTriple(50, 0, 0));

    // ANGLE always exposes framebuffer fetch because too many apps assume it's there.  See comments
    // on |mIsColorFramebufferFetchCoherent| for details.  Non-coherent framebuffer fetch is always
    // supported by Vulkan.
    //
    // Without exposeNonConformantExtensionsAndVersions, this feature is disable on Intel/windows
    // due to lack of input attachment support for swapchain images, and Intel/mesa before mesa
    // 22.0 for the same reason.  Without VK_GOOGLE_surfaceless_query, there is no way to
    // automatically deduce this support.
    //
    // http://issuetracker.google.com/376899587
    // Advanced blend emulation depends on this functionality, lack of which prevents support for
    // ES 3.2; exposeNonConformantExtensionsAndVersions is used to force this.
    const bool supportsFramebufferFetchInSurface =
        IsAndroid() || !isIntel ||
        (isIntel && IsLinux() && driverVersion >= angle::VersionTriple(22, 0, 0)) ||
        mFeatures.exposeNonConformantExtensionsAndVersions.enabled;

    // Emulating framebuffer fetch causes significant perf regressions on samsung
    const bool framebufferFetchEmulationCausesPerfRegression = isSamsung;

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsShaderFramebufferFetch,
        (supportsFramebufferFetchInSurface && !framebufferFetchEmulationCausesPerfRegression));
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsShaderFramebufferFetchNonCoherent,
        (supportsFramebufferFetchInSurface && !framebufferFetchEmulationCausesPerfRegression));

    // On ARM hardware, framebuffer-fetch-like behavior on Vulkan is known to be coherent even
    // without the Vulkan extension.
    //
    // On IMG hardware, similarly framebuffer-fetch-like behavior on Vulkan is known to be coherent,
    // but the Vulkan extension cannot be exposed.  This is because the Vulkan extension guarantees
    // coherence when accessing all samples of a pixel from any other sample, but IMG hardware is
    // _not_ coherent in that case.  This is not a problem for GLES because the invocation for each
    // sample can only access values for the same sample by reading "the current color value",
    // unlike Vulkan-GLSL's |subpassLoad()| which takes a sample index.
    mIsColorFramebufferFetchCoherent =
        isARM || isPowerVR || mFeatures.supportsRasterizationOrderAttachmentAccess.enabled;

    // Support EGL_KHR_lock_surface3 extension.
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsLockSurfaceExtension, IsAndroid());

    // http://anglebug.com/42265370
    // Android needs swapbuffers to update image and present to display.
    ANGLE_FEATURE_CONDITION(&mFeatures, swapbuffersOnFlushOrFinishWithSingleBuffer, IsAndroid());

    // Workaround a Qualcomm imprecision with dithering
    ANGLE_FEATURE_CONDITION(&mFeatures, roundOutputAfterDithering, isQualcomm);

    // GL_KHR_blend_equation_advanced is emulated when the equivalent Vulkan extension is not
    // usable.
    ANGLE_FEATURE_CONDITION(
        &mFeatures, emulateAdvancedBlendEquations,
        !mFeatures.supportsBlendOperationAdvanced.enabled && supportsFramebufferFetchInSurface);

    // GL_KHR_blend_equation_advanced_coherent ensures that the blending operations are performed in
    // API primitive order.
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsBlendOperationAdvancedCoherent,
        mFeatures.supportsBlendOperationAdvanced.enabled &&
            mBlendOperationAdvancedFeatures.advancedBlendCoherentOperations == VK_TRUE);

    // http://anglebug.com/42265410
    // Android expects VkPresentRegionsKHR rectangles with a bottom-left origin, while spec
    // states they should have a top-left origin.
    ANGLE_FEATURE_CONDITION(&mFeatures, bottomLeftOriginPresentRegionRectangles, IsAndroid());

    // Use VMA for image suballocation.
    ANGLE_FEATURE_CONDITION(&mFeatures, useVmaForImageSuballocation, true);

    // Use larger size for DynamicBuffer objects used as streaming vertex buffers (currently limited
    // to GLES1).
    ANGLE_FEATURE_CONDITION(&mFeatures, useLargeSizeForDynamicBuffers,
                            mPhysicalDeviceProperties.limits.maxMemoryAllocationCount <=
                                kAllocationCountThresholdForDynamicVertexDataSize);

    // Some platforms perform better using BGR565 than RGB565.
    bool isBGR565Renderable = hasImageFormatFeatureBits(angle::FormatID::B5G6R5_UNORM,
                                                        VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
    ANGLE_FEATURE_CONDITION(&mFeatures, preferBGR565ToRGB565, isBGR565Renderable && isQualcomm);

    // Emit SPIR-V 1.4 when supported.  The following old drivers have various bugs with SPIR-V 1.4:
    //
    // - Nvidia drivers - Crashes when creating pipelines, not using any SPIR-V 1.4 features.  Known
    //                    good since at least version 525.  http://anglebug.com/343249127
    // - Qualcomm drivers - Crashes when creating pipelines in the presence of OpCopyLogical with
    //                      some types.
    //                      Known good since at least version 512.829.0.
    //                      http://anglebug.com/343218484
    // - ARM proprietary drivers - Fail tests when OpSelect uses a scalar to select between vectors.
    //                             Known good since at least version 47.
    //                             http://anglebug.com/343218491
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsSPIRV14,
        ExtensionFound(VK_KHR_SPIRV_1_4_EXTENSION_NAME, deviceExtensionNames) &&
            !(isNvidia && driverVersion < angle::VersionTriple(525, 0, 0)) &&
            !(isQualcommProprietary && driverVersion < angle::VersionTriple(512, 829, 0)) &&
            !(isARMProprietary && driverVersion < angle::VersionTriple(47, 0, 0)));

    // Retain debug info in SPIR-V blob.
    ANGLE_FEATURE_CONDITION(&mFeatures, retainSPIRVDebugInfo, getEnableValidationLayers());

    // For discrete GPUs, most of device local memory is host invisible. We should not force the
    // host visible flag for them and result in allocation failure.
    ANGLE_FEATURE_CONDITION(
        &mFeatures, preferDeviceLocalMemoryHostVisible,
        canPreferDeviceLocalMemoryHostVisible(mPhysicalDeviceProperties.deviceType));

    // Multiple dynamic state issues on ARM have been fixed.
    // http://issuetracker.google.com/285124778
    // http://issuetracker.google.com/285196249
    // http://issuetracker.google.com/286224923
    // http://issuetracker.google.com/287318431
    //
    // On Pixel devices, the issues have been fixed since r44, but on others since r44p1.
    //
    // Regressions have been detected using r46 on older architectures, which are fixed in r51.
    // http://issuetracker.google.com/336411904
    const bool isARMExtendedDynamicStateBuggy =
        isARMProprietary &&
        (driverVersion < angle::VersionTriple(44, 1, 0) ||
         (isMaliJobManagerBasedGPU && driverVersion >= angle::VersionTriple(46, 0, 0) &&
          driverVersion < angle::VersionTriple(51, 0, 0)));

    // Intel driver has issues with VK_EXT_vertex_input_dynamic_state
    // http://anglebug.com/42265637#comment9
    //
    // On ARM proprietary drivers prior to r48, |vkCmdBindVertexBuffers2| applies strides to the
    // wrong index, according to the errata:
    // https://developer.arm.com/documentation/SDEN-3735689/0100/?lang=en
    //
    // On Qualcomm proprietary drivers prior to 777, this feature had a bug
    // (http://anglebug.com/381384988). Further data also shows that disable vertexInputDynamicState
    // has less overall CPU overhead.
    //
    // Use of vertexInputDynamicState on PowerVR devices is disabled for performance reasons
    // (http://issuetracker.google.com/469320616).
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsVertexInputDynamicState,
        mVertexInputDynamicStateFeatures.vertexInputDynamicState == VK_TRUE &&
            !(IsWindows() && isIntel) &&
            !(isARMProprietary && driverVersion < angle::VersionTriple(48, 0, 0)) &&
            !isQualcommProprietary && !isPowerVR);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsExtendedDynamicState,
                            mExtendedDynamicStateFeatures.extendedDynamicState == VK_TRUE &&
                                !isARMExtendedDynamicStateBuggy);

    // VK_EXT_vertex_input_dynamic_state enables dynamic state for the full vertex input state. As
    // such, when available use supportsVertexInputDynamicState instead of
    // useVertexInputBindingStrideDynamicState.
    //
    // Vertex input binding stride is buggy for Windows/Intel drivers before 100.9684
    // (https://anglebug.com/42266992).
    //
    // |vkCmdBindVertexBuffers2| applies strides to the wrong index on ARM proprietary drivers prior
    // to r48, according to the errata:
    // https://developer.arm.com/documentation/SDEN-3735689/0100/?lang=en
    const bool isVertexInputBindingStrideBuggy =
        (IsWindows() && isIntel && driverVersion < angle::VersionTriple(100, 9684, 0)) ||
        (isARMProprietary && driverVersion < angle::VersionTriple(48, 0, 0));
    ANGLE_FEATURE_CONDITION(&mFeatures, useVertexInputBindingStrideDynamicState,
                            mFeatures.supportsExtendedDynamicState.enabled &&
                                !mFeatures.supportsVertexInputDynamicState.enabled &&
                                !isVertexInputBindingStrideBuggy);
    // On ARM proprietary drivers prior to r52, |vkCmdSetCullMode| incorrectly culls non-triangle
    // topologies, according to the errata:
    // https://developer.arm.com/documentation/SDEN-3735689/0100/?lang=en
    ANGLE_FEATURE_CONDITION(
        &mFeatures, useCullModeDynamicState,
        mFeatures.supportsExtendedDynamicState.enabled && !isARMExtendedDynamicStateBuggy &&
            !(isARMProprietary && driverVersion < angle::VersionTriple(52, 0, 0)));
    ANGLE_FEATURE_CONDITION(&mFeatures, useDepthCompareOpDynamicState,
                            mFeatures.supportsExtendedDynamicState.enabled);
    ANGLE_FEATURE_CONDITION(&mFeatures, useDepthTestEnableDynamicState,
                            mFeatures.supportsExtendedDynamicState.enabled);
    ANGLE_FEATURE_CONDITION(
        &mFeatures, useDepthWriteEnableDynamicState,
        mFeatures.supportsExtendedDynamicState.enabled && !isARMExtendedDynamicStateBuggy);
    ANGLE_FEATURE_CONDITION(&mFeatures, useFrontFaceDynamicState,
                            mFeatures.supportsExtendedDynamicState.enabled);
    // On ARM proprietary drivers, there seems to be a bug with primitive topology dynamic state in
    // combination with geometry shaders.
    //
    // On Samsung, it was observed that the combination of primitive topology dynamic state
    // _enabled_ and primitive restart dynamic state _disabled_ is buggy.  However, the feature is
    // not disabled because primitive restart is not disabled outside tests.
    //
    // Also seeing rendering issues on PowerVR (http://b/472763050)
    ANGLE_FEATURE_CONDITION(
        &mFeatures, usePrimitiveTopologyDynamicState,
        mFeatures.supportsExtendedDynamicState.enabled && !isARMProprietary && !isPowerVR);
    ANGLE_FEATURE_CONDITION(&mFeatures, useStencilOpDynamicState,
                            mFeatures.supportsExtendedDynamicState.enabled);
    ANGLE_FEATURE_CONDITION(&mFeatures, useStencilTestEnableDynamicState,
                            mFeatures.supportsExtendedDynamicState.enabled);

    // vkCmdBindVertexBuffers2EXT() requires extended dynamic state.
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsBindVertexBuffers2,
                            mFeatures.supportsExtendedDynamicState.enabled);

    // Providing vkCmdBindVertexBuffers2() with a pointer to the sizes of the bound buffers can help
    // with syncval issues and robustness.
    ANGLE_FEATURE_CONDITION(
        &mFeatures, forceSizePointerForBoundVertexBuffers,
        mEnableValidationLayers && mFeatures.supportsBindVertexBuffers2.enabled);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsExtendedDynamicState2,
                            mExtendedDynamicState2Features.extendedDynamicState2 == VK_TRUE &&
                                !isARMExtendedDynamicStateBuggy);

    ANGLE_FEATURE_CONDITION(
        &mFeatures, usePrimitiveRestartEnableDynamicState,
        mFeatures.supportsExtendedDynamicState2.enabled && !isARMExtendedDynamicStateBuggy);
    ANGLE_FEATURE_CONDITION(&mFeatures, useRasterizerDiscardEnableDynamicState,
                            mFeatures.supportsExtendedDynamicState2.enabled);
    ANGLE_FEATURE_CONDITION(&mFeatures, useDepthBiasEnableDynamicState,
                            mFeatures.supportsExtendedDynamicState2.enabled);

    // Disabled on Intel/Mesa due to driver bug (crbug.com/1379201).  This bug is fixed since Mesa
    // 22.2.0.
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsLogicOpDynamicState,
        mFeatures.supportsExtendedDynamicState2.enabled &&
            mExtendedDynamicState2Features.extendedDynamicState2LogicOp == VK_TRUE &&
            !(IsLinux() && isIntel && driverVersion < angle::VersionTriple(22, 2, 0)) &&
            !(IsAndroid() && isGalaxyS23));

    // Older Samsung drivers with version < 24.0.0 have a bug in imageless framebuffer support.
    const bool isSamsungDriverWithImagelessFramebufferBug =
        isSamsung && driverVersion < angle::VersionTriple(24, 0, 0);
    // Qualcomm with imageless framebuffers, vkCreateFramebuffer loops forever (512.801).
    // http://issuetracker.google.com/369693310
    //
    // On some devices, crashes are seen with vkCmdBeginRenderPass, likely due to imageless
    // framebuffers (512.805).  http://crbug.com/415968761
    const bool isQualcommWithImagelessFramebufferBug =
        isQualcommProprietary && driverVersion < angle::VersionTriple(512, 806, 0);
    // Some ARM-based phones with the 38.0 and 38.1 ARM proprietary driver crash when creating
    // imageless framebuffers.
    const bool isARMProprietaryWithImagelessFramebufferBug =
        isARMProprietary && driverVersion >= angle::VersionTriple(38, 0, 0) &&
        driverVersion < angle::VersionTriple(38, 2, 0);
    // PowerVR with imageless framebuffer spends enormous amounts of time in framebuffer destruction
    // and creation. ANGLE doesn't cache imageless framebuffers, instead adding them to garbage
    // collection, expecting them to be lightweight.
    // http://issuetracker.google.com/372273294
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsImagelessFramebuffer,
                            mImagelessFramebufferFeatures.imagelessFramebuffer == VK_TRUE &&
                                !isSamsungDriverWithImagelessFramebufferBug &&
                                !isARMProprietaryWithImagelessFramebufferBug &&
                                !isQualcommWithImagelessFramebufferBug && !isPowerVR);

    if (ExtensionFound(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME, deviceExtensionNames))
    {
        queryAndCacheFragmentShadingRates();
    }

    // Support GL_QCOM_shading_rate extension
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsFragmentShadingRate,
                            canSupportFragmentShadingRate());

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsPrimitiveFragmentShadingRate,
                            mFragmentShadingRateFeatures.primitiveFragmentShadingRate == VK_TRUE);

    // Support QCOM foveated rendering extensions.
    // Gated on supportsImagelessFramebuffer and supportsRenderPassLoadStoreOpNone
    // to reduce code complexity.
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsFoveatedRendering,
                            mFeatures.supportsImagelessFramebuffer.enabled &&
                                mFeatures.supportsRenderPassLoadStoreOpNone.enabled &&
                                mFeatures.supportsFragmentShadingRate.enabled &&
                                canSupportFoveatedRendering());

    // Force CPU based generation of fragment shading rate attachment data if
    // VkPhysicalDeviceFeatures::shaderStorageImageExtendedFormats is not supported
    ANGLE_FEATURE_CONDITION(&mFeatures, generateFragmentShadingRateAttchementWithCpu,
                            mPhysicalDeviceFeatures.shaderStorageImageExtendedFormats != VK_TRUE);

    // We can use the interlock to support GL_ANGLE_shader_pixel_local_storage_coherent.
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsFragmentShaderPixelInterlock,
        mFragmentShaderInterlockFeatures.fragmentShaderPixelInterlock == VK_TRUE);

    // The VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_EXT behavior is used by
    // ANGLE, which requires the robustBufferAccess feature to be available.
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsPipelineRobustness,
                            mPipelineRobustnessFeatures.pipelineRobustness == VK_TRUE &&
                                mPhysicalDeviceFeatures.robustBufferAccess);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsPipelineProtectedAccess,
                            mPipelineProtectedAccessFeatures.pipelineProtectedAccess == VK_TRUE &&
                                mProtectedMemoryFeatures.protectedMemory == VK_TRUE);

    // VK_EXT_graphics_pipeline_library is available on NVIDIA drivers earlier
    // than version 531, but there are transient visual glitches with rendering
    // on those earlier versions.  http://anglebug.com/42266655
    //
    // On RADV, creating graphics pipeline can crash in the driver.  http://crbug.com/1497512
    //
    // Some unacceptable performance degradation has been observed on device with ARM proprietary
    // driver when graphics pipeline is enabled, therefore it's recommended to disable it until the
    // problematic area gets addressed and fixed. http://anglebug.com/404581992
    //
    // PowerVR graphics pipeline support is in development and not yet tested with ANGLE.
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsGraphicsPipelineLibrary,
                            mGraphicsPipelineLibraryFeatures.graphicsPipelineLibrary == VK_TRUE &&
                                (!isNvidia || driverVersion >= angle::VersionTriple(531, 0, 0)) &&
                                !isRADV && !isARMProprietary && !isPowerVR);

    // When VK_EXT_graphics_pipeline_library is not used:
    //
    //   The following drivers are known to key the pipeline cache blobs with vertex input and
    //   fragment output state, causing draw-time pipeline creation to miss the cache regardless of
    //   warm up:
    //
    //     - ARM proprietary drivers
    //     - Imagination drivers
    //
    //   The following drivers are instead known to _not_ include said state, and hit the cache at
    //   draw time.
    //
    //     - SwiftShader
    //     - Open source Qualcomm drivers
    //
    //   The situation is unknown for other drivers.
    //
    //   Additionally, numerous tests that previously never created a Vulkan pipeline fail or crash
    //   on proprietary Qualcomm drivers when they do during cache warm up.  On Intel/Linux, one
    //   trace shows flakiness with this.
    //
    // When VK_EXT_graphics_pipeline_library is used, warm up is always enabled as the chances of
    // blobs being reused is very high.
    const bool libraryBlobsAreReusedByMonolithicPipelines = !isARMProprietary && !isPowerVR;
    ANGLE_FEATURE_CONDITION(
        &mFeatures, warmUpPipelineCacheAtLink,
        mFeatures.supportsGraphicsPipelineLibrary.enabled ||
            (libraryBlobsAreReusedByMonolithicPipelines && !isQualcommProprietary &&
             !(IsLinux() && isIntel) && !(IsChromeOS() && isSwiftShader)));

    // On SwiftShader, no data is retrieved from the pipeline cache, so there is no reason to
    // serialize it or put it in the blob cache.
    // For Windows NVIDIA Vulkan driver, Vulkan pipeline cache will only generate one
    // single huge cache for one process shared by all graphics pipelines in the same process,
    // which can be huge. zlib take long time to compress it.
    ANGLE_FEATURE_CONDITION(&mFeatures, skipPipelineCacheSerialization, isSwiftShader || isNvidia);

    // Practically all drivers still prefer to do cross-stage linking.
    // graphicsPipelineLibraryFastLinking allows them to quickly produce working pipelines, but it
    // is typically not as efficient as complete pipelines.
    //
    // Unfortunately, the monolithic pipeline is not required to produce the exact same output as
    // linked-pipelines, which violates OpenGL ES rules:
    //
    //   Rule 4 The same vertex or fragment shader will produce the same result when run multiple
    //   times with the same input. The wording 'the same shader' means a program object that is
    //   populated with the same source strings, which are compiled and then linked, possibly
    //   multiple times, and which program object is then executed using the same GL state vector.
    //   Invariance is relaxed for shaders with side effects, such as image stores, image atomic
    //   operations, or accessing atomic counters (see section A.5)
    //
    // For that reason, this feature is disabled by default.  An application that does not rely on
    // the above rule and would like to benefit from the gains may override this.
    ANGLE_FEATURE_CONDITION(&mFeatures, preferMonolithicPipelinesOverLibraries,
                            mFeatures.supportsGraphicsPipelineLibrary.enabled && false);

    // To avoid memory bloating due to using pipeline caches per program, the pipeline cache in the
    // renderer can be used.
    ANGLE_FEATURE_CONDITION(&mFeatures, preferGlobalPipelineCache,
                            isNvidia || (isAMD && !isRADV) || isSamsung || isQualcommProprietary);

    // Whether the pipeline caches should merge into the global pipeline cache.  This should only be
    // enabled on platforms if:
    //
    // - preferGlobalPipelineCache is not enabled
    // - VK_EXT_graphics_pipeline_library is not supported.  In that case, only the program's cache
    //   used during warm up is merged into the global cache for later monolithic pipeline creation.
    // - VK_EXT_graphics_pipeline_library is supported, monolithic pipelines are preferred, and the
    //   driver is able to reuse blobs from partial pipelines when creating monolithic pipelines.
    ANGLE_FEATURE_CONDITION(&mFeatures, mergeProgramPipelineCachesToGlobalCache,
                            !mFeatures.preferGlobalPipelineCache.enabled &&
                                (!mFeatures.supportsGraphicsPipelineLibrary.enabled ||
                                 (mFeatures.preferMonolithicPipelinesOverLibraries.enabled &&
                                  libraryBlobsAreReusedByMonolithicPipelines)));

    // Whether all accesses to pipeline cache need to be externally synchronized. This should only
    // be enabled on platforms if:
    //
    // - mergeProgramPipelineCachesToGlobalCache is enabled
    // - preferMonolithicPipelinesOverLibraries is enabled
    // - stale nvidia drivers
    ANGLE_FEATURE_CONDITION(&mFeatures, externallySynchronizePipelineCacheAccess,
                            mFeatures.mergeProgramPipelineCachesToGlobalCache.enabled ||
                                mFeatures.preferMonolithicPipelinesOverLibraries.enabled ||
                                (isNvidia && driverVersion < angle::VersionTriple(441, 0, 0)));

    ANGLE_FEATURE_CONDITION(&mFeatures, enableAsyncPipelineCacheCompression, true);

    // Enable using an extra submit fence for the command batches. In case there is an external
    // fence during the main submission, this extra fence will be used for an empty submission right
    // after it.
    ANGLE_FEATURE_CONDITION(&mFeatures, enableExtraSubmitFence, false);

    // Sync monolithic pipelines to the blob cache occasionally on platforms that would benefit from
    // it:
    //
    // - VK_EXT_graphics_pipeline_library is not supported, and the program cache is not warmed up:
    //   If the pipeline cache is being warmed up at link time, the blobs corresponding to each
    //   program is individually retrieved and stored in the blob cache already.
    // - VK_EXT_graphics_pipeline_library is supported, but monolithic pipelines are still
    //   preferred, and the cost of syncing the large cache is acceptable.
    //
    // Otherwise monolithic pipelines are recreated on every run.
    const bool hasNoPipelineWarmUp = !mFeatures.supportsGraphicsPipelineLibrary.enabled &&
                                     !mFeatures.warmUpPipelineCacheAtLink.enabled;
    const bool canSyncLargeMonolithicCache =
        mFeatures.supportsGraphicsPipelineLibrary.enabled &&
        mFeatures.preferMonolithicPipelinesOverLibraries.enabled &&
        (!IsAndroid() || mFeatures.enableAsyncPipelineCacheCompression.enabled);
    ANGLE_FEATURE_CONDITION(&mFeatures, syncMonolithicPipelinesToBlobCache,
                            !mFeatures.skipPipelineCacheSerialization.enabled &&
                                (hasNoPipelineWarmUp || canSyncLargeMonolithicCache));

    // Enable the feature on Samsung by default, because it has big blob cache.
    ANGLE_FEATURE_CONDITION(&mFeatures, useDualPipelineBlobCacheSlots, isSamsung);

    // Disable by default, because currently it is uncommon that blob cache supports storing
    // zero sized blobs (or erasing blobs).
    ANGLE_FEATURE_CONDITION(&mFeatures, useEmptyBlobsToEraseOldPipelineCacheFromBlobCache, false);

    // Assume that platform has blob cache that has LRU eviction.
    ANGLE_FEATURE_CONDITION(&mFeatures, hasBlobCacheThatEvictsOldItemsFirst, true);
    // Also assume that platform blob cache evicts only minimum number of items when it has LRU,
    // in which case verification is not required.
    ANGLE_FEATURE_CONDITION(&mFeatures, verifyPipelineCacheInBlobCache,
                            !mFeatures.hasBlobCacheThatEvictsOldItemsFirst.enabled);

    // On ARM proprietary driver, dynamic state for stencil write mask doesn't work correctly in the
    // presence of discard or alpha to coverage, if the static state provided when creating the
    // pipeline has a value of 0. Fixed in r43p0 release.
    ANGLE_FEATURE_CONDITION(&mFeatures, useNonZeroStencilWriteMaskStaticState,
                            isARMProprietary && driverVersion < angle::VersionTriple(43, 0, 0));

    // On some vendors per-sample shading is not enabled despite the presence of a Sample
    // decoration. Guard against this by parsing shader for "sample" decoration and explicitly
    // enabling per-sample shading pipeline state.
    ANGLE_FEATURE_CONDITION(&mFeatures, explicitlyEnablePerSampleShading, !isQualcommProprietary);

    // Force to create swapchain with continuous refresh on shared present. Disabled by default.
    // Only enable it on integrations without EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID passthrough.
    ANGLE_FEATURE_CONDITION(&mFeatures, forceContinuousRefreshOnSharedPresent, false);

    // Enable setting frame timestamp surface attribute on Android platform.
    // Frame timestamp is enabled by calling into "vkGetPastPresentationTimingGOOGLE"
    // which, on Android platforms, makes the necessary ANativeWindow API calls.
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsTimestampSurfaceAttribute,
                            IsAndroid() && ExtensionFound(VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
                                                          deviceExtensionNames));

    // Only enable VK_EXT_host_image_copy on hardware where identicalMemoryTypeRequirements is set.
    // That lets ANGLE avoid having to fallback to non-host-copyable image allocations if the
    // host-copyable one fails due to out-of-that-specific-kind-of-memory.
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsHostImageCopy,
                            mHostImageCopyFeatures.hostImageCopy == VK_TRUE &&
                                mHostImageCopyProperties.identicalMemoryTypeRequirements);
    // Software renderers always benefit from host-image-copy, because that's just memcpy.
    ANGLE_FEATURE_CONDITION(&mFeatures, allowHostImageCopyAfterInitialUpload, isSoftwareRenderer);

    // 1) host vk driver does not natively support ETC format.
    // 2) host vk driver supports BC format.
    // 3) host vk driver supports subgroup instructions: clustered, shuffle.
    //    * This limitation can be removed if necessary.
    // 4) host vk driver has maxTexelBufferSize >= 64M.
    //    * Usually on desktop device the limit is more than 128M. we may switch to dynamic
    //    decide cpu or gpu upload texture based on texture size.
    constexpr VkSubgroupFeatureFlags kRequiredSubgroupOp =
        VK_SUBGROUP_FEATURE_SHUFFLE_BIT | VK_SUBGROUP_FEATURE_CLUSTERED_BIT;
    static constexpr bool kSupportTranscodeEtcToBc = false;
    static constexpr uint32_t kMaxTexelBufferSize  = 64 * 1024 * 1024;
    const VkPhysicalDeviceLimits &limitsVk         = mPhysicalDeviceProperties.limits;
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsComputeTranscodeEtcToBc,
                            !mPhysicalDeviceFeatures.textureCompressionETC2 &&
                                kSupportTranscodeEtcToBc &&
                                (mSubgroupProperties.supportedOperations & kRequiredSubgroupOp) ==
                                    kRequiredSubgroupOp &&
                                (limitsVk.maxTexelBufferElements >= kMaxTexelBufferSize));

    // Limit GL_MAX_SHADER_STORAGE_BLOCK_SIZE to 256MB on older ARM hardware.
    ANGLE_FEATURE_CONDITION(&mFeatures, limitMaxStorageBufferSize, isMaliJobManagerBasedGPU);

    // http://anglebug.com/42265782
    // Flushing mutable textures causes flakes in perf tests using Windows/Intel GPU. Failures are
    // due to lost context/device.
    // http://b/278600575
    // Flushing mutable texture is disabled for discrete GPUs to mitigate possible VRAM OOM.
    ANGLE_FEATURE_CONDITION(
        &mFeatures, mutableMipmapTextureUpload,
        canPreferDeviceLocalMemoryHostVisible(mPhysicalDeviceProperties.deviceType));

    // Allow passthrough of EGL colorspace attributes on Android platform and for vendors that
    // are known to support wide color gamut.
    ANGLE_FEATURE_CONDITION(&mFeatures, eglColorspaceAttributePassthrough,
                            IsAndroid() && isSamsung);

    // GBM does not have a VkSurface hence it does not support presentation through a Vulkan queue.
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsPresentation,
                            nativeWindowSystem != angle::NativeWindowSystem::Gbm);

    // For tiled renderer, the renderpass query result may not available until the entire renderpass
    // is completed. This may cause a bubble in the application thread waiting result to be
    // available. When this feature flag is enabled, we will issue an immediate flush when we detect
    // there is switch from query enabled draw to query disabled draw. Since most apps uses bunch of
    // query back to back, this should only introduce one extra flush per frame.
    // https://issuetracker.google.com/250706693
    ANGLE_FEATURE_CONDITION(&mFeatures, preferSubmitOnAnySamplesPassedQueryEnd,
                            isTileBasedRenderer && !isQualcommProprietary);

    // ARM proprietary driver appears having a bug that if we did not wait for submission to
    // complete, but call vkGetQueryPoolResults(VK_QUERY_RESULT_WAIT_BIT), it may result
    // VK_NOT_READY. https://issuetracker.google.com/253522366
    //
    // Workaround for nvidia earlier version driver which appears having a bug that On older nvidia
    // driver, vkGetQueryPoolResult() with VK_QUERY_RESULT_WAIT_BIT may result in incorrect result.
    // In that case we force into CPU wait for submission to complete. http://anglebug.com/42265186
    ANGLE_FEATURE_CONDITION(
        &mFeatures, forceWaitForSubmissionToCompleteForQueryResult,
        isARMProprietary || (isNvidia && driverVersion < angle::VersionTriple(470, 0, 0)));

    // Some ARM proprietary drivers may not free memory in "vkFreeCommandBuffers()" without
    // VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT flag.
    ANGLE_FEATURE_CONDITION(&mFeatures, useResetCommandBufferBitForSecondaryPools,
                            isARMProprietary);

    // Intel, Mali and AMD mesa drivers need depthBiasConstantFactor to be doubled to align with GL.
    ANGLE_FEATURE_CONDITION(&mFeatures, doubleDepthBiasConstantFactor,
                            (isIntel && !IsWindows()) || isMesaPanVK || isRADV || isNvidia);

    // Required to pass android.media.codec.cts.EncodeDecodeTest
    // https://issuetracker.google.com/246218584
    ANGLE_FEATURE_CONDITION(
        &mFeatures, mapUnspecifiedColorSpaceToPassThrough,
        ExtensionFound(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME, mEnabledInstanceExtensions));

    ANGLE_FEATURE_CONDITION(&mFeatures, enablePipelineCacheDataCompression, true);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsTimelineSemaphore,
                            mTimelineSemaphoreFeatures.timelineSemaphore == VK_TRUE);

#if defined(ANGLE_PLATFORM_ANDROID)
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsExternalFormatResolve,
                            mExternalFormatResolveFeatures.externalFormatResolve == VK_TRUE);

    // We can fully support GL_EXT_YUV_target iff we have support for
    // VK_ANDROID_external_format_resolve.
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsYuvTarget,
                            mFeatures.supportsExternalFormatResolve.enabled);

#else
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsExternalFormatResolve, false);
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsYuvTarget, false);
#endif

    // VkEvent has much bigger overhead. Until we know that it helps desktop GPUs, we restrict it to
    // TBRs. Also enabled for testing drivers to get more test coverage in bots.
    ANGLE_FEATURE_CONDITION(&mFeatures, useVkEventForImageBarrier,
                            isTileBasedRenderer || isSoftwareRenderer);
    ANGLE_FEATURE_CONDITION(&mFeatures, useVkEventForBufferBarrier,
                            isTileBasedRenderer || isSoftwareRenderer);

    // VkEvent is better than pipeline barriers on Mali GPUs with vertex sync deferred mode enabled.
    // Be unable to query GPU features currently, we restrict it to Mali non-JobManagerBased GPUs.
    ANGLE_FEATURE_CONDITION(
        &mFeatures, isVertexSyncDeferred,
        mFeatures.useVkEventForBufferBarrier.enabled && isARM && !isMaliJobManagerBasedGPU);

    // vkCmdResetEvent adds extra GPU overhead and ARM prefers CPU overhead of creating/destroying
    // VkEvent instead of GPU overhead associated with vkCmdResetEvent.
    ANGLE_FEATURE_CONDITION(&mFeatures, recycleVkEvent, isSwiftShader);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsDynamicRendering,
                            mDynamicRenderingFeatures.dynamicRendering == VK_TRUE);

    // Don't enable VK_KHR_maintenance5 without VK_KHR_dynamic_rendering
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsMaintenance5,
                            mFeatures.supportsDynamicRendering.enabled &&
                                mMaintenance5Features.maintenance5 == VK_TRUE);

    // Disabled on Nvidia driver due to a bug with attachment location mapping, resulting in
    // incorrect rendering in the presence of gaps in locations.  http://anglebug.com/372883691.
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsDynamicRenderingLocalRead,
        mFeatures.supportsDynamicRendering.enabled &&
            mDynamicRenderingLocalReadFeatures.dynamicRenderingLocalRead == VK_TRUE && !isNvidia);

    // Using dynamic rendering when VK_KHR_dynamic_rendering_local_read is available, because that's
    // needed for framebuffer fetch, MSRTT and advanced blend emulation.
    //
    // VK_EXT_legacy_dithering needs to be at version 2 and VK_KHR_maintenance5 to be usable with
    // dynamic rendering.  If only version 1 is exposed, it's not sacrificied for dynamic rendering
    // and render pass objects are continued to be used.
    //
    // Using dynamic rendering when emulating GL_EXT_multisampled_render_to_texture is
    // supported. Except for SwiftShader, which crashes when binding non-attachment textures as
    // input attachments.
    //
    // Use of dynamic rendering is disabled on older ARM proprietary drivers due to driver bugs
    // (http://issuetracker.google.com/356051947).
    //
    // Use of dynamic rendering is disabled on older Qualcomm drivers due to driver bugs
    // (http://crbug.com/415738891).
    //
    // Use of dynamic rendering on PowerVR devices is disabled for performance reasons
    // (http://issuetracker.google.com/372273294).
    const bool hasLegacyDitheringV1 =
        mFeatures.supportsLegacyDithering.enabled &&
        (mLegacyDitheringVersion < 2 || !mFeatures.supportsMaintenance5.enabled);
    ANGLE_FEATURE_CONDITION(
        &mFeatures, preferDynamicRendering,
        mFeatures.supportsDynamicRendering.enabled &&
            mFeatures.supportsDynamicRenderingLocalRead.enabled && !hasLegacyDitheringV1 &&
            !isSwiftShader &&
            !(isARMProprietary && driverVersion < angle::VersionTriple(52, 0, 0)) &&
            !(isQualcommProprietary && driverVersion < angle::VersionTriple(512, 801, 0)) &&
            !isPowerVR);

    // On tile-based renderers, breaking the render pass is costly.  Changing into and out of
    // framebuffer fetch causes the render pass to break so that the layout of the color attachments
    // can be adjusted.  On such hardware, the switch to framebuffer fetch mode is made permanent so
    // such render pass breaks don't happen.
    //
    // This only applies to legacy render passes; with dynamic rendering there is no render pass
    // break when switching framebuffer fetch usage.
    ANGLE_FEATURE_CONDITION(&mFeatures, permanentlySwitchToFramebufferFetchMode,
                            isTileBasedRenderer && !mFeatures.preferDynamicRendering.enabled);

    // Vulkan supports depth/stencil input attachments same as it does with color.
    // GL_ARM_shader_framebuffer_fetch_depth_stencil requires coherent behavior however, so this
    // extension is exposed only where coherent framebuffer fetch is available.
    //
    // Additionally, the implementation assumes VK_KHR_dynamic_rendering_local_read to avoid
    // complications with VkRenderPass objects.
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsShaderFramebufferFetchDepthStencil,
        mFeatures.supportsShaderFramebufferFetch.enabled &&
            mRasterizationOrderAttachmentAccessFeatures.rasterizationOrderDepthAttachmentAccess ==
                VK_TRUE &&
            mRasterizationOrderAttachmentAccessFeatures.rasterizationOrderStencilAttachmentAccess ==
                VK_TRUE &&
            mFeatures.preferDynamicRendering.enabled);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsSynchronization2,
                            mSynchronization2Features.synchronization2 == VK_TRUE);

    // Disable descriptorSet cache for testing drivers to ensure the code path gets tested.
    ANGLE_FEATURE_CONDITION(&mFeatures, descriptorSetCache, !isSoftwareRenderer);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsImageCompressionControl,
                            mImageCompressionControlFeatures.imageCompressionControl == VK_TRUE);

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsImageCompressionControlSwapchain,
        mImageCompressionControlSwapchainFeatures.imageCompressionControlSwapchain == VK_TRUE);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsAstcSliced3d, isARM);

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsTextureCompressionAstcHdr,
        mTextureCompressionASTCHDRFeatures.textureCompressionASTC_HDR == VK_TRUE);

    // Not all hardware can support 3D textures with ASTC HDR (http://anglebug.com/416095435)
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsAstcHdr3dTextures,
        mFeatures.supportsTextureCompressionAstcHdr.enabled && CanSupportAstcHdr3D(this));

    // http://anglebug.com/42264006
    // GL_EXT_clip_cull_distance also adds features to geometry and tessellation shaders, which are
    // currently disabled.
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsClipCullDistanceInGSAndTS, false);

    // http://anglebug.com/442950569
    // feature is currently experimental (i.e. dont default enable even if device supports it)
    // keep it as an opt-in override instead
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsBufferDeviceAddress, false);

    // Disable memory report feature overrides if extension is not supported.
    if ((mFeatures.logMemoryReportCallbacks.enabled || mFeatures.logMemoryReportStats.enabled) &&
        !mMemoryReportFeatures.deviceMemoryReport)
    {
        WARN() << "Disabling the following feature(s) because driver does not support "
                  "VK_EXT_device_memory_report extension:";
        if (getFeatures().logMemoryReportStats.enabled)
        {
            WARN() << "\tlogMemoryReportStats";
            mFeatures.logMemoryReportStats.applyOverride(false);
        }
        if (getFeatures().logMemoryReportCallbacks.enabled)
        {
            WARN() << "\tlogMemoryReportCallbacks";
            mFeatures.logMemoryReportCallbacks.applyOverride(false);
        }
    }

    // Check if VK implementation needs to strip-out non-semantic reflection info from shader module
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsShaderNonSemanticInfo,
        ExtensionFound(VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME, deviceExtensionNames));

    // Unconditionally enable GL_ANGLE_rgbx_internal_format extension
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsAngleRgbxInternalFormat, true);

    // Don't expose GL_APPLE_clip_distance on Samsung devices
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsAppleClipDistance, !isSamsung);

    // Force enable sample usage for AHB images for Samsung
    ANGLE_FEATURE_CONDITION(&mFeatures, forceSampleUsageForAhbBackedImages, isSamsung);

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsAstcDecodeMode,
        ExtensionFound(VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME, deviceExtensionNames));

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsAstcDecodeModeRgb9e5,
                            mPhysicalDeviceAstcDecodeFeatures.decodeModeSharedExponent == VK_TRUE &&
                                mFeatures.supportsAstcDecodeMode.enabled);

    // Disable uniformAndStorageBuffer16BitAccess and supportsShaderFloat16 on Samsung devices
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supports16BitUniformAndStorageBuffer,
        m16BitStorageFeatures.uniformAndStorageBuffer16BitAccess == VK_TRUE && !isSamsung);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsShaderFloat16,
                            mShaderFloat16Int8Features.shaderFloat16 == VK_TRUE && !isSamsung);

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsShaderDemoteToHelperInvocation,
        mShaderDemoteToHelperInvocationFeatures.shaderDemoteToHelperInvocation == VK_TRUE);

    // http://anglebug.com/440941211:
    // Disable the feature on Windows Intel because some shaders using 16-bit floats crash
    // http://anglebug.com/443302350
    // http://anglebug.com/443302625
    // Temporarily disable the feature on PowerVR while the above 2 bugs are under investigations
    // http://anglebug.com/446159597
    // Disable the feature on Samsung devices
    // https://b.corp.google.com/issues/446844410
    // Disable on driver implementations other than ARM proprietary until the performance impact on
    // them is verified.
    ANGLE_FEATURE_CONDITION(&mFeatures, convertLowpAndMediumpFloatUniformsTo16Bits,
                            mFeatures.supports16BitUniformAndStorageBuffer.enabled &&
                                mFeatures.supportsShaderFloat16.enabled && isARMProprietary);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsUnifiedImageLayouts,
                            mUnifiedImageLayoutsFeatures.unifiedImageLayouts == VK_TRUE);

    // REALTIME priority is not permitted on most operating systems.  This feature is limited to
    // Android for now.
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsGlobalPriority,
        mPhysicalDeviceGlobalPriorityQueryFeatures.globalPriorityQuery == VK_TRUE && IsAndroid());

    // There are use cases where synchronization is not performed properly when texture is modified
    // between different contexts. To avoid rendering artifacts, force submit staged updates.
    ANGLE_FEATURE_CONDITION(&mFeatures, forceSubmitImmutableTextureUpdates, true);

    // Don't expose these 2 extensions on Samsung devices -
    // 1. GL_ANGLE_shader_pixel_local_storage
    // 2. GL_ANGLE_shader_pixel_local_storage_coherent
    ANGLE_FEATURE_CONDITION(&mFeatures, supportShaderPixelLocalStorageAngle, !isSamsung);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportFragmentShadingRateExtExtensions,
                            mFeatures.supportsFragmentShadingRate.enabled && !isSamsung);

    // http://issuetracker.google.com/372273294
    // Older Unity titles are calling glClear on depth/stencil followed by a call to
    // glInvalidateFramebuffer, but expect the contents of the framebuffer to still be valid.
    // In this case, we can't drop the clears that we've deferred.
    ANGLE_FEATURE_CONDITION(&mFeatures, dropDepthStencilClearOnInvalidate, false);

    // VK_QCOM_tile_memory_heap is available. Earlier qualcomm driver has a bug with copying stencil
    // data from tile memory.
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsTileMemoryHeap,
        mTileMemoryHeapFeatures.tileMemoryHeap == VK_TRUE &&
            !(isQualcommProprietary && driverVersion < angle::VersionTriple(512, 868, 1)));

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsAstc3d,
                            mTextureCompressionASTC3DFeatures.textureCompressionASTC_3D == VK_TRUE);

    // This feature flag shows reduced CPU instruction.
    // Older Samsung drivers with version < 25.0.0 have a bug in vertex attribute packing that
    // causes failures in some deqp tests when enableMergeClientAttribBuffer feature is enabled.
    const bool isSamsungDriverWithVertexAttributePackingBug =
        isSamsung && driverVersion < angle::VersionTriple(25, 0, 0);
    ANGLE_FEATURE_CONDITION(&mFeatures, enableMergeClientAttribBuffer,
                            !isSamsungDriverWithVertexAttributePackingBug);

    // Enable this feature to avoid image allocation overhead when repeatedly uploading the same
    // texture that has already been uploaded, outside a render pass.
    ANGLE_FEATURE_CONDITION(&mFeatures, avoidImageGhostOutsideRenderPass, !isARM);

    // Precompute the vertex pre-rotation swap + flip into a driver uniform to reduce additional
    // instructions executed per vertex
    ANGLE_FEATURE_CONDITION(&mFeatures, preferPrecomputedVertexTransform, isQualcommProprietary);
}

// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Features specific to OpenCL backend
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
void Renderer::initOpenCLFeatures(const vk::ExtensionNameList &deviceExtensionNames,
                                  const angle::FeatureOverrides &featureOverrides)
{
    const bool isSamsung = IsSamsung(mPhysicalDeviceProperties.vendorID);

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsExternalMemoryHost,
        ExtensionFound(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME, deviceExtensionNames));

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsUniformBufferStandardLayout,
        mUniformBufferStandardLayoutFeatures.uniformBufferStandardLayout == VK_TRUE);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsShaderFloat16,
                            mShaderFloat16Int8Features.shaderFloat16 == VK_TRUE);
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsShaderInt8,
                            mShaderFloat16Int8Features.shaderInt8 == VK_TRUE);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsShaderIntegerDotProduct,
                            mShaderIntegerDotProductFeatures.shaderIntegerDotProduct == VK_TRUE);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsShaderFloat64,
                            mPhysicalDeviceFeatures.shaderFloat64 == VK_TRUE);

    ANGLE_FEATURE_CONDITION(&mFeatures, supportsShaderAtomicInt64,
                            mShaderAtomicInt64Features.shaderBufferInt64Atomics == VK_TRUE &&
                                mShaderAtomicInt64Features.shaderSharedInt64Atomics == VK_TRUE);

    // Rounding features from VK_KHR_float_controls extension
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsDenormFtzFp16,
                            mFloatControlProperties.shaderDenormFlushToZeroFloat16 == VK_TRUE);
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsDenormFtzFp32,
                            mFloatControlProperties.shaderDenormFlushToZeroFloat32 == VK_TRUE);
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsDenormFtzFp64,
                            mFloatControlProperties.shaderDenormFlushToZeroFloat64 == VK_TRUE);
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsDenormPreserveFp16,
                            mFloatControlProperties.shaderDenormPreserveFloat16 == VK_TRUE);
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsDenormPreserveFp32,
                            mFloatControlProperties.shaderDenormPreserveFloat32 == VK_TRUE);
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsDenormPreserveFp64,
                            mFloatControlProperties.shaderDenormPreserveFloat64 == VK_TRUE);
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsRoundingModeRteFp16,
                            mFloatControlProperties.shaderRoundingModeRTEFloat16 == VK_TRUE);
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsRoundingModeRteFp32,
                            mFloatControlProperties.shaderRoundingModeRTEFloat32 == VK_TRUE);
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsRoundingModeRteFp64,
                            mFloatControlProperties.shaderRoundingModeRTEFloat64 == VK_TRUE);
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsRoundingModeRtzFp16,
                            mFloatControlProperties.shaderRoundingModeRTZFloat16 == VK_TRUE);
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsRoundingModeRtzFp32,
                            mFloatControlProperties.shaderRoundingModeRTZFloat32 == VK_TRUE);
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsRoundingModeRtzFp64,
                            mFloatControlProperties.shaderRoundingModeRTZFloat64 == VK_TRUE);
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsSignedZeroInfNanPreserveFp16,
        mFloatControlProperties.shaderSignedZeroInfNanPreserveFloat16 == VK_TRUE);
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsSignedZeroInfNanPreserveFp32,
        mFloatControlProperties.shaderSignedZeroInfNanPreserveFloat32 == VK_TRUE);
    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsSignedZeroInfNanPreserveFp64,
        mFloatControlProperties.shaderSignedZeroInfNanPreserveFloat64 == VK_TRUE);

    // 8bit storage features
    ANGLE_FEATURE_CONDITION(&mFeatures, supports8BitStorageBuffer,
                            m8BitStorageFeatures.storageBuffer8BitAccess == VK_TRUE);

    ANGLE_FEATURE_CONDITION(&mFeatures, supports8BitUniformAndStorageBuffer,
                            m8BitStorageFeatures.uniformAndStorageBuffer8BitAccess == VK_TRUE);

    ANGLE_FEATURE_CONDITION(&mFeatures, supports8BitPushConstant,
                            m8BitStorageFeatures.storagePushConstant8 == VK_TRUE);

    // 16bit storage features
    ANGLE_FEATURE_CONDITION(&mFeatures, supports16BitStorageBuffer,
                            m16BitStorageFeatures.storageBuffer16BitAccess == VK_TRUE);

    ANGLE_FEATURE_CONDITION(&mFeatures, supports16BitUniformAndStorageBuffer,
                            m16BitStorageFeatures.uniformAndStorageBuffer16BitAccess == VK_TRUE);

    ANGLE_FEATURE_CONDITION(&mFeatures, supports16BitPushConstant,
                            m16BitStorageFeatures.storagePushConstant16 == VK_TRUE);

    ANGLE_FEATURE_CONDITION(&mFeatures, supports16BitInputOutput,
                            m16BitStorageFeatures.storageInputOutput16 == VK_TRUE);

    // Enable the use of below native kernels
    // Each builtin kernel gets its own feature and condition, for now a single feature
    // condition is setup
    ANGLE_FEATURE_CONDITION(&mFeatures, usesNativeBuiltinClKernel, isSamsung);

    ANGLE_FEATURE_CONDITION(&mFeatures, debugClDumpCommandStream, false);

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsAmdShaderCoreProperties,
        ExtensionFound(VK_AMD_SHADER_CORE_PROPERTIES_EXTENSION_NAME, deviceExtensionNames));

    // The OpenCL extension cl_khr_subgroups needs support for
    // Basic - for subgroup size and related ops and barrier ops
    // Vote - for subgroup all/any ops
    // Arithmetic - for subgroup reduce and scan ops
    constexpr VkSubgroupFeatureFlags kRequiredSubgroupBits = VK_SUBGROUP_FEATURE_BASIC_BIT |
                                                             VK_SUBGROUP_FEATURE_VOTE_BIT |
                                                             VK_SUBGROUP_FEATURE_ARITHMETIC_BIT;

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsClKhrSubgroups,
        (mSubgroupProperties.supportedStages & VK_SHADER_STAGE_COMPUTE_BIT) != 0 &&
            (mSubgroupProperties.supportedOperations & kRequiredSubgroupBits) ==
                kRequiredSubgroupBits);

    // TODO: some vendors have issues with alpha channel images, this feature/workaround
    // serves as a allowlist around this support/feature http://anglebug.com/540157153
    const bool vendorsSupportingAlphaChannel = isSamsung;
    ANGLE_FEATURE_CONDITION(&mFeatures, enableAlphaChannelImages, vendorsSupportingAlphaChannel);

    ANGLE_FEATURE_CONDITION(
        &mFeatures, supportsClFp16,
        mFeatures.supportsShaderFloat16.enabled && (mFeatures.supportsRoundingModeRteFp16.enabled ||
                                                    mFeatures.supportsRoundingModeRtzFp16.enabled));

    ANGLE_FEATURE_CONDITION(&mFeatures, debugSupportsClFp64, false);
    ANGLE_FEATURE_CONDITION(&mFeatures, supportsClFp64,
                            mFeatures.debugSupportsClFp64.enabled &&
                                mFeatures.supportsShaderFloat64.enabled &&
                                mFeatures.supportsRoundingModeRteFp64.enabled &&
                                mFeatures.supportsRoundingModeRtzFp64.enabled &&
                                mFeatures.supportsDenormFtzFp64.enabled);
}

// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// All features set in this function must use the applyOverride method
// so that the value set is sticky
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
void Renderer::appBasedFeatureOverrides(const vk::ExtensionNameList &extensions) {}

angle::Result Renderer::initPipelineCache(vk::ErrorContext *context,
                                          vk::PipelineCache *pipelineCache,
                                          bool *success)
{
    angle::MemoryBuffer initialData;
    if (!mFeatures.disablePipelineCacheLoadForTesting.enabled)
    {
        ANGLE_TRY(GetAndDecompressPipelineCacheVk(context, mGlobalOps, &initialData, success));
    }

    VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {};

    pipelineCacheCreateInfo.sType           = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
    pipelineCacheCreateInfo.flags           = 0;
    pipelineCacheCreateInfo.initialDataSize = *success ? initialData.size() : 0;
    pipelineCacheCreateInfo.pInitialData    = *success ? initialData.data() : nullptr;

    ANGLE_VK_TRY(context, pipelineCache->init(mDevice, pipelineCacheCreateInfo));

    return angle::Result::Continue;
}

angle::Result Renderer::ensurePipelineCacheInitialized(vk::ErrorContext *context)
{
    // If it is initialized already, there is nothing to do
    if (mPipelineCacheInitialized)
    {
        return angle::Result::Continue;
    }

    std::unique_lock<angle::SimpleMutex> lock(mPipelineCacheMutex);

    // If another thread initialized it first don't redo it
    if (mPipelineCacheInitialized)
    {
        return angle::Result::Continue;
    }

    // We should now create the pipeline cache with the blob cache pipeline data.
    bool loadedFromBlobCache = false;
    ANGLE_TRY(initPipelineCache(context, &mPipelineCache, &loadedFromBlobCache));
    if (loadedFromBlobCache)
    {
        ANGLE_TRY(getLockedPipelineCacheDataIfNew(context, &mPipelineCacheSizeAtLastSync,
                                                  mPipelineCacheSizeAtLastSync, nullptr));
    }

    mPipelineCacheInitialized = true;

    return angle::Result::Continue;
}

size_t Renderer::getNextPipelineCacheBlobCacheSlotIndex(size_t *previousSlotIndexOut)
{
    if (previousSlotIndexOut != nullptr)
    {
        *previousSlotIndexOut = mCurrentPipelineCacheBlobCacheSlotIndex;
    }
    if (getFeatures().useDualPipelineBlobCacheSlots.enabled)
    {
        mCurrentPipelineCacheBlobCacheSlotIndex = 1 - mCurrentPipelineCacheBlobCacheSlotIndex;
    }
    return mCurrentPipelineCacheBlobCacheSlotIndex;
}

size_t Renderer::updatePipelineCacheChunkCount(size_t chunkCount)
{
    const size_t previousChunkCount = mPipelineCacheChunkCount;
    mPipelineCacheChunkCount        = chunkCount;
    return previousChunkCount;
}

angle::Result Renderer::getPipelineCache(vk::ErrorContext *context,
                                         vk::PipelineCacheAccess *pipelineCacheOut)
{
    ANGLE_TRY(ensurePipelineCacheInitialized(context));

    angle::SimpleMutex *pipelineCacheMutex =
        context->getFeatures().externallySynchronizePipelineCacheAccess.enabled
            ? &mPipelineCacheMutex
            : nullptr;

    pipelineCacheOut->init(&mPipelineCache, pipelineCacheMutex);
    return angle::Result::Continue;
}

angle::Result Renderer::mergeIntoPipelineCache(vk::ErrorContext *context,
                                               const vk::PipelineCache &pipelineCache)
{
    // It is an error to call into this method when the feature is disabled.
    ASSERT(context->getFeatures().mergeProgramPipelineCachesToGlobalCache.enabled);

    vk::PipelineCacheAccess globalCache;
    ANGLE_TRY(getPipelineCache(context, &globalCache));

    globalCache.merge(this, pipelineCache);

    return angle::Result::Continue;
}

const gl::Caps &Renderer::getNativeCaps() const
{
    ensureCapsInitialized();
    return mNativeCaps;
}

const gl::TextureCapsMap &Renderer::getNativeTextureCaps() const
{
    ensureCapsInitialized();
    return mNativeTextureCaps;
}

const gl::Extensions &Renderer::getNativeExtensions() const
{
    ensureCapsInitialized();
    return mNativeExtensions;
}

const gl::Limitations &Renderer::getNativeLimitations() const
{
    ensureCapsInitialized();
    return mNativeLimitations;
}

const ShPixelLocalStorageOptions &Renderer::getNativePixelLocalStorageOptions() const
{
    return mNativePLSOptions;
}

void Renderer::initializeFrontendFeatures(angle::FrontendFeatures *features) const
{
    const bool isSwiftShader =
        IsSwiftshader(mPhysicalDeviceProperties.vendorID, mPhysicalDeviceProperties.deviceID);
    const bool isSamsung = IsSamsung(mPhysicalDeviceProperties.vendorID);

    // Hopefully-temporary work-around for a crash on SwiftShader.  An Android process is turning
    // off GL error checking, and then asking ANGLE to write past the end of a buffer.
    // https://issuetracker.google.com/issues/220069903
    ANGLE_FEATURE_CONDITION(features, forceGlErrorChecking, (IsAndroid() && isSwiftShader));

    // Disable shader and program caching on Samsung devices.
    ANGLE_FEATURE_CONDITION(features, cacheCompiledShader, !isSamsung);
    ANGLE_FEATURE_CONDITION(features, disableProgramCaching, isSamsung);

    // https://issuetracker.google.com/292285899
    ANGLE_FEATURE_CONDITION(features, uncurrentEglSurfaceUponSurfaceDestroy, true);

    // The Vulkan backend's handling of compile and link is thread-safe
    ANGLE_FEATURE_CONDITION(features, compileJobIsThreadSafe, true);
    ANGLE_FEATURE_CONDITION(features, linkJobIsThreadSafe, true);
    // Always run the link's warm up job in a thread.  It's an optimization only, and does not block
    // the link resolution.
    ANGLE_FEATURE_CONDITION(features, alwaysRunLinkSubJobsThreaded, true);

    // Enable the program binary blob compression for glGetProgramBinary and glGetProgramiv.  It
    // will be decompressed when loading the program binary by glProgramBinary.
    ANGLE_FEATURE_CONDITION(features, compressProgramBinaryBlob, isSamsung);
}

angle::Result Renderer::getLockedPipelineCacheDataIfNew(vk::ErrorContext *context,
                                                        size_t *pipelineCacheSizeOut,
                                                        size_t lastSyncSize,
                                                        std::vector<uint8_t> *pipelineCacheDataOut)
{
    // Because this function may call |getCacheData| twice, |mPipelineCacheMutex| is not passed to
    // |PipelineAccessCache|, and is expected to be locked once **by the caller**.
    mPipelineCacheMutex.assertLocked();

    vk::PipelineCacheAccess globalCache;
    globalCache.init(&mPipelineCache, nullptr);

    ANGLE_VK_TRY(context, globalCache.getCacheData(context, pipelineCacheSizeOut, nullptr));

    // If the cache data is unchanged since last sync, don't retrieve the data.  Also, make sure we
    // will receive enough data to hold the pipeline cache header Table 7.  Layout for pipeline
    // cache header version VK_PIPELINE_CACHE_HEADER_VERSION_ONE.
    const size_t kPipelineCacheHeaderSize = 16 + VK_UUID_SIZE;
    if (*pipelineCacheSizeOut <= lastSyncSize || *pipelineCacheSizeOut < kPipelineCacheHeaderSize ||
        pipelineCacheDataOut == nullptr)
    {
        return angle::Result::Continue;
    }

    pipelineCacheDataOut->resize(*pipelineCacheSizeOut);
    VkResult result =
        globalCache.getCacheData(context, pipelineCacheSizeOut, pipelineCacheDataOut->data());
    if (ANGLE_UNLIKELY(result == VK_INCOMPLETE))
    {
        WARN()
            << "Received VK_INCOMPLETE when retrieving pipeline cache data, which should be "
               "impossible as the size query was previously done under the same lock, but this is "
               "a recoverable error";
    }
    else
    {
        ANGLE_VK_TRY(context, result);
    }

    // If vkGetPipelineCacheData ends up writing fewer bytes than requested, shrink the buffer to
    // avoid leaking garbage memory and potential rejection of the data by subsequent
    // vkCreatePipelineCache call.  Some drivers may ignore entire buffer if there padding present.
    ASSERT(*pipelineCacheSizeOut <= pipelineCacheDataOut->size());
    pipelineCacheDataOut->resize(*pipelineCacheSizeOut);

    return angle::Result::Continue;
}

angle::Result Renderer::syncPipelineCacheVk(const gl::Context *contextGL)
{
    // Skip syncing until pipeline cache is initialized.
    if (!mPipelineCacheInitialized)
    {
        return angle::Result::Continue;
    }
    ASSERT(mPipelineCache.valid());

    if (!mFeatures.syncMonolithicPipelinesToBlobCache.enabled)
    {
        return angle::Result::Continue;
    }

    if (--mPipelineCacheVkUpdateTimeout > 0)
    {
        return angle::Result::Continue;
    }

    mPipelineCacheVkUpdateTimeout =
        mFeatures.syncPipelineCacheToBlobCacheEveryFrame.enabled ? 1 : kPipelineCacheVkUpdatePeriod;

    ContextVk *contextVk = vk::GetImpl(contextGL);

    // Use worker thread pool to complete compression.
    // If the last task hasn't been finished, skip the syncing.
    if (mCompressEvent && !mCompressEvent->isReady())
    {
        ANGLE_PERF_WARNING(contextVk->getDebug(), GL_DEBUG_SEVERITY_LOW,
                           "Skip syncing pipeline cache data when the last task is not ready.");
        return angle::Result::Continue;
    }

    size_t pipelineCacheSize = 0;
    std::vector<uint8_t> pipelineCacheData;
    {
        std::unique_lock<angle::SimpleMutex> lock(mPipelineCacheMutex);
        ANGLE_TRY(getLockedPipelineCacheDataIfNew(
            contextVk, &pipelineCacheSize, mPipelineCacheSizeAtLastSync, &pipelineCacheData));
    }
    if (pipelineCacheData.empty())
    {
        return angle::Result::Continue;
    }
    mPipelineCacheSizeAtLastSync = pipelineCacheSize;

    vk::GlobalOps *globalOps = getGlobalOps();
    ASSERT(globalOps);
    if (mFeatures.enableAsyncPipelineCacheCompression.enabled)
    {
        // zlib compression ratio normally ranges from 2:1 to 5:1. Set kMaxTotalSize to 64M to
        // ensure the size can fit into the 32MB blob cache limit on supported platforms.
        constexpr size_t kMaxTotalSize = 64 * 1024 * 1024;

        // Create task to compress.
        mCompressEvent = contextGL->getWorkerThreadPool()->postWorkerTask(
            std::make_shared<CompressAndStorePipelineCacheTask>(
                globalOps, this, std::move(pipelineCacheData), kMaxTotalSize));
    }
    else
    {
        // If enableAsyncPipelineCacheCompression is disabled, to avoid the risk, set kMaxTotalSize
        // to 64k.
        constexpr size_t kMaxTotalSize = 64 * 1024;
        CompressAndStorePipelineCacheVk(globalOps, this, pipelineCacheData, kMaxTotalSize);
    }

    return angle::Result::Continue;
}

angle::Result Renderer::onFrameBoundary(const gl::Context *contextGL)
{
    ASSERT(contextGL);
    return syncPipelineCacheVk(contextGL);
}

// These functions look at the mandatory format for support, and fallback to querying the device (if
// necessary) to test the availability of the bits.
bool Renderer::hasLinearImageFormatFeatureBits(angle::FormatID formatID,
                                               const VkFormatFeatureFlags featureBits) const
{
    return hasFormatFeatureBits<&VkFormatProperties::linearTilingFeatures>(formatID, featureBits);
}

VkFormatFeatureFlags Renderer::getLinearImageFormatFeatureBits(
    angle::FormatID formatID,
    const VkFormatFeatureFlags featureBits) const
{
    return getFormatFeatureBits<&VkFormatProperties::linearTilingFeatures>(formatID, featureBits);
}

VkFormatFeatureFlags Renderer::getImageFormatFeatureBits(
    angle::FormatID formatID,
    const VkFormatFeatureFlags featureBits) const
{
    return getFormatFeatureBits<&VkFormatProperties::optimalTilingFeatures>(formatID, featureBits);
}

VkFormatFeatureFlags Renderer::getBufferFormatFeatureBits(
    angle::FormatID formatID,
    const VkFormatFeatureFlags featureBits) const
{
    return getFormatFeatureBits<&VkFormatProperties::bufferFeatures>(formatID, featureBits);
}

bool Renderer::hasImageFormatFeatureBits(angle::FormatID formatID,
                                         const VkFormatFeatureFlags featureBits) const
{
    return hasFormatFeatureBits<&VkFormatProperties::optimalTilingFeatures>(formatID, featureBits);
}

bool Renderer::hasBufferFormatFeatureBits(angle::FormatID formatID,
                                          const VkFormatFeatureFlags featureBits) const
{
    return hasFormatFeatureBits<&VkFormatProperties::bufferFeatures>(formatID, featureBits);
}

void Renderer::outputVmaStatString()
{
    // Output the VMA stats string
    // This JSON string can be passed to VmaDumpVis.py to generate a visualization of the
    // allocations the VMA has performed.
    char *statsString;
    mAllocator.buildStatsString(&statsString, true);
    INFO() << std::endl << statsString << std::endl;
    mAllocator.freeStatsString(statsString);
}

angle::Result Renderer::queueSubmitOneOff(vk::ErrorContext *context,
                                          vk::ScopedPrimaryCommandBuffer &&scopedCommandBuffer,
                                          vk::ProtectionType protectionType,
                                          egl::ContextPriority priority,
                                          VkSemaphore waitSemaphore,
                                          VkPipelineStageFlags waitSemaphoreStageMasks,
                                          QueueSerial *queueSerialOut)
{
    ANGLE_TRACE_EVENT0("gpu.angle", "Renderer::queueSubmitOneOff");
    DeviceScoped<PrimaryCommandBuffer> commandBuffer = scopedCommandBuffer.unlockAndRelease();
    PrimaryCommandBuffer &primary                    = commandBuffer.get();

    // Allocate a one off SerialIndex and generate a QueueSerial and then use it and release the
    // index.
    vk::ScopedQueueSerialIndex index;
    ANGLE_TRY(allocateScopedQueueSerialIndex(&index));
    QueueSerial submitQueueSerial(index.get(), generateQueueSerial(index.get()));

    ANGLE_TRY(mCommandQueue.queueSubmitOneOff(context, protectionType, priority,
                                              primary.getHandle(), waitSemaphore,
                                              waitSemaphoreStageMasks, submitQueueSerial));

    mSubmittedResourceUse.setQueueSerial(submitQueueSerial);
    *queueSerialOut = submitQueueSerial;
    if (primary.valid())
    {
        mOneOffCommandPoolMap[protectionType].releaseCommandBuffer(submitQueueSerial,
                                                                   std::move(primary));
    }

    ANGLE_TRY(mCommandQueue.postSubmitCheck(context));

    return angle::Result::Continue;
}

angle::Result Renderer::queueSubmitWaitSemaphore(vk::ErrorContext *context,
                                                 egl::ContextPriority priority,
                                                 const vk::Semaphore &waitSemaphore,
                                                 VkPipelineStageFlags waitSemaphoreStageMasks,
                                                 QueueSerial submitQueueSerial)
{
    ANGLE_TRY(mCommandQueue.queueSubmitOneOff(context, vk::ProtectionType::Unprotected, priority,
                                              VK_NULL_HANDLE, waitSemaphore.getHandle(),
                                              waitSemaphoreStageMasks, submitQueueSerial));
    mSubmittedResourceUse.setQueueSerial(submitQueueSerial);
    return angle::Result::Continue;
}

template <VkFormatFeatureFlags VkFormatProperties::*features>
VkFormatFeatureFlags Renderer::getFormatFeatureBits(angle::FormatID formatID,
                                                    const VkFormatFeatureFlags featureBits) const
{
    ASSERT(formatID != angle::FormatID::NONE);
    VkFormatProperties &deviceProperties = mFormatProperties[formatID];

    if (deviceProperties.bufferFeatures == kInvalidFormatFeatureFlags)
    {
        // If we don't have the actual device features, see if the requested features are mandatory.
        // If so, there's no need to query the device.
        const VkFormatProperties &mandatoryProperties = vk::GetMandatoryFormatSupport(formatID);
        if (IsMaskFlagSet(mandatoryProperties.*features, featureBits))
        {
            return featureBits;
        }

        if (vk::IsYUVExternalFormat(formatID))
        {
            const vk::ExternalYuvFormatInfo &externalFormatInfo =
                mExternalFormatTable.getExternalFormatInfo(formatID);
            deviceProperties.optimalTilingFeatures = externalFormatInfo.formatFeatures;
        }
        else
        {
            VkFormat vkFormat = vk::GetVkFormatFromFormatID(this, formatID);
            ASSERT(vkFormat != VK_FORMAT_UNDEFINED);

            if (vkFormat == VK_FORMAT_A8_UNORM &&
                (!mFeatures.supportsMaintenance5.enabled ||
                 mGlobalOps->getFrontendApi() != GlobalOps::Api::OpenCL))
            {
                // TODO: VK_FORMAT_A8_UNORM currently only available in (VK_KHR_maintenance5 +
                // OpenCL) usage - GLES should go to fallback format (R8_UNORM)
                // http://anglebug.com/42266715
                return 0;
            }

            // Otherwise query the format features and cache it.
            VK_CALL(vkGetPhysicalDeviceFormatProperties, mPhysicalDevice, vkFormat,
                    &deviceProperties);
            // Workaround for some Android devices that don't indicate filtering
            // support on D16_UNORM and they should.
            if (mFeatures.forceD16TexFilter.enabled && vkFormat == VK_FORMAT_D16_UNORM)
            {
                deviceProperties.*features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
            }
        }
    }

    return deviceProperties.*features & featureBits;
}

template <VkFormatFeatureFlags VkFormatProperties::*features>
bool Renderer::hasFormatFeatureBits(angle::FormatID formatID,
                                    const VkFormatFeatureFlags featureBits) const
{
    return IsMaskFlagSet(getFormatFeatureBits<features>(formatID, featureBits), featureBits);
}

bool Renderer::haveSameFormatFeatureBits(angle::FormatID formatID1, angle::FormatID formatID2) const
{
    if (formatID1 == angle::FormatID::NONE || formatID2 == angle::FormatID::NONE)
    {
        return false;
    }

    constexpr VkFormatFeatureFlags kImageUsageFeatureBits =
        VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT |
        VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;

    VkFormatFeatureFlags fmt1LinearFeatureBits =
        getLinearImageFormatFeatureBits(formatID1, kImageUsageFeatureBits);
    VkFormatFeatureFlags fmt1OptimalFeatureBits =
        getImageFormatFeatureBits(formatID1, kImageUsageFeatureBits);

    return hasLinearImageFormatFeatureBits(formatID2, fmt1LinearFeatureBits) &&
           hasImageFormatFeatureBits(formatID2, fmt1OptimalFeatureBits);
}

void Renderer::cleanupGarbage(bool *anyGarbageCleanedOut)
{
    bool anyCleaned = false;

    // Clean up general garbage
    anyCleaned = mSharedGarbageList.cleanupSubmittedGarbage(this) > 0 || anyCleaned;

    // Clean up suballocation garbages
    anyCleaned = mSuballocationGarbageList.cleanupSubmittedGarbage(this) > 0 || anyCleaned;

    // Note: do this after clean up mSuballocationGarbageList so that we will have more chances to
    // find orphaned blocks being empty.
    anyCleaned = mOrphanedBufferBlockList.pruneEmptyBufferBlocks(this) > 0 || anyCleaned;

    // Clean up RefCountedEvent that are done resetting
    anyCleaned = mRefCountedEventRecycler.cleanupResettingEvents(this) > 0 || anyCleaned;

    if (anyGarbageCleanedOut != nullptr)
    {
        *anyGarbageCleanedOut = anyCleaned;
    }
}

void Renderer::cleanupPendingSubmissionGarbage()
{
    // Check if pending garbage is still pending. If not, move them to the garbage list.
    mSharedGarbageList.cleanupUnsubmittedGarbage(this);
    mSuballocationGarbageList.cleanupUnsubmittedGarbage(this);
}

uint64_t Renderer::getMaxFenceWaitTimeNs() const
{
    constexpr uint64_t kMaxFenceWaitTimeNs = std::numeric_limits<uint64_t>::max();

    return kMaxFenceWaitTimeNs;
}

VkDeviceSize Renderer::padVertexAttribBufferSizeIfNeeded(VkDeviceSize bufferSize)
{
    // When the padding feature is disabled, the max attribute stride should remain 0.
    ASSERT(mFeatures.padBuffersToMaxVertexAttribStride.enabled ^ (mMaxVertexAttribStride == 0));
    return bufferSize + mMaxVertexAttribStride;
}

void Renderer::setGlobalDebugAnnotator(bool *installedAnnotatorOut)
{
    // Install one of two DebugAnnotator classes:
    //
    // 1) The global class enables basic ANGLE debug functionality (e.g. Vulkan validation errors
    //    will cause dEQP tests to fail).
    //
    // 2) The DebugAnnotatorVk class processes OpenGL ES commands that the application uses.  It is
    //    installed for the following purposes:
    //
    //    1) To enable calling the vkCmd*DebugUtilsLabelEXT functions in order to communicate to
    //       debuggers (e.g. AGI) the OpenGL ES commands that the application uses.  In addition to
    //       simply installing DebugAnnotatorVk, also enable calling vkCmd*DebugUtilsLabelEXT.
    //
    //    2) To enable logging to Android logcat the OpenGL ES commands that the application uses.
    bool installDebugAnnotatorVk = false;

    // Enable calling the vkCmd*DebugUtilsLabelEXT functions if the vkCmd*DebugUtilsLabelEXT
    // functions exist, and if the kEnableDebugMarkersVarName environment variable is set.
    if (vkCmdBeginDebugUtilsLabelEXT)
    {
        // Use the GetAndSet variant to improve future lookup times
        std::string enabled = angle::GetAndSetEnvironmentVarOrUnCachedAndroidProperty(
            kEnableDebugMarkersVarName, kEnableDebugMarkersPropertyName);
        if (!enabled.empty() && enabled.compare("0") != 0)
        {
            mAngleDebuggerMode      = true;
            installDebugAnnotatorVk = true;
        }
    }
#if defined(ANGLE_ENABLE_TRACE_ANDROID_LOGCAT)
    // Only install DebugAnnotatorVk to log all API commands to Android's logcat.
    installDebugAnnotatorVk = true;
#endif

    {
        if (installDebugAnnotatorVk)
        {
            std::unique_lock<angle::SimpleMutex> lock(gl::GetDebugMutex());
            gl::InitializeDebugAnnotations(&mAnnotator);
        }
    }

    *installedAnnotatorOut = installDebugAnnotatorVk;
}

void Renderer::reloadVolkIfNeeded() const
{
#if defined(ANGLE_SHARED_LIBVULKAN)
    if ((mInstance != VK_NULL_HANDLE) && (volkGetLoadedInstance() != mInstance))
    {
        VK_CALL(volkLoadInstance, mInstance);
    }

    if ((mDevice != VK_NULL_HANDLE) && (volkGetLoadedDevice() != mDevice))
    {
        VK_CALL(volkLoadDevice, mDevice);
    }

    initializeInstanceExtensionEntryPointsFromCore();
    initializeDeviceExtensionEntryPointsFromCore();
#endif  // defined(ANGLE_SHARED_LIBVULKAN)
}

void Renderer::initializeInstanceExtensionEntryPointsFromCore() const
{
    // Initialize extension entry points from core ones.  In some cases, such as VMA, the extension
    // entry point is unconditionally used.
    InitGetPhysicalDeviceProperties2KHRFunctionsFromCore();
    if (mFeatures.supportsExternalFenceCapabilities.enabled)
    {
        InitExternalFenceCapabilitiesFunctionsFromCore();
    }
    if (mFeatures.supportsExternalSemaphoreCapabilities.enabled)
    {
        InitExternalSemaphoreCapabilitiesFunctionsFromCore();
    }
}

void Renderer::initializeDeviceExtensionEntryPointsFromCore() const
{
    if (mFeatures.supportsGetMemoryRequirements2.enabled)
    {
        InitGetMemoryRequirements2KHRFunctionsFromCore();
    }
    if (mFeatures.supportsBindMemory2.enabled)
    {
        InitBindMemory2KHRFunctionsFromCore();
    }
    if (mFeatures.supportsYUVSamplerConversion.enabled)
    {
        InitSamplerYcbcrKHRFunctionsFromCore();
    }
    if (mFeatures.supportsMaintenance5.enabled)
    {
        InitGetImageSubresourceLayoutEXTFunctionFromKHR();
    }
}

angle::Result Renderer::submitCommands(vk::ErrorContext *context,
                                       const vk::Semaphore *signalSemaphore,
                                       const vk::SharedExternalFence *externalFence,
                                       const QueueSerial &submitQueueSerial,
                                       CommandsState &&commandsState)
{
    ASSERT(signalSemaphore == nullptr || signalSemaphore->valid());
    const VkSemaphore signalVkSemaphore =
        signalSemaphore ? signalSemaphore->getHandle() : VK_NULL_HANDLE;

    vk::SharedExternalFence externalFenceCopy;
    if (externalFence != nullptr)
    {
        externalFenceCopy = *externalFence;
    }

    ANGLE_TRY(mCommandQueue.submitCommands(context, signalVkSemaphore, std::move(externalFenceCopy),
                                           submitQueueSerial, std::move(commandsState)));

    ANGLE_TRY(mCommandQueue.postSubmitCheck(context));

    return angle::Result::Continue;
}

angle::Result Renderer::insertOneOffSubmitDebugMarker(vk::ErrorContext *context,
                                                      vk::ProtectionType protectionType,
                                                      egl::ContextPriority priority,
                                                      QueueSubmitReason reason)
{
    if (!enableDebugUtils() && !angleDebuggerMode())
    {
        return angle::Result::Continue;
    }

    ScopedPrimaryCommandBuffer scopedCommandBuffer(getDevice());
    ANGLE_TRY(getCommandBufferOneOff(context, protectionType, &scopedCommandBuffer));
    PrimaryCommandBuffer &commandBuffer = scopedCommandBuffer.get();
    insertSubmitDebugMarkerInCommandBuffer(commandBuffer, reason);
    ANGLE_VK_TRY(context, commandBuffer.end());

    QueueSerial queueSerial;
    return queueSubmitOneOff(context, std::move(scopedCommandBuffer), protectionType, priority,
                             VK_NULL_HANDLE, 0, &queueSerial);
}

void Renderer::insertSubmitDebugMarkerInCommandBuffer(PrimaryCommandBuffer &commandBuffer,
                                                      QueueSubmitReason reason)
{
    if (!enableDebugUtils() && !angleDebuggerMode())
    {
        return;
    }

    VkDebugUtilsLabelEXT labelInfo;
    vk::MakeDebugUtilsLabel(GL_DEBUG_SOURCE_API, kQueueSubmitReason[reason], &labelInfo);
    commandBuffer.insertDebugUtilsLabelEXT(labelInfo);
}

angle::Result Renderer::submitPriorityDependency(vk::ErrorContext *context,
                                                 vk::ProtectionTypes protectionTypes,
                                                 egl::ContextPriority srcContextPriority,
                                                 egl::ContextPriority dstContextPriority,
                                                 SerialIndex index)
{
    RendererScoped<vk::ReleasableResource<vk::Semaphore>> semaphore(this);
    ANGLE_VK_TRY(context, semaphore.get().get().init(mDevice, VK_SEMAPHORE_TYPE_BINARY));

    // First, submit already flushed commands / wait semaphores into the source Priority VkQueue.
    // Commands that are in the Secondary Command Buffers will be flushed into the new VkQueue.

    // Submit commands and attach Signal Semaphore.
    ASSERT(protectionTypes.any());
    while (protectionTypes.any())
    {
        vk::ProtectionType protectionType = protectionTypes.first();
        protectionTypes.reset(protectionType);
        CommandsState commandsState(this, protectionType, srcContextPriority);

        QueueSerial queueSerial(index, generateQueueSerial(index));
        // Submit semaphore only if this is the last submission (all into the same VkQueue).
        const vk::Semaphore *signalSemaphore = nullptr;
        if (protectionTypes.none())
        {
            // Update QueueSerial to collect semaphore using the latest possible queueSerial.
            semaphore.get().setQueueSerial(queueSerial);
            signalSemaphore = &semaphore.get().get();
        }

        ANGLE_TRY(insertOneOffSubmitDebugMarker(context, protectionType, srcContextPriority,
                                                QueueSubmitReason::ContextPriorityChange));
        ANGLE_TRY(submitCommands(context, signalSemaphore, nullptr, queueSerial,
                                 std::move(commandsState)));
        mSubmittedResourceUse.setQueueSerial(queueSerial);
    }

    // Submit only Wait Semaphore into the destination Priority (VkQueue).
    QueueSerial queueSerial(index, generateQueueSerial(index));
    semaphore.get().setQueueSerial(queueSerial);

    ANGLE_TRY(insertOneOffSubmitDebugMarker(context, ProtectionType::Unprotected,
                                            dstContextPriority, QueueSubmitReason::WaitSemaphore));
    ANGLE_TRY(queueSubmitWaitSemaphore(context, dstContextPriority, semaphore.get().get(),
                                       VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, queueSerial));

    return angle::Result::Continue;
}

void Renderer::handleDeviceLost()
{
    mCommandQueue.handleDeviceLost(this);
}

angle::Result Renderer::finishResourceUse(vk::ErrorContext *context, const vk::ResourceUse &use)
{
    return mCommandQueue.finishResourceUse(context, use, getMaxFenceWaitTimeNs());
}

angle::Result Renderer::finishQueueSerial(vk::ErrorContext *context, const QueueSerial &queueSerial)
{
    ASSERT(queueSerial.valid());
    return mCommandQueue.finishQueueSerial(context, queueSerial, getMaxFenceWaitTimeNs());
}

angle::Result Renderer::waitForResourceUseToFinishWithUserTimeout(vk::ErrorContext *context,
                                                                  const vk::ResourceUse &use,
                                                                  uint64_t timeout,
                                                                  VkResult *result)
{
    ANGLE_TRACE_EVENT0("gpu.angle", "Renderer::waitForResourceUseToFinishWithUserTimeout");
    return mCommandQueue.waitForResourceUseToFinishWithUserTimeout(context, use, timeout, result);
}

VkResult Renderer::queuePresent(vk::ErrorContext *context,
                                egl::ContextPriority priority,
                                const VkPresentInfoKHR &presentInfo)
{
    VkResult result = mCommandQueue.queuePresent(priority, presentInfo);

    if (getFeatures().logMemoryReportStats.enabled)
    {
        mMemoryReport.logMemoryReportStats();
    }

    return result;
}

template <typename CommandBufferHelperT, typename RecyclerT>
angle::Result Renderer::getCommandBufferImpl(vk::ErrorContext *context,
                                             vk::SecondaryCommandPool *commandPool,
                                             RecyclerT *recycler,
                                             CommandBufferHelperT **commandBufferHelperOut)
{
    return recycler->getCommandBufferHelper(context, commandPool, commandBufferHelperOut);
}

angle::Result Renderer::getOutsideRenderPassCommandBufferHelper(
    vk::ErrorContext *context,
    vk::SecondaryCommandPool *commandPool,
    vk::OutsideRenderPassCommandBufferHelper **commandBufferHelperOut)
{
    ANGLE_TRACE_EVENT0("gpu.angle", "Renderer::getOutsideRenderPassCommandBufferHelper");
    return getCommandBufferImpl(context, commandPool, &mOutsideRenderPassCommandBufferRecycler,
                                commandBufferHelperOut);
}

angle::Result Renderer::getRenderPassCommandBufferHelper(
    vk::ErrorContext *context,
    vk::SecondaryCommandPool *commandPool,
    vk::RenderPassCommandBufferHelper **commandBufferHelperOut)
{
    ANGLE_TRACE_EVENT0("gpu.angle", "Renderer::getRenderPassCommandBufferHelper");
    return getCommandBufferImpl(context, commandPool, &mRenderPassCommandBufferRecycler,
                                commandBufferHelperOut);
}

void Renderer::recycleOutsideRenderPassCommandBufferHelper(
    vk::OutsideRenderPassCommandBufferHelper **commandBuffer)
{
    ANGLE_TRACE_EVENT0("gpu.angle", "Renderer::recycleOutsideRenderPassCommandBufferHelper");
    mOutsideRenderPassCommandBufferRecycler.recycleCommandBufferHelper(commandBuffer);
}

void Renderer::recycleRenderPassCommandBufferHelper(
    vk::RenderPassCommandBufferHelper **commandBuffer)
{
    ANGLE_TRACE_EVENT0("gpu.angle", "Renderer::recycleRenderPassCommandBufferHelper");
    mRenderPassCommandBufferRecycler.recycleCommandBufferHelper(commandBuffer);
}

void Renderer::logCacheStats() const
{
    if (!vk::kOutputCumulativePerfCounters)
    {
        return;
    }

    std::unique_lock<angle::SimpleMutex> localLock(mCacheStatsMutex);

    int cacheType = 0;
    INFO() << "Vulkan object cache hit ratios: ";
    for (const CacheStats &stats : mVulkanCacheStats)
    {
        INFO() << "    CacheType " << cacheType++ << ": " << stats.getHitRatio();
    }
}

angle::Result Renderer::getFormatDescriptorCountForVkFormat(vk::ErrorContext *context,
                                                            VkFormat format,
                                                            uint32_t *descriptorCountOut)
{
    if (mVkFormatDescriptorCountMap.count(format) == 0)
    {
        // Query device for descriptor count with basic values for most of
        // VkPhysicalDeviceImageFormatInfo2 members.
        VkPhysicalDeviceImageFormatInfo2 imageFormatInfo = {};
        imageFormatInfo.sType  = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2;
        imageFormatInfo.format = format;
        imageFormatInfo.type   = VK_IMAGE_TYPE_2D;
        imageFormatInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
        imageFormatInfo.usage  = VK_IMAGE_USAGE_SAMPLED_BIT;
        imageFormatInfo.flags  = 0;

        VkImageFormatProperties imageFormatProperties                            = {};
        VkSamplerYcbcrConversionImageFormatProperties ycbcrImageFormatProperties = {};
        ycbcrImageFormatProperties.sType =
            VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES;

        VkImageFormatProperties2 imageFormatProperties2 = {};
        imageFormatProperties2.sType                 = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
        imageFormatProperties2.pNext                 = &ycbcrImageFormatProperties;
        imageFormatProperties2.imageFormatProperties = imageFormatProperties;

        ANGLE_VK_TRY(context, VK_CALL(vkGetPhysicalDeviceImageFormatProperties2, mPhysicalDevice,
                                      &imageFormatInfo, &imageFormatProperties2));

        mVkFormatDescriptorCountMap[format] =
            ycbcrImageFormatProperties.combinedImageSamplerDescriptorCount;
    }

    ASSERT(descriptorCountOut);
    *descriptorCountOut = mVkFormatDescriptorCountMap[format];
    return angle::Result::Continue;
}

angle::Result Renderer::getFormatDescriptorCountForExternalFormat(vk::ErrorContext *context,
                                                                  uint64_t format,
                                                                  uint32_t *descriptorCountOut)
{
    ASSERT(descriptorCountOut);

    // TODO: need to query for external formats as well once spec is fixed.
    // http://anglebug.com/42264669
    ANGLE_VK_CHECK(context, getFeatures().useMultipleDescriptorsForExternalFormats.enabled,
                   VK_ERROR_INCOMPATIBLE_DRIVER);

    // Vulkan spec has a gap in that there is no mechanism available to query the immutable
    // sampler descriptor count of an external format. For now, return a default value.
    constexpr uint32_t kExternalFormatDefaultDescriptorCount = 4;
    *descriptorCountOut = kExternalFormatDefaultDescriptorCount;
    return angle::Result::Continue;
}

void Renderer::onAllocateHandle(vk::HandleType handleType)
{
    std::unique_lock<angle::SimpleMutex> localLock(mActiveHandleCountsMutex);
    mActiveHandleCounts.onAllocate(handleType);
}

void Renderer::onDeallocateHandle(vk::HandleType handleType, uint32_t count)
{
    std::unique_lock<angle::SimpleMutex> localLock(mActiveHandleCountsMutex);
    mActiveHandleCounts.onDeallocate(handleType, count);
}

VkDeviceSize Renderer::getPreferredInitialBufferBlockSize(uint32_t memoryTypeIndex) const
{
    // Try not to exceed 1/64 of heap size to begin with.
    const VkDeviceSize heapSize = getMemoryProperties().getHeapSizeForMemoryType(memoryTypeIndex);
    return std::min(heapSize / 64, mPreferredInitialBufferBlockSize);
}

VkDeviceSize Renderer::getPreferredLargeBufferBlockSize(uint32_t memoryTypeIndex) const
{
    // Try not to exceed 1/64 of heap size to begin with.
    const VkDeviceSize heapSize = getMemoryProperties().getHeapSizeForMemoryType(memoryTypeIndex);
    return std::min(heapSize / 64, mPreferredLargeHeapBlockSize);
}

angle::Result Renderer::allocateScopedQueueSerialIndex(vk::ScopedQueueSerialIndex *indexOut)
{
    SerialIndex index;
    ANGLE_TRY(allocateQueueSerialIndex(&index));
    indexOut->init(index, &mQueueSerialIndexAllocator);
    return angle::Result::Continue;
}

angle::Result Renderer::allocateQueueSerialIndex(SerialIndex *serialIndexOut)
{
    *serialIndexOut = mQueueSerialIndexAllocator.allocate();
    if (*serialIndexOut == kInvalidQueueSerialIndex)
    {
        return angle::Result::Stop;
    }
    return angle::Result::Continue;
}

void Renderer::releaseQueueSerialIndex(SerialIndex index)
{
    mQueueSerialIndexAllocator.release(index);
}

angle::Result Renderer::cleanupSomeGarbage(ErrorContext *context, bool *anyGarbageCleanedOut)
{
    return mCommandQueue.cleanupSomeGarbage(context, 0, anyGarbageCleanedOut);
}

void Renderer::logFeatures() const
{
    INFO() << "List of all Renderer.mFeatures:";
    for (const auto &featureInfo : mFeatures.getFeatures())
    {
        INFO() << "\tmFeatures." << featureInfo.second->name << ": " << featureInfo.second->enabled;
    }
}

// static
const char *Renderer::GetVulkanObjectTypeName(VkObjectType type)
{
    return GetVkObjectTypeName(type);
}

ImageMemorySuballocator::ImageMemorySuballocator() {}
ImageMemorySuballocator::~ImageMemorySuballocator() {}

void ImageMemorySuballocator::destroy(Renderer *renderer)
{
    const Allocator &allocator = renderer->getAllocator();
    for (auto &pool : mMemoryPools)
    {
        if (pool.valid())
        {
            pool.destroy(allocator);
        }
    }
}

VkResult ImageMemorySuballocator::allocateAndBindMemory(
    ErrorContext *context,
    Image *image,
    const VkImageCreateInfo *imageCreateInfo,
    VkMemoryPropertyFlags requiredFlags,
    VkMemoryPropertyFlags preferredFlags,
    const VkMemoryRequirements *memoryRequirements,
    const bool allocateDedicatedMemory,
    MemoryAllocationType memoryAllocationType,
    Allocation *allocationOut,
    VkMemoryPropertyFlags *memoryFlagsOut,
    uint32_t *memoryTypeIndexOut,
    VkDeviceSize *sizeOut)
{
    ASSERT(image && image->valid());
    ASSERT(allocationOut && !allocationOut->valid());
    Renderer *renderer         = context->getRenderer();
    const Allocator &allocator = renderer->getAllocator();

    // The required size must not be greater than the maximum allocation size allowed by the driver.
    if (memoryRequirements->size > renderer->getMaxMemoryAllocationSize())
    {
        renderer->getMemoryAllocationTracker()->onExceedingMaxMemoryAllocationSize(
            memoryRequirements->size);
        return VK_ERROR_OUT_OF_DEVICE_MEMORY;
    }

    // Avoid device-local and host-visible combinations if possible. Here, "preferredFlags" is
    // expected to be the same as "requiredFlags" except in the device-local bit.
    ASSERT((preferredFlags & ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) ==
           (requiredFlags & ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));

    const bool isDeviceLocalBitRequiredAndPreferred =
        (requiredFlags & preferredFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0;
    uint32_t memoryTypeBits = memoryRequirements->memoryTypeBits;
    if (isDeviceLocalBitRequiredAndPreferred)
    {
        memoryTypeBits =
            GetMemoryTypeBitsExcludingHostVisible(renderer, preferredFlags, memoryTypeBits);
    }

    // Allocate and bind memory for the image. Try allocating on the device first.
    //
    // Custom pools are used to suballocate images from a specific block size, and prevent VMA
    // from falling back to attempting dedicated allocation in case it failed to allocate a large
    // block to suballocate from.
    //
    // Dedicated allocations are only allocated on a pool if the pool's block size is set to 0.
    // Therefore, they use the default VMA pool.
    VkResult result;
    if (allocateDedicatedMemory)
    {
        result = vma::AllocateAndBindMemoryForImage(
            allocator.getHandle(), &image->mHandle, requiredFlags, preferredFlags, memoryTypeBits,
            allocateDedicatedMemory, &allocationOut->mHandle, memoryTypeIndexOut, sizeOut);
    }
    else
    {
        uint32_t poolMemoryTypeIndex;
        VK_RESULT_TRY(vma::FindMemoryTypeIndexForImageInfo(
            allocator.getHandle(), imageCreateInfo, requiredFlags, preferredFlags, memoryTypeBits,
            allocateDedicatedMemory, &poolMemoryTypeIndex));

        Pool *selectedPool;
        VK_RESULT_TRY(getMemoryPool(renderer, poolMemoryTypeIndex, &selectedPool));
        ASSERT(selectedPool != nullptr);
        result = vma::AllocateAndBindMemoryForImageFromPool(
            allocator.getHandle(), &image->mHandle, selectedPool->getHandle(),
            &allocationOut->mHandle, memoryTypeIndexOut, sizeOut);

        // In case allocation fails due to running out of device memory, but the device-local bit
        // is not required, try allocating the image memory on another pool based on the required
        // bits only.
        if (result == VK_ERROR_OUT_OF_DEVICE_MEMORY && !isDeviceLocalBitRequiredAndPreferred)
        {
            VK_RESULT_TRY(vma::FindMemoryTypeIndexForImageInfo(
                allocator.getHandle(), imageCreateInfo, requiredFlags, requiredFlags,
                memoryTypeBits, allocateDedicatedMemory, &poolMemoryTypeIndex));
            VK_RESULT_TRY(getMemoryPool(renderer, poolMemoryTypeIndex, &selectedPool));
            ASSERT(selectedPool != nullptr);
            result = vma::AllocateAndBindMemoryForImageFromPool(
                allocator.getHandle(), &image->mHandle, selectedPool->getHandle(),
                &allocationOut->mHandle, memoryTypeIndexOut, sizeOut);
        }
    }

    // We need to get the property flags of the allocated memory if successful.
    if (result == VK_SUCCESS)
    {
        *memoryFlagsOut =
            renderer->getMemoryProperties().getMemoryType(*memoryTypeIndexOut).propertyFlags;

        renderer->onMemoryAlloc(memoryAllocationType, *sizeOut, *memoryTypeIndexOut,
                                allocationOut->getHandle());
    }
    return result;
}

VkResult ImageMemorySuballocator::mapMemoryAndInitWithNonZeroValue(Renderer *renderer,
                                                                   Allocation *allocation,
                                                                   VkDeviceSize size,
                                                                   int value,
                                                                   VkMemoryPropertyFlags flags)
{
    ASSERT(allocation && allocation->valid());
    const Allocator &allocator = renderer->getAllocator();

    void *mappedMemoryData;
    VkResult result = vma::MapMemory(allocator.getHandle(), allocation->mHandle, &mappedMemoryData);
    if (result != VK_SUCCESS)
    {
        return result;
    }

    memset(mappedMemoryData, value, static_cast<size_t>(size));
    vma::UnmapMemory(allocator.getHandle(), allocation->mHandle);

    // If the memory type is not host coherent, we perform an explicit flush.
    if ((flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0)
    {
        vma::FlushAllocation(allocator.getHandle(), allocation->mHandle, 0, VK_WHOLE_SIZE);
    }

    return VK_SUCCESS;
}

VkResult ImageMemorySuballocator::getMemoryPool(Renderer *renderer,
                                                uint32_t poolMemoryTypeIndex,
                                                Pool **poolOut)
{
    Pool &pool = mMemoryPools[poolMemoryTypeIndex];
    if (!pool.valid())
    {
        VK_RESULT_TRY(pool.init(renderer->getAllocator(), poolMemoryTypeIndex,
                                renderer->getPreferredLargeHeapBlockSize()));
    }

    *poolOut = &pool;
    return VK_SUCCESS;
}

bool ImageMemorySuballocator::needsDedicatedMemory(VkDeviceSize size) const
{
    return size >= kImageSizeThresholdForDedicatedMemoryAllocation;
}

}  // namespace vk
}  // namespace rx
