aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/sksl
diff options
context:
space:
mode:
Diffstat (limited to 'src/sksl')
-rw-r--r--src/sksl/SkSLCompiler.cpp5
-rw-r--r--src/sksl/SkSLGLSLCodeGenerator.cpp18
-rw-r--r--src/sksl/SkSLGLSLCodeGenerator.h36
-rw-r--r--src/sksl/SkSLMain.cpp14
-rw-r--r--src/sksl/ir/SkSLFunctionDeclaration.h2
-rw-r--r--src/sksl/ir/SkSLSymbolTable.cpp18
-rw-r--r--src/sksl/ir/SkSLSymbolTable.h2
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: