// 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 "utils/WGPUHelpers.h"

class InternalUsageValidationDisabledTest : public ValidationTest {};

// Test that using DawnTextureInternalUsageDescriptor is an error if DawnInternalUsages is not
// enabled
TEST_F(InternalUsageValidationDisabledTest, TextureDescriptorRequiresFeature) {
    wgpu::TextureDescriptor textureDesc = {};
    textureDesc.size = {1, 1};
    textureDesc.usage = wgpu::TextureUsage::CopySrc;
    textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;

    // Control case: Normal texture creation works
    device.CreateTexture(&textureDesc);

    wgpu::DawnTextureInternalUsageDescriptor internalDesc = {};
    textureDesc.nextInChain = &internalDesc;

    // Error with chained feature struct.
    ASSERT_DEVICE_ERROR(device.CreateTexture(&textureDesc));

    // Also does not work with various internal usages.
    internalDesc.internalUsage = wgpu::TextureUsage::CopySrc;
    ASSERT_DEVICE_ERROR(device.CreateTexture(&textureDesc));

    internalDesc.internalUsage = wgpu::TextureUsage::CopyDst;
    ASSERT_DEVICE_ERROR(device.CreateTexture(&textureDesc));
}

// Test that using DawnEncoderInternalUsageDescriptor is an error if DawnInternalUsages is not
// enabled
TEST_F(InternalUsageValidationDisabledTest, CommandEncoderDescriptorRequiresFeature) {
    wgpu::CommandEncoderDescriptor encoderDesc = {};

    // Control case: Normal encoder creation works
    device.CreateCommandEncoder(&encoderDesc);

    wgpu::DawnEncoderInternalUsageDescriptor internalDesc = {};
    encoderDesc.nextInChain = &internalDesc;

    // Error with chained DawnEncoderInternalUsageDescriptor.
    ASSERT_DEVICE_ERROR(wgpu::CommandEncoder encoder = device.CreateCommandEncoder(&encoderDesc));

    // Check that the encoder records that it is invalid, and not any other errors.
    encoder.InjectValidationError("injected error");
    ASSERT_DEVICE_ERROR(encoder.Finish(),
                        testing::HasSubstr("[Invalid CommandEncoder] is invalid"));
}

class TextureInternalUsageValidationTest : public ValidationTest {
    WGPUDevice CreateTestDevice() override {
        wgpu::DeviceDescriptor descriptor;
        wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::DawnInternalUsages};
        descriptor.requiredFeatures = requiredFeatures;
        descriptor.requiredFeaturesCount = 1;
        return adapter.CreateDevice(&descriptor);
    }
};

// Test that internal usages can be passed in a chained descriptor.
TEST_F(TextureInternalUsageValidationTest, Basic) {
    wgpu::TextureDescriptor textureDesc = {};
    textureDesc.size = {1, 1};
    textureDesc.usage = wgpu::TextureUsage::CopySrc;
    textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;

    wgpu::DawnTextureInternalUsageDescriptor internalDesc = {};
    textureDesc.nextInChain = &internalDesc;

    // Internal usage: none
    device.CreateTexture(&textureDesc);

    // Internal usage is the same as the base usage.
    internalDesc.internalUsage = wgpu::TextureUsage::CopySrc;
    device.CreateTexture(&textureDesc);

    // Internal usage adds to the base usage.
    internalDesc.internalUsage = wgpu::TextureUsage::CopyDst;
    device.CreateTexture(&textureDesc);
}

// Test that internal usages takes part in other validation that
// depends on the usage.
TEST_F(TextureInternalUsageValidationTest, UsageValidation) {
    {
        wgpu::TextureDescriptor textureDesc = {};
        textureDesc.size = {1, 1};
        textureDesc.usage = wgpu::TextureUsage::CopySrc;
        textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;

        wgpu::DawnTextureInternalUsageDescriptor internalDesc = {};
        textureDesc.nextInChain = &internalDesc;

        // Internal usage adds an invalid usage.
        internalDesc.internalUsage = static_cast<wgpu::TextureUsage>(-1);
        ASSERT_DEVICE_ERROR(device.CreateTexture(&textureDesc));
    }

    {
        wgpu::TextureDescriptor textureDesc = {};
        textureDesc.size = {1, 1};
        textureDesc.usage = wgpu::TextureUsage::CopySrc;
        textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
        textureDesc.sampleCount = 4;

        // Control case: multisampled texture
        device.CreateTexture(&textureDesc);

        wgpu::DawnTextureInternalUsageDescriptor internalDesc = {};
        textureDesc.nextInChain = &internalDesc;

        // OK: internal usage adds nothing.
        device.CreateTexture(&textureDesc);

        // Internal usage adds storage usage which is invalid
        // with multisampling.
        internalDesc.internalUsage = wgpu::TextureUsage::StorageBinding;
        ASSERT_DEVICE_ERROR(device.CreateTexture(&textureDesc));
    }
}

// Test that internal usage does not add to the validated usage
// for command encoding
// This test also test the internal copy
TEST_F(TextureInternalUsageValidationTest, DeprecatedCommandValidation) {
    wgpu::TextureDescriptor textureDesc = {};
    textureDesc.size = {1, 1};
    textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;

    textureDesc.usage = wgpu::TextureUsage::CopyDst;
    wgpu::Texture dst = device.CreateTexture(&textureDesc);

    textureDesc.usage = wgpu::TextureUsage::CopySrc;
    wgpu::Texture src = device.CreateTexture(&textureDesc);

    textureDesc.usage = wgpu::TextureUsage::None;

    wgpu::DawnTextureInternalUsageDescriptor internalDesc = {};
    textureDesc.nextInChain = &internalDesc;
    internalDesc.internalUsage = wgpu::TextureUsage::CopySrc;

    wgpu::Texture srcInternal = device.CreateTexture(&textureDesc);

    // Control: src -> dst
    {
        wgpu::ImageCopyTexture srcImageCopyTexture = utils::CreateImageCopyTexture(src, 0, {0, 0});
        wgpu::ImageCopyTexture dstImageCopyTexture = utils::CreateImageCopyTexture(dst, 0, {0, 0});
        wgpu::Extent3D extent3D = {1, 1};

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        encoder.CopyTextureToTexture(&srcImageCopyTexture, &dstImageCopyTexture, &extent3D);
        encoder.Finish();
    }

    // Invalid: src internal -> dst
    {
        wgpu::ImageCopyTexture srcImageCopyTexture =
            utils::CreateImageCopyTexture(srcInternal, 0, {0, 0});
        wgpu::ImageCopyTexture dstImageCopyTexture = utils::CreateImageCopyTexture(dst, 0, {0, 0});
        wgpu::Extent3D extent3D = {1, 1};

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        encoder.CopyTextureToTexture(&srcImageCopyTexture, &dstImageCopyTexture, &extent3D);
        ASSERT_DEVICE_ERROR(encoder.Finish());
    }

    // Control with internal copy: src -> dst
    {
        wgpu::ImageCopyTexture srcImageCopyTexture = utils::CreateImageCopyTexture(src, 0, {0, 0});
        wgpu::ImageCopyTexture dstImageCopyTexture = utils::CreateImageCopyTexture(dst, 0, {0, 0});
        wgpu::Extent3D extent3D = {1, 1};

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        encoder.CopyTextureToTextureInternal(&srcImageCopyTexture, &dstImageCopyTexture, &extent3D);
        encoder.Finish();
    }

    // Valid with internal copy: src internal -> dst
    {
        wgpu::ImageCopyTexture srcImageCopyTexture =
            utils::CreateImageCopyTexture(srcInternal, 0, {0, 0});
        wgpu::ImageCopyTexture dstImageCopyTexture = utils::CreateImageCopyTexture(dst, 0, {0, 0});
        wgpu::Extent3D extent3D = {1, 1};

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        encoder.CopyTextureToTextureInternal(&srcImageCopyTexture, &dstImageCopyTexture, &extent3D);
        encoder.Finish();
    }
}

