// Copyright 2018 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 <limits>
#include <memory>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

#include "dawn/common/Constants.h"
#include "dawn/native/CompilationMessages.h"
#include "dawn/native/ShaderModule.h"
#include "dawn/tests/unittests/validation/ValidationTest.h"
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
#include "dawn/utils/WGPUHelpers.h"

#if TINT_BUILD_SPV_READER && !defined(__EMSCRIPTEN__)
#include "spirv-tools/optimizer.hpp"
#endif  // TINT_BUILD_SPV_READER && !defined(__EMSCRIPTEN__)

namespace dawn {
namespace {

class ShaderModuleValidationTest : public ValidationTest {};

#if TINT_BUILD_SPV_READER && !defined(__EMSCRIPTEN__)

wgpu::ShaderModule CreateShaderModuleFromASM(
    const wgpu::Device& device,
    const char* source,
    wgpu::DawnShaderModuleSPIRVOptionsDescriptor* spirv_options = nullptr) {
    // Use SPIRV-Tools's C API to assemble the SPIR-V assembly text to binary. Because the types
    // aren't RAII, we don't return directly on success and instead always go through the code
    // path that destroys the SPIRV-Tools objects.
    wgpu::ShaderModule result = nullptr;

    spv_context context = spvContextCreate(SPV_ENV_UNIVERSAL_1_3);
    DAWN_ASSERT(context != nullptr);

    spv_binary spirv = nullptr;
    spv_diagnostic diagnostic = nullptr;
    if (spvTextToBinary(context, source, strlen(source), &spirv, &diagnostic) == SPV_SUCCESS) {
        DAWN_ASSERT(spirv != nullptr);
        DAWN_ASSERT(spirv->wordCount <= std::numeric_limits<uint32_t>::max());

        wgpu::ShaderSourceSPIRV spirvDesc;
        spirvDesc.codeSize = static_cast<uint32_t>(spirv->wordCount);
        spirvDesc.code = spirv->code;
        spirvDesc.nextInChain = spirv_options;

        wgpu::ShaderModuleDescriptor descriptor;
        descriptor.nextInChain = &spirvDesc;
        result = device.CreateShaderModule(&descriptor);
    } else {
        DAWN_ASSERT(diagnostic != nullptr);
        dawn::WarningLog() << "CreateShaderModuleFromASM SPIRV assembly error:"
                           << diagnostic->position.line + 1 << ":"
                           << diagnostic->position.column + 1 << ": " << diagnostic->error;
    }

    spvDiagnosticDestroy(diagnostic);
    spvBinaryDestroy(spirv);
    spvContextDestroy(context);

    return result;
}

// Test case with a simpler shader that should successfully be created
TEST_F(ShaderModuleValidationTest, CreationSuccess) {
    const char* shader = R"(
                   OpCapability Shader
              %1 = OpExtInstImport "GLSL.std.450"
                   OpMemoryModel Logical GLSL450
                   OpEntryPoint Fragment %main "main" %fragColor
                   OpExecutionMode %main OriginUpperLeft
                   OpSource GLSL 450
                   OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
                   OpSourceExtension "GL_GOOGLE_include_directive"
                   OpName %main "main"
                   OpName %fragColor "fragColor"
                   OpDecorate %fragColor Location 0
           %void = OpTypeVoid
              %3 = OpTypeFunction %void
          %float = OpTypeFloat 32
        %v4float = OpTypeVector %float 4
    %_ptr_Output_v4float = OpTypePointer Output %v4float
      %fragColor = OpVariable %_ptr_Output_v4float Output
        %float_1 = OpConstant %float 1
        %float_0 = OpConstant %float 0
             %12 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
           %main = OpFunction %void None %3
              %5 = OpLabel
                   OpStore %fragColor %12
                   OpReturn
                   OpFunctionEnd)";

    CreateShaderModuleFromASM(device, shader);
}

// Tint's SPIR-V reader transforms a combined image sampler into two
// variables: an image part and a sampler part.  The sampler part's binding
// number is incremented. This may produce a conflict, which is solved
// by iterating further binding increments.  It's easy to use in simple cases:
// a sampled image variable effectively takes up two binding slots.
TEST_F(ShaderModuleValidationTest, CombinedTextureAndSampler) {
    // SPIR-V ASM produced by glslang for the following fragment shader:
    //
    //   #version 450
    //   layout(set = 0, binding = 0) uniform sampler2D tex;
    //   void main () {}
    //
    // Note that the following defines an interface combined texture/sampler which is not allowed
    // in Dawn / WebGPU.
    //
    //   %8 = OpTypeSampledImage %7
    //   %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
    //   %tex = OpVariable %_ptr_UniformConstant_8 UniformConstant
    const char* shader = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %main "main"
               OpExecutionMode %main OriginUpperLeft
               OpSource GLSL 450
               OpName %main "main"
               OpName %tex "tex"
               OpDecorate %tex DescriptorSet 0
               OpDecorate %tex Binding 0
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
      %float = OpTypeFloat 32
          %7 = OpTypeImage %float 2D 0 0 0 1 Unknown
          %8 = OpTypeSampledImage %7
%_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
        %tex = OpVariable %_ptr_UniformConstant_8 UniformConstant
       %main = OpFunction %void None %3
          %5 = OpLabel
               OpReturn
               OpFunctionEnd
        )";

