1fd4e5da5Sopenharmony_ci// Copyright (c) 2021 Google LLC
2fd4e5da5Sopenharmony_ci//
3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License.
5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at
6fd4e5da5Sopenharmony_ci//
7fd4e5da5Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
8fd4e5da5Sopenharmony_ci//
9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and
13fd4e5da5Sopenharmony_ci// limitations under the License.
14fd4e5da5Sopenharmony_ci
15fd4e5da5Sopenharmony_ci// Validation tests for decorations
16fd4e5da5Sopenharmony_ci
17fd4e5da5Sopenharmony_ci#include <string>
18fd4e5da5Sopenharmony_ci#include <vector>
19fd4e5da5Sopenharmony_ci
20fd4e5da5Sopenharmony_ci#include "gmock/gmock.h"
21fd4e5da5Sopenharmony_ci#include "test/unit_spirv.h"
22fd4e5da5Sopenharmony_ci#include "test/val/val_code_generator.h"
23fd4e5da5Sopenharmony_ci#include "test/val/val_fixtures.h"
24fd4e5da5Sopenharmony_ci
25fd4e5da5Sopenharmony_cinamespace spvtools {
26fd4e5da5Sopenharmony_cinamespace val {
27fd4e5da5Sopenharmony_cinamespace {
28fd4e5da5Sopenharmony_ci
29fd4e5da5Sopenharmony_ciusing ::testing::Combine;
30fd4e5da5Sopenharmony_ciusing ::testing::Eq;
31fd4e5da5Sopenharmony_ciusing ::testing::HasSubstr;
32fd4e5da5Sopenharmony_ciusing ::testing::Values;
33fd4e5da5Sopenharmony_ci
34fd4e5da5Sopenharmony_ciusing DecorationTest = spvtest::ValidateBase<bool>;
35fd4e5da5Sopenharmony_ci
36fd4e5da5Sopenharmony_ciTEST_F(DecorationTest, WorkgroupSizeShader) {
37fd4e5da5Sopenharmony_ci  const std::string text = R"(
38fd4e5da5Sopenharmony_ciOpCapability Shader
39fd4e5da5Sopenharmony_ciOpCapability Linkage
40fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
41fd4e5da5Sopenharmony_ciOpDecorate %ones BuiltIn WorkgroupSize
42fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
43fd4e5da5Sopenharmony_ci%int3 = OpTypeVector %int 3
44fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
45fd4e5da5Sopenharmony_ci%ones = OpConstantComposite %int3 %int_1 %int_1 %int_1
46fd4e5da5Sopenharmony_ci)";
47fd4e5da5Sopenharmony_ci
48fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
49fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
50fd4e5da5Sopenharmony_ci}
51fd4e5da5Sopenharmony_ci
52fd4e5da5Sopenharmony_ciTEST_F(DecorationTest, WorkgroupSizeKernel) {
53fd4e5da5Sopenharmony_ci  const std::string text = R"(
54fd4e5da5Sopenharmony_ciOpCapability Kernel
55fd4e5da5Sopenharmony_ciOpCapability Linkage
56fd4e5da5Sopenharmony_ciOpMemoryModel Logical OpenCL
57fd4e5da5Sopenharmony_ciOpDecorate %var BuiltIn WorkgroupSize
58fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
59fd4e5da5Sopenharmony_ci%int3 = OpTypeVector %int 3
60fd4e5da5Sopenharmony_ci%ptr = OpTypePointer Input %int3
61fd4e5da5Sopenharmony_ci%var = OpVariable %ptr Input
62fd4e5da5Sopenharmony_ci)";
63fd4e5da5Sopenharmony_ci
64fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
65fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
66fd4e5da5Sopenharmony_ci}
67fd4e5da5Sopenharmony_ci
68fd4e5da5Sopenharmony_ciusing MemberOnlyDecorations = spvtest::ValidateBase<std::string>;
69fd4e5da5Sopenharmony_ci
70fd4e5da5Sopenharmony_ciTEST_P(MemberOnlyDecorations, MemberDecoration) {
71fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
72fd4e5da5Sopenharmony_ci  const std::string text = R"(
73fd4e5da5Sopenharmony_ciOpCapability Shader
74fd4e5da5Sopenharmony_ciOpCapability Linkage
75fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
76fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 )" +
77fd4e5da5Sopenharmony_ci                           deco + R"(
78fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
79fd4e5da5Sopenharmony_ci%float2 = OpTypeVector %float 2
80fd4e5da5Sopenharmony_ci%float2x2 = OpTypeMatrix %float2 2
81fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %float2x2
82fd4e5da5Sopenharmony_ci)";
83fd4e5da5Sopenharmony_ci
84fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
85fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
86fd4e5da5Sopenharmony_ci}
87fd4e5da5Sopenharmony_ci
88fd4e5da5Sopenharmony_ciTEST_P(MemberOnlyDecorations, Decoration) {
89fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
90fd4e5da5Sopenharmony_ci  const std::string text = R"(
91fd4e5da5Sopenharmony_ciOpCapability Shader
92fd4e5da5Sopenharmony_ciOpCapability Linkage
93fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
94fd4e5da5Sopenharmony_ciOpDecorate %struct )" + deco +
95fd4e5da5Sopenharmony_ci                           R"(
96fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
97fd4e5da5Sopenharmony_ci%float2 = OpTypeVector %float 2
98fd4e5da5Sopenharmony_ci%float2x2 = OpTypeMatrix %float2 2
99fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %float2x2
100fd4e5da5Sopenharmony_ci)";
101fd4e5da5Sopenharmony_ci
102fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
103fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
104fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
105fd4e5da5Sopenharmony_ci              HasSubstr("can only be applied to structure members"));
106fd4e5da5Sopenharmony_ci}
107fd4e5da5Sopenharmony_ci
108fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(ValidateMemberOnlyDecorations, MemberOnlyDecorations,
109fd4e5da5Sopenharmony_ci                         Values("RowMajor", "ColMajor", "MatrixStride 16"
110fd4e5da5Sopenharmony_ci                                // SPIR-V spec bug?
111fd4e5da5Sopenharmony_ci                                /*,"Offset 0"*/));
112fd4e5da5Sopenharmony_ci
113fd4e5da5Sopenharmony_ciusing NonMemberOnlyDecorations = spvtest::ValidateBase<std::string>;
114fd4e5da5Sopenharmony_ci
115fd4e5da5Sopenharmony_ciTEST_P(NonMemberOnlyDecorations, MemberDecoration) {
116fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
117fd4e5da5Sopenharmony_ci  const auto text = R"(
118fd4e5da5Sopenharmony_ciOpCapability Shader
119fd4e5da5Sopenharmony_ciOpCapability Kernel
120fd4e5da5Sopenharmony_ciOpCapability Linkage
121fd4e5da5Sopenharmony_ciOpCapability InputAttachment
122fd4e5da5Sopenharmony_ciOpCapability Addresses
123fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses
124fd4e5da5Sopenharmony_ciOpCapability ShaderNonUniform
125fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_no_integer_wrap_decoration"
126fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_physical_storage_buffer"
127fd4e5da5Sopenharmony_ciOpExtension "SPV_GOOGLE_hlsl_functionality1"
128fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_descriptor_indexing"
129fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
130fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 )" +
131fd4e5da5Sopenharmony_ci                    deco + R"(
132fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
133fd4e5da5Sopenharmony_ci%float2 = OpTypeVector %float 2
134fd4e5da5Sopenharmony_ci%float2x2 = OpTypeMatrix %float2 2
135fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %float2x2
136fd4e5da5Sopenharmony_ci)";
137fd4e5da5Sopenharmony_ci
138fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
139fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
140fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
141fd4e5da5Sopenharmony_ci              HasSubstr("cannot be applied to structure members"));
142fd4e5da5Sopenharmony_ci}
143fd4e5da5Sopenharmony_ci
144fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(
145fd4e5da5Sopenharmony_ci    ValidateNonMemberOnlyDecorations, NonMemberOnlyDecorations,
146fd4e5da5Sopenharmony_ci    Values("SpecId 1", "Block", "BufferBlock", "ArrayStride 4", "GLSLShared",
147fd4e5da5Sopenharmony_ci           "GLSLPacked", "CPacked",
148fd4e5da5Sopenharmony_ci           // TODO: https://github.com/KhronosGroup/glslang/issues/703:
149fd4e5da5Sopenharmony_ci           // glslang applies Restrict to structure members.
150fd4e5da5Sopenharmony_ci           //"Restrict",
151fd4e5da5Sopenharmony_ci           "Aliased", "Constant", "Uniform", "SaturatedConversion", "Index 0",
152fd4e5da5Sopenharmony_ci           "Binding 0", "DescriptorSet 0", "FuncParamAttr Zext",
153fd4e5da5Sopenharmony_ci           "FPRoundingMode RTE", "FPFastMathMode None",
154fd4e5da5Sopenharmony_ci           "LinkageAttributes \"ext\" Import", "NoContraction",
155fd4e5da5Sopenharmony_ci           "InputAttachmentIndex 0", "Alignment 4", "MaxByteOffset 4",
156fd4e5da5Sopenharmony_ci           "AlignmentId %float", "MaxByteOffsetId %float", "NoSignedWrap",
157fd4e5da5Sopenharmony_ci           "NoUnsignedWrap", "NonUniform", "RestrictPointer", "AliasedPointer",
158fd4e5da5Sopenharmony_ci           "CounterBuffer %float"));
159fd4e5da5Sopenharmony_ci
160fd4e5da5Sopenharmony_ciusing StructDecorations = spvtest::ValidateBase<std::string>;
161fd4e5da5Sopenharmony_ci
162fd4e5da5Sopenharmony_ciTEST_P(StructDecorations, Struct) {
163fd4e5da5Sopenharmony_ci  const std::string deco = GetParam();
164fd4e5da5Sopenharmony_ci  const std::string text = R"(
165fd4e5da5Sopenharmony_ciOpCapability Shader
166fd4e5da5Sopenharmony_ciOpCapability Kernel
167fd4e5da5Sopenharmony_ciOpCapability Linkage
168fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
169fd4e5da5Sopenharmony_ciOpDecorate %struct )" + deco +
170fd4e5da5Sopenharmony_ci                           R"(
171fd4e5da5Sopenharmony_ci%struct = OpTypeStruct
172fd4e5da5Sopenharmony_ci)";
173fd4e5da5Sopenharmony_ci
174fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
175fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
176fd4e5da5Sopenharmony_ci}
177fd4e5da5Sopenharmony_ci
178fd4e5da5Sopenharmony_ciTEST_P(StructDecorations, OtherType) {
179fd4e5da5Sopenharmony_ci  const std::string deco = GetParam();
180fd4e5da5Sopenharmony_ci  const std::string text = R"(
181fd4e5da5Sopenharmony_ciOpCapability Shader
182fd4e5da5Sopenharmony_ciOpCapability Kernel
183fd4e5da5Sopenharmony_ciOpCapability Linkage
184fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
185fd4e5da5Sopenharmony_ciOpDecorate %int )" + deco + R"(
186fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
187fd4e5da5Sopenharmony_ci)";
188fd4e5da5Sopenharmony_ci
189fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
190fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
191fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a structure type"));
192fd4e5da5Sopenharmony_ci}
193fd4e5da5Sopenharmony_ci
194fd4e5da5Sopenharmony_ciTEST_P(StructDecorations, Variable) {
195fd4e5da5Sopenharmony_ci  const std::string deco = GetParam();
196fd4e5da5Sopenharmony_ci  const std::string text = R"(
197fd4e5da5Sopenharmony_ciOpCapability Shader
198fd4e5da5Sopenharmony_ciOpCapability Kernel
199fd4e5da5Sopenharmony_ciOpCapability Linkage
200fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
201fd4e5da5Sopenharmony_ciOpDecorate %var )" + deco + R"(
202fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
203fd4e5da5Sopenharmony_ci%ptr = OpTypePointer Private %int
204fd4e5da5Sopenharmony_ci%var = OpVariable %ptr Private
205fd4e5da5Sopenharmony_ci)";
206fd4e5da5Sopenharmony_ci
207fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
208fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
209fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a structure type"));
210fd4e5da5Sopenharmony_ci}
211fd4e5da5Sopenharmony_ci
212fd4e5da5Sopenharmony_ciTEST_P(StructDecorations, FunctionParameter) {
213fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
214fd4e5da5Sopenharmony_ci  const std::string text = R"(
215fd4e5da5Sopenharmony_ciOpCapability Shader
216fd4e5da5Sopenharmony_ciOpCapability Kernel
217fd4e5da5Sopenharmony_ciOpCapability Linkage
218fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
219fd4e5da5Sopenharmony_ciOpDecorate %func LinkageAttributes "import" Import
220fd4e5da5Sopenharmony_ciOpDecorate %param )" + deco +
221fd4e5da5Sopenharmony_ci                           R"(
222fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
223fd4e5da5Sopenharmony_ci%void = OpTypeVoid
224fd4e5da5Sopenharmony_ci%fn = OpTypeFunction %void %int
225fd4e5da5Sopenharmony_ci%func = OpFunction %void None %fn
226fd4e5da5Sopenharmony_ci%param = OpFunctionParameter %int
227fd4e5da5Sopenharmony_ciOpFunctionEnd
228fd4e5da5Sopenharmony_ci)";
229fd4e5da5Sopenharmony_ci
230fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
231fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
232fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a structure type"));
233fd4e5da5Sopenharmony_ci}
234fd4e5da5Sopenharmony_ci
235fd4e5da5Sopenharmony_ciTEST_P(StructDecorations, Constant) {
236fd4e5da5Sopenharmony_ci  const std::string deco = GetParam();
237fd4e5da5Sopenharmony_ci  const std::string text = R"(
238fd4e5da5Sopenharmony_ciOpCapability Shader
239fd4e5da5Sopenharmony_ciOpCapability Kernel
240fd4e5da5Sopenharmony_ciOpCapability Linkage
241fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
242fd4e5da5Sopenharmony_ciOpDecorate %int_0 )" + deco +
243fd4e5da5Sopenharmony_ci                           R"(
244fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
245fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
246fd4e5da5Sopenharmony_ci)";
247fd4e5da5Sopenharmony_ci
248fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
249fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
250fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a structure type"));
251fd4e5da5Sopenharmony_ci}
252fd4e5da5Sopenharmony_ci
253fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(ValidateStructDecorations, StructDecorations,
254fd4e5da5Sopenharmony_ci                         Values("Block", "BufferBlock", "GLSLShared",
255fd4e5da5Sopenharmony_ci                                "GLSLPacked", "CPacked"));
256fd4e5da5Sopenharmony_ci
257fd4e5da5Sopenharmony_ciusing ArrayDecorations = spvtest::ValidateBase<std::string>;
258fd4e5da5Sopenharmony_ci
259fd4e5da5Sopenharmony_ciTEST_P(ArrayDecorations, Array) {
260fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
261fd4e5da5Sopenharmony_ci  const std::string text = R"(
262fd4e5da5Sopenharmony_ciOpCapability Shader
263fd4e5da5Sopenharmony_ciOpCapability Linkage
264fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
265fd4e5da5Sopenharmony_ciOpDecorate %array )" + deco +
266fd4e5da5Sopenharmony_ci                           R"(
267fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
268fd4e5da5Sopenharmony_ci%int_4 = OpConstant %int 4
269fd4e5da5Sopenharmony_ci%array = OpTypeArray %int %int_4
270fd4e5da5Sopenharmony_ci)";
271fd4e5da5Sopenharmony_ci
272fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
273fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
274fd4e5da5Sopenharmony_ci}
275fd4e5da5Sopenharmony_ci
276fd4e5da5Sopenharmony_ciTEST_P(ArrayDecorations, RuntimeArray) {
277fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
278fd4e5da5Sopenharmony_ci  const std::string text = R"(
279fd4e5da5Sopenharmony_ciOpCapability Shader
280fd4e5da5Sopenharmony_ciOpCapability Linkage
281fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
282fd4e5da5Sopenharmony_ciOpDecorate %array )" + deco +
283fd4e5da5Sopenharmony_ci                           R"(
284fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
285fd4e5da5Sopenharmony_ci%array = OpTypeRuntimeArray %int
286fd4e5da5Sopenharmony_ci)";
287fd4e5da5Sopenharmony_ci
288fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
289fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
290fd4e5da5Sopenharmony_ci}
291fd4e5da5Sopenharmony_ci
292fd4e5da5Sopenharmony_ciTEST_P(ArrayDecorations, Pointer) {
293fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
294fd4e5da5Sopenharmony_ci  const std::string text = R"(
295fd4e5da5Sopenharmony_ciOpCapability Shader
296fd4e5da5Sopenharmony_ciOpCapability Linkage
297fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
298fd4e5da5Sopenharmony_ciOpDecorate %ptr )" + deco + R"(
299fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
300fd4e5da5Sopenharmony_ci%ptr = OpTypePointer Workgroup %int
301fd4e5da5Sopenharmony_ci)";
302fd4e5da5Sopenharmony_ci
303fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
304fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
305fd4e5da5Sopenharmony_ci}
306fd4e5da5Sopenharmony_ci
307fd4e5da5Sopenharmony_ciTEST_P(ArrayDecorations, Struct) {
308fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
309fd4e5da5Sopenharmony_ci  const std::string text = R"(
310fd4e5da5Sopenharmony_ciOpCapability Shader
311fd4e5da5Sopenharmony_ciOpCapability Linkage
312fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
313fd4e5da5Sopenharmony_ciOpDecorate %struct )" + deco +
314fd4e5da5Sopenharmony_ci                           R"(
315fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
316fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %int
317fd4e5da5Sopenharmony_ci)";
318fd4e5da5Sopenharmony_ci
319fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
320fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
321fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
322fd4e5da5Sopenharmony_ci              HasSubstr("must be an array or pointer type"));
323fd4e5da5Sopenharmony_ci}
324fd4e5da5Sopenharmony_ci
325fd4e5da5Sopenharmony_ciTEST_P(ArrayDecorations, Variable) {
326fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
327fd4e5da5Sopenharmony_ci  const std::string text = R"(
328fd4e5da5Sopenharmony_ciOpCapability Shader
329fd4e5da5Sopenharmony_ciOpCapability Linkage
330fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
331fd4e5da5Sopenharmony_ciOpDecorate %var )" + deco + R"(
332fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
333fd4e5da5Sopenharmony_ci%ptr = OpTypePointer Private %int
334fd4e5da5Sopenharmony_ci%var = OpVariable %ptr Private
335fd4e5da5Sopenharmony_ci)";
336fd4e5da5Sopenharmony_ci
337fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
338fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
339fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
340fd4e5da5Sopenharmony_ci              HasSubstr("must be an array or pointer type"));
341fd4e5da5Sopenharmony_ci}
342fd4e5da5Sopenharmony_ci
343fd4e5da5Sopenharmony_ciTEST_P(ArrayDecorations, FunctionParameter) {
344fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
345fd4e5da5Sopenharmony_ci  const std::string text = R"(
346fd4e5da5Sopenharmony_ciOpCapability Shader
347fd4e5da5Sopenharmony_ciOpCapability Linkage
348fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
349fd4e5da5Sopenharmony_ciOpDecorate %func LinkageAttributes "import" Import
350fd4e5da5Sopenharmony_ciOpDecorate %param )" + deco +
351fd4e5da5Sopenharmony_ci                           R"(
352fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
353fd4e5da5Sopenharmony_ci%void = OpTypeVoid
354fd4e5da5Sopenharmony_ci%fn = OpTypeFunction %void %int
355fd4e5da5Sopenharmony_ci%func = OpFunction %void None %fn
356fd4e5da5Sopenharmony_ci%param = OpFunctionParameter %int
357fd4e5da5Sopenharmony_ciOpFunctionEnd
358fd4e5da5Sopenharmony_ci)";
359fd4e5da5Sopenharmony_ci
360fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
361fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
362fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
363fd4e5da5Sopenharmony_ci              HasSubstr("must be an array or pointer type"));
364fd4e5da5Sopenharmony_ci}
365fd4e5da5Sopenharmony_ci
366fd4e5da5Sopenharmony_ciTEST_P(ArrayDecorations, Constant) {
367fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
368fd4e5da5Sopenharmony_ci  const std::string text = R"(
369fd4e5da5Sopenharmony_ciOpCapability Shader
370fd4e5da5Sopenharmony_ciOpCapability Linkage
371fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
372fd4e5da5Sopenharmony_ciOpDecorate %null )" + deco +
373fd4e5da5Sopenharmony_ci                           R"(
374fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
375fd4e5da5Sopenharmony_ci%int_4 = OpConstant %int 4
376fd4e5da5Sopenharmony_ci%array = OpTypeArray %int %int_4
377fd4e5da5Sopenharmony_ci%null = OpConstantNull %array
378fd4e5da5Sopenharmony_ci)";
379fd4e5da5Sopenharmony_ci
380fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
381fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
382fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
383fd4e5da5Sopenharmony_ci              HasSubstr("must be an array or pointer type"));
384fd4e5da5Sopenharmony_ci}
385fd4e5da5Sopenharmony_ci
386fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(ValidateArrayDecorations, ArrayDecorations,
387fd4e5da5Sopenharmony_ci                         Values("ArrayStride 4"));
388fd4e5da5Sopenharmony_ci
389fd4e5da5Sopenharmony_ciusing BuiltInDecorations = spvtest::ValidateBase<std::string>;
390fd4e5da5Sopenharmony_ci
391fd4e5da5Sopenharmony_ciTEST_P(BuiltInDecorations, Variable) {
392fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
393fd4e5da5Sopenharmony_ci  const std::string text = R"(
394fd4e5da5Sopenharmony_ciOpCapability Shader
395fd4e5da5Sopenharmony_ciOpCapability Linkage
396fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
397fd4e5da5Sopenharmony_ciOpDecorate %var BuiltIn )" +
398fd4e5da5Sopenharmony_ci                           deco + R"(
399fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
400fd4e5da5Sopenharmony_ci%ptr = OpTypePointer Input %int
401fd4e5da5Sopenharmony_ci%var = OpVariable %ptr Input
402fd4e5da5Sopenharmony_ci)";
403fd4e5da5Sopenharmony_ci
404fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
405fd4e5da5Sopenharmony_ci  if (deco != "WorkgroupSize") {
406fd4e5da5Sopenharmony_ci    EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
407fd4e5da5Sopenharmony_ci  } else {
408fd4e5da5Sopenharmony_ci    EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
409fd4e5da5Sopenharmony_ci    EXPECT_THAT(getDiagnosticString(),
410fd4e5da5Sopenharmony_ci                HasSubstr("must be a constant for WorkgroupSize"));
411fd4e5da5Sopenharmony_ci  }
412fd4e5da5Sopenharmony_ci}
413fd4e5da5Sopenharmony_ci
414fd4e5da5Sopenharmony_ciTEST_P(BuiltInDecorations, IntegerType) {
415fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
416fd4e5da5Sopenharmony_ci  const std::string text = R"(
417fd4e5da5Sopenharmony_ciOpCapability Shader
418fd4e5da5Sopenharmony_ciOpCapability Linkage
419fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
420fd4e5da5Sopenharmony_ciOpDecorate %int BuiltIn )" +
421fd4e5da5Sopenharmony_ci                           deco + R"(
422fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
423fd4e5da5Sopenharmony_ci)";
424fd4e5da5Sopenharmony_ci
425fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
426fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
427fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
428fd4e5da5Sopenharmony_ci              HasSubstr("BuiltIns can only target variables, structure members "
429fd4e5da5Sopenharmony_ci                        "or constants"));
430fd4e5da5Sopenharmony_ci}
431fd4e5da5Sopenharmony_ci
432fd4e5da5Sopenharmony_ciTEST_P(BuiltInDecorations, FunctionParameter) {
433fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
434fd4e5da5Sopenharmony_ci  const std::string text = R"(
435fd4e5da5Sopenharmony_ciOpCapability Shader
436fd4e5da5Sopenharmony_ciOpCapability Linkage
437fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
438fd4e5da5Sopenharmony_ciOpDecorate %func LinkageAttributes "import" Import
439fd4e5da5Sopenharmony_ciOpDecorate %param BuiltIn )" +
440fd4e5da5Sopenharmony_ci                           deco + R"(
441fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
442fd4e5da5Sopenharmony_ci%void = OpTypeVoid
443fd4e5da5Sopenharmony_ci%fn = OpTypeFunction %void %int
444fd4e5da5Sopenharmony_ci%func = OpFunction %void None %fn
445fd4e5da5Sopenharmony_ci%param = OpFunctionParameter %int
446fd4e5da5Sopenharmony_ciOpFunctionEnd
447fd4e5da5Sopenharmony_ci)";
448fd4e5da5Sopenharmony_ci
449fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
450fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
451fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
452fd4e5da5Sopenharmony_ci              HasSubstr("BuiltIns can only target variables, structure members "
453fd4e5da5Sopenharmony_ci                        "or constants"));
454fd4e5da5Sopenharmony_ci}
455fd4e5da5Sopenharmony_ci
456fd4e5da5Sopenharmony_ciTEST_P(BuiltInDecorations, Constant) {
457fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
458fd4e5da5Sopenharmony_ci  const std::string text = R"(
459fd4e5da5Sopenharmony_ciOpCapability Shader
460fd4e5da5Sopenharmony_ciOpCapability Linkage
461fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
462fd4e5da5Sopenharmony_ciOpDecorate %const BuiltIn )" +
463fd4e5da5Sopenharmony_ci                           deco + R"(
464fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
465fd4e5da5Sopenharmony_ci%int3 = OpTypeVector %int 3
466fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
467fd4e5da5Sopenharmony_ci%const = OpConstantComposite %int3 %int_1 %int_1 %int_1
468fd4e5da5Sopenharmony_ci)";
469fd4e5da5Sopenharmony_ci
470fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
471fd4e5da5Sopenharmony_ci  if (deco == "WorkgroupSize") {
472fd4e5da5Sopenharmony_ci    EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
473fd4e5da5Sopenharmony_ci  } else {
474fd4e5da5Sopenharmony_ci    EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
475fd4e5da5Sopenharmony_ci    EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a variable"));
476fd4e5da5Sopenharmony_ci  }
477fd4e5da5Sopenharmony_ci}
478fd4e5da5Sopenharmony_ci
479fd4e5da5Sopenharmony_ciTEST_P(BuiltInDecorations, SpecConstant) {
480fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
481fd4e5da5Sopenharmony_ci  const std::string text = R"(
482fd4e5da5Sopenharmony_ciOpCapability Shader
483fd4e5da5Sopenharmony_ciOpCapability Linkage
484fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
485fd4e5da5Sopenharmony_ciOpDecorate %const BuiltIn )" +
486fd4e5da5Sopenharmony_ci                           deco + R"(
487fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
488fd4e5da5Sopenharmony_ci%int3 = OpTypeVector %int 3
489fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
490fd4e5da5Sopenharmony_ci%const = OpSpecConstantComposite %int3 %int_1 %int_1 %int_1
491fd4e5da5Sopenharmony_ci)";
492fd4e5da5Sopenharmony_ci
493fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
494fd4e5da5Sopenharmony_ci  if (deco == "WorkgroupSize") {
495fd4e5da5Sopenharmony_ci    EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
496fd4e5da5Sopenharmony_ci  } else {
497fd4e5da5Sopenharmony_ci    EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
498fd4e5da5Sopenharmony_ci    EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a variable"));
499fd4e5da5Sopenharmony_ci  }
500fd4e5da5Sopenharmony_ci}
501fd4e5da5Sopenharmony_ci
502fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(ValidateBuiltInDecorations, BuiltInDecorations,
503fd4e5da5Sopenharmony_ci                         Values("Position", "PointSize", "VertexId",
504fd4e5da5Sopenharmony_ci                                "InstanceId", "FragCoord", "FrontFacing",
505fd4e5da5Sopenharmony_ci                                "NumWorkgroups", "WorkgroupSize",
506fd4e5da5Sopenharmony_ci                                "LocalInvocationId", "GlobalInvocationId"));
507fd4e5da5Sopenharmony_ci
508fd4e5da5Sopenharmony_ciusing MemoryObjectDecorations = spvtest::ValidateBase<std::string>;
509fd4e5da5Sopenharmony_ci
510fd4e5da5Sopenharmony_ciTEST_P(MemoryObjectDecorations, Variable) {
511fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
512fd4e5da5Sopenharmony_ci  const std::string text = R"(
513fd4e5da5Sopenharmony_ciOpCapability Shader
514fd4e5da5Sopenharmony_ciOpCapability Linkage
515fd4e5da5Sopenharmony_ciOpCapability SampleRateShading
516fd4e5da5Sopenharmony_ciOpCapability TransformFeedback
517fd4e5da5Sopenharmony_ciOpCapability GeometryStreams
518fd4e5da5Sopenharmony_ciOpCapability Tessellation
519fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses
520fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_physical_storage_buffer"
521fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
522fd4e5da5Sopenharmony_ciOpDecorate %var )" + deco + R"(
523fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
524fd4e5da5Sopenharmony_ci%ptr = OpTypePointer Input %float
525fd4e5da5Sopenharmony_ci%var = OpVariable %ptr Input
526fd4e5da5Sopenharmony_ci)";
527fd4e5da5Sopenharmony_ci
528fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
529fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
530fd4e5da5Sopenharmony_ci}
531fd4e5da5Sopenharmony_ci
532fd4e5da5Sopenharmony_ciTEST_P(MemoryObjectDecorations, FunctionParameterGood) {
533fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
534fd4e5da5Sopenharmony_ci  const std::string text = R"(
535fd4e5da5Sopenharmony_ciOpCapability Shader
536fd4e5da5Sopenharmony_ciOpCapability Linkage
537fd4e5da5Sopenharmony_ciOpCapability SampleRateShading
538fd4e5da5Sopenharmony_ciOpCapability TransformFeedback
539fd4e5da5Sopenharmony_ciOpCapability GeometryStreams
540fd4e5da5Sopenharmony_ciOpCapability Tessellation
541fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses
542fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_physical_storage_buffer"
543fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
544fd4e5da5Sopenharmony_ciOpDecorate %func LinkageAttributes "import" Import
545fd4e5da5Sopenharmony_ciOpDecorate %param )" + deco +
546fd4e5da5Sopenharmony_ci                           R"(
547fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
548fd4e5da5Sopenharmony_ci%ptr = OpTypePointer Input %float
549fd4e5da5Sopenharmony_ci%void = OpTypeVoid
550fd4e5da5Sopenharmony_ci%fn = OpTypeFunction %void %ptr
551fd4e5da5Sopenharmony_ci%func = OpFunction %void None %fn
552fd4e5da5Sopenharmony_ci%param = OpFunctionParameter %ptr
553fd4e5da5Sopenharmony_ciOpFunctionEnd
554fd4e5da5Sopenharmony_ci)";
555fd4e5da5Sopenharmony_ci
556fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
557fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
558fd4e5da5Sopenharmony_ci}
559fd4e5da5Sopenharmony_ci
560fd4e5da5Sopenharmony_ciTEST_P(MemoryObjectDecorations, FunctionParameterNotAPointer) {
561fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
562fd4e5da5Sopenharmony_ci  const std::string text = R"(
563fd4e5da5Sopenharmony_ciOpCapability Shader
564fd4e5da5Sopenharmony_ciOpCapability Linkage
565fd4e5da5Sopenharmony_ciOpCapability SampleRateShading
566fd4e5da5Sopenharmony_ciOpCapability TransformFeedback
567fd4e5da5Sopenharmony_ciOpCapability GeometryStreams
568fd4e5da5Sopenharmony_ciOpCapability Tessellation
569fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses
570fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_physical_storage_buffer"
571fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
572fd4e5da5Sopenharmony_ciOpDecorate %func LinkageAttributes "import" Import
573fd4e5da5Sopenharmony_ciOpDecorate %param )" + deco +
574fd4e5da5Sopenharmony_ci                           R"(
575fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
576fd4e5da5Sopenharmony_ci%void = OpTypeVoid
577fd4e5da5Sopenharmony_ci%fn = OpTypeFunction %void %float
578fd4e5da5Sopenharmony_ci%func = OpFunction %void None %fn
579fd4e5da5Sopenharmony_ci%param = OpFunctionParameter %float
580fd4e5da5Sopenharmony_ciOpFunctionEnd
581fd4e5da5Sopenharmony_ci)";
582fd4e5da5Sopenharmony_ci
583fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
584fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
585fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a pointer type"));
586fd4e5da5Sopenharmony_ci}
587fd4e5da5Sopenharmony_ci
588fd4e5da5Sopenharmony_ciTEST_P(MemoryObjectDecorations, FloatType) {
589fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
590fd4e5da5Sopenharmony_ci  const std::string text = R"(
591fd4e5da5Sopenharmony_ciOpCapability Shader
592fd4e5da5Sopenharmony_ciOpCapability Linkage
593fd4e5da5Sopenharmony_ciOpCapability SampleRateShading
594fd4e5da5Sopenharmony_ciOpCapability TransformFeedback
595fd4e5da5Sopenharmony_ciOpCapability GeometryStreams
596fd4e5da5Sopenharmony_ciOpCapability Tessellation
597fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses
598fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_physical_storage_buffer"
599fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
600fd4e5da5Sopenharmony_ciOpDecorate %float )" + deco +
601fd4e5da5Sopenharmony_ci                           R"(
602fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
603fd4e5da5Sopenharmony_ci)";
604fd4e5da5Sopenharmony_ci
605fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
606fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
607fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
608fd4e5da5Sopenharmony_ci              HasSubstr("must be a memory object declaration"));
609fd4e5da5Sopenharmony_ci}
610fd4e5da5Sopenharmony_ci
611fd4e5da5Sopenharmony_ciTEST_P(MemoryObjectDecorations, Constant) {
612fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
613fd4e5da5Sopenharmony_ci  const std::string text = R"(
614fd4e5da5Sopenharmony_ciOpCapability Shader
615fd4e5da5Sopenharmony_ciOpCapability Linkage
616fd4e5da5Sopenharmony_ciOpCapability SampleRateShading
617fd4e5da5Sopenharmony_ciOpCapability TransformFeedback
618fd4e5da5Sopenharmony_ciOpCapability GeometryStreams
619fd4e5da5Sopenharmony_ciOpCapability Tessellation
620fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses
621fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_physical_storage_buffer"
622fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
623fd4e5da5Sopenharmony_ciOpDecorate %const )" + deco +
624fd4e5da5Sopenharmony_ci                           R"(
625fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
626fd4e5da5Sopenharmony_ci%const = OpConstant %float 0
627fd4e5da5Sopenharmony_ci)";
628fd4e5da5Sopenharmony_ci
629fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
630fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
631fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
632fd4e5da5Sopenharmony_ci              HasSubstr("must be a memory object declaration"));
633fd4e5da5Sopenharmony_ci}
634fd4e5da5Sopenharmony_ci
635fd4e5da5Sopenharmony_ci// NonWritable and NonReadable are covered by other tests.
636fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(
637fd4e5da5Sopenharmony_ci    ValidateMemoryObjectDecorations, MemoryObjectDecorations,
638fd4e5da5Sopenharmony_ci    Values("NoPerspective", "Flat", "Patch", "Centroid", "Component 0",
639fd4e5da5Sopenharmony_ci           "Sample", "Restrict", "Aliased", "Volatile", "Coherent", "Stream 0",
640fd4e5da5Sopenharmony_ci           "XfbBuffer 1", "XfbStride 1", "AliasedPointer", "RestrictPointer"));
641fd4e5da5Sopenharmony_ci
642fd4e5da5Sopenharmony_ciusing VariableDecorations = spvtest::ValidateBase<std::string>;
643fd4e5da5Sopenharmony_ci
644fd4e5da5Sopenharmony_ciTEST_P(VariableDecorations, Variable) {
645fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
646fd4e5da5Sopenharmony_ci  const std::string text = R"(
647fd4e5da5Sopenharmony_ciOpCapability Shader
648fd4e5da5Sopenharmony_ciOpCapability Kernel
649fd4e5da5Sopenharmony_ciOpCapability Linkage
650fd4e5da5Sopenharmony_ciOpCapability InputAttachment
651fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
652fd4e5da5Sopenharmony_ciOpDecorate %var )" + deco + R"(
653fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
654fd4e5da5Sopenharmony_ci%ptr = OpTypePointer Input %float
655fd4e5da5Sopenharmony_ci%var = OpVariable %ptr Input
656fd4e5da5Sopenharmony_ci)";
657fd4e5da5Sopenharmony_ci
658fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
659fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
660fd4e5da5Sopenharmony_ci}
661fd4e5da5Sopenharmony_ci
662fd4e5da5Sopenharmony_ciTEST_P(VariableDecorations, FunctionParameter) {
663fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
664fd4e5da5Sopenharmony_ci  const std::string text = R"(
665fd4e5da5Sopenharmony_ciOpCapability Shader
666fd4e5da5Sopenharmony_ciOpCapability Kernel
667fd4e5da5Sopenharmony_ciOpCapability Linkage
668fd4e5da5Sopenharmony_ciOpCapability InputAttachment
669fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
670fd4e5da5Sopenharmony_ciOpDecorate %func LinkageAttributes "import" Import
671fd4e5da5Sopenharmony_ciOpDecorate %param )" + deco +
672fd4e5da5Sopenharmony_ci                           R"(
673fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
674fd4e5da5Sopenharmony_ci%void = OpTypeVoid
675fd4e5da5Sopenharmony_ci%fn = OpTypeFunction %void %float
676fd4e5da5Sopenharmony_ci%func = OpFunction %void None %fn
677fd4e5da5Sopenharmony_ci%param = OpFunctionParameter %float
678fd4e5da5Sopenharmony_ciOpFunctionEnd
679fd4e5da5Sopenharmony_ci)";
680fd4e5da5Sopenharmony_ci
681fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
682fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
683fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a variable"));
684fd4e5da5Sopenharmony_ci}
685fd4e5da5Sopenharmony_ci
686fd4e5da5Sopenharmony_ciTEST_P(VariableDecorations, FloatType) {
687fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
688fd4e5da5Sopenharmony_ci  const std::string text = R"(
689fd4e5da5Sopenharmony_ciOpCapability Shader
690fd4e5da5Sopenharmony_ciOpCapability Kernel
691fd4e5da5Sopenharmony_ciOpCapability Linkage
692fd4e5da5Sopenharmony_ciOpCapability InputAttachment
693fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
694fd4e5da5Sopenharmony_ciOpDecorate %float )" + deco +
695fd4e5da5Sopenharmony_ci                           R"(
696fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
697fd4e5da5Sopenharmony_ci)";
698fd4e5da5Sopenharmony_ci
699fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
700fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
701fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a variable"));
702fd4e5da5Sopenharmony_ci}
703fd4e5da5Sopenharmony_ci
704fd4e5da5Sopenharmony_ciTEST_P(VariableDecorations, Constant) {
705fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
706fd4e5da5Sopenharmony_ci  const std::string text = R"(
707fd4e5da5Sopenharmony_ciOpCapability Shader
708fd4e5da5Sopenharmony_ciOpCapability Kernel
709fd4e5da5Sopenharmony_ciOpCapability Linkage
710fd4e5da5Sopenharmony_ciOpCapability InputAttachment
711fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
712fd4e5da5Sopenharmony_ciOpDecorate %const )" + deco +
713fd4e5da5Sopenharmony_ci                           R"(
714fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
715fd4e5da5Sopenharmony_ci%const = OpConstant %float 0
716fd4e5da5Sopenharmony_ci)";
717fd4e5da5Sopenharmony_ci
718fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
719fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
720fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a variable"));
721fd4e5da5Sopenharmony_ci}
722fd4e5da5Sopenharmony_ci
723fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(ValidateVariableDecorations, VariableDecorations,
724fd4e5da5Sopenharmony_ci                         Values("Invariant", "Constant", "Location 0",
725fd4e5da5Sopenharmony_ci                                "Index 0", "Binding 0", "DescriptorSet 0"));
726fd4e5da5Sopenharmony_ci
727fd4e5da5Sopenharmony_ciusing VulkanIOStorageClass =
728fd4e5da5Sopenharmony_ci    spvtest::ValidateBase<std::tuple<std::string, std::string>>;
729fd4e5da5Sopenharmony_ci
730fd4e5da5Sopenharmony_ciTEST_P(VulkanIOStorageClass, Invalid) {
731fd4e5da5Sopenharmony_ci  const auto deco = std::get<0>(GetParam());
732fd4e5da5Sopenharmony_ci  const auto sc = std::get<1>(GetParam());
733fd4e5da5Sopenharmony_ci  const std::string text = R"(
734fd4e5da5Sopenharmony_ciOpCapability Shader
735fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_storage_buffer_storage_class"
736fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
737fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
738fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
739fd4e5da5Sopenharmony_ciOpDecorate %var )" + deco + R"( 0
740fd4e5da5Sopenharmony_ci%void = OpTypeVoid
741fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
742fd4e5da5Sopenharmony_ci%ptr = OpTypePointer )" +
743fd4e5da5Sopenharmony_ci                           sc +
744fd4e5da5Sopenharmony_ci                           R"( %float
745fd4e5da5Sopenharmony_ci%var = OpVariable %ptr )" + sc +
746fd4e5da5Sopenharmony_ci                           R"(
747fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
748fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
749fd4e5da5Sopenharmony_ci%entry = OpLabel
750fd4e5da5Sopenharmony_ciOpReturn
751fd4e5da5Sopenharmony_ciOpFunctionEnd
752fd4e5da5Sopenharmony_ci)";
753fd4e5da5Sopenharmony_ci
754fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
755fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
756fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
757fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-Location-06672"));
758fd4e5da5Sopenharmony_ci  EXPECT_THAT(
759fd4e5da5Sopenharmony_ci      getDiagnosticString(),
760fd4e5da5Sopenharmony_ci      HasSubstr("decoration must not be applied to this storage class"));
761fd4e5da5Sopenharmony_ci}
762fd4e5da5Sopenharmony_ci
763fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(ValidateVulkanIOStorageClass, VulkanIOStorageClass,
764fd4e5da5Sopenharmony_ci                         Combine(Values("Location", "Component"),
765fd4e5da5Sopenharmony_ci                                 Values("StorageBuffer", "Uniform",
766fd4e5da5Sopenharmony_ci                                        "UniformConstant", "Workgroup",
767fd4e5da5Sopenharmony_ci                                        "Private")));
768fd4e5da5Sopenharmony_ci
769fd4e5da5Sopenharmony_ciusing VulkanResourceStorageClass =
770fd4e5da5Sopenharmony_ci    spvtest::ValidateBase<std::tuple<std::string, std::string>>;
771fd4e5da5Sopenharmony_ci
772fd4e5da5Sopenharmony_ciTEST_P(VulkanResourceStorageClass, Invalid) {
773fd4e5da5Sopenharmony_ci  const auto deco = std::get<0>(GetParam());
774fd4e5da5Sopenharmony_ci  const auto sc = std::get<1>(GetParam());
775fd4e5da5Sopenharmony_ci  const std::string text = R"(
776fd4e5da5Sopenharmony_ciOpCapability Shader
777fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
778fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
779fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
780fd4e5da5Sopenharmony_ciOpDecorate %var )" + deco + R"( 0
781fd4e5da5Sopenharmony_ci%void = OpTypeVoid
782fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
783fd4e5da5Sopenharmony_ci%ptr = OpTypePointer )" +
784fd4e5da5Sopenharmony_ci                           sc +
785fd4e5da5Sopenharmony_ci                           R"( %float
786fd4e5da5Sopenharmony_ci%var = OpVariable %ptr )" + sc +
787fd4e5da5Sopenharmony_ci                           R"(
788fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
789fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
790fd4e5da5Sopenharmony_ci%entry = OpLabel
791fd4e5da5Sopenharmony_ciOpReturn
792fd4e5da5Sopenharmony_ciOpFunctionEnd
793fd4e5da5Sopenharmony_ci)";
794fd4e5da5Sopenharmony_ci
795fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
796fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
797fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
798fd4e5da5Sopenharmony_ci              HasSubstr("VUID-StandaloneSpirv-DescriptorSet-06491"));
799fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
800fd4e5da5Sopenharmony_ci              HasSubstr("must be in the StorageBuffer, Uniform, or "
801fd4e5da5Sopenharmony_ci                        "UniformConstant storage class"));
802fd4e5da5Sopenharmony_ci}
803fd4e5da5Sopenharmony_ci
804fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(ValidateVulkanResourceStorageClass,
805fd4e5da5Sopenharmony_ci                         VulkanResourceStorageClass,
806fd4e5da5Sopenharmony_ci                         Combine(Values("DescriptorSet", "Binding"),
807fd4e5da5Sopenharmony_ci                                 Values("Private", "Input", "Output",
808fd4e5da5Sopenharmony_ci                                        "Workgroup")));
809fd4e5da5Sopenharmony_ci
810fd4e5da5Sopenharmony_ciusing VulkanInterpolationStorageClass = spvtest::ValidateBase<std::string>;
811fd4e5da5Sopenharmony_ci
812fd4e5da5Sopenharmony_ciTEST_P(VulkanInterpolationStorageClass, Input) {
813fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
814fd4e5da5Sopenharmony_ci  const std::string text = R"(
815fd4e5da5Sopenharmony_ciOpCapability Shader
816fd4e5da5Sopenharmony_ciOpCapability SampleRateShading
817fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
818fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
819fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
820fd4e5da5Sopenharmony_ciOpDecorate %var )" + deco + R"(
821fd4e5da5Sopenharmony_ci%void = OpTypeVoid
822fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
823fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
824fd4e5da5Sopenharmony_ci%ptr = OpTypePointer Input %float
825fd4e5da5Sopenharmony_ci%var = OpVariable %ptr Input
826fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
827fd4e5da5Sopenharmony_ci%entry = OpLabel
828fd4e5da5Sopenharmony_ciOpReturn
829fd4e5da5Sopenharmony_ciOpFunctionEnd
830fd4e5da5Sopenharmony_ci)";
831fd4e5da5Sopenharmony_ci
832fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
833fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
834fd4e5da5Sopenharmony_ci}
835fd4e5da5Sopenharmony_ci
836fd4e5da5Sopenharmony_ciTEST_P(VulkanInterpolationStorageClass, Output) {
837fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
838fd4e5da5Sopenharmony_ci  const std::string text = R"(
839fd4e5da5Sopenharmony_ciOpCapability Shader
840fd4e5da5Sopenharmony_ciOpCapability SampleRateShading
841fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
842fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main"
843fd4e5da5Sopenharmony_ciOpDecorate %var )" + deco + R"(
844fd4e5da5Sopenharmony_ci%void = OpTypeVoid
845fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
846fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
847fd4e5da5Sopenharmony_ci%ptr = OpTypePointer Output %float
848fd4e5da5Sopenharmony_ci%var = OpVariable %ptr Output
849fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
850fd4e5da5Sopenharmony_ci%entry = OpLabel
851fd4e5da5Sopenharmony_ciOpReturn
852fd4e5da5Sopenharmony_ciOpFunctionEnd
853fd4e5da5Sopenharmony_ci)";
854fd4e5da5Sopenharmony_ci
855fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
856fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
857fd4e5da5Sopenharmony_ci}
858fd4e5da5Sopenharmony_ci
859fd4e5da5Sopenharmony_ciTEST_P(VulkanInterpolationStorageClass, Private) {
860fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
861fd4e5da5Sopenharmony_ci  const std::string text = R"(
862fd4e5da5Sopenharmony_ciOpCapability Shader
863fd4e5da5Sopenharmony_ciOpCapability SampleRateShading
864fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
865fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
866fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
867fd4e5da5Sopenharmony_ciOpDecorate %var )" + deco + R"(
868fd4e5da5Sopenharmony_ci%void = OpTypeVoid
869fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
870fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
871fd4e5da5Sopenharmony_ci%ptr = OpTypePointer Private %float
872fd4e5da5Sopenharmony_ci%var = OpVariable %ptr Private
873fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
874fd4e5da5Sopenharmony_ci%entry = OpLabel
875fd4e5da5Sopenharmony_ciOpReturn
876fd4e5da5Sopenharmony_ciOpFunctionEnd
877fd4e5da5Sopenharmony_ci)";
878fd4e5da5Sopenharmony_ci
879fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
880fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
881fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
882fd4e5da5Sopenharmony_ci              HasSubstr("storage class must be Input or Output"));
883fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
884fd4e5da5Sopenharmony_ci              HasSubstr("[VUID-StandaloneSpirv-Flat-04670"));
885fd4e5da5Sopenharmony_ci}
886fd4e5da5Sopenharmony_ci
887fd4e5da5Sopenharmony_ciTEST_P(VulkanInterpolationStorageClass, Uniform) {
888fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
889fd4e5da5Sopenharmony_ci  const std::string text = R"(
890fd4e5da5Sopenharmony_ciOpCapability Shader
891fd4e5da5Sopenharmony_ciOpCapability SampleRateShading
892fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
893fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
894fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
895fd4e5da5Sopenharmony_ciOpDecorate %var )" + deco + R"(
896fd4e5da5Sopenharmony_ciOpDecorate %var Binding 0
897fd4e5da5Sopenharmony_ciOpDecorate %var DescriptorSet 0
898fd4e5da5Sopenharmony_ci%void = OpTypeVoid
899fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
900fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
901fd4e5da5Sopenharmony_ci%ptr = OpTypePointer Uniform %float
902fd4e5da5Sopenharmony_ci%var = OpVariable %ptr Uniform
903fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
904fd4e5da5Sopenharmony_ci%entry = OpLabel
905fd4e5da5Sopenharmony_ciOpReturn
906fd4e5da5Sopenharmony_ciOpFunctionEnd
907fd4e5da5Sopenharmony_ci)";
908fd4e5da5Sopenharmony_ci
909fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
910fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
911fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
912fd4e5da5Sopenharmony_ci              HasSubstr("storage class must be Input or Output"));
913fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
914fd4e5da5Sopenharmony_ci              HasSubstr("[VUID-StandaloneSpirv-Flat-04670"));
915fd4e5da5Sopenharmony_ci}
916fd4e5da5Sopenharmony_ci
917fd4e5da5Sopenharmony_ciTEST_P(VulkanInterpolationStorageClass, StorageBuffer) {
918fd4e5da5Sopenharmony_ci  const auto deco = GetParam();
919fd4e5da5Sopenharmony_ci  const std::string text = R"(
920fd4e5da5Sopenharmony_ciOpCapability Shader
921fd4e5da5Sopenharmony_ciOpCapability SampleRateShading
922fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_storage_buffer_storage_class"
923fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
924fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
925fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
926fd4e5da5Sopenharmony_ciOpDecorate %var )" + deco + R"(
927fd4e5da5Sopenharmony_ciOpDecorate %var Binding 0
928fd4e5da5Sopenharmony_ciOpDecorate %var DescriptorSet 0
929fd4e5da5Sopenharmony_ci%void = OpTypeVoid
930fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
931fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
932fd4e5da5Sopenharmony_ci%ptr = OpTypePointer StorageBuffer %float
933fd4e5da5Sopenharmony_ci%var = OpVariable %ptr StorageBuffer
934fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
935fd4e5da5Sopenharmony_ci%entry = OpLabel
936fd4e5da5Sopenharmony_ciOpReturn
937fd4e5da5Sopenharmony_ciOpFunctionEnd
938fd4e5da5Sopenharmony_ci)";
939fd4e5da5Sopenharmony_ci
940fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
941fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
942fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
943fd4e5da5Sopenharmony_ci              HasSubstr("storage class must be Input or Output"));
944fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
945fd4e5da5Sopenharmony_ci              HasSubstr("[VUID-StandaloneSpirv-Flat-04670"));
946fd4e5da5Sopenharmony_ci}
947fd4e5da5Sopenharmony_ci
948fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(ValidateVulkanInterpolationStorageClass,
949fd4e5da5Sopenharmony_ci                         VulkanInterpolationStorageClass,
950fd4e5da5Sopenharmony_ci                         Values("Flat", "NoPerspective", "Centroid", "Sample"));
951fd4e5da5Sopenharmony_ci
952fd4e5da5Sopenharmony_ci}  // namespace
953fd4e5da5Sopenharmony_ci}  // namespace val
954fd4e5da5Sopenharmony_ci}  // namespace spvtools
955