1 // Copyright 2020 The Tint Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "gmock/gmock.h"
16 #include "src/reader/spirv/parser_impl_test_helper.h"
17 #include "src/reader/spirv/spirv_tools_helpers_test.h"
18
19 namespace tint {
20 namespace reader {
21 namespace spirv {
22 namespace {
23
24 using ::testing::Eq;
25 using ::testing::UnorderedElementsAre;
26
27 using SpvParserGetDecorationsTest = SpvParserTest;
28
29 const char* kSkipReason = "This example is deliberately a SPIR-V fragment";
30
TEST_F(SpvParserGetDecorationsTest,GetDecorationsFor_NotAnId)31 TEST_F(SpvParserGetDecorationsTest, GetDecorationsFor_NotAnId) {
32 auto p = parser(test::Assemble(""));
33 EXPECT_TRUE(p->BuildAndParseInternalModule());
34 auto decorations = p->GetDecorationsFor(42);
35 EXPECT_TRUE(decorations.empty());
36 EXPECT_TRUE(p->error().empty());
37 p->SkipDumpingPending(kSkipReason);
38 }
39
TEST_F(SpvParserGetDecorationsTest,GetDecorationsFor_NoDecorations)40 TEST_F(SpvParserGetDecorationsTest, GetDecorationsFor_NoDecorations) {
41 auto p = parser(test::Assemble("%1 = OpTypeVoid"));
42 EXPECT_TRUE(p->BuildAndParseInternalModule());
43 auto decorations = p->GetDecorationsFor(1);
44 EXPECT_TRUE(decorations.empty());
45 EXPECT_TRUE(p->error().empty());
46 p->SkipDumpingPending(kSkipReason);
47 }
48
TEST_F(SpvParserGetDecorationsTest,GetDecorationsFor_OneDecoration)49 TEST_F(SpvParserGetDecorationsTest, GetDecorationsFor_OneDecoration) {
50 auto p = parser(test::Assemble(R"(
51 OpDecorate %10 Block
52 %float = OpTypeFloat 32
53 %10 = OpTypeStruct %float
54 )"));
55 EXPECT_TRUE(p->BuildAndParseInternalModule());
56 auto decorations = p->GetDecorationsFor(10);
57 EXPECT_THAT(decorations,
58 UnorderedElementsAre(Decoration{SpvDecorationBlock}));
59 EXPECT_TRUE(p->error().empty());
60 p->SkipDumpingPending(kSkipReason);
61 }
62
TEST_F(SpvParserGetDecorationsTest,GetDecorationsFor_MultiDecoration)63 TEST_F(SpvParserGetDecorationsTest, GetDecorationsFor_MultiDecoration) {
64 auto p = parser(test::Assemble(R"(
65 OpDecorate %5 RelaxedPrecision
66 OpDecorate %5 Location 7 ; Invalid case made up for test
67 %float = OpTypeFloat 32
68 %5 = OpConstant %float 3.14
69 )"));
70 EXPECT_TRUE(p->BuildAndParseInternalModule());
71 auto decorations = p->GetDecorationsFor(5);
72 EXPECT_THAT(decorations,
73 UnorderedElementsAre(Decoration{SpvDecorationRelaxedPrecision},
74 Decoration{SpvDecorationLocation, 7}));
75 EXPECT_TRUE(p->error().empty());
76 p->SkipDumpingPending(kSkipReason);
77 }
78
TEST_F(SpvParserGetDecorationsTest,GetDecorationsForMember_NotAnId)79 TEST_F(SpvParserGetDecorationsTest, GetDecorationsForMember_NotAnId) {
80 auto p = parser(test::Assemble(""));
81 EXPECT_TRUE(p->BuildAndParseInternalModule());
82 auto decorations = p->GetDecorationsForMember(42, 9);
83 EXPECT_TRUE(decorations.empty());
84 EXPECT_TRUE(p->error().empty());
85 p->SkipDumpingPending(kSkipReason);
86 }
87
TEST_F(SpvParserGetDecorationsTest,GetDecorationsForMember_NotAStruct)88 TEST_F(SpvParserGetDecorationsTest, GetDecorationsForMember_NotAStruct) {
89 auto p = parser(test::Assemble("%1 = OpTypeVoid"));
90 EXPECT_TRUE(p->BuildAndParseInternalModule());
91 auto decorations = p->GetDecorationsFor(1);
92 EXPECT_TRUE(decorations.empty());
93 EXPECT_TRUE(p->error().empty());
94 p->SkipDumpingPending(kSkipReason);
95 }
96
TEST_F(SpvParserGetDecorationsTest,GetDecorationsForMember_MemberWithoutDecoration)97 TEST_F(SpvParserGetDecorationsTest,
98 GetDecorationsForMember_MemberWithoutDecoration) {
99 auto p = parser(test::Assemble(R"(
100 %uint = OpTypeInt 32 0
101 %10 = OpTypeStruct %uint
102 )"));
103 EXPECT_TRUE(p->BuildAndParseInternalModule());
104 auto decorations = p->GetDecorationsForMember(10, 0);
105 EXPECT_TRUE(decorations.empty());
106 EXPECT_TRUE(p->error().empty());
107 p->SkipDumpingPending(kSkipReason);
108 }
109
TEST_F(SpvParserGetDecorationsTest,GetDecorationsForMember_RelaxedPrecision)110 TEST_F(SpvParserGetDecorationsTest, GetDecorationsForMember_RelaxedPrecision) {
111 auto p = parser(test::Assemble(R"(
112 OpMemberDecorate %10 0 RelaxedPrecision
113 %float = OpTypeFloat 32
114 %10 = OpTypeStruct %float
115 )"));
116 EXPECT_TRUE(p->BuildAndParseInternalModule()) << p->error();
117 auto decorations = p->GetDecorationsForMember(10, 0);
118 EXPECT_THAT(decorations,
119 UnorderedElementsAre(Decoration{SpvDecorationRelaxedPrecision}));
120 EXPECT_TRUE(p->error().empty());
121 p->SkipDumpingPending(kSkipReason);
122 }
123
124 // TODO(dneto): Enable when ArrayStride is handled
TEST_F(SpvParserGetDecorationsTest,DISABLED_GetDecorationsForMember_OneDecoration)125 TEST_F(SpvParserGetDecorationsTest,
126 DISABLED_GetDecorationsForMember_OneDecoration) {
127 auto p = parser(test::Assemble(R"(
128 OpMemberDecorate %10 1 ArrayStride 12
129 %uint = OpTypeInt 32 0
130 %uint_2 = OpConstant %uint 2
131 %arr = OpTypeArray %uint %uint_2
132 %10 = OpTypeStruct %uint %arr
133 )"));
134 EXPECT_TRUE(p->BuildAndParseInternalModule()) << p->error();
135 auto decorations = p->GetDecorationsForMember(10, 1);
136 EXPECT_THAT(decorations,
137 UnorderedElementsAre(Decoration{SpvDecorationArrayStride, 12}));
138 EXPECT_TRUE(p->error().empty());
139 }
140
141 // TODO(dneto): Enable when ArrayStride, MatrixStride, ColMajor are handled
142 // crbug.com/tint/30 for ArrayStride
143 // crbug.com/tint/31 for matrix layout
TEST_F(SpvParserGetDecorationsTest,DISABLED_GetDecorationsForMember_MultiDecoration)144 TEST_F(SpvParserGetDecorationsTest,
145 DISABLED_GetDecorationsForMember_MultiDecoration) {
146 auto p = parser(test::Assemble(R"(
147 OpMemberDecorate %50 1 RelaxedPrecision
148 OpMemberDecorate %50 2 ArrayStride 16
149 OpMemberDecorate %50 2 MatrixStride 8
150 OpMemberDecorate %50 2 ColMajor
151 %float = OpTypeFloat 32
152 %vec = OpTypeVector %float 2
153 %mat = OpTypeMatrix %vec 2
154 %uint = OpTypeInt 32 0
155 %uint_2 = OpConstant %uint 2
156 %arr = OpTypeArray %mat %uint_2
157 %50 = OpTypeStruct %uint %float %arr
158 )"));
159 EXPECT_TRUE(p->BuildAndParseInternalModule()) << p->error();
160
161 EXPECT_TRUE(p->GetDecorationsForMember(50, 0).empty());
162 EXPECT_THAT(p->GetDecorationsForMember(50, 1),
163 UnorderedElementsAre(Decoration{SpvDecorationRelaxedPrecision}));
164 EXPECT_THAT(p->GetDecorationsForMember(50, 2),
165 UnorderedElementsAre(Decoration{SpvDecorationColMajor},
166 Decoration{SpvDecorationMatrixStride, 8},
167 Decoration{SpvDecorationArrayStride, 16}));
168 EXPECT_TRUE(p->error().empty());
169 }
170
171 } // namespace
172 } // namespace spirv
173 } // namespace reader
174 } // namespace tint
175