From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- gfx/angle/src/compiler/translator/OutputHLSL.h | 226 +++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100755 gfx/angle/src/compiler/translator/OutputHLSL.h (limited to 'gfx/angle/src/compiler/translator/OutputHLSL.h') diff --git a/gfx/angle/src/compiler/translator/OutputHLSL.h b/gfx/angle/src/compiler/translator/OutputHLSL.h new file mode 100755 index 000000000..833f4736b --- /dev/null +++ b/gfx/angle/src/compiler/translator/OutputHLSL.h @@ -0,0 +1,226 @@ +// +// Copyright (c) 2002-2014 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_OUTPUTHLSL_H_ +#define COMPILER_TRANSLATOR_OUTPUTHLSL_H_ + +#include +#include +#include + +#include "angle_gl.h" +#include "compiler/translator/ASTMetadataHLSL.h" +#include "compiler/translator/IntermNode.h" +#include "compiler/translator/ParseContext.h" + +class BuiltInFunctionEmulator; + +namespace sh +{ +class StructureHLSL; +class TextureFunctionHLSL; +class UnfoldShortCircuit; +class UniformHLSL; + +typedef std::map ReferencedSymbols; + +class OutputHLSL : public TIntermTraverser +{ + public: + OutputHLSL(sh::GLenum shaderType, + int shaderVersion, + const TExtensionBehavior &extensionBehavior, + const char *sourcePath, + ShShaderOutput outputType, + int numRenderTargets, + const std::vector &uniforms, + ShCompileOptions compileOptions); + + ~OutputHLSL(); + + void output(TIntermNode *treeRoot, TInfoSinkBase &objSink); + + const std::map &getInterfaceBlockRegisterMap() const; + const std::map &getUniformRegisterMap() const; + + static TString initializer(const TType &type); + + TInfoSinkBase &getInfoSink() { ASSERT(!mInfoSinkStack.empty()); return *mInfoSinkStack.top(); } + + static bool canWriteAsHLSLLiteral(TIntermTyped *expression); + + protected: + void header(TInfoSinkBase &out, const BuiltInFunctionEmulator *builtInFunctionEmulator); + + // Visit AST nodes and output their code to the body stream + void visitSymbol(TIntermSymbol*); + void visitRaw(TIntermRaw*); + void visitConstantUnion(TIntermConstantUnion*); + bool visitSwizzle(Visit visit, TIntermSwizzle *node) override; + bool visitBinary(Visit visit, TIntermBinary*); + bool visitUnary(Visit visit, TIntermUnary*); + bool visitTernary(Visit visit, TIntermTernary *); + bool visitIfElse(Visit visit, TIntermIfElse *); + bool visitSwitch(Visit visit, TIntermSwitch *); + bool visitCase(Visit visit, TIntermCase *); + bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override; + bool visitAggregate(Visit visit, TIntermAggregate*); + bool visitBlock(Visit visit, TIntermBlock *node); + bool visitDeclaration(Visit visit, TIntermDeclaration *node); + bool visitLoop(Visit visit, TIntermLoop*); + bool visitBranch(Visit visit, TIntermBranch*); + + bool handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node); + + // Emit one of three strings depending on traverse phase. Called with literal strings so using const char* instead of TString. + void outputTriplet(TInfoSinkBase &out, + Visit visit, + const char *preString, + const char *inString, + const char *postString); + void outputLineDirective(TInfoSinkBase &out, int line); + TString argumentString(const TIntermSymbol *symbol); + int vectorSize(const TType &type) const; + + // Emit constructor. Called with literal names so using const char* instead of TString. + void outputConstructor(TInfoSinkBase &out, + Visit visit, + const TType &type, + const char *name, + const TIntermSequence *parameters); + const TConstantUnion *writeConstantUnion(TInfoSinkBase &out, + const TType &type, + const TConstantUnion *constUnion); + + void outputEqual(Visit visit, const TType &type, TOperator op, TInfoSinkBase &out); + + void writeEmulatedFunctionTriplet(TInfoSinkBase &out, Visit visit, const char *preStr); + void makeFlaggedStructMaps(const std::vector &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); + // Returns true if variable initializer could be written using literal {} notation. + bool writeConstantInitialization(TInfoSinkBase &out, + TIntermSymbol *symbolNode, + TIntermTyped *expression); + + void writeDeferredGlobalInitializers(TInfoSinkBase &out); + void writeIfElse(TInfoSinkBase &out, TIntermIfElse *node); + + // Returns the function name + TString addStructEqualityFunction(const TStructure &structure); + TString addArrayEqualityFunction(const TType &type); + TString addArrayAssignmentFunction(const TType &type); + TString addArrayConstructIntoFunction(const TType &type); + + // Ensures if the type is a struct, the struct is defined + void ensureStructDefined(const TType &type); + + sh::GLenum mShaderType; + int mShaderVersion; + const TExtensionBehavior &mExtensionBehavior; + const char *mSourcePath; + const ShShaderOutput mOutputType; + ShCompileOptions mCompileOptions; + + bool mInsideFunction; + + // Output streams + TInfoSinkBase mHeader; + 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 mInfoSinkStack; + + ReferencedSymbols mReferencedUniforms; + ReferencedSymbols mReferencedInterfaceBlocks; + ReferencedSymbols mReferencedAttributes; + ReferencedSymbols mReferencedVaryings; + ReferencedSymbols mReferencedOutputVariables; + + StructureHLSL *mStructureHLSL; + UniformHLSL *mUniformHLSL; + TextureFunctionHLSL *mTextureFunctionHLSL; + + // Parameters determining what goes in the header output + bool mUsesFragColor; + bool mUsesFragData; + bool mUsesDepthRange; + bool mUsesFragCoord; + bool mUsesPointCoord; + bool mUsesFrontFacing; + bool mUsesPointSize; + bool mUsesInstanceID; + bool mUsesVertexID; + bool mUsesFragDepth; + bool mUsesXor; + bool mUsesDiscardRewriting; + bool mUsesNestedBreak; + bool mRequiresIEEEStrictCompiling; + + + int mNumRenderTargets; + + int mUniqueIndex; // For creating unique names + + CallDAG mCallDag; + MetadataList mASTMetadataList; + ASTMetadataHLSL *mCurrentFunctionMetadata; + bool mOutputLod0Function; + bool mInsideDiscontinuousLoop; + int mNestedLoopDepth; + + TIntermSymbol *mExcessiveLoopIndex; + + TString structInitializerString(int indent, const TStructure &structure, const TString &rhsStructName); + + std::map mFlaggedStructMappedNames; + std::map mFlaggedStructOriginalNames; + + 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 mEqualityFunctions; + + struct StructEqualityFunction : public HelperFunction + { + const TStructure *structure; + }; + std::vector mStructEqualityFunctions; + + struct ArrayHelperFunction : public HelperFunction + { + TType type; + }; + std::vector mArrayEqualityFunctions; + + std::vector mArrayAssignmentFunctions; + + // The construct-into functions are functions that fill an N-element array passed as an out parameter + // with the other N parameters of the function. This is used to work around that arrays can't be + // return values in HLSL. + std::vector mArrayConstructIntoFunctions; + + private: + TString samplerNamePrefixFromStruct(TIntermTyped *node); + bool ancestorEvaluatesToSamplerInStruct(Visit visit); +}; + +} + +#endif // COMPILER_TRANSLATOR_OUTPUTHLSL_H_ -- cgit v1.2.3