tint/writer: Handle and emit 'const' variables
Bug: tint:1580
Change-Id: Ib3a5ff5c567e19eca1ba8fb3c2f7e83dee68e2a0
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/94686
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
diff --git a/src/tint/writer/hlsl/generator_impl.cc b/src/tint/writer/hlsl/generator_impl.cc
index 8139e6b..bd58e30 100644
--- a/src/tint/writer/hlsl/generator_impl.cc
+++ b/src/tint/writer/hlsl/generator_impl.cc
@@ -2617,12 +2617,7 @@
// TODO(crbug.com/tint/1580): Once 'const' is implemented, 'let' will no longer resolve
// to a shader-creation time constant value, and this can be removed.
if (auto constant = sem->ConstantValue()) {
- // We do not want to inline array constants, as this will undo the work of
- // PromoteInitializersToLet, which ensures that arrays are declarated in 'let's
- // before their usage.
- if (!constant.Type()->Is<sem::Array>()) {
- return EmitConstant(out, constant);
- }
+ return EmitConstant(out, constant);
}
}
}
@@ -2856,6 +2851,9 @@
},
[&](const ast::Let* let) { return EmitProgramConstVariable(let); },
[&](const ast::Override* override) { return EmitOverride(override); },
+ [&](const ast::Const*) {
+ return true; // Constants are embedded at their use
+ },
[&](Default) {
TINT_ICE(Writer, diagnostics_)
<< "unhandled global variable type " << global->TypeInfo().name;
@@ -3174,8 +3172,7 @@
return true;
},
[&](const sem::Matrix* m) {
- if (!EmitType(out, constant.Type(), ast::StorageClass::kNone, ast::Access::kUndefined,
- "")) {
+ if (!EmitType(out, m, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
return false;
}
@@ -3193,6 +3190,34 @@
}
return true;
},
+ [&](const sem::Array* a) {
+ if (constant.AllZero(start, end)) {
+ out << "(";
+ if (!EmitType(out, a, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
+ return false;
+ }
+ out << ")0";
+ return true;
+ }
+
+ out << "{";
+ TINT_DEFER(out << "}");
+
+ auto* el_ty = a->ElemType();
+
+ uint32_t step = 0;
+ sem::Type::DeepestElementOf(el_ty, &step);
+ for (size_t i = start; i < end; i += step) {
+ if (i > start) {
+ out << ", ";
+ }
+ if (!EmitConstantRange(out, constant, el_ty, i, i + step)) {
+ return false;
+ }
+ }
+
+ return true;
+ },
[&](Default) {
diagnostics_.add_error(
diag::System::Writer,
@@ -3571,6 +3596,9 @@
v->variable, //
[&](const ast::Var* var) { return EmitVar(var); },
[&](const ast::Let* let) { return EmitLet(let); },
+ [&](const ast::Const*) {
+ return true; // Constants are embedded at their use
+ },
[&](Default) { //
TINT_ICE(Writer, diagnostics_)
<< "unknown variable type: " << v->variable->TypeInfo().name;