Disallow Multiple Render Targets When Using Dual Source Blending
Because multiple backends do not allow multiple render targets when
using dual source blending, disallow usage of any non-zero render target
outputs when dual source blending is in use.
Bug: dawn:1709
Change-Id: I1430797df9e887298c251a405e0e2defc9f43508
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/146020
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/lang/wgsl/resolver/dual_source_blending_extension_test.cc b/src/tint/lang/wgsl/resolver/dual_source_blending_extension_test.cc
index 7c88185..54d9649 100644
--- a/src/tint/lang/wgsl/resolver/dual_source_blending_extension_test.cc
+++ b/src/tint/lang/wgsl/resolver/dual_source_blending_extension_test.cc
@@ -143,5 +143,33 @@
EXPECT_EQ(r()->error(), "12:34 error: index attribute must only be used with @location(0)");
}
+class DualSourceBlendingExtensionTestWithParams : public ResolverTestWithParam<int> {
+ public:
+ DualSourceBlendingExtensionTestWithParams() {
+ Enable(core::Extension::kChromiumInternalDualSourceBlending);
+ }
+};
+
+// Rendering to multiple render targets while using dual source blending should fail.
+TEST_P(DualSourceBlendingExtensionTestWithParams, MultipleRenderTargetsNotAllowed) {
+ Structure("Output",
+ Vector{
+ Member("a", ty.vec4<f32>(), Vector{Location(0_a), Index(0_a)}),
+ Member("b", ty.vec4<f32>(), Vector{Location(0_a), Index(1_a)}),
+ Member("c", ty.vec4<f32>(), Vector{Location(Source{{12, 34}}, AInt(GetParam()))}),
+ });
+
+ EXPECT_FALSE(r()->Resolve());
+ StringStream err;
+ err << "12:34 error: Multiple render targets are not allowed when using dual source blending. "
+ "The output @location("
+ << GetParam() << ") is not allowed as a render target.";
+ EXPECT_EQ(r()->error(), err.str());
+}
+
+INSTANTIATE_TEST_SUITE_P(DualSourceBlendingExtensionTests,
+ DualSourceBlendingExtensionTestWithParams,
+ testing::Values(1, 2, 3, 4, 5, 6, 7));
+
} // namespace
} // namespace tint::resolver
diff --git a/src/tint/lang/wgsl/resolver/validator.cc b/src/tint/lang/wgsl/resolver/validator.cc
index 5e39cad..ab50d71 100644
--- a/src/tint/lang/wgsl/resolver/validator.cc
+++ b/src/tint/lang/wgsl/resolver/validator.cc
@@ -2125,6 +2125,7 @@
return false;
}
+ auto has_index = false;
Hashset<std::pair<uint32_t, uint32_t>, 8> locationsAndIndexes;
for (auto* member : str->Members()) {
if (auto* r = member->Type()->As<core::type::Array>()) {
@@ -2170,6 +2171,7 @@
},
[&](const ast::IndexAttribute* index) {
index_attribute = index;
+ has_index = true;
return IndexAttribute(index, stage);
},
[&](const ast::BuiltinAttribute* builtin_attr) {
@@ -2242,6 +2244,15 @@
index = member->Attributes().index.value();
}
uint32_t location = member->Attributes().location.value();
+ if (has_index && location != 0) {
+ StringStream err;
+ err << "Multiple render targets are not allowed when using dual source blending. "
+ "The output @location("
+ << location << ") is not allowed as a render target.";
+ AddError(err.str(), location_attribute->source);
+ return false;
+ }
+
std::pair<uint32_t, uint32_t> locationAndIndex(location, index);
if (!locationsAndIndexes.Add(locationAndIndex)) {
StringStream err;