Reland "Rewrite switch statements in GLSL strict-ES2 mode."
This reverts commitd26d0e6a47
. Reason for revert: uses dedicated caps bit Original change's description: > Revert "Rewrite switch statements in GLSL strict-ES2 mode." > > This reverts commit45e3838006
. > > Reason for revert: Also need to rewrite them in actual ES2 mode. > > Original change's description: > > Rewrite switch statements in GLSL strict-ES2 mode. > > > > Once this lands, switch statements will work everywhere--Metal, SPIR-V, > > GLSL, and SkVM. > > > > Change-Id: I2797d0a872de8be77bb9f7aa6acb93421d571d70 > > Bug: skia:12450 > > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/452356 > > Commit-Queue: John Stiles <johnstiles@google.com> > > Auto-Submit: John Stiles <johnstiles@google.com> > > Reviewed-by: Brian Osman <brianosman@google.com> > > Bug: skia:12450 > Change-Id: I92656ed40289872405c0873f2c56a52b04e35b1d > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/452556 > Auto-Submit: Brian Osman <brianosman@google.com> > Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com> > Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com> Bug: skia:12450 Change-Id: I0d3b0969d2040dbb4ee808132146687767c97442 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/452560 Commit-Queue: John Stiles <johnstiles@google.com> Commit-Queue: Brian Osman <brianosman@google.com> Auto-Submit: John Stiles <johnstiles@google.com> Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
6b88839eed
commit
c81edd0e8c
@ -397,10 +397,6 @@ sksl_shared_tests = [
|
||||
"/sksl/shared/Structs.sksl",
|
||||
"/sksl/shared/StructsInFunctions.sksl",
|
||||
"/sksl/shared/StructMaxDepth.sksl",
|
||||
"/sksl/shared/Switch.sksl",
|
||||
"/sksl/shared/SwitchDefaultOnly.sksl",
|
||||
"/sksl/shared/SwitchWithFallthrough.sksl",
|
||||
"/sksl/shared/SwitchWithLoops.sksl",
|
||||
"/sksl/shared/SwizzleBoolConstants.sksl",
|
||||
"/sksl/shared/SwizzleByConstantIndex.sksl",
|
||||
"/sksl/shared/SwizzleByIndex.sksl",
|
||||
@ -523,6 +519,10 @@ sksl_settings_tests = [
|
||||
"/sksl/inliner/ExponentialGrowth.sksl",
|
||||
"/sksl/inliner/InlinerCanBeDisabled.sksl",
|
||||
"/sksl/shared/Derivatives.sksl",
|
||||
"/sksl/shared/Switch.sksl",
|
||||
"/sksl/shared/SwitchDefaultOnly.sksl",
|
||||
"/sksl/shared/SwitchWithFallthrough.sksl",
|
||||
"/sksl/shared/SwitchWithLoops.sksl",
|
||||
"/sksl/workarounds/AbsInt.sksl",
|
||||
"/sksl/workarounds/BlendGuardedDivide.sksl",
|
||||
"/sksl/workarounds/BlendModesAllZeroVec.sksl",
|
||||
|
@ -1,3 +1,5 @@
|
||||
/*#pragma settings RewriteSwitchStatements*/
|
||||
|
||||
uniform half4 colorGreen, colorRed;
|
||||
|
||||
half4 main(float2 coords) {
|
||||
|
@ -1,3 +1,5 @@
|
||||
/*#pragma settings RewriteSwitchStatements*/
|
||||
|
||||
uniform half4 colorGreen, colorRed;
|
||||
|
||||
half4 main(float2 coords) {
|
||||
|
@ -1,3 +1,5 @@
|
||||
/*#pragma settings RewriteSwitchStatements*/
|
||||
|
||||
uniform half4 colorGreen, colorRed;
|
||||
|
||||
bool switch_fallthrough(int value) {
|
||||
|
@ -1,3 +1,5 @@
|
||||
/*#pragma settings RewriteSwitchStatements*/
|
||||
|
||||
uniform half4 colorGreen, colorRed;
|
||||
|
||||
bool switch_with_break_in_loop(int x) {
|
||||
|
@ -1354,9 +1354,67 @@ void GLSLCodeGenerator::writeDoStatement(const DoStatement& d) {
|
||||
}
|
||||
|
||||
void GLSLCodeGenerator::writeSwitchStatement(const SwitchStatement& s) {
|
||||
if (fProgram.fConfig->strictES2Mode()) {
|
||||
// TODO(skia:12450): write switch compatibility code
|
||||
fContext.fErrors->error(s.fLine, "switch statements are not supported");
|
||||
if (this->caps().rewriteSwitchStatements()) {
|
||||
String fallthroughVar = "_tmpSwitchFallthrough" + to_string(fVarCount++);
|
||||
String valueVar = "_tmpSwitchValue" + to_string(fVarCount++);
|
||||
String loopVar = "_tmpSwitchLoop" + to_string(fVarCount++);
|
||||
this->write("int ");
|
||||
this->write(valueVar);
|
||||
this->write(" = ");
|
||||
this->writeExpression(*s.value(), Precedence::kAssignment);
|
||||
this->write(", ");
|
||||
this->write(fallthroughVar);
|
||||
this->writeLine(" = 0;");
|
||||
this->write("for (int ");
|
||||
this->write(loopVar);
|
||||
this->write(" = 0; ");
|
||||
this->write(loopVar);
|
||||
this->write(" < 1; ");
|
||||
this->write(loopVar);
|
||||
this->writeLine("++) {");
|
||||
fIndentation++;
|
||||
|
||||
bool firstCase = true;
|
||||
for (const std::unique_ptr<Statement>& stmt : s.cases()) {
|
||||
const SwitchCase& c = stmt->as<SwitchCase>();
|
||||
if (c.value()) {
|
||||
this->write("if ((");
|
||||
if (firstCase) {
|
||||
firstCase = false;
|
||||
} else {
|
||||
this->write(fallthroughVar);
|
||||
this->write(" > 0) || (");
|
||||
}
|
||||
this->write(valueVar);
|
||||
this->write(" == ");
|
||||
this->writeExpression(*c.value(), Precedence::kEquality);
|
||||
this->writeLine(")) {");
|
||||
fIndentation++;
|
||||
|
||||
// We write the entire case-block statement here, and then set `switchFallthrough`
|
||||
// to 1. If the case-block had a break statement in it, we break out of the outer
|
||||
// for-loop entirely, meaning the `switchFallthrough` assignment never occurs, nor
|
||||
// does any code after it inside the switch. We've forbidden `continue` statements
|
||||
// inside switch case-blocks entirely, so we don't need to consider their effect on
|
||||
// control flow; see the Finalizer in FunctionDefinition::Convert.
|
||||
this->writeStatement(*c.statement());
|
||||
this->finishLine();
|
||||
this->write(fallthroughVar);
|
||||
this->write(" = 1;");
|
||||
this->writeLine();
|
||||
|
||||
fIndentation--;
|
||||
this->writeLine("}");
|
||||
} else {
|
||||
// This is the default case. Since it's always last, we can just dump in the code.
|
||||
this->writeStatement(*c.statement());
|
||||
this->finishLine();
|
||||
}
|
||||
}
|
||||
|
||||
fIndentation--;
|
||||
this->writeLine("}");
|
||||
return;
|
||||
}
|
||||
|
||||
this->write("switch (");
|
||||
|
@ -323,10 +323,10 @@ SKSL_TEST(SkSLStaticIf, "shared/StaticIf.sksl")
|
||||
SKSL_TEST_ES3(SkSLStaticSwitch, "shared/StaticSwitch.sksl")
|
||||
SKSL_TEST(SkSLStructArrayFollowedByScalar, "shared/StructArrayFollowedByScalar.sksl")
|
||||
SKSL_TEST(SkSLStructsInFunctions, "shared/StructsInFunctions.sksl")
|
||||
SKSL_TEST_ES3(SkSLSwitch, "shared/Switch.sksl")
|
||||
SKSL_TEST_ES3(SkSLSwitchDefaultOnly, "shared/SwitchDefaultOnly.sksl")
|
||||
SKSL_TEST_ES3(SkSLSwitchWithFallthrough, "shared/SwitchWithFallthrough.sksl")
|
||||
SKSL_TEST_ES3(SkSLSwitchWithLoops, "shared/SwitchWithLoops.sksl")
|
||||
SKSL_TEST(SkSLSwitch, "shared/Switch.sksl")
|
||||
SKSL_TEST(SkSLSwitchDefaultOnly, "shared/SwitchDefaultOnly.sksl")
|
||||
SKSL_TEST(SkSLSwitchWithFallthrough, "shared/SwitchWithFallthrough.sksl")
|
||||
SKSL_TEST(SkSLSwitchWithLoops, "shared/SwitchWithLoops.sksl")
|
||||
SKSL_TEST(SkSLSwizzleBoolConstants, "shared/SwizzleBoolConstants.sksl")
|
||||
SKSL_TEST(SkSLSwizzleByConstantIndex, "shared/SwizzleByConstantIndex.sksl")
|
||||
SKSL_TEST(SkSLSwizzleConstants, "shared/SwizzleConstants.sksl")
|
||||
|
@ -1,19 +1,23 @@
|
||||
|
||||
#version 400
|
||||
out vec4 sk_FragColor;
|
||||
uniform vec4 colorGreen;
|
||||
uniform vec4 colorRed;
|
||||
vec4 main() {
|
||||
vec4 color;
|
||||
switch (int(colorGreen.y)) {
|
||||
case 0:
|
||||
int _tmpSwitchValue1 = int(colorGreen.y), _tmpSwitchFallthrough0 = 0;
|
||||
for (int _tmpSwitchLoop2 = 0; _tmpSwitchLoop2 < 1; _tmpSwitchLoop2++) {
|
||||
if ((_tmpSwitchValue1 == 0)) {
|
||||
color = colorRed;
|
||||
break;
|
||||
case 1:
|
||||
_tmpSwitchFallthrough0 = 1;
|
||||
}
|
||||
if ((_tmpSwitchFallthrough0 > 0) || (_tmpSwitchValue1 == 1)) {
|
||||
color = colorGreen;
|
||||
break;
|
||||
default:
|
||||
color = colorRed;
|
||||
break;
|
||||
_tmpSwitchFallthrough0 = 1;
|
||||
}
|
||||
color = colorRed;
|
||||
break;
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
|
||||
#version 400
|
||||
out vec4 sk_FragColor;
|
||||
uniform vec4 colorGreen;
|
||||
uniform vec4 colorRed;
|
||||
vec4 main() {
|
||||
switch (int(colorGreen.y)) {
|
||||
case 0:
|
||||
default:
|
||||
return colorGreen;
|
||||
int _tmpSwitchValue1 = int(colorGreen.y), _tmpSwitchFallthrough0 = 0;
|
||||
for (int _tmpSwitchLoop2 = 0; _tmpSwitchLoop2 < 1; _tmpSwitchLoop2++) {
|
||||
return colorGreen;
|
||||
}
|
||||
}
|
||||
|
11
tests/sksl/shared/SwitchDefaultOnlyStandaloneSettings.glsl
Normal file
11
tests/sksl/shared/SwitchDefaultOnlyStandaloneSettings.glsl
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
out vec4 sk_FragColor;
|
||||
uniform vec4 colorGreen;
|
||||
uniform vec4 colorRed;
|
||||
vec4 main() {
|
||||
switch (int(colorGreen.y)) {
|
||||
case 0:
|
||||
default:
|
||||
return colorGreen;
|
||||
}
|
||||
}
|
19
tests/sksl/shared/SwitchStandaloneSettings.glsl
Normal file
19
tests/sksl/shared/SwitchStandaloneSettings.glsl
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
out vec4 sk_FragColor;
|
||||
uniform vec4 colorGreen;
|
||||
uniform vec4 colorRed;
|
||||
vec4 main() {
|
||||
vec4 color;
|
||||
switch (int(colorGreen.y)) {
|
||||
case 0:
|
||||
color = colorRed;
|
||||
break;
|
||||
case 1:
|
||||
color = colorGreen;
|
||||
break;
|
||||
default:
|
||||
color = colorRed;
|
||||
break;
|
||||
}
|
||||
return color;
|
||||
}
|
@ -1,34 +1,54 @@
|
||||
|
||||
#version 400
|
||||
out vec4 sk_FragColor;
|
||||
uniform vec4 colorGreen;
|
||||
uniform vec4 colorRed;
|
||||
bool switch_fallthrough_twice_bi(int value) {
|
||||
bool ok = false;
|
||||
switch (value) {
|
||||
case 0:
|
||||
int _tmpSwitchValue1 = value, _tmpSwitchFallthrough0 = 0;
|
||||
for (int _tmpSwitchLoop2 = 0; _tmpSwitchLoop2 < 1; _tmpSwitchLoop2++) {
|
||||
if ((_tmpSwitchValue1 == 0)) {
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
_tmpSwitchFallthrough0 = 1;
|
||||
}
|
||||
if ((_tmpSwitchFallthrough0 > 0) || (_tmpSwitchValue1 == 1)) {
|
||||
{
|
||||
}
|
||||
_tmpSwitchFallthrough0 = 1;
|
||||
}
|
||||
if ((_tmpSwitchFallthrough0 > 0) || (_tmpSwitchValue1 == 2)) {
|
||||
{
|
||||
}
|
||||
_tmpSwitchFallthrough0 = 1;
|
||||
}
|
||||
if ((_tmpSwitchFallthrough0 > 0) || (_tmpSwitchValue1 == 3)) {
|
||||
ok = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
_tmpSwitchFallthrough0 = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
vec4 main() {
|
||||
int x = int(colorGreen.y);
|
||||
bool _0_ok = false;
|
||||
switch (x) {
|
||||
case 2:
|
||||
int _tmpSwitchValue4 = x, _tmpSwitchFallthrough3 = 0;
|
||||
for (int _tmpSwitchLoop5 = 0; _tmpSwitchLoop5 < 1; _tmpSwitchLoop5++) {
|
||||
if ((_tmpSwitchValue4 == 2)) {
|
||||
break;
|
||||
case 1:
|
||||
case 0:
|
||||
_tmpSwitchFallthrough3 = 1;
|
||||
}
|
||||
if ((_tmpSwitchFallthrough3 > 0) || (_tmpSwitchValue4 == 1)) {
|
||||
{
|
||||
}
|
||||
_tmpSwitchFallthrough3 = 1;
|
||||
}
|
||||
if ((_tmpSwitchFallthrough3 > 0) || (_tmpSwitchValue4 == 0)) {
|
||||
_0_ok = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
_tmpSwitchFallthrough3 = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return _0_ok && switch_fallthrough_twice_bi(x) ? colorGreen : colorRed;
|
||||
}
|
||||
|
@ -0,0 +1,34 @@
|
||||
|
||||
out vec4 sk_FragColor;
|
||||
uniform vec4 colorGreen;
|
||||
uniform vec4 colorRed;
|
||||
bool switch_fallthrough_twice_bi(int value) {
|
||||
bool ok = false;
|
||||
switch (value) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
ok = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
vec4 main() {
|
||||
int x = int(colorGreen.y);
|
||||
bool _0_ok = false;
|
||||
switch (x) {
|
||||
case 2:
|
||||
break;
|
||||
case 1:
|
||||
case 0:
|
||||
_0_ok = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return _0_ok && switch_fallthrough_twice_bi(x) ? colorGreen : colorRed;
|
||||
}
|
@ -1,30 +1,34 @@
|
||||
|
||||
#version 400
|
||||
out vec4 sk_FragColor;
|
||||
uniform vec4 colorGreen;
|
||||
uniform vec4 colorRed;
|
||||
bool switch_with_continue_in_loop_bi(int x) {
|
||||
int val = 0;
|
||||
switch (x) {
|
||||
case 1:
|
||||
int _tmpSwitchValue1 = x, _tmpSwitchFallthrough0 = 0;
|
||||
for (int _tmpSwitchLoop2 = 0; _tmpSwitchLoop2 < 1; _tmpSwitchLoop2++) {
|
||||
if ((_tmpSwitchValue1 == 1)) {
|
||||
for (int i = 0;i < 10; ++i) {
|
||||
++val;
|
||||
continue;
|
||||
++val;
|
||||
}
|
||||
default:
|
||||
++val;
|
||||
_tmpSwitchFallthrough0 = 1;
|
||||
}
|
||||
++val;
|
||||
}
|
||||
return val == 11;
|
||||
}
|
||||
bool loop_with_break_in_switch_bi(int x) {
|
||||
int val = 0;
|
||||
for (int i = 0;i < 10; ++i) {
|
||||
switch (x) {
|
||||
case 1:
|
||||
int _tmpSwitchValue4 = x, _tmpSwitchFallthrough3 = 0;
|
||||
for (int _tmpSwitchLoop5 = 0; _tmpSwitchLoop5 < 1; _tmpSwitchLoop5++) {
|
||||
if ((_tmpSwitchValue4 == 1)) {
|
||||
++val;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
_tmpSwitchFallthrough3 = 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
++val;
|
||||
}
|
||||
@ -33,15 +37,17 @@ bool loop_with_break_in_switch_bi(int x) {
|
||||
vec4 main() {
|
||||
int x = int(colorGreen.y);
|
||||
int _0_val = 0;
|
||||
switch (x) {
|
||||
case 1:
|
||||
int _tmpSwitchValue7 = x, _tmpSwitchFallthrough6 = 0;
|
||||
for (int _tmpSwitchLoop8 = 0; _tmpSwitchLoop8 < 1; _tmpSwitchLoop8++) {
|
||||
if ((_tmpSwitchValue7 == 1)) {
|
||||
for (int _1_i = 0;_1_i < 10; ++_1_i) {
|
||||
++_0_val;
|
||||
break;
|
||||
++_0_val;
|
||||
}
|
||||
default:
|
||||
++_0_val;
|
||||
_tmpSwitchFallthrough6 = 1;
|
||||
}
|
||||
++_0_val;
|
||||
}
|
||||
return (_0_val == 2 && switch_with_continue_in_loop_bi(x)) && loop_with_break_in_switch_bi(x) ? colorGreen : colorRed;
|
||||
}
|
||||
|
47
tests/sksl/shared/SwitchWithLoopsStandaloneSettings.glsl
Normal file
47
tests/sksl/shared/SwitchWithLoopsStandaloneSettings.glsl
Normal file
@ -0,0 +1,47 @@
|
||||
|
||||
out vec4 sk_FragColor;
|
||||
uniform vec4 colorGreen;
|
||||
uniform vec4 colorRed;
|
||||
bool switch_with_continue_in_loop_bi(int x) {
|
||||
int val = 0;
|
||||
switch (x) {
|
||||
case 1:
|
||||
for (int i = 0;i < 10; ++i) {
|
||||
++val;
|
||||
continue;
|
||||
++val;
|
||||
}
|
||||
default:
|
||||
++val;
|
||||
}
|
||||
return val == 11;
|
||||
}
|
||||
bool loop_with_break_in_switch_bi(int x) {
|
||||
int val = 0;
|
||||
for (int i = 0;i < 10; ++i) {
|
||||
switch (x) {
|
||||
case 1:
|
||||
++val;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
++val;
|
||||
}
|
||||
return val == 20;
|
||||
}
|
||||
vec4 main() {
|
||||
int x = int(colorGreen.y);
|
||||
int _0_val = 0;
|
||||
switch (x) {
|
||||
case 1:
|
||||
for (int _1_i = 0;_1_i < 10; ++_1_i) {
|
||||
++_0_val;
|
||||
break;
|
||||
++_0_val;
|
||||
}
|
||||
default:
|
||||
++_0_val;
|
||||
}
|
||||
return (_0_val == 2 && switch_with_continue_in_loop_bi(x)) && loop_with_break_in_switch_bi(x) ? colorGreen : colorRed;
|
||||
}
|
Loading…
Reference in New Issue
Block a user