// Copyright 2019 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "dawn/native/CommandValidation.h"

#include <algorithm>
#include <array>
#include <limits>
#include <sstream>
#include <string>
#include <utility>

#include "dawn/common/Numeric.h"
#include "dawn/native/BindGroup.h"
#include "dawn/native/Buffer.h"
#include "dawn/native/ChainUtils.h"
#include "dawn/native/CommandBufferStateTracker.h"
#include "dawn/native/Commands.h"
#include "dawn/native/Device.h"
#include "dawn/native/Instance.h"
#include "dawn/native/PassResourceUsage.h"
#include "dawn/native/PhysicalDevice.h"
#include "dawn/native/QuerySet.h"
#include "dawn/native/RenderBundle.h"
#include "dawn/native/RenderPipeline.h"
#include "dawn/native/ValidationUtils_autogen.h"
#include "dawn/native/webgpu_absl_format.h"

namespace dawn::native {

namespace {

std::string ToBufferSyncScopeResourceUsage(wgpu::BufferUsage syncScopeBufferUsage) {
    constexpr std::array kUsageInfoList = {
        std::make_pair(wgpu::BufferUsage::Index, "Index"),
        std::make_pair(wgpu::BufferUsage::Vertex, "Vertex"),
        std::make_pair(wgpu::BufferUsage::Indirect, "Indirect"),
        std::make_pair(wgpu::BufferUsage::Uniform, "Uniform"),
        std::make_pair(wgpu::BufferUsage::Storage, "Storage(read-write)"),
        std::make_pair(kReadOnlyStorageBuffer, "Storage(read-only)"),
        std::make_pair(kReadOnlyTexelBuffer, "TexelBuffer(read-only)")};

    std::stringstream stream;
    bool first = true;
    for (const auto& [usage, info] : kUsageInfoList) {
        if (syncScopeBufferUsage & usage) {
            if (!first) {
                stream << "|";
            }
            first = false;
            stream << info;
            syncScopeBufferUsage &= ~usage;
        }
    }

    if (static_cast<bool>(syncScopeBufferUsage)) {
        if (!first) {
            stream << "|";
        }
        stream << "BufferUsage::0x" << std::hex
               << static_cast<typename std::underlying_type<wgpu::BufferUsage>::type>(
                      syncScopeBufferUsage);
    }

    return stream.str();
}

std::string ToTextureSyncScopeResourceUsage(wgpu::TextureUsage syncScopeTextureUsage) {
    constexpr std::array kUsageInfoList = {
        std::make_pair(wgpu::TextureUsage::TextureBinding, "TextureBinding"),
        std::make_pair(wgpu::TextureUsage::StorageBinding, "Storage(read-write)"),
        std::make_pair(kWriteOnlyStorageTexture, "Storage(write-only)"),
        std::make_pair(kReadOnlyStorageTexture, "Storage(read-only)"),
        std::make_pair(wgpu::TextureUsage::RenderAttachment, "RenderAttachment"),
        std::make_pair(kReadOnlyRenderAttachment, "RenderAttachment(read-only)")};

    std::stringstream stream;
    bool first = true;
    for (const auto& [usage, info] : kUsageInfoList) {
        if (syncScopeTextureUsage & usage) {
            if (!first) {
                stream << "|";
            }
            first = false;
            stream << info;
            syncScopeTextureUsage &= ~usage;
        }
    }

    if (static_cast<bool>(syncScopeTextureUsage)) {
        if (!first) {
            stream << "|";
        }
        stream << "TextureUsage::0x" << std::hex
               << static_cast<typename std::underlying_type<wgpu::TextureUsage>::type>(
                      syncScopeTextureUsage);
    }

    return stream.str();
}

}  // namespace

// Performs validation of the "synchronization scope" rules of WebGPU.
MaybeError ValidateSyncScopeResourceUsage(const SyncScopeResourceUsage& scope) {
    // Buffers can only be used as single-write or multiple read.
    for (size_t i = 0; i < scope.bufferSyncInfos.size(); ++i) {
        const wgpu::BufferUsage usage = scope.bufferSyncInfos[i].usage;
        bool readOnly = IsSubset(usage, kReadOnlyBufferUsages);
        bool singleUse = wgpu::HasZeroOrOneBits(usage);

        DAWN_INVALID_IF(!readOnly && !singleUse,
                        "%s usage (%s) includes writable usage and another usage in the same "
                        "synchronization scope.",
                        scope.buffers[i], ToBufferSyncScopeResourceUsage(usage));
    }

    // Check that every single subresource is used as either a single-write usage or a
    // combination of readonly usages.
    for (size_t i = 0; i < scope.textureSyncInfos.size(); ++i) {
        const TextureSubresourceSyncInfo& textureSyncInfo = scope.textureSyncInfos[i];
        DAWN_TRY(textureSyncInfo.Iterate(
            [&](const SubresourceRange&, const TextureSyncInfo& syncInfo) -> MaybeError {
                bool readOnly = IsSubset(syncInfo.usage, kReadOnlyTextureUsages);
                bool singleUse = wgpu::HasZeroOrOneBits(syncInfo.usage);
                if (readOnly || singleUse) {
                    return {};
                }
                // kResolveTextureLoadAndStoreUsages are kResolveAttachmentLoadingUsage &
                // RenderAttachment usage used in the same pass.
                // This is accepted because kResolveAttachmentLoadingUsage is an internal loading
                // operation for blitting a resolve target to an MSAA attachment. And there won't be
                // and read-after-write hazard.
                if (syncInfo.usage == kResolveTextureLoadAndStoreUsages) {
                    return {};
                }
                return DAWN_VALIDATION_ERROR(
                    "%s usage (%s) includes writable usage and another usage in the same "
                    "synchronization scope.",
                    scope.textures[i], ToTextureSyncScopeResourceUsage(syncInfo.usage));
            }));
    }
    return {};
}

MaybeError ValidateTimestampQuery(const DeviceBase* device,
                                  const QuerySetBase* querySet,
                                  uint32_t queryIndex,
                                  Feature requiredFeature) {
    DAWN_TRY(device->ValidateObject(querySet));

    DAWN_INVALID_IF(!device->HasFeature(requiredFeature),
                    "Timestamp queries used without the %s feature enabled.",
                    ToAPI(requiredFeature));

    DAWN_INVALID_IF(querySet->GetQueryType() != wgpu::QueryType::Timestamp,
                    "The type of %s is not %s.", querySet, wgpu::QueryType::Timestamp);

    DAWN_INVALID_IF(queryIndex >= querySet->GetQueryCount(),
                    "Query index (%u) exceeds the number of queries (%u) in %s.", queryIndex,
                    querySet->GetQueryCount(), querySet);

    return {};
}

MaybeError ValidatePassTimestampWrites(const DeviceBase* device,
                                       const PassTimestampWrites* timestampWrites) {
    DAWN_INVALID_IF(!device->HasFeature(Feature::TimestampQuery),
                    "Timestamp queries used without the timestamp-query feature enabled.");

    UnpackedPtr<PassTimestampWrites> unpacked;
    DAWN_TRY_ASSIGN(unpacked, ValidateAndUnpack(timestampWrites));

    QuerySetBase* querySet = unpacked->querySet;
    DAWN_CHECK(unpacked->querySet != nullptr);
    DAWN_TRY(device->ValidateObject(querySet));
    DAWN_INVALID_IF(querySet->GetQueryType() != wgpu::QueryType::Timestamp,
                    "The type of %s is not %s.", querySet, wgpu::QueryType::Timestamp);

    if (unpacked->beginningOfPassWriteIndex != wgpu::kQuerySetIndexUndefined) {
        DAWN_INVALID_IF(unpacked->beginningOfPassWriteIndex >= querySet->GetQueryCount(),
                        "beginningOfPassWriteIndex (%u) exceeds the number of queries (%u) in %s.",
                        unpacked->beginningOfPassWriteIndex, querySet->GetQueryCount(), querySet);
    }
    if (unpacked->endOfPassWriteIndex != wgpu::kQuerySetIndexUndefined) {
        DAWN_INVALID_IF(unpacked->endOfPassWriteIndex >= querySet->GetQueryCount(),
                        "endOfPassWriteIndex (%u) exceeds the number of queries (%u) in %s.",
                        unpacked->endOfPassWriteIndex, querySet->GetQueryCount(), querySet);
    }

    DAWN_INVALID_IF(unpacked->beginningOfPassWriteIndex == wgpu::kQuerySetIndexUndefined &&
                        unpacked->endOfPassWriteIndex == wgpu::kQuerySetIndexUndefined,
                    "Both beginningOfPassWriteIndex and endOfPassWriteIndex are undefined.");

    DAWN_INVALID_IF(unpacked->beginningOfPassWriteIndex == unpacked->endOfPassWriteIndex,
                    "beginningOfPassWriteIndex (%u) is equal to endOfPassWriteIndex (%u).",
                    unpacked->beginningOfPassWriteIndex, unpacked->endOfPassWriteIndex);

    return {};
}

MaybeError ValidateWriteBuffer(const DeviceBase* device,
                               const BufferBase* buffer,
                               uint64_t bufferOffset,
                               uint64_t size) {
    DAWN_TRY(device->ValidateObject(buffer));

    DAWN_INVALID_IF(bufferOffset % 4 != 0, "BufferOffset (%u) is not a multiple of 4.",
                    bufferOffset);

    DAWN_INVALID_IF(size % 4 != 0, "Size (%u) is not a multiple of 4.", size);

    uint64_t bufferSize = buffer->GetSize();
    DAWN_INVALID_IF(bufferOffset > bufferSize || size > (bufferSize - bufferOffset),
                    "Write range (bufferOffset: %u, size: %u) does not fit in %s size (%u).",
                    bufferOffset, size, buffer, bufferSize);

    DAWN_TRY(ValidateCanUseAs(buffer, wgpu::BufferUsage::CopyDst));

    return {};
}

ResultOrError<uint64_t> ComputeRequiredBytesInCopy(const TexelBlockInfo& blockInfo,
                                                   const Extent3D& copySize,
                                                   uint32_t bytesPerRow,
                                                   uint32_t rowsPerImage) {
    DAWN_CHECK(copySize.width % blockInfo.width == 0);
    DAWN_CHECK(copySize.height % blockInfo.height == 0);
    if (copySize.depthOrArrayLayers == 0) {
        return 0;
    }
    uint32_t widthInBlocks = copySize.width / blockInfo.width;
    uint32_t heightInBlocks = copySize.height / blockInfo.height;
    uint64_t bytesInLastRow = Safe32x32(widthInBlocks, blockInfo.byteSize);

    // Check for potential overflows for the rest of the computations. We have the following
    // invariants:
    //
    //   bytesInLastRow <= bytesPerRow
    //   heightInBlocks <= rowsPerImage
    //
    // So:
    //
    //   bytesInLastImage  = bytesPerRow * (heightInBlocks - 1) + bytesInLastRow
    //                    <= bytesPerRow * heightInBlocks
    //                    <= bytesPerRow * rowsPerImage
    //                    <= bytesPerImage
    //
    // This means that if the computation of depth * bytesPerImage doesn't overflow, none of the
    // computations for requiredBytesInCopy will. (and it's not a very pessimizing check)
    DAWN_CHECK(copySize.depthOrArrayLayers <= 1 || (bytesPerRow != wgpu::kCopyStrideUndefined &&
                                                    rowsPerImage != wgpu::kCopyStrideUndefined));
    uint64_t bytesPerImage = Safe32x32(bytesPerRow, rowsPerImage);
    DAWN_INVALID_IF(
        bytesPerImage > std::numeric_limits<uint64_t>::max() / copySize.depthOrArrayLayers,
        "The number of bytes per image (%u) exceeds the maximum (%u) when copying %u images.",
        bytesPerImage, std::numeric_limits<uint64_t>::max() / copySize.depthOrArrayLayers,
        copySize.depthOrArrayLayers);

    uint64_t requiredBytesInCopy = bytesPerImage * (copySize.depthOrArrayLayers - 1);
    if (heightInBlocks > 0) {
        DAWN_CHECK(heightInBlocks <= 1 || bytesPerRow != wgpu::kCopyStrideUndefined);
        uint64_t bytesInLastImage = Safe32x32(bytesPerRow, heightInBlocks - 1) + bytesInLastRow;
        requiredBytesInCopy += bytesInLastImage;
    }
    return requiredBytesInCopy;
}

uint64_t ComputeRequiredBytesInCopy(const TypedTexelBlockInfo& blockInfo,
                                    const BlockExtent3D& copySize,
                                    BlockCount blocksPerRow,
                                    BlockCount rowsPerImage) {
    // See ComputeRequiredBytesInCopy overload as this is mostly the same modulo some validation.
    if (copySize.depthOrArrayLayers == BlockCount{0}) {
        return 0;
    }
    BlockCount widthInBlocks = copySize.width;
    BlockCount heightInBlocks = copySize.height;
    BlockCount blocksInLastRow = widthInBlocks;
    BlockCount blocksPerImage = blocksPerRow * rowsPerImage;
    uint64_t bytesPerImage = blockInfo.ToBytes(blocksPerImage);
    uint64_t maxBytesPerImage =
        std::numeric_limits<uint64_t>::max() / static_cast<uint64_t>(copySize.depthOrArrayLayers);
    DAWN_CHECK(bytesPerImage <= maxBytesPerImage);
    BlockCount blocksToCopy = blocksPerImage * (copySize.depthOrArrayLayers - BlockCount{1});
    uint64_t requiredBytesInCopy = blockInfo.ToBytes(blocksToCopy);
    if (heightInBlocks > BlockCount{0}) {
        BlockCount blocksInLastImage =
            blocksPerRow * (heightInBlocks - BlockCount{1}) + blocksInLastRow;
        uint64_t bytesInLastImage = blockInfo.ToBytes(blocksInLastImage);
        requiredBytesInCopy += bytesInLastImage;
    }
    return requiredBytesInCopy;
}

MaybeError ValidateCopySizeFitsInBuffer(const Ref<BufferBase>& buffer,
                                        uint64_t offset,
                                        uint64_t size,
                                        BufferSizeType checkBufferSizeType) {
    uint64_t bufferSize = 0;
    switch (checkBufferSizeType) {
        case BufferSizeType::Size:
            bufferSize = buffer->GetSize();
            break;
        case BufferSizeType::AllocatedSize:
            bufferSize = buffer->GetAllocatedSize();
            break;
    }
    bool fitsInBuffer = offset <= bufferSize && (size <= (bufferSize - offset));
    DAWN_INVALID_IF(!fitsInBuffer,
                    "Copy range (offset: %u, size: %u) does not fit in %s size (%u).", offset, size,
                    buffer.Get(), bufferSize);

    return {};
}

// Replace wgpu::kCopyStrideUndefined with real values, so backends don't have to think about
// it.
void ApplyDefaultTexelCopyBufferLayoutOptions(TexelCopyBufferLayout* layout,
                                              const TexelBlockInfo& blockInfo,
                                              const Extent3D& copyExtent) {
    DAWN_CHECK(layout != nullptr);
    DAWN_CHECK(copyExtent.height % blockInfo.height == 0);
    uint32_t heightInBlocks = copyExtent.height / blockInfo.height;

    if (layout->bytesPerRow == wgpu::kCopyStrideUndefined) {
        DAWN_CHECK(copyExtent.width % blockInfo.width == 0);
        uint32_t widthInBlocks = copyExtent.width / blockInfo.width;
        uint32_t bytesInLastRow = widthInBlocks * blockInfo.byteSize;

        DAWN_CHECK(heightInBlocks <= 1 && copyExtent.depthOrArrayLayers <= 1);
        layout->bytesPerRow = Align(bytesInLastRow, kTextureBytesPerRowAlignment);
    }
    if (layout->rowsPerImage == wgpu::kCopyStrideUndefined) {
        DAWN_CHECK(copyExtent.depthOrArrayLayers <= 1);
        layout->rowsPerImage = heightInBlocks;
    }
}

MaybeError ValidateLinearTextureData(const TexelCopyBufferLayout& layout,
                                     uint64_t byteSize,
                                     const TexelBlockInfo& blockInfo,
                                     const Extent3D& copyExtent) {
    DAWN_CHECK(copyExtent.height % blockInfo.height == 0);
    uint32_t heightInBlocks = copyExtent.height / blockInfo.height;

    DAWN_INVALID_IF(
        copyExtent.depthOrArrayLayers > 1 && (layout.bytesPerRow == wgpu::kCopyStrideUndefined ||
                                              layout.rowsPerImage == wgpu::kCopyStrideUndefined),
        "Copy depth (%u) is > 1, but bytesPerRow (%u) or rowsPerImage (%u) are not specified.",
        copyExtent.depthOrArrayLayers,
        WrapUndefined(layout.bytesPerRow, wgpu::kCopyStrideUndefined),
        WrapUndefined(layout.rowsPerImage, wgpu::kCopyStrideUndefined));

    DAWN_INVALID_IF(heightInBlocks > 1 && layout.bytesPerRow == wgpu::kCopyStrideUndefined,
                    "HeightInBlocks (%u) is > 1, but bytesPerRow is not specified.",
                    heightInBlocks);

    // Validation for other members in layout:
    DAWN_CHECK(copyExtent.width % blockInfo.width == 0);
    uint32_t widthInBlocks = copyExtent.width / blockInfo.width;
    DAWN_CHECK(Safe32x32(widthInBlocks, blockInfo.byteSize) <=
               std::numeric_limits<uint32_t>::max());
    uint32_t bytesInLastRow = widthInBlocks * blockInfo.byteSize;

    // These != wgpu::kCopyStrideUndefined checks are technically redundant with the > checks,
    // but they should get optimized out.
    DAWN_INVALID_IF(
        layout.bytesPerRow != wgpu::kCopyStrideUndefined && bytesInLastRow > layout.bytesPerRow,
        "The byte size of each row (%u) is > bytesPerRow (%u).", bytesInLastRow,
        layout.bytesPerRow);

    DAWN_INVALID_IF(
        layout.rowsPerImage != wgpu::kCopyStrideUndefined && heightInBlocks > layout.rowsPerImage,
        "The height of each image in blocks (%u) is > rowsPerImage (%u).", heightInBlocks,
        layout.rowsPerImage);

    // We compute required bytes in copy after validating texel block alignments
    // because the divisibility conditions are necessary for the algorithm to be valid,
    // also the bytesPerRow bound is necessary to avoid overflows.
    uint64_t requiredBytesInCopy;
    DAWN_TRY_ASSIGN(
        requiredBytesInCopy,
        ComputeRequiredBytesInCopy(blockInfo, copyExtent, layout.bytesPerRow, layout.rowsPerImage));

    bool fitsInData =
        layout.offset <= byteSize && (requiredBytesInCopy <= (byteSize - layout.offset));
    DAWN_INVALID_IF(
        !fitsInData,
        "Required size for texture data layout (%u) exceeds the linear data size (%u) with "
        "offset (%u).",
        requiredBytesInCopy, byteSize, layout.offset);

    return {};
}

MaybeError ValidateTexelCopyBufferInfo(DeviceBase const* device,
                                       const TexelCopyBufferInfo& texelCopyBufferInfo) {
    DAWN_TRY(device->ValidateObject(texelCopyBufferInfo.buffer));
    auto alignment = kTextureBytesPerRowAlignment;
    if (device->HasFeature(Feature::DawnTexelCopyBufferRowAlignment)) {
        alignment =
            device->GetLimits().texelCopyBufferRowAlignmentLimits.minTexelCopyBufferRowAlignment;
    }
    if (texelCopyBufferInfo.layout.bytesPerRow != wgpu::kCopyStrideUndefined) {
        DAWN_INVALID_IF(texelCopyBufferInfo.layout.bytesPerRow % alignment != 0,
                        "bytesPerRow (%u) is not a multiple of %u.",
                        texelCopyBufferInfo.layout.bytesPerRow, alignment);
    }

    return {};
}

MaybeError ValidateTexelCopyTextureInfo(DeviceBase const* device,
                                        const TexelCopyTextureInfo& textureCopy,
                                        const Extent3D& copySize) {
    const TextureBase* texture = textureCopy.texture;
    DAWN_TRY(device->ValidateObject(texture));

    DAWN_INVALID_IF(textureCopy.mipLevel >= texture->GetNumMipLevels(),
                    "MipLevel (%u) is greater than the number of mip levels (%u) in %s.",
                    textureCopy.mipLevel, texture->GetNumMipLevels(), texture);

    DAWN_TRY(ValidateTextureAspect(textureCopy.aspect));

    const auto aspect = SelectFormatAspects(texture->GetFormat(), textureCopy.aspect);
    DAWN_INVALID_IF(aspect == Aspect::None,
                    "%s format (%s) does not have the selected aspect (%s).", texture,
                    texture->GetFormat().format, textureCopy.aspect);

    if (texture->GetSampleCount() > 1 || texture->GetFormat().HasDepthOrStencil()) {
        Extent3D subresourceSize =
            texture->GetMipLevelSingleSubresourcePhysicalSize(textureCopy.mipLevel, aspect);
        DAWN_CHECK(texture->GetDimension() == wgpu::TextureDimension::e2D);
        DAWN_INVALID_IF(
            textureCopy.origin.x != 0 || textureCopy.origin.y != 0 ||
                subresourceSize.width != copySize.width ||
                subresourceSize.height != copySize.height,
            "Copy origin (%s) and size (%s) does not cover the entire subresource (origin: "
            "[x: 0, y: 0], size: %s) of %s. The entire subresource must be copied when the "
            "format (%s) is a depth/stencil format or the sample count (%u) is > 1.",
            textureCopy.origin, copySize, subresourceSize, texture, texture->GetFormat().format,
            texture->GetSampleCount());
    }

    return {};
}

MaybeError ValidateTextureCopyRange(DeviceBase const* device,
                                    const TexelCopyTextureInfo& textureCopy,
                                    const Extent3D& copySize) {
    const TextureBase* texture = textureCopy.texture;
    const Format& format = textureCopy.texture->GetFormat();
    const Aspect aspect = ConvertAspect(format, textureCopy.aspect);

    DAWN_CHECK(!format.IsMultiPlanar() || HasOneBit(aspect));

    // Validation for the copy being in-bounds:
    Extent3D mipSize =
        texture->GetMipLevelSingleSubresourcePhysicalSize(textureCopy.mipLevel, aspect);
    // For 1D/2D textures, include the array layer as depth so it can be checked with other
    // dimensions.
    if (texture->GetDimension() != wgpu::TextureDimension::e3D) {
        mipSize.depthOrArrayLayers = texture->GetArrayLayers();
    }
    // All texture dimensions are in uint32_t so by doing checks in uint64_t we avoid
    // overflows.
    DAWN_INVALID_IF(
        static_cast<uint64_t>(textureCopy.origin.x) + static_cast<uint64_t>(copySize.width) >
                static_cast<uint64_t>(mipSize.width) ||
            static_cast<uint64_t>(textureCopy.origin.y) + static_cast<uint64_t>(copySize.height) >
                static_cast<uint64_t>(mipSize.height) ||
            static_cast<uint64_t>(textureCopy.origin.z) +
                    static_cast<uint64_t>(copySize.depthOrArrayLayers) >
                static_cast<uint64_t>(mipSize.depthOrArrayLayers),
        "Texture copy range (origin: %s, copySize: %s) touches outside of %s mip level %u "
        "size (%s).",
        textureCopy.origin, copySize, texture, textureCopy.mipLevel, mipSize);

    // Validation for the texel block alignments:
    if (format.isCompressed) {
        const TexelBlockInfo& blockInfo = GetBlockInfo(textureCopy);
        DAWN_INVALID_IF(
            textureCopy.origin.x % blockInfo.width != 0,
            "Texture copy origin.x (%u) is not a multiple of compressed texture format block "
            "width (%u).",
            textureCopy.origin.x, blockInfo.width);
        DAWN_INVALID_IF(
            textureCopy.origin.y % blockInfo.height != 0,
            "Texture copy origin.y (%u) is not a multiple of compressed texture format block "
            "height (%u).",
            textureCopy.origin.y, blockInfo.height);
        DAWN_INVALID_IF(
            copySize.width % blockInfo.width != 0,
            "copySize.width (%u) is not a multiple of compressed texture format block width "
            "(%u).",
            copySize.width, blockInfo.width);
        DAWN_INVALID_IF(copySize.height % blockInfo.height != 0,
                        "copySize.height (%u) is not a multiple of compressed texture format block "
                        "height (%u).",
                        copySize.height, blockInfo.height);
    }

    return {};
}

// Always returns a single aspect (color, stencil, depth, or ith plane for multi-planar
// formats).
ResultOrError<Aspect> SingleAspectUsedByTexelCopyTextureInfo(const TexelCopyTextureInfo& view) {
    const Format& format = view.texture->GetFormat();
    switch (view.aspect) {
        case wgpu::TextureAspect::All: {
            DAWN_INVALID_IF(
                !HasOneBit(format.aspects),
                "More than a single aspect (%s) is selected for multi-planar format (%s) in "
                "%s <-> linear data copy.",
                view.aspect, format.format, view.texture);

            Aspect single = format.aspects;
            return single;
        }
        case wgpu::TextureAspect::DepthOnly:
            DAWN_CHECK(format.aspects & Aspect::Depth);
            return Aspect::Depth;
        case wgpu::TextureAspect::StencilOnly:
            DAWN_CHECK(format.aspects & Aspect::Stencil);
            return Aspect::Stencil;
        case wgpu::TextureAspect::Plane0Only:
            return Aspect::Plane0;
        case wgpu::TextureAspect::Plane1Only:
            return Aspect::Plane1;
        case wgpu::TextureAspect::Plane2Only:
            return Aspect::Plane2;
        case wgpu::TextureAspect::Undefined:
            break;
    }
    DAWN_UNREACHABLE();
}

MaybeError ValidateLinearToDepthStencilCopyRestrictions(const TexelCopyTextureInfo& dst) {
    Aspect aspectUsed;
    DAWN_TRY_ASSIGN(aspectUsed, SingleAspectUsedByTexelCopyTextureInfo(dst));

    const Format& format = dst.texture->GetFormat();
    switch (format.format) {
        case wgpu::TextureFormat::Depth16Unorm:
            return {};
        default:
            DAWN_INVALID_IF(aspectUsed == Aspect::Depth,
                            "Cannot copy into the depth aspect of %s with format %s.", dst.texture,
                            format.format);
            break;
    }

    return {};
}

MaybeError ValidateTextureToTextureCopyCommonRestrictions(DeviceBase const* device,
                                                          const TexelCopyTextureInfo& src,
                                                          const TexelCopyTextureInfo& dst,
                                                          const Extent3D& copySize) {
    const uint32_t srcSamples = src.texture->GetSampleCount();
    const uint32_t dstSamples = dst.texture->GetSampleCount();

    DAWN_INVALID_IF(
        srcSamples != dstSamples,
        "Source %s sample count (%u) and destination %s sample count (%u) does not match.",
        src.texture, srcSamples, dst.texture, dstSamples);

    DAWN_INVALID_IF(device->IsCompatibilityMode() && srcSamples != 1,
                    "Source %s and destination %s with sample count (%u) > 1 cannot be copied in "
                    "compatibility mode.",
                    src.texture, dst.texture, srcSamples);

    // Metal cannot select a single aspect for texture-to-texture copies.
    const Format& format = src.texture->GetFormat();
    DAWN_INVALID_IF(
        SelectFormatAspects(format, src.aspect) != format.aspects,
        "Source %s aspect (%s) doesn't select all the aspects of the source format (%s).",
        src.texture, src.aspect, format.format);

    DAWN_INVALID_IF(
        SelectFormatAspects(format, dst.aspect) != format.aspects,
        "Destination %s aspect (%s) doesn't select all the aspects of the destination format "
        "(%s).",
        dst.texture, dst.aspect, format.format);

    if (src.texture == dst.texture) {
        switch (src.texture->GetDimension()) {
            case wgpu::TextureDimension::Undefined:
                DAWN_UNREACHABLE();

            case wgpu::TextureDimension::e1D:
                DAWN_ASSERT(src.mipLevel == 0);
                return DAWN_VALIDATION_ERROR("Copy is from %s to itself.", src.texture);

            case wgpu::TextureDimension::e2D:
                DAWN_INVALID_IF(
                    src.mipLevel == dst.mipLevel &&
                        IsRangeOverlapped(src.origin.z, dst.origin.z, copySize.depthOrArrayLayers),
                    "Copy source and destination are overlapping layer ranges "
                    "([%u, %u) and [%u, %u)) of %s mip level %u",
                    src.origin.z, src.origin.z + copySize.depthOrArrayLayers, dst.origin.z,
                    dst.origin.z + copySize.depthOrArrayLayers, src.texture, src.mipLevel);
                break;

            case wgpu::TextureDimension::e3D:
                DAWN_INVALID_IF(src.mipLevel == dst.mipLevel,
                                "Copy is from %s mip level %u to itself.", src.texture,
                                src.mipLevel);
                break;
        }
    }

    return {};
}

MaybeError ValidateTextureToTextureCopyRestrictions(DeviceBase const* device,
                                                    const TexelCopyTextureInfo& src,
                                                    const TexelCopyTextureInfo& dst,
                                                    const Extent3D& copySize) {
    // Metal requires texture-to-texture copies happens between texture formats that equal to
    // each other or only have diff on srgb-ness.
    DAWN_INVALID_IF(!src.texture->GetFormat().CopyCompatibleWith(dst.texture->GetFormat()),
                    "Source %s format (%s) and destination %s format (%s) are not copy compatible.",
                    src.texture, src.texture->GetFormat().format, dst.texture,
                    dst.texture->GetFormat().format);

    return ValidateTextureToTextureCopyCommonRestrictions(device, src, dst, copySize);
}

MaybeError ValidateCanUseAs(const TextureBase* texture,
                            wgpu::TextureUsage usage,
                            UsageValidationMode mode) {
    DAWN_CHECK(wgpu::HasZeroOrOneBits(usage));
    switch (mode) {
        case UsageValidationMode::Default:
            DAWN_INVALID_IF(!(texture->GetUsage() & usage), "%s usage (%s) doesn't include %s.",
                            texture, texture->GetUsage(), usage);
            break;
        case UsageValidationMode::Internal:
            DAWN_INVALID_IF(!(texture->GetInternalUsage() & usage),
                            "%s internal usage (%s) doesn't include %s.", texture,
                            texture->GetInternalUsage(), usage);
            break;
    }
    return {};
}

MaybeError ValidateCanUseAs(const TextureViewBase* textureView,
                            wgpu::TextureUsage usage,
                            UsageValidationMode mode) {
    DAWN_CHECK(wgpu::HasZeroOrOneBits(usage));
    DAWN_CHECK(IsSubset(usage, kTextureViewOnlyUsages));
    switch (mode) {
        case UsageValidationMode::Default:
            DAWN_INVALID_IF(!(textureView->GetUsage() & usage), "%s usage (%s) doesn't include %s.",
                            textureView, textureView->GetUsage(), usage);
            break;
        case UsageValidationMode::Internal:
            DAWN_INVALID_IF(!(textureView->GetInternalUsage() & usage),
                            "%s internal usage (%s) doesn't include %s.", textureView,
                            textureView->GetInternalUsage(), usage);
            break;
    }
    return {};
}

MaybeError ValidateCanUseAs(const BufferBase* buffer, wgpu::BufferUsage usage) {
    DAWN_CHECK(wgpu::HasZeroOrOneBits(usage));
    DAWN_INVALID_IF(!(buffer->GetUsage() & usage), "%s usage (%s) doesn't include %s.", buffer,
                    buffer->GetUsage(), usage);
    return {};
}

MaybeError ValidateCanUseAsInternal(const BufferBase* buffer, wgpu::BufferUsage usage) {
    DAWN_INVALID_IF(!(buffer->GetInternalUsage() & usage),
                    "%s internal usage (%s) doesn't include %s.", buffer,
                    buffer->GetInternalUsage(), usage);
    return {};
}

namespace {
std::string TextureFormatsToString(const ColorAttachmentFormats& formats) {
    std::ostringstream ss;
    ss << "[ ";
    for (const Format* format : formats) {
        ss << absl::StrFormat("%s", format->format) << " ";
    }
    ss << "]";
    return ss.str();
}
}  // anonymous namespace

MaybeError ValidateColorAttachmentBytesPerSample(DeviceBase* device,
                                                 const ColorAttachmentFormats& formats) {
    uint32_t totalByteSize = 0;
    for (const Format* format : formats) {
        totalByteSize = Align(totalByteSize, format->renderTargetComponentAlignment);
        totalByteSize += format->renderTargetPixelByteCost;
    }
    uint32_t maxColorAttachmentBytesPerSample =
        device->GetLimits().v1.maxColorAttachmentBytesPerSample;
    DAWN_INVALID_IF(
        totalByteSize > maxColorAttachmentBytesPerSample,
        "Total color attachment bytes per sample (%u) exceeds maximum (%u) with formats "
        "(%s).%s",
        totalByteSize, maxColorAttachmentBytesPerSample, TextureFormatsToString(formats),
        DAWN_INCREASE_LIMIT_MESSAGE(device->GetAdapter()->GetLimits().v1,
                                    maxColorAttachmentBytesPerSample, totalByteSize));

    return {};
}

MaybeError ValidatePLSInfo(
    const DeviceBase* device,
    uint64_t totalSize,
    ityp::span<size_t, StorageAttachmentInfoForValidation> storageAttachments) {
    DAWN_INVALID_IF(
        !(device->HasFeature(Feature::PixelLocalStorageCoherent) ||
          device->HasFeature(Feature::PixelLocalStorageNonCoherent)),
        "Pixel Local Storage feature used without either of the pixel-local-storage-coherent or "
        "pixel-local-storage-non-coherent features enabled.");

    // Validate totalPixelLocalStorageSize
    DAWN_INVALID_IF(totalSize % kPLSSlotByteSize != 0,
                    "totalPixelLocalStorageSize (%i) is not a multiple of %i.", totalSize,
                    kPLSSlotByteSize);
    DAWN_INVALID_IF(totalSize > kMaxPLSSize,
                    "totalPixelLocalStorageSize (%i) is larger than maxPixelLocalStorageSize (%i).",
                    totalSize, kMaxPLSSize);

    std::array<size_t, kMaxPLSSlots> indexForSlot;
    constexpr size_t kSlotNotSet = std::numeric_limits<size_t>::max();
    indexForSlot.fill(kSlotNotSet);
    for (size_t i = 0; i < storageAttachments.size(); i++) {
        const Format& format = device->GetValidInternalFormat(storageAttachments[i].format);
        DAWN_CHECK(format.SupportsStorageAttachment());

        // Validate the slot's offset.
        uint64_t offset = storageAttachments[i].offset;
        DAWN_INVALID_IF(offset % kPLSSlotByteSize != 0,
                        "storageAttachments[%i].offset (%i) is not a multiple of %i.", i, offset,
                        kPLSSlotByteSize);
        DAWN_INVALID_IF(
            offset > kMaxPLSSize,
            "storageAttachments[%i].offset (%i) is larger than maxPixelLocalStorageSize (%i).", i,
            offset, kMaxPLSSize);
        // This can't overflow because kMaxPLSSize + max texel byte size is way less than 2^32.
        DAWN_INVALID_IF(
            offset + format.GetAspectInfo(Aspect::Color).block.byteSize > totalSize,
            "storageAttachments[%i]'s footprint [%i, %i) does not fit in the total size (%i).", i,
            offset, format.GetAspectInfo(Aspect::Color).block.byteSize, totalSize);

        // Validate that there are no collisions, each storage attachment takes a single slot so
        // we don't need to loop over all slots for a storage attachment.
        DAWN_CHECK(format.GetAspectInfo(Aspect::Color).block.byteSize == kPLSSlotByteSize);
        size_t slot = offset / kPLSSlotByteSize;
        DAWN_INVALID_IF(indexForSlot[slot] != kSlotNotSet,
                        "storageAttachments[%i] and storageAttachment[%i] conflict.", i,
                        indexForSlot[slot]);
        indexForSlot[slot] = i;
    }

    return {};
}

}  // namespace dawn::native
