summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.h
blob: 5552eb606f7a04355225f91c646720d9ac55e9b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//
// 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.
//

#ifndef COMPILER_TRANSLATOR_OUTPUTGLSLBASE_H_
#define COMPILER_TRANSLATOR_OUTPUTGLSLBASE_H_

#include <set>

#include "compiler/translator/ExtensionBehavior.h"
#include "compiler/translator/HashNames.h"
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/Pragma.h"
#include "compiler/translator/tree_util/IntermTraverse.h"

namespace sh
{
class TCompiler;

class TOutputGLSLBase : public TIntermTraverser
{
  public:
    TOutputGLSLBase(TCompiler *compiler,
                    TInfoSinkBase &objSink,
                    const ShCompileOptions &compileOptions);

    ShShaderOutput getShaderOutput() const { return mOutput; }

    // Return the original name if hash function pointer is NULL;
    // otherwise return the hashed name. Has special handling for internal names and built-ins,
    // which are not hashed.
    ImmutableString hashName(const TSymbol *symbol);

  protected:
    TInfoSinkBase &objSink() { return mObjSink; }
    void writeFloat(TInfoSinkBase &out, float f);
    void writeTriplet(Visit visit, const char *preStr, const char *inStr, const char *postStr);
    std::string getCommonLayoutQualifiers(TIntermSymbol *variable);
    std::string getMemoryQualifiers(const TType &type);
    virtual void writeLayoutQualifier(TIntermSymbol *variable);
    void writeFieldLayoutQualifier(const TField *field);
    void writeInvariantQualifier(const TType &type);
    void writePreciseQualifier(const TType &type);
    virtual void writeVariableType(const TType &type,
                                   const TSymbol *symbol,
                                   bool isFunctionArgument);
    virtual bool writeVariablePrecision(TPrecision precision) = 0;
    void writeFunctionParameters(const TFunction *func);
    const TConstantUnion *writeConstantUnion(const TType &type, const TConstantUnion *pConstUnion);
    void writeConstructorTriplet(Visit visit, const TType &type);
    ImmutableString getTypeName(const TType &type);

    void visitSymbol(TIntermSymbol *node) override;
    void visitConstantUnion(TIntermConstantUnion *node) override;
    bool visitSwizzle(Visit visit, TIntermSwizzle *node) override;
    bool visitBinary(Visit visit, TIntermBinary *node) override;
    bool visitUnary(Visit visit, TIntermUnary *node) override;
    bool visitTernary(Visit visit, TIntermTernary *node) override;
    bool visitIfElse(Visit visit, TIntermIfElse *node) override;
    bool visitSwitch(Visit visit, TIntermSwitch *node) override;
    bool visitCase(Visit visit, TIntermCase *node) override;
    void visitFunctionPrototype(TIntermFunctionPrototype *node) override;
    bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
    bool visitAggregate(Visit visit, TIntermAggregate *node) override;
    bool visitBlock(Visit visit, TIntermBlock *node) override;
    bool visitGlobalQualifierDeclaration(Visit visit,
                                         TIntermGlobalQualifierDeclaration *node) override;
    bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
    bool visitLoop(Visit visit, TIntermLoop *node) override;
    bool visitBranch(Visit visit, TIntermBranch *node) override;
    void visitPreprocessorDirective(TIntermPreprocessorDirective *node) override;

    void visitCodeBlock(TIntermBlock *node);

    ImmutableString hashFieldName(const TField *field);
    // Same as hashName(), but without hashing "main".
    ImmutableString hashFunctionNameIfNeeded(const TFunction *func);
    // Used to translate function names for differences between ESSL and GLSL
    virtual ImmutableString translateTextureFunction(const ImmutableString &name,
                                                     const ShCompileOptions &option)
    {
        return name;
    }

    void declareStruct(const TStructure *structure);
    void writeQualifier(TQualifier qualifier, const TType &type, const TSymbol *symbol);

    const char *mapQualifierToString(TQualifier qualifier);

    sh::GLenum getShaderType() const { return mShaderType; }
    bool isHighPrecisionSupported() const { return mHighPrecisionSupported; }
    const char *getIndentPrefix(int extraIndentDepth = 0);

    bool needsToWriteLayoutQualifier(const TType &type);

  private:
    void declareInterfaceBlockLayout(const TType &type);
    void declareInterfaceBlock(const TType &type);

    void writeFunctionTriplet(Visit visit,
                              const ImmutableString &functionName,
                              bool useEmulatedFunction);

    TInfoSinkBase &mObjSink;
    bool mDeclaringVariable;

    // name hashing.
    ShHashFunction64 mHashFunction;
    NameMap &mNameMap;

    sh::GLenum mShaderType;
    const int mShaderVersion;
    ShShaderOutput mOutput;

    bool mHighPrecisionSupported;

    // Emit "layout(locaton = 0)" for fragment outputs whose location is unspecified. This is for
    // transformations like pixel local storage, where new outputs are introduced to the shader, and
    // previously valid fragment outputs with an implicit location of 0 are now required to specify
    // their location.
    bool mAlwaysSpecifyFragOutLocation;

    const ShCompileOptions &mCompileOptions;
};

void WritePragma(TInfoSinkBase &out, const ShCompileOptions &compileOptions, const TPragma &pragma);

void WriteGeometryShaderLayoutQualifiers(TInfoSinkBase &out,
                                         sh::TLayoutPrimitiveType inputPrimitive,
                                         int invocations,
                                         sh::TLayoutPrimitiveType outputPrimitive,
                                         int maxVertices);

void WriteTessControlShaderLayoutQualifiers(TInfoSinkBase &out, int inputVertices);

void WriteTessEvaluationShaderLayoutQualifiers(TInfoSinkBase &out,
                                               sh::TLayoutTessEvaluationType inputPrimitive,
                                               sh::TLayoutTessEvaluationType inputVertexSpacing,
                                               sh::TLayoutTessEvaluationType inputOrdering,
                                               sh::TLayoutTessEvaluationType inputPoint);

void EmitEarlyFragmentTestsGLSL(const TCompiler &, TInfoSinkBase &sink);
void EmitWorkGroupSizeGLSL(const TCompiler &, TInfoSinkBase &sink);
void EmitMultiviewGLSL(const TCompiler &,
                       const ShCompileOptions &,
                       const TExtension,
                       const TBehavior,
                       TInfoSinkBase &sink);

}  // namespace sh

#endif  // COMPILER_TRANSLATOR_OUTPUTGLSLBASE_H_