Revert of Turned on SkSL->GLSL compiler (patchset #12 id:220001 of https://codereview.chromium.org/2288033003/ )

Reason for revert:
Compilation errors on some bots.

Original issue's description:
> Turned on SkSL->GLSL compiler
> GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2288033003
>
> Committed: https://skia.googlesource.com/skia/+/9b0fe3d125f237d9884732a48414fa85fc71b4e3

TBR=benjaminwagner@google.com,bsalomon@google.com,egdaniel@google.com
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true

Review-Url: https://codereview.chromium.org/2337553002
This commit is contained in:
ethannicholas 2016-09-12 09:15:53 -07:00 committed by Commit bot
parent b3e9ae6c0c
commit a316395e66
17 changed files with 126 additions and 503 deletions

View File

@ -18,7 +18,7 @@
],
'all_dependent_settings': {
'include_dirs': [
'<(skia_src_path)/sksl',
'../src/sksl',
],
},
},

View File

@ -7,7 +7,6 @@
#include "GrGLContext.h"
#include "GrGLGLSL.h"
#include "SkSLCompiler.h"
////////////////////////////////////////////////////////////////////////////////
@ -64,17 +63,6 @@ GrGLContext* GrGLContext::Create(const GrGLInterface* interface, const GrContext
return new GrGLContext(args);
}
GrGLContext::~GrGLContext() {
delete fCompiler;
}
SkSL::Compiler* GrGLContext::compiler() {
if (!fCompiler) {
fCompiler = new SkSL::Compiler();
}
return fCompiler;
}
GrGLContextInfo::GrGLContextInfo(const ConstructorArgs& args) {
fInterface.reset(SkRef(args.fInterface));
fGLVersion = args.fGLVersion;

View File

@ -15,9 +15,6 @@
#include "GrGLUtil.h"
struct GrContextOptions;
namespace SkSL {
class Compiler;
}
/**
* Encapsulates information about an OpenGL context including the OpenGL
@ -42,8 +39,6 @@ public:
const GrGLExtensions& extensions() const { return fInterface->fExtensions; }
virtual ~GrGLContextInfo() {}
protected:
struct ConstructorArgs {
const GrGLInterface* fInterface;
@ -69,7 +64,7 @@ protected:
};
/**
* Extension of GrGLContextInfo that also provides access to GrGLInterface and SkSL::Compiler.
* Extension of GrGLContextInfo that also provides access to GrGLInterface.
*/
class GrGLContext : public GrGLContextInfo {
public:
@ -81,16 +76,8 @@ public:
const GrGLInterface* interface() const { return fInterface; }
SkSL::Compiler* compiler();
~GrGLContext() override;
private:
GrGLContext(const ConstructorArgs& args)
: INHERITED(args)
, fCompiler(nullptr) {}
SkSL::Compiler* fCompiler;
GrGLContext(const ConstructorArgs& args) : INHERITED(args) {}
typedef GrGLContextInfo INHERITED;
};

View File

@ -3781,11 +3781,20 @@ bool GrGLGpu::createCopyProgram(int progIdx) {
fshaderTxt.append(";");
uTexture.appendDecl(glslCaps, &fshaderTxt);
fshaderTxt.append(";");
const char* fsOutName;
if (glslCaps->mustDeclareFragmentShaderOutput()) {
oFragColor.appendDecl(glslCaps, &fshaderTxt);
fshaderTxt.append(";");
fsOutName = oFragColor.c_str();
} else {
fsOutName = "gl_FragColor";
}
fshaderTxt.appendf(
"// Copy Program FS\n"
"void main() {"
" sk_FragColor = %s(u_texture, v_texCoord);"
" %s = %s(u_texture, v_texCoord);"
"}",
fsOutName,
GrGLSLTexture2DFunctionName(kVec2f_GrSLType, kSamplerTypes[progIdx], this->glslGeneration())
);
@ -3918,6 +3927,14 @@ bool GrGLGpu::createMipmapProgram(int progIdx) {
}
uTexture.appendDecl(glslCaps, &fshaderTxt);
fshaderTxt.append(";");
const char* fsOutName;
if (glslCaps->mustDeclareFragmentShaderOutput()) {
oFragColor.appendDecl(glslCaps, &fshaderTxt);
fshaderTxt.append(";");
fsOutName = oFragColor.c_str();
} else {
fsOutName = "gl_FragColor";
}
const char* sampleFunction = GrGLSLTexture2DFunctionName(kVec2f_GrSLType,
kTexture2DSampler_GrSLType,
this->glslGeneration());
@ -3928,19 +3945,19 @@ bool GrGLGpu::createMipmapProgram(int progIdx) {
if (oddWidth && oddHeight) {
fshaderTxt.appendf(
" sk_FragColor = (%s(u_texture, v_texCoord0) + %s(u_texture, v_texCoord1) + "
" %s(u_texture, v_texCoord2) + %s(u_texture, v_texCoord3)) * 0.25;",
sampleFunction, sampleFunction, sampleFunction, sampleFunction
" %s = (%s(u_texture, v_texCoord0) + %s(u_texture, v_texCoord1) + "
" %s(u_texture, v_texCoord2) + %s(u_texture, v_texCoord3)) * 0.25;",
fsOutName, sampleFunction, sampleFunction, sampleFunction, sampleFunction
);
} else if (oddWidth || oddHeight) {
fshaderTxt.appendf(
" sk_FragColor = (%s(u_texture, v_texCoord0) + %s(u_texture, v_texCoord1)) * 0.5;",
sampleFunction, sampleFunction
" %s = (%s(u_texture, v_texCoord0) + %s(u_texture, v_texCoord1)) * 0.5;",
fsOutName, sampleFunction, sampleFunction
);
} else {
fshaderTxt.appendf(
" sk_FragColor = %s(u_texture, v_texCoord0);",
sampleFunction
" %s = %s(u_texture, v_texCoord0);",
fsOutName, sampleFunction
);
}
@ -4027,11 +4044,20 @@ bool GrGLGpu::createWireRectProgram() {
&fshaderTxt);
uColor.appendDecl(this->glCaps().glslCaps(), &fshaderTxt);
fshaderTxt.append(";");
const char* fsOutName;
if (this->glCaps().glslCaps()->mustDeclareFragmentShaderOutput()) {
oFragColor.appendDecl(this->glCaps().glslCaps(), &fshaderTxt);
fshaderTxt.append(";");
fsOutName = oFragColor.c_str();
} else {
fsOutName = "gl_FragColor";
}
fshaderTxt.appendf(
"// Write Rect Program FS\n"
"void main() {"
" sk_FragColor = %s;"
" %s = %s;"
"}",
fsOutName,
uColor.c_str()
);

View File

@ -9,8 +9,6 @@
#include "gl/GrGLGpu.h"
#include "gl/GrGLSLPrettyPrint.h"
#include "SkTraceEvent.h"
#include "SkSLCompiler.h"
#include "ir/SkSLProgram.h"
#define GL_CALL(X) GR_GL_CALL(gpu->glInterface(), X)
#define GL_CALL_RET(R, X) GR_GL_CALL_RET(gpu->glInterface(), R, X)
@ -20,74 +18,6 @@ static const bool c_PrintShaders{false};
static void print_shader_source(const char** strings, int* lengths, int count);
static SkSL::GLCaps skslcaps_for_context(const GrGLContext& context) {
GrGLStandard standard = context.standard();
const GrGLCaps* caps = context.caps();
const GrGLSLCaps* glslCaps = caps->glslCaps();
SkSL::GLCaps result;
switch (standard) {
case kGL_GrGLStandard:
result.fStandard = SkSL::GLCaps::kGL_Standard;
break;
case kGLES_GrGLStandard:
result.fStandard = SkSL::GLCaps::kGLES_Standard;
break;
default:
SkASSERT(false);
result.fStandard = SkSL::GLCaps::kGL_Standard;
}
switch (glslCaps->generation()) {
case k110_GrGLSLGeneration:
if (kGLES_GrGLStandard == standard) {
// ES2's shader language is based on GLSL 1.20 but is version 1.00 of the ES
// language
result.fVersion = 100;
} else {
SkASSERT(kGL_GrGLStandard == standard);
result.fVersion = 110;
}
break;
case k130_GrGLSLGeneration:
SkASSERT(kGL_GrGLStandard == standard);
result.fVersion = 130;
break;
case k140_GrGLSLGeneration:
SkASSERT(kGL_GrGLStandard == standard);
result.fVersion = 140;
break;
case k150_GrGLSLGeneration:
SkASSERT(kGL_GrGLStandard == standard);
result.fVersion = 150;
break;
case k330_GrGLSLGeneration:
if (kGLES_GrGLStandard == standard) {
result.fVersion = 300;
} else {
SkASSERT(kGL_GrGLStandard == standard);
result.fVersion = 330;
}
break;
case k400_GrGLSLGeneration:
SkASSERT(kGL_GrGLStandard == standard);
result.fVersion = 400;
break;
case k310es_GrGLSLGeneration:
SkASSERT(kGLES_GrGLStandard == standard);
result.fVersion = 310;
break;
case k320es_GrGLSLGeneration:
SkASSERT(kGLES_GrGLStandard == standard);
result.fVersion = 320;
break;
}
result.fIsCoreProfile = caps->isCoreProfile();
result.fUsesPrecisionModifiers = glslCaps->usesPrecisionModifiers();
result.fMustDeclareFragmentShaderOutput = glslCaps->mustDeclareFragmentShaderOutput();
result.fCanUseMinAndAbsTogether = glslCaps->canUseMinAndAbsTogether();
return result;
}
GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx,
GrGLuint programId,
GrGLenum type,
@ -103,32 +33,15 @@ GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx,
return 0;
}
std::string sksl;
#ifdef SK_DEBUG
SkString prettySource = GrGLSLPrettyPrint::PrettyPrintGLSL(strings, lengths, count, false);
sksl = std::string(prettySource.c_str());
const GrGLchar* sourceStr = prettySource.c_str();
GrGLint sourceLength = static_cast<GrGLint>(prettySource.size());
GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength));
#else
for (int i = 0; i < count; i++) {
sksl.append(strings[i], lengths[i]);
}
GR_GL_CALL(gli, ShaderSource(shaderId, count, strings, lengths));
#endif
std::string glsl;
// creating Compiler is expensive, and we are single-threaded anyway, so just reuse a static one
static SkSL::Compiler compiler;
SkSL::GLCaps caps = skslcaps_for_context(glCtx);
SkASSERT(type == GR_GL_VERTEX_SHADER || type == GR_GL_FRAGMENT_SHADER);
SkDEBUGCODE(bool result = )compiler.toGLSL(type == GR_GL_VERTEX_SHADER
? SkSL::Program::kVertex_Kind
: SkSL::Program::kFragment_Kind,
std::string(sksl.c_str()),
caps,
&glsl);
SkASSERTF(result, "SkSL errors:\n%s", compiler.errorText().c_str());
const char* glslChars = glsl.c_str();
GrGLint glslLength = (GrGLint) glsl.length();
GR_GL_CALL(gli, ShaderSource(shaderId, 1, &glslChars, &glslLength));
// If tracing is enabled in chrome then we pretty print
bool traceShader;
TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), &traceShader);