    CreateShaderModuleFromASM(device, shader);
}

TEST_F(ShaderModuleValidationTest, ArrayOfCombinedTextureAndSampler) {
    // SPIR-V ASM produced by glslang for the following fragment shader:
    //
    //   #version 450
    //   layout(set = 0, binding = 0) uniform sampler2D tex[2];
    //   void main () {}
    //
    // Dawn/WebGPU does not yet support arrays of sampled images.
    const char* shader = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %main "main"
               OpExecutionMode %main OriginUpperLeft
               OpSource GLSL 450
               OpName %main "main"
               OpName %tex "tex"
               OpDecorate %tex Binding 0
               OpDecorate %tex DescriptorSet 0
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
      %float = OpTypeFloat 32
          %7 = OpTypeImage %float 2D 0 0 0 1 Unknown
          %8 = OpTypeSampledImage %7
       %uint = OpTypeInt 32 0
     %uint_2 = OpConstant %uint 2
%_arr_8_uint_2 = OpTypeArray %8 %uint_2
%_ptr_UniformConstant__arr_8_uint_2 = OpTypePointer UniformConstant %_arr_8_uint_2
        %tex = OpVariable %_ptr_UniformConstant__arr_8_uint_2 UniformConstant
       %main = OpFunction %void None %3
          %5 = OpLabel
               OpReturn
               OpFunctionEnd
        )";

    ASSERT_DEVICE_ERROR(CreateShaderModuleFromASM(device, shader));
}

// Test that it is not allowed to declare a multisampled-array interface texture.
// TODO(enga): Also test multisampled cube, cube array, and 3D. These have no GLSL keywords.
TEST_F(ShaderModuleValidationTest, MultisampledArrayTexture) {
    // SPIR-V ASM produced by glslang for the following fragment shader:
    //
    //  #version 450
    //  layout(set=0, binding=0) uniform texture2DMSArray tex;
    //  void main () {}}
    //
    // Note that the following defines an interface array multisampled texture which is not allowed
    // in Dawn / WebGPU.
    //
    //  %7 = OpTypeImage %float 2D 0 1 1 1 Unknown
    //  %_ptr_UniformConstant_7 = OpTypePointer UniformConstant %7
    //  %tex = OpVariable %_ptr_UniformConstant_7 UniformConstant
    const char* shader = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %main "main"
               OpExecutionMode %main OriginUpperLeft
               OpSource GLSL 450
               OpName %main "main"
               OpName %tex "tex"
               OpDecorate %tex DescriptorSet 0
               OpDecorate %tex Binding 0
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
      %float = OpTypeFloat 32
          %7 = OpTypeImage %float 2D 0 1 1 1 Unknown
%_ptr_UniformConstant_7 = OpTypePointer UniformConstant %7
        %tex = OpVariable %_ptr_UniformConstant_7 UniformConstant
       %main = OpFunction %void None %3
          %5 = OpLabel
               OpReturn
               OpFunctionEnd
        )";

    ASSERT_DEVICE_ERROR(CreateShaderModuleFromASM(device, shader));
}

const char* kShaderWithNonUniformDerivative = R"(
               OpCapability Shader
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %foo "foo" %x
               OpExecutionMode %foo OriginUpperLeft
               OpDecorate %x Location 0
      %float = OpTypeFloat 32
%_ptr_Input_float = OpTypePointer Input %float
          %x = OpVariable %_ptr_Input_float Input
       %void = OpTypeVoid
    %float_0 = OpConstantNull %float
       %bool = OpTypeBool
  %func_type = OpTypeFunction %void
        %foo = OpFunction %void None %func_type
  %foo_start = OpLabel
    %x_value = OpLoad %float %x
  %condition = OpFOrdGreaterThan %bool %x_value %float_0
               OpSelectionMerge %merge None
               OpBranchConditional %condition %true_branch %merge
%true_branch = OpLabel
     %result = OpDPdx %float %x_value
               OpBranch %merge
      %merge = OpLabel
               OpReturn
               OpFunctionEnd)";

// Test that creating a module with a SPIR-V shader that has a uniformity violation fails when no
// SPIR-V options descriptor is used.
TEST_F(ShaderModuleValidationTest, NonUniformDerivatives_NoOptions) {
    ASSERT_DEVICE_ERROR(CreateShaderModuleFromASM(device, kShaderWithNonUniformDerivative));
}

// Test that creating a module with a SPIR-V shader that has a uniformity violation fails when
// passing a SPIR-V options descriptor with the `allowNonUniformDerivatives` flag set to `false`.
TEST_F(ShaderModuleValidationTest, NonUniformDerivatives_FlagSetToFalse) {
    wgpu::DawnShaderModuleSPIRVOptionsDescriptor spirv_options_desc = {};
    spirv_options_desc.allowNonUniformDerivatives = false;
    ASSERT_DEVICE_ERROR(
        CreateShaderModuleFromASM(device, kShaderWithNonUniformDerivative, &spirv_options_desc));
}

