aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Chris Dalton <csmartdalton@google.com>2018-03-07 07:46:10 -0700
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-03-14 16:35:50 +0000
commitc2d0dd658bbb8caebf0cc9d5cf4b98b1bda616e7 (patch)
treee3484818ca2d9b65df1c1b54595ea0e5b2f44891
parentc4f49040919ef5698c9abd31f7f250f572d8caa8 (diff)
Add a shader cap for incomplete short int precision
Bug: skia: Change-Id: Iac36eb763e687f6ecc3acbd4afced66f95596be2 Reviewed-on: https://skia-review.googlesource.com/109003 Reviewed-by: Brian Salomon <bsalomon@google.com> Reviewed-by: Ethan Nicholas <ethannicholas@google.com> Commit-Queue: Chris Dalton <csmartdalton@google.com>
-rw-r--r--include/gpu/GrShaderCaps.h5
-rw-r--r--src/gpu/GrShaderCaps.cpp3
-rw-r--r--src/gpu/gl/GrGLCaps.cpp6
-rw-r--r--src/sksl/SkSLGLSLCodeGenerator.cpp10
-rw-r--r--src/sksl/SkSLUtil.h8
-rw-r--r--tests/SkSLGLSLTest.cpp43
6 files changed, 73 insertions, 2 deletions
diff --git a/include/gpu/GrShaderCaps.h b/include/gpu/GrShaderCaps.h
index 86a2566675..f86e87c461 100644
--- a/include/gpu/GrShaderCaps.h
+++ b/include/gpu/GrShaderCaps.h
@@ -119,6 +119,10 @@ public:
// 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; }
+
bool requiresLocalOutputColorForFBFetch() const { return fRequiresLocalOutputColorForFBFetch; }
bool mustObfuscateUniformColor() const { return fMustObfuscateUniformColor; }
@@ -261,6 +265,7 @@ private:
bool fMustGuardDivisionEvenAfterExplicitZeroCheck : 1;
bool fCanUseFragCoord : 1;
bool fInterpolantsAreInaccurate : 1;
+ bool fIncompleteShortIntPrecision : 1;
const char* fVersionDeclString;
diff --git a/src/gpu/GrShaderCaps.cpp b/src/gpu/GrShaderCaps.cpp
index 517deaddc6..5c6d0b9ce7 100644
--- a/src/gpu/GrShaderCaps.cpp
+++ b/src/gpu/GrShaderCaps.cpp
@@ -39,6 +39,7 @@ GrShaderCaps::GrShaderCaps(const GrContextOptions& options) {
fMustGuardDivisionEvenAfterExplicitZeroCheck = false;
fCanUseFragCoord = true;
fInterpolantsAreInaccurate = false;
+ fIncompleteShortIntPrecision = false;
fFlatInterpolationSupport = false;
fPreferFlatInterpolation = false;
fNoPerspectiveInterpolationSupport = false;
@@ -110,6 +111,7 @@ void GrShaderCaps::dumpJSON(SkJSONWriter* writer) const {
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);
writer->appendBool("No perspective interpolation support", fNoPerspectiveInterpolationSupport);
@@ -144,6 +146,7 @@ void GrShaderCaps::applyOptionsOverrides(const GrContextOptions& options) {
SkASSERT(!fMustGuardDivisionEvenAfterExplicitZeroCheck);
SkASSERT(fCanUseFragCoord);
SkASSERT(!fInterpolantsAreInaccurate);
+ SkASSERT(!fIncompleteShortIntPrecision);
}
#if GR_TEST_UTILS
fDualSourceBlendingSupport = fDualSourceBlendingSupport && !options.fSuppressDualSourceBlending;
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 3b5f6b2278..4def7b7427 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -2371,6 +2371,12 @@ void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo,
shaderCaps->fInterpolantsAreInaccurate = true;
}
+ // On Mali G71, mediump ints don't appear capable of representing every integer beyond +/-2048.
+ // (Are they implemented with fp16?)
+ if (kARM_GrGLVendor == ctxInfo.vendor()) {
+ shaderCaps->fIncompleteShortIntPrecision = true;
+ }
+
// Disabling advanced blend on various platforms with major known issues. We also block Chrome
// for now until its own blacklists can be updated.
if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp
index 2fa7492b20..996714ec62 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.cpp
+++ b/src/sksl/SkSLGLSLCodeGenerator.cpp
@@ -1015,8 +1015,14 @@ const char* GLSLCodeGenerator::getTypePrecision(const Type& type) {
if (usesPrecisionModifiers()) {
switch (type.kind()) {
case Type::kScalar_Kind:
- if (type == *fContext.fHalf_Type || type == *fContext.fShort_Type ||
- type == *fContext.fUShort_Type) {
+ if (type == *fContext.fShort_Type || type == *fContext.fUShort_Type) {
+ if (fProgram.fSettings.fForceHighPrecision ||
+ fProgram.fSettings.fCaps->incompleteShortIntPrecision()) {
+ return "highp ";
+ }
+ return "mediump ";
+ }
+ if (type == *fContext.fHalf_Type) {
return fProgram.fSettings.fForceHighPrecision ? "highp " : "mediump ";
}
if (type == *fContext.fFloat_Type || type == *fContext.fInt_Type ||
diff --git a/src/sksl/SkSLUtil.h b/src/sksl/SkSLUtil.h
index c16156a413..113b13a644 100644
--- a/src/sksl/SkSLUtil.h
+++ b/src/sksl/SkSLUtil.h
@@ -299,6 +299,14 @@ public:
result->fCanUseFragCoord = false;
return result;
}
+
+ static sk_sp<GrShaderCaps> IncompleteShortIntPrecision() {
+ sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
+ result->fVersionDeclString = "#version 310es";
+ result->fUsesPrecisionModifiers = true;
+ result->fIncompleteShortIntPrecision = true;
+ return result;
+ }
};
#endif
diff --git a/tests/SkSLGLSLTest.cpp b/tests/SkSLGLSLTest.cpp
index e63719781d..27797b6189 100644
--- a/tests/SkSLGLSLTest.cpp
+++ b/tests/SkSLGLSLTest.cpp
@@ -1902,4 +1902,47 @@ DEF_TEST(SkSLTernaryLValue, r) {
"}\n");
}
+DEF_TEST(SkSLIncompleteShortIntPrecision, r) {
+ test(r,
+ "uniform sampler2D tex;"
+ "in float2 texcoord;"
+ "in short2 offset;"
+ "void main() {"
+ " short scalar = offset.y;"
+ " sk_FragColor = texture(tex, texcoord + float2(offset * scalar));"
+ "}",
+ *SkSL::ShaderCapsFactory::UsesPrecisionModifiers(),
+ "#version 400\n"
+ "precision mediump float;\n"
+ "out mediump vec4 sk_FragColor;\n"
+ "uniform sampler2D tex;\n"
+ "in highp vec2 texcoord;\n"
+ "in mediump ivec2 offset;\n"
+ "void main() {\n"
+ " mediump int scalar = offset.y;\n"
+ " sk_FragColor = texture(tex, texcoord + vec2(offset * scalar));\n"
+ "}\n",
+ SkSL::Program::kFragment_Kind);
+ test(r,
+ "uniform sampler2D tex;"
+ "in float2 texcoord;"
+ "in short2 offset;"
+ "void main() {"
+ " short scalar = offset.y;"
+ " sk_FragColor = texture(tex, texcoord + float2(offset * scalar));"
+ "}",
+ *SkSL::ShaderCapsFactory::IncompleteShortIntPrecision(),
+ "#version 310es\n"
+ "precision mediump float;\n"
+ "out mediump vec4 sk_FragColor;\n"
+ "uniform sampler2D tex;\n"
+ "in highp vec2 texcoord;\n"
+ "in highp ivec2 offset;\n"
+ "void main() {\n"
+ " highp int scalar = offset.y;\n"
+ " sk_FragColor = texture(tex, texcoord + vec2(offset * scalar));\n"
+ "}\n",
+ SkSL::Program::kFragment_Kind);
+}
+
#endif