Add rewrite_do_while_loops workaround
Bug: chromium: 644669, 829614 Change-Id: Ic6a4cbd9f7c73b9b9a78608f1b4ac4ce4c4f2cb9 Reviewed-on: https://skia-review.googlesource.com/148439 Commit-Queue: Adrienne Walker <enne@chromium.org> Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
parent
9b7e99e394
commit
8b23ca6406
@ -30,6 +30,8 @@
|
||||
pack_parameters_workaround_with_pack_buffer) \
|
||||
GPU_OP(RESTORE_SCISSOR_ON_FBO_CHANGE, \
|
||||
restore_scissor_on_fbo_change) \
|
||||
GPU_OP(REWRITE_DO_WHILE_LOOPS, \
|
||||
rewrite_do_while_loops) \
|
||||
GPU_OP(UNBIND_ATTACHMENTS_ON_BOUND_RENDER_FBO_DELETE, \
|
||||
unbind_attachments_on_bound_render_fbo_delete) \
|
||||
GPU_OP(UNFOLD_SHORT_CIRCUIT_AS_TERNARY_OPERATION, \
|
||||
|
@ -41,6 +41,7 @@ GrShaderCaps::GrShaderCaps(const GrContextOptions& options) {
|
||||
fAddAndTrueToLoopCondition = false;
|
||||
fUnfoldShortCircuitAsTernary = false;
|
||||
fEmulateAbsIntFunction = false;
|
||||
fRewriteDoWhileLoops = false;
|
||||
fFlatInterpolationSupport = false;
|
||||
fPreferFlatInterpolation = false;
|
||||
fNoPerspectiveInterpolationSupport = false;
|
||||
@ -110,6 +111,7 @@ void GrShaderCaps::dumpJSON(SkJSONWriter* writer) const {
|
||||
writer->appendBool("Add and true to loops workaround", fAddAndTrueToLoopCondition);
|
||||
writer->appendBool("Unfold short circuit as ternary", fUnfoldShortCircuitAsTernary);
|
||||
writer->appendBool("Emulate abs(int) function", fEmulateAbsIntFunction);
|
||||
writer->appendBool("Rewrite do while loops", fRewriteDoWhileLoops);
|
||||
writer->appendBool("Flat interpolation support", fFlatInterpolationSupport);
|
||||
writer->appendBool("Prefer flat interpolation", fPreferFlatInterpolation);
|
||||
writer->appendBool("No perspective interpolation support", fNoPerspectiveInterpolationSupport);
|
||||
@ -145,6 +147,7 @@ void GrShaderCaps::applyOptionsOverrides(const GrContextOptions& options) {
|
||||
SkASSERT(!fAddAndTrueToLoopCondition);
|
||||
SkASSERT(!fUnfoldShortCircuitAsTernary);
|
||||
SkASSERT(!fEmulateAbsIntFunction);
|
||||
SkASSERT(!fRewriteDoWhileLoops);
|
||||
}
|
||||
#if GR_TEST_UTILS
|
||||
fDualSourceBlendingSupport = fDualSourceBlendingSupport && !options.fSuppressDualSourceBlending;
|
||||
|
@ -133,6 +133,8 @@ public:
|
||||
|
||||
bool emulateAbsIntFunction() const { return fEmulateAbsIntFunction; }
|
||||
|
||||
bool rewriteDoWhileLoops() const { return fRewriteDoWhileLoops; }
|
||||
|
||||
bool requiresLocalOutputColorForFBFetch() const { return fRequiresLocalOutputColorForFBFetch; }
|
||||
|
||||
bool mustObfuscateUniformColor() const { return fMustObfuscateUniformColor; }
|
||||
@ -271,6 +273,7 @@ private:
|
||||
bool fAddAndTrueToLoopCondition : 1;
|
||||
bool fUnfoldShortCircuitAsTernary : 1;
|
||||
bool fEmulateAbsIntFunction : 1;
|
||||
bool fRewriteDoWhileLoops : 1;
|
||||
|
||||
const char* fVersionDeclString;
|
||||
|
||||
|
@ -2581,6 +2581,10 @@ void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo,
|
||||
shaderCaps->fEmulateAbsIntFunction = true;
|
||||
}
|
||||
|
||||
if (fDriverBugWorkarounds.rewrite_do_while_loops) {
|
||||
shaderCaps->fRewriteDoWhileLoops = 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 (kAdreno430_GrGLRenderer == ctxInfo.renderer() ||
|
||||
|
@ -10,5 +10,6 @@ max_msaa_sample_count_4
|
||||
max_texture_size_limit_4096
|
||||
pack_parameters_workaround_with_pack_buffer
|
||||
restore_scissor_on_fbo_change
|
||||
rewrite_do_while_loops
|
||||
unbind_attachments_on_bound_render_fbo_delete
|
||||
unfold_short_circuit_as_ternary_operation
|
||||
|
@ -1334,11 +1334,56 @@ void GLSLCodeGenerator::writeWhileStatement(const WhileStatement& w) {
|
||||
}
|
||||
|
||||
void GLSLCodeGenerator::writeDoStatement(const DoStatement& d) {
|
||||
this->write("do ");
|
||||
if (!fProgram.fSettings.fCaps->rewriteDoWhileLoops()) {
|
||||
this->write("do ");
|
||||
this->writeStatement(*d.fStatement);
|
||||
this->write(" while (");
|
||||
this->writeExpression(*d.fTest, kTopLevel_Precedence);
|
||||
this->write(");");
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, do the do while loop workaround, to rewrite loops of the form:
|
||||
// do {
|
||||
// CODE;
|
||||
// } while (CONDITION)
|
||||
//
|
||||
// to loops of the form
|
||||
// bool temp = false;
|
||||
// while (true) {
|
||||
// if (temp) {
|
||||
// if (!CONDITION) {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// temp = true;
|
||||
// CODE;
|
||||
// }
|
||||
String tmpVar = "_tmpLoopSeenOnce" + to_string(fVarCount++);
|
||||
this->write("bool ");
|
||||
this->write(tmpVar);
|
||||
this->writeLine(" = false;");
|
||||
this->writeLine("while (true) {");
|
||||
fIndentation++;
|
||||
this->write("if (");
|
||||
this->write(tmpVar);
|
||||
this->writeLine(") {");
|
||||
fIndentation++;
|
||||
this->write("if (!");
|
||||
this->writeExpression(*d.fTest, kPrefix_Precedence);
|
||||
this->writeLine(") {");
|
||||
fIndentation++;
|
||||
this->writeLine("break;");
|
||||
fIndentation--;
|
||||
this->writeLine("}");
|
||||
fIndentation--;
|
||||
this->writeLine("}");
|
||||
this->write(tmpVar);
|
||||
this->writeLine(" = true;");
|
||||
this->writeStatement(*d.fStatement);
|
||||
this->write(" while (");
|
||||
this->writeExpression(*d.fTest, kTopLevel_Precedence);
|
||||
this->write(");");
|
||||
this->writeLine();
|
||||
fIndentation--;
|
||||
this->write("}");
|
||||
}
|
||||
|
||||
void GLSLCodeGenerator::writeSwitchStatement(const SwitchStatement& s) {
|
||||
|
@ -189,6 +189,10 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool rewriteDoWhileLoops() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* fbFetchColorName() const {
|
||||
return nullptr;
|
||||
}
|
||||
@ -353,6 +357,13 @@ public:
|
||||
result->fEmulateAbsIntFunction = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
static sk_sp<GrShaderCaps> RewriteDoWhileLoops() {
|
||||
sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
|
||||
result->fVersionDeclString = "#version 400";
|
||||
result->fRewriteDoWhileLoops = true;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -2047,3 +2047,50 @@ DEF_TEST(SkSLWorkaroundEmulateAbsIntFunction, r) {
|
||||
SkSL::Program::kFragment_Kind
|
||||
);
|
||||
}
|
||||
|
||||
DEF_TEST(SkSLWorkaroundRewriteDoWhileLoops, r) {
|
||||
test(r,
|
||||
"void main() {"
|
||||
" int i = 0;"
|
||||
" do {"
|
||||
" ++i;"
|
||||
" do {"
|
||||
" i++;"
|
||||
" } while (true);"
|
||||
" } while (i < 10);"
|
||||
" sk_FragColor = float4(i);"
|
||||
"}",
|
||||
*SkSL::ShaderCapsFactory::RewriteDoWhileLoops(),
|
||||
"#version 400\n"
|
||||
"out vec4 sk_FragColor;\n"
|
||||
"void main() {\n"
|
||||
" int i = 0;\n"
|
||||
" bool _tmpLoopSeenOnce0 = false;\n"
|
||||
" while (true) {\n"
|
||||
" if (_tmpLoopSeenOnce0) {\n"
|
||||
" if (!(i < 10)) {\n"
|
||||
" break;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" _tmpLoopSeenOnce0 = true;\n"
|
||||
" {\n"
|
||||
" ++i;\n"
|
||||
" bool _tmpLoopSeenOnce1 = false;\n"
|
||||
" while (true) {\n"
|
||||
" if (_tmpLoopSeenOnce1) {\n"
|
||||
" if (!true) {\n"
|
||||
" break;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" _tmpLoopSeenOnce1 = true;\n"
|
||||
" {\n"
|
||||
" i++;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" sk_FragColor = vec4(float(i));\n"
|
||||
"}\n",
|
||||
SkSL::Program::kFragment_Kind
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user