// Test that creating a module with a SPIR-V shader that has a uniformity violation succeeds when
// passing a SPIR-V options descriptor with the `allowNonUniformDerivatives` flag set to `true`.
TEST_F(ShaderModuleValidationTest, NonUniformDerivatives_FlagSetToTrue) {
    wgpu::DawnShaderModuleSPIRVOptionsDescriptor spirv_options_desc = {};
    spirv_options_desc.allowNonUniformDerivatives = true;
    CreateShaderModuleFromASM(device, kShaderWithNonUniformDerivative, &spirv_options_desc);
}

#endif  // TINT_BUILD_SPV_READER && !defined(__EMSCRIPTEN__)

// Test that it is invalid to create a shader module with no chained descriptor. (It must be
// WGSL or SPIRV, not empty)
TEST_F(ShaderModuleValidationTest, NoChainedDescriptor) {
    wgpu::ShaderModuleDescriptor desc = {};
    ASSERT_DEVICE_ERROR(device.CreateShaderModule(&desc));
}

// Test that it is invalid to create a shader module that uses both the WGSL descriptor and the
// SPIRV descriptor.
TEST_F(ShaderModuleValidationTest, MultipleChainedDescriptor_WgslAndSpirv) {
    uint32_t code = 42;
    wgpu::ShaderModuleDescriptor desc = {};
    wgpu::ShaderSourceSPIRV spirv_desc = {};
    spirv_desc.code = &code;
    spirv_desc.codeSize = 1;
    wgpu::ShaderSourceWGSL wgsl_desc = {};
    wgsl_desc.code = "";
    wgsl_desc.nextInChain = &spirv_desc;
    desc.nextInChain = &wgsl_desc;
    ASSERT_DEVICE_ERROR(device.CreateShaderModule(&desc));
}

// Test that it is invalid to create a shader module that uses both the WGSL descriptor and the
// Dawn SPIRV options descriptor.
TEST_F(ShaderModuleValidationTest, MultipleChainedDescriptor_WgslAndDawnSpirvOptions) {
    wgpu::ShaderModuleDescriptor desc = {};
    wgpu::DawnShaderModuleSPIRVOptionsDescriptor spirv_options_desc = {};
    wgpu::ShaderSourceWGSL wgsl_desc = {};
    wgsl_desc.nextInChain = &spirv_options_desc;
    wgsl_desc.code = "";
    desc.nextInChain = &wgsl_desc;
    ASSERT_DEVICE_ERROR(device.CreateShaderModule(&desc));
}

// Test that it is invalid to create a shader module that only uses the Dawn SPIRV options
// descriptor without the SPIRV descriptor.
TEST_F(ShaderModuleValidationTest, OnlySpirvOptionsDescriptor) {
    wgpu::ShaderModuleDescriptor desc = {};
    wgpu::DawnShaderModuleSPIRVOptionsDescriptor spirv_options_desc = {};
    desc.nextInChain = &spirv_options_desc;
    ASSERT_DEVICE_ERROR(device.CreateShaderModule(&desc));
}

// Test that it is invalid to pass ShaderModuleCompilationOptions if the feature is not enabled.
TEST_F(ShaderModuleValidationTest, ShaderModuleCompilationOptionsNoFeature) {
    wgpu::ShaderModuleDescriptor desc = {};
    wgpu::ShaderSourceWGSL wgslDesc = {};
    wgslDesc.code = "@compute @workgroup_size(1) fn main() {}";

    wgpu::ShaderModuleCompilationOptions compilationOptions = {};
    desc.nextInChain = &wgslDesc;
    wgslDesc.nextInChain = &compilationOptions;
    ASSERT_DEVICE_ERROR(device.CreateShaderModule(&desc),
                        testing::HasSubstr("FeatureName::ShaderModuleCompilationOptions"));
}

