spirv-reader: Add interpolate(flat) to integral pipeline IO
This is now required in WGSL, and will soon become an error in Tint.
Bug: tint:1224
Change-Id: Ide98c4c0b7aac86a2b43f7e02abde3d8a297dce4
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/68920
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: David Neto <dneto@google.com>
Commit-Queue: James Price <jrprice@google.com>
diff --git a/src/reader/spirv/parser_impl.cc b/src/reader/spirv/parser_impl.cc
index 0ace622..15fed61 100644
--- a/src/reader/spirv/parser_impl.cc
+++ b/src/reader/spirv/parser_impl.cc
@@ -1777,9 +1777,9 @@
bool ParserImpl::ConvertPipelineDecorations(const Type* store_type,
const DecorationList& decorations,
ast::DecorationList* ast_decos) {
- bool has_interpolate_no_perspective = false;
- bool has_interpolate_sampling_centroid = false;
- bool has_interpolate_sampling_sample = false;
+ // Vulkan defaults to perspective-correct interpolation.
+ ast::InterpolationType type = ast::InterpolationType::kPerspective;
+ ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone;
for (const auto& deco : decorations) {
TINT_ASSERT(Reader, deco.size() > 0);
@@ -1793,22 +1793,14 @@
create<ast::LocationDecoration>(Source{}, deco[1]));
break;
case SpvDecorationFlat:
- // In WGSL, integral types are always flat, and so the decoration
- // is never specified.
- if (!store_type->IsIntegerScalarOrVector()) {
- ast_decos->emplace_back(create<ast::InterpolateDecoration>(
- Source{}, ast::InterpolationType::kFlat,
- ast::InterpolationSampling::kNone));
- // Only one interpolate attribute is allowed.
- return true;
- }
+ type = ast::InterpolationType::kFlat;
break;
case SpvDecorationNoPerspective:
if (store_type->IsIntegerScalarOrVector()) {
// This doesn't capture the array or struct case.
return Fail() << "NoPerspective is invalid on integral IO";
}
- has_interpolate_no_perspective = true;
+ type = ast::InterpolationType::kLinear;
break;
case SpvDecorationCentroid:
if (store_type->IsIntegerScalarOrVector()) {
@@ -1816,7 +1808,7 @@
return Fail()
<< "Centroid interpolation sampling is invalid on integral IO";
}
- has_interpolate_sampling_centroid = true;
+ sampling = ast::InterpolationSampling::kCentroid;
break;
case SpvDecorationSample:
if (store_type->IsIntegerScalarOrVector()) {
@@ -1824,33 +1816,19 @@
return Fail()
<< "Sample interpolation sampling is invalid on integral IO";
}
- has_interpolate_sampling_sample = true;
+ sampling = ast::InterpolationSampling::kSample;
break;
default:
break;
}
}
- // Apply non-integral interpolation.
- if (has_interpolate_no_perspective || has_interpolate_sampling_centroid ||
- has_interpolate_sampling_sample) {
- const ast::InterpolationType type =
- has_interpolate_no_perspective ? ast::InterpolationType::kLinear
- : ast::InterpolationType::kPerspective;
- const ast::InterpolationSampling sampling =
- has_interpolate_sampling_centroid
- ? ast::InterpolationSampling::kCentroid
- : (has_interpolate_sampling_sample
- ? ast::InterpolationSampling::kSample
- : ast::InterpolationSampling::
- kNone /* Center is the default */);
- if (type == ast::InterpolationType::kPerspective &&
- sampling == ast::InterpolationSampling::kNone) {
- // This is the default. Don't add a decoration.
- } else {
- ast_decos->emplace_back(
- create<ast::InterpolateDecoration>(type, sampling));
- }
+ // Apply interpolation.
+ if (type == ast::InterpolationType::kPerspective &&
+ sampling == ast::InterpolationSampling::kNone) {
+ // This is the default. Don't add a decoration.
+ } else {
+ ast_decos->emplace_back(create<ast::InterpolateDecoration>(type, sampling));
}
return success();
diff --git a/src/reader/spirv/parser_impl_module_var_test.cc b/src/reader/spirv/parser_impl_module_var_test.cc
index 27bca8b..9d12fcd 100644
--- a/src/reader/spirv/parser_impl_module_var_test.cc
+++ b/src/reader/spirv/parser_impl_module_var_test.cc
@@ -4813,7 +4813,7 @@
};
[[stage(vertex)]]
-fn main([[location(1)]] x_1_param : u32, [[location(2)]] x_2_param : vec2<u32>, [[location(3)]] x_3_param : i32, [[location(4)]] x_4_param : vec2<i32>, [[location(5), interpolate(flat)]] x_5_param : f32, [[location(6), interpolate(flat)]] x_6_param : vec2<f32>) -> main_out {
+fn main([[location(1), interpolate(flat)]] x_1_param : u32, [[location(2), interpolate(flat)]] x_2_param : vec2<u32>, [[location(3), interpolate(flat)]] x_3_param : i32, [[location(4), interpolate(flat)]] x_4_param : vec2<i32>, [[location(5), interpolate(flat)]] x_5_param : f32, [[location(6), interpolate(flat)]] x_6_param : vec2<f32>) -> main_out {
x_1 = x_1_param;
x_2 = x_2_param;
x_3 = x_3_param;
@@ -4893,13 +4893,13 @@
}
struct main_out {
- [[location(1)]]
+ [[location(1), interpolate(flat)]]
x_1_1 : u32;
- [[location(2)]]
+ [[location(2), interpolate(flat)]]
x_2_1 : vec2<u32>;
- [[location(3)]]
+ [[location(3), interpolate(flat)]]
x_3_1 : i32;
- [[location(4)]]
+ [[location(4), interpolate(flat)]]
x_4_1 : vec2<i32>;
[[location(5), interpolate(flat)]]
x_5_1 : f32;