// 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 "common/Math.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,
    };

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

    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:
        // Choose the LCM of all current compressed texture format texel dimensions as the
        // dimensions of the default texture.
        static constexpr uint32_t kWidth = 120;
        static constexpr uint32_t kHeight = 120;
        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 equal to the maximum for a 2D texture is allowed
        {
            uint32_t maxTextureDimension2D = GetSupportedLimits().limits.maxTextureDimension2D;
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.size.width = maxTextureDimension2D;
            descriptor.size.height = maxTextureDimension2D;
            descriptor.mipLevelCount = Log2(maxTextureDimension2D) + 1u;

            device.CreateTexture(&descriptor);
        }

        // Mip level exceeding the maximum for a 2D texture not allowed
        {
            uint32_t maxTextureDimension2D = GetSupportedLimits().limits.maxTextureDimension2D;
            wgpu::TextureDescriptor descriptor = defaultDescriptor;
            descriptor.size.width = maxTextureDimension2D;
            descriptor.size.height = maxTextureDimension2D;
            descriptor.mipLevelCount = Log2(maxTextureDimension2D) + 2u;

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

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

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

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

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

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

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

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

            descriptor.size.width = 1;
            descriptor.size.height = supportedLimits.maxTextureDimension2D + 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 = supportedLimits.maxTextureDimension2D >> 1;
            descriptor.size.height = supportedLimits.maxTextureDimension2D >> 1;
            device.CreateTexture(&descriptor);
        }

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

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

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

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

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

            descriptor.size = {1, 1, supportedLimits.maxTextureDimension3D + 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 = {supportedLimits.maxTextureDimension3D >> 1,
                               supportedLimits.maxTextureDimension3D >> 1,
                               supportedLimits.maxTextureDimension3D >> 1};
            device.CreateTexture(&descriptor);
        }

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

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

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

        wgpu::TextureFormat depthStencilFormats[] = {
            wgpu::TextureFormat::Stencil8,     wgpu::TextureFormat::Depth16Unorm,
            wgpu::TextureFormat::Depth24Plus,  wgpu::TextureFormat::Depth24PlusStencil8,
            wgpu::TextureFormat::Depth32Float,
        };

        for (wgpu::TextureDimension dimension : kDimensions) {
            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 depth24unorm-stencil8 will fail when the feature
    // Depth24UnormStencil8 is not enabled.
    TEST_F(TextureValidationTest, UseD24S8FormatWithoutEnablingFeature) {
        wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
        descriptor.format = wgpu::TextureFormat::Depth24UnormStencil8;
        ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
    }

    // Test that the creation of a texture with depth32float-stencil8 will fail when the feature
    // Depth32FloatStencil8 is not enabled.
    TEST_F(TextureValidationTest, UseD32S8FormatWithoutEnablingFeature) {
        wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
        descriptor.format = wgpu::TextureFormat::Depth32FloatStencil8;
        ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
    }

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

    // Test that the creation of a texture with ETC2 format will fail when the feature
    // textureCompressionETC2 is not enabled.
    TEST_F(TextureValidationTest, UseETC2FormatWithoutEnablingFeature) {
        for (wgpu::TextureFormat format : utils::kETC2Formats) {
            wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
            descriptor.format = format;
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
        }
    }

    // Test that the creation of a texture with ASTC format will fail when the feature
    // textureCompressionASTC is not enabled.
    TEST_F(TextureValidationTest, UseASTCFormatWithoutEnablingFeature) {
        for (wgpu::TextureFormat format : utils::kASTCFormats) {
            wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
            descriptor.format = format;
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
        }
    }

    class D24S8TextureFormatsValidationTests : public TextureValidationTest {
      protected:
        WGPUDevice CreateTestDevice() override {
            wgpu::DeviceDescriptor descriptor;
            wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::Depth24UnormStencil8};
            descriptor.requiredFeatures = requiredFeatures;
            descriptor.requiredFeaturesCount = 1;
            return adapter.CreateDevice(&descriptor);
        }
    };

    // Test that depth24unorm-stencil8 format is invalid for 3D texture
    TEST_F(D24S8TextureFormatsValidationTests, DepthStencilFormatsFor3D) {
        wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();

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

    class D32S8TextureFormatsValidationTests : public TextureValidationTest {
      protected:
        WGPUDevice CreateTestDevice() override {
            wgpu::DeviceDescriptor descriptor;
            wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::Depth32FloatStencil8};
            descriptor.requiredFeatures = requiredFeatures;
            descriptor.requiredFeaturesCount = 1;
            return adapter.CreateDevice(&descriptor);
        }
    };

    // Test that depth32float-stencil8 format is invalid for 3D texture
    TEST_F(D32S8TextureFormatsValidationTests, DepthStencilFormatsFor3D) {
        wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();

        for (wgpu::TextureDimension dimension : kDimensions) {
            descriptor.format = wgpu::TextureFormat::Depth32FloatStencil8;
            descriptor.dimension = dimension;
            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 {
            wgpu::DeviceDescriptor descriptor;
            wgpu::FeatureName requiredFeatures[3] = {wgpu::FeatureName::TextureCompressionBC,
                                                     wgpu::FeatureName::TextureCompressionETC2,
                                                     wgpu::FeatureName::TextureCompressionASTC};
            descriptor.requiredFeatures = requiredFeatures;
            descriptor.requiredFeaturesCount = 3;
            return adapter.CreateDevice(&descriptor);
        }

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

      private:
        // Choose the LCM of all current compressed texture format texel dimensions as the
        // dimensions of the default texture.
        static constexpr uint32_t kWidth = 120;
        static constexpr uint32_t kHeight = 120;
    };

    // Test that only CopySrc, CopyDst and Sampled are accepted as usage in compressed formats.
    TEST_F(CompressedTextureFormatsValidationTests, TextureUsage) {
        wgpu::TextureUsage invalidUsages[] = {
            wgpu::TextureUsage::RenderAttachment,
            wgpu::TextureUsage::StorageBinding,
            wgpu::TextureUsage::Present,
        };
        for (wgpu::TextureFormat format : utils::kCompressedFormats) {
            for (wgpu::TextureUsage usage : invalidUsages) {
                wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
                descriptor.format = format;
                descriptor.usage = usage;
                ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
            }
        }
    }

    // Test that using various MipLevelCount is allowed for compressed formats.
    TEST_F(CompressedTextureFormatsValidationTests, MipLevelCount) {
        for (wgpu::TextureFormat format : utils::kCompressedFormats) {
            for (uint32_t mipLevels : {1, 3, 6}) {
                wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
                descriptor.format = format;
                descriptor.mipLevelCount = mipLevels;
                device.CreateTexture(&descriptor);
            }
        }
    }

    // Test that it is invalid to specify SampleCount>1 in compressed formats.
    TEST_F(CompressedTextureFormatsValidationTests, SampleCount) {
        for (wgpu::TextureFormat format : utils::kCompressedFormats) {
            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 compressed formats.
    TEST_F(CompressedTextureFormatsValidationTests, 2DArrayTexture) {
        for (wgpu::TextureFormat format : utils::kCompressedFormats) {
            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 compressed formats.
    TEST_F(CompressedTextureFormatsValidationTests, 3DTexture) {
        for (wgpu::TextureFormat format : utils::kCompressedFormats) {
            wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
            descriptor.format = format;
            descriptor.size.depthOrArrayLayers = 4;
            descriptor.dimension = wgpu::TextureDimension::e3D;
            ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
        }
    }

    // Test that it is invalid to use numbers for a texture's width/height that are not multiples
    // of the compressed block sizes.
    TEST_F(CompressedTextureFormatsValidationTests, TextureSize) {
        for (wgpu::TextureFormat format : utils::kCompressedFormats) {
            uint32_t blockWidth = utils::GetTextureFormatBlockWidth(format);
            uint32_t blockHeight = utils::GetTextureFormatBlockHeight(format);

            // Test that the default size (120 x 120) is valid for all formats.
            {
                wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
                descriptor.format = format;
                ASSERT_TRUE(descriptor.size.width % blockWidth == 0 &&
                            descriptor.size.height % blockHeight == 0);
                device.CreateTexture(&descriptor);
            }

            // Test that invalid width should cause an error. Note that if the block width of the
            // compression type is even, we test that alignment to half the width is not sufficient.
            {
                wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
                descriptor.format = format;
                descriptor.size.width =
                    blockWidth % 2 == 0 ? blockWidth - (blockWidth / 2) : blockWidth - 1;
                ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
            }

            // Test that invalid width should cause an error. Note that if the block height of the
            // compression type is even, we test that alignment to half the height is not
            // sufficient.
            {
                wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
                descriptor.format = format;
                descriptor.size.height =
                    blockHeight % 2 == 0 ? blockHeight - (blockHeight / 2) : blockHeight - 1;
                ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
            }

            // Test a working dimension based on some constant multipliers to the dimensions.
            {
                constexpr uint32_t kWidthMultiplier = 3;
                constexpr uint32_t kHeightMultiplier = 8;
                wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
                descriptor.format = format;
                descriptor.size.width = kWidthMultiplier * blockWidth;
                descriptor.size.height = kHeightMultiplier * blockHeight;
                device.CreateTexture(&descriptor);
            }
        }
    }

}  // namespace
