aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-04-02 12:50:49 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-04-02 12:50:49 +0000
commit42eff161a2acdbf03a71666b3fc31079a1bba86f (patch)
tree88b39d33417bda3929dac0d839072e0a630e7ff2 /src/gpu
parent05a2ee052c9ef4c781b7b590b00b3d2da3b3449a (diff)
Reland 8459 with fix for #extension after default precision in FS.
git-svn-id: http://skia.googlecode.com/svn/trunk@8479 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/effects/GrEdgeEffect.cpp10
-rw-r--r--src/gpu/gl/GrGLProgram.cpp2
-rw-r--r--src/gpu/gl/GrGLSL.cpp10
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.cpp56
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.h32
5 files changed, 84 insertions, 26 deletions
diff --git a/src/gpu/effects/GrEdgeEffect.cpp b/src/gpu/effects/GrEdgeEffect.cpp
index dd7474fd00..6f56413963 100644
--- a/src/gpu/effects/GrEdgeEffect.cpp
+++ b/src/gpu/effects/GrEdgeEffect.cpp
@@ -38,7 +38,7 @@ public:
builder->fsCodeAppendf("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
break;
case GrEdgeEffect::kQuad_EdgeType:
- GrAssert(builder->ctxInfo().caps()->shaderDerivativeSupport());
+ SkAssertResult(builder->enableFeature(GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
builder->addVarying(kVec4f_GrSLType, "QuadEdge", &vsName, &fsName);
// keep the derivative instructions outside the conditional
@@ -56,12 +56,9 @@ public:
fsName);
builder->fsCodeAppendf("\t\t\tedgeAlpha = "
"clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);\n\t\t}\n");
- if (kES2_GrGLBinding == builder->ctxInfo().binding()) {
- builder->fHeader.append("#extension GL_OES_standard_derivatives: enable\n");
- }
break;
case GrEdgeEffect::kHairQuad_EdgeType:
- GrAssert(builder->ctxInfo().caps()->shaderDerivativeSupport());
+ SkAssertResult(builder->enableFeature(GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
builder->addVarying(kVec4f_GrSLType, "HairQuadEdge", &vsName, &fsName);
builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName);
@@ -73,9 +70,6 @@ public:
fsName);
builder->fsCodeAppend("\t\tedgeAlpha = sqrt(edgeAlpha*edgeAlpha / dot(gF, gF));\n");
builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
- if (kES2_GrGLBinding == builder->ctxInfo().binding()) {
- builder->fHeader.append("#extension GL_OES_standard_derivatives: enable\n");
- }
break;
};
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index e1fa3a2613..51cae5c8c8 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -462,8 +462,6 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
// the dual source output has no canonical var name, have to
// declare an output, which is incompatible with gl_FragColor/gl_FragData.
bool dualSourceOutputWritten = false;
- builder.fHeader.append(GrGetGLSLVersionDecl(fContext.info().binding(),
- fContext.info().glslGeneration()));
GrGLShaderVar colorOutput;
bool isColorDeclared = GrGLSLSetupFSColorOuput(fContext.info().glslGeneration(),
diff --git a/src/gpu/gl/GrGLSL.cpp b/src/gpu/gl/GrGLSL.cpp
index b7946fc07a..3ec7fc45b2 100644
--- a/src/gpu/gl/GrGLSL.cpp
+++ b/src/gpu/gl/GrGLSL.cpp
@@ -9,8 +9,7 @@
#include "GrGLShaderVar.h"
#include "SkString.h"
-GrGLSLGeneration GrGetGLSLGeneration(GrGLBinding binding,
- const GrGLInterface* gl) {
+GrGLSLGeneration GrGetGLSLGeneration(GrGLBinding binding, const GrGLInterface* gl) {
GrGLSLVersion ver = GrGLGetGLSLVersion(gl);
switch (binding) {
case kDesktop_GrGLBinding:
@@ -34,8 +33,7 @@ GrGLSLGeneration GrGetGLSLGeneration(GrGLBinding binding,
}
}
-const char* GrGetGLSLVersionDecl(GrGLBinding binding,
- GrGLSLGeneration gen) {
+const char* GrGetGLSLVersionDecl(GrGLBinding binding, GrGLSLGeneration gen) {
switch (gen) {
case k110_GrGLSLGeneration:
if (kES2_GrGLBinding == binding) {
@@ -61,9 +59,7 @@ const char* GrGetGLSLVersionDecl(GrGLBinding binding,
}
}
-bool GrGLSLSetupFSColorOuput(GrGLSLGeneration gen,
- const char* nameIfDeclared,
- GrGLShaderVar* var) {
+bool GrGLSLSetupFSColorOuput(GrGLSLGeneration gen, const char* nameIfDeclared, GrGLShaderVar* var) {
bool declaredOutput = k110_GrGLSLGeneration != gen;
var->set(kVec4f_GrSLType,
GrGLShaderVar::kOut_TypeModifier,
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp
index 0e91df296f..f7ecf367cf 100644
--- a/src/gpu/gl/GrGLShaderBuilder.cpp
+++ b/src/gpu/gl/GrGLShaderBuilder.cpp
@@ -104,6 +104,7 @@ GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo,
, fCtxInfo(ctxInfo)
, fUniformManager(uniformManager)
, fCurrentStageIdx(kNonStageIdx)
+ , fFSFeaturesAddedMask(0)
#if GR_GL_EXPERIMENTAL_GS
, fUsesGS(desc.fExperimentalGS)
#else
@@ -157,6 +158,47 @@ GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo,
}
}
+bool GrGLShaderBuilder::enableFeature(GLSLFeature feature) {
+ switch (feature) {
+ case kStandardDerivatives_GLSLFeature:
+ if (!fCtxInfo.caps()->shaderDerivativeSupport()) {
+ return false;
+ }
+ if (kES2_GrGLBinding == fCtxInfo.binding()) {
+ this->addFSFeature(1 << kStandardDerivatives_GLSLFeature,
+ "GL_OES_standard_derivatives");
+ }
+ return true;
+ default:
+ GrCrash("Unexpected GLSLFeature requested.");
+ return false;
+ }
+}
+
+bool GrGLShaderBuilder::enablePrivateFeature(GLSLPrivateFeature feature) {
+ switch (feature) {
+ case kFragCoordConventions_GLSLPrivateFeature:
+ if (!fCtxInfo.caps()->fragCoordConventionsSupport()) {
+ return false;
+ }
+ if (fCtxInfo.glslGeneration() < k150_GrGLSLGeneration) {
+ this->addFSFeature(1 << kFragCoordConventions_GLSLPrivateFeature,
+ "GL_ARB_fragment_coord_conventions");
+ }
+ return true;
+ default:
+ GrCrash("Unexpected GLSLPrivateFeature requested.");
+ return false;
+ }
+}
+
+void GrGLShaderBuilder::addFSFeature(uint32_t featureBit, const char* extensionName) {
+ if (!(featureBit & fFSFeaturesAddedMask)) {
+ fFSExtensions.appendf("#extension %s: require\n", extensionName);
+ fFSFeaturesAddedMask |= featureBit;
+ }
+}
+
const char* GrGLShaderBuilder::dstColor() const {
if (fDstCopySampler.isInitialized()) {
return kDstColorName;
@@ -388,9 +430,7 @@ const char* GrGLShaderBuilder::fragmentPosition() {
#if 1
if (fCtxInfo.caps()->fragCoordConventionsSupport()) {
if (!fSetupFragPosition) {
- if (fCtxInfo.glslGeneration() < k150_GrGLSLGeneration) {
- fFSHeader.append("#extension GL_ARB_fragment_coord_conventions: require\n");
- }
+ SkAssertResult(this->enablePrivateFeature(kFragCoordConventions_GLSLPrivateFeature));
fFSInputs.push_back().set(kVec4f_GrSLType,
GrGLShaderVar::kIn_TypeModifier,
"gl_FragCoord",
@@ -507,9 +547,11 @@ void GrGLShaderBuilder::appendUniformDecls(ShaderType stype, SkString* out) cons
}
void GrGLShaderBuilder::getShader(ShaderType type, SkString* shaderStr) const {
+ const char* version = GrGetGLSLVersionDecl(fCtxInfo.binding(), fCtxInfo.glslGeneration());
+
switch (type) {
case kVertex_ShaderType:
- *shaderStr = fHeader;
+ *shaderStr = version;
this->appendUniformDecls(kVertex_ShaderType, shaderStr);
this->appendDecls(fVSAttrs, shaderStr);
this->appendDecls(fVSOutputs, shaderStr);
@@ -519,7 +561,7 @@ void GrGLShaderBuilder::getShader(ShaderType type, SkString* shaderStr) const {
break;
case kGeometry_ShaderType:
if (fUsesGS) {
- *shaderStr = fHeader;
+ *shaderStr = version;
shaderStr->append(fGSHeader);
this->appendDecls(fGSInputs, shaderStr);
this->appendDecls(fGSOutputs, shaderStr);
@@ -531,11 +573,11 @@ void GrGLShaderBuilder::getShader(ShaderType type, SkString* shaderStr) const {
}
break;
case kFragment_ShaderType:
- *shaderStr = fHeader;
+ *shaderStr = version;
+ shaderStr->append(fFSExtensions);
append_default_precision_qualifier(kDefaultFragmentPrecision,
fCtxInfo.binding(),
shaderStr);
- shaderStr->append(fFSHeader);
this->appendUniformDecls(kFragment_ShaderType, shaderStr);
this->appendDecls(fFSInputs, shaderStr);
// We shouldn't have declared outputs on 1.10
diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h
index 4e39f91e35..ab093fb050 100644
--- a/src/gpu/gl/GrGLShaderBuilder.h
+++ b/src/gpu/gl/GrGLShaderBuilder.h
@@ -107,6 +107,22 @@ public:
GrGLShaderBuilder(const GrGLContextInfo&, GrGLUniformManager&, const GrGLProgramDesc&);
/**
+ * Use of these features may require a GLSL extension to be enabled. Shaders may not compile
+ * if code is added that uses one of these features without calling enableFeature()
+ */
+ enum GLSLFeature {
+ kStandardDerivatives_GLSLFeature = 0,
+
+ kLastGLSLFeature = kStandardDerivatives_GLSLFeature
+ };
+
+ /**
+ * If the feature is supported then true is returned and any necessary #extension declarations
+ * are added to the shaders. If the feature is not supported then false will be returned.
+ */
+ bool enableFeature(GLSLFeature);
+
+ /**
* Called by GrGLEffects to add code to one of the shaders.
*/
void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
@@ -313,7 +329,6 @@ private:
// TODO: Everything below here private.
public:
- SkString fHeader; // VS+FS, GLSL version, etc
VarArray fVSAttrs;
VarArray fVSOutputs;
VarArray fGSInputs;
@@ -327,6 +342,18 @@ private:
kNonStageIdx = -1,
};
+ /**
+ * Features that should only be enabled by GrGLShaderBuilder itself.
+ */
+ enum GLSLPrivateFeature {
+ kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1
+ };
+ bool enablePrivateFeature(GLSLPrivateFeature);
+
+ // If we ever have VS/GS features we can expand this to take a bitmask of ShaderType and track
+ // the enables separately for each shader.
+ void addFSFeature(uint32_t featureBit, const char* extensionName);
+
// Interpretation of DstReadKey when generating code
enum {
kNoDstRead_DstReadKey = 0,
@@ -338,8 +365,9 @@ private:
const GrGLContextInfo& fCtxInfo;
GrGLUniformManager& fUniformManager;
int fCurrentStageIdx;
+ uint32_t fFSFeaturesAddedMask;
SkString fFSFunctions;
- SkString fFSHeader;
+ SkString fFSExtensions;
bool fUsesGS;