diff options
author | Brian Salomon <bsalomon@google.com> | 2018-07-10 09:23:40 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-07-10 13:52:04 +0000 |
commit | a7a278205bb040061cb4ba46839efe18635c7edc (patch) | |
tree | 3bae3874270ea6cd4922b97b66d7be7d10dbc803 | |
parent | e4db80f1a6a51d11b5471783332513781388cb8d (diff) |
Remove interpolants are inaccurate workaround for Adreno 3xx.
The chrome screenshot unit test that led to adding this workaround has
been adjusted to avoid testing AA edges of rendered rectangles. We're
accepting the inaccuracy in favor of increased performance.
Chrome change: https://chromium-review.googlesource.com/c/chromium/src/+/1129041
Bug: chromium:847984
Change-Id: I9b714ade2a67e956ebb2773ebe3b8632dc3a50c6
Reviewed-on: https://skia-review.googlesource.com/140180
Commit-Queue: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
-rw-r--r-- | src/gpu/GrShaderCaps.cpp | 3 | ||||
-rw-r--r-- | src/gpu/GrShaderCaps.h | 4 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.cpp | 4 | ||||
-rw-r--r-- | src/gpu/ops/GrTextureOp.cpp | 85 |
4 files changed, 28 insertions, 68 deletions
diff --git a/src/gpu/GrShaderCaps.cpp b/src/gpu/GrShaderCaps.cpp index 486909e028..70c7388f29 100644 --- a/src/gpu/GrShaderCaps.cpp +++ b/src/gpu/GrShaderCaps.cpp @@ -38,7 +38,6 @@ GrShaderCaps::GrShaderCaps(const GrContextOptions& options) { fMustObfuscateUniformColor = false; fMustGuardDivisionEvenAfterExplicitZeroCheck = false; fCanUseFragCoord = true; - fInterpolantsAreInaccurate = false; fIncompleteShortIntPrecision = false; fFlatInterpolationSupport = false; fPreferFlatInterpolation = false; @@ -112,7 +111,6 @@ void GrShaderCaps::dumpJSON(SkJSONWriter* writer) const { writer->appendBool("Must guard division even after explicit zero check", fMustGuardDivisionEvenAfterExplicitZeroCheck); writer->appendBool("Can use gl_FragCoord", fCanUseFragCoord); - writer->appendBool("Interpolants are inaccurate", fInterpolantsAreInaccurate); writer->appendBool("Incomplete short int precision", fIncompleteShortIntPrecision); writer->appendBool("Flat interpolation support", fFlatInterpolationSupport); writer->appendBool("Prefer flat interpolation", fPreferFlatInterpolation); @@ -148,7 +146,6 @@ void GrShaderCaps::applyOptionsOverrides(const GrContextOptions& options) { SkASSERT(!fMustObfuscateUniformColor); SkASSERT(!fMustGuardDivisionEvenAfterExplicitZeroCheck); SkASSERT(fCanUseFragCoord); - SkASSERT(!fInterpolantsAreInaccurate); SkASSERT(!fIncompleteShortIntPrecision); } #if GR_TEST_UTILS diff --git a/src/gpu/GrShaderCaps.h b/src/gpu/GrShaderCaps.h index e16c9f6d5b..66c75dfebb 100644 --- a/src/gpu/GrShaderCaps.h +++ b/src/gpu/GrShaderCaps.h @@ -121,9 +121,6 @@ public: // If false, SkSL uses a workaround so that sk_FragCoord doesn't actually query gl_FragCoord bool canUseFragCoord() const { return fCanUseFragCoord; } - // If true interpolated vertex shader outputs are inaccurate. - bool interpolantsAreInaccurate() const { return fInterpolantsAreInaccurate; } - // If true, short ints can't represent every integer in the 16-bit two's complement range as // required by the spec. SKSL will always emit full ints. bool incompleteShortIntPrecision() const { return fIncompleteShortIntPrecision; } @@ -277,7 +274,6 @@ private: bool fMustObfuscateUniformColor : 1; bool fMustGuardDivisionEvenAfterExplicitZeroCheck : 1; bool fCanUseFragCoord : 1; - bool fInterpolantsAreInaccurate : 1; bool fIncompleteShortIntPrecision : 1; const char* fVersionDeclString; diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index d35dadda03..e7dabbbefb 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -2608,11 +2608,9 @@ void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo, #endif // We've seen Adreno 3xx devices produce incorrect (flipped) values for gl_FragCoord, in some - // (rare) situations. It's sporadic, and mostly on older drivers. It also seems to be the case - // that the interpolation of vertex shader outputs is quite inaccurate. + // (rare) situations. It's sporadic, and mostly on older drivers. if (kAdreno3xx_GrGLRenderer == ctxInfo.renderer()) { shaderCaps->fCanUseFragCoord = false; - shaderCaps->fInterpolantsAreInaccurate = true; } // gl_FragCoord has an incorrect subpixel offset on legacy Tegra hardware. diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp index bced31dbc5..2fe8bb0ab4 100644 --- a/src/gpu/ops/GrTextureOp.cpp +++ b/src/gpu/ops/GrTextureOp.cpp @@ -203,69 +203,38 @@ public: } args.fFragBuilder->codeAppend(";"); if (textureGP.usesCoverageEdgeAA()) { - const char* aaDistName = nullptr; bool mulByFragCoordW = false; - // When interpolation is inaccurate we perform the evaluation of the edge - // equations in the fragment shader rather than interpolating values computed - // in the vertex shader. - if (!args.fShaderCaps->interpolantsAreInaccurate()) { - GrGLSLVarying aaDistVarying(kFloat4_GrSLType, - GrGLSLVarying::Scope::kVertToFrag); - if (kFloat3_GrVertexAttribType == textureGP.fPositions.type()) { - args.fVaryingHandler->addVarying("aaDists", &aaDistVarying); - // The distance from edge equation e to homogenous point p=sk_Position - // is e.x*p.x/p.wx + e.y*p.y/p.w + e.z. However, we want screen space - // interpolation of this distance. We can do this by multiplying the - // varying in the VS by p.w and then multiplying by sk_FragCoord.w in - // the FS. So we output e.x*p.x + e.y*p.y + e.z * p.w - args.fVertBuilder->codeAppendf( - R"(%s = float4(dot(aaEdge0, %s), dot(aaEdge1, %s), - dot(aaEdge2, %s), dot(aaEdge3, %s));)", - aaDistVarying.vsOut(), textureGP.fPositions.name(), - textureGP.fPositions.name(), textureGP.fPositions.name(), - textureGP.fPositions.name()); - mulByFragCoordW = true; - } else { - args.fVaryingHandler->addVarying("aaDists", &aaDistVarying); - args.fVertBuilder->codeAppendf( - R"(%s = float4(dot(aaEdge0.xy, %s.xy) + aaEdge0.z, - dot(aaEdge1.xy, %s.xy) + aaEdge1.z, - dot(aaEdge2.xy, %s.xy) + aaEdge2.z, - dot(aaEdge3.xy, %s.xy) + aaEdge3.z);)", - aaDistVarying.vsOut(), textureGP.fPositions.name(), - textureGP.fPositions.name(), textureGP.fPositions.name(), - textureGP.fPositions.name()); - } - aaDistName = aaDistVarying.fsIn(); + GrGLSLVarying aaDistVarying(kFloat4_GrSLType, + GrGLSLVarying::Scope::kVertToFrag); + if (kFloat3_GrVertexAttribType == textureGP.fPositions.type()) { + args.fVaryingHandler->addVarying("aaDists", &aaDistVarying); + // The distance from edge equation e to homogenous point p=sk_Position + // is e.x*p.x/p.wx + e.y*p.y/p.w + e.z. However, we want screen space + // interpolation of this distance. We can do this by multiplying the + // varying in the VS by p.w and then multiplying by sk_FragCoord.w in + // the FS. So we output e.x*p.x + e.y*p.y + e.z * p.w + args.fVertBuilder->codeAppendf( + R"(%s = float4(dot(aaEdge0, %s), dot(aaEdge1, %s), + dot(aaEdge2, %s), dot(aaEdge3, %s));)", + aaDistVarying.vsOut(), textureGP.fPositions.name(), + textureGP.fPositions.name(), textureGP.fPositions.name(), + textureGP.fPositions.name()); + mulByFragCoordW = true; } else { - GrGLSLVarying aaEdgeVarying[4]{ - {kFloat3_GrSLType, GrGLSLVarying::Scope::kVertToFrag}, - {kFloat3_GrSLType, GrGLSLVarying::Scope::kVertToFrag}, - {kFloat3_GrSLType, GrGLSLVarying::Scope::kVertToFrag}, - {kFloat3_GrSLType, GrGLSLVarying::Scope::kVertToFrag} - }; - for (int i = 0; i < 4; ++i) { - SkString name; - name.printf("aaEdge%d", i); - args.fVaryingHandler->addVarying(name.c_str(), &aaEdgeVarying[i], - Interpolation::kCanBeFlat); - args.fVertBuilder->codeAppendf( - "%s = aaEdge%d;", aaEdgeVarying[i].vsOut(), i); - } - args.fFragBuilder->codeAppendf( - R"(float4 aaDists = float4(dot(%s.xy, sk_FragCoord.xy) + %s.z, - dot(%s.xy, sk_FragCoord.xy) + %s.z, - dot(%s.xy, sk_FragCoord.xy) + %s.z, - dot(%s.xy, sk_FragCoord.xy) + %s.z);)", - aaEdgeVarying[0].fsIn(), aaEdgeVarying[0].fsIn(), - aaEdgeVarying[1].fsIn(), aaEdgeVarying[1].fsIn(), - aaEdgeVarying[2].fsIn(), aaEdgeVarying[2].fsIn(), - aaEdgeVarying[3].fsIn(), aaEdgeVarying[3].fsIn()); - aaDistName = "aaDists"; + args.fVaryingHandler->addVarying("aaDists", &aaDistVarying); + args.fVertBuilder->codeAppendf( + R"(%s = float4(dot(aaEdge0.xy, %s.xy) + aaEdge0.z, + dot(aaEdge1.xy, %s.xy) + aaEdge1.z, + dot(aaEdge2.xy, %s.xy) + aaEdge2.z, + dot(aaEdge3.xy, %s.xy) + aaEdge3.z);)", + aaDistVarying.vsOut(), textureGP.fPositions.name(), + textureGP.fPositions.name(), textureGP.fPositions.name(), + textureGP.fPositions.name()); } args.fFragBuilder->codeAppendf( "float mindist = min(min(%s.x, %s.y), min(%s.z, %s.w));", - aaDistName, aaDistName, aaDistName, aaDistName); + aaDistVarying.fsIn(), aaDistVarying.fsIn(), aaDistVarying.fsIn(), + aaDistVarying.fsIn()); if (mulByFragCoordW) { args.fFragBuilder->codeAppend("mindist *= sk_FragCoord.w;"); } |