[spirv-reader][ir] Better gl_PerVertex handling.
In the case where we've skipped emitting certain variables to the
gl_PerVertex structure, we need to fail on any use of the structure
which is not an `access` as all the members may not be present.
Bug: 42250952
Change-Id: I33e678f680e14f64f4d54da375feccd9ea769977
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/222014
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/spirv/reader/lower/shader_io.cc b/src/tint/lang/spirv/reader/lower/shader_io.cc
index ddff8a4..4e64e64 100644
--- a/src/tint/lang/spirv/reader/lower/shader_io.cc
+++ b/src/tint/lang/spirv/reader/lower/shader_io.cc
@@ -196,9 +196,12 @@
auto var_attributes = var->Attributes();
auto var_type = var->Result(0)->Type()->UnwrapPtr();
if (auto* str = var_type->As<core::type::Struct>()) {
+ bool skipped_member_emission = false;
+
// Add an output for each member of the struct.
for (auto* member : str->Members()) {
if (ShouldSkipMemberEmission(var, member)) {
+ skipped_member_emission = true;
continue;
}
@@ -221,6 +224,15 @@
results.Push(b.Load(access)->Result(0));
});
}
+
+ // If we skipped emission of any member, then we need to make sure the var is only
+ // used through `access` instructions, otherwise the members may no longer match due
+ // to the skipping.
+ if (skipped_member_emission) {
+ for (auto& usage : var->Result(0)->UsagesUnsorted()) {
+ TINT_ASSERT(usage->instruction->Is<core::ir::Access>());
+ }
+ }
} else {
// Load the final result from the original variable.
b.Append(wrapper->Block(), [&] {
@@ -305,9 +317,7 @@
if (!chain) {
continue;
}
- if (chain->Indices().IsEmpty()) {
- continue;
- }
+ TINT_ASSERT(chain->Indices().Length() >= 1);
// A member access has to be a constant index
auto* cnst = chain->Indices()[0]->As<core::ir::Constant>();