writer/spirv: Implement invariant attribute

Bug: tint:772
Change-Id: I94f8e95f7c1206f33dbf4defba2d22d95a5cfb1e
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/57643
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
James Price 2021-07-12 14:48:20 +00:00 committed by Tint LUCI CQ
parent 762c81b4eb
commit 88b8e2f289
5 changed files with 150 additions and 32 deletions

View File

@ -145,9 +145,9 @@ void Spirv::HandleEntryPointIOTypes(CloneContext& ctx) const {
for (auto* member : struct_ty->members()) {
ast::DecorationList new_decorations = RemoveDecorations(
&ctx, member->decorations(), [](const ast::Decoration* deco) {
return deco
->IsAnyOf<ast::BuiltinDecoration, ast::InterpolateDecoration,
ast::LocationDecoration>();
return deco->IsAnyOf<
ast::BuiltinDecoration, ast::InterpolateDecoration,
ast::InvariantDecoration, ast::LocationDecoration>();
});
new_struct_members.push_back(
ctx.dst->Member(ctx.Clone(member->symbol()),
@ -316,9 +316,9 @@ Symbol Spirv::HoistToInputVariables(
// Base case: create a global variable and return.
ast::DecorationList new_decorations =
RemoveDecorations(&ctx, decorations, [](const ast::Decoration* deco) {
return !deco->IsAnyOf<ast::BuiltinDecoration,
ast::InterpolateDecoration,
ast::LocationDecoration>();
return !deco->IsAnyOf<
ast::BuiltinDecoration, ast::InterpolateDecoration,
ast::InvariantDecoration, ast::LocationDecoration>();
});
new_decorations.push_back(
ctx.dst->ASTNodes().Create<ast::DisableValidationDecoration>(
@ -382,9 +382,9 @@ void Spirv::HoistToOutputVariables(CloneContext& ctx,
// Create a global variable.
ast::DecorationList new_decorations =
RemoveDecorations(&ctx, decorations, [](const ast::Decoration* deco) {
return !deco->IsAnyOf<ast::BuiltinDecoration,
ast::InterpolateDecoration,
ast::LocationDecoration>();
return !deco->IsAnyOf<
ast::BuiltinDecoration, ast::InterpolateDecoration,
ast::InvariantDecoration, ast::LocationDecoration>();
});
new_decorations.push_back(
ctx.dst->ASTNodes().Create<ast::DisableValidationDecoration>(

View File

@ -601,6 +601,58 @@ fn frag_main() {
EXPECT_EQ(expect, str(got));
}
TEST_F(SpirvTest, HandleEntryPointIOTypes_InvariantAttributes) {
auto* src = R"(
struct VertexOut {
[[builtin(position), invariant]] pos : vec4<f32>;
};
[[stage(vertex)]]
fn main1() -> VertexOut {
return VertexOut();
}
[[stage(vertex)]]
fn main2() -> [[builtin(position), invariant]] vec4<f32> {
return vec4<f32>();
}
)";
auto* expect = R"(
struct VertexOut {
pos : vec4<f32>;
};
[[builtin(position), invariant, internal(disable_validation__ignore_storage_class)]] var<out> tint_symbol_1 : vec4<f32>;
fn tint_symbol_2(tint_symbol : VertexOut) {
tint_symbol_1 = tint_symbol.pos;
}
[[stage(vertex)]]
fn main1() {
tint_symbol_2(VertexOut());
return;
}
[[builtin(position), invariant, internal(disable_validation__ignore_storage_class)]] var<out> tint_symbol_4 : vec4<f32>;
fn tint_symbol_5(tint_symbol_3 : vec4<f32>) {
tint_symbol_4 = tint_symbol_3;
}
[[stage(vertex)]]
fn main2() {
tint_symbol_5(vec4<f32>());
return;
}
)";
auto got = Run<Spirv>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(SpirvTest, HandleEntryPointIOTypes_StructLayoutDecorations) {
auto* src = R"(
[[block]]

View File

@ -853,6 +853,9 @@ bool Builder::GenerateGlobalVariable(ast::Variable* var) {
} else if (auto* interpolate = deco->As<ast::InterpolateDecoration>()) {
AddInterpolationDecorations(var_id, interpolate->type(),
interpolate->sampling());
} else if (deco->Is<ast::InvariantDecoration>()) {
push_annot(spv::Op::OpDecorate,
{Operand::Int(var_id), Operand::Int(SpvDecorationInvariant)});
} else if (auto* binding = deco->As<ast::BindingDecoration>()) {
push_annot(spv::Op::OpDecorate,
{Operand::Int(var_id), Operand::Int(SpvDecorationBinding),

View File

@ -1,9 +1,40 @@
SKIP: FAILED
[[stage(vertex)]]
fn main() -> [[builtin(position), invariant]] vec4<f32> {
return vec4<f32>();
}
Failed to generate: unknown decoration
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 19
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %main "main" %tint_pointsize %tint_symbol_1
OpName %tint_pointsize "tint_pointsize"
OpName %tint_symbol_1 "tint_symbol_1"
OpName %tint_symbol_2 "tint_symbol_2"
OpName %tint_symbol "tint_symbol"
OpName %main "main"
OpDecorate %tint_pointsize BuiltIn PointSize
OpDecorate %tint_symbol_1 BuiltIn Position
OpDecorate %tint_symbol_1 Invariant
%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
%void = OpTypeVoid
%9 = OpTypeFunction %void %v4float
%14 = OpTypeFunction %void
%float_1 = OpConstant %float 1
%tint_symbol_2 = OpFunction %void None %9
%tint_symbol = OpFunctionParameter %v4float
%13 = OpLabel
OpStore %tint_symbol_1 %tint_symbol
OpReturn
OpFunctionEnd
%main = OpFunction %void None %14
%16 = OpLabel
OpStore %tint_pointsize %float_1
%18 = OpFunctionCall %void %tint_symbol_2 %8
OpReturn
OpFunctionEnd

View File

@ -1,14 +1,46 @@
SKIP: FAILED
struct Out {
[[builtin(position), invariant]]
pos : vec4<f32>;
};
[[stage(vertex)]]
fn main() -> Out {
return Out();
}
Failed to generate: unknown decoration
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 22
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %main "main" %tint_pointsize %tint_symbol_1
OpName %tint_pointsize "tint_pointsize"
OpName %tint_symbol_1 "tint_symbol_1"
OpName %Out "Out"
OpMemberName %Out 0 "pos"
OpName %tint_symbol_2 "tint_symbol_2"
OpName %tint_symbol "tint_symbol"
OpName %main "main"
OpDecorate %tint_pointsize BuiltIn PointSize
OpDecorate %tint_symbol_1 BuiltIn Position
OpDecorate %tint_symbol_1 Invariant
OpMemberDecorate %Out 0 Offset 0
%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
%void = OpTypeVoid
%Out = OpTypeStruct %v4float
%9 = OpTypeFunction %void %Out
%16 = OpTypeFunction %void
%float_1 = OpConstant %float 1
%21 = OpConstantNull %Out
%tint_symbol_2 = OpFunction %void None %9
%tint_symbol = OpFunctionParameter %Out
%14 = OpLabel
%15 = OpCompositeExtract %v4float %tint_symbol 0
OpStore %tint_symbol_1 %15
OpReturn
OpFunctionEnd
%main = OpFunction %void None %16
%18 = OpLabel
OpStore %tint_pointsize %float_1
%20 = OpFunctionCall %void %tint_symbol_2 %21
OpReturn
OpFunctionEnd