TEST_F(TextureInternalUsageValidationTest, CommandValidation) {
    wgpu::TextureDescriptor textureDesc = {};
    textureDesc.size = {1, 1};
    textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;

    textureDesc.usage = wgpu::TextureUsage::CopyDst;
    wgpu::Texture dst = device.CreateTexture(&textureDesc);

    textureDesc.usage = wgpu::TextureUsage::CopySrc;
    wgpu::Texture src = device.CreateTexture(&textureDesc);

    textureDesc.usage = wgpu::TextureUsage::None;

    wgpu::DawnTextureInternalUsageDescriptor internalDesc = {};
    textureDesc.nextInChain = &internalDesc;
    internalDesc.internalUsage = wgpu::TextureUsage::CopySrc;

    wgpu::Texture srcInternal = device.CreateTexture(&textureDesc);

    // Control: src -> dst
    {
        wgpu::ImageCopyTexture srcImageCopyTexture = utils::CreateImageCopyTexture(src, 0, {0, 0});
        wgpu::ImageCopyTexture dstImageCopyTexture = utils::CreateImageCopyTexture(dst, 0, {0, 0});
        wgpu::Extent3D extent3D = {1, 1};

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        encoder.CopyTextureToTexture(&srcImageCopyTexture, &dstImageCopyTexture, &extent3D);
        encoder.Finish();
    }

    // Invalid: src internal -> dst
    {
        wgpu::ImageCopyTexture srcImageCopyTexture =
            utils::CreateImageCopyTexture(srcInternal, 0, {0, 0});
        wgpu::ImageCopyTexture dstImageCopyTexture = utils::CreateImageCopyTexture(dst, 0, {0, 0});
        wgpu::Extent3D extent3D = {1, 1};

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        encoder.CopyTextureToTexture(&srcImageCopyTexture, &dstImageCopyTexture, &extent3D);
        ASSERT_DEVICE_ERROR(encoder.Finish());
    }

    // Invalid: src internal -> dst, with internal descriptor, but useInternalUsages set to false.
    {
        wgpu::ImageCopyTexture srcImageCopyTexture =
            utils::CreateImageCopyTexture(srcInternal, 0, {0, 0});
        wgpu::ImageCopyTexture dstImageCopyTexture = utils::CreateImageCopyTexture(dst, 0, {0, 0});
        wgpu::Extent3D extent3D = {1, 1};

        wgpu::CommandEncoderDescriptor encoderDesc = {};
        wgpu::DawnEncoderInternalUsageDescriptor internalDesc = {};
        internalDesc.useInternalUsages = false;
        encoderDesc.nextInChain = &internalDesc;
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder(&encoderDesc);

        encoder.CopyTextureToTexture(&srcImageCopyTexture, &dstImageCopyTexture, &extent3D);
        ASSERT_DEVICE_ERROR(encoder.Finish());
    }

    // Control with internal copy: src -> dst
    {
        wgpu::ImageCopyTexture srcImageCopyTexture = utils::CreateImageCopyTexture(src, 0, {0, 0});
        wgpu::ImageCopyTexture dstImageCopyTexture = utils::CreateImageCopyTexture(dst, 0, {0, 0});
        wgpu::Extent3D extent3D = {1, 1};

        wgpu::CommandEncoderDescriptor encoderDesc = {};
        wgpu::DawnEncoderInternalUsageDescriptor internalDesc = {};
        internalDesc.useInternalUsages = true;
        encoderDesc.nextInChain = &internalDesc;
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder(&encoderDesc);

        encoder.CopyTextureToTexture(&srcImageCopyTexture, &dstImageCopyTexture, &extent3D);
        encoder.Finish();
    }

    // Valid with internal copy: src internal -> dst
    {
        wgpu::ImageCopyTexture srcImageCopyTexture =
            utils::CreateImageCopyTexture(srcInternal, 0, {0, 0});
        wgpu::ImageCopyTexture dstImageCopyTexture = utils::CreateImageCopyTexture(dst, 0, {0, 0});
        wgpu::Extent3D extent3D = {1, 1};

        wgpu::CommandEncoderDescriptor encoderDesc = {};
        wgpu::DawnEncoderInternalUsageDescriptor internalDesc = {};
        internalDesc.useInternalUsages = true;
        encoderDesc.nextInChain = &internalDesc;
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder(&encoderDesc);

        encoder.CopyTextureToTexture(&srcImageCopyTexture, &dstImageCopyTexture, &extent3D);
        encoder.Finish();
    }
}
