Revert "Remove interpolants are inaccurate workaround for Adreno 3xx."
This reverts commit a7a278205b
.
Reason for revert: Chrome change had to be reverted because of new failures on Nexus 9 and 6P.
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>
TBR=bsalomon@google.com,brianosman@google.com
Change-Id: Ic6b0e5a343556e59d144852f9fa5b561302f9781
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: chromium:847984
Reviewed-on: https://skia-review.googlesource.com/140380
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
d275ef501c
commit
1b112cc560
@ -38,6 +38,7 @@ GrShaderCaps::GrShaderCaps(const GrContextOptions& options) {
|
||||
fMustObfuscateUniformColor = false;
|
||||
fMustGuardDivisionEvenAfterExplicitZeroCheck = false;
|
||||
fCanUseFragCoord = true;
|
||||
fInterpolantsAreInaccurate = false;
|
||||
fIncompleteShortIntPrecision = false;
|
||||
fFlatInterpolationSupport = false;
|
||||
fPreferFlatInterpolation = false;
|
||||
@ -111,6 +112,7 @@ 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);
|
||||
@ -146,6 +148,7 @@ void GrShaderCaps::applyOptionsOverrides(const GrContextOptions& options) {
|
||||
SkASSERT(!fMustObfuscateUniformColor);
|
||||
SkASSERT(!fMustGuardDivisionEvenAfterExplicitZeroCheck);
|
||||
SkASSERT(fCanUseFragCoord);
|
||||
SkASSERT(!fInterpolantsAreInaccurate);
|
||||
SkASSERT(!fIncompleteShortIntPrecision);
|
||||
}
|
||||
#if GR_TEST_UTILS
|
||||
|
@ -121,6 +121,9 @@ 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; }
|
||||
@ -274,6 +277,7 @@ private:
|
||||
bool fMustObfuscateUniformColor : 1;
|
||||
bool fMustGuardDivisionEvenAfterExplicitZeroCheck : 1;
|
||||
bool fCanUseFragCoord : 1;
|
||||
bool fInterpolantsAreInaccurate : 1;
|
||||
bool fIncompleteShortIntPrecision : 1;
|
||||
|
||||
const char* fVersionDeclString;
|
||||
|
@ -2608,9 +2608,11 @@ 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.
|
||||
// (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.
|
||||
if (kAdreno3xx_GrGLRenderer == ctxInfo.renderer()) {
|
||||
shaderCaps->fCanUseFragCoord = false;
|
||||
shaderCaps->fInterpolantsAreInaccurate = true;
|
||||
}
|
||||
|
||||
// gl_FragCoord has an incorrect subpixel offset on legacy Tegra hardware.
|
||||
|
@ -203,38 +203,69 @@ public:
|
||||
}
|
||||
args.fFragBuilder->codeAppend(";");
|
||||
if (textureGP.usesCoverageEdgeAA()) {
|
||||
const char* aaDistName = nullptr;
|
||||
bool mulByFragCoordW = false;
|
||||
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;
|
||||
// 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();
|
||||
} 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());
|
||||
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.fFragBuilder->codeAppendf(
|
||||
"float mindist = min(min(%s.x, %s.y), min(%s.z, %s.w));",
|
||||
aaDistVarying.fsIn(), aaDistVarying.fsIn(), aaDistVarying.fsIn(),
|
||||
aaDistVarying.fsIn());
|
||||
aaDistName, aaDistName, aaDistName, aaDistName);
|
||||
if (mulByFragCoordW) {
|
||||
args.fFragBuilder->codeAppend("mindist *= sk_FragCoord.w;");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user