aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar csmartdalton <csmartdalton@google.com>2017-02-15 10:41:27 -0700
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-02-17 17:29:23 +0000
commit2e777ead127b03a06ccc7dfc983e1b28e1aa2f86 (patch)
treee7577081a11a7b303d65f5f19087d66417edf345 /src
parente14349a7545e7bd1e93f4c3095db8f481939b053 (diff)
Add a workaround for platforms with broken geo shader invocations
BUG=skia: Change-Id: I9105b65b522d9ffac5a90ca7126bfd4ae88f8069 Reviewed-on: https://skia-review.googlesource.com/8422 Reviewed-by: Greg Daniel <egdaniel@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Chris Dalton <csmartdalton@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrShaderCaps.cpp3
-rw-r--r--src/gpu/gl/GrGLCaps.cpp7
-rw-r--r--src/gpu/glsl/GrGLSLGeometryShaderBuilder.cpp25
-rw-r--r--src/gpu/glsl/GrGLSLGeometryShaderBuilder.h3
4 files changed, 33 insertions, 5 deletions
diff --git a/src/gpu/GrShaderCaps.cpp b/src/gpu/GrShaderCaps.cpp
index 621ac3db03..69af070bc7 100644
--- a/src/gpu/GrShaderCaps.cpp
+++ b/src/gpu/GrShaderCaps.cpp
@@ -58,6 +58,7 @@ GrShaderCaps::GrShaderCaps(const GrContextOptions& options) {
fMustForceNegatedAtanParamToFloat = false;
fAtan2ImplementedAsAtanYOverX = false;
fRequiresLocalOutputColorForFBFetch = false;
+ fMustImplementGSInvocationsWithLoop = false;
fFlatInterpolationSupport = false;
fNoPerspectiveInterpolationSupport = false;
fMultisampleInterpolationSupport = false;
@@ -144,6 +145,8 @@ SkString GrShaderCaps::dump() const {
"YES" : "NO"));
r.appendf("Must use local out color for FBFetch: %s\n", (fRequiresLocalOutputColorForFBFetch ?
"YES" : "NO"));
+ r.appendf("Must implement geo shader invocations with loop : %s\n",
+ (fMustImplementGSInvocationsWithLoop ? "YES" : "NO"));
r.appendf("Flat interpolation support: %s\n", (fFlatInterpolationSupport ? "YES" : "NO"));
r.appendf("No perspective interpolation support: %s\n", (fNoPerspectiveInterpolationSupport ?
"YES" : "NO"));
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index aea875f23b..4c252215a9 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -870,6 +870,13 @@ void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo) {
if (shaderCaps->fFBFetchSupport && kQualcomm_GrGLVendor == ctxInfo.vendor()) {
shaderCaps->fRequiresLocalOutputColorForFBFetch = true;
}
+
+#ifdef SK_BUILD_FOR_MAC
+ // On at least some MacBooks, geometry shaders fall apart if we use more than one invocation. To
+ // work around this, we always use a single invocation and wrap the shader in a loop. The long-
+ // term plan for this WAR is for it to eventually be baked into SkSL.
+ shaderCaps->fMustImplementGSInvocationsWithLoop = true;
+#endif
}
bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
diff --git a/src/gpu/glsl/GrGLSLGeometryShaderBuilder.cpp b/src/gpu/glsl/GrGLSLGeometryShaderBuilder.cpp
index a8e746cf0a..01f223f4b3 100644
--- a/src/gpu/glsl/GrGLSLGeometryShaderBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLGeometryShaderBuilder.cpp
@@ -35,22 +35,39 @@ static const char* output_type_name(GrGLSLGeometryBuilder::OutputType out) {
GrGLSLGeometryBuilder::GrGLSLGeometryBuilder(GrGLSLProgramBuilder* program)
: INHERITED(program)
- , fIsConfigured(false) {
+ , fNumInvocations(0) {
}
void GrGLSLGeometryBuilder::configure(InputType inputType, OutputType outputType, int maxVertices,
int numInvocations) {
- SkASSERT(!fIsConfigured);
+ SkASSERT(!this->isConfigured());
+ fNumInvocations = numInvocations;
+ if (this->getProgramBuilder()->shaderCaps()->mustImplementGSInvocationsWithLoop()) {
+ maxVertices *= numInvocations;
+ numInvocations = 1;
+ }
this->addLayoutQualifier(input_type_name(inputType), kIn_InterfaceQualifier);
this->addLayoutQualifier(SkStringPrintf("invocations = %i", numInvocations).c_str(),
kIn_InterfaceQualifier);
this->addLayoutQualifier(output_type_name(outputType), kOut_InterfaceQualifier);
this->addLayoutQualifier(SkStringPrintf("max_vertices = %i", maxVertices).c_str(),
kOut_InterfaceQualifier);
- fIsConfigured = true;
}
void GrGLSLGeometryBuilder::onFinalize() {
- SkASSERT(fIsConfigured);
+ SkASSERT(this->isConfigured());
fProgramBuilder->varyingHandler()->getGeomDecls(&this->inputs(), &this->outputs());
+ GrShaderVar sk_InvocationID("sk_InvocationID", kInt_GrSLType);
+ this->declareGlobal(sk_InvocationID);
+ SkASSERT(sk_InvocationID.getName() == SkString("sk_InvocationID"));
+ if (this->getProgramBuilder()->shaderCaps()->mustImplementGSInvocationsWithLoop()) {
+ SkString invokeFn;
+ this->emitFunction(kVoid_GrSLType, "invoke", 0, nullptr, this->code().c_str(), &invokeFn);
+ this->code().printf("for (sk_InvocationID = 0; sk_InvocationID < %i; ++sk_InvocationID) {"
+ "%s();"
+ "EndPrimitive();"
+ "}", fNumInvocations, invokeFn.c_str());
+ } else {
+ this->codePrependf("sk_InvocationID = gl_InvocationID;");
+ }
}
diff --git a/src/gpu/glsl/GrGLSLGeometryShaderBuilder.h b/src/gpu/glsl/GrGLSLGeometryShaderBuilder.h
index feedcf2930..04be53030e 100644
--- a/src/gpu/glsl/GrGLSLGeometryShaderBuilder.h
+++ b/src/gpu/glsl/GrGLSLGeometryShaderBuilder.h
@@ -31,11 +31,12 @@ public:
};
void configure(InputType, OutputType, int maxVertices, int numInvocations = 1);
+ bool isConfigured() const { return fNumInvocations; }
private:
void onFinalize() override;
- bool fIsConfigured;
+ int fNumInvocations;
friend class GrGLProgramBuilder;