writer/spirv: Implement interpolate attributes
Add the SampleRateShading capability if the sampling type is `sample`.
Bug: tint:746
Change-Id: I20fb25913f5c0919b6d16a9d0e9fc8b1551ff7ea
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/56247
Kokoro: Kokoro <noreply+kokoro@google.com>
Auto-Submit: James Price <jrprice@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc
index 4af004a..1c2b34e 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -842,6 +842,8 @@
push_annot(spv::Op::OpDecorate,
{Operand::Int(var_id), Operand::Int(SpvDecorationLocation),
Operand::Int(location->value())});
+ } else if (auto* interpolate = deco->As<ast::InterpolateDecoration>()) {
+ AddInterpolationDecorations(var_id, interpolate);
} else if (auto* binding = deco->As<ast::BindingDecoration>()) {
push_annot(spv::Op::OpDecorate,
{Operand::Int(var_id), Operand::Int(SpvDecorationBinding),
@@ -3986,6 +3988,37 @@
return SpvBuiltInMax;
}
+void Builder::AddInterpolationDecorations(
+ uint32_t id,
+ ast::InterpolateDecoration* interpolate) {
+ switch (interpolate->type()) {
+ case ast::InterpolationType::kLinear:
+ push_annot(spv::Op::OpDecorate,
+ {Operand::Int(id), Operand::Int(SpvDecorationNoPerspective)});
+ break;
+ case ast::InterpolationType::kFlat:
+ push_annot(spv::Op::OpDecorate,
+ {Operand::Int(id), Operand::Int(SpvDecorationFlat)});
+ break;
+ case ast::InterpolationType::kPerspective:
+ break;
+ }
+ switch (interpolate->sampling()) {
+ case ast::InterpolationSampling::kCentroid:
+ push_annot(spv::Op::OpDecorate,
+ {Operand::Int(id), Operand::Int(SpvDecorationCentroid)});
+ break;
+ case ast::InterpolationSampling::kSample:
+ push_capability(SpvCapabilitySampleRateShading);
+ push_annot(spv::Op::OpDecorate,
+ {Operand::Int(id), Operand::Int(SpvDecorationSample)});
+ break;
+ case ast::InterpolationSampling::kCenter:
+ case ast::InterpolationSampling::kNone:
+ break;
+ }
+}
+
SpvImageFormat Builder::convert_image_format_to_spv(
const ast::ImageFormat format) {
switch (format) {
diff --git a/src/writer/spirv/builder.h b/src/writer/spirv/builder.h
index 7c9a6ac..ee1e306 100644
--- a/src/writer/spirv/builder.h
+++ b/src/writer/spirv/builder.h
@@ -27,6 +27,7 @@
#include "src/ast/continue_statement.h"
#include "src/ast/discard_statement.h"
#include "src/ast/if_statement.h"
+#include "src/ast/interpolate_decoration.h"
#include "src/ast/loop_statement.h"
#include "src/ast/return_statement.h"
#include "src/ast/switch_statement.h"
@@ -208,6 +209,13 @@
/// @returns the SPIR-V builtin or SpvBuiltInMax on error.
SpvBuiltIn ConvertBuiltin(ast::Builtin builtin, ast::StorageClass storage);
+ /// Converts an interpolate attribute to SPIR-V decorations and pushes a
+ /// capability if needed.
+ /// @param id the id to decorate
+ /// @param interpolate the interpolation attribute to convert
+ void AddInterpolationDecorations(uint32_t id,
+ ast::InterpolateDecoration* interpolate);
+
/// Generates a label for the given id. Emits an error and returns false if
/// we're currently outside a function.
/// @param id the id to use for the label
diff --git a/test/shader_io/interpolate_input_parameters.wgsl.expected.spvasm b/test/shader_io/interpolate_input_parameters.wgsl.expected.spvasm
index ca6d27f..5b0348f 100644
--- a/test/shader_io/interpolate_input_parameters.wgsl.expected.spvasm
+++ b/test/shader_io/interpolate_input_parameters.wgsl.expected.spvasm
@@ -1,24 +1,51 @@
-SKIP: FAILED
-
-
-[[location(0), internal(disable_validation__ignore_storage_class)]] var<in> tint_symbol : f32;
-
-[[location(1), interpolate(flat), internal(disable_validation__ignore_storage_class)]] var<in> tint_symbol_1 : f32;
-
-[[location(2), interpolate(perspective, center), internal(disable_validation__ignore_storage_class)]] var<in> tint_symbol_2 : f32;
-
-[[location(3), interpolate(perspective, centroid), internal(disable_validation__ignore_storage_class)]] var<in> tint_symbol_3 : f32;
-
-[[location(4), interpolate(perspective, sample), internal(disable_validation__ignore_storage_class)]] var<in> tint_symbol_4 : f32;
-
-[[location(5), interpolate(linear, center), internal(disable_validation__ignore_storage_class)]] var<in> tint_symbol_5 : f32;
-
-[[location(6), interpolate(linear, centroid), internal(disable_validation__ignore_storage_class)]] var<in> tint_symbol_6 : f32;
-
-[[location(7), interpolate(linear, sample), internal(disable_validation__ignore_storage_class)]] var<in> tint_symbol_7 : f32;
-
-[[stage(fragment)]]
-fn main() {
-}
-
-Failed to generate: unknown decoration
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 15
+; Schema: 0
+ OpCapability Shader
+ OpCapability SampleRateShading
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main"
+ OpExecutionMode %main OriginUpperLeft
+ OpName %tint_symbol "tint_symbol"
+ OpName %tint_symbol_1 "tint_symbol_1"
+ OpName %tint_symbol_2 "tint_symbol_2"
+ OpName %tint_symbol_3 "tint_symbol_3"
+ OpName %tint_symbol_4 "tint_symbol_4"
+ OpName %tint_symbol_5 "tint_symbol_5"
+ OpName %tint_symbol_6 "tint_symbol_6"
+ OpName %tint_symbol_7 "tint_symbol_7"
+ OpName %main "main"
+ OpDecorate %tint_symbol Location 0
+ OpDecorate %tint_symbol_1 Location 1
+ OpDecorate %tint_symbol_1 Flat
+ OpDecorate %tint_symbol_2 Location 2
+ OpDecorate %tint_symbol_3 Location 3
+ OpDecorate %tint_symbol_3 Centroid
+ OpDecorate %tint_symbol_4 Location 4
+ OpDecorate %tint_symbol_4 Sample
+ OpDecorate %tint_symbol_5 Location 5
+ OpDecorate %tint_symbol_5 NoPerspective
+ OpDecorate %tint_symbol_6 Location 6
+ OpDecorate %tint_symbol_6 NoPerspective
+ OpDecorate %tint_symbol_6 Centroid
+ OpDecorate %tint_symbol_7 Location 7
+ OpDecorate %tint_symbol_7 NoPerspective
+ OpDecorate %tint_symbol_7 Sample
+ %float = OpTypeFloat 32
+%_ptr_Input_float = OpTypePointer Input %float
+%tint_symbol = OpVariable %_ptr_Input_float Input
+%tint_symbol_1 = OpVariable %_ptr_Input_float Input
+%tint_symbol_2 = OpVariable %_ptr_Input_float Input
+%tint_symbol_3 = OpVariable %_ptr_Input_float Input
+%tint_symbol_4 = OpVariable %_ptr_Input_float Input
+%tint_symbol_5 = OpVariable %_ptr_Input_float Input
+%tint_symbol_6 = OpVariable %_ptr_Input_float Input
+%tint_symbol_7 = OpVariable %_ptr_Input_float Input
+ %void = OpTypeVoid
+ %11 = OpTypeFunction %void
+ %main = OpFunction %void None %11
+ %14 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/shader_io/interpolate_input_struct.wgsl.expected.spvasm b/test/shader_io/interpolate_input_struct.wgsl.expected.spvasm
index 619801a..5b0348f 100644
--- a/test/shader_io/interpolate_input_struct.wgsl.expected.spvasm
+++ b/test/shader_io/interpolate_input_struct.wgsl.expected.spvasm
@@ -1,35 +1,51 @@
-SKIP: FAILED
-
-
-struct In {
- none : f32;
- flat : f32;
- perspective_center : f32;
- perspective_centroid : f32;
- perspective_sample : f32;
- linear_center : f32;
- linear_centroid : f32;
- linear_sample : f32;
-};
-
-[[location(0), internal(disable_validation__ignore_storage_class)]] var<in> tint_symbol : f32;
-
-[[location(1), interpolate(flat), internal(disable_validation__ignore_storage_class)]] var<in> tint_symbol_1 : f32;
-
-[[location(2), interpolate(perspective, center), internal(disable_validation__ignore_storage_class)]] var<in> tint_symbol_2 : f32;
-
-[[location(3), interpolate(perspective, centroid), internal(disable_validation__ignore_storage_class)]] var<in> tint_symbol_3 : f32;
-
-[[location(4), interpolate(perspective, sample), internal(disable_validation__ignore_storage_class)]] var<in> tint_symbol_4 : f32;
-
-[[location(5), interpolate(linear, center), internal(disable_validation__ignore_storage_class)]] var<in> tint_symbol_5 : f32;
-
-[[location(6), interpolate(linear, centroid), internal(disable_validation__ignore_storage_class)]] var<in> tint_symbol_6 : f32;
-
-[[location(7), interpolate(linear, sample), internal(disable_validation__ignore_storage_class)]] var<in> tint_symbol_7 : f32;
-
-[[stage(fragment)]]
-fn main() {
-}
-
-Failed to generate: unknown decoration
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 15
+; Schema: 0
+ OpCapability Shader
+ OpCapability SampleRateShading
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main"
+ OpExecutionMode %main OriginUpperLeft
+ OpName %tint_symbol "tint_symbol"
+ OpName %tint_symbol_1 "tint_symbol_1"
+ OpName %tint_symbol_2 "tint_symbol_2"
+ OpName %tint_symbol_3 "tint_symbol_3"
+ OpName %tint_symbol_4 "tint_symbol_4"
+ OpName %tint_symbol_5 "tint_symbol_5"
+ OpName %tint_symbol_6 "tint_symbol_6"
+ OpName %tint_symbol_7 "tint_symbol_7"
+ OpName %main "main"
+ OpDecorate %tint_symbol Location 0
+ OpDecorate %tint_symbol_1 Location 1
+ OpDecorate %tint_symbol_1 Flat
+ OpDecorate %tint_symbol_2 Location 2
+ OpDecorate %tint_symbol_3 Location 3
+ OpDecorate %tint_symbol_3 Centroid
+ OpDecorate %tint_symbol_4 Location 4
+ OpDecorate %tint_symbol_4 Sample
+ OpDecorate %tint_symbol_5 Location 5
+ OpDecorate %tint_symbol_5 NoPerspective
+ OpDecorate %tint_symbol_6 Location 6
+ OpDecorate %tint_symbol_6 NoPerspective
+ OpDecorate %tint_symbol_6 Centroid
+ OpDecorate %tint_symbol_7 Location 7
+ OpDecorate %tint_symbol_7 NoPerspective
+ OpDecorate %tint_symbol_7 Sample
+ %float = OpTypeFloat 32
+%_ptr_Input_float = OpTypePointer Input %float
+%tint_symbol = OpVariable %_ptr_Input_float Input
+%tint_symbol_1 = OpVariable %_ptr_Input_float Input
+%tint_symbol_2 = OpVariable %_ptr_Input_float Input
+%tint_symbol_3 = OpVariable %_ptr_Input_float Input
+%tint_symbol_4 = OpVariable %_ptr_Input_float Input
+%tint_symbol_5 = OpVariable %_ptr_Input_float Input
+%tint_symbol_6 = OpVariable %_ptr_Input_float Input
+%tint_symbol_7 = OpVariable %_ptr_Input_float Input
+ %void = OpTypeVoid
+ %11 = OpTypeFunction %void
+ %main = OpFunction %void None %11
+ %14 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/shader_io/interpolate_return_struct.wgsl.expected.spvasm b/test/shader_io/interpolate_return_struct.wgsl.expected.spvasm
index fb6b3c6..ccf9580 100644
--- a/test/shader_io/interpolate_return_struct.wgsl.expected.spvasm
+++ b/test/shader_io/interpolate_return_struct.wgsl.expected.spvasm
@@ -1,55 +1,110 @@
-SKIP: FAILED
-
-
-[[builtin(pointsize), internal(disable_validation__ignore_storage_class)]] var<out> tint_pointsize : f32;
-
-struct Out {
- pos : vec4<f32>;
- none : f32;
- flat : f32;
- perspective_center : f32;
- perspective_centroid : f32;
- perspective_sample : f32;
- linear_center : f32;
- linear_centroid : f32;
- linear_sample : f32;
-};
-
-[[builtin(position), internal(disable_validation__ignore_storage_class)]] var<out> tint_symbol_1 : vec4<f32>;
-
-[[location(0), internal(disable_validation__ignore_storage_class)]] var<out> tint_symbol_2 : f32;
-
-[[location(1), interpolate(flat), internal(disable_validation__ignore_storage_class)]] var<out> tint_symbol_3 : f32;
-
-[[location(2), interpolate(perspective, center), internal(disable_validation__ignore_storage_class)]] var<out> tint_symbol_4 : f32;
-
-[[location(3), interpolate(perspective, centroid), internal(disable_validation__ignore_storage_class)]] var<out> tint_symbol_5 : f32;
-
-[[location(4), interpolate(perspective, sample), internal(disable_validation__ignore_storage_class)]] var<out> tint_symbol_6 : f32;
-
-[[location(5), interpolate(linear, center), internal(disable_validation__ignore_storage_class)]] var<out> tint_symbol_7 : f32;
-
-[[location(6), interpolate(linear, centroid), internal(disable_validation__ignore_storage_class)]] var<out> tint_symbol_8 : f32;
-
-[[location(7), interpolate(linear, sample), internal(disable_validation__ignore_storage_class)]] var<out> tint_symbol_9 : f32;
-
-fn tint_symbol_10(tint_symbol : Out) {
- tint_symbol_1 = tint_symbol.pos;
- tint_symbol_2 = tint_symbol.none;
- tint_symbol_3 = tint_symbol.flat;
- tint_symbol_4 = tint_symbol.perspective_center;
- tint_symbol_5 = tint_symbol.perspective_centroid;
- tint_symbol_6 = tint_symbol.perspective_sample;
- tint_symbol_7 = tint_symbol.linear_center;
- tint_symbol_8 = tint_symbol.linear_centroid;
- tint_symbol_9 = tint_symbol.linear_sample;
-}
-
-[[stage(vertex)]]
-fn main() {
- tint_pointsize = 1.0;
- tint_symbol_10(Out());
- return;
-}
-
-Failed to generate: unknown decoration
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 38
+; Schema: 0
+ OpCapability Shader
+ OpCapability SampleRateShading
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main" %tint_pointsize %tint_symbol_1 %tint_symbol_2 %tint_symbol_3 %tint_symbol_4 %tint_symbol_5 %tint_symbol_6 %tint_symbol_7 %tint_symbol_8 %tint_symbol_9
+ OpName %tint_pointsize "tint_pointsize"
+ OpName %tint_symbol_1 "tint_symbol_1"
+ OpName %tint_symbol_2 "tint_symbol_2"
+ OpName %tint_symbol_3 "tint_symbol_3"
+ OpName %tint_symbol_4 "tint_symbol_4"
+ OpName %tint_symbol_5 "tint_symbol_5"
+ OpName %tint_symbol_6 "tint_symbol_6"
+ OpName %tint_symbol_7 "tint_symbol_7"
+ OpName %tint_symbol_8 "tint_symbol_8"
+ OpName %tint_symbol_9 "tint_symbol_9"
+ OpName %Out "Out"
+ OpMemberName %Out 0 "pos"
+ OpMemberName %Out 1 "none"
+ OpMemberName %Out 2 "flat"
+ OpMemberName %Out 3 "perspective_center"
+ OpMemberName %Out 4 "perspective_centroid"
+ OpMemberName %Out 5 "perspective_sample"
+ OpMemberName %Out 6 "linear_center"
+ OpMemberName %Out 7 "linear_centroid"
+ OpMemberName %Out 8 "linear_sample"
+ OpName %tint_symbol_10 "tint_symbol_10"
+ OpName %tint_symbol "tint_symbol"
+ OpName %main "main"
+ OpDecorate %tint_pointsize BuiltIn PointSize
+ OpDecorate %tint_symbol_1 BuiltIn Position
+ OpDecorate %tint_symbol_2 Location 0
+ OpDecorate %tint_symbol_3 Location 1
+ OpDecorate %tint_symbol_3 Flat
+ OpDecorate %tint_symbol_4 Location 2
+ OpDecorate %tint_symbol_5 Location 3
+ OpDecorate %tint_symbol_5 Centroid
+ OpDecorate %tint_symbol_6 Location 4
+ OpDecorate %tint_symbol_6 Sample
+ OpDecorate %tint_symbol_7 Location 5
+ OpDecorate %tint_symbol_7 NoPerspective
+ OpDecorate %tint_symbol_8 Location 6
+ OpDecorate %tint_symbol_8 NoPerspective
+ OpDecorate %tint_symbol_8 Centroid
+ OpDecorate %tint_symbol_9 Location 7
+ OpDecorate %tint_symbol_9 NoPerspective
+ OpDecorate %tint_symbol_9 Sample
+ OpMemberDecorate %Out 0 Offset 0
+ OpMemberDecorate %Out 1 Offset 16
+ OpMemberDecorate %Out 2 Offset 20
+ OpMemberDecorate %Out 3 Offset 24
+ OpMemberDecorate %Out 4 Offset 28
+ OpMemberDecorate %Out 5 Offset 32
+ OpMemberDecorate %Out 6 Offset 36
+ OpMemberDecorate %Out 7 Offset 40
+ OpMemberDecorate %Out 8 Offset 44
+ %float = OpTypeFloat 32
+%_ptr_Output_float = OpTypePointer Output %float
+ %4 = OpConstantNull %float
+%tint_pointsize = OpVariable %_ptr_Output_float Output %4
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %8 = OpConstantNull %v4float
+%tint_symbol_1 = OpVariable %_ptr_Output_v4float Output %8
+%tint_symbol_2 = OpVariable %_ptr_Output_float Output %4
+%tint_symbol_3 = OpVariable %_ptr_Output_float Output %4
+%tint_symbol_4 = OpVariable %_ptr_Output_float Output %4
+%tint_symbol_5 = OpVariable %_ptr_Output_float Output %4
+%tint_symbol_6 = OpVariable %_ptr_Output_float Output %4
+%tint_symbol_7 = OpVariable %_ptr_Output_float Output %4
+%tint_symbol_8 = OpVariable %_ptr_Output_float Output %4
+%tint_symbol_9 = OpVariable %_ptr_Output_float Output %4
+ %void = OpTypeVoid
+ %Out = OpTypeStruct %v4float %float %float %float %float %float %float %float %float
+ %17 = OpTypeFunction %void %Out
+ %32 = OpTypeFunction %void
+ %float_1 = OpConstant %float 1
+ %37 = OpConstantNull %Out
+%tint_symbol_10 = OpFunction %void None %17
+%tint_symbol = OpFunctionParameter %Out
+ %22 = OpLabel
+ %23 = OpCompositeExtract %v4float %tint_symbol 0
+ OpStore %tint_symbol_1 %23
+ %24 = OpCompositeExtract %float %tint_symbol 1
+ OpStore %tint_symbol_2 %24
+ %25 = OpCompositeExtract %float %tint_symbol 2
+ OpStore %tint_symbol_3 %25
+ %26 = OpCompositeExtract %float %tint_symbol 3
+ OpStore %tint_symbol_4 %26
+ %27 = OpCompositeExtract %float %tint_symbol 4
+ OpStore %tint_symbol_5 %27
+ %28 = OpCompositeExtract %float %tint_symbol 5
+ OpStore %tint_symbol_6 %28
+ %29 = OpCompositeExtract %float %tint_symbol 6
+ OpStore %tint_symbol_7 %29
+ %30 = OpCompositeExtract %float %tint_symbol 7
+ OpStore %tint_symbol_8 %30
+ %31 = OpCompositeExtract %float %tint_symbol 8
+ OpStore %tint_symbol_9 %31
+ OpReturn
+ OpFunctionEnd
+ %main = OpFunction %void None %32
+ %34 = OpLabel
+ OpStore %tint_pointsize %float_1
+ %36 = OpFunctionCall %void %tint_symbol_10 %37
+ OpReturn
+ OpFunctionEnd