// 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 "tests/unittests/validation/ValidationTest.h"

#include "common/Constants.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/TextureUtils.h"
#include "utils/WGPUHelpers.h"

namespace {

    constexpr wgpu::TextureFormat kNonRenderableColorFormats[] = {
        wgpu::TextureFormat::RG11B10Ufloat, wgpu::TextureFormat::RGB9E5Ufloat,
        wgpu::TextureFormat::R8Snorm,       wgpu::TextureFormat::RG8Snorm,
        wgpu::TextureFormat::RGBA8Snorm,
    };

    class TextureValidationTest : public ValidationTest {
      protected:
        void SetUp() override {
            ValidationTest::SetUp();

            queue = device.GetQueue();
        }

        wgpu::TextureDescriptor CreateDefaultTextureDescriptor() {
            wgpu::TextureDescriptor descriptor;
            descriptor.size.width = kWidth;
            descriptor.size.height = kHeight;
            descriptor.size.depthOrArrayLayers = kDefaultDepth;
            descriptor.mipLevelCount = kDefaultMipLevels;
            descriptor.sampleCount = kDefaultSampleCount;
            descriptor.dimension = wgpu::TextureDimension::e2D;
            descriptor.format = kDefaultTextureFormat;
            descriptor.usage =
                wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TextureBinding;
            return descriptor;
        }

        wgpu::Queue queue;

      private:
        static constexpr uint32_t kWidth = 32;
        static constexpr uint32_t kHeight = 32;
        static constexpr uint32_t kDefaultDepth = 1;
        static constexpr uint32_t kDefaultMipLevels = 1;
        static constexpr uint32_t kDefaultSampleCount = 1;

        static constexpr wgpu::TextureFormat kDefaultTextureFormat =
            wgpu::TextureFormat::RGBA8Unorm;
    };

    // Test the validation of sample count
    TEST_F(TextureValidationTest, SampleCount) {
        wgpu::TextureDescriptor defaultDescriptor = CreateDefaultTextureDescriptor();

        // sampleCount == 1 is allowed.
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.sampleCount = 1;

            device.CreateTexture(&descriptor);
        }

        // sampleCount == 4 is allowed.
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.sampleCount = 4;

