Compat: Make sample, linear usage info createShaderModule errors
There errors were pipeline creation errors but the spec changed
to make them shader module creation errors.
Bug: 340322894
Change-Id: I537aa5e0e10ec85a838040fba36546af57b10db6
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/193700
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: Gregg Tavares <gman@chromium.org>
diff --git a/src/dawn/native/RenderPipeline.cpp b/src/dawn/native/RenderPipeline.cpp
index c94db8b..cd1441b 100644
--- a/src/dawn/native/RenderPipeline.cpp
+++ b/src/dawn/native/RenderPipeline.cpp
@@ -797,18 +797,6 @@
"different from the interpolation sampling (%s) of the fragment input at "
"location %u.",
vertexOutputInfo.interpolationSampling, i, fragmentInputInfo.interpolationSampling, i);
-
- DAWN_INVALID_IF(device->IsCompatibilityMode() &&
- vertexOutputInfo.interpolationType == InterpolationType::Linear,
- "The interpolation type (%s) of the vertex output at location %u is not "
- "supported in compatibility mode",
- vertexOutputInfo.interpolationType, i);
-
- DAWN_INVALID_IF(device->IsCompatibilityMode() &&
- vertexOutputInfo.interpolationSampling == InterpolationSampling::Sample,
- "The interpolation sampling (%s) of the vertex output at location %u is "
- "not supported in compatibility mode",
- vertexOutputInfo.interpolationSampling, i);
}
return {};
diff --git a/src/dawn/tests/unittests/validation/CompatValidationTests.cpp b/src/dawn/tests/unittests/validation/CompatValidationTests.cpp
index 3313b26..fec272f 100644
--- a/src/dawn/tests/unittests/validation/CompatValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/CompatValidationTests.cpp
@@ -235,6 +235,7 @@
TEST_F(CompatValidationTest, CanNotUseShaderWithUnsupportedInterpolateTypeOrSampling) {
static const char* interpolateParams[] = {
+ "perspective", // should pass
"linear",
"perspective, sample",
};
@@ -250,43 +251,15 @@
v.color = vec4f(1);
return v;
}
- @fragment fn fsWithoutBadInterpolationUsage() -> @location(0) vec4f {
- return vec4f(1);
- }
- @fragment fn fsWithBadInterpolationUsage1(v: Vertex) -> @location(0) vec4f {
- return vec4f(1);
- }
- @fragment fn fsWithBadInterpolationUsage2(v: Vertex) -> @location(0) vec4f {
- return v.pos;
- }
- @fragment fn fsWithBadInterpolationUsage3(v: Vertex) -> @location(0) vec4f {
- return v.color;
- }
)",
interpolateParam);
- wgpu::ShaderModule moduleInterpolationLinear =
- utils::CreateShaderModule(device, wgsl.c_str());
-
- static const char* entryPoints[] = {
- "fsWithoutBadInterpolationUsage",
- "fsWithBadInterpolationUsage1",
- "fsWithBadInterpolationUsage2",
- "fsWithBadInterpolationUsage3",
- };
- for (auto entryPoint : entryPoints) {
- utils::ComboRenderPipelineDescriptor descriptor;
- descriptor.vertex.module = moduleInterpolationLinear;
- descriptor.cFragment.module = moduleInterpolationLinear;
- descriptor.cFragment.entryPoint = entryPoint;
-
- bool shouldSucceed = entryPoint == entryPoints[0];
-
- if (shouldSucceed) {
- device.CreateRenderPipeline(&descriptor);
- } else {
- ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor),
- testing::HasSubstr("in compatibility mode"));
- }
+ if (strcmp(interpolateParam, "perspective") == 0) {
+ wgpu::ShaderModule moduleInterpolationLinear =
+ utils::CreateShaderModule(device, wgsl.c_str());
+ } else {
+ ASSERT_DEVICE_ERROR(wgpu::ShaderModule moduleInterpolationLinear =
+ utils::CreateShaderModule(device, wgsl.c_str()),
+ testing::HasSubstr("in compatibility mode"));
}
}
}
diff --git a/src/tint/lang/wgsl/resolver/compatibility_mode_test.cc b/src/tint/lang/wgsl/resolver/compatibility_mode_test.cc
index 49b96a6..758fa8d 100644
--- a/src/tint/lang/wgsl/resolver/compatibility_mode_test.cc
+++ b/src/tint/lang/wgsl/resolver/compatibility_mode_test.cc
@@ -179,5 +179,96 @@
R"(12:34 error: use of '@builtin(sample_index)' is not allowed in compatibility mode)");
}
+TEST_F(ResolverCompatibilityModeTest, LinearInterpolation_Parameter) {
+ // @fragment
+ // fn main(@location(1) @interpolate(linear) value : f32) {
+ // }
+
+ Func("main",
+ Vector{Param("value", ty.f32(),
+ Vector{
+ Location(1_i),
+ Interpolate(Source{{12, 34}}, core::InterpolationType::kLinear,
+ core::InterpolationSampling::kCenter),
+ })},
+ ty.void_(), Empty,
+ Vector{
+ Stage(ast::PipelineStage::kFragment),
+ },
+ Vector{
+ Builtin(core::BuiltinValue::kPosition),
+ });
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ R"(12:34 error: use of '@interpolate(linear)' is not allowed in compatibility mode)");
+}
+
+TEST_F(ResolverCompatibilityModeTest, LinearInterpolation_StructMember) {
+ // struct S {
+ // @location(1) @interpolate(linear) value : f32,
+ // }
+
+ Structure("S", Vector{
+ Member("value", ty.f32(),
+ Vector{
+ Location(1_i),
+ Interpolate(Source{{12, 34}}, core::InterpolationType::kLinear,
+ core::InterpolationSampling::kCenter),
+ }),
+ });
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ R"(12:34 error: use of '@interpolate(linear)' is not allowed in compatibility mode)");
+}
+
+TEST_F(ResolverCompatibilityModeTest, SampleInterpolation_Parameter) {
+ // @fragment
+ // fn main(@location(1) @interpolate(perspective, sample) value : f32) {
+ // }
+
+ Func("main",
+ Vector{Param("value", ty.f32(),
+ Vector{
+ Location(1_i),
+ Interpolate(Source{{12, 34}}, core::InterpolationType::kPerspective,
+ core::InterpolationSampling::kSample),
+ })},
+ ty.void_(), Empty,
+ Vector{
+ Stage(ast::PipelineStage::kFragment),
+ },
+ Vector{
+ Builtin(core::BuiltinValue::kPosition),
+ });
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: use of '@interpolate(..., sample)' is not allowed in compatibility mode)");
+}
+
+TEST_F(ResolverCompatibilityModeTest, SampleInterpolation_StructMember) {
+ // struct S {
+ // @location(1) @interpolate(perspective, sample) value : f32,
+ // }
+
+ Structure("S",
+ Vector{
+ Member("value", ty.f32(),
+ Vector{
+ Location(1_i),
+ Interpolate(Source{{12, 34}}, core::InterpolationType::kPerspective,
+ core::InterpolationSampling::kSample),
+ }),
+ });
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: use of '@interpolate(..., sample)' is not allowed in compatibility mode)");
+}
+
} // namespace
} // namespace tint::resolver
diff --git a/src/tint/lang/wgsl/resolver/validator.cc b/src/tint/lang/wgsl/resolver/validator.cc
index 2f9951d..a19c181 100644
--- a/src/tint/lang/wgsl/resolver/validator.cc
+++ b/src/tint/lang/wgsl/resolver/validator.cc
@@ -1120,6 +1120,22 @@
return false;
}
+ if (mode_ == wgsl::ValidationMode::kCompat) {
+ if (i_type->Value() == core::InterpolationType::kLinear) {
+ AddError(attr->source)
+ << "use of '@interpolate(linear)' is not allowed in compatibility mode";
+ return false;
+ }
+
+ if (attr->sampling) {
+ auto s_type = sem_.AsInterpolationSampling(sem_.Get(attr->sampling));
+ if (s_type->Value() == core::InterpolationSampling::kSample) {
+ AddError(attr->source)
+ << "use of '@interpolate(..., sample)' is not allowed in compatibility mode";
+ return false;
+ }
+ }
+ }
return true;
}