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-17 13:30:20 +0000 |
commit | 9b4bd599015445dbbfb85af3159404c1c5c21bc4 (patch) | |
tree | 06d7e3355b6f0cd38c4afa0263c7cf60c7e4c5a2 | |
parent | f960398f331912adceb3455cd10c65e33ce184e0 (diff) |
Reland "Remove interpolants are inaccurate workaround for Adreno 3xx."
This is a reland of a7a278205bb040061cb4ba46839efe18635c7edc
Clean reland. Change to Chrome screenshot unit test has stuck. The previous
revert of that was the reason this had to be reverted.
Original change's description:
> 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>
Bug: chromium:847984
Change-Id: I2dc1195f07bb27015b0a7a0fa6263d0e60a32a15
Reviewed-on: https://skia-review.googlesource.com/141761
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@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 10f04813ca..9ab5f90882 100644 --- a/src/gpu/GrShaderCaps.cpp +++ b/src/gpu/GrShaderCaps.cpp @@ -37,7 +37,6 @@ GrShaderCaps::GrShaderCaps(const GrContextOptions& options) { fMustObfuscateUniformColor = false; fMustGuardDivisionEvenAfterExplicitZeroCheck = false; fCanUseFragCoord = true; - fInterpolantsAreInaccurate = false; fIncompleteShortIntPrecision = false; fFlatInterpolationSupport = false; fPreferFlatInterpolation = false; @@ -108,7 +107,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); @@ -143,7 +141,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 7985a741c9..ee3681a0b2 100644 --- a/src/gpu/GrShaderCaps.h +++ b/src/gpu/GrShaderCaps.h @@ -118,9 +118,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; } @@ -267,7 +264,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 0e5ed52350..1f208c8978 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -2558,11 +2558,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 108ee4294a..ff0198533f 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;"); } |