// Tests that shader module compilation messages can be queried.
TEST_F(ShaderModuleValidationTest, GetCompilationMessages) {
    // This test works assuming ShaderModule is backed by a native::ShaderModuleBase, which
    // is not the case on the wire.
    DAWN_SKIP_TEST_IF(UsesWire());

    wgpu::ShaderModule shaderModule = utils::CreateShaderModule(device, R"(
        @fragment fn main() -> @location(0) vec4f {
            return vec4f(0.0, 1.0, 0.0, 1.0);
        })");

    native::ShaderModuleBase* shaderModuleBase = native::FromAPI(shaderModule.Get());

    // Build a list of messages to test.
    native::ParsedCompilationMessages messages;
    messages.AddMessageForTesting("Info Message");
    messages.AddMessageForTesting("Warning Message", wgpu::CompilationMessageType::Warning);
    messages.AddMessageForTesting("Error Message", wgpu::CompilationMessageType::Error, 3, 4);
    messages.AddMessageForTesting("Complete Message", wgpu::CompilationMessageType::Info, 3, 4, 5,
                                  6);
    auto ownedMessages = std::make_unique<native::OwnedCompilationMessages>(std::move(messages));
    // Set the messages on the shader module base.
    shaderModuleBase->SetCompilationMessagesForTesting(&ownedMessages);
    // Assert that the messages are set.
    ASSERT_EQ(ownedMessages, nullptr);

    shaderModule.GetCompilationInfo(
        wgpu::CallbackMode::AllowSpontaneous,
        [](wgpu::CompilationInfoRequestStatus status, const wgpu::CompilationInfo* info) {
            ASSERT_EQ(wgpu::CompilationInfoRequestStatus::Success, status);
            ASSERT_NE(nullptr, info);
            ASSERT_EQ(4u, info->messageCount);

            const wgpu::CompilationMessage* message = &info->messages[0];
            ASSERT_EQ("Info Message", std::string_view(message->message));
            ASSERT_EQ(wgpu::CompilationMessageType::Info, message->type);
            ASSERT_EQ(0u, message->lineNum);
            ASSERT_EQ(0u, message->linePos);
            ASSERT_NE(nullptr, message->nextInChain);
            ASSERT_EQ(wgpu::SType::DawnCompilationMessageUtf16, message->nextInChain->sType);
            const wgpu::DawnCompilationMessageUtf16* utf16 =
                reinterpret_cast<const wgpu::DawnCompilationMessageUtf16*>(message->nextInChain);
            EXPECT_EQ(0u, utf16->linePos);

            message = &info->messages[1];
            ASSERT_EQ("Warning Message", std::string_view(message->message));
            ASSERT_EQ(wgpu::CompilationMessageType::Warning, message->type);
            ASSERT_EQ(0u, message->lineNum);
            ASSERT_EQ(0u, message->linePos);
            ASSERT_NE(nullptr, message->nextInChain);
            ASSERT_EQ(wgpu::SType::DawnCompilationMessageUtf16, message->nextInChain->sType);
            utf16 =
                reinterpret_cast<const wgpu::DawnCompilationMessageUtf16*>(message->nextInChain);
            EXPECT_EQ(0u, utf16->linePos);

            message = &info->messages[2];
            ASSERT_EQ("Error Message", std::string_view(message->message));
            ASSERT_EQ(wgpu::CompilationMessageType::Error, message->type);
            ASSERT_EQ(3u, message->lineNum);
            ASSERT_EQ(4u, message->linePos);
            ASSERT_NE(nullptr, message->nextInChain);
            ASSERT_EQ(wgpu::SType::DawnCompilationMessageUtf16, message->nextInChain->sType);
            utf16 =
                reinterpret_cast<const wgpu::DawnCompilationMessageUtf16*>(message->nextInChain);
            EXPECT_EQ(4u, utf16->linePos);

            message = &info->messages[3];
            ASSERT_EQ("Complete Message", std::string_view(message->message));
            ASSERT_EQ(wgpu::CompilationMessageType::Info, message->type);
            ASSERT_EQ(3u, message->lineNum);
            ASSERT_EQ(4u, message->linePos);
            ASSERT_EQ(5u, message->offset);
            ASSERT_EQ(6u, message->length);
            ASSERT_NE(nullptr, message->nextInChain);
            ASSERT_EQ(wgpu::SType::DawnCompilationMessageUtf16, message->nextInChain->sType);
            utf16 =
                reinterpret_cast<const wgpu::DawnCompilationMessageUtf16*>(message->nextInChain);
            EXPECT_EQ(4u, utf16->linePos);
            ASSERT_EQ(5u, utf16->offset);
            ASSERT_EQ(6u, utf16->length);
        });
}

// Validate the maximum location of effective inter-stage variables cannot be greater than 16
// (kMaxInterStageShaderVariables).
TEST_F(ShaderModuleValidationTest, MaximumShaderIOLocations) {
    auto CheckTestPipeline = [&](bool success, uint32_t maximumOutputLocation,
                                 wgpu::ShaderStage failingShaderStage) {
        // Build the ShaderIO struct containing variables up to maximumOutputLocation.
        std::ostringstream stream;
        stream << "struct ShaderIO {\n";
        for (uint32_t location = 1; location <= maximumOutputLocation; ++location) {
            stream << "@location(" << location << ") var" << location << ": f32,\n";
        }

        if (failingShaderStage == wgpu::ShaderStage::Vertex) {
            stream << " @builtin(position) pos: vec4f,";
        }
        stream << "}\n";

        std::string ioStruct = stream.str();

        // Build the test pipeline. Note that it's not possible with just ASSERT_DEVICE_ERROR
        // whether it is the vertex or fragment shader that fails. So instead we will look for the
        // string "failingVertex" or "failingFragment" in the error message.
        utils::ComboRenderPipelineDescriptor pDesc;
        pDesc.cTargets[0].format = wgpu::TextureFormat::RGBA8Unorm;

        const char* errorMatcher = nullptr;
        switch (failingShaderStage) {
            case wgpu::ShaderStage::Vertex: {
                errorMatcher = "failingVertex";
                pDesc.vertex.entryPoint = "failingVertex";
                pDesc.vertex.module = utils::CreateShaderModule(device, (ioStruct + R"(
                    @vertex fn failingVertex() -> ShaderIO {
                        var shaderIO : ShaderIO;
                        shaderIO.pos = vec4f(0.0, 0.0, 0.0, 1.0);
                        return shaderIO;
                     }
                )")
                                                                            .c_str());
                pDesc.cFragment.module = utils::CreateShaderModule(device, R"(
                    @fragment fn main() -> @location(0) vec4f {
                        return vec4f(0.0);
                    }
                )");
                break;
            }

            case wgpu::ShaderStage::Fragment: {
                errorMatcher = "failingFragment";
                pDesc.cFragment.entryPoint = "failingFragment";
                pDesc.cFragment.module = utils::CreateShaderModule(device, (ioStruct + R"(
                    @fragment fn failingFragment(io : ShaderIO) -> @location(0) vec4f {
                        return vec4f(0.0);
                     }
                )")
                                                                               .c_str());
                pDesc.vertex.module = utils::CreateShaderModule(device, R"(
                    @vertex fn main() -> @builtin(position) vec4f {
                        return vec4f(0.0);
                    }
                )");
                break;
            }

            default:
                DAWN_UNREACHABLE();
        }

        if (success) {
            if (failingShaderStage == wgpu::ShaderStage::Vertex) {
                // It is allowed that fragment inputs are a subset of the vertex output variables.
                device.CreateRenderPipeline(&pDesc);
            } else {
                ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&pDesc),
                                    testing::HasSubstr("The fragment input at location"));
            }
        } else {
            ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&pDesc),
                                testing::HasSubstr(errorMatcher));
        }
    };

    // It is allowed to create a shader module with the maximum active vertex output location ==
    // (kMaxInterStageShaderVariables - 1);
    CheckTestPipeline(true, kMaxInterStageShaderVariables - 1, wgpu::ShaderStage::Vertex);

    // It isn't allowed to create a shader module with the maximum active vertex output location ==
    // kMaxInterStageShaderVariables;
    CheckTestPipeline(false, kMaxInterStageShaderVariables, wgpu::ShaderStage::Vertex);

    // It is allowed to create a shader module with the maximum active fragment input location ==
    // (kMaxInterStageShaderVariables - 1);
    CheckTestPipeline(true, kMaxInterStageShaderVariables - 1, wgpu::ShaderStage::Fragment);

    // It isn't allowed to create a shader module with the maximum active vertex output location ==
    // kMaxInterStageShaderVariables;
    CheckTestPipeline(false, kMaxInterStageShaderVariables, wgpu::ShaderStage::Fragment);
}

