aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2018-07-10 09:23:40 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-07-10 13:52:04 +0000
commita7a278205bb040061cb4ba46839efe18635c7edc (patch)
tree3bae3874270ea6cd4922b97b66d7be7d10dbc803
parente4db80f1a6a51d11b5471783332513781388cb8d (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.cpp3
-rw-r--r--src/gpu/GrShaderCaps.h4
-rw-r--r--src/gpu/gl/GrGLCaps.cpp4
-rw-r--r--src/gpu/ops/GrTextureOp.cpp85
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;");
}