// Copyright 2018 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "dawn/native/vulkan/TextureVk.h"

#include <utility>

#include "dawn/common/Assert.h"
#include "dawn/common/Math.h"
#include "dawn/native/DynamicUploader.h"
#include "dawn/native/EnumMaskIterator.h"
#include "dawn/native/Error.h"
#include "dawn/native/VulkanBackend.h"
#include "dawn/native/vulkan/AdapterVk.h"
#include "dawn/native/vulkan/BufferVk.h"
#include "dawn/native/vulkan/CommandRecordingContext.h"
#include "dawn/native/vulkan/DeviceVk.h"
#include "dawn/native/vulkan/FencedDeleter.h"
#include "dawn/native/vulkan/ResourceHeapVk.h"
#include "dawn/native/vulkan/ResourceMemoryAllocatorVk.h"
#include "dawn/native/vulkan/StagingBufferVk.h"
#include "dawn/native/vulkan/UtilsVulkan.h"
#include "dawn/native/vulkan/VulkanError.h"

namespace dawn::native::vulkan {

namespace {
// Converts an Dawn texture dimension to a Vulkan image view type.
// Contrary to image types, image view types include arrayness and cubemapness
VkImageViewType VulkanImageViewType(wgpu::TextureViewDimension dimension) {
    switch (dimension) {
        case wgpu::TextureViewDimension::e1D:
            return VK_IMAGE_VIEW_TYPE_1D;
        case wgpu::TextureViewDimension::e2D:
            return VK_IMAGE_VIEW_TYPE_2D;
        case wgpu::TextureViewDimension::e2DArray:
            return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
        case wgpu::TextureViewDimension::Cube:
            return VK_IMAGE_VIEW_TYPE_CUBE;
        case wgpu::TextureViewDimension::CubeArray:
            return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
        case wgpu::TextureViewDimension::e3D:
            return VK_IMAGE_VIEW_TYPE_3D;

        case wgpu::TextureViewDimension::Undefined:
            break;
    }
    UNREACHABLE();
}

// Computes which vulkan access type could be required for the given Dawn usage.
// TODO(crbug.com/dawn/269): We shouldn't need any access usages for srcAccessMask when
// the previous usage is readonly because an execution dependency is sufficient.
VkAccessFlags VulkanAccessFlags(wgpu::TextureUsage usage, const Format& format) {
    VkAccessFlags flags = 0;

    if (usage & wgpu::TextureUsage::CopySrc) {
        flags |= VK_ACCESS_TRANSFER_READ_BIT;
    }
    if (usage & wgpu::TextureUsage::CopyDst) {
        flags |= VK_ACCESS_TRANSFER_WRITE_BIT;
    }
    if (usage & wgpu::TextureUsage::TextureBinding) {
        flags |= VK_ACCESS_SHADER_READ_BIT;
    }
    if (usage & wgpu::TextureUsage::StorageBinding) {
        flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
    }
    if (usage & wgpu::TextureUsage::RenderAttachment) {
        if (format.HasDepthOrStencil()) {
            flags |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
                     VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
        } else {
            flags |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
        }
    }
    if (usage & kReadOnlyRenderAttachment) {
        flags |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
    }
    if (usage & kPresentTextureUsage) {
        // The present usage is only used internally by the swapchain and is never used in
        // combination with other usages.
        ASSERT(usage == kPresentTextureUsage);
        // The Vulkan spec has the following note:
        //
        //   When transitioning the image to VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR or
        //   VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, there is no need to delay subsequent
        //   processing, or perform any visibility operations (as vkQueuePresentKHR performs
        //   automatic visibility operations). To achieve this, the dstAccessMask member of
        //   the VkImageMemoryBarrier should be set to 0, and the dstStageMask parameter
        //   should be set to VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT.
        //
        // So on the transition to Present we don't need an access flag. The other
        // direction doesn't matter because swapchain textures always start a new frame
        // as uninitialized.
        flags |= 0;
    }

    return flags;
}

// Computes which Vulkan pipeline stage can access a texture in the given Dawn usage
VkPipelineStageFlags VulkanPipelineStage(wgpu::TextureUsage usage, const Format& format) {
    VkPipelineStageFlags flags = 0;

    if (usage == wgpu::TextureUsage::None) {
        // This only happens when a texture is initially created (and for srcAccessMask) in
        // which case there is no need to wait on anything to stop accessing this texture.
        return VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
    }
    if (usage & (wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst)) {
        flags |= VK_PIPELINE_STAGE_TRANSFER_BIT;
    }
    if (usage & wgpu::TextureUsage::TextureBinding) {
        // TODO(crbug.com/dawn/851): Only transition to the usage we care about to avoid
        // introducing FS -> VS dependencies that would prevent parallelization on tiler
        // GPUs
        flags |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
                 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
    }
    if (usage & wgpu::TextureUsage::StorageBinding) {
        flags |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
    }
    if (usage & (wgpu::TextureUsage::RenderAttachment | kReadOnlyRenderAttachment)) {
        if (format.HasDepthOrStencil()) {
            flags |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
                     VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
        } else {
            flags |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
        }
    }
    if (usage & kPresentTextureUsage) {
        // The present usage is only used internally by the swapchain and is never used in
        // combination with other usages.
        ASSERT(usage == kPresentTextureUsage);
        // The Vulkan spec has the following note:
        //
        //   When transitioning the image to VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR or
        //   VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, there is no need to delay subsequent
        //   processing, or perform any visibility operations (as vkQueuePresentKHR performs
        //   automatic visibility operations). To achieve this, the dstAccessMask member of
        //   the VkImageMemoryBarrier should be set to 0, and the dstStageMask parameter
        //   should be set to VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT.
        //
        // So on the transition to Present we use the "bottom of pipe" stage. The other
        // direction doesn't matter because swapchain textures always start a new frame
        // as uninitialized.
        flags |= VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
    }

    // A zero value isn't a valid pipeline stage mask
    ASSERT(flags != 0);
    return flags;
}

VkImageMemoryBarrier BuildMemoryBarrier(const Texture* texture,
                                        wgpu::TextureUsage lastUsage,
                                        wgpu::TextureUsage usage,
                                        const SubresourceRange& range) {
    VkImageMemoryBarrier barrier;
    barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
    barrier.pNext = nullptr;
    barrier.srcAccessMask = VulkanAccessFlags(lastUsage, texture->GetFormat());
    barrier.dstAccessMask = VulkanAccessFlags(usage, texture->GetFormat());
    barrier.oldLayout = VulkanImageLayout(texture, lastUsage);
    barrier.newLayout = VulkanImageLayout(texture, usage);
    barrier.image = texture->GetHandle();
    barrier.subresourceRange.aspectMask = VulkanAspectMask(range.aspects);
    barrier.subresourceRange.baseMipLevel = range.baseMipLevel;
    barrier.subresourceRange.levelCount = range.levelCount;
    barrier.subresourceRange.baseArrayLayer = range.baseArrayLayer;
    barrier.subresourceRange.layerCount = range.layerCount;

    barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
    barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
    return barrier;
}

void FillVulkanCreateInfoSizesAndType(const Texture& texture, VkImageCreateInfo* info) {
    const Extent3D& size = texture.GetSize();

    info->mipLevels = texture.GetNumMipLevels();
    info->samples = VulkanSampleCount(texture.GetSampleCount());

    // Fill in the image type, and paper over differences in how the array layer count is
    // specified between WebGPU and Vulkan.
    switch (texture.GetDimension()) {
        case wgpu::TextureDimension::e1D:
            info->imageType = VK_IMAGE_TYPE_1D;
            info->extent = {size.width, 1, 1};
            info->arrayLayers = 1;
            break;

        case wgpu::TextureDimension::e2D:
            info->imageType = VK_IMAGE_TYPE_2D;
            info->extent = {size.width, size.height, 1};
            info->arrayLayers = size.depthOrArrayLayers;
            break;

        case wgpu::TextureDimension::e3D:
            info->imageType = VK_IMAGE_TYPE_3D;
            info->extent = {size.width, size.height, size.depthOrArrayLayers};
            info->arrayLayers = 1;
            break;
    }
}

}  // namespace

// Converts Dawn texture format to Vulkan formats.
VkFormat VulkanImageFormat(const Device* device, wgpu::TextureFormat format) {
    switch (format) {
        case wgpu::TextureFormat::R8Unorm:
            return VK_FORMAT_R8_UNORM;
        case wgpu::TextureFormat::R8Snorm:
            return VK_FORMAT_R8_SNORM;
        case wgpu::TextureFormat::R8Uint:
            return VK_FORMAT_R8_UINT;
        case wgpu::TextureFormat::R8Sint:
            return VK_FORMAT_R8_SINT;

        case wgpu::TextureFormat::R16Uint:
            return VK_FORMAT_R16_UINT;
        case wgpu::TextureFormat::R16Sint:
            return VK_FORMAT_R16_SINT;
        case wgpu::TextureFormat::R16Float:
            return VK_FORMAT_R16_SFLOAT;
        case wgpu::TextureFormat::RG8Unorm:
            return VK_FORMAT_R8G8_UNORM;
        case wgpu::TextureFormat::RG8Snorm:
            return VK_FORMAT_R8G8_SNORM;
        case wgpu::TextureFormat::RG8Uint:
            return VK_FORMAT_R8G8_UINT;
        case wgpu::TextureFormat::RG8Sint:
            return VK_FORMAT_R8G8_SINT;

        case wgpu::TextureFormat::R32Uint:
            return VK_FORMAT_R32_UINT;
        case wgpu::TextureFormat::R32Sint:
            return VK_FORMAT_R32_SINT;
        case wgpu::TextureFormat::R32Float:
            return VK_FORMAT_R32_SFLOAT;
        case wgpu::TextureFormat::RG16Uint:
            return VK_FORMAT_R16G16_UINT;
        case wgpu::TextureFormat::RG16Sint:
            return VK_FORMAT_R16G16_SINT;
        case wgpu::TextureFormat::RG16Float:
            return VK_FORMAT_R16G16_SFLOAT;
        case wgpu::TextureFormat::RGBA8Unorm:
            return VK_FORMAT_R8G8B8A8_UNORM;
        case wgpu::TextureFormat::RGBA8UnormSrgb:
            return VK_FORMAT_R8G8B8A8_SRGB;
        case wgpu::TextureFormat::RGBA8Snorm:
            return VK_FORMAT_R8G8B8A8_SNORM;
        case wgpu::TextureFormat::RGBA8Uint:
            return VK_FORMAT_R8G8B8A8_UINT;
        case wgpu::TextureFormat::RGBA8Sint:
            return VK_FORMAT_R8G8B8A8_SINT;
        case wgpu::TextureFormat::BGRA8Unorm:
            return VK_FORMAT_B8G8R8A8_UNORM;
        case wgpu::TextureFormat::BGRA8UnormSrgb:
            return VK_FORMAT_B8G8R8A8_SRGB;
        case wgpu::TextureFormat::RGB10A2Unorm:
            return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
        case wgpu::TextureFormat::RG11B10Ufloat:
            return VK_FORMAT_B10G11R11_UFLOAT_PACK32;
        case wgpu::TextureFormat::RGB9E5Ufloat:
            return VK_FORMAT_E5B9G9R9_UFLOAT_PACK32;

        case wgpu::TextureFormat::RG32Uint:
            return VK_FORMAT_R32G32_UINT;
        case wgpu::TextureFormat::RG32Sint:
            return VK_FORMAT_R32G32_SINT;
        case wgpu::TextureFormat::RG32Float:
            return VK_FORMAT_R32G32_SFLOAT;
        case wgpu::TextureFormat::RGBA16Uint:
            return VK_FORMAT_R16G16B16A16_UINT;
        case wgpu::TextureFormat::RGBA16Sint:
            return VK_FORMAT_R16G16B16A16_SINT;
        case wgpu::TextureFormat::RGBA16Float:
            return VK_FORMAT_R16G16B16A16_SFLOAT;

        case wgpu::TextureFormat::RGBA32Uint:
            return VK_FORMAT_R32G32B32A32_UINT;
        case wgpu::TextureFormat::RGBA32Sint:
            return VK_FORMAT_R32G32B32A32_SINT;
        case wgpu::TextureFormat::RGBA32Float:
            return VK_FORMAT_R32G32B32A32_SFLOAT;

        case wgpu::TextureFormat::Depth16Unorm:
            return VK_FORMAT_D16_UNORM;
        case wgpu::TextureFormat::Depth32Float:
            return VK_FORMAT_D32_SFLOAT;
        case wgpu::TextureFormat::Depth24Plus:
            return VK_FORMAT_D32_SFLOAT;
        case wgpu::TextureFormat::Depth24PlusStencil8:
            // Depth24PlusStencil8 maps to either of these two formats because only requires
            // that one of the two be present. The VulkanUseD32S8 toggle combines the wish of
            // the environment, default to using D32S8, and availability information so we know
            // that the format is available.
            if (device->IsToggleEnabled(Toggle::VulkanUseD32S8)) {
                return VK_FORMAT_D32_SFLOAT_S8_UINT;
            } else {
                return VK_FORMAT_D24_UNORM_S8_UINT;
            }
        case wgpu::TextureFormat::Depth24UnormStencil8:
            return VK_FORMAT_D24_UNORM_S8_UINT;
        case wgpu::TextureFormat::Depth32FloatStencil8:
            return VK_FORMAT_D32_SFLOAT_S8_UINT;
        case wgpu::TextureFormat::Stencil8:
            // Try to use the stencil8 format if possible, otherwise use whatever format we can
            // use that contains a stencil8 component.
            if (device->IsToggleEnabled(Toggle::VulkanUseS8)) {
                return VK_FORMAT_S8_UINT;
            } else {
                return VulkanImageFormat(device, wgpu::TextureFormat::Depth24PlusStencil8);
            }

        case wgpu::TextureFormat::BC1RGBAUnorm:
            return VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
        case wgpu::TextureFormat::BC1RGBAUnormSrgb:
            return VK_FORMAT_BC1_RGBA_SRGB_BLOCK;
        case wgpu::TextureFormat::BC2RGBAUnorm:
            return VK_FORMAT_BC2_UNORM_BLOCK;
        case wgpu::TextureFormat::BC2RGBAUnormSrgb:
            return VK_FORMAT_BC2_SRGB_BLOCK;
        case wgpu::TextureFormat::BC3RGBAUnorm:
            return VK_FORMAT_BC3_UNORM_BLOCK;
        case wgpu::TextureFormat::BC3RGBAUnormSrgb:
            return VK_FORMAT_BC3_SRGB_BLOCK;
        case wgpu::TextureFormat::BC4RSnorm:
            return VK_FORMAT_BC4_SNORM_BLOCK;
        case wgpu::TextureFormat::BC4RUnorm:
            return VK_FORMAT_BC4_UNORM_BLOCK;
        case wgpu::TextureFormat::BC5RGSnorm:
            return VK_FORMAT_BC5_SNORM_BLOCK;
        case wgpu::TextureFormat::BC5RGUnorm:
            return VK_FORMAT_BC5_UNORM_BLOCK;
        case wgpu::TextureFormat::BC6HRGBFloat:
            return VK_FORMAT_BC6H_SFLOAT_BLOCK;
        case wgpu::TextureFormat::BC6HRGBUfloat:
            return VK_FORMAT_BC6H_UFLOAT_BLOCK;
        case wgpu::TextureFormat::BC7RGBAUnorm:
            return VK_FORMAT_BC7_UNORM_BLOCK;
        case wgpu::TextureFormat::BC7RGBAUnormSrgb:
            return VK_FORMAT_BC7_SRGB_BLOCK;

        case wgpu::TextureFormat::ETC2RGB8Unorm:
            return VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
        case wgpu::TextureFormat::ETC2RGB8UnormSrgb:
            return VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK;
        case wgpu::TextureFormat::ETC2RGB8A1Unorm:
            return VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
        case wgpu::TextureFormat::ETC2RGB8A1UnormSrgb:
            return VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK;
        case wgpu::TextureFormat::ETC2RGBA8Unorm:
            return VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
        case wgpu::TextureFormat::ETC2RGBA8UnormSrgb:
            return VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK;
        case wgpu::TextureFormat::EACR11Unorm:
            return VK_FORMAT_EAC_R11_UNORM_BLOCK;
        case wgpu::TextureFormat::EACR11Snorm:
            return VK_FORMAT_EAC_R11_SNORM_BLOCK;
        case wgpu::TextureFormat::EACRG11Unorm:
            return VK_FORMAT_EAC_R11G11_UNORM_BLOCK;
        case wgpu::TextureFormat::EACRG11Snorm:
            return VK_FORMAT_EAC_R11G11_SNORM_BLOCK;

        case wgpu::TextureFormat::ASTC4x4Unorm:
            return VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
        case wgpu::TextureFormat::ASTC4x4UnormSrgb:
            return VK_FORMAT_ASTC_4x4_SRGB_BLOCK;
        case wgpu::TextureFormat::ASTC5x4Unorm:
            return VK_FORMAT_ASTC_5x4_UNORM_BLOCK;
        case wgpu::TextureFormat::ASTC5x4UnormSrgb:
            return VK_FORMAT_ASTC_5x4_SRGB_BLOCK;
        case wgpu::TextureFormat::ASTC5x5Unorm:
            return VK_FORMAT_ASTC_5x5_UNORM_BLOCK;
        case wgpu::TextureFormat::ASTC5x5UnormSrgb:
            return VK_FORMAT_ASTC_5x5_SRGB_BLOCK;
        case wgpu::TextureFormat::ASTC6x5Unorm:
            return VK_FORMAT_ASTC_6x5_UNORM_BLOCK;
        case wgpu::TextureFormat::ASTC6x5UnormSrgb:
            return VK_FORMAT_ASTC_6x5_SRGB_BLOCK;
        case wgpu::TextureFormat::ASTC6x6Unorm:
            return VK_FORMAT_ASTC_6x6_UNORM_BLOCK;
        case wgpu::TextureFormat::ASTC6x6UnormSrgb:
            return VK_FORMAT_ASTC_6x6_SRGB_BLOCK;
        case wgpu::TextureFormat::ASTC8x5Unorm:
            return VK_FORMAT_ASTC_8x5_UNORM_BLOCK;
        case wgpu::TextureFormat::ASTC8x5UnormSrgb:
            return VK_FORMAT_ASTC_8x5_SRGB_BLOCK;
        case wgpu::TextureFormat::ASTC8x6Unorm:
            return VK_FORMAT_ASTC_8x6_UNORM_BLOCK;
        case wgpu::TextureFormat::ASTC8x6UnormSrgb:
            return VK_FORMAT_ASTC_8x6_SRGB_BLOCK;
        case wgpu::TextureFormat::ASTC8x8Unorm:
            return VK_FORMAT_ASTC_8x8_UNORM_BLOCK;
        case wgpu::TextureFormat::ASTC8x8UnormSrgb:
            return VK_FORMAT_ASTC_8x8_SRGB_BLOCK;
        case wgpu::TextureFormat::ASTC10x5Unorm:
            return VK_FORMAT_ASTC_10x5_UNORM_BLOCK;
        case wgpu::TextureFormat::ASTC10x5UnormSrgb:
            return VK_FORMAT_ASTC_10x5_SRGB_BLOCK;
        case wgpu::TextureFormat::ASTC10x6Unorm:
            return VK_FORMAT_ASTC_10x6_UNORM_BLOCK;
        case wgpu::TextureFormat::ASTC10x6UnormSrgb:
            return VK_FORMAT_ASTC_10x6_SRGB_BLOCK;
        case wgpu::TextureFormat::ASTC10x8Unorm:
            return VK_FORMAT_ASTC_10x8_UNORM_BLOCK;
        case wgpu::TextureFormat::ASTC10x8UnormSrgb:
            return VK_FORMAT_ASTC_10x8_SRGB_BLOCK;
        case wgpu::TextureFormat::ASTC10x10Unorm:
            return VK_FORMAT_ASTC_10x10_UNORM_BLOCK;
        case wgpu::TextureFormat::ASTC10x10UnormSrgb:
            return VK_FORMAT_ASTC_10x10_SRGB_BLOCK;
        case wgpu::TextureFormat::ASTC12x10Unorm:
            return VK_FORMAT_ASTC_12x10_UNORM_BLOCK;
        case wgpu::TextureFormat::ASTC12x10UnormSrgb:
            return VK_FORMAT_ASTC_12x10_SRGB_BLOCK;
        case wgpu::TextureFormat::ASTC12x12Unorm:
            return VK_FORMAT_ASTC_12x12_UNORM_BLOCK;
        case wgpu::TextureFormat::ASTC12x12UnormSrgb:
            return VK_FORMAT_ASTC_12x12_SRGB_BLOCK;

        case wgpu::TextureFormat::R8BG8Biplanar420Unorm:
            return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;

        case wgpu::TextureFormat::Undefined:
            break;
    }
    UNREACHABLE();
}

// Converts the Dawn usage flags to Vulkan usage flags. Also needs the format to choose
// between color and depth attachment usages.
VkImageUsageFlags VulkanImageUsage(wgpu::TextureUsage usage, const Format& format) {
    VkImageUsageFlags flags = 0;

    if (usage & wgpu::TextureUsage::CopySrc) {
        flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
    }
    if (usage & wgpu::TextureUsage::CopyDst) {
        flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
    }
    if (usage & wgpu::TextureUsage::TextureBinding) {
        flags |= VK_IMAGE_USAGE_SAMPLED_BIT;
        // If the sampled texture is a depth/stencil texture, its image layout will be set
        // to DEPTH_STENCIL_READ_ONLY_OPTIMAL in order to support readonly depth/stencil
        // attachment. That layout requires DEPTH_STENCIL_ATTACHMENT_BIT image usage.
        if (format.HasDepthOrStencil() && format.isRenderable) {
            flags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
        }
    }
    if (usage & wgpu::TextureUsage::StorageBinding) {
        flags |= VK_IMAGE_USAGE_STORAGE_BIT;
    }
    if (usage & wgpu::TextureUsage::RenderAttachment) {
        if (format.HasDepthOrStencil()) {
            flags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
        } else {
            flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
        }
    }
    if (usage & kReadOnlyRenderAttachment) {
        flags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
    }

    return flags;
}

// Chooses which Vulkan image layout should be used for the given Dawn usage. Note that this
// layout must match the layout given to various Vulkan operations as well as the layout given
// to descriptor set writes.
VkImageLayout VulkanImageLayout(const Texture* texture, wgpu::TextureUsage usage) {
    if (usage == wgpu::TextureUsage::None) {
        return VK_IMAGE_LAYOUT_UNDEFINED;
    }

    if (!wgpu::HasZeroOrOneBits(usage)) {
        // Sampled | kReadOnlyRenderAttachment is the only possible multi-bit usage, if more
        // appear we might need additional special-casing.
        ASSERT(usage == (wgpu::TextureUsage::TextureBinding | kReadOnlyRenderAttachment));

        // WebGPU requires both aspects to be readonly if the attachment's format does have
        // both depth and stencil aspects. Vulkan 1.0 supports readonly for both aspects too
        // via DEPTH_STENCIL_READ_ONLY image layout. Vulkan 1.1 and above can support separate
        // readonly for a single aspect via DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL and
        // DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL layouts. But Vulkan 1.0 cannot support
        // it, and WebGPU doesn't need that currently.
        return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
    }

    // Usage has a single bit so we can switch on its value directly.
    switch (usage) {
        case wgpu::TextureUsage::CopyDst:
            return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;

            // The layout returned here is the one that will be used at bindgroup creation time.
            // The bindgrpup's layout must match the runtime layout of the image when it is
            // used via the bindgroup, but we don't know exactly what it will be yet. So we
            // have to prepare for the pessimistic case.
        case wgpu::TextureUsage::TextureBinding:
            // Only VK_IMAGE_LAYOUT_GENERAL can do sampling and storage access of texture at the
            // same time.
            if (texture->GetInternalUsage() & wgpu::TextureUsage::StorageBinding) {
                return VK_IMAGE_LAYOUT_GENERAL;
            }
            // The sampled image can be used as a readonly depth/stencil attachment at the same
            // time if it is a depth/stencil renderable format, so the image layout need to be
            // VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL.
            if (texture->GetFormat().HasDepthOrStencil() && texture->GetFormat().isRenderable) {
                return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
            }
            return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;

            // Vulkan texture copy functions require the image to be in _one_  known layout.
            // Depending on whether parts of the texture have been transitioned to only CopySrc
            // or a combination with something else, the texture could be in a combination of
            // GENERAL and TRANSFER_SRC_OPTIMAL. This would be a problem, so we make CopySrc use
            // GENERAL.
            // TODO(crbug.com/dawn/851): We no longer need to transition resources all at
            // once and can instead track subresources so we should lift this limitation.
        case wgpu::TextureUsage::CopySrc:
            // Read-only and write-only storage textures must use general layout because load
            // and store operations on storage images can only be done on the images in
            // VK_IMAGE_LAYOUT_GENERAL layout.
        case wgpu::TextureUsage::StorageBinding:
            return VK_IMAGE_LAYOUT_GENERAL;

        case wgpu::TextureUsage::RenderAttachment:
            if (texture->GetFormat().HasDepthOrStencil()) {
                return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
            } else {
                return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
            }

        case kReadOnlyRenderAttachment:
            return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;

        case kPresentTextureUsage:
            return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;

        case wgpu::TextureUsage::None:
            break;
    }
    UNREACHABLE();
}

VkSampleCountFlagBits VulkanSampleCount(uint32_t sampleCount) {
    switch (sampleCount) {
        case 1:
            return VK_SAMPLE_COUNT_1_BIT;
        case 4:
            return VK_SAMPLE_COUNT_4_BIT;
    }
    UNREACHABLE();
}

MaybeError ValidateVulkanImageCanBeWrapped(const DeviceBase*, const TextureDescriptor* descriptor) {
    DAWN_INVALID_IF(descriptor->dimension != wgpu::TextureDimension::e2D,
                    "Texture dimension (%s) is not %s.", descriptor->dimension,
                    wgpu::TextureDimension::e2D);

    DAWN_INVALID_IF(descriptor->mipLevelCount != 1, "Mip level count (%u) is not 1.",
                    descriptor->mipLevelCount);

    DAWN_INVALID_IF(descriptor->size.depthOrArrayLayers != 1, "Array layer count (%u) is not 1.",
                    descriptor->size.depthOrArrayLayers);

    DAWN_INVALID_IF(descriptor->sampleCount != 1, "Sample count (%u) is not 1.",
                    descriptor->sampleCount);

    return {};
}

bool IsSampleCountSupported(const dawn::native::vulkan::Device* device,
                            const VkImageCreateInfo& imageCreateInfo) {
    ASSERT(device);

    VkPhysicalDevice physicalDevice = ToBackend(device->GetAdapter())->GetPhysicalDevice();
    VkImageFormatProperties properties;
    if (device->fn.GetPhysicalDeviceImageFormatProperties(
            physicalDevice, imageCreateInfo.format, imageCreateInfo.imageType,
            imageCreateInfo.tiling, imageCreateInfo.usage, imageCreateInfo.flags,
            &properties) != VK_SUCCESS) {
        UNREACHABLE();
    }

    return properties.sampleCounts & imageCreateInfo.samples;
}

// static
ResultOrError<Ref<Texture>> Texture::Create(Device* device,
                                            const TextureDescriptor* descriptor,
                                            VkImageUsageFlags extraUsages) {
    Ref<Texture> texture = AcquireRef(new Texture(device, descriptor, TextureState::OwnedInternal));
    DAWN_TRY(texture->InitializeAsInternalTexture(extraUsages));
    return std::move(texture);
}

// static
ResultOrError<Texture*> Texture::CreateFromExternal(
    Device* device,
    const ExternalImageDescriptorVk* descriptor,
    const TextureDescriptor* textureDescriptor,
    external_memory::Service* externalMemoryService) {
    Ref<Texture> texture =
        AcquireRef(new Texture(device, textureDescriptor, TextureState::OwnedInternal));
    DAWN_TRY(texture->InitializeFromExternal(descriptor, externalMemoryService));
    return texture.Detach();
}

// static
Ref<Texture> Texture::CreateForSwapChain(Device* device,
                                         const TextureDescriptor* descriptor,
                                         VkImage nativeImage) {
    Ref<Texture> texture = AcquireRef(new Texture(device, descriptor, TextureState::OwnedExternal));
    texture->InitializeForSwapChain(nativeImage);
    return texture;
}

Texture::Texture(Device* device, const TextureDescriptor* descriptor, TextureState state)
    : TextureBase(device, descriptor, state),
      // A usage of none will make sure the texture is transitioned before its first use as
      // required by the Vulkan spec.
      mSubresourceLastUsages(std::make_unique<SubresourceStorage<wgpu::TextureUsage>>(
          (ShouldCombineDepthStencilBarriers() ? Aspect::CombinedDepthStencil
                                               : GetFormat().aspects),
          GetArrayLayers(),
          GetNumMipLevels(),
          wgpu::TextureUsage::None)) {}

MaybeError Texture::InitializeAsInternalTexture(VkImageUsageFlags extraUsages) {
    Device* device = ToBackend(GetDevice());

    // Create the Vulkan image "container". We don't need to check that the format supports the
    // combination of sample, usage etc. because validation should have been done in the Dawn
    // frontend already based on the minimum supported formats in the Vulkan spec
    VkImageCreateInfo createInfo = {};
    FillVulkanCreateInfoSizesAndType(*this, &createInfo);

    PNextChainBuilder createInfoChain(&createInfo);

    createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
    createInfo.format = VulkanImageFormat(device, GetFormat().format);
    createInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
    createInfo.usage = VulkanImageUsage(GetInternalUsage(), GetFormat()) | extraUsages;
    createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
    createInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;

    VkImageFormatListCreateInfo imageFormatListInfo = {};
    std::vector<VkFormat> viewFormats;
    if (GetViewFormats().any()) {
        createInfo.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
        if (device->GetDeviceInfo().HasExt(DeviceExt::ImageFormatList)) {
            createInfoChain.Add(&imageFormatListInfo,
                                VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO);
            viewFormats.push_back(VulkanImageFormat(device, GetFormat().format));
            for (FormatIndex i : IterateBitSet(GetViewFormats())) {
                const Format& viewFormat = device->GetValidInternalFormat(i);
                viewFormats.push_back(VulkanImageFormat(device, viewFormat.format));
            }

            imageFormatListInfo.viewFormatCount = viewFormats.size();
            imageFormatListInfo.pViewFormats = viewFormats.data();
        }
    }

    ASSERT(IsSampleCountSupported(device, createInfo));

    if (GetArrayLayers() >= 6 && GetWidth() == GetHeight()) {
        createInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
    }

    // We always set VK_IMAGE_USAGE_TRANSFER_DST_BIT unconditionally beause the Vulkan images
    // that are used in vkCmdClearColorImage() must have been created with this flag, which is
    // also required for the implementation of robust resource initialization.
    createInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;

    DAWN_TRY(CheckVkSuccess(
        device->fn.CreateImage(device->GetVkDevice(), &createInfo, nullptr, &*mHandle),
        "CreateImage"));

    // Create the image memory and associate it with the container
    VkMemoryRequirements requirements;
    device->fn.GetImageMemoryRequirements(device->GetVkDevice(), mHandle, &requirements);

    DAWN_TRY_ASSIGN(mMemoryAllocation, device->GetResourceMemoryAllocator()->Allocate(
                                           requirements, MemoryKind::Opaque));

    DAWN_TRY(CheckVkSuccess(
        device->fn.BindImageMemory(device->GetVkDevice(), mHandle,
                                   ToBackend(mMemoryAllocation.GetResourceHeap())->GetMemory(),
                                   mMemoryAllocation.GetOffset()),
        "BindImageMemory"));

    if (device->IsToggleEnabled(Toggle::NonzeroClearResourcesOnCreationForTesting)) {
        DAWN_TRY(ClearTexture(ToBackend(GetDevice())->GetPendingRecordingContext(),
                              GetAllSubresources(), TextureBase::ClearValue::NonZero));
    }

    SetLabelImpl();

    return {};
}

// Internally managed, but imported from external handle
MaybeError Texture::InitializeFromExternal(const ExternalImageDescriptorVk* descriptor,
                                           external_memory::Service* externalMemoryService) {
    Device* device = ToBackend(GetDevice());
    VkFormat format = VulkanImageFormat(device, GetFormat().format);
    VkImageUsageFlags usage = VulkanImageUsage(GetInternalUsage(), GetFormat());
    DAWN_INVALID_IF(!externalMemoryService->SupportsCreateImage(descriptor, format, usage,
                                                                &mSupportsDisjointVkImage),
                    "Creating an image from external memory is not supported.");
    // mSubresourceLastUsages was initialized with Plane0/Plane1 in the constructor for
    // multiplanar formats, so we need to correct it to Color here.
    if (ShouldCombineMultiPlaneBarriers()) {
        mSubresourceLastUsages = std::make_unique<SubresourceStorage<wgpu::TextureUsage>>(
            ComputeAspectsForSubresourceStorage(), GetArrayLayers(), GetNumMipLevels(),
            wgpu::TextureUsage::None);
    }

    mExternalState = ExternalState::PendingAcquire;

    mPendingAcquireOldLayout = descriptor->releasedOldLayout;
    mPendingAcquireNewLayout = descriptor->releasedNewLayout;

    VkImageCreateInfo baseCreateInfo = {};
    FillVulkanCreateInfoSizesAndType(*this, &baseCreateInfo);

    PNextChainBuilder createInfoChain(&baseCreateInfo);

    baseCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
    baseCreateInfo.format = format;
    baseCreateInfo.usage = usage;
    baseCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
    baseCreateInfo.queueFamilyIndexCount = 0;
    baseCreateInfo.pQueueFamilyIndices = nullptr;

    // We always set VK_IMAGE_USAGE_TRANSFER_DST_BIT unconditionally beause the Vulkan images
    // that are used in vkCmdClearColorImage() must have been created with this flag, which is
    // also required for the implementation of robust resource initialization.
    baseCreateInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;

    VkImageFormatListCreateInfo imageFormatListInfo = {};
    std::vector<VkFormat> viewFormats;
    if (GetViewFormats().any()) {
        baseCreateInfo.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
        if (device->GetDeviceInfo().HasExt(DeviceExt::ImageFormatList)) {
            createInfoChain.Add(&imageFormatListInfo,
                                VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO);
            for (FormatIndex i : IterateBitSet(GetViewFormats())) {
                const Format& viewFormat = device->GetValidInternalFormat(i);
                viewFormats.push_back(VulkanImageFormat(device, viewFormat.format));
            }

            imageFormatListInfo.viewFormatCount = viewFormats.size();
            imageFormatListInfo.pViewFormats = viewFormats.data();
        }
    }

    DAWN_TRY_ASSIGN(mHandle, externalMemoryService->CreateImage(descriptor, baseCreateInfo));

    SetLabelHelper("Dawn_ExternalTexture");

    return {};
}

void Texture::InitializeForSwapChain(VkImage nativeImage) {
    mHandle = nativeImage;
    SetLabelHelper("Dawn_SwapChainTexture");
}

MaybeError Texture::BindExternalMemory(const ExternalImageDescriptorVk* descriptor,
                                       VkSemaphore signalSemaphore,
                                       VkDeviceMemory externalMemoryAllocation,
                                       std::vector<VkSemaphore> waitSemaphores) {
    Device* device = ToBackend(GetDevice());
    DAWN_TRY(CheckVkSuccess(
        device->fn.BindImageMemory(device->GetVkDevice(), mHandle, externalMemoryAllocation, 0),
        "BindImageMemory (external)"));

    // Don't clear imported texture if already initialized
    if (descriptor->isInitialized) {
        SetIsSubresourceContentInitialized(true, GetAllSubresources());
    }

    // Success, acquire all the external objects.
    mExternalAllocation = externalMemoryAllocation;
    mSignalSemaphore = signalSemaphore;
    mWaitRequirements = std::move(waitSemaphores);
    return {};
}

MaybeError Texture::ExportExternalTexture(VkImageLayout desiredLayout,
                                          VkSemaphore* signalSemaphore,
                                          VkImageLayout* releasedOldLayout,
                                          VkImageLayout* releasedNewLayout) {
    Device* device = ToBackend(GetDevice());

    DAWN_INVALID_IF(mExternalState == ExternalState::Released,
                    "Can't export a signal semaphore from signaled texture %s.", this);

    DAWN_INVALID_IF(mExternalAllocation == VK_NULL_HANDLE,
                    "Can't export a signal semaphore from destroyed or non-external texture %s.",
                    this);

    ASSERT(mSignalSemaphore != VK_NULL_HANDLE);

    // Release the texture
    mExternalState = ExternalState::Released;

    Aspect aspects = ComputeAspectsForSubresourceStorage();
    ASSERT(GetNumMipLevels() == 1 && GetArrayLayers() == 1);
    wgpu::TextureUsage usage = mSubresourceLastUsages->Get(aspects, 0, 0);

    VkImageMemoryBarrier barrier;
    barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
    barrier.pNext = nullptr;
    barrier.image = GetHandle();
    barrier.subresourceRange.aspectMask = VulkanAspectMask(aspects);
    barrier.subresourceRange.baseMipLevel = 0;
    barrier.subresourceRange.levelCount = 1;
    barrier.subresourceRange.baseArrayLayer = 0;
    barrier.subresourceRange.layerCount = 1;

    barrier.srcAccessMask = VulkanAccessFlags(usage, GetFormat());
    barrier.dstAccessMask = 0;  // The barrier must be paired with another barrier that will
                                // specify the dst access mask on the importing queue.

    barrier.oldLayout = VulkanImageLayout(this, usage);
    if (desiredLayout == VK_IMAGE_LAYOUT_UNDEFINED) {
        // VK_IMAGE_LAYOUT_UNDEFINED is invalid here. We use it as a
        // special value to indicate no layout transition should be done.
        barrier.newLayout = barrier.oldLayout;
    } else {
        barrier.newLayout = desiredLayout;
    }

    barrier.srcQueueFamilyIndex = device->GetGraphicsQueueFamily();
    barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_EXTERNAL_KHR;

    VkPipelineStageFlags srcStages = VulkanPipelineStage(usage, GetFormat());
    VkPipelineStageFlags dstStages =
        VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;  // We don't know when the importing queue will need
                                            // the texture, so pass
                                            // VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT to ensure
                                            // the barrier happens-before any usage in the
                                            // importing queue.

    CommandRecordingContext* recordingContext = device->GetPendingRecordingContext();
    device->fn.CmdPipelineBarrier(recordingContext->commandBuffer, srcStages, dstStages, 0, 0,
                                  nullptr, 0, nullptr, 1, &barrier);

    // Queue submit to signal we are done with the texture
    recordingContext->signalSemaphores.push_back(mSignalSemaphore);
    DAWN_TRY(device->SubmitPendingCommands());

    // Write out the layouts and signal semaphore
    *releasedOldLayout = barrier.oldLayout;
    *releasedNewLayout = barrier.newLayout;
    *signalSemaphore = mSignalSemaphore;

    mSignalSemaphore = VK_NULL_HANDLE;

    // Destroy the texture so it can't be used again
    Destroy();
    return {};
}

Texture::~Texture() {}

void Texture::SetLabelHelper(const char* prefix) {
    SetDebugName(ToBackend(GetDevice()), mHandle, prefix, GetLabel());
}

void Texture::SetLabelImpl() {
    SetLabelHelper("Dawn_InternalTexture");
}

void Texture::DestroyImpl() {
    if (GetTextureState() == TextureState::OwnedInternal) {
        Device* device = ToBackend(GetDevice());

        // For textures created from a VkImage, the allocation if kInvalid so the Device knows
        // to skip the deallocation of the (absence of) VkDeviceMemory.
        device->GetResourceMemoryAllocator()->Deallocate(&mMemoryAllocation);

        if (mHandle != VK_NULL_HANDLE) {
            device->GetFencedDeleter()->DeleteWhenUnused(mHandle);
        }

        if (mExternalAllocation != VK_NULL_HANDLE) {
            device->GetFencedDeleter()->DeleteWhenUnused(mExternalAllocation);
        }

        mHandle = VK_NULL_HANDLE;
        mExternalAllocation = VK_NULL_HANDLE;
        // If a signal semaphore exists it should be requested before we delete the texture
        ASSERT(mSignalSemaphore == VK_NULL_HANDLE);
    }
    // For Vulkan, we currently run the base destruction code after the internal changes because
    // of the dependency on the texture state which the base code overwrites too early.
    TextureBase::DestroyImpl();
}

VkImage Texture::GetHandle() const {
    return mHandle;
}

void Texture::TweakTransitionForExternalUsage(CommandRecordingContext* recordingContext,
                                              std::vector<VkImageMemoryBarrier>* barriers,
                                              size_t transitionBarrierStart) {
    ASSERT(GetNumMipLevels() == 1 && GetArrayLayers() == 1);

    // transitionBarrierStart specify the index where barriers for current transition start in
    // the vector. barriers->size() - transitionBarrierStart is the number of barriers that we
    // have already added into the vector during current transition.
    ASSERT(barriers->size() - transitionBarrierStart <= 1);

    if (mExternalState == ExternalState::PendingAcquire) {
        if (barriers->size() == transitionBarrierStart) {
            barriers->push_back(BuildMemoryBarrier(
                this, wgpu::TextureUsage::None, wgpu::TextureUsage::None,
                SubresourceRange::SingleMipAndLayer(0, 0, ComputeAspectsForSubresourceStorage())));
        }

        VkImageMemoryBarrier* barrier = &(*barriers)[transitionBarrierStart];
        // Transfer texture from external queue to graphics queue
        barrier->srcQueueFamilyIndex = VK_QUEUE_FAMILY_EXTERNAL_KHR;
        barrier->dstQueueFamilyIndex = ToBackend(GetDevice())->GetGraphicsQueueFamily();

        // srcAccessMask means nothing when importing. Queue transfers require a barrier on
        // both the importing and exporting queues. The exporting queue should have specified
        // this.
        barrier->srcAccessMask = 0;

        // This should be the first barrier after import.
        ASSERT(barrier->oldLayout == VK_IMAGE_LAYOUT_UNDEFINED);

        // Save the desired layout. We may need to transition through an intermediate
        // |mPendingAcquireLayout| first.
        VkImageLayout desiredLayout = barrier->newLayout;

        bool isInitialized = IsSubresourceContentInitialized(GetAllSubresources());

        // We don't care about the pending old layout if the texture is uninitialized. The
        // driver is free to discard it. Also it is invalid to transition to layout UNDEFINED or
        // PREINITIALIZED. If the embedder provided no new layout, or we don't care about the
        // previous contents, we can skip the layout transition.
        // https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkImageMemoryBarrier-newLayout-01198
        if (!isInitialized || mPendingAcquireNewLayout == VK_IMAGE_LAYOUT_UNDEFINED ||
            mPendingAcquireNewLayout == VK_IMAGE_LAYOUT_PREINITIALIZED) {
            barrier->oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
            barrier->newLayout = desiredLayout;
        } else {
            barrier->oldLayout = mPendingAcquireOldLayout;
            barrier->newLayout = mPendingAcquireNewLayout;
        }

        // If these are unequal, we need an another barrier to transition the layout.
        if (barrier->newLayout != desiredLayout) {
            VkImageMemoryBarrier layoutBarrier;
            layoutBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
            layoutBarrier.pNext = nullptr;
            layoutBarrier.image = GetHandle();
            layoutBarrier.subresourceRange = barrier->subresourceRange;

            // Transition from the acquired new layout to the desired layout.
            layoutBarrier.oldLayout = barrier->newLayout;
            layoutBarrier.newLayout = desiredLayout;

            // We already transitioned these.
            layoutBarrier.srcAccessMask = 0;
            layoutBarrier.dstAccessMask = 0;
            layoutBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
            layoutBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;

            barriers->push_back(layoutBarrier);
        }

        mExternalState = ExternalState::Acquired;
    }

    mLastExternalState = mExternalState;

    recordingContext->waitSemaphores.insert(recordingContext->waitSemaphores.end(),
                                            mWaitRequirements.begin(), mWaitRequirements.end());
    mWaitRequirements.clear();
}

bool Texture::CanReuseWithoutBarrier(wgpu::TextureUsage lastUsage, wgpu::TextureUsage usage) {
    // Reuse the texture directly and avoid encoding barriers when it isn't needed.
    bool lastReadOnly = IsSubset(lastUsage, kReadOnlyTextureUsages);
    if (lastReadOnly && lastUsage == usage && mLastExternalState == mExternalState) {
        return true;
    }
    return false;
}

// Base Vulkan doesn't support transitioning depth and stencil separately. We work around
// this limitation by combining the usages in the two planes of `textureUsages` into a
// single plane in a new SubresourceStorage<TextureUsage>. The barriers will be produced
// for DEPTH | STENCIL since the SubresourceRange uses Aspect::CombinedDepthStencil.
bool Texture::ShouldCombineDepthStencilBarriers() const {
    // If the Stencil8 format is being emulated then memory barriers also need to include
    // the depth aspect. (See: crbug.com/dawn/1331)
    if (GetFormat().format == wgpu::TextureFormat::Stencil8 &&
        !GetDevice()->IsToggleEnabled(Toggle::VulkanUseS8)) {
        return true;
    }
    return GetFormat().aspects == (Aspect::Depth | Aspect::Stencil);
}

// The Vulkan spec requires:
// "If image has a single-plane color format or is not disjoint, then the aspectMask member of
// subresourceRange must be VK_IMAGE_ASPECT_COLOR_BIT.".
// For multi-planar formats, we currently only support import them in non-disjoint way.
bool Texture::ShouldCombineMultiPlaneBarriers() const {
    // TODO(chromium:1258986): Figure out how to support disjoint vkImage.
    ASSERT(!mSupportsDisjointVkImage);
    return GetFormat().aspects == (Aspect::Plane0 | Aspect::Plane1);
}

Aspect Texture::ComputeAspectsForSubresourceStorage() const {
    if (ShouldCombineDepthStencilBarriers()) {
        return Aspect::CombinedDepthStencil;
    }
    // Force to use Aspect::Color for Aspect::Plane0/1.
    if (ShouldCombineMultiPlaneBarriers()) {
        return Aspect::Color;
    }
    return GetFormat().aspects;
}

void Texture::TransitionUsageForPass(CommandRecordingContext* recordingContext,
                                     const TextureSubresourceUsage& textureUsages,
                                     std::vector<VkImageMemoryBarrier>* imageBarriers,
                                     VkPipelineStageFlags* srcStages,
                                     VkPipelineStageFlags* dstStages) {
    if (ShouldCombineBarriers()) {
        Aspect combinedAspect = ComputeAspectsForSubresourceStorage();
        SubresourceStorage<wgpu::TextureUsage> combinedUsages(combinedAspect, GetArrayLayers(),
                                                              GetNumMipLevels());
        textureUsages.Iterate([&](const SubresourceRange& range, wgpu::TextureUsage usage) {
            SubresourceRange updateRange = range;
            updateRange.aspects = combinedAspect;

            combinedUsages.Update(updateRange,
                                  [&](const SubresourceRange&, wgpu::TextureUsage* combinedUsage) {
                                      *combinedUsage |= usage;
                                  });
        });

        TransitionUsageForPassImpl(recordingContext, combinedUsages, imageBarriers, srcStages,
                                   dstStages);
    } else {
        TransitionUsageForPassImpl(recordingContext, textureUsages, imageBarriers, srcStages,
                                   dstStages);
    }
}

void Texture::TransitionUsageForPassImpl(
    CommandRecordingContext* recordingContext,
    const SubresourceStorage<wgpu::TextureUsage>& subresourceUsages,
    std::vector<VkImageMemoryBarrier>* imageBarriers,
    VkPipelineStageFlags* srcStages,
    VkPipelineStageFlags* dstStages) {
    size_t transitionBarrierStart = imageBarriers->size();
    const Format& format = GetFormat();

    wgpu::TextureUsage allUsages = wgpu::TextureUsage::None;
    wgpu::TextureUsage allLastUsages = wgpu::TextureUsage::None;

    mSubresourceLastUsages->Merge(subresourceUsages, [&](const SubresourceRange& range,
                                                         wgpu::TextureUsage* lastUsage,
                                                         const wgpu::TextureUsage& newUsage) {
        if (newUsage == wgpu::TextureUsage::None || CanReuseWithoutBarrier(*lastUsage, newUsage)) {
            return;
        }

        imageBarriers->push_back(BuildMemoryBarrier(this, *lastUsage, newUsage, range));

        allLastUsages |= *lastUsage;
        allUsages |= newUsage;

        *lastUsage = newUsage;
    });

    if (mExternalState != ExternalState::InternalOnly) {
        TweakTransitionForExternalUsage(recordingContext, imageBarriers, transitionBarrierStart);
    }

    *srcStages |= VulkanPipelineStage(allLastUsages, format);
    *dstStages |= VulkanPipelineStage(allUsages, format);
}

void Texture::TransitionUsageNow(CommandRecordingContext* recordingContext,
                                 wgpu::TextureUsage usage,
                                 const SubresourceRange& range) {
    std::vector<VkImageMemoryBarrier> barriers;

    VkPipelineStageFlags srcStages = 0;
    VkPipelineStageFlags dstStages = 0;

    TransitionUsageAndGetResourceBarrier(usage, range, &barriers, &srcStages, &dstStages);

    if (mExternalState != ExternalState::InternalOnly) {
        TweakTransitionForExternalUsage(recordingContext, &barriers, 0);
    }

    if (!barriers.empty()) {
        ASSERT(srcStages != 0 && dstStages != 0);
        ToBackend(GetDevice())
            ->fn.CmdPipelineBarrier(recordingContext->commandBuffer, srcStages, dstStages, 0, 0,
                                    nullptr, 0, nullptr, barriers.size(), barriers.data());
    }
}

void Texture::TransitionUsageAndGetResourceBarrier(wgpu::TextureUsage usage,
                                                   const SubresourceRange& range,
                                                   std::vector<VkImageMemoryBarrier>* imageBarriers,
                                                   VkPipelineStageFlags* srcStages,
                                                   VkPipelineStageFlags* dstStages) {
    if (ShouldCombineBarriers()) {
        SubresourceRange updatedRange = range;
        updatedRange.aspects = ComputeAspectsForSubresourceStorage();
        TransitionUsageAndGetResourceBarrierImpl(usage, updatedRange, imageBarriers, srcStages,
                                                 dstStages);
    } else {
        TransitionUsageAndGetResourceBarrierImpl(usage, range, imageBarriers, srcStages, dstStages);
    }
}

void Texture::TransitionUsageAndGetResourceBarrierImpl(
    wgpu::TextureUsage usage,
    const SubresourceRange& range,
    std::vector<VkImageMemoryBarrier>* imageBarriers,
    VkPipelineStageFlags* srcStages,
    VkPipelineStageFlags* dstStages) {
    ASSERT(imageBarriers != nullptr);
    const Format& format = GetFormat();

    wgpu::TextureUsage allLastUsages = wgpu::TextureUsage::None;
    mSubresourceLastUsages->Update(
        range, [&](const SubresourceRange& range, wgpu::TextureUsage* lastUsage) {
            if (CanReuseWithoutBarrier(*lastUsage, usage)) {
                return;
            }

            imageBarriers->push_back(BuildMemoryBarrier(this, *lastUsage, usage, range));

            allLastUsages |= *lastUsage;
            *lastUsage = usage;
        });

    *srcStages |= VulkanPipelineStage(allLastUsages, format);
    *dstStages |= VulkanPipelineStage(usage, format);
}

MaybeError Texture::ClearTexture(CommandRecordingContext* recordingContext,
                                 const SubresourceRange& range,
                                 TextureBase::ClearValue clearValue) {
    Device* device = ToBackend(GetDevice());

    const bool isZero = clearValue == TextureBase::ClearValue::Zero;
    uint32_t uClearColor = isZero ? 0 : 1;
    int32_t sClearColor = isZero ? 0 : 1;
    float fClearColor = isZero ? 0.f : 1.f;

    TransitionUsageNow(recordingContext, wgpu::TextureUsage::CopyDst, range);

    VkImageSubresourceRange imageRange = {};
    imageRange.levelCount = 1;
    imageRange.layerCount = 1;

    if (GetFormat().isCompressed) {
        if (range.aspects == Aspect::None) {
            return {};
        }
        // need to clear the texture with a copy from buffer
        ASSERT(range.aspects == Aspect::Color);
        const TexelBlockInfo& blockInfo = GetFormat().GetAspectInfo(range.aspects).block;

        Extent3D largestMipSize = GetMipLevelPhysicalSize(range.baseMipLevel);

        uint32_t bytesPerRow = Align((largestMipSize.width / blockInfo.width) * blockInfo.byteSize,
                                     device->GetOptimalBytesPerRowAlignment());
        uint64_t bufferSize = bytesPerRow * (largestMipSize.height / blockInfo.height) *
                              largestMipSize.depthOrArrayLayers;
        DynamicUploader* uploader = device->GetDynamicUploader();
        UploadHandle uploadHandle;
        DAWN_TRY_ASSIGN(
            uploadHandle,
            uploader->Allocate(bufferSize, device->GetPendingCommandSerial(), blockInfo.byteSize));
        memset(uploadHandle.mappedBuffer, uClearColor, bufferSize);

        std::vector<VkBufferImageCopy> regions;
        for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
             ++level) {
            Extent3D copySize = GetMipLevelPhysicalSize(level);
            imageRange.baseMipLevel = level;
            for (uint32_t layer = range.baseArrayLayer;
                 layer < range.baseArrayLayer + range.layerCount; ++layer) {
                if (clearValue == TextureBase::ClearValue::Zero &&
                    IsSubresourceContentInitialized(
                        SubresourceRange::SingleMipAndLayer(level, layer, range.aspects))) {
                    // Skip lazy clears if already initialized.
                    continue;
                }

                TextureDataLayout dataLayout;
                dataLayout.offset = uploadHandle.startOffset;
                dataLayout.rowsPerImage = copySize.height / blockInfo.height;
                dataLayout.bytesPerRow = bytesPerRow;
                TextureCopy textureCopy;
                textureCopy.aspect = range.aspects;
                textureCopy.mipLevel = level;
                textureCopy.origin = {0, 0, layer};
                textureCopy.texture = this;

                regions.push_back(ComputeBufferImageCopyRegion(dataLayout, textureCopy, copySize));
            }
        }
        device->fn.CmdCopyBufferToImage(recordingContext->commandBuffer,
                                        ToBackend(uploadHandle.stagingBuffer)->GetBufferHandle(),
                                        GetHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
                                        regions.size(), regions.data());
    } else {
        for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
             ++level) {
            imageRange.baseMipLevel = level;
            for (uint32_t layer = range.baseArrayLayer;
                 layer < range.baseArrayLayer + range.layerCount; ++layer) {
                Aspect aspects = Aspect::None;
                for (Aspect aspect : IterateEnumMask(range.aspects)) {
                    if (clearValue == TextureBase::ClearValue::Zero &&
                        IsSubresourceContentInitialized(
                            SubresourceRange::SingleMipAndLayer(level, layer, aspect))) {
                        // Skip lazy clears if already initialized.
                        continue;
                    }
                    aspects |= aspect;
                }

                if (aspects == Aspect::None) {
                    continue;
                }

                imageRange.aspectMask = VulkanAspectMask(aspects);
                imageRange.baseArrayLayer = layer;

                if (aspects & (Aspect::Depth | Aspect::Stencil | Aspect::CombinedDepthStencil)) {
                    VkClearDepthStencilValue clearDepthStencilValue[1];
                    clearDepthStencilValue[0].depth = fClearColor;
                    clearDepthStencilValue[0].stencil = uClearColor;
                    device->fn.CmdClearDepthStencilImage(recordingContext->commandBuffer,
                                                         GetHandle(),
                                                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
                                                         clearDepthStencilValue, 1, &imageRange);
                } else {
                    ASSERT(aspects == Aspect::Color);
                    VkClearColorValue clearColorValue;
                    switch (GetFormat().GetAspectInfo(Aspect::Color).baseType) {
                        case wgpu::TextureComponentType::Float:
                            clearColorValue.float32[0] = fClearColor;
                            clearColorValue.float32[1] = fClearColor;
                            clearColorValue.float32[2] = fClearColor;
                            clearColorValue.float32[3] = fClearColor;
                            break;
                        case wgpu::TextureComponentType::Sint:
                            clearColorValue.int32[0] = sClearColor;
                            clearColorValue.int32[1] = sClearColor;
                            clearColorValue.int32[2] = sClearColor;
                            clearColorValue.int32[3] = sClearColor;
                            break;
                        case wgpu::TextureComponentType::Uint:
                            clearColorValue.uint32[0] = uClearColor;
                            clearColorValue.uint32[1] = uClearColor;
                            clearColorValue.uint32[2] = uClearColor;
                            clearColorValue.uint32[3] = uClearColor;
                            break;
                        case wgpu::TextureComponentType::DepthComparison:
                            UNREACHABLE();
                    }
                    device->fn.CmdClearColorImage(recordingContext->commandBuffer, GetHandle(),
                                                  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
                                                  &clearColorValue, 1, &imageRange);
                }
            }
        }
    }

    if (clearValue == TextureBase::ClearValue::Zero) {
        SetIsSubresourceContentInitialized(true, range);
        device->IncrementLazyClearCountForTesting();
    }
    return {};
}