// Validate the number of total inter-stage user-defined variables count and built-in variables
// cannot exceed kMaxInterStageShaderVariables.
TEST_F(ShaderModuleValidationTest, MaximumInterStageShaderVariables) {
    auto CheckTestPipeline = [&](bool success,
                                 uint32_t totalUserDefinedInterStageShaderVariablesCount,
                                 wgpu::ShaderStage failingShaderStage,
                                 const char* extraBuiltInDeclarations = "",
                                 bool usePointListAsPrimitiveType = false) {
        // Build the ShaderIO struct containing totalUserDefinedInterStageShaderVariablesCount
        // variables.
        std::ostringstream stream;
        stream << "struct ShaderIO {\n" << extraBuiltInDeclarations << "\n";
        uint32_t vec4InputLocations = totalUserDefinedInterStageShaderVariablesCount;

        for (uint32_t location = 0; location < vec4InputLocations; ++location) {
            stream << "@location(" << location << ") var" << location << ": vec4f,\n";
        }

        if (failingShaderStage == wgpu::ShaderStage::Vertex) {
            stream << " @builtin(position) pos: vec4f,\n";
        }
        stream << "}\n";

        std::string ioStruct = stream.str();

        // Build the test pipeline. Note that it's not possible with just ASSERT_DEVICE_ERROR
        // whether it is the vertex or fragment shader that fails. So instead we will look for the
        // string "failingVertex" or "failingFragment" in the error message.
        utils::ComboRenderPipelineDescriptor pDesc;
        pDesc.cTargets[0].format = wgpu::TextureFormat::RGBA8Unorm;
        if (usePointListAsPrimitiveType) {
            pDesc.primitive.topology = wgpu::PrimitiveTopology::PointList;
        } else {
            pDesc.primitive.topology = wgpu::PrimitiveTopology::TriangleList;
        }

        const char* errorMatcher = nullptr;
        switch (failingShaderStage) {
            case wgpu::ShaderStage::Vertex: {
                if (usePointListAsPrimitiveType) {
                    errorMatcher = "PointList";
                } else {
                    errorMatcher = "failingVertex";
                }

                std::string shader = ioStruct + R"(
                    @vertex fn failingVertex() -> ShaderIO {
                        var shaderIO : ShaderIO;
                        shaderIO.pos = vec4f(0.0, 0.0, 0.0, 1.0);
                        return shaderIO;
                     }
                    @fragment fn main() -> @location(0) vec4f {
                        return vec4f(0.0);
                    })";
                wgpu::ShaderModule shaderModule = utils::CreateShaderModule(device, shader);

                pDesc.vertex.entryPoint = "failingVertex";
                pDesc.vertex.module = shaderModule;
                pDesc.cFragment.module = shaderModule;
                break;
            }

            case wgpu::ShaderStage::Fragment: {
                std::string shader = ioStruct + R"(
                     @vertex fn main() -> @builtin(position) vec4f {
                        return vec4f(0.0);
                     }
                     @fragment fn failingFragment(io : ShaderIO) -> @location(0) vec4f {
                        return vec4f(0.0);
                     })";
                wgpu::ShaderModule shaderModule = utils::CreateShaderModule(device, shader);

                errorMatcher = "failingFragment";
                pDesc.cFragment.entryPoint = "failingFragment";
                pDesc.cFragment.module = shaderModule;
                pDesc.vertex.module = shaderModule;
                break;
            }

            default:
                DAWN_UNREACHABLE();
        }

        if (success) {
            if (failingShaderStage == wgpu::ShaderStage::Vertex) {
                // It is allowed that fragment inputs are a subset of the vertex output variables.
                device.CreateRenderPipeline(&pDesc);
            } else {
                ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&pDesc),
                                    testing::HasSubstr("The fragment input at location"));
            }
        } else {
            ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&pDesc),
                                testing::HasSubstr(errorMatcher));
        }
    };

    // Verify when there is no input builtin variable in a fragment shader, the total user-defined
    // input variables count must be less than kMaxInterStageShaderVariables.
    {
        CheckTestPipeline(true, kMaxInterStageShaderVariables, wgpu::ShaderStage::Fragment);
        CheckTestPipeline(false, kMaxInterStageShaderVariables + 1, wgpu::ShaderStage::Fragment);
    }

    // Verify the total user-defined vertex output variables count must be less than
    // kMaxInterStageShaderVariables.
    {
        CheckTestPipeline(true, kMaxInterStageShaderVariables, wgpu::ShaderStage::Vertex);
        CheckTestPipeline(false, kMaxInterStageShaderVariables + 1, wgpu::ShaderStage::Vertex);
    }

    // Verify the total user-defined vertex output variables count must be less than or equal to
    // (kMaxInterStageShaderVariables - 1) when the primitive topology is PointList.
    {
        constexpr bool kUsePointListAsPrimitiveTopology = true;
        const char* kExtraBuiltins = "";

        {
            uint32_t variablesCount = kMaxInterStageShaderVariables - 1;
            CheckTestPipeline(true, variablesCount, wgpu::ShaderStage::Vertex, kExtraBuiltins,
                              kUsePointListAsPrimitiveTopology);
        }
        {
            uint32_t variablesCount = kMaxInterStageShaderVariables;
            CheckTestPipeline(false, variablesCount, wgpu::ShaderStage::Vertex, kExtraBuiltins,
                              kUsePointListAsPrimitiveTopology);
        }
    }

    // @builtin(position) in fragment shaders shouldn't be counted into the maximum inter-stage
    // variables count.
    {
        CheckTestPipeline(true, kMaxInterStageShaderVariables, wgpu::ShaderStage::Fragment,
                          "@builtin(position) fragCoord : vec4f,");
    }

    // @builtin(front_facing), @builtin(sample_index) and @builtin(sample_mask) should all be
    // counted into the maximum inter-stage variables count. Then the maximum user-defined
    // inter-stage shader variables can only be (kMaxInterStageShaderVariables - 1) because these
    // user-defined inter-stage shader variables always consume 1 shader variable.
    {
        constexpr uint8_t kMaskFrontFacing = 1;
        constexpr uint8_t kMaskSampleIndex = 1 << 1;
        constexpr uint8_t kMaskSampleMask = 1 << 2;
        for (uint8_t mask = 1; mask <= 7; ++mask) {
            std::string builtInDeclarations = "";
            if (mask & kMaskFrontFacing) {
                builtInDeclarations += "@builtin(front_facing) frontFacing : bool,";
            }
            if (mask & kMaskSampleIndex) {
                builtInDeclarations += "@builtin(sample_index) sampleIndex : u32,";
            }
            if (mask & kMaskSampleMask) {
                builtInDeclarations += "@builtin(sample_mask) sampleMask : u32,";
            }

            {
                uint32_t variablesCount = kMaxInterStageShaderVariables - 1;
                CheckTestPipeline(true, variablesCount, wgpu::ShaderStage::Fragment,
                                  builtInDeclarations.c_str());
            }
            {
                uint32_t variablesCount = kMaxInterStageShaderVariables;
                CheckTestPipeline(false, variablesCount, wgpu::ShaderStage::Fragment,
                                  builtInDeclarations.c_str());
            }
        }
    }
}

