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>
This commit is contained in:
parent
c4f4904091
commit
c2d0dd658b
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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() ||
|
||||
|
@ -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 ||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user