void Texture::EnsureSubresourceContentInitialized(CommandRecordingContext* recordingContext,
                                                  const SubresourceRange& range) {
    if (!GetDevice()->IsToggleEnabled(Toggle::LazyClearResourceOnFirstUse)) {
        return;
    }
    if (!IsSubresourceContentInitialized(range)) {
        // If subresource has not been initialized, clear it to black as it could contain dirty
        // bits from recycled memory
        GetDevice()->ConsumedError(
            ClearTexture(recordingContext, range, TextureBase::ClearValue::Zero));
    }
}

VkImageLayout Texture::GetCurrentLayoutForSwapChain() const {
    ASSERT(GetFormat().aspects == Aspect::Color);
    return VulkanImageLayout(this, mSubresourceLastUsages->Get(Aspect::Color, 0, 0));
}

// static
ResultOrError<Ref<TextureView>> TextureView::Create(TextureBase* texture,
                                                    const TextureViewDescriptor* descriptor) {
    Ref<TextureView> view = AcquireRef(new TextureView(texture, descriptor));
    DAWN_TRY(view->Initialize(descriptor));
    return view;
}

MaybeError TextureView::Initialize(const TextureViewDescriptor* descriptor) {
    if ((GetTexture()->GetInternalUsage() &
         ~(wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst)) == 0) {
        // If the texture view has no other usage than CopySrc and CopyDst, then it can't
        // actually be used as a render pass attachment or sampled/storage texture. The Vulkan
        // validation errors warn if you create such a vkImageView, so return early.
        return {};
    }

    // Texture could be destroyed by the time we make a view.
    if (GetTexture()->GetTextureState() == Texture::TextureState::Destroyed) {
        return {};
    }

    Device* device = ToBackend(GetTexture()->GetDevice());

    VkImageViewCreateInfo createInfo;
    createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
    createInfo.pNext = nullptr;
    createInfo.flags = 0;
    createInfo.image = ToBackend(GetTexture())->GetHandle();
    createInfo.viewType = VulkanImageViewType(descriptor->dimension);

    const Format& textureFormat = GetTexture()->GetFormat();
    if (textureFormat.HasStencil() &&
        (textureFormat.HasDepth() || !device->IsToggleEnabled(Toggle::VulkanUseS8))) {
        // Unlike multi-planar formats, depth-stencil formats have multiple aspects but are not
        // created with VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT.
        // https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkImageViewCreateInfo.html#VUID-VkImageViewCreateInfo-image-01762
        // Without, VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, the view format must match the texture
        // format.
        createInfo.format = VulkanImageFormat(device, textureFormat.format);
    } else {
        createInfo.format = VulkanImageFormat(device, descriptor->format);
    }

    createInfo.components = VkComponentMapping{VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
                                               VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};

    const SubresourceRange& subresources = GetSubresourceRange();
    createInfo.subresourceRange.baseMipLevel = subresources.baseMipLevel;
    createInfo.subresourceRange.levelCount = subresources.levelCount;
    createInfo.subresourceRange.baseArrayLayer = subresources.baseArrayLayer;
    createInfo.subresourceRange.layerCount = subresources.layerCount;
    createInfo.subresourceRange.aspectMask = VulkanAspectMask(subresources.aspects);

    DAWN_TRY(CheckVkSuccess(
        device->fn.CreateImageView(device->GetVkDevice(), &createInfo, nullptr, &*mHandle),
        "CreateImageView"));

    SetLabelImpl();

    return {};
}

TextureView::~TextureView() {}

void TextureView::DestroyImpl() {
    Device* device = ToBackend(GetTexture()->GetDevice());

    if (mHandle != VK_NULL_HANDLE) {
        device->GetFencedDeleter()->DeleteWhenUnused(mHandle);
        mHandle = VK_NULL_HANDLE;
    }
}

VkImageView TextureView::GetHandle() const {
    return mHandle;
}

void TextureView::SetLabelImpl() {
    SetDebugName(ToBackend(GetDevice()), mHandle, "Dawn_TextureView", GetLabel());
}

}  // namespace dawn::native::vulkan