            device.CreateTexture(&descriptor);
        }

        // It is an error to create a texture with an invalid sampleCount.
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.sampleCount = 3;

            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
        }

        // It is an error to create a multisampled texture with mipLevelCount > 1.
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.sampleCount = 4;
            descriptor.mipLevelCount = 2;

            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
        }

        // It is an error to create a multisampled 1D or 3D texture.
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.sampleCount = 4;

            descriptor.size.height = 1;
            descriptor.dimension = wgpu::TextureDimension::e1D;
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));

            descriptor.dimension = wgpu::TextureDimension::e3D;
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
        }

        // It is an error to create a multisample texture when the format cannot support
        // multisample.
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.sampleCount = 4;

            for (wgpu::TextureFormat format : kNonRenderableColorFormats) {
                // If a format can support multisample, it must be renderable.
                descriptor.format = format;
                ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
            }
        }

        // Currently we do not support multisampled 2D textures with depth>1.
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.sampleCount = 4;
            descriptor.size.depthOrArrayLayers = 2;

            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
        }

        // It is an error to set TextureUsage::StorageBinding when sampleCount > 1.
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.sampleCount = 4;
            descriptor.usage |= wgpu::TextureUsage::StorageBinding;

            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
        }
    }

    // Test the validation of the mip level count
    TEST_F(TextureValidationTest, MipLevelCount) {
        wgpu::TextureDescriptor defaultDescriptor = CreateDefaultTextureDescriptor();

        // mipLevelCount == 1 is allowed
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.size.width = 32;
            descriptor.size.height = 32;
            descriptor.mipLevelCount = 1;

            device.CreateTexture(&descriptor);
        }

        // mipLevelCount == 0 is an error
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.size.width = 32;
            descriptor.size.height = 32;
            descriptor.mipLevelCount = 0;

            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
        }

        // Full mip chains are allowed
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.size.width = 32;
            descriptor.size.height = 32;
            // Mip level sizes: 32, 16, 8, 4, 2, 1
            descriptor.mipLevelCount = 6;

            device.CreateTexture(&descriptor);
        }

        // Test non-power-of-two width
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            // Mip level width: 31, 15, 7, 3, 1
            descriptor.size.width = 31;
            descriptor.size.height = 4;

            // Full mip chains on non-power-of-two width are allowed
            descriptor.mipLevelCount = 5;
            device.CreateTexture(&descriptor);

            // Too big mip chains on non-power-of-two width are disallowed
            descriptor.mipLevelCount = 6;
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
        }

        // Test non-power-of-two height
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.size.width = 4;
            // Mip level height: 31, 15, 7, 3, 1
            descriptor.size.height = 31;

            // Full mip chains on non-power-of-two height are allowed
            descriptor.mipLevelCount = 5;
            device.CreateTexture(&descriptor);

            // Too big mip chains on non-power-of-two height are disallowed
            descriptor.mipLevelCount = 6;
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
        }

        // Undefined shift check if miplevel is bigger than the integer bit width.
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.size.width = 32;
            descriptor.size.height = 32;
            descriptor.mipLevelCount = 100;

            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
        }

        // Non square mip map halves the resolution until a 1x1 dimension
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.size.width = 32;
            descriptor.size.height = 8;
            // Mip maps: 32 * 8, 16 * 4, 8 * 2, 4 * 1, 2 * 1, 1 * 1
            descriptor.mipLevelCount = 6;

            device.CreateTexture(&descriptor);
        }

        // Non square mip map for a 3D textures
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.size.width = 32;
            descriptor.size.height = 8;
            descriptor.size.depthOrArrayLayers = 64;
            descriptor.dimension = wgpu::TextureDimension::e3D;
            // Non square mip map halves width, height and depth until a 1x1x1 dimension for a 3D
            // texture. So there are 7 mipmaps at most: 32 * 8 * 64, 16 * 4 * 32, 8 * 2 * 16,
            // 4 * 1 * 8, 2 * 1 * 4, 1 * 1 * 2, 1 * 1 * 1.
            descriptor.mipLevelCount = 7;
            device.CreateTexture(&descriptor);
        }

        // Non square mip map for 2D textures with depth > 1
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.size.width = 32;
            descriptor.size.height = 8;
            descriptor.size.depthOrArrayLayers = 64;
            // Non square mip map halves width and height until a 1x1 dimension for a 2D texture,
            // even its depth > 1. So there are 6 mipmaps at most: 32 * 8, 16 * 4, 8 * 2, 4 * 1, 2 *
            // 1, 1 * 1.
            descriptor.dimension = wgpu::TextureDimension::e2D;
            descriptor.mipLevelCount = 7;
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
            descriptor.mipLevelCount = 6;
            device.CreateTexture(&descriptor);
        }

        // Mip level exceeding kMaxTexture2DMipLevels not allowed
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.size.width = 1 >> kMaxTexture2DMipLevels;
            descriptor.size.height = 1 >> kMaxTexture2DMipLevels;
            descriptor.mipLevelCount = kMaxTexture2DMipLevels + 1u;

            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
        }
    }

    // Test the validation of array layer count
    TEST_F(TextureValidationTest, ArrayLayerCount) {
        wgpu::TextureDescriptor defaultDescriptor = CreateDefaultTextureDescriptor();

        // Array layer count exceeding kMaxTextureArrayLayers is not allowed for 2D texture
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;

            descriptor.size.depthOrArrayLayers = kMaxTextureArrayLayers + 1u;
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
        }

        // Array layer count less than kMaxTextureArrayLayers is allowed
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.size.depthOrArrayLayers = kMaxTextureArrayLayers >> 1;
            device.CreateTexture(&descriptor);
        }

        // Array layer count equal to kMaxTextureArrayLayers is allowed
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.size.depthOrArrayLayers = kMaxTextureArrayLayers;
            device.CreateTexture(&descriptor);
        }
    }

    // Test the validation of 2D texture size
    TEST_F(TextureValidationTest, 2DTextureSize) {
        wgpu::TextureDescriptor defaultDescriptor = CreateDefaultTextureDescriptor();

        // Out-of-bound texture dimension is not allowed
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.size.width = kMaxTextureDimension2D + 1u;
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));

            descriptor.size.width = 1;
            descriptor.size.height = kMaxTextureDimension2D + 1u;
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
        }

        // Zero-sized texture is not allowed
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.size = {0, 1, 1};
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));

            descriptor.size = {1, 0, 1};
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));

            descriptor.size = {1, 1, 0};
            // 2D texture with depth=0 is not allowed
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
        }

        // Texture size less than max dimension is allowed
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.size.width = kMaxTextureDimension2D >> 1;
            descriptor.size.height = kMaxTextureDimension2D >> 1;
            device.CreateTexture(&descriptor);
        }

        // Texture size equal to max dimension is allowed
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.size.width = kMaxTextureDimension2D;
            descriptor.size.height = kMaxTextureDimension2D;
            descriptor.dimension = wgpu::TextureDimension::e2D;
            device.CreateTexture(&descriptor);
        }
    }

    // Test the validation of 3D texture size
    TEST_F(TextureValidationTest, 3DTextureSize) {
        wgpu::TextureDescriptor defaultDescriptor = CreateDefaultTextureDescriptor();

        // Out-of-bound texture dimension is not allowed
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.dimension = wgpu::TextureDimension::e3D;

            descriptor.size = {kMaxTextureDimension3D + 1u, 1, 1};
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));

            descriptor.size = {1, kMaxTextureDimension3D + 1u, 1};
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));

            descriptor.size = {1, 1, kMaxTextureDimension3D + 1u};
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
        }

        // Zero-sized texture is not allowed
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.dimension = wgpu::TextureDimension::e3D;

            descriptor.size = {0, 1, 1};
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));

            descriptor.size = {1, 0, 1};
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));

            descriptor.size = {1, 1, 0};
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
        }

        // Texture size less than max dimension is allowed
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.dimension = wgpu::TextureDimension::e3D;

            descriptor.size = {kMaxTextureDimension3D >> 1, kMaxTextureDimension3D >> 1,
                               kMaxTextureDimension3D >> 1};
            device.CreateTexture(&descriptor);
        }

        // Texture size equal to max dimension is allowed
        {
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.dimension = wgpu::TextureDimension::e3D;

            descriptor.size = {kMaxTextureDimension3D, kMaxTextureDimension3D,
                               kMaxTextureDimension3D};
            device.CreateTexture(&descriptor);
        }
    }

    // Test that depth/stencil formats are invalid for 3D texture
    TEST_F(TextureValidationTest, DepthStencilFormatsFor3D) {
        wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();

        wgpu::TextureDimension dimensions[] = {
            wgpu::TextureDimension::e1D,
            wgpu::TextureDimension::e3D,
        };

        // TODO(dawn:690): Uncomment these depth/stencil formats after we implement them in Dawn.
        wgpu::TextureFormat depthStencilFormats[] = {
            wgpu::TextureFormat::Depth32Float, wgpu::TextureFormat::Depth24Plus,
            wgpu::TextureFormat::Stencil8, wgpu::TextureFormat::Depth24PlusStencil8,
            // wgpu::TextureFormat::Depth16Unorm,
            // wgpu::TextureFormat::Depth24UnormStencil8,
            // wgpu::TextureFormat::Depth32FloatStencil8,
        };

        for (wgpu::TextureDimension dimension : dimensions) {
            for (wgpu::TextureFormat format : depthStencilFormats) {
                descriptor.format = format;
                descriptor.dimension = dimension;
                ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
            }
        }
    }

    // Test that it is valid to destroy a texture
    TEST_F(TextureValidationTest, DestroyTexture) {
        wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
        wgpu::Texture texture = device.CreateTexture(&descriptor);
        texture.Destroy();
    }

    // Test that it's valid to destroy a destroyed texture
    TEST_F(TextureValidationTest, DestroyDestroyedTexture) {
        wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
        wgpu::Texture texture = device.CreateTexture(&descriptor);
        texture.Destroy();
        texture.Destroy();
    }

    // Test that it's invalid to submit a destroyed texture in a queue
    // in the case of destroy, encode, submit
    TEST_F(TextureValidationTest, DestroyEncodeSubmit) {
        wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
        wgpu::Texture texture = device.CreateTexture(&descriptor);
        wgpu::TextureView textureView = texture.CreateView();

        utils::ComboRenderPassDescriptor renderPass({textureView});

        // Destroy the texture
        texture.Destroy();

        wgpu::CommandEncoder encoder_post_destroy = device.CreateCommandEncoder();
        {
            wgpu::RenderPassEncoder pass = encoder_post_destroy.BeginRenderPass(&renderPass);
            pass.EndPass();
        }
        wgpu::CommandBuffer commands = encoder_post_destroy.Finish();

        // Submit should fail due to destroyed texture
        ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
    }

    // Test that it's invalid to submit a destroyed texture in a queue
    // in the case of encode, destroy, submit
    TEST_F(TextureValidationTest, EncodeDestroySubmit) {
        wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
        wgpu::Texture texture = device.CreateTexture(&descriptor);
        wgpu::TextureView textureView = texture.CreateView();

        utils::ComboRenderPassDescriptor renderPass({textureView});

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        {
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
            pass.EndPass();
        }
        wgpu::CommandBuffer commands = encoder.Finish();

        // Destroy the texture
        texture.Destroy();

        // Submit should fail due to destroyed texture
        ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
    }

    // Test it is an error to create an RenderAttachment texture with a non-renderable format.
    TEST_F(TextureValidationTest, NonRenderableAndRenderAttachment) {
        wgpu::TextureDescriptor descriptor;
        descriptor.size = {1, 1, 1};
        descriptor.usage = wgpu::TextureUsage::RenderAttachment;

        // Succeeds because RGBA8Unorm is renderable
        descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
        device.CreateTexture(&descriptor);

        for (wgpu::TextureFormat format : kNonRenderableColorFormats) {
            // Fails because `format` is non-renderable
            descriptor.format = format;
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
        }
    }

    // Test it is an error to create a Storage texture with any format that doesn't support
    // TextureUsage::StorageBinding texture usages.
    TEST_F(TextureValidationTest, TextureFormatNotSupportTextureUsageStorage) {
        wgpu::TextureDescriptor descriptor;
        descriptor.size = {1, 1, 1};
        descriptor.usage = wgpu::TextureUsage::StorageBinding;

        for (wgpu::TextureFormat format : utils::kAllTextureFormats) {
            descriptor.format = format;
            if (utils::TextureFormatSupportsStorageTexture(format)) {
                device.CreateTexture(&descriptor);
            } else {
                ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
            }
        }
    }

    // Test it is an error to create a texture with format "Undefined".
    TEST_F(TextureValidationTest, TextureFormatUndefined) {
        wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
        descriptor.format = wgpu::TextureFormat::Undefined;
        ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
    }

    // Test that the creation of a texture with BC format will fail when the extension
    // textureCompressionBC is not enabled.
    TEST_F(TextureValidationTest, UseBCFormatWithoutEnablingExtension) {
        for (wgpu::TextureFormat format : utils::kBCFormats) {
            wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
            descriptor.format = format;
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
        }
    }

    // TODO(jiawei.shao@intel.com): add tests to verify we cannot create 1D or 3D textures with
    // compressed texture formats.
    class CompressedTextureFormatsValidationTests : public TextureValidationTest {
      protected:
        WGPUDevice CreateTestDevice() override {
            dawn_native::DeviceDescriptor descriptor;
            descriptor.requiredExtensions = {"texture_compression_bc"};
            return adapter.CreateDevice(&descriptor);
        }

        wgpu::TextureDescriptor CreateDefaultTextureDescriptor() {
            wgpu::TextureDescriptor descriptor =
                TextureValidationTest::CreateDefaultTextureDescriptor();
            descriptor.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst |
                               wgpu::TextureUsage::TextureBinding;
            return descriptor;
        }
    };

    // Test the validation of texture size when creating textures in compressed texture formats.
    // It is invalid to use a number that is not a multiple of 4 (the compressed block width and
    // height of all BC formats) as the width or height of textures in BC formats.
    TEST_F(CompressedTextureFormatsValidationTests, TextureSize) {
        for (wgpu::TextureFormat format : utils::kBCFormats) {
            {
                wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
                descriptor.format = format;
                ASSERT_TRUE(descriptor.size.width % 4 == 0 && descriptor.size.height % 4 == 0);
                device.CreateTexture(&descriptor);
            }

            {
                wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
                descriptor.format = format;
                descriptor.size.width = 31;
                ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
            }

            {
                wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
                descriptor.format = format;
                descriptor.size.height = 31;
                ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
            }

            {
                wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
                descriptor.format = format;
                descriptor.size.width = 12;
                descriptor.size.height = 32;
                device.CreateTexture(&descriptor);
            }
        }
    }

    // Test the validation of texture usages when creating textures in compressed texture formats.
    // Only CopySrc, CopyDst and Sampled are accepted as the texture usage of the textures in BC
    // formats.
    TEST_F(CompressedTextureFormatsValidationTests, TextureUsage) {
        wgpu::TextureUsage invalidUsages[] = {
            wgpu::TextureUsage::RenderAttachment,
            wgpu::TextureUsage::StorageBinding,
            wgpu::TextureUsage::Present,
        };
        for (wgpu::TextureFormat format : utils::kBCFormats) {
            for (wgpu::TextureUsage usage : invalidUsages) {
                wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
                descriptor.format = format;
                descriptor.usage = usage;
                ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
            }
        }
    }

    TEST_F(CompressedTextureFormatsValidationTests, MipLevelCount) {
        for (wgpu::TextureFormat format : utils::kBCFormats) {
            for (uint32_t mipLevels : {1, 3, 6}) {
                wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
                descriptor.format = format;
                descriptor.mipLevelCount = mipLevels;
                device.CreateTexture(&descriptor);
            }
        }
    }

    // Test the validation of sample count when creating textures in compressed texture formats.
    // It is invalid to specify SampleCount > 1 when we create a texture in BC formats.
    TEST_F(CompressedTextureFormatsValidationTests, SampleCount) {
        for (wgpu::TextureFormat format : utils::kBCFormats) {
            wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
            descriptor.format = format;
            descriptor.sampleCount = 4;
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
        }
    }

    // Test that it is allowed to create a 2D texture with depth>1 in BC formats.
    TEST_F(CompressedTextureFormatsValidationTests, 2DArrayTexture) {
        for (wgpu::TextureFormat format : utils::kBCFormats) {
            wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
            descriptor.format = format;
            descriptor.size.depthOrArrayLayers = 6;
            device.CreateTexture(&descriptor);
        }
    }

    // Test that it is not allowed to create a 3D texture in BC formats.
    TEST_F(CompressedTextureFormatsValidationTests, 3DTexture) {
        for (wgpu::TextureFormat format : utils::kBCFormats) {
            wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
            descriptor.format = format;
            descriptor.size.depthOrArrayLayers = 4;
            descriptor.dimension = wgpu::TextureDimension::e3D;
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
        }
    }

}  // namespace
