//
// Copyright 2002 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.
//

#include "compiler/translator/VersionGLSL.h"

#include "angle_gl.h"
#include "compiler/translator/Symbol.h"
#include "nb/cpp14oncpp11.h"

namespace sh
{

namespace
{
CONSTEXPR const ImmutableString kGlPointCoordString("gl_PointCoord");
}  // anonymous namespace

int ShaderOutputTypeToGLSLVersion(ShShaderOutput output)
{
    switch (output)
    {
        case SH_GLSL_130_OUTPUT:
            return GLSL_VERSION_130;
        case SH_GLSL_140_OUTPUT:
            return GLSL_VERSION_140;
        case SH_GLSL_150_CORE_OUTPUT:
            return GLSL_VERSION_150;
        case SH_GLSL_330_CORE_OUTPUT:
            return GLSL_VERSION_330;
        case SH_GLSL_400_CORE_OUTPUT:
            return GLSL_VERSION_400;
        case SH_GLSL_410_CORE_OUTPUT:
            return GLSL_VERSION_410;
        case SH_GLSL_420_CORE_OUTPUT:
            return GLSL_VERSION_420;
        case SH_GLSL_430_CORE_OUTPUT:
            return GLSL_VERSION_430;
        case SH_GLSL_440_CORE_OUTPUT:
            return GLSL_VERSION_440;
        case SH_GLSL_450_CORE_OUTPUT:
            return GLSL_VERSION_450;
        case SH_GLSL_COMPATIBILITY_OUTPUT:
            return GLSL_VERSION_110;
        default:
            UNREACHABLE();
            return 0;
    }
}

// We need to scan for the following:
// 1. "invariant" keyword: This can occur in both - vertex and fragment shaders
//    but only at the global scope.
// 2. "gl_PointCoord" built-in variable: This can only occur in fragment shader
//    but inside any scope.
// 3. Call to a matrix constructor with another matrix as argument.
//    (These constructors were reserved in GLSL version 1.10.)
// 4. Arrays as "out" function parameters.
//    GLSL spec section 6.1.1: "When calling a function, expressions that do
//    not evaluate to l-values cannot be passed to parameters declared as
//    out or inout."
//    GLSL 1.1 section 5.8: "Other binary or unary expressions,
//    non-dereferenced arrays, function names, swizzles with repeated fields,
//    and constants cannot be l-values."
//    GLSL 1.2 relaxed the restriction on arrays, section 5.8: "Variables that
//    are built-in types, entire structures or arrays... are all l-values."
//
TVersionGLSL::TVersionGLSL(sh::GLenum type, const TPragma &pragma, ShShaderOutput output)
    : TIntermTraverser(true, false, false)
{
    mVersion = ShaderOutputTypeToGLSLVersion(output);
    if (pragma.stdgl.invariantAll)
    {
        ensureVersionIsAtLeast(GLSL_VERSION_120);
    }
    if (type == GL_COMPUTE_SHADER)
    {
        ensureVersionIsAtLeast(GLSL_VERSION_430);
    }
}

void TVersionGLSL::visitSymbol(TIntermSymbol *node)
{
    if (node->variable().symbolType() == SymbolType::BuiltIn &&
        node->getName() == kGlPointCoordString)
    {
        ensureVersionIsAtLeast(GLSL_VERSION_120);
    }
}

bool TVersionGLSL::visitDeclaration(Visit, TIntermDeclaration *node)
{
    const TIntermSequence &sequence = *(node->getSequence());
    if (sequence.front()->getAsTyped()->getType().isInvariant())
    {
        ensureVersionIsAtLeast(GLSL_VERSION_120);
    }
    return true;
}

bool TVersionGLSL::visitGlobalQualifierDeclaration(Visit, TIntermGlobalQualifierDeclaration *node)
{
    ensureVersionIsAtLeast(GLSL_VERSION_120);
    return true;
}

void TVersionGLSL::visitFunctionPrototype(TIntermFunctionPrototype *node)
{
    size_t paramCount = node->getFunction()->getParamCount();
    for (size_t i = 0; i < paramCount; ++i)
    {
        const TVariable *param = node->getFunction()->getParam(i);
        const TType &type      = param->getType();
        if (type.isArray())
        {
            TQualifier qualifier = type.getQualifier();
            if ((qualifier == EvqOut) || (qualifier == EvqInOut))
            {
                ensureVersionIsAtLeast(GLSL_VERSION_120);
                break;
            }
        }
    }
}

bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node)
{
    if (node->getOp() == EOpConstruct && node->getType().isMatrix())
    {
        const TIntermSequence &sequence = *(node->getSequence());
        if (sequence.size() == 1)
        {
            TIntermTyped *typed = sequence.front()->getAsTyped();
            if (typed && typed->isMatrix())
            {
                ensureVersionIsAtLeast(GLSL_VERSION_120);
            }
        }
    }
    return true;
}

void TVersionGLSL::ensureVersionIsAtLeast(int version)
{
    mVersion = std::max(version, mVersion);
}

}  // namespace sh
