1//
2// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7#include "compiler/translator/TranslatorGLSL.h"
8
9#include "compiler/translator/OutputGLSL.h"
10#include "compiler/translator/VersionGLSL.h"
11
12static void writeVersion(sh::GLenum type, TIntermNode* root,
13                         TInfoSinkBase& sink) {
14    TVersionGLSL versionGLSL(type);
15    root->traverse(&versionGLSL);
16    int version = versionGLSL.getVersion();
17    // We need to write version directive only if it is greater than 110.
18    // If there is no version directive in the shader, 110 is implied.
19    if (version > 110) {
20        sink << "#version " << version << "\n";
21    }
22}
23
24TranslatorGLSL::TranslatorGLSL(sh::GLenum type, ShShaderSpec spec)
25    : TCompiler(type, spec, SH_GLSL_OUTPUT) {
26}
27
28void TranslatorGLSL::translate(TIntermNode* root) {
29    TInfoSinkBase& sink = getInfoSink().obj;
30
31    // Write GLSL version.
32    writeVersion(getShaderType(), root, sink);
33
34    // Write extension behaviour as needed
35    writeExtensionBehavior();
36
37    // Write emulated built-in functions if needed.
38    getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition(
39        sink, false);
40
41    // Write array bounds clamping emulation if needed.
42    getArrayBoundsClamper().OutputClampingFunctionDefinition(sink);
43
44    // Write translated shader.
45    TOutputGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), getSymbolTable(), getShaderVersion());
46    root->traverse(&outputGLSL);
47}
48
49void TranslatorGLSL::writeExtensionBehavior() {
50    TInfoSinkBase& sink = getInfoSink().obj;
51    const TExtensionBehavior& extensionBehavior = getExtensionBehavior();
52    for (TExtensionBehavior::const_iterator iter = extensionBehavior.begin();
53         iter != extensionBehavior.end(); ++iter) {
54        if (iter->second == EBhUndefined)
55            continue;
56
57        // For GLSL output, we don't need to emit most extensions explicitly,
58        // but some we need to translate.
59        if (iter->first == "GL_EXT_shader_texture_lod") {
60            sink << "#extension GL_ARB_shader_texture_lod : "
61                 << getBehaviorString(iter->second) << "\n";
62        }
63    }
64}
65