[spirv-reader][ir] Fixup interpolation values.
When coming from SPIR-V all fragment sharder integer inputs are
decorated as `flat`. We need to strip these off when coming to WGSL if
they don't have a `location` attached as well.
The default value of `perspective,center` is stripped off as well.
Bug: 42250952
Change-Id: Ie817fe59329dcd45f2bb893322d44e8232aebee5
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/246334
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/lang/spirv/reader/parser/parser.cc b/src/tint/lang/spirv/reader/parser/parser.cc
index 45482cf..b79b4f9 100644
--- a/src/tint/lang/spirv/reader/parser/parser.cc
+++ b/src/tint/lang/spirv/reader/parser/parser.cc
@@ -3293,7 +3293,9 @@
// Create the interpolation field with the default values on first call.
if (!io_attributes.interpolation.has_value()) {
io_attributes.interpolation = core::Interpolation{
- core::InterpolationType::kPerspective, core::InterpolationSampling::kCenter};
+ .type = core::InterpolationType::kPerspective,
+ .sampling = core::InterpolationSampling::kCenter,
+ };
}
return io_attributes.interpolation.value();
};
@@ -3342,6 +3344,22 @@
}
}
+ if (io_attributes.interpolation.has_value()) {
+ // WGSL requires that '@interpolate(flat)' needs to be paired with '@location', however
+ // SPIR-V requires all fragment shader integer Inputs are 'flat'. If the decorations do
+ // not contain a spv::Decoration::Location, then remove the interpolation decoration.
+ //
+ // The `perspective,center` interpolation is the default value if one isn't provided.
+ // Just strip it off. This keeps us from accidentally applying interpolation where it
+ // isn't permitted, and it isn't necessary.
+ if ((io_attributes.interpolation->type == core::InterpolationType::kFlat &&
+ !io_attributes.location.has_value()) ||
+ (io_attributes.interpolation->type == core::InterpolationType::kPerspective &&
+ io_attributes.interpolation->sampling == core::InterpolationSampling::kCenter)) {
+ io_attributes.interpolation = std::nullopt;
+ }
+ }
+
auto* element_ty = Type(inst.type_id(), access_mode)->As<core::type::Pointer>();
auto* var = b_.Var(element_ty);
if (inst.NumOperands() > 3) {
diff --git a/src/tint/lang/spirv/reader/parser/var_test.cc b/src/tint/lang/spirv/reader/parser/var_test.cc
index d1e845c..a45acb2 100644
--- a/src/tint/lang/spirv/reader/parser/var_test.cc
+++ b/src/tint/lang/spirv/reader/parser/var_test.cc
@@ -1328,5 +1328,41 @@
)");
}
+TEST_F(SpirvParserTest, InterpolationFlatNoLocation) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpCapability SampleRateShading
+ OpMemoryModel Logical Simple
+ OpEntryPoint Fragment %3 "main" %gl_SampleID
+ OpExecutionMode %3 OriginUpperLeft
+ OpDecorate %gl_SampleID BuiltIn SampleId
+ OpDecorate %gl_SampleID Flat
+ %void = OpTypeVoid
+ %5 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+%_ptr_Input_uint = OpTypePointer Input %uint
+%gl_SampleID = OpVariable %_ptr_Input_uint Input
+ %3 = OpFunction %void None %5
+ %10 = OpLabel
+ %2 = OpLoad %uint %gl_SampleID
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+$B1: { # root
+ %1:ptr<__in, u32, read> = var undef @builtin(sample_index)
+}
+
+%main = @fragment func():void {
+ $B2: {
+ %3:u32 = load %1
+ ret
+ }
+}
+)");
+}
+
} // namespace
} // namespace tint::spirv::reader