do/while loops in SPIR-V no longer cause an assertion failure
BUG=skia: Change-Id: Ic5f590879d8ada5d4580b5c6e9091ccc9532be4b Reviewed-on: https://skia-review.googlesource.com/6605 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
parent
6d4d6cce5e
commit
fd146aa1dd
@ -2626,6 +2626,12 @@ void SPIRVCodeGenerator::writeStatement(const Statement& s, SkWStream& out) {
|
||||
case Statement::kFor_Kind:
|
||||
this->writeForStatement((ForStatement&) s, out);
|
||||
break;
|
||||
case Statement::kWhile_Kind:
|
||||
this->writeWhileStatement((WhileStatement&) s, out);
|
||||
break;
|
||||
case Statement::kDo_Kind:
|
||||
this->writeDoStatement((DoStatement&) s, out);
|
||||
break;
|
||||
case Statement::kBreak_Kind:
|
||||
this->writeInstruction(SpvOpBranch, fBreakTarget.top(), out);
|
||||
break;
|
||||
@ -2712,6 +2718,70 @@ void SPIRVCodeGenerator::writeForStatement(const ForStatement& f, SkWStream& out
|
||||
fContinueTarget.pop();
|
||||
}
|
||||
|
||||
void SPIRVCodeGenerator::writeWhileStatement(const WhileStatement& w, SkWStream& out) {
|
||||
// We believe the while loop code below will work, but Skia doesn't actually use them and
|
||||
// adequately testing this code in the absence of Skia exercising it isn't straightforward. For
|
||||
// the time being, we just fail with an error due to the lack of testing. If you encounter this
|
||||
// message, simply remove the error call below to see whether our while loop support actually
|
||||
// works.
|
||||
fErrors.error(w.fPosition, "internal error: while loop support has been disabled in SPIR-V, "
|
||||
"see SkSLSPIRVCodeGenerator.cpp for details");
|
||||
|
||||
SpvId header = this->nextId();
|
||||
SpvId start = this->nextId();
|
||||
SpvId body = this->nextId();
|
||||
fContinueTarget.push(start);
|
||||
SpvId end = this->nextId();
|
||||
fBreakTarget.push(end);
|
||||
this->writeInstruction(SpvOpBranch, header, out);
|
||||
this->writeLabel(header, out);
|
||||
this->writeInstruction(SpvOpLoopMerge, end, start, SpvLoopControlMaskNone, out);
|
||||
this->writeInstruction(SpvOpBranch, start, out);
|
||||
this->writeLabel(start, out);
|
||||
SpvId test = this->writeExpression(*w.fTest, out);
|
||||
this->writeInstruction(SpvOpBranchConditional, test, body, end, out);
|
||||
this->writeLabel(body, out);
|
||||
this->writeStatement(*w.fStatement, out);
|
||||
if (fCurrentBlock) {
|
||||
this->writeInstruction(SpvOpBranch, start, out);
|
||||
}
|
||||
this->writeLabel(end, out);
|
||||
fBreakTarget.pop();
|
||||
fContinueTarget.pop();
|
||||
}
|
||||
|
||||
void SPIRVCodeGenerator::writeDoStatement(const DoStatement& d, SkWStream& out) {
|
||||
// We believe the do loop code below will work, but Skia doesn't actually use them and
|
||||
// adequately testing this code in the absence of Skia exercising it isn't straightforward. For
|
||||
// the time being, we just fail with an error due to the lack of testing. If you encounter this
|
||||
// message, simply remove the error call below to see whether our do loop support actually
|
||||
// works.
|
||||
fErrors.error(d.fPosition, "internal error: do loop support has been disabled in SPIR-V, see "
|
||||
"SkSLSPIRVCodeGenerator.cpp for details");
|
||||
|
||||
SpvId header = this->nextId();
|
||||
SpvId start = this->nextId();
|
||||
SpvId next = this->nextId();
|
||||
fContinueTarget.push(next);
|
||||
SpvId end = this->nextId();
|
||||
fBreakTarget.push(end);
|
||||
this->writeInstruction(SpvOpBranch, header, out);
|
||||
this->writeLabel(header, out);
|
||||
this->writeInstruction(SpvOpLoopMerge, end, start, SpvLoopControlMaskNone, out);
|
||||
this->writeInstruction(SpvOpBranch, start, out);
|
||||
this->writeLabel(start, out);
|
||||
this->writeStatement(*d.fStatement, out);
|
||||
if (fCurrentBlock) {
|
||||
this->writeInstruction(SpvOpBranch, next, out);
|
||||
}
|
||||
this->writeLabel(next, out);
|
||||
SpvId test = this->writeExpression(*d.fTest, out);
|
||||
this->writeInstruction(SpvOpBranchConditional, test, start, end, out);
|
||||
this->writeLabel(end, out);
|
||||
fBreakTarget.pop();
|
||||
fContinueTarget.pop();
|
||||
}
|
||||
|
||||
void SPIRVCodeGenerator::writeReturnStatement(const ReturnStatement& r, SkWStream& out) {
|
||||
if (r.fExpression) {
|
||||
this->writeInstruction(SpvOpReturnValue, this->writeExpression(*r.fExpression, out),
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "ir/SkSLBinaryExpression.h"
|
||||
#include "ir/SkSLBoolLiteral.h"
|
||||
#include "ir/SkSLConstructor.h"
|
||||
#include "ir/SkSLDoStatement.h"
|
||||
#include "ir/SkSLFloatLiteral.h"
|
||||
#include "ir/SkSLIfStatement.h"
|
||||
#include "ir/SkSLIndexExpression.h"
|
||||
@ -38,6 +39,7 @@
|
||||
#include "ir/SkSLVarDeclarations.h"
|
||||
#include "ir/SkSLVarDeclarationsStatement.h"
|
||||
#include "ir/SkSLVariableReference.h"
|
||||
#include "ir/SkSLWhileStatement.h"
|
||||
#include "spirv.h"
|
||||
|
||||
namespace SkSL {
|
||||
@ -191,6 +193,10 @@ private:
|
||||
|
||||
void writeForStatement(const ForStatement& f, SkWStream& out);
|
||||
|
||||
void writeWhileStatement(const WhileStatement& w, SkWStream& out);
|
||||
|
||||
void writeDoStatement(const DoStatement& d, SkWStream& out);
|
||||
|
||||
void writeReturnStatement(const ReturnStatement& r, SkWStream& out);
|
||||
|
||||
void writeCapabilities(SkWStream& out);
|
||||
|
Loading…
Reference in New Issue
Block a user