// Test that numeric ID must be unique
TEST_F(ShaderModuleValidationTest, OverridableConstantsNumericIDConflicts) {
    ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, R"(
@id(1234) override c0: u32;
@id(1234) override c1: u32;

struct Buf {
    data : array<u32, 2>
}

@group(0) @binding(0) var<storage, read_write> buf : Buf;

@compute @workgroup_size(1) fn main() {
    // make sure the overridable constants are not optimized out
    buf.data[0] = c0;
    buf.data[1] = c1;
})"));
}

// Test that @binding must be less then kMaxBindingsPerBindGroup
TEST_F(ShaderModuleValidationTest, MaxBindingNumber) {
    static_assert(kMaxBindingsPerBindGroup == 1000);

    wgpu::ComputePipelineDescriptor desc;

    // kMaxBindingsPerBindGroup-1 is valid.
    desc.compute.module = utils::CreateShaderModule(device, R"(
        @group(0) @binding(999) var s : sampler;
        @compute @workgroup_size(1) fn main() {
            _ = s;
        }
    )");
    device.CreateComputePipeline(&desc);

    // kMaxBindingsPerBindGroup is an error
    desc.compute.module = utils::CreateShaderModule(device, R"(
        @group(0) @binding(1000) var s : sampler;
        @compute @workgroup_size(1) fn main() {
            _ = s;
        }
    )");
    ASSERT_DEVICE_ERROR(device.CreateComputePipeline(&desc));
}

