mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-11 22:44:04 +00:00
writer/hlsl: Inline fallthrough case statements
FXC does not support fallthrough case statements (DXC does). Fixed: tint:1082 Change-Id: I82e1add5455e438056259f773f34bf9db05970b4 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/60480 Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Ben Clayton <bclayton@chromium.org> Auto-Submit: Ben Clayton <bclayton@google.com> Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
committed by
Tint LUCI CQ
parent
8ebff3dc85
commit
c0fbce65d8
@@ -58,15 +58,6 @@ namespace {
|
||||
const char kTempNamePrefix[] = "tint_tmp";
|
||||
const char kSpecConstantPrefix[] = "WGSL_SPEC_CONSTANT_";
|
||||
|
||||
bool last_is_break_or_fallthrough(const ast::BlockStatement* stmts) {
|
||||
if (stmts->empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return stmts->last()->Is<ast::BreakStatement>() ||
|
||||
stmts->last()->Is<ast::FallthroughStatement>();
|
||||
}
|
||||
|
||||
const char* image_format_to_rwtexture_type(ast::ImageFormat image_format) {
|
||||
switch (image_format) {
|
||||
case ast::ImageFormat::kRgba8Unorm:
|
||||
@@ -2019,7 +2010,8 @@ std::string GeneratorImpl::generate_builtin_name(
|
||||
return "";
|
||||
}
|
||||
|
||||
bool GeneratorImpl::EmitCase(ast::CaseStatement* stmt) {
|
||||
bool GeneratorImpl::EmitCase(ast::SwitchStatement* s, size_t case_idx) {
|
||||
auto* stmt = s->body()[case_idx];
|
||||
if (stmt->IsDefault()) {
|
||||
line() << "default: {";
|
||||
} else {
|
||||
@@ -2036,17 +2028,32 @@ bool GeneratorImpl::EmitCase(ast::CaseStatement* stmt) {
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
ScopedIndent si(this);
|
||||
if (!EmitStatements(stmt->body()->statements())) {
|
||||
increment_indent();
|
||||
TINT_DEFER({
|
||||
decrement_indent();
|
||||
line() << "}";
|
||||
});
|
||||
|
||||
// Emit the case statement
|
||||
if (!EmitStatements(stmt->body()->statements())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Inline all fallthrough case statements. FXC cannot handle fallthroughs.
|
||||
while (tint::Is<ast::FallthroughStatement>(stmt->body()->last())) {
|
||||
case_idx++;
|
||||
stmt = s->body()[case_idx];
|
||||
// Generate each fallthrough case statement in a new block. This is done to
|
||||
// prevent symbol collision of variables declared in these cases statements.
|
||||
if (!EmitBlock(stmt->body())) {
|
||||
return false;
|
||||
}
|
||||
if (!last_is_break_or_fallthrough(stmt->body())) {
|
||||
line() << "break;";
|
||||
}
|
||||
}
|
||||
|
||||
line() << "}";
|
||||
if (!tint::IsAnyOf<ast::BreakStatement, ast::FallthroughStatement>(
|
||||
stmt->body()->last())) {
|
||||
line() << "break;";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -2900,8 +2907,8 @@ bool GeneratorImpl::EmitSwitch(ast::SwitchStatement* stmt) {
|
||||
|
||||
{
|
||||
ScopedIndent si(this);
|
||||
for (auto* s : stmt->body()) {
|
||||
if (!EmitCase(s)) {
|
||||
for (size_t i = 0; i < stmt->body().size(); i++) {
|
||||
if (!EmitCase(stmt, i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,9 +196,10 @@ class GeneratorImpl : public TextGenerator {
|
||||
ast::CallExpression* expr,
|
||||
const sem::Intrinsic* intrinsic);
|
||||
/// Handles a case statement
|
||||
/// @param stmt the statement
|
||||
/// @param s the switch statement
|
||||
/// @param case_idx the index of the switch case in the switch statement
|
||||
/// @returns true if the statement was emitted successfully
|
||||
bool EmitCase(ast::CaseStatement* stmt);
|
||||
bool EmitCase(ast::SwitchStatement* s, size_t case_idx);
|
||||
/// Handles generating constructor expressions
|
||||
/// @param out the output of the expression stream
|
||||
/// @param expr the constructor expression
|
||||
|
||||
@@ -31,7 +31,7 @@ TEST_F(HlslGeneratorImplTest_Case, Emit_Case) {
|
||||
|
||||
gen.increment_indent();
|
||||
|
||||
ASSERT_TRUE(gen.EmitCase(s->body()[0])) << gen.error();
|
||||
ASSERT_TRUE(gen.EmitCase(s, 0)) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"( case 5: {
|
||||
break;
|
||||
}
|
||||
@@ -46,7 +46,7 @@ TEST_F(HlslGeneratorImplTest_Case, Emit_Case_BreaksByDefault) {
|
||||
|
||||
gen.increment_indent();
|
||||
|
||||
ASSERT_TRUE(gen.EmitCase(s->body()[0])) << gen.error();
|
||||
ASSERT_TRUE(gen.EmitCase(s, 0)) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"( case 5: {
|
||||
break;
|
||||
}
|
||||
@@ -55,7 +55,9 @@ TEST_F(HlslGeneratorImplTest_Case, Emit_Case_BreaksByDefault) {
|
||||
|
||||
TEST_F(HlslGeneratorImplTest_Case, Emit_Case_WithFallthrough) {
|
||||
auto* s =
|
||||
Switch(1, Case(Literal(5), Block(create<ast::FallthroughStatement>())),
|
||||
Switch(1, //
|
||||
Case(Literal(4), Block(create<ast::FallthroughStatement>())), //
|
||||
Case(Literal(5), Block(create<ast::ReturnStatement>())), //
|
||||
DefaultCase());
|
||||
WrapInFunction(s);
|
||||
|
||||
@@ -63,9 +65,13 @@ TEST_F(HlslGeneratorImplTest_Case, Emit_Case_WithFallthrough) {
|
||||
|
||||
gen.increment_indent();
|
||||
|
||||
ASSERT_TRUE(gen.EmitCase(s->body()[0])) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"( case 5: {
|
||||
ASSERT_TRUE(gen.EmitCase(s, 0)) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"( case 4: {
|
||||
/* fallthrough */
|
||||
{
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
)");
|
||||
}
|
||||
@@ -80,7 +86,7 @@ TEST_F(HlslGeneratorImplTest_Case, Emit_Case_MultipleSelectors) {
|
||||
|
||||
gen.increment_indent();
|
||||
|
||||
ASSERT_TRUE(gen.EmitCase(s->body()[0])) << gen.error();
|
||||
ASSERT_TRUE(gen.EmitCase(s, 0)) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"( case 5:
|
||||
case 6: {
|
||||
break;
|
||||
@@ -96,7 +102,7 @@ TEST_F(HlslGeneratorImplTest_Case, Emit_Case_Default) {
|
||||
|
||||
gen.increment_indent();
|
||||
|
||||
ASSERT_TRUE(gen.EmitCase(s->body()[0])) << gen.error();
|
||||
ASSERT_TRUE(gen.EmitCase(s, 0)) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"( default: {
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user