Convert `@location` to store expression internally.
This CL updates the internal storage for a `@location` attribute
to store the `Expression` instead of a raw `uint32_t`. The current
parser is updated to generate an `IntLiteralExpression` so we still
parse as a `uint32_t` at the moment.
Bug: tint:1633
Change-Id: I2b9684754a657b39554160c81727cf1541bee96c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/101461
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
diff --git a/src/tint/writer/glsl/generator_impl.cc b/src/tint/writer/glsl/generator_impl.cc
index 8b2d898..132f542 100644
--- a/src/tint/writer/glsl/generator_impl.cc
+++ b/src/tint/writer/glsl/generator_impl.cc
@@ -1856,7 +1856,7 @@
return Switch(
global, //
[&](const ast::Var* var) {
- auto* sem = builder_.Sem().Get(global);
+ auto* sem = builder_.Sem().Get<sem::GlobalVariable>(global);
switch (sem->StorageClass()) {
case ast::StorageClass::kUniform:
return EmitUniformVariable(var, sem);
@@ -2005,7 +2005,7 @@
return true;
}
-bool GeneratorImpl::EmitIOVariable(const sem::Variable* var) {
+bool GeneratorImpl::EmitIOVariable(const sem::GlobalVariable* var) {
auto* decl = var->Declaration();
if (auto* b = ast::GetAttribute<ast::BuiltinAttribute>(decl->attributes)) {
@@ -2018,7 +2018,7 @@
}
auto out = line();
- EmitAttributes(out, decl->attributes);
+ EmitAttributes(out, var, decl->attributes);
EmitInterpolationQualifiers(out, decl->attributes);
auto name = builder_.Symbols().NameFor(decl->symbol);
@@ -2065,15 +2065,16 @@
}
bool GeneratorImpl::EmitAttributes(std::ostream& out,
+ const sem::GlobalVariable* var,
utils::VectorRef<const ast::Attribute*> attributes) {
if (attributes.IsEmpty()) {
return true;
}
bool first = true;
for (auto* attr : attributes) {
- if (auto* location = attr->As<ast::LocationAttribute>()) {
+ if (attr->As<ast::LocationAttribute>()) {
out << (first ? "layout(" : ", ");
- out << "location = " << std::to_string(location->value);
+ out << "location = " << std::to_string(var->Location().value());
first = false;
}
}
diff --git a/src/tint/writer/glsl/generator_impl.h b/src/tint/writer/glsl/generator_impl.h
index 502df8b..e70bdc2 100644
--- a/src/tint/writer/glsl/generator_impl.h
+++ b/src/tint/writer/glsl/generator_impl.h
@@ -324,7 +324,7 @@
/// Handles emitting a global variable with the input or output storage class
/// @param var the global variable
/// @returns true on success
- bool EmitIOVariable(const sem::Variable* var);
+ bool EmitIOVariable(const sem::GlobalVariable* var);
/// Handles emitting interpolation qualifiers
/// @param out the output of the expression stream
@@ -333,9 +333,12 @@
utils::VectorRef<const ast::Attribute*> attrs);
/// Handles emitting attributes
/// @param out the output of the expression stream
+ /// @param var the global variable semantics
/// @param attrs the attributes
/// @returns true if the attributes were emitted
- bool EmitAttributes(std::ostream& out, utils::VectorRef<const ast::Attribute*> attrs);
+ bool EmitAttributes(std::ostream& out,
+ const sem::GlobalVariable* var,
+ utils::VectorRef<const ast::Attribute*> attrs);
/// Handles emitting the entry point function
/// @param func the entry point
/// @returns true if the entry point function was emitted
diff --git a/src/tint/writer/glsl/generator_impl_function_test.cc b/src/tint/writer/glsl/generator_impl_function_test.cc
index c388005..fd74e2d 100644
--- a/src/tint/writer/glsl/generator_impl_function_test.cc
+++ b/src/tint/writer/glsl/generator_impl_function_test.cc
@@ -128,7 +128,7 @@
// }
Func("frag_main",
utils::Vector{
- Param("foo", ty.f32(), utils::Vector{Location(0)}),
+ Param("foo", ty.f32(), utils::Vector{Location(0_a)}),
},
ty.f32(),
utils::Vector{
@@ -138,7 +138,7 @@
Stage(ast::PipelineStage::kFragment),
},
utils::Vector{
- Location(1),
+ Location(1_a),
});
GeneratorImpl& gen = SanitizeAndBuild();
@@ -218,8 +218,8 @@
"Interface",
utils::Vector{
Member("pos", ty.vec4<f32>(), utils::Vector{Builtin(ast::BuiltinValue::kPosition)}),
- Member("col1", ty.f32(), utils::Vector{Location(1)}),
- Member("col2", ty.f32(), utils::Vector{Location(2)}),
+ Member("col1", ty.f32(), utils::Vector{Location(1_a)}),
+ Member("col2", ty.f32(), utils::Vector{Location(2_a)}),
});
Func("vert_main", utils::Empty, ty.Of(interface_struct),
diff --git a/src/tint/writer/hlsl/generator_impl.cc b/src/tint/writer/hlsl/generator_impl.cc
index 3625db6..b05db3e 100644
--- a/src/tint/writer/hlsl/generator_impl.cc
+++ b/src/tint/writer/hlsl/generator_impl.cc
@@ -3947,23 +3947,24 @@
std::string pre, post;
if (auto* decl = mem->Declaration()) {
for (auto* attr : decl->attributes) {
- if (auto* location = attr->As<ast::LocationAttribute>()) {
+ if (attr->Is<ast::LocationAttribute>()) {
auto& pipeline_stage_uses = str->PipelineStageUses();
if (pipeline_stage_uses.size() != 1) {
TINT_ICE(Writer, diagnostics_) << "invalid entry point IO struct uses";
}
+ auto loc = mem->Location().value();
if (pipeline_stage_uses.count(sem::PipelineStageUsage::kVertexInput)) {
- post += " : TEXCOORD" + std::to_string(location->value);
+ post += " : TEXCOORD" + std::to_string(loc);
} else if (pipeline_stage_uses.count(
sem::PipelineStageUsage::kVertexOutput)) {
- post += " : TEXCOORD" + std::to_string(location->value);
+ post += " : TEXCOORD" + std::to_string(loc);
} else if (pipeline_stage_uses.count(
sem::PipelineStageUsage::kFragmentInput)) {
- post += " : TEXCOORD" + std::to_string(location->value);
+ post += " : TEXCOORD" + std::to_string(loc);
} else if (pipeline_stage_uses.count(
sem::PipelineStageUsage::kFragmentOutput)) {
- post += " : SV_Target" + std::to_string(location->value);
+ post += " : SV_Target" + std::to_string(loc);
} else {
TINT_ICE(Writer, diagnostics_) << "invalid use of location attribute";
}
diff --git a/src/tint/writer/hlsl/generator_impl_function_test.cc b/src/tint/writer/hlsl/generator_impl_function_test.cc
index 14e8a70..bcd1891 100644
--- a/src/tint/writer/hlsl/generator_impl_function_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_function_test.cc
@@ -117,7 +117,7 @@
// fn frag_main(@location(0) foo : f32) -> @location(1) f32 {
// return foo;
// }
- auto* foo_in = Param("foo", ty.f32(), utils::Vector{Location(0)});
+ auto* foo_in = Param("foo", ty.f32(), utils::Vector{Location(0_a)});
Func("frag_main", utils::Vector{foo_in}, ty.f32(),
utils::Vector{
Return("foo"),
@@ -126,7 +126,7 @@
Stage(ast::PipelineStage::kFragment),
},
utils::Vector{
- Location(1),
+ Location(1_a),
});
GeneratorImpl& gen = SanitizeAndBuild();
@@ -210,8 +210,8 @@
"Interface",
utils::Vector{
Member("pos", ty.vec4<f32>(), utils::Vector{Builtin(ast::BuiltinValue::kPosition)}),
- Member("col1", ty.f32(), utils::Vector{Location(1)}),
- Member("col2", ty.f32(), utils::Vector{Location(2)}),
+ Member("col1", ty.f32(), utils::Vector{Location(1_a)}),
+ Member("col2", ty.f32(), utils::Vector{Location(2_a)}),
});
Func("vert_main", utils::Empty, ty.Of(interface_struct),
diff --git a/src/tint/writer/msl/generator_impl.cc b/src/tint/writer/msl/generator_impl.cc
index 7617678..70bdb61 100644
--- a/src/tint/writer/msl/generator_impl.cc
+++ b/src/tint/writer/msl/generator_impl.cc
@@ -2785,24 +2785,25 @@
out << " [[" << name << "]]";
return true;
},
- [&](const ast::LocationAttribute* loc) {
+ [&](const ast::LocationAttribute*) {
auto& pipeline_stage_uses = str->PipelineStageUses();
if (pipeline_stage_uses.size() != 1) {
TINT_ICE(Writer, diagnostics_) << "invalid entry point IO struct uses";
return false;
}
+ uint32_t loc = mem->Location().value();
if (pipeline_stage_uses.count(sem::PipelineStageUsage::kVertexInput)) {
- out << " [[attribute(" + std::to_string(loc->value) + ")]]";
+ out << " [[attribute(" + std::to_string(loc) + ")]]";
} else if (pipeline_stage_uses.count(
sem::PipelineStageUsage::kVertexOutput)) {
- out << " [[user(locn" + std::to_string(loc->value) + ")]]";
+ out << " [[user(locn" + std::to_string(loc) + ")]]";
} else if (pipeline_stage_uses.count(
sem::PipelineStageUsage::kFragmentInput)) {
- out << " [[user(locn" + std::to_string(loc->value) + ")]]";
+ out << " [[user(locn" + std::to_string(loc) + ")]]";
} else if (pipeline_stage_uses.count(
sem::PipelineStageUsage::kFragmentOutput)) {
- out << " [[color(" + std::to_string(loc->value) + ")]]";
+ out << " [[color(" + std::to_string(loc) + ")]]";
} else {
TINT_ICE(Writer, diagnostics_) << "invalid use of location decoration";
return false;
diff --git a/src/tint/writer/msl/generator_impl_function_test.cc b/src/tint/writer/msl/generator_impl_function_test.cc
index fd612b3..addd255 100644
--- a/src/tint/writer/msl/generator_impl_function_test.cc
+++ b/src/tint/writer/msl/generator_impl_function_test.cc
@@ -91,7 +91,7 @@
// fn frag_main(@location(0) foo : f32) -> @location(1) f32 {
// return foo;
// }
- auto* foo_in = Param("foo", ty.f32(), utils::Vector{Location(0)});
+ auto* foo_in = Param("foo", ty.f32(), utils::Vector{Location(0_a)});
Func("frag_main", utils::Vector{foo_in}, ty.f32(),
utils::Vector{
Return("foo"),
@@ -100,7 +100,7 @@
Stage(ast::PipelineStage::kFragment),
},
utils::Vector{
- Location(1),
+ Location(1_a),
});
GeneratorImpl& gen = SanitizeAndBuild();
@@ -188,8 +188,8 @@
auto* interface_struct = Structure(
"Interface",
utils::Vector{
- Member("col1", ty.f32(), utils::Vector{Location(1)}),
- Member("col2", ty.f32(), utils::Vector{Location(2)}),
+ Member("col1", ty.f32(), utils::Vector{Location(1_a)}),
+ Member("col2", ty.f32(), utils::Vector{Location(2_a)}),
Member("pos", ty.vec4<f32>(), utils::Vector{Builtin(ast::BuiltinValue::kPosition)}),
});
diff --git a/src/tint/writer/spirv/builder.cc b/src/tint/writer/spirv/builder.cc
index 04cbaac..3ee241d 100644
--- a/src/tint/writer/spirv/builder.cc
+++ b/src/tint/writer/spirv/builder.cc
@@ -884,9 +884,9 @@
U32Operand(ConvertBuiltin(builtin->builtin, sem->StorageClass()))});
return true;
},
- [&](const ast::LocationAttribute* location) {
+ [&](const ast::LocationAttribute*) {
push_annot(spv::Op::OpDecorate, {Operand(var_id), U32Operand(SpvDecorationLocation),
- Operand(location->value)});
+ Operand(sem->Location().value())});
return true;
},
[&](const ast::InterpolateAttribute* interpolate) {
diff --git a/src/tint/writer/spirv/builder_entry_point_test.cc b/src/tint/writer/spirv/builder_entry_point_test.cc
index 424e89b..a4128c1 100644
--- a/src/tint/writer/spirv/builder_entry_point_test.cc
+++ b/src/tint/writer/spirv/builder_entry_point_test.cc
@@ -48,7 +48,7 @@
});
auto* loc1 = Param("loc1", ty.f32(),
utils::Vector{
- Location(1u),
+ Location(1_u),
});
auto* mul = Mul(Expr(MemberAccessor("coord", "x")), Expr("loc1"));
auto* col = Var("col", ty.f32(), mul);
@@ -120,7 +120,7 @@
// }
auto* loc_in = Param("loc_in", ty.u32(),
utils::Vector{
- Location(0),
+ Location(0_a),
Flat(),
});
auto* cond =
@@ -134,7 +134,7 @@
Stage(ast::PipelineStage::kFragment),
},
utils::Vector{
- Location(0),
+ Location(0_a),
});
spirv::Builder& b = SanitizeAndBuild();
@@ -211,7 +211,7 @@
auto* interface = Structure(
"Interface",
utils::Vector{
- Member("value", ty.f32(), utils::Vector{Location(1u)}),
+ Member("value", ty.f32(), utils::Vector{Location(1_u)}),
Member("pos", ty.vec4<f32>(), utils::Vector{Builtin(ast::BuiltinValue::kPosition)}),
});
diff --git a/src/tint/writer/wgsl/generator_impl.cc b/src/tint/writer/wgsl/generator_impl.cc
index bd75fb8..804d9ea 100644
--- a/src/tint/writer/wgsl/generator_impl.cc
+++ b/src/tint/writer/wgsl/generator_impl.cc
@@ -756,7 +756,11 @@
return true;
},
[&](const ast::LocationAttribute* location) {
- out << "location(" << location->value << ")";
+ out << "location(";
+ if (!EmitExpression(out, location->value)) {
+ return false;
+ }
+ out << ")";
return true;
},
[&](const ast::BuiltinAttribute* builtin) {
diff --git a/src/tint/writer/wgsl/generator_impl_function_test.cc b/src/tint/writer/wgsl/generator_impl_function_test.cc
index 3b80e69..af09a13 100644
--- a/src/tint/writer/wgsl/generator_impl_function_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_function_test.cc
@@ -116,7 +116,7 @@
});
auto* loc1 = Param("loc1", ty.f32(),
utils::Vector{
- Location(1u),
+ Location(1_a),
});
auto* func = Func("frag_main", utils::Vector{coord, loc1}, ty.void_(), utils::Empty,
utils::Vector{
@@ -143,7 +143,7 @@
Stage(ast::PipelineStage::kFragment),
},
utils::Vector{
- Location(1u),
+ Location(1_a),
});
GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/wgsl/generator_impl_type_test.cc b/src/tint/writer/wgsl/generator_impl_type_test.cc
index 5390057..ef90579 100644
--- a/src/tint/writer/wgsl/generator_impl_type_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_type_test.cc
@@ -274,7 +274,7 @@
auto* s = Structure(
"S", utils::Vector{
Member("a", ty.u32(), utils::Vector{Builtin(ast::BuiltinValue::kVertexIndex)}),
- Member("b", ty.f32(), utils::Vector{Location(2u)}),
+ Member("b", ty.f32(), utils::Vector{Location(2_a)}),
});
GeneratorImpl& gen = Build();