// Copyright 2021 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 "dawn/utils/ComboRenderPipelineDescriptor.h"
#include "dawn/utils/WGPUHelpers.h"

namespace {
    class ExternalTextureTest : public ValidationTest {
      public:
        wgpu::TextureDescriptor CreateTextureDescriptor(
            wgpu::TextureFormat format = kDefaultTextureFormat) {
            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 = format;
            descriptor.usage = kDefaultUsage;
            return descriptor;
        }

      protected:
        void SetUp() override {
            ValidationTest::SetUp();

            queue = device.GetQueue();
        }

        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::TextureUsage kDefaultUsage =
            wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::RenderAttachment;

        static constexpr wgpu::TextureFormat kDefaultTextureFormat =
            wgpu::TextureFormat::RGBA8Unorm;
        static constexpr wgpu::TextureFormat kBiplanarPlane0Format = wgpu::TextureFormat::R8Unorm;
        static constexpr wgpu::TextureFormat kBiplanarPlane1Format = wgpu::TextureFormat::RG8Unorm;

        wgpu::Queue queue;
    };

    TEST_F(ExternalTextureTest, CreateExternalTextureValidation) {
        // Creating an external texture from a 2D, single-subresource texture should succeed.
        {
            wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
            wgpu::Texture texture = device.CreateTexture(&textureDescriptor);

            wgpu::ExternalTextureDescriptor externalDesc;
            externalDesc.plane0 = texture.CreateView();
            device.CreateExternalTexture(&externalDesc);
        }

        // Creating an external texture from a non-2D texture should fail.
        {
            wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
            textureDescriptor.dimension = wgpu::TextureDimension::e3D;
            wgpu::Texture internalTexture = device.CreateTexture(&textureDescriptor);

            wgpu::ExternalTextureDescriptor externalDesc;
            externalDesc.plane0 = internalTexture.CreateView();
            ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
        }

        // Creating an external texture from a texture with mip count > 1 should fail.
        {
            wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
            textureDescriptor.mipLevelCount = 2;
            wgpu::Texture internalTexture = device.CreateTexture(&textureDescriptor);

            wgpu::ExternalTextureDescriptor externalDesc;
            externalDesc.plane0 = internalTexture.CreateView();
            ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
        }

        // Creating an external texture from a texture without TextureUsage::TextureBinding should
        // fail.
        {
            wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
            textureDescriptor.mipLevelCount = 2;
            wgpu::Texture internalTexture = device.CreateTexture(&textureDescriptor);

            wgpu::ExternalTextureDescriptor externalDesc;
            externalDesc.plane0 = internalTexture.CreateView();
            ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
        }

        // Creating an external texture with an unsupported format should fail.
        {
            wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
            textureDescriptor.format = wgpu::TextureFormat::R8Uint;
            wgpu::Texture internalTexture = device.CreateTexture(&textureDescriptor);

            wgpu::ExternalTextureDescriptor externalDesc;
            externalDesc.plane0 = internalTexture.CreateView();
            ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
        }

        // Creating an external texture with an multisampled texture should fail.
        {
            wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
            textureDescriptor.sampleCount = 4;
            wgpu::Texture internalTexture = device.CreateTexture(&textureDescriptor);

            wgpu::ExternalTextureDescriptor externalDesc;
            externalDesc.plane0 = internalTexture.CreateView();
            ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
        }

        // Creating an external texture with an error texture view should fail.
        {
            wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
            wgpu::Texture internalTexture = device.CreateTexture(&textureDescriptor);

            wgpu::TextureViewDescriptor errorViewDescriptor;
            errorViewDescriptor.format = kDefaultTextureFormat;
            errorViewDescriptor.dimension = wgpu::TextureViewDimension::e2D;
            errorViewDescriptor.mipLevelCount = 1;
            errorViewDescriptor.arrayLayerCount = 2;
            ASSERT_DEVICE_ERROR(wgpu::TextureView errorTextureView =
                                    internalTexture.CreateView(&errorViewDescriptor));

            wgpu::ExternalTextureDescriptor externalDesc;
            externalDesc.plane0 = errorTextureView;
            ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
        }
    }

