writer: Use semantic info for constant IDs This enables the backends to emit overridable constants that had no ID specified in the attribute. Bug: tint:755 Change-Id: I86587205e065715257f546b546e792a5262562e8 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/50842 Commit-Queue: James Price <jrprice@google.com> Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc index c7a3f26..d76f4f1 100644 --- a/src/writer/hlsl/generator_impl.cc +++ b/src/writer/hlsl/generator_impl.cc
@@ -2689,8 +2689,8 @@ auto* sem = builder_.Sem().Get(var); auto* type = sem->Type(); - if (ast::HasDecoration<ast::OverrideDecoration>(var->decorations())) { - auto const_id = var->constant_id(); + if (sem->IsPipelineConstant()) { + auto const_id = sem->ConstantId(); out << "#ifndef WGSL_SPEC_CONSTANT_" << const_id << std::endl;
diff --git a/src/writer/hlsl/generator_impl_module_constant_test.cc b/src/writer/hlsl/generator_impl_module_constant_test.cc index 6680341..6e82c94 100644 --- a/src/writer/hlsl/generator_impl_module_constant_test.cc +++ b/src/writer/hlsl/generator_impl_module_constant_test.cc
@@ -33,11 +33,10 @@ } TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_SpecConstant) { - auto* var = Const("pos", ty.f32(), Expr(3.0f), - ast::DecorationList{ - create<ast::OverrideDecoration>(23), - }); - WrapInFunction(Decl(var)); + auto* var = GlobalConst("pos", ty.f32(), Expr(3.0f), + ast::DecorationList{ + create<ast::OverrideDecoration>(23), + }); GeneratorImpl& gen = Build(); @@ -67,6 +66,33 @@ )"); } +TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_SpecConstant_NoId) { + auto* a = GlobalConst("a", ty.f32(), Expr(3.0f), + ast::DecorationList{ + create<ast::OverrideDecoration>(0), + }); + auto* b = GlobalConst("b", ty.f32(), Expr(2.0f), + ast::DecorationList{ + create<ast::OverrideDecoration>(), + }); + + GeneratorImpl& gen = Build(); + + ASSERT_TRUE(gen.EmitProgramConstVariable(out, a)) << gen.error(); + ASSERT_TRUE(gen.EmitProgramConstVariable(out, b)) << gen.error(); + EXPECT_EQ(result(), R"(#ifndef WGSL_SPEC_CONSTANT_0 +#define WGSL_SPEC_CONSTANT_0 3.0f +#endif +static const float a = WGSL_SPEC_CONSTANT_0; +#undef WGSL_SPEC_CONSTANT_0 +#ifndef WGSL_SPEC_CONSTANT_1 +#define WGSL_SPEC_CONSTANT_1 2.0f +#endif +static const float b = WGSL_SPEC_CONSTANT_1; +#undef WGSL_SPEC_CONSTANT_1 +)"); +} + } // namespace } // namespace hlsl } // namespace writer
diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc index afb3c5d..0996127 100644 --- a/src/writer/msl/generator_impl.cc +++ b/src/writer/msl/generator_impl.cc
@@ -2257,8 +2257,9 @@ out_ << " " << program_->Symbols().NameFor(var->symbol()); } - if (ast::HasDecoration<ast::OverrideDecoration>(var->decorations())) { - out_ << " [[function_constant(" << var->constant_id() << ")]]"; + auto* sem_var = program_->Sem().Get(var); + if (sem_var->IsPipelineConstant()) { + out_ << " [[function_constant(" << sem_var->ConstantId() << ")]]"; } else if (var->constructor() != nullptr) { out_ << " = "; if (!EmitExpression(var->constructor())) {
diff --git a/src/writer/msl/generator_impl_module_constant_test.cc b/src/writer/msl/generator_impl_module_constant_test.cc index a939ee2..ec70cf5 100644 --- a/src/writer/msl/generator_impl_module_constant_test.cc +++ b/src/writer/msl/generator_impl_module_constant_test.cc
@@ -23,8 +23,8 @@ using MslGeneratorImplTest = TestHelper; TEST_F(MslGeneratorImplTest, Emit_ModuleConstant) { - auto* var = Const("pos", ty.array<f32, 3>(), array<f32, 3>(1.f, 2.f, 3.f)); - WrapInFunction(Decl(var)); + auto* var = + GlobalConst("pos", ty.array<f32, 3>(), array<f32, 3>(1.f, 2.f, 3.f)); GeneratorImpl& gen = Build(); @@ -33,11 +33,10 @@ } TEST_F(MslGeneratorImplTest, Emit_SpecConstant) { - auto* var = Const("pos", ty.f32(), Expr(3.f), - ast::DecorationList{ - create<ast::OverrideDecoration>(23), - }); - WrapInFunction(Decl(var)); + auto* var = GlobalConst("pos", ty.f32(), Expr(3.f), + ast::DecorationList{ + create<ast::OverrideDecoration>(23), + }); GeneratorImpl& gen = Build(); @@ -45,6 +44,25 @@ EXPECT_EQ(gen.result(), "constant float pos [[function_constant(23)]];\n"); } +TEST_F(MslGeneratorImplTest, Emit_SpecConstant_NoId) { + auto* var_a = GlobalConst("a", ty.f32(), nullptr, + ast::DecorationList{ + create<ast::OverrideDecoration>(0), + }); + auto* var_b = GlobalConst("b", ty.f32(), nullptr, + ast::DecorationList{ + create<ast::OverrideDecoration>(), + }); + + GeneratorImpl& gen = Build(); + + ASSERT_TRUE(gen.EmitProgramConstVariable(var_a)) << gen.error(); + ASSERT_TRUE(gen.EmitProgramConstVariable(var_b)) << gen.error(); + EXPECT_EQ(gen.result(), R"(constant float a [[function_constant(0)]]; +constant float b [[function_constant(1)]]; +)"); +} + } // namespace } // namespace msl } // namespace writer
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc index 377ed2c..2fd180a 100644 --- a/src/writer/spirv/builder.cc +++ b/src/writer/spirv/builder.cc
@@ -1493,9 +1493,10 @@ ast::Literal* lit) { ScalarConstant constant; - if (var && ast::HasDecoration<ast::OverrideDecoration>(var->decorations())) { + auto* sem_var = builder_.Sem().Get(var); + if (sem_var && sem_var->IsPipelineConstant()) { constant.is_spec_op = true; - constant.constant_id = var->constant_id(); + constant.constant_id = sem_var->ConstantId(); } if (auto* l = lit->As<ast::BoolLiteral>()) {
diff --git a/src/writer/spirv/builder_global_variable_test.cc b/src/writer/spirv/builder_global_variable_test.cc index 79b8d5c..d3db49f 100644 --- a/src/writer/spirv/builder_global_variable_test.cc +++ b/src/writer/spirv/builder_global_variable_test.cc
@@ -311,6 +311,32 @@ )"); } +TEST_F(BuilderTest, GlobalVar_Override_NoId) { + auto* var_a = GlobalConst("a", ty.bool_(), Expr(true), + ast::DecorationList{ + create<ast::OverrideDecoration>(0), + }); + auto* var_b = GlobalConst("b", ty.bool_(), Expr(false), + ast::DecorationList{ + create<ast::OverrideDecoration>(), + }); + + spirv::Builder& b = Build(); + + EXPECT_TRUE(b.GenerateGlobalVariable(var_a)) << b.error(); + EXPECT_TRUE(b.GenerateGlobalVariable(var_b)) << b.error(); + EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %2 "a" +OpName %3 "b" +)"); + EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %2 SpecId 0 +OpDecorate %3 SpecId 1 +)"); + EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool +%2 = OpSpecConstantTrue %1 +%3 = OpSpecConstantFalse %1 +)"); +} + struct BuiltinData { ast::Builtin builtin; ast::StorageClass storage;
diff --git a/src/writer/wgsl/generator_impl.cc b/src/writer/wgsl/generator_impl.cc index a5be99d..7317829 100644 --- a/src/writer/wgsl/generator_impl.cc +++ b/src/writer/wgsl/generator_impl.cc
@@ -609,7 +609,10 @@ } else if (auto* builtin = deco->As<ast::BuiltinDecoration>()) { out_ << "builtin(" << builtin->value() << ")"; } else if (auto* override_deco = deco->As<ast::OverrideDecoration>()) { - out_ << "override(" << override_deco->value() << ")"; + out_ << "override"; + if (override_deco->HasValue()) { + out_ << "(" << override_deco->value() << ")"; + } } else if (auto* size = deco->As<ast::StructMemberSizeDecoration>()) { out_ << "size(" << size->size() << ")"; } else if (auto* align = deco->As<ast::StructMemberAlignDecoration>()) {
diff --git a/src/writer/wgsl/generator_impl_global_decl_test.cc b/src/writer/wgsl/generator_impl_global_decl_test.cc index 4a91097..e9cceca 100644 --- a/src/writer/wgsl/generator_impl_global_decl_test.cc +++ b/src/writer/wgsl/generator_impl_global_decl_test.cc
@@ -129,6 +129,21 @@ " [[group(0), binding(0)]] var t : [[access(read)]] texture_1d<f32>;\n"); } +TEST_F(WgslGeneratorImplTest, Emit_OverridableConstants) { + GlobalConst("a", ty.f32(), nullptr, {Override()}); + GlobalConst("b", ty.f32(), nullptr, {Override(7u)}); + + GeneratorImpl& gen = Build(); + + gen.increment_indent(); + + ASSERT_TRUE(gen.Generate(nullptr)) << gen.error(); + EXPECT_EQ(gen.result(), R"( [[override]] let a : f32; + + [[override(7)]] let b : f32; +)"); +} + } // namespace } // namespace wgsl } // namespace writer