Wrap switch statements in blocks in HLSL
If variables are declared inside a GLSL switch statement, they are
scoped until the end of the switch statement. This is not compatible
with HLSL rules, where the scoping is until the end of the case. To
work around this, wrap switch statements in a block that declares
the variables in HLSL.
This is done after most other transformations done to the AST are
complete, since some of the other transformations may introduce
temporary variables.
BUG=angleproject:2179
TEST=angle_end2end_tests
Change-Id: Id0bb89affe103177fd3d6a6b2f3619b5e1ada0a6
Reviewed-on: https://chromium-review.googlesource.com/716381
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/tests/gl_tests/GLSLTest.cpp b/src/tests/gl_tests/GLSLTest.cpp
index ff79852..4e7bb7f 100644
--- a/src/tests/gl_tests/GLSLTest.cpp
+++ b/src/tests/gl_tests/GLSLTest.cpp
@@ -3622,6 +3622,75 @@
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}
+// Test switch/case where a variable is declared inside one of the cases and is accessed by a
+// subsequent case.
+TEST_P(GLSLTest_ES3, SwitchWithVariableDeclarationInside)
+{
+ const std::string &fragmentShader =
+ R"(#version 300 es
+
+ precision highp float;
+ out vec4 my_FragColor;
+
+ uniform int u_zero;
+
+ void main()
+ {
+ my_FragColor = vec4(1, 0, 0, 1);
+ switch (u_zero)
+ {
+ case 0:
+ ivec2 i;
+ i = ivec2(1, 0);
+ default:
+ my_FragColor = vec4(0, i[0], 0, 1);
+ }
+ })";
+
+ ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
+ drawQuad(program.get(), "inputAttribute", 0.5f);
+ EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
+// Test nested switch/case where a variable is declared inside one of the cases and is accessed by a
+// subsequent case.
+TEST_P(GLSLTest_ES3, NestedSwitchWithVariableDeclarationInside)
+{
+ const std::string &fragmentShader =
+ R"(#version 300 es
+
+ precision highp float;
+ out vec4 my_FragColor;
+
+ uniform int u_zero;
+ uniform int u_zero2;
+
+ void main()
+ {
+ my_FragColor = vec4(1, 0, 0, 1);
+ switch (u_zero)
+ {
+ case 0:
+ ivec2 i;
+ i = ivec2(1, 0);
+ switch (u_zero2)
+ {
+ case 0:
+ int j;
+ default:
+ j = 1;
+ i *= j;
+ }
+ default:
+ my_FragColor = vec4(0, i[0], 0, 1);
+ }
+ })";
+
+ ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
+ drawQuad(program.get(), "inputAttribute", 0.5f);
+ EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_INSTANTIATE_TEST(GLSLTest,
ES2_D3D9(),