diff options
Diffstat (limited to 'src/sksl')
-rw-r--r-- | src/sksl/SkSLCompiler.cpp | 5 | ||||
-rw-r--r-- | src/sksl/SkSLGLSLCodeGenerator.cpp | 18 | ||||
-rw-r--r-- | src/sksl/SkSLGLSLCodeGenerator.h | 36 | ||||
-rw-r--r-- | src/sksl/SkSLMain.cpp | 14 | ||||
-rw-r--r-- | src/sksl/ir/SkSLFunctionDeclaration.h | 2 | ||||
-rw-r--r-- | src/sksl/ir/SkSLSymbolTable.cpp | 18 | ||||
-rw-r--r-- | src/sksl/ir/SkSLSymbolTable.h | 2 |
7 files changed, 62 insertions, 33 deletions
diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp index d4fbc95d39..5b502dce2f 100644 --- a/src/sksl/SkSLCompiler.cpp +++ b/src/sksl/SkSLCompiler.cpp @@ -19,6 +19,7 @@ #include "ir/SkSLIntLiteral.h" #include "ir/SkSLModifiersDeclaration.h" #include "ir/SkSLSymbolTable.h" +#include "ir/SkSLUnresolvedFunction.h" #include "ir/SkSLVarDeclarations.h" #include "SkMutex.h" @@ -135,6 +136,7 @@ Compiler::Compiler() Modifiers::Flag ignored1; std::vector<std::unique_ptr<ProgramElement>> ignored2; this->internalConvertProgram(SKSL_INCLUDE, &ignored1, &ignored2); + fIRGenerator->fSymbolTable->markAllFunctionsBuiltin(); ASSERT(!fErrorCount); } @@ -393,10 +395,11 @@ std::unique_ptr<Program> Compiler::convertProgram(Program::Kind kind, std::strin this->internalConvertProgram(SKSL_FRAG_INCLUDE, &ignored, &elements); break; } + fIRGenerator->fSymbolTable->markAllFunctionsBuiltin(); Modifiers::Flag defaultPrecision; this->internalConvertProgram(text, &defaultPrecision, &elements); auto result = std::unique_ptr<Program>(new Program(kind, defaultPrecision, std::move(elements), - fIRGenerator->fSymbolTable));; + fIRGenerator->fSymbolTable)); fIRGenerator->popSymbolTable(); this->writeErrorCount(); return result; diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp index 45644e8cd1..8a26f6a713 100644 --- a/src/sksl/SkSLGLSLCodeGenerator.cpp +++ b/src/sksl/SkSLGLSLCodeGenerator.cpp @@ -150,7 +150,7 @@ void GLSLCodeGenerator::writeMinAbsHack(Expression& absExpr, Expression& otherEx } void GLSLCodeGenerator::writeFunctionCall(const FunctionCall& c) { - if (!fCaps.fCanUseMinAndAbsTogether && c.fFunction.fName == "min") { + if (!fCaps.fCanUseMinAndAbsTogether && c.fFunction.fName == "min" && c.fFunction.fBuiltin) { ASSERT(c.fArguments.size() == 2); if (is_abs(*c.fArguments[0])) { this->writeMinAbsHack(*c.fArguments[0], *c.fArguments[1]); @@ -164,7 +164,8 @@ void GLSLCodeGenerator::writeFunctionCall(const FunctionCall& c) { } } if (fCaps.fMustForceNegatedAtanParamToFloat && c.fFunction.fName == "atan" && - c.fArguments.size() == 2 && c.fArguments[1]->fKind == Expression::kPrefix_Kind) { + c.fFunction.fBuiltin && c.fArguments.size() == 2 && + c.fArguments[1]->fKind == Expression::kPrefix_Kind) { const PrefixExpression& p = (PrefixExpression&) *c.fArguments[1]; if (p.fOperator == Token::MINUS) { this->write("atan("); @@ -175,6 +176,12 @@ void GLSLCodeGenerator::writeFunctionCall(const FunctionCall& c) { return; } } + if (!fFoundDerivatives && fCaps.fShaderDerivativeExtensionString != "" && + (c.fFunction.fName == "dFdx" || c.fFunction.fName == "dFdy") && c.fFunction.fBuiltin) { + ASSERT(fCaps.fShaderDerivativeSupport); + fHeader << "#extension " << fCaps.fShaderDerivativeExtensionString << " : require\n"; + fFoundDerivatives = true; + } this->write(c.fFunction.fName + "("); const char* separator = ""; for (const auto& arg : c.fArguments) { @@ -578,7 +585,7 @@ void GLSLCodeGenerator::writeReturnStatement(const ReturnStatement& r) { void GLSLCodeGenerator::generateCode(const Program& program, std::ostream& out) { ASSERT(fOut == nullptr); - fOut = &out; + fOut = &fHeader; fProgramKind = program.fKind; this->write("#version " + to_string(fCaps.fVersion)); if (fCaps.fStandard == GLCaps::kGLES_Standard && fCaps.fVersion >= 300) { @@ -592,6 +599,8 @@ void GLSLCodeGenerator::generateCode(const Program& program, std::ostream& out) this->writeExtension((Extension&) *e); } } + std::stringstream body; + fOut = &body; if (fCaps.fStandard == GLCaps::kGLES_Standard) { this->write("precision "); switch (program.fDefaultPrecision) { @@ -649,6 +658,9 @@ void GLSLCodeGenerator::generateCode(const Program& program, std::ostream& out) } } fOut = nullptr; + + out << fHeader.str(); + out << body.str(); } } diff --git a/src/sksl/SkSLGLSLCodeGenerator.h b/src/sksl/SkSLGLSLCodeGenerator.h index 17ac90ea23..97e6038146 100644 --- a/src/sksl/SkSLGLSLCodeGenerator.h +++ b/src/sksl/SkSLGLSLCodeGenerator.h @@ -45,20 +45,25 @@ namespace SkSL { #define kLast_Capability SpvCapabilityMultiViewport struct GLCaps { - int fVersion; + GLCaps() {} + + int fVersion = 400; enum { kGL_Standard, kGLES_Standard - } fStandard; - bool fIsCoreProfile; - bool fUsesPrecisionModifiers; - bool fMustDeclareFragmentShaderOutput; + } fStandard = kGL_Standard; + bool fIsCoreProfile = false; + bool fUsesPrecisionModifiers = false; + bool fMustDeclareFragmentShaderOutput = false; + bool fShaderDerivativeSupport = true; + // extension string to enable derivative support, or null if unnecessary + std::string fShaderDerivativeExtensionString; // The Tegra3 compiler will sometimes never return if we have min(abs(x), y) - bool fCanUseMinAndAbsTogether; + bool fCanUseMinAndAbsTogether = true; // On Intel GPU there is an issue where it misinterprets an atan argument (second argument only, // apparently) of the form "-<expr>" as an int, so we rewrite it as "-1.0 * <expr>" to avoid // this problem - bool fMustForceNegatedAtanParamToFloat; + bool fMustForceNegatedAtanParamToFloat = false; }; /** @@ -89,11 +94,7 @@ public: GLSLCodeGenerator(const Context* context, GLCaps caps) : fContext(*context) - , fCaps(caps) - , fOut(nullptr) - , fVarCount(0) - , fIndentation(0) - , fAtLineStart(true) {} + , fCaps(caps) {} void generateCode(const Program& program, std::ostream& out) override; @@ -176,16 +177,19 @@ private: const Context& fContext; const GLCaps fCaps; - std::ostream* fOut; + std::ostream* fOut = nullptr; + std::stringstream fHeader; std::string fFunctionHeader; Program::Kind fProgramKind; - int fVarCount; - int fIndentation; - bool fAtLineStart; + 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; + // true if we have run into usages of dFdx / dFdy + bool fFoundDerivatives = false; }; } diff --git a/src/sksl/SkSLMain.cpp b/src/sksl/SkSLMain.cpp index fe925e0c6e..eb07b4d032 100644 --- a/src/sksl/SkSLMain.cpp +++ b/src/sksl/SkSLMain.cpp @@ -16,18 +16,6 @@ bool endsWith(const std::string& s, const std::string& ending) { return false; } -static SkSL::GLCaps default_caps() { - return { - 400, - SkSL::GLCaps::kGL_Standard, - false, // isCoreProfile - false, // usesPrecisionModifiers; - false, // mustDeclareFragmentShaderOutput - true, // canUseMinAndAbsTogether - false // mustForceNegatedAtanParamToFloat - }; -} - /** * Very simple standalone executable to facilitate testing. */ @@ -69,7 +57,7 @@ int main(int argc, const char** argv) { } else if (endsWith(name, ".glsl")) { std::ofstream out(argv[2], std::ofstream::binary); SkSL::Compiler compiler; - if (!compiler.toGLSL(kind, text, default_caps(), out)) { + if (!compiler.toGLSL(kind, text, SkSL::GLCaps(), out)) { printf("%s", compiler.errorText().c_str()); exit(3); } diff --git a/src/sksl/ir/SkSLFunctionDeclaration.h b/src/sksl/ir/SkSLFunctionDeclaration.h index 16a184a6d7..ffde0c66c1 100644 --- a/src/sksl/ir/SkSLFunctionDeclaration.h +++ b/src/sksl/ir/SkSLFunctionDeclaration.h @@ -24,6 +24,7 @@ struct FunctionDeclaration : public Symbol { std::vector<const Variable*> parameters, const Type& returnType) : INHERITED(position, kFunctionDeclaration_Kind, std::move(name)) , fDefined(false) + , fBuiltin(false) , fParameters(std::move(parameters)) , fReturnType(returnType) {} @@ -55,6 +56,7 @@ struct FunctionDeclaration : public Symbol { } mutable bool fDefined; + bool fBuiltin; const std::vector<const Variable*> fParameters; const Type& fReturnType; diff --git a/src/sksl/ir/SkSLSymbolTable.cpp b/src/sksl/ir/SkSLSymbolTable.cpp index 9d8c0063c5..6d8e9a7ea6 100644 --- a/src/sksl/ir/SkSLSymbolTable.cpp +++ b/src/sksl/ir/SkSLSymbolTable.cpp @@ -97,4 +97,22 @@ void SymbolTable::addWithoutOwnership(const std::string& name, const Symbol* sym } } + +void SymbolTable::markAllFunctionsBuiltin() { + for (const auto& pair : fSymbols) { + switch (pair.second->fKind) { + case Symbol::kFunctionDeclaration_Kind: + ((FunctionDeclaration&) *pair.second).fBuiltin = true; + break; + case Symbol::kUnresolvedFunction_Kind: + for (auto& f : ((UnresolvedFunction&) *pair.second).fFunctions) { + ((FunctionDeclaration*) f)->fBuiltin = true; + } + break; + default: + break; + } + } +} + } // namespace diff --git a/src/sksl/ir/SkSLSymbolTable.h b/src/sksl/ir/SkSLSymbolTable.h index d732023ff0..be2b49c48d 100644 --- a/src/sksl/ir/SkSLSymbolTable.h +++ b/src/sksl/ir/SkSLSymbolTable.h @@ -39,6 +39,8 @@ public: Symbol* takeOwnership(Symbol* s); + void markAllFunctionsBuiltin(); + const std::shared_ptr<SymbolTable> fParent; private: |