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
18 namespace tint {
19 namespace reader {
20 namespace spirv {
21 namespace {
22
23 using ::testing::Eq;
24
TEST_F(SpvParserTest,ConvertMemberDecoration_Empty)25 TEST_F(SpvParserTest, ConvertMemberDecoration_Empty) {
26 auto p = parser(std::vector<uint32_t>{});
27
28 auto result = p->ConvertMemberDecoration(1, 1, nullptr, {});
29 EXPECT_TRUE(result.empty());
30 EXPECT_THAT(p->error(), Eq("malformed SPIR-V decoration: it's empty"));
31 }
32
TEST_F(SpvParserTest,ConvertMemberDecoration_OffsetWithoutOperand)33 TEST_F(SpvParserTest, ConvertMemberDecoration_OffsetWithoutOperand) {
34 auto p = parser(std::vector<uint32_t>{});
35
36 auto result =
37 p->ConvertMemberDecoration(12, 13, nullptr, {SpvDecorationOffset});
38 EXPECT_TRUE(result.empty());
39 EXPECT_THAT(p->error(), Eq("malformed Offset decoration: expected 1 literal "
40 "operand, has 0: member 13 of SPIR-V type 12"));
41 }
42
TEST_F(SpvParserTest,ConvertMemberDecoration_OffsetWithTooManyOperands)43 TEST_F(SpvParserTest, ConvertMemberDecoration_OffsetWithTooManyOperands) {
44 auto p = parser(std::vector<uint32_t>{});
45
46 auto result =
47 p->ConvertMemberDecoration(12, 13, nullptr, {SpvDecorationOffset, 3, 4});
48 EXPECT_TRUE(result.empty());
49 EXPECT_THAT(p->error(), Eq("malformed Offset decoration: expected 1 literal "
50 "operand, has 2: member 13 of SPIR-V type 12"));
51 }
52
TEST_F(SpvParserTest,ConvertMemberDecoration_Offset)53 TEST_F(SpvParserTest, ConvertMemberDecoration_Offset) {
54 auto p = parser(std::vector<uint32_t>{});
55
56 auto result =
57 p->ConvertMemberDecoration(1, 1, nullptr, {SpvDecorationOffset, 8});
58 ASSERT_FALSE(result.empty());
59 EXPECT_TRUE(result[0]->Is<ast::StructMemberOffsetDecoration>());
60 auto* offset_deco = result[0]->As<ast::StructMemberOffsetDecoration>();
61 ASSERT_NE(offset_deco, nullptr);
62 EXPECT_EQ(offset_deco->offset, 8u);
63 EXPECT_TRUE(p->error().empty());
64 }
65
TEST_F(SpvParserTest,ConvertMemberDecoration_Matrix2x2_Stride_Natural)66 TEST_F(SpvParserTest, ConvertMemberDecoration_Matrix2x2_Stride_Natural) {
67 auto p = parser(std::vector<uint32_t>{});
68
69 spirv::F32 f32;
70 spirv::Matrix matrix(&f32, 2, 2);
71 auto result =
72 p->ConvertMemberDecoration(1, 1, &matrix, {SpvDecorationMatrixStride, 8});
73 EXPECT_TRUE(result.empty());
74 EXPECT_TRUE(p->error().empty());
75 }
76
TEST_F(SpvParserTest,ConvertMemberDecoration_Matrix2x2_Stride_Custom)77 TEST_F(SpvParserTest, ConvertMemberDecoration_Matrix2x2_Stride_Custom) {
78 auto p = parser(std::vector<uint32_t>{});
79
80 spirv::F32 f32;
81 spirv::Matrix matrix(&f32, 2, 2);
82 auto result = p->ConvertMemberDecoration(1, 1, &matrix,
83 {SpvDecorationMatrixStride, 16});
84 ASSERT_FALSE(result.empty());
85 EXPECT_TRUE(result[0]->Is<ast::StrideDecoration>());
86 auto* stride_deco = result[0]->As<ast::StrideDecoration>();
87 ASSERT_NE(stride_deco, nullptr);
88 EXPECT_EQ(stride_deco->stride, 16u);
89 EXPECT_TRUE(p->error().empty());
90 }
91
TEST_F(SpvParserTest,ConvertMemberDecoration_Matrix2x4_Stride_Natural)92 TEST_F(SpvParserTest, ConvertMemberDecoration_Matrix2x4_Stride_Natural) {
93 auto p = parser(std::vector<uint32_t>{});
94
95 spirv::F32 f32;
96 spirv::Matrix matrix(&f32, 2, 4);
97 auto result = p->ConvertMemberDecoration(1, 1, &matrix,
98 {SpvDecorationMatrixStride, 16});
99 EXPECT_TRUE(result.empty());
100 EXPECT_TRUE(p->error().empty());
101 }
102
TEST_F(SpvParserTest,ConvertMemberDecoration_Matrix2x4_Stride_Custom)103 TEST_F(SpvParserTest, ConvertMemberDecoration_Matrix2x4_Stride_Custom) {
104 auto p = parser(std::vector<uint32_t>{});
105
106 spirv::F32 f32;
107 spirv::Matrix matrix(&f32, 2, 4);
108 auto result = p->ConvertMemberDecoration(1, 1, &matrix,
109 {SpvDecorationMatrixStride, 64});
110 ASSERT_FALSE(result.empty());
111 EXPECT_TRUE(result[0]->Is<ast::StrideDecoration>());
112 auto* stride_deco = result[0]->As<ast::StrideDecoration>();
113 ASSERT_NE(stride_deco, nullptr);
114 EXPECT_EQ(stride_deco->stride, 64u);
115 EXPECT_TRUE(p->error().empty());
116 }
117
TEST_F(SpvParserTest,ConvertMemberDecoration_Matrix2x3_Stride_Custom)118 TEST_F(SpvParserTest, ConvertMemberDecoration_Matrix2x3_Stride_Custom) {
119 auto p = parser(std::vector<uint32_t>{});
120
121 spirv::F32 f32;
122 spirv::Matrix matrix(&f32, 2, 3);
123 auto result = p->ConvertMemberDecoration(1, 1, &matrix,
124 {SpvDecorationMatrixStride, 32});
125 ASSERT_FALSE(result.empty());
126 EXPECT_TRUE(result[0]->Is<ast::StrideDecoration>());
127 auto* stride_deco = result[0]->As<ast::StrideDecoration>();
128 ASSERT_NE(stride_deco, nullptr);
129 EXPECT_EQ(stride_deco->stride, 32u);
130 EXPECT_TRUE(p->error().empty());
131 }
132
TEST_F(SpvParserTest,ConvertMemberDecoration_RelaxedPrecision)133 TEST_F(SpvParserTest, ConvertMemberDecoration_RelaxedPrecision) {
134 // WGSL does not support relaxed precision. Drop it.
135 // It's functionally correct to use full precision f32 instead of
136 // relaxed precision f32.
137 auto p = parser(std::vector<uint32_t>{});
138
139 auto result = p->ConvertMemberDecoration(1, 1, nullptr,
140 {SpvDecorationRelaxedPrecision});
141 EXPECT_TRUE(result.empty());
142 EXPECT_TRUE(p->error().empty());
143 }
144
TEST_F(SpvParserTest,ConvertMemberDecoration_UnhandledDecoration)145 TEST_F(SpvParserTest, ConvertMemberDecoration_UnhandledDecoration) {
146 auto p = parser(std::vector<uint32_t>{});
147
148 auto result = p->ConvertMemberDecoration(12, 13, nullptr, {12345678});
149 EXPECT_TRUE(result.empty());
150 EXPECT_THAT(p->error(), Eq("unhandled member decoration: 12345678 on member "
151 "13 of SPIR-V type 12"));
152 }
153
154 } // namespace
155 } // namespace spirv
156 } // namespace reader
157 } // namespace tint
158