// Test that missing decorations on shader IO or bindings causes a validation error.
TEST_F(ShaderModuleValidationTest, MissingDecorations) {
    // Vertex input.
    utils::CreateShaderModule(device, R"(
        @vertex fn main(@location(0) a : vec4f) -> @builtin(position) vec4f {
            return vec4(1.0);
        }
    )");
    ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, R"(
        @vertex fn main(a : vec4f) -> @builtin(position) vec4f {
            return vec4(1.0);
        }
    )"));

    // Vertex output
    utils::CreateShaderModule(device, R"(
        struct Output {
            @builtin(position) pos : vec4f,
            @location(0) a : f32,
        }
        @vertex fn main() -> Output {
            var output : Output;
            return output;
        }
    )");
    ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, R"(
        struct Output {
            @builtin(position) pos : vec4f,
            a : f32,
        }
        @vertex fn main() -> Output {
            var output : Output;
            return output;
        }
    )"));

    // Fragment input
    utils::CreateShaderModule(device, R"(
        @fragment fn main(@location(0) a : vec4f) -> @location(0) f32 {
            return 1.0;
        }
    )");
    ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, R"(
        @fragment fn main(a : vec4f) -> @location(0) f32 {
            return 1.0;
        }
    )"));

    // Fragment input
    utils::CreateShaderModule(device, R"(
        @fragment fn main() -> @location(0) f32 {
            return 1.0;
        }
    )");
    ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, R"(
        @fragment fn main() -> f32 {
            return 1.0;
        }
    )"));

    // Binding decorations
    utils::CreateShaderModule(device, R"(
        @group(0) @binding(0) var s : sampler;
        @fragment fn main() -> @location(0) f32 {
            _ = s;
            return 1.0;
        }
    )");
    ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, R"(
        @binding(0) var s : sampler;
        @fragment fn main() -> @location(0) f32 {
            _ = s;
            return 1.0;
        }
    )"));
    ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, R"(
        @group(0) var s : sampler;
        @fragment fn main() -> @location(0) f32 {
            _ = s;
            return 1.0;
        }
    )"));
}

// Test creating an error shader module with device.CreateErrorShaderModule()
TEST_F(ShaderModuleValidationTest, CreateErrorShaderModule) {
    wgpu::ShaderSourceWGSL wgslDesc = {};
    wgpu::ShaderModuleDescriptor descriptor = {};
    descriptor.nextInChain = &wgslDesc;
    wgslDesc.code = "@compute @workgroup_size(1) fn main() {}";

    wgpu::ShaderModule errorShaderModule;
    ASSERT_DEVICE_ERROR(errorShaderModule = device.CreateErrorShaderModule(
                            &descriptor, "Shader compilation error"));

    errorShaderModule.GetCompilationInfo(
        wgpu::CallbackMode::AllowSpontaneous,
        [](wgpu::CompilationInfoRequestStatus status, const wgpu::CompilationInfo* info) {
            ASSERT_EQ(wgpu::CompilationInfoRequestStatus::Success, status);
            ASSERT_NE(nullptr, info);
            ASSERT_EQ(1u, info->messageCount);

            const wgpu::CompilationMessage* message = &info->messages[0];
            ASSERT_EQ("Shader compilation error", std::string_view(message->message));
            ASSERT_EQ(wgpu::CompilationMessageType::Error, message->type);
            ASSERT_EQ(0u, message->lineNum);
            ASSERT_EQ(0u, message->linePos);
        });

    FlushWire();
}

struct WGSLExtensionInfo {
    const char* wgslName;
    // Is this WGSL extension experimental, i.e. guarded by AllowUnsafeAPIs toggle
    bool isExperimental;
    // The WebGPU features that required to enable this extension, set to empty if no feature
    // required.
    const std::vector<const char*> requiredFeatureNames;
    // The WGSL extensions dependency that required to enable this extension, set to empty if no
    // dependency.
    const std::vector<const char*> dependingExtensionNames;
};

const struct WGSLExtensionInfo kExtensions[] = {
    {"f16", false, {"shader-f16"}, {}},
    {"clip_distances", false, {"clip-distances"}, {}},
    {"dual_source_blending", false, {"dual-source-blending"}, {}},
    {"subgroups", false, {"subgroups"}, {}},
    {"primitive_index", false, {"primitive-index"}, {}},
    {"chromium_experimental_pixel_local", true, {"pixel-local-storage-coherent"}, {}},
    {"chromium_disable_uniformity_analysis", true, {}, {}},
    {"chromium_internal_graphite", true, {}, {}},
    {"chromium_experimental_framebuffer_fetch", true, {"framebuffer-fetch"}, {}},
    {"chromium_experimental_subgroup_matrix", true, {"chromium-experimental-subgroup-matrix"}, {}},
    {"chromium_experimental_dynamic_binding", true, {"chromium-experimental-bindless"}, {}}

    // Currently the following WGSL extensions are not enabled under any situation.
    /*
    {"chromium_experimental_immediate", true, {}},
    {"chromium_internal_relaxed_uniform_layout", true, {}},
    */
};

std::string EnableDependingWGSLExtensions(const WGSLExtensionInfo& extension) {
    std::stringstream s;
    for (const char* dependency : extension.dependingExtensionNames) {
        s << "enable " << dependency << ";\n";
    }
    return s.str();
}