    // Test that external texture creation works as expected in multiplane scenarios.
    TEST_F(ExternalTextureTest, CreateMultiplanarExternalTextureValidation) {
        // Creating an external texture from two 2D, single-subresource textures with a biplanar
        // format should succeed.
        {
            wgpu::TextureDescriptor plane0TextureDescriptor =
                CreateTextureDescriptor(kBiplanarPlane0Format);
            wgpu::TextureDescriptor plane1TextureDescriptor =
                CreateTextureDescriptor(kBiplanarPlane1Format);
            wgpu::Texture texture0 = device.CreateTexture(&plane0TextureDescriptor);
            wgpu::Texture texture1 = device.CreateTexture(&plane1TextureDescriptor);

            wgpu::ExternalTextureDescriptor externalDesc;
            externalDesc.plane0 = texture0.CreateView();
            externalDesc.plane1 = texture1.CreateView();

            device.CreateExternalTexture(&externalDesc);
        }

        // Creating a multiplanar external texture with an unsupported format for plane0 should
        // result in an error.
        {
            wgpu::TextureDescriptor plane0TextureDescriptor =
                CreateTextureDescriptor(kDefaultTextureFormat);
            wgpu::TextureDescriptor plane1TextureDescriptor =
                CreateTextureDescriptor(kBiplanarPlane1Format);
            wgpu::Texture texture0 = device.CreateTexture(&plane0TextureDescriptor);
            wgpu::Texture texture1 = device.CreateTexture(&plane1TextureDescriptor);

            wgpu::ExternalTextureDescriptor externalDesc;
            externalDesc.plane0 = texture0.CreateView();
            externalDesc.plane1 = texture1.CreateView();

            ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
        }

        // Creating a multiplanar external texture with an unsupported format for plane1 should
        // result in an error.
        {
            wgpu::TextureDescriptor plane0TextureDescriptor =
                CreateTextureDescriptor(kBiplanarPlane0Format);
            wgpu::TextureDescriptor plane1TextureDescriptor =
                CreateTextureDescriptor(kDefaultTextureFormat);
            wgpu::Texture texture0 = device.CreateTexture(&plane0TextureDescriptor);
            wgpu::Texture texture1 = device.CreateTexture(&plane1TextureDescriptor);

            wgpu::ExternalTextureDescriptor externalDesc;
            externalDesc.plane0 = texture0.CreateView();
            externalDesc.plane1 = texture1.CreateView();

            ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
        }

        // Creating a multiplanar external texture with a non-sRGB color space should fail.
        {
            wgpu::TextureDescriptor plane0TextureDescriptor =
                CreateTextureDescriptor(kBiplanarPlane0Format);
            wgpu::TextureDescriptor plane1TextureDescriptor =
                CreateTextureDescriptor(kBiplanarPlane1Format);
            wgpu::Texture texture0 = device.CreateTexture(&plane0TextureDescriptor);
            wgpu::Texture texture1 = device.CreateTexture(&plane1TextureDescriptor);

            wgpu::ExternalTextureDescriptor externalDesc;
            externalDesc.plane0 = texture0.CreateView();
            externalDesc.plane1 = texture1.CreateView();
            externalDesc.colorSpace = wgpu::PredefinedColorSpace::Undefined;
            ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
        }
    }

