diff options
Diffstat (limited to 'src/3rdparty/angle/src/compiler/translator/OutputHLSL.h')
-rw-r--r-- | src/3rdparty/angle/src/compiler/translator/OutputHLSL.h | 113 |
1 files changed, 85 insertions, 28 deletions
diff --git a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h index 5525e6eaa6..51da877c72 100644 --- a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h +++ b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h @@ -4,18 +4,20 @@ // found in the LICENSE file. // -#ifndef COMPILER_OUTPUTHLSL_H_ -#define COMPILER_OUTPUTHLSL_H_ +#ifndef COMPILER_TRANSLATOR_OUTPUTHLSL_H_ +#define COMPILER_TRANSLATOR_OUTPUTHLSL_H_ #include <list> #include <set> #include <map> +#include <stack> #include "angle_gl.h" - #include "compiler/translator/IntermNode.h" #include "compiler/translator/ParseContext.h" +class BuiltInFunctionEmulator; + namespace sh { class UnfoldShortCircuit; @@ -27,20 +29,25 @@ typedef std::map<TString, TIntermSymbol*> ReferencedSymbols; class OutputHLSL : public TIntermTraverser { public: - OutputHLSL(TParseContext &context, TranslatorHLSL *parentTranslator); - ~OutputHLSL(); + OutputHLSL(sh::GLenum shaderType, int shaderVersion, + const TExtensionBehavior &extensionBehavior, + const char *sourcePath, ShShaderOutput outputType, + int numRenderTargets, const std::vector<Uniform> &uniforms, + int compileOptions); - void output(); + ~OutputHLSL(); - TInfoSinkBase &getBodyStream(); + void output(TIntermNode *treeRoot, TInfoSinkBase &objSink); const std::map<std::string, unsigned int> &getInterfaceBlockRegisterMap() const; const std::map<std::string, unsigned int> &getUniformRegisterMap() const; static TString initializer(const TType &type); + TInfoSinkBase &getInfoSink() { ASSERT(!mInfoSinkStack.empty()); return *mInfoSinkStack.top(); } + protected: - void header(); + void header(const BuiltInFunctionEmulator *builtInFunctionEmulator); // Visit AST nodes and output their code to the body stream void visitSymbol(TIntermSymbol*); @@ -49,6 +56,8 @@ class OutputHLSL : public TIntermTraverser bool visitBinary(Visit visit, TIntermBinary*); bool visitUnary(Visit visit, TIntermUnary*); bool visitSelection(Visit visit, TIntermSelection*); + bool visitSwitch(Visit visit, TIntermSwitch *); + bool visitCase(Visit visit, TIntermCase *); bool visitAggregate(Visit visit, TIntermAggregate*); bool visitLoop(Visit visit, TIntermLoop*); bool visitBranch(Visit visit, TIntermBranch*); @@ -56,16 +65,39 @@ class OutputHLSL : public TIntermTraverser void traverseStatements(TIntermNode *node); bool isSingleStatement(TIntermNode *node); bool handleExcessiveLoop(TIntermLoop *node); - void outputTriplet(Visit visit, const TString &preString, const TString &inString, const TString &postString); + + // Emit one of three strings depending on traverse phase. Called with literal strings so using const char* instead of TString. + void outputTriplet(Visit visit, const char *preString, const char *inString, const char *postString, TInfoSinkBase &out); + void outputTriplet(Visit visit, const char *preString, const char *inString, const char *postString); void outputLineDirective(int line); TString argumentString(const TIntermSymbol *symbol); int vectorSize(const TType &type) const; - void outputConstructor(Visit visit, const TType &type, const TString &name, const TIntermSequence *parameters); + // Emit constructor. Called with literal names so using const char* instead of TString. + void outputConstructor(Visit visit, const TType &type, const char *name, const TIntermSequence *parameters); const ConstantUnion *writeConstantUnion(const TType &type, const ConstantUnion *constUnion); - TParseContext &mContext; + void outputEqual(Visit visit, const TType &type, TOperator op, TInfoSinkBase &out); + + void writeEmulatedFunctionTriplet(Visit visit, const char *preStr); + void makeFlaggedStructMaps(const std::vector<TIntermTyped *> &flaggedStructs); + + // Returns true if it found a 'same symbol' initializer (initializer that references the variable it's initting) + bool writeSameSymbolInitializer(TInfoSinkBase &out, TIntermSymbol *symbolNode, TIntermTyped *expression); + void writeDeferredGlobalInitializers(TInfoSinkBase &out); + + // Returns the function name + TString addStructEqualityFunction(const TStructure &structure); + TString addArrayEqualityFunction(const TType &type); + TString addArrayAssignmentFunction(const TType &type); + + sh::GLenum mShaderType; + int mShaderVersion; + const TExtensionBehavior &mExtensionBehavior; + const char *mSourcePath; const ShShaderOutput mOutputType; + int mCompileOptions; + UnfoldShortCircuit *mUnfoldShortCircuit; bool mInsideFunction; @@ -74,6 +106,11 @@ class OutputHLSL : public TIntermTraverser TInfoSinkBase mBody; TInfoSinkBase mFooter; + // A stack is useful when we want to traverse in the header, or in helper functions, but not always + // write to the body. Instead use an InfoSink stack to keep our current state intact. + // TODO (jmadill): Just passing an InfoSink in function parameters would be simpler. + std::stack<TInfoSinkBase *> mInfoSinkStack; + ReferencedSymbols mReferencedUniforms; ReferencedSymbols mReferencedInterfaceBlocks; ReferencedSymbols mReferencedAttributes; @@ -119,25 +156,13 @@ class OutputHLSL : public TIntermTraverser bool mUsesPointCoord; bool mUsesFrontFacing; bool mUsesPointSize; + bool mUsesInstanceID; bool mUsesFragDepth; bool mUsesXor; - bool mUsesMod1; - bool mUsesMod2v; - bool mUsesMod2f; - bool mUsesMod3v; - bool mUsesMod3f; - bool mUsesMod4v; - bool mUsesMod4f; - bool mUsesFaceforward1; - bool mUsesFaceforward2; - bool mUsesFaceforward3; - bool mUsesFaceforward4; - bool mUsesAtan2_1; - bool mUsesAtan2_2; - bool mUsesAtan2_3; - bool mUsesAtan2_4; bool mUsesDiscardRewriting; bool mUsesNestedBreak; + bool mRequiresIEEEStrictCompiling; + int mNumRenderTargets; @@ -156,9 +181,41 @@ class OutputHLSL : public TIntermTraverser std::map<TIntermTyped*, TString> mFlaggedStructMappedNames; std::map<TIntermTyped*, TString> mFlaggedStructOriginalNames; - void makeFlaggedStructMaps(const std::vector<TIntermTyped *> &flaggedStructs); + // Some initializers use varyings, uniforms or attributes, thus we can't evaluate some variables + // at global static scope in HLSL. These variables depend on values which we retrieve from the + // shader input structure, which we set in the D3D main function. Instead, we can initialize + // these static globals after we initialize our other globals. + std::vector<std::pair<TIntermSymbol*, TIntermTyped*>> mDeferredGlobalInitializers; + + struct HelperFunction + { + TString functionName; + TString functionDefinition; + + virtual ~HelperFunction() {} + }; + + // A list of all equality comparison functions. It's important to preserve the order at + // which we add the functions, since nested structures call each other recursively, and + // structure equality functions may need to call array equality functions and vice versa. + // The ownership of the pointers is maintained by the type-specific arrays. + std::vector<HelperFunction*> mEqualityFunctions; + + struct StructEqualityFunction : public HelperFunction + { + const TStructure *structure; + }; + std::vector<StructEqualityFunction*> mStructEqualityFunctions; + + struct ArrayHelperFunction : public HelperFunction + { + TType type; + }; + std::vector<ArrayHelperFunction*> mArrayEqualityFunctions; + + std::vector<ArrayHelperFunction> mArrayAssignmentFunctions; }; } -#endif // COMPILER_OUTPUTHLSL_H_ +#endif // COMPILER_TRANSLATOR_OUTPUTHLSL_H_ |