bb43b7e85e
SkSL::Type now asserts if you try to create a multi-dimensional array; various looping/recursing constructs that no longer need to loop or recurse were updated. Change-Id: I191b4a032ddc6e7759cebc8b41c536cfaaf1b626 Bug: skia:11026 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/340759 Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: Brian Osman <brianosman@google.com> Auto-Submit: John Stiles <johnstiles@google.com>
255 lines
7.6 KiB
C++
255 lines
7.6 KiB
C++
/*
|
|
* Copyright 2016 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#ifndef SKSL_GLSLCODEGENERATOR
|
|
#define SKSL_GLSLCODEGENERATOR
|
|
|
|
#include <stack>
|
|
#include <tuple>
|
|
#include <unordered_map>
|
|
|
|
#include "src/sksl/SkSLCodeGenerator.h"
|
|
#include "src/sksl/SkSLStringStream.h"
|
|
#include "src/sksl/ir/SkSLBinaryExpression.h"
|
|
#include "src/sksl/ir/SkSLBoolLiteral.h"
|
|
#include "src/sksl/ir/SkSLConstructor.h"
|
|
#include "src/sksl/ir/SkSLDoStatement.h"
|
|
#include "src/sksl/ir/SkSLExtension.h"
|
|
#include "src/sksl/ir/SkSLFieldAccess.h"
|
|
#include "src/sksl/ir/SkSLFloatLiteral.h"
|
|
#include "src/sksl/ir/SkSLForStatement.h"
|
|
#include "src/sksl/ir/SkSLFunctionCall.h"
|
|
#include "src/sksl/ir/SkSLFunctionDeclaration.h"
|
|
#include "src/sksl/ir/SkSLFunctionDefinition.h"
|
|
#include "src/sksl/ir/SkSLFunctionPrototype.h"
|
|
#include "src/sksl/ir/SkSLIfStatement.h"
|
|
#include "src/sksl/ir/SkSLIndexExpression.h"
|
|
#include "src/sksl/ir/SkSLIntLiteral.h"
|
|
#include "src/sksl/ir/SkSLInterfaceBlock.h"
|
|
#include "src/sksl/ir/SkSLPostfixExpression.h"
|
|
#include "src/sksl/ir/SkSLPrefixExpression.h"
|
|
#include "src/sksl/ir/SkSLProgramElement.h"
|
|
#include "src/sksl/ir/SkSLReturnStatement.h"
|
|
#include "src/sksl/ir/SkSLSetting.h"
|
|
#include "src/sksl/ir/SkSLStatement.h"
|
|
#include "src/sksl/ir/SkSLSwitchStatement.h"
|
|
#include "src/sksl/ir/SkSLSwizzle.h"
|
|
#include "src/sksl/ir/SkSLTernaryExpression.h"
|
|
#include "src/sksl/ir/SkSLVarDeclarations.h"
|
|
#include "src/sksl/ir/SkSLVariableReference.h"
|
|
#include "src/sksl/ir/SkSLWhileStatement.h"
|
|
|
|
namespace SkSL {
|
|
|
|
#define kLast_Capability SpvCapabilityMultiViewport
|
|
|
|
/**
|
|
* Converts a Program into GLSL code.
|
|
*/
|
|
class GLSLCodeGenerator : public CodeGenerator {
|
|
public:
|
|
enum Precedence {
|
|
kParentheses_Precedence = 1,
|
|
kPostfix_Precedence = 2,
|
|
kPrefix_Precedence = 3,
|
|
kMultiplicative_Precedence = 4,
|
|
kAdditive_Precedence = 5,
|
|
kShift_Precedence = 6,
|
|
kRelational_Precedence = 7,
|
|
kEquality_Precedence = 8,
|
|
kBitwiseAnd_Precedence = 9,
|
|
kBitwiseXor_Precedence = 10,
|
|
kBitwiseOr_Precedence = 11,
|
|
kLogicalAnd_Precedence = 12,
|
|
kLogicalXor_Precedence = 13,
|
|
kLogicalOr_Precedence = 14,
|
|
kTernary_Precedence = 15,
|
|
kAssignment_Precedence = 16,
|
|
kSequence_Precedence = 17,
|
|
kTopLevel_Precedence = kSequence_Precedence
|
|
};
|
|
|
|
GLSLCodeGenerator(const Context* context, const Program* program, ErrorReporter* errors,
|
|
OutputStream* out)
|
|
: INHERITED(program, errors, out)
|
|
, fLineEnding("\n")
|
|
, fContext(*context)
|
|
, fProgramKind(program->fKind) {}
|
|
|
|
bool generateCode() override;
|
|
|
|
protected:
|
|
void write(const char* s);
|
|
|
|
void writeLine();
|
|
|
|
void writeLine(const char* s);
|
|
|
|
void write(const String& s);
|
|
|
|
void write(StringFragment s);
|
|
|
|
void writeLine(const String& s);
|
|
|
|
virtual void writeHeader();
|
|
|
|
virtual bool usesPrecisionModifiers() const;
|
|
|
|
virtual String getTypeName(const Type& type);
|
|
|
|
bool writeStructDefinition(const Type& type);
|
|
|
|
void writeType(const Type& type);
|
|
|
|
void writeExtension(const String& name);
|
|
|
|
void writeExtension(const String& name, bool require);
|
|
|
|
void writeInterfaceBlock(const InterfaceBlock& intf);
|
|
|
|
void writeFunctionStart(const FunctionDeclaration& f);
|
|
|
|
void writeFunctionDeclaration(const FunctionDeclaration& f);
|
|
|
|
void writeFunctionPrototype(const FunctionPrototype& f);
|
|
|
|
virtual void writeFunction(const FunctionDefinition& f);
|
|
|
|
void writeLayout(const Layout& layout);
|
|
|
|
void writeModifiers(const Modifiers& modifiers, bool globalContext);
|
|
|
|
virtual void writeInputVars();
|
|
|
|
virtual void writeVarInitializer(const Variable& var, const Expression& value);
|
|
|
|
const char* getTypePrecision(const Type& type);
|
|
|
|
void writeTypePrecision(const Type& type);
|
|
|
|
void writeVarDeclaration(const VarDeclaration& var, bool global);
|
|
|
|
void writeFragCoord();
|
|
|
|
virtual void writeVariableReference(const VariableReference& ref);
|
|
|
|
void writeExpression(const Expression& expr, Precedence parentPrecedence);
|
|
|
|
void writeIntrinsicCall(const FunctionCall& c);
|
|
|
|
void writeMinAbsHack(Expression& absExpr, Expression& otherExpr);
|
|
|
|
void writeDeterminantHack(const Expression& mat);
|
|
|
|
void writeInverseHack(const Expression& mat);
|
|
|
|
void writeTransposeHack(const Expression& mat);
|
|
|
|
void writeInverseSqrtHack(const Expression& x);
|
|
|
|
virtual void writeFunctionCall(const FunctionCall& c);
|
|
|
|
void writeConstructor(const Constructor& c, Precedence parentPrecedence);
|
|
|
|
virtual void writeFieldAccess(const FieldAccess& f);
|
|
|
|
virtual void writeSwizzle(const Swizzle& swizzle);
|
|
|
|
static Precedence GetBinaryPrecedence(Token::Kind op);
|
|
|
|
virtual void writeBinaryExpression(const BinaryExpression& b, Precedence parentPrecedence);
|
|
void writeShortCircuitWorkaroundExpression(const BinaryExpression& b,
|
|
Precedence parentPrecedence);
|
|
|
|
void writeTernaryExpression(const TernaryExpression& t, Precedence parentPrecedence);
|
|
|
|
virtual void writeIndexExpression(const IndexExpression& expr);
|
|
|
|
void writePrefixExpression(const PrefixExpression& p, Precedence parentPrecedence);
|
|
|
|
void writePostfixExpression(const PostfixExpression& p, Precedence parentPrecedence);
|
|
|
|
void writeBoolLiteral(const BoolLiteral& b);
|
|
|
|
virtual void writeIntLiteral(const IntLiteral& i);
|
|
|
|
void writeFloatLiteral(const FloatLiteral& f);
|
|
|
|
virtual void writeSetting(const Setting& s);
|
|
|
|
void writeStatement(const Statement& s);
|
|
|
|
void writeBlock(const Block& b);
|
|
|
|
virtual void writeIfStatement(const IfStatement& stmt);
|
|
|
|
void writeForStatement(const ForStatement& f);
|
|
|
|
void writeWhileStatement(const WhileStatement& w);
|
|
|
|
void writeDoStatement(const DoStatement& d);
|
|
|
|
virtual void writeSwitchStatement(const SwitchStatement& s);
|
|
|
|
virtual void writeReturnStatement(const ReturnStatement& r);
|
|
|
|
virtual void writeProgramElement(const ProgramElement& e);
|
|
|
|
const char* fLineEnding;
|
|
const Context& fContext;
|
|
StringStream fExtensions;
|
|
StringStream fGlobals;
|
|
StringStream fExtraFunctions;
|
|
String fFunctionHeader;
|
|
Program::Kind fProgramKind;
|
|
int fVarCount = 0;
|
|
int fIndentation = 0;
|
|
bool fAtLineStart = false;
|
|
// Keeps track of which struct types we have written. Given that we are unlikely to ever write
|
|
// more than one or two structs per shader, a simple linear search will be faster than anything
|
|
// fancier.
|
|
std::vector<const Type*> fWrittenStructs;
|
|
std::set<String> fWrittenIntrinsics;
|
|
// true if we have run into usages of dFdx / dFdy
|
|
bool fFoundDerivatives = false;
|
|
bool fFoundExternalSamplerDecl = false;
|
|
bool fFoundRectSamplerDecl = false;
|
|
bool fFoundGSInvocations = false;
|
|
bool fSetupFragPositionGlobal = false;
|
|
bool fSetupFragPositionLocal = false;
|
|
bool fSetupFragCoordWorkaround = false;
|
|
// if non-empty, replace all texture / texture2D / textureProj / etc. calls with this name
|
|
String fTextureFunctionOverride;
|
|
|
|
// We map function names to function class so we can quickly deal with function calls that need
|
|
// extra processing
|
|
enum class FunctionClass {
|
|
kAbs,
|
|
kAtan,
|
|
kDeterminant,
|
|
kDFdx,
|
|
kDFdy,
|
|
kFwidth,
|
|
kFMA,
|
|
kFract,
|
|
kInverse,
|
|
kInverseSqrt,
|
|
kMin,
|
|
kPow,
|
|
kSaturate,
|
|
kTexture,
|
|
kTranspose
|
|
};
|
|
static std::unordered_map<StringFragment, FunctionClass>* fFunctionClasses;
|
|
|
|
using INHERITED = CodeGenerator;
|
|
};
|
|
|
|
} // namespace SkSL
|
|
|
|
#endif
|