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:
parent
b3e9ae6c0c
commit
a316395e66
@ -18,7 +18,7 @@
|
||||
],
|
||||
'all_dependent_settings': {
|
||||
'include_dirs': [
|
||||
'<(skia_src_path)/sksl',
|
||||
'../src/sksl',
|
||||
],
|
||||
},
|
||||
},
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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()
|
||||
);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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, ...) {
|
||||
|
@ -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
|
||||
|
@ -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.
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -4,6 +4,4 @@ STRINGIFY(
|
||||
|
||||
layout(builtin=15) in vec4 gl_FragCoord;
|
||||
|
||||
layout(builtin=10001) vec4 sk_FragColor;
|
||||
|
||||
)
|
@ -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");
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user