    // Test that submitting a render pass that contains a destroyed external texture results in
    // an error.
    TEST_F(ExternalTextureTest, SubmitDestroyedExternalTextureInRenderPass) {
        wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
        wgpu::Texture texture = device.CreateTexture(&textureDescriptor);

        wgpu::ExternalTextureDescriptor externalDesc;
        externalDesc.plane0 = texture.CreateView();
        wgpu::ExternalTexture externalTexture = device.CreateExternalTexture(&externalDesc);

        // Create a bind group that contains the external texture.
        wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, &utils::kExternalTextureBindingLayout}});
        wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, bgl, {{0, externalTexture}});

        // Create another texture to use as a color attachment.
        wgpu::TextureDescriptor renderTextureDescriptor = CreateTextureDescriptor();
        wgpu::Texture renderTexture = device.CreateTexture(&renderTextureDescriptor);
        wgpu::TextureView renderView = renderTexture.CreateView();

        utils::ComboRenderPassDescriptor renderPass({renderView}, nullptr);

        // Control case should succeed.
        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
            {
                pass.SetBindGroup(0, bindGroup);
                pass.EndPass();
            }

            wgpu::CommandBuffer commands = encoder.Finish();

            queue.Submit(1, &commands);
        }

        // Destroying the external texture should result in an error.
        {
            externalTexture.Destroy();
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
            {
                pass.SetBindGroup(0, bindGroup);
                pass.EndPass();
            }

            wgpu::CommandBuffer commands = encoder.Finish();
            ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
        }
    }

    // Test that submitting a render pass that contains a destroyed external texture plane
    // results in an error.
    TEST_F(ExternalTextureTest, SubmitDestroyedExternalTexturePlaneInRenderPass) {
        wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
        wgpu::Texture texture = device.CreateTexture(&textureDescriptor);

        wgpu::ExternalTextureDescriptor externalDesc;
        externalDesc.plane0 = texture.CreateView();
        wgpu::ExternalTexture externalTexture = device.CreateExternalTexture(&externalDesc);

        // Create a bind group that contains the external texture.
        wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, &utils::kExternalTextureBindingLayout}});
        wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, bgl, {{0, externalTexture}});

        // Create another texture to use as a color attachment.
        wgpu::TextureDescriptor renderTextureDescriptor = CreateTextureDescriptor();
        wgpu::Texture renderTexture = device.CreateTexture(&renderTextureDescriptor);
        wgpu::TextureView renderView = renderTexture.CreateView();

        utils::ComboRenderPassDescriptor renderPass({renderView}, nullptr);

        // Control case should succeed.
        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
            {
                pass.SetBindGroup(0, bindGroup);
                pass.EndPass();
            }

            wgpu::CommandBuffer commands = encoder.Finish();

            queue.Submit(1, &commands);
        }

        // Destroying an external texture underlying plane should result in an error.
        {
            texture.Destroy();
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
            {
                pass.SetBindGroup(0, bindGroup);
                pass.EndPass();
            }

            wgpu::CommandBuffer commands = encoder.Finish();
            ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
        }
    }

    // Test that submitting a compute pass that contains a destroyed external texture results in
    // an error.
    TEST_F(ExternalTextureTest, SubmitDestroyedExternalTextureInComputePass) {
        wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
        wgpu::Texture texture = device.CreateTexture(&textureDescriptor);

        wgpu::ExternalTextureDescriptor externalDesc;
        externalDesc.plane0 = texture.CreateView();
        wgpu::ExternalTexture externalTexture = device.CreateExternalTexture(&externalDesc);

        // Create a bind group that contains the external texture.
        wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, &utils::kExternalTextureBindingLayout}});
        wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, bgl, {{0, externalTexture}});

        wgpu::ComputePassDescriptor computePass;

        // Control case should succeed.
        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass(&computePass);
            {
                pass.SetBindGroup(0, bindGroup);
                pass.EndPass();
            }

            wgpu::CommandBuffer commands = encoder.Finish();

            queue.Submit(1, &commands);
        }

        // Destroying the external texture should result in an error.
        {
            externalTexture.Destroy();
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass(&computePass);
            {
                pass.SetBindGroup(0, bindGroup);
                pass.EndPass();
            }

            wgpu::CommandBuffer commands = encoder.Finish();
            ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
        }
    }

    // Test that submitting a compute pass that contains a destroyed external texture plane
    // results in an error.
    TEST_F(ExternalTextureTest, SubmitDestroyedExternalTexturePlaneInComputePass) {
        wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
        wgpu::Texture texture = device.CreateTexture(&textureDescriptor);

        wgpu::ExternalTextureDescriptor externalDesc;
        externalDesc.plane0 = texture.CreateView();
        wgpu::ExternalTexture externalTexture = device.CreateExternalTexture(&externalDesc);

        // Create a bind group that contains the external texture.
        wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, &utils::kExternalTextureBindingLayout}});
        wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, bgl, {{0, externalTexture}});

        wgpu::ComputePassDescriptor computePass;

        // Control case should succeed.
        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass(&computePass);
            {
                pass.SetBindGroup(0, bindGroup);
                pass.EndPass();
            }

            wgpu::CommandBuffer commands = encoder.Finish();
            queue.Submit(1, &commands);
        }

        // Destroying an external texture underlying plane should result in an error.
        {
            texture.Destroy();
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass(&computePass);
            {
                pass.SetBindGroup(0, bindGroup);
                pass.EndPass();
            }

            wgpu::CommandBuffer commands = encoder.Finish();
            ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
        }
    }
}  // namespace
