//
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ANGLE_draw_id.cpp:
//   Test for ANGLE_draw_id extension
//

#include "GLSLANG/ShaderLang.h"
#include "angle_gl.h"
#include "compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.h"
#include "gtest/gtest.h"
#include "tests/test_utils/compiler_test.h"

using namespace sh;

class EmulateGLDrawIDTest : public MatchOutputCodeTest
{
  public:
    EmulateGLDrawIDTest()
        : MatchOutputCodeTest(GL_VERTEX_SHADER, SH_VARIABLES, SH_GLSL_COMPATIBILITY_OUTPUT)
    {
        getResources()->ANGLE_multi_draw = 1;
    }

  protected:
    void CheckCompileFailure(const std::string &shaderString, const char *expectedError = nullptr)
    {
        std::string translatedCode;
        std::string infoLog;
        bool success = compileTestShader(GL_VERTEX_SHADER, SH_GLES2_SPEC,
                                         SH_GLSL_COMPATIBILITY_OUTPUT, shaderString, getResources(),
                                         SH_VARIABLES, &translatedCode, &infoLog);
        EXPECT_FALSE(success);
        if (expectedError)
        {
            EXPECT_TRUE(infoLog.find(expectedError) != std::string::npos);
        }
    }
};

// Check that compilation fails if the compile option to emulate gl_DrawID
// is not set
TEST_F(EmulateGLDrawIDTest, RequiresEmulation)
{
    CheckCompileFailure(
        "#extension GL_ANGLE_multi_draw : require\n"
        "void main() {\n"
        "   gl_Position = vec4(float(gl_DrawID), 0.0, 0.0, 1.0);\n"
        "}\n",
        "extension is not supported");
}

// Check that compiling with emulation with gl_DrawID works with different shader versions
TEST_F(EmulateGLDrawIDTest, CheckCompile)
{
    const std::string shaderString =
        "#extension GL_ANGLE_multi_draw : require\n"
        "void main() {\n"
        "   gl_Position = vec4(float(gl_DrawID), 0.0, 0.0, 1.0);\n"
        "}\n";

    compile(shaderString, SH_OBJECT_CODE | SH_VARIABLES | SH_EMULATE_GL_DRAW_ID);
    compile("#version 100\n" + shaderString, SH_OBJECT_CODE | SH_VARIABLES | SH_EMULATE_GL_DRAW_ID);
    compile("#version 300 es\n" + shaderString,
            SH_OBJECT_CODE | SH_VARIABLES | SH_EMULATE_GL_DRAW_ID);
}

// Check that gl_DrawID is properly emulated
TEST_F(EmulateGLDrawIDTest, EmulatesUniform)
{
    addOutputType(SH_GLSL_COMPATIBILITY_OUTPUT);
    addOutputType(SH_ESSL_OUTPUT);
#ifdef ANGLE_ENABLE_VULKAN
    addOutputType(SH_GLSL_VULKAN_OUTPUT);
#endif
#ifdef ANGLE_ENABLE_HLSL
    addOutputType(SH_HLSL_3_0_OUTPUT);
    addOutputType(SH_HLSL_3_0_OUTPUT);
#endif

    const std::string &shaderString =
        "#extension GL_ANGLE_multi_draw : require\n"
        "void main() {\n"
        "   gl_Position = vec4(float(gl_DrawID), 0.0, 0.0, 1.0);\n"
        "}\n";

    compile(shaderString, SH_OBJECT_CODE | SH_VARIABLES | SH_EMULATE_GL_DRAW_ID);

    EXPECT_TRUE(notFoundInCode("gl_DrawID"));
    EXPECT_TRUE(foundInCode("angle_DrawID"));
    EXPECT_TRUE(notFoundInCode("GL_ANGLE_multi_draw"));

    EXPECT_TRUE(foundInCode(SH_GLSL_COMPATIBILITY_OUTPUT, "uniform int angle_DrawID"));
    EXPECT_TRUE(foundInCode(SH_ESSL_OUTPUT, "uniform highp int angle_DrawID"));

#ifdef ANGLE_ENABLE_VULKAN
    EXPECT_TRUE(
        foundInCode(SH_GLSL_VULKAN_OUTPUT, "uniform defaultUniformsVS\n{\n    int angle_DrawID;"));
#endif
#ifdef ANGLE_ENABLE_HLSL
    EXPECT_TRUE(foundInCode(SH_HLSL_3_0_OUTPUT, "uniform int angle_DrawID : register"));
    EXPECT_TRUE(foundInCode(SH_HLSL_3_0_OUTPUT, "uniform int angle_DrawID : register"));
#endif
}

// Check that a user-defined "gl_DrawID" is not permitted
TEST_F(EmulateGLDrawIDTest, DisallowsUserDefinedGLDrawID)
{
    // Check that it is not permitted without the extension
    CheckCompileFailure(
        "uniform int gl_DrawID;\n"
        "void main() {\n"
        "   gl_Position = vec4(float(gl_DrawID), 0.0, 0.0, 1.0);\n"
        "}\n",
        "reserved built-in name");

    CheckCompileFailure(
        "void main() {\n"
        "   int gl_DrawID = 0;\n"
        "   gl_Position = vec4(float(gl_DrawID), 0.0, 0.0, 1.0);\n"
        "}\n",
        "reserved built-in name");

    // Check that it is not permitted with the extension
    CheckCompileFailure(
        "#extension GL_ANGLE_multi_draw : require\n"
        "uniform int gl_DrawID;\n"
        "void main() {\n"
        "   gl_Position = vec4(float(gl_DrawID), 0.0, 0.0, 1.0);\n"
        "}\n",
        "reserved built-in name");

    CheckCompileFailure(
        "#extension GL_ANGLE_multi_draw : require\n"
        "void main() {\n"
        "   int gl_DrawID = 0;\n"
        "   gl_Position = vec4(float(gl_DrawID), 0.0, 0.0, 1.0);\n"
        "}\n",
        "reserved built-in name");
}

// gl_DrawID is translated to angle_DrawID internally. Check that a user-defined
// angle_DrawID is permitted
TEST_F(EmulateGLDrawIDTest, AllowsUserDefinedANGLEDrawID)
{
    addOutputType(SH_GLSL_COMPATIBILITY_OUTPUT);
    addOutputType(SH_ESSL_OUTPUT);
#ifdef ANGLE_ENABLE_VULKAN
    addOutputType(SH_GLSL_VULKAN_OUTPUT);
#endif
#ifdef ANGLE_ENABLE_HLSL
    addOutputType(SH_HLSL_3_0_OUTPUT);
    addOutputType(SH_HLSL_3_0_OUTPUT);
#endif

    const std::string &shaderString =
        "#extension GL_ANGLE_multi_draw : require\n"
        "uniform int angle_DrawID;\n"
        "void main() {\n"
        "   gl_Position = vec4(float(angle_DrawID + gl_DrawID), 0.0, 0.0, 1.0);\n"
        "}\n";

    compile(shaderString, SH_OBJECT_CODE | SH_VARIABLES | SH_EMULATE_GL_DRAW_ID);

    // " angle_DrawID" (note the space) should appear exactly twice:
    //    once in the declaration and once in the body.
    // The user-defined angle_DrawID should be decorated
    EXPECT_TRUE(foundInCode(" angle_DrawID", 2));
}