class ShaderModuleExtensionValidationTestBase : public ValidationTest {
  protected:
    // Skip tests if using Wire, because some features are not supported by the wire and cause the
    // device creation failed.
    void SetUp() override {
        DAWN_SKIP_TEST_IF(UsesWire());
        ValidationTest::SetUp();
    }

    std::vector<wgpu::FeatureName> GetAllFeatures() {
        std::vector<wgpu::FeatureName> requiredFeatures;
        wgpu::SupportedFeatures supportedFeatures;
        adapter.GetFeatures(&supportedFeatures);
        for (uint32_t i = 0; i < supportedFeatures.featureCount; ++i) {
            requiredFeatures.push_back(supportedFeatures.features[i]);
        }
        return requiredFeatures;
    }
};

// Test validating WGSL extension on safe device with no feature required.
class ShaderModuleExtensionValidationTestSafeNoFeature
    : public ShaderModuleExtensionValidationTestBase {
  protected:
    bool AllowUnsafeAPIs() override { return false; }
    std::vector<wgpu::FeatureName> GetRequiredFeatures() override { return {}; }
};

TEST_F(ShaderModuleExtensionValidationTestSafeNoFeature,
       OnlyStableExtensionsRequiringNoFeatureAllowed) {
    for (auto& extension : kExtensions) {
        std::string wgsl = EnableDependingWGSLExtensions(extension) + std::string("enable ") +
                           extension.wgslName + R"(;

@compute @workgroup_size(1) fn main() {})";

        // On a safe device with no feature required, only stable extensions requiring no features
        // are allowed.
        if (!extension.isExperimental && extension.requiredFeatureNames.size() == 0) {
            utils::CreateShaderModule(device, wgsl.c_str());
        } else {
            ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, wgsl.c_str()));
        }
    }
}

// Test validating WGSL extension on unsafe device with no feature required.
class ShaderModuleExtensionValidationTestUnsafeNoFeature
    : public ShaderModuleExtensionValidationTestBase {
  protected:
    std::vector<wgpu::FeatureName> GetRequiredFeatures() override { return {}; }
};

TEST_F(ShaderModuleExtensionValidationTestUnsafeNoFeature,
       OnlyExtensionsRequiringNoFeatureAllowed) {
    for (auto& extension : kExtensions) {
        std::string wgsl = EnableDependingWGSLExtensions(extension) + std::string("enable ") +
                           extension.wgslName + R"(;

@compute @workgroup_size(1) fn main() {})";

        // On an unsafe device with no feature required, only extensions requiring no features are
        // allowed.
        if (extension.requiredFeatureNames.size() == 0) {
            utils::CreateShaderModule(device, wgsl.c_str());
        } else {
            ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, wgsl.c_str()));
        }
    }
}

// Test validating WGSL extension on safe device with all features required.
class ShaderModuleExtensionValidationTestSafeAllFeatures
    : public ShaderModuleExtensionValidationTestBase {
  protected:
    bool AllowUnsafeAPIs() override { return false; }
    std::vector<wgpu::FeatureName> GetRequiredFeatures() override { return GetAllFeatures(); }
};

TEST_F(ShaderModuleExtensionValidationTestSafeAllFeatures, OnlyStableExtensionsAllowed) {
    for (auto& extension : kExtensions) {
        std::string wgsl = EnableDependingWGSLExtensions(extension) + std::string("enable ") +
                           extension.wgslName + R"(;

@compute @workgroup_size(1) fn main() {})";

        // On a safe device with all feature required, only stable extensions are allowed.
        if (!extension.isExperimental) {
            utils::CreateShaderModule(device, wgsl.c_str());
        } else {
            ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, wgsl.c_str()));
        }
    }
}

// Test validating WGSL extension on unsafe device with all features required.
class ShaderModuleExtensionValidationTestUnsafeAllFeatures
    : public ShaderModuleExtensionValidationTestBase {
  protected:
    std::vector<wgpu::FeatureName> GetRequiredFeatures() override { return GetAllFeatures(); }
};

TEST_F(ShaderModuleExtensionValidationTestUnsafeAllFeatures, AllExtensionsAllowed) {
    for (auto& extension : kExtensions) {
        std::string wgsl = EnableDependingWGSLExtensions(extension) + std::string("enable ") +
                           extension.wgslName + R"(;

@compute @workgroup_size(1) fn main() {})";

        // On an unsafe device with all feature required, all extensions are allowed.
        utils::CreateShaderModule(device, wgsl.c_str());
    }
}

// Test it is valid to chain ShaderModuleCompilationOptions and path true/false for strictMath.
TEST_F(ShaderModuleExtensionValidationTestUnsafeAllFeatures, ShaderModuleCompilationOptions) {
    wgpu::ShaderModuleDescriptor desc = {};
    wgpu::ShaderSourceWGSL wgslDesc = {};
    wgslDesc.code = "@compute @workgroup_size(1) fn main() {}";

    wgpu::ShaderModuleCompilationOptions compilationOptions = {};
    desc.nextInChain = &wgslDesc;
    wgslDesc.nextInChain = &compilationOptions;

    compilationOptions.strictMath = false;
    device.CreateShaderModule(&desc);

    compilationOptions.strictMath = true;
    device.CreateShaderModule(&desc);
}

}  // anonymous namespace
}  // namespace dawn
