Skip to content

Commit 6c4c005

Browse files
mdenton8Angle LUCI CQ
authored andcommitted
WGSL: fix do-while when body has continue
If the body of the do while had a "continue" it would skip over the evaluation of the loop condition and potentially loop forever. Change to use the special WGSL "continuing" statement, which goes at the end of a loop body and always executes, even if there is an earlier "continue". Bug: angleproject:42267100 Change-Id: I4ac73e6abcb12e0ff395b83dc5666ac1870724e9 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/7003772 Reviewed-by: Liza Burakova <liza@chromium.org> Commit-Queue: Matthew Denton <mpdenton@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org>
1 parent e1c14f0 commit 6c4c005

2 files changed

Lines changed: 29 additions & 3 deletions

File tree

src/compiler/translator/wgsl/TranslatorWGSL.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2367,6 +2367,23 @@ bool OutputWGSLTraverser::emulateDoWhileLoop(TIntermLoop *loopNode)
23672367
{
23682368
ASSERT(loopNode->getType() == TLoopType::ELoopDoWhile);
23692369

2370+
// Emulate do-while with an infinite loop and a WGSL-special "continuing" and "break-if"
2371+
// statement.
2372+
//
2373+
// Example GLSL:
2374+
// do {
2375+
// // Loop body, which might contain 'continue'
2376+
// } while(condition)
2377+
//
2378+
// Becomes WGSL:
2379+
// loop {
2380+
// // Loop body, which might contain 'continue'
2381+
2382+
// continuing {
2383+
// break if !condition;
2384+
// }
2385+
// }
2386+
23702387
TIntermNode *initNode = loopNode->getInit();
23712388
TIntermTyped *condNode = loopNode->getCondition();
23722389
TIntermTyped *exprNode = loopNode->getExpression();
@@ -2377,13 +2394,20 @@ bool OutputWGSLTraverser::emulateDoWhileLoop(TIntermLoop *loopNode)
23772394
// Write an infinite loop.
23782395
mSink << "loop {\n";
23792396
mIndentLevel++;
2397+
// The loop body may contain a "continue" branch.
23802398
loopNode->getBody()->traverse(this);
23812399
mSink << "\n";
23822400
emitIndentation();
23832401
// At the end of the loop, break if the loop condition dos not still hold.
2384-
mSink << "if (!(";
2402+
mSink << "continuing {\n";
2403+
mIndentLevel++;
2404+
emitIndentation();
2405+
mSink << "break if !(";
23852406
condNode->traverse(this);
2386-
mSink << ") { break; }\n";
2407+
mSink << ");\n";
2408+
mIndentLevel--;
2409+
emitIndentation();
2410+
mSink << "}\n";
23872411
mIndentLevel--;
23882412
emitIndentation();
23892413
mSink << "}";

src/tests/compiler_tests/WGSLOutput_test.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,9 @@ fn _uwhileLoopDemo()
646646
{
647647
(_ui)++;
648648
}
649-
if (!((_ui) < (5i)) { break; }
649+
continuing {
650+
break if !((_ui) < (5i));
651+
}
650652
}
651653
}
652654

0 commit comments

Comments
 (0)