View File

@ -321,7 +321,7 @@ void GrGLSLFragmentShaderBuilder::enableSecondaryOutput() {
}
const char* GrGLSLFragmentShaderBuilder::getPrimaryColorOutputName() const {
return fHasCustomColorOutput ? DeclaredColorOutputName() : "sk_FragColor";
return fHasCustomColorOutput ? DeclaredColorOutputName() : "gl_FragColor";
}
void GrGLSLFragmentBuilder::declAppendf(const char* fmt, ...) {

View File

@ -213,20 +213,24 @@ public:
private:
static const char* TypeModifierString(const GrGLSLCaps* glslCaps, TypeModifier t) {
GrGLSLGeneration gen = glslCaps->generation();
switch (t) {
case kNone_TypeModifier:
return "";
case kAttribute_TypeModifier: // fall through
case kVaryingIn_TypeModifier: // fall through
case kIn_TypeModifier:
return "in";
case kInOut_TypeModifier:
return "inout";
case kVaryingOut_TypeModifier: // fall through
case kOut_TypeModifier:
return "out";
case kUniform_TypeModifier:
return "uniform";
case kAttribute_TypeModifier:
return k110_GrGLSLGeneration == gen ? "attribute" : "in";
case kVaryingIn_TypeModifier:
return k110_GrGLSLGeneration == gen ? "varying" : "in";
case kVaryingOut_TypeModifier:
return k110_GrGLSLGeneration == gen ? "varying" : "out";
default:
SkFAIL("Unknown shader variable type modifier.");
return ""; // suppress warning

View File

@ -1,34 +0,0 @@
Overview
========
SkSL ("Skia Shading Language") is a variant of GLSL which is used as Skia's
internal shading language. SkSL is, at its heart, a single standardized version
of GLSL which avoids all of the various version and dialect differences found
in GLSL "in the wild", but it does bring a few of its own changes to the table.
Skia uses the SkSL compiler to convert SkSL code to GLSL, GLSL ES, or SPIR-V
before handing it over to the graphics driver.
Differences from GLSL
=====================
SkSL is based on GLSL 4.5. For the most part, write SkSL exactly as you would
desktop GLSL, and the SkSL compiler will take care of version and dialect
differences (for instance, you always use "in" and "out", and skslc will handle
translating them to "varying" and "attribute" as appropriate). Be aware of the
following differences between SkSL and GLSL:
* no #version or "precision" statement is required, and they will be ignored if
present
* the output color is sk_FragColor (do not declare it)
* lowp, mediump, and highp are always permitted (but will only be respected if
you run on a GLES device)
* you do not need to include ".0" to make a number a float (meaning that
"vec2(x, y) * 4" is perfectly legal in SkSL, unlike GLSL where it would have
to be expressed "vec2(x, y) * 4.0". There is no performance penalty for this,
as the number is converted to a float at compile time)
* some built-in functions and one or two rarely-used language features are not
yet supported (sorry!)
SkSL is still under development, and is expected to diverge further from GLSL
over time.

View File

@ -24,8 +24,6 @@ class IRGenerator;
* file into an abstract syntax tree (a tree of ASTNodes), then performs semantic analysis to
* produce a Program (a tree of IRNodes), then feeds the Program into a CodeGenerator to produce
* compiled output.
*
* See the README for information about SkSL.
*/
class Compiler : public ErrorReporter {
public:

View File

@ -16,8 +16,6 @@
#include "ir/SkSLIndexExpression.h"
#include "ir/SkSLVariableReference.h"
#define SK_FRAGCOLOR_BUILTIN 10001
namespace SkSL {
void GLSLCodeGenerator::write(const char* s) {
@ -68,7 +66,7 @@ void GLSLCodeGenerator::writeType(const Type& type) {
this->writeLine("struct " + type.name() + " {");
fIndentation++;
for (const auto& f : type.fields()) {
this->writeModifiers(f.fModifiers, false);
this->writeModifiers(f.fModifiers);
// sizes (which must be static in structs) are part of the type name here
this->writeType(*f.fType);
this->writeLine(" " + f.fName + ";");
@ -126,40 +124,7 @@ void GLSLCodeGenerator::writeExpression(const Expression& expr, Precedence paren
}
}
static bool is_abs(Expression& expr) {
if (expr.fKind != Expression::kFunctionCall_Kind) {
return false;
}
return ((FunctionCall&) expr).fFunction.fName == "abs";
}
// turns min(abs(x), y) into (abs(x) > (tmpVar = y) ? tmpVar : abs(x)) to avoid a Tegra3 compiler
// bug.
void GLSLCodeGenerator::writeMinAbsHack(Expression& absExpr, Expression& otherExpr) {
ASSERT(!fCaps.fCanUseMinAndAbsTogether);
std::string varName = "minAbsHackVar" + to_string(fVarCount++);
this->fFunctionHeader += " " + otherExpr.fType.name() + " " + varName + ";\n";
this->write("(");
this->writeExpression(absExpr, kTopLevel_Precedence);
this->write(" > (" + varName + " = ");
this->writeExpression(otherExpr, kRelational_Precedence);
this->write(") ? " + varName + " : ");
this->writeExpression(absExpr, kTernary_Precedence);
this->write(")");
}
void GLSLCodeGenerator::writeFunctionCall(const FunctionCall& c) {
if (!fCaps.fCanUseMinAndAbsTogether && c.fFunction.fName == "min") {
ASSERT(c.fArguments.size() == 2);
if (is_abs(*c.fArguments[0])) {
this->writeMinAbsHack(*c.fArguments[0], *c.fArguments[1]);
return;
}
if (is_abs(*c.fArguments[1])) {
this->writeMinAbsHack(*c.fArguments[1], *c.fArguments[0]);
return;
}
}
this->write(c.fFunction.fName + "(");
const char* separator = "";
for (const auto& arg : c.fArguments) {
@ -182,15 +147,7 @@ void GLSLCodeGenerator::writeConstructor(const Constructor& c) {
}
void GLSLCodeGenerator::writeVariableReference(const VariableReference& ref) {
if (ref.fVariable.fModifiers.fLayout.fBuiltin == SK_FRAGCOLOR_BUILTIN) {
if (fCaps.fMustDeclareFragmentShaderOutput) {
this->write("sk_FragColor");
} else {
this->write("gl_FragColor");
}
} else {
this->write(ref.fVariable.fName);
}
this->write(ref.fVariable.fName);
}
void GLSLCodeGenerator::writeIndexExpression(const IndexExpression& expr) {
@ -327,89 +284,28 @@ void GLSLCodeGenerator::writeFunction(const FunctionDefinition& f) {
for (const auto& param : f.fDeclaration.fParameters) {
this->write(separator);
separator = ", ";
this->writeModifiers(param->fModifiers, false);
this->writeModifiers(param->fModifiers);
this->writeType(param->fType);
this->write(" " + param->fName);
}
this->writeLine(") {");
fFunctionHeader = "";
std::ostream* oldOut = fOut;
std::stringstream buffer;
fOut = &buffer;
fIndentation++;
for (const auto& s : f.fBody->fStatements) {
this->writeStatement(*s);
this->writeLine();
}
fIndentation--;
this->writeLine("}");
fOut = oldOut;
this->write(fFunctionHeader);
this->write(buffer.str());
this->write(") ");
this->writeBlock(*f.fBody);
this->writeLine();
}
void GLSLCodeGenerator::writeModifiers(const Modifiers& modifiers,
bool globalContext) {
if (modifiers.fFlags & Modifiers::kNoPerspective_Flag) {
this->write("noperspective ");
}
if (modifiers.fFlags & Modifiers::kFlat_Flag) {
this->write("flat ");
}
std::string layout = modifiers.fLayout.description();
if (layout.length()) {
this->write(layout + " ");
}
if ((modifiers.fFlags & Modifiers::kIn_Flag) &&
(modifiers.fFlags & Modifiers::kOut_Flag)) {
this->write("inout ");
} else if (modifiers.fFlags & Modifiers::kIn_Flag) {
if (globalContext && fCaps.fVersion < 130) {
this->write(fProgramKind == Program::kVertex_Kind ? "attribute "
: "varying ");
} else {
this->write("in ");
}
} else if (modifiers.fFlags & Modifiers::kOut_Flag) {
if (globalContext && fCaps.fVersion < 130) {
this->write("varying ");
} else {
this->write("out ");
}
}
if (modifiers.fFlags & Modifiers::kUniform_Flag) {
this->write("uniform ");
}
if (modifiers.fFlags & Modifiers::kConst_Flag) {
this->write("const ");
}
if (fCaps.fUsesPrecisionModifiers) {
bool modifier = false;
if (modifiers.fFlags & Modifiers::kLowp_Flag) {
this->write("lowp ");
modifier = true;
}
if (modifiers.fFlags & Modifiers::kHighp_Flag) {
this->write("highp ");
modifier = true;
}
if (!modifier) {
this->write("mediump ");
}
}
void GLSLCodeGenerator::writeModifiers(const Modifiers& modifiers) {
this->write(modifiers.description());
}
void GLSLCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
if (intf.fVariable.fName == "gl_PerVertex") {
return;
}
this->writeModifiers(intf.fVariable.fModifiers, true);
this->writeModifiers(intf.fVariable.fModifiers);
this->writeLine(intf.fVariable.fType.name() + " {");
fIndentation++;
for (const auto& f : intf.fVariable.fType.fields()) {
this->writeModifiers(f.fModifiers, false);
this->writeModifiers(f.fModifiers);
this->writeType(*f.fType);
this->writeLine(" " + f.fName + ";");
}
@ -417,9 +313,9 @@ void GLSLCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
this->writeLine("};");
}
void GLSLCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, bool global) {
void GLSLCodeGenerator::writeVarDeclarations(const VarDeclarations& decl) {
ASSERT(decl.fVars.size() > 0);
this->writeModifiers(decl.fVars[0].fVar->fModifiers, global);
this->writeModifiers(decl.fVars[0].fVar->fModifiers);
this->writeType(decl.fBaseType);
std::string separator = " ";
for (const auto& var : decl.fVars) {
@ -453,7 +349,7 @@ void GLSLCodeGenerator::writeStatement(const Statement& s) {
this->writeReturnStatement((ReturnStatement&) s);
break;
case Statement::kVarDeclarations_Kind:
this->writeVarDeclarations(*((VarDeclarationsStatement&) s).fDeclaration, false);
this->writeVarDeclarations(*((VarDeclarationsStatement&) s).fDeclaration);
break;
case Statement::kIf_Kind:
this->writeIfStatement((IfStatement&) s);
@ -548,12 +444,9 @@ void GLSLCodeGenerator::writeReturnStatement(const ReturnStatement& r) {
void GLSLCodeGenerator::generateCode(const Program& program, std::ostream& out) {
ASSERT(fOut == nullptr);
fOut = &out;
fProgramKind = program.fKind;
this->write("#version " + to_string(fCaps.fVersion));
if (fCaps.fStandard == GLCaps::kGLES_Standard) {
this->write(" es");
} else if (fCaps.fIsCoreProfile) {
this->write(" core");
}
this->writeLine();
for (const auto& e : program.fElements) {
@ -563,16 +456,10 @@ void GLSLCodeGenerator::generateCode(const Program& program, std::ostream& out)
break;
case ProgramElement::kVar_Kind: {
VarDeclarations& decl = (VarDeclarations&) *e;
if (decl.fVars.size() > 0) {
int builtin = decl.fVars[0].fVar->fModifiers.fLayout.fBuiltin;
if (builtin == -1) {
// normal var
this->writeVarDeclarations(decl, true);
this->writeLine();
} else if (builtin == SK_FRAGCOLOR_BUILTIN &&
fCaps.fMustDeclareFragmentShaderOutput) {
this->writeLine("out vec4 sk_FragColor;");
}
if (decl.fVars.size() > 0 &&
decl.fVars[0].fVar->fModifiers.fLayout.fBuiltin == -1) {
this->writeVarDeclarations(decl);
this->writeLine();
}
break;
}

View File

@ -50,11 +50,6 @@ struct GLCaps {
kGL_Standard,
kGLES_Standard
} fStandard;
bool fIsCoreProfile;
bool fUsesPrecisionModifiers;
bool fMustDeclareFragmentShaderOutput;
// The Tegra3 compiler will sometimes never return if we have min(abs(x), y)
bool fCanUseMinAndAbsTogether;
};
/**
@ -86,7 +81,6 @@ public:
GLSLCodeGenerator(const Context* context, GLCaps caps)
: fContext(*context)
, fCaps(caps)
, fVarCount(0)
, fIndentation(0)
, fAtLineStart(true) {}
@ -117,11 +111,11 @@ private:
void writeLayout(const Layout& layout);
void writeModifiers(const Modifiers& modifiers, bool globalContext);
void writeModifiers(const Modifiers& modifiers);
void writeGlobalVars(const VarDeclaration& vs);
void writeVarDeclarations(const VarDeclarations& decl, bool global);
void writeVarDeclarations(const VarDeclarations& decl);
void writeVariableReference(const VariableReference& ref);
@ -129,8 +123,6 @@ private:
void writeIntrinsicCall(const FunctionCall& c);
void writeMinAbsHack(Expression& absExpr, Expression& otherExpr);
void writeFunctionCall(const FunctionCall& c);
void writeConstructor(const Constructor& c);
@ -172,9 +164,6 @@ private:
const Context& fContext;
const GLCaps fCaps;
std::ostream* fOut;
std::string fFunctionHeader;
Program::Kind fProgramKind;
int fVarCount;
int fIndentation;
bool fAtLineStart;
// Keeps track of which struct types we have written. Given that we are unlikely to ever write

View File

@ -419,9 +419,8 @@ std::unique_ptr<FunctionDefinition> IRGenerator::convertFunction(const ASTFuncti
for (size_t i = 0; i < parameters.size(); i++) {
if (parameters[i]->fModifiers != other->fParameters[i]->fModifiers) {
fErrors.error(f.fPosition, "modifiers on parameter " +
to_string((uint64_t) i + 1) +
" differ between declaration and "
"definition");
to_string(i + 1) + " differ between " +
"declaration and definition");
return nullptr;
}
}
@ -617,9 +616,8 @@ std::unique_ptr<Expression> IRGenerator::coerce(std::unique_ptr<Expression> expr
ASSERT(ctor);
return this->call(Position(), std::move(ctor), std::move(args));
}
std::vector<std::unique_ptr<Expression>> args;
args.push_back(std::move(expr));
return std::unique_ptr<Expression>(new Constructor(Position(), type, std::move(args)));
ABORT("cannot coerce %s to %s", expr->fType.description().c_str(),
type.description().c_str());
}
static bool is_matrix_multiply(const Type& left, const Type& right) {
@ -834,12 +832,12 @@ std::unique_ptr<Expression> IRGenerator::call(Position position,
std::vector<std::unique_ptr<Expression>> arguments) {
if (function.fParameters.size() != arguments.size()) {
std::string msg = "call to '" + function.fName + "' expected " +
to_string((uint64_t) function.fParameters.size()) +
to_string(function.fParameters.size()) +
" argument";
if (function.fParameters.size() != 1) {
msg += "s";
}
msg += ", but found " + to_string((uint64_t) arguments.size());
msg += ", but found " + to_string(arguments.size());
fErrors.error(position, msg);
return nullptr;
}
@ -940,7 +938,7 @@ std::unique_ptr<Expression> IRGenerator::convertConstructor(
if (args.size() != 1) {
fErrors.error(position, "invalid arguments to '" + type.description() +
"' constructor, (expected exactly 1 argument, but found " +
to_string((uint64_t) args.size()) + ")");
to_string(args.size()) + ")");
}
if (args[0]->fType == *fContext.fBool_Type) {
std::unique_ptr<IntLiteral> zero(new IntLiteral(fContext, position, 0));

View File

@ -185,8 +185,7 @@ void Parser::precision() {
this->expect(Token::SEMICOLON, "';'");
}
/* DIRECTIVE(#version) INT_LITERAL ("es" | "compatibility")? |
DIRECTIVE(#extension) IDENTIFIER COLON IDENTIFIER */
/* DIRECTIVE(#version) INT_LITERAL | DIRECTIVE(#extension) IDENTIFIER COLON IDENTIFIER */
std::unique_ptr<ASTDeclaration> Parser::directive() {
Token start;
if (!this->expect(Token::DIRECTIVE, "a directive", &start)) {
@ -194,12 +193,7 @@ std::unique_ptr<ASTDeclaration> Parser::directive() {
}
if (start.fText == "#version") {
this->expect(Token::INT_LITERAL, "a version number");
Token next = this->peek();
if (next.fText == "es" || next.fText == "compatibility") {
this->nextToken();
}
// version is ignored for now; it will eventually become an error when we stop pretending
// to be GLSL
// ignored for now
return nullptr;
} else if (start.fText == "#extension") {
Token name;

View File

@ -9,41 +9,6 @@
namespace SkSL {
std::string to_string(double value) {
std::stringstream buffer;
buffer << std::setprecision(std::numeric_limits<double>::digits10) << value;
std::string result = buffer.str();
if (result.find_last_of(".") == std::string::npos &&
result.find_last_of("e") == std::string::npos) {
result += ".0";
}
return result;
}
std::string to_string(int32_t value) {
std::stringstream buffer;
buffer << value;
return buffer.str();
}
std::string to_string(uint32_t value) {
std::stringstream buffer;
buffer << value;
return buffer.str();
}
std::string to_string(int64_t value) {
std::stringstream buffer;
buffer << value;
return buffer.str();
}
std::string to_string(uint64_t value) {
std::stringstream buffer;
buffer << value;
return buffer.str();
}
int stoi(std::string s) {
return atoi(s.c_str());
}

View File

@ -19,15 +19,11 @@ namespace SkSL {
// our own definitions of certain std:: functions, because they are not always present on Android
std::string to_string(double value);
std::string to_string(int32_t value);
std::string to_string(uint32_t value);
std::string to_string(int64_t value);
std::string to_string(uint64_t value);
template <typename T> std::string to_string(T value) {
std::stringstream buffer;
buffer << std::setprecision(std::numeric_limits<T>::digits10) << value;
return buffer.str();
}
#if _MSC_VER
#define NORETURN __declspec(noreturn)

View File

@ -4,6 +4,4 @@ STRINGIFY(
layout(builtin=15) in vec4 gl_FragCoord;
layout(builtin=10001) vec4 sk_FragColor;
)

View File

@ -26,52 +26,46 @@ static void test(skiatest::Reporter* r, const char* src, SkSL::GLCaps caps, cons
}
}
static SkSL::GLCaps default_caps() {
return {
400,
SkSL::GLCaps::kGL_Standard,
false, // isCoreProfile
false, // usesPrecisionModifiers;
false, // mustDeclareFragmentShaderOutput
true // canUseMinAndAbsTogether
};
}
DEF_TEST(SkSLHelloWorld, r) {
SkSL::GLCaps caps = { 400, SkSL::GLCaps::kGL_Standard };
test(r,
"void main() { sk_FragColor = vec4(0.75); }",
default_caps(),
"out vec4 fragColor; void main() { fragColor = vec4(0.75); }",
caps,
"#version 400\n"
"out vec4 fragColor;\n"
"void main() {\n"
" gl_FragColor = vec4(0.75);\n"
" fragColor = vec4(0.75);\n"
"}\n");
}
DEF_TEST(SkSLControl, r) {
SkSL::GLCaps caps = { 400, SkSL::GLCaps::kGL_Standard };
test(r,
"out vec4 fragColor;"
"void main() {"
"if (1 + 2 + 3 > 5) { sk_FragColor = vec4(0.75); } else { discard; }"
"if (1 + 2 + 3 > 5) { fragColor = vec4(0.75); } else { discard; }"
"int i = 0;"
"while (i < 10) sk_FragColor *= 0.5;"
"do { sk_FragColor += 0.01; } while (sk_FragColor.x < 0.7);"
"while (i < 10) fragColor *= 0.5;"
"do { fragColor += 0.01; } while (fragColor.x < 0.7);"
"for (int i = 0; i < 10; i++) {"
"if (i % 0 == 1) break; else continue;"
"}"
"return;"
"}",
default_caps(),
caps,
"#version 400\n"
"out vec4 fragColor;\n"
"void main() {\n"
" if ((1 + 2) + 3 > 5) {\n"
" gl_FragColor = vec4(0.75);\n"
" fragColor = vec4(0.75);\n"
" } else {\n"
" discard;\n"
" }\n"
" int i = 0;\n"
" while (i < 10) gl_FragColor *= 0.5;\n"
" while (i < 10) fragColor *= 0.5;\n"
" do {\n"
" gl_FragColor += 0.01;\n"
" } while (gl_FragColor.x < 0.7);\n"
" fragColor += 0.01;\n"
" } while (fragColor.x < 0.7);\n"
" for (int i = 0;i < 10; i++) {\n"
" if (i % 0 == 1) break; else continue;\n"
" }\n"
@ -80,30 +74,34 @@ DEF_TEST(SkSLControl, r) {
}
DEF_TEST(SkSLFunctions, r) {
SkSL::GLCaps caps = { 400, SkSL::GLCaps::kGL_Standard };
test(r,
"out vec4 fragColor;"
"float foo(float v[2]) { return v[0] * v[1]; }"
"void bar(inout float x) { float y[2], z; y[0] = x; y[1] = x * 2; z = foo(y); x = z; }"
"void main() { float x = 10; bar(x); sk_FragColor = vec4(x); }",
default_caps(),
"void main() { float x = 10; bar(x); fragColor = vec4(x); }",
caps,
"#version 400\n"
"out vec4 fragColor;\n"
"float foo(in float[2] v) {\n"
" return v[0] * v[1];\n"
"}\n"
"void bar(inout float x) {\n"
" float y[2], z;\n"
" y[0] = x;\n"
" y[1] = x * 2.0;\n"
" y[1] = x * 2;\n"
" z = foo(y);\n"
" x = z;\n"
"}\n"
"void main() {\n"
" float x = 10.0;\n"
" float x = 10;\n"
" bar(x);\n"
" gl_FragColor = vec4(x);\n"
" fragColor = vec4(x);\n"
"}\n");
}
DEF_TEST(SkSLOperators, r) {
SkSL::GLCaps caps = { 400, SkSL::GLCaps::kGL_Standard };
test(r,
"void main() {"
"float x = 1, y = 2;"
@ -125,17 +123,17 @@ DEF_TEST(SkSLOperators, r) {
"z <<= 4;"
"z %= 5;"
"}",
default_caps(),
caps,
"#version 400\n"
"void main() {\n"
" float x = 1.0, y = 2.0;\n"
" float x = 1, y = 2;\n"
" int z = 3;\n"
" x = x + ((y * float(z)) * x) * (y - float(z));\n"
" y = (x / y) / float(z);\n"
" z = (((z / 2) % 3 << 4) >> 2) << 1;\n"
" bool b = x > 4.0 == x < 2.0 || (2 >= 5 && y <= float(z)) && 12 != 11;\n"
" x += 12.0;\n"
" x -= 12.0;\n"
" bool b = x > 4 == x < 2 || (2 >= 5 && y <= float(z)) && 12 != 11;\n"
" x += 12;\n"
" x -= 12;\n"
" x *= (y /= float(z = 10));\n"
" b ||= false;\n"
" b &&= true;\n"
@ -150,6 +148,7 @@ DEF_TEST(SkSLOperators, r) {
}
DEF_TEST(SkSLMatrices, r) {
SkSL::GLCaps caps = { 400, SkSL::GLCaps::kGL_Standard };
test(r,
"void main() {"
"mat2x4 x = mat2x4(1);"
@ -158,18 +157,19 @@ DEF_TEST(SkSLMatrices, r) {
"vec3 v1 = mat3(1) * vec3(1);"
"vec3 v2 = vec3(1) * mat3(1);"
"}",
default_caps(),
caps,
"#version 400\n"
"void main() {\n"
" mat2x4 x = mat2x4(1.0);\n"
" mat3x2 y = mat3x2(1.0, 0.0, 0.0, 1.0, vec2(2.0, 2.0));\n"
" mat2x4 x = mat2x4(1);\n"
" mat3x2 y = mat3x2(1, 0, 0, 1, vec2(2, 2));\n"
" mat3x4 z = x * y;\n"
" vec3 v1 = mat3(1.0) * vec3(1.0);\n"
" vec3 v2 = vec3(1.0) * mat3(1.0);\n"
" vec3 v1 = mat3(1) * vec3(1);\n"
" vec3 v2 = vec3(1) * mat3(1);\n"
"}\n");
}
DEF_TEST(SkSLInterfaceBlock, r) {
SkSL::GLCaps caps = { 400, SkSL::GLCaps::kGL_Standard };
test(r,
"uniform testBlock {"
"float x;"
@ -179,12 +179,12 @@ DEF_TEST(SkSLInterfaceBlock, r) {
"};"
"void main() {"
"}",
default_caps(),
caps,
"#version 400\n"
"uniform testBlock {\n"
" float x;\n"
" float[2] y;\n"
" layout (binding = 12) mat3x2 z;\n"
" layout (binding = 12)mat3x2 z;\n"
" bool w;\n"
"};\n"
"void main() {\n"
@ -192,6 +192,7 @@ DEF_TEST(SkSLInterfaceBlock, r) {
}
DEF_TEST(SkSLStructs, r) {
SkSL::GLCaps caps = { 400, SkSL::GLCaps::kGL_Standard };
test(r,
"struct A {"
"int x;"
@ -206,7 +207,7 @@ DEF_TEST(SkSLStructs, r) {
"B b1, b2, b3;"
"void main() {"
"}",
default_caps(),
caps,
"#version 400\n"
"struct A {\n"
" int x;\n"
@ -217,97 +218,10 @@ DEF_TEST(SkSLStructs, r) {
"struct B {\n"
" float x;\n"
" float[2] y;\n"
" layout (binding = 1) A z;\n"
" layout (binding = 1)A z;\n"
"}\n"
" b1, b2, b3;\n"
"void main() {\n"
"}\n");
}
DEF_TEST(SkSLVersion, r) {
SkSL::GLCaps caps = default_caps();
caps.fVersion = 450;
caps.fIsCoreProfile = true;
test(r,
"in float test; void main() { sk_FragColor = vec4(0.75); }",
caps,
"#version 450 core\n"
"in float test;\n"
"void main() {\n"
" gl_FragColor = vec4(0.75);\n"
"}\n");
caps.fVersion = 110;
caps.fIsCoreProfile = false;
test(r,
"in float test; void main() { sk_FragColor = vec4(0.75); }",
caps,
"#version 110\n"
"varying float test;\n"
"void main() {\n"
" gl_FragColor = vec4(0.75);\n"
"}\n");
}
DEF_TEST(SkSLDeclareOutput, r) {
SkSL::GLCaps caps = default_caps();
caps.fMustDeclareFragmentShaderOutput = true;
test(r,
"void main() { sk_FragColor = vec4(0.75); }",
caps,
"#version 400\n"
"out vec4 sk_FragColor;\n"
"void main() {\n"
" sk_FragColor = vec4(0.75);\n"
"}\n");
}
DEF_TEST(SkSLUsesPrecisionModifiers, r) {
SkSL::GLCaps caps = default_caps();
test(r,
"void main() { float x = 0.75; highp float y = 1; }",
caps,
"#version 400\n"
"void main() {\n"
" float x = 0.75;\n"
" float y = 1.0;\n"
"}\n");
caps.fUsesPrecisionModifiers = true;
test(r,
"void main() { float x = 0.75; highp float y = 1; }",
caps,
"#version 400\n"
"void main() {\n"
" mediump float x = 0.75;\n"
" highp float y = 1.0;\n"
"}\n");
}
DEF_TEST(SkSLMinAbs, r) {
test(r,
"void main() {"
"float x = -5;"
"x = min(abs(x), 6);"
"}",
default_caps(),
"#version 400\n"
"void main() {\n"
" float x = -5.0;\n"
" x = min(abs(x), 6.0);\n"
"}\n");
SkSL::GLCaps caps = default_caps();
caps.fCanUseMinAndAbsTogether = false;
test(r,
"void main() {"
"float x = -5.0;"
"x = min(abs(x), 6.0);"
"}",
caps,
"#version 400\n"
"void main() {\n"
" float minAbsHackVar0;\n"
" float x = -5.0;\n"
" x = (abs(x) > (minAbsHackVar0 = 6.0) ? minAbsHackVar0 : abs(x));\n"
"}\n");
}