1fd4e5da5Sopenharmony_ci// Copyright (c) 2015-2016 The Khronos Group Inc.
2fd4e5da5Sopenharmony_ci// Copyright (c) 2016 Google Inc.
3fd4e5da5Sopenharmony_ci//
4fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
5fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License.
6fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at
7fd4e5da5Sopenharmony_ci//
8fd4e5da5Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
9fd4e5da5Sopenharmony_ci//
10fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
11fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
12fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and
14fd4e5da5Sopenharmony_ci// limitations under the License.
15fd4e5da5Sopenharmony_ci
16fd4e5da5Sopenharmony_ci// Unit tests for ValidationState_t.
17fd4e5da5Sopenharmony_ci
18fd4e5da5Sopenharmony_ci#include <vector>
19fd4e5da5Sopenharmony_ci
20fd4e5da5Sopenharmony_ci#include "gtest/gtest.h"
21fd4e5da5Sopenharmony_ci#include "source/enum_set.h"
22fd4e5da5Sopenharmony_ci#include "source/extensions.h"
23fd4e5da5Sopenharmony_ci#include "source/latest_version_spirv_header.h"
24fd4e5da5Sopenharmony_ci#include "source/spirv_validator_options.h"
25fd4e5da5Sopenharmony_ci#include "source/val/validation_state.h"
26fd4e5da5Sopenharmony_ci
27fd4e5da5Sopenharmony_cinamespace spvtools {
28fd4e5da5Sopenharmony_cinamespace val {
29fd4e5da5Sopenharmony_cinamespace {
30fd4e5da5Sopenharmony_ci
31fd4e5da5Sopenharmony_ci// This is all we need for these tests.
32fd4e5da5Sopenharmony_cistatic uint32_t kFakeBinary[] = {0};
33fd4e5da5Sopenharmony_ci
34fd4e5da5Sopenharmony_ci// A test with a ValidationState_t member transparently.
35fd4e5da5Sopenharmony_ciclass ValidationStateTest : public testing::Test {
36fd4e5da5Sopenharmony_ci public:
37fd4e5da5Sopenharmony_ci  ValidationStateTest()
38fd4e5da5Sopenharmony_ci      : context_(spvContextCreate(SPV_ENV_UNIVERSAL_1_0)),
39fd4e5da5Sopenharmony_ci        options_(spvValidatorOptionsCreate()),
40fd4e5da5Sopenharmony_ci        state_(context_, options_, kFakeBinary, 0, 1) {}
41fd4e5da5Sopenharmony_ci
42fd4e5da5Sopenharmony_ci  ~ValidationStateTest() override {
43fd4e5da5Sopenharmony_ci    spvContextDestroy(context_);
44fd4e5da5Sopenharmony_ci    spvValidatorOptionsDestroy(options_);
45fd4e5da5Sopenharmony_ci  }
46fd4e5da5Sopenharmony_ci
47fd4e5da5Sopenharmony_ci protected:
48fd4e5da5Sopenharmony_ci  spv_context context_;
49fd4e5da5Sopenharmony_ci  spv_validator_options options_;
50fd4e5da5Sopenharmony_ci  ValidationState_t state_;
51fd4e5da5Sopenharmony_ci};
52fd4e5da5Sopenharmony_ci
53fd4e5da5Sopenharmony_ci// A test of ValidationState_t::HasAnyOfCapabilities().
54fd4e5da5Sopenharmony_ciusing ValidationState_HasAnyOfCapabilities = ValidationStateTest;
55fd4e5da5Sopenharmony_ci
56fd4e5da5Sopenharmony_ciTEST_F(ValidationState_HasAnyOfCapabilities, EmptyMask) {
57fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.HasAnyOfCapabilities({}));
58fd4e5da5Sopenharmony_ci  state_.RegisterCapability(spv::Capability::Matrix);
59fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.HasAnyOfCapabilities({}));
60fd4e5da5Sopenharmony_ci  state_.RegisterCapability(spv::Capability::ImageMipmap);
61fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.HasAnyOfCapabilities({}));
62fd4e5da5Sopenharmony_ci  state_.RegisterCapability(spv::Capability::Pipes);
63fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.HasAnyOfCapabilities({}));
64fd4e5da5Sopenharmony_ci  state_.RegisterCapability(spv::Capability::StorageImageArrayDynamicIndexing);
65fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.HasAnyOfCapabilities({}));
66fd4e5da5Sopenharmony_ci  state_.RegisterCapability(spv::Capability::ClipDistance);
67fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.HasAnyOfCapabilities({}));
68fd4e5da5Sopenharmony_ci  state_.RegisterCapability(spv::Capability::StorageImageWriteWithoutFormat);
69fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.HasAnyOfCapabilities({}));
70fd4e5da5Sopenharmony_ci}
71fd4e5da5Sopenharmony_ci
72fd4e5da5Sopenharmony_ciTEST_F(ValidationState_HasAnyOfCapabilities, SingleCapMask) {
73fd4e5da5Sopenharmony_ci  EXPECT_FALSE(state_.HasAnyOfCapabilities({spv::Capability::Matrix}));
74fd4e5da5Sopenharmony_ci  EXPECT_FALSE(state_.HasAnyOfCapabilities({spv::Capability::ImageMipmap}));
75fd4e5da5Sopenharmony_ci  state_.RegisterCapability(spv::Capability::Matrix);
76fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.HasAnyOfCapabilities({spv::Capability::Matrix}));
77fd4e5da5Sopenharmony_ci  EXPECT_FALSE(state_.HasAnyOfCapabilities({spv::Capability::ImageMipmap}));
78fd4e5da5Sopenharmony_ci  state_.RegisterCapability(spv::Capability::ImageMipmap);
79fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.HasAnyOfCapabilities({spv::Capability::Matrix}));
80fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.HasAnyOfCapabilities({spv::Capability::ImageMipmap}));
81fd4e5da5Sopenharmony_ci}
82fd4e5da5Sopenharmony_ci
83fd4e5da5Sopenharmony_ciTEST_F(ValidationState_HasAnyOfCapabilities, MultiCapMask) {
84fd4e5da5Sopenharmony_ci  const auto set1 =
85fd4e5da5Sopenharmony_ci      CapabilitySet{spv::Capability::SampledRect, spv::Capability::ImageBuffer};
86fd4e5da5Sopenharmony_ci  const auto set2 =
87fd4e5da5Sopenharmony_ci      CapabilitySet{spv::Capability::StorageImageWriteWithoutFormat,
88fd4e5da5Sopenharmony_ci                    spv::Capability::StorageImageReadWithoutFormat,
89fd4e5da5Sopenharmony_ci                    spv::Capability::GeometryStreams};
90fd4e5da5Sopenharmony_ci  EXPECT_FALSE(state_.HasAnyOfCapabilities(set1));
91fd4e5da5Sopenharmony_ci  EXPECT_FALSE(state_.HasAnyOfCapabilities(set2));
92fd4e5da5Sopenharmony_ci  state_.RegisterCapability(spv::Capability::ImageBuffer);
93fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.HasAnyOfCapabilities(set1));
94fd4e5da5Sopenharmony_ci  EXPECT_FALSE(state_.HasAnyOfCapabilities(set2));
95fd4e5da5Sopenharmony_ci}
96fd4e5da5Sopenharmony_ci
97fd4e5da5Sopenharmony_ci// A test of ValidationState_t::HasAnyOfExtensions().
98fd4e5da5Sopenharmony_ciusing ValidationState_HasAnyOfExtensions = ValidationStateTest;
99fd4e5da5Sopenharmony_ci
100fd4e5da5Sopenharmony_ciTEST_F(ValidationState_HasAnyOfExtensions, EmptyMask) {
101fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.HasAnyOfExtensions({}));
102fd4e5da5Sopenharmony_ci  state_.RegisterExtension(Extension::kSPV_KHR_shader_ballot);
103fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.HasAnyOfExtensions({}));
104fd4e5da5Sopenharmony_ci  state_.RegisterExtension(Extension::kSPV_KHR_16bit_storage);
105fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.HasAnyOfExtensions({}));
106fd4e5da5Sopenharmony_ci  state_.RegisterExtension(Extension::kSPV_NV_viewport_array2);
107fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.HasAnyOfExtensions({}));
108fd4e5da5Sopenharmony_ci}
109fd4e5da5Sopenharmony_ci
110fd4e5da5Sopenharmony_ciTEST_F(ValidationState_HasAnyOfExtensions, SingleCapMask) {
111fd4e5da5Sopenharmony_ci  EXPECT_FALSE(state_.HasAnyOfExtensions({Extension::kSPV_KHR_shader_ballot}));
112fd4e5da5Sopenharmony_ci  EXPECT_FALSE(state_.HasAnyOfExtensions({Extension::kSPV_KHR_16bit_storage}));
113fd4e5da5Sopenharmony_ci  state_.RegisterExtension(Extension::kSPV_KHR_shader_ballot);
114fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.HasAnyOfExtensions({Extension::kSPV_KHR_shader_ballot}));
115fd4e5da5Sopenharmony_ci  EXPECT_FALSE(state_.HasAnyOfExtensions({Extension::kSPV_KHR_16bit_storage}));
116fd4e5da5Sopenharmony_ci  state_.RegisterExtension(Extension::kSPV_KHR_16bit_storage);
117fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.HasAnyOfExtensions({Extension::kSPV_KHR_shader_ballot}));
118fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.HasAnyOfExtensions({Extension::kSPV_KHR_16bit_storage}));
119fd4e5da5Sopenharmony_ci}
120fd4e5da5Sopenharmony_ci
121fd4e5da5Sopenharmony_ciTEST_F(ValidationState_HasAnyOfExtensions, MultiCapMask) {
122fd4e5da5Sopenharmony_ci  const auto set1 = ExtensionSet{Extension::kSPV_KHR_multiview,
123fd4e5da5Sopenharmony_ci                                 Extension::kSPV_KHR_16bit_storage};
124fd4e5da5Sopenharmony_ci  const auto set2 = ExtensionSet{Extension::kSPV_KHR_shader_draw_parameters,
125fd4e5da5Sopenharmony_ci                                 Extension::kSPV_NV_stereo_view_rendering,
126fd4e5da5Sopenharmony_ci                                 Extension::kSPV_KHR_shader_ballot};
127fd4e5da5Sopenharmony_ci  EXPECT_FALSE(state_.HasAnyOfExtensions(set1));
128fd4e5da5Sopenharmony_ci  EXPECT_FALSE(state_.HasAnyOfExtensions(set2));
129fd4e5da5Sopenharmony_ci  state_.RegisterExtension(Extension::kSPV_KHR_multiview);
130fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.HasAnyOfExtensions(set1));
131fd4e5da5Sopenharmony_ci  EXPECT_FALSE(state_.HasAnyOfExtensions(set2));
132fd4e5da5Sopenharmony_ci}
133fd4e5da5Sopenharmony_ci
134fd4e5da5Sopenharmony_ci// A test of ValidationState_t::IsOpcodeInCurrentLayoutSection().
135fd4e5da5Sopenharmony_ciusing ValidationState_InLayoutState = ValidationStateTest;
136fd4e5da5Sopenharmony_ci
137fd4e5da5Sopenharmony_ciTEST_F(ValidationState_InLayoutState, Variable) {
138fd4e5da5Sopenharmony_ci  state_.SetCurrentLayoutSectionForTesting(kLayoutTypes);
139fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpVariable));
140fd4e5da5Sopenharmony_ci
141fd4e5da5Sopenharmony_ci  state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDefinitions);
142fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpVariable));
143fd4e5da5Sopenharmony_ci}
144fd4e5da5Sopenharmony_ci
145fd4e5da5Sopenharmony_ciTEST_F(ValidationState_InLayoutState, ExtInst) {
146fd4e5da5Sopenharmony_ci  state_.SetCurrentLayoutSectionForTesting(kLayoutTypes);
147fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpExtInst));
148fd4e5da5Sopenharmony_ci
149fd4e5da5Sopenharmony_ci  state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDefinitions);
150fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpExtInst));
151fd4e5da5Sopenharmony_ci}
152fd4e5da5Sopenharmony_ci
153fd4e5da5Sopenharmony_ciTEST_F(ValidationState_InLayoutState, Undef) {
154fd4e5da5Sopenharmony_ci  state_.SetCurrentLayoutSectionForTesting(kLayoutTypes);
155fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpUndef));
156fd4e5da5Sopenharmony_ci
157fd4e5da5Sopenharmony_ci  state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDefinitions);
158fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpUndef));
159fd4e5da5Sopenharmony_ci}
160fd4e5da5Sopenharmony_ci
161fd4e5da5Sopenharmony_ciTEST_F(ValidationState_InLayoutState, Function) {
162fd4e5da5Sopenharmony_ci  state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDeclarations);
163fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpFunction));
164fd4e5da5Sopenharmony_ci
165fd4e5da5Sopenharmony_ci  state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDefinitions);
166fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpFunction));
167fd4e5da5Sopenharmony_ci}
168fd4e5da5Sopenharmony_ci
169fd4e5da5Sopenharmony_ciTEST_F(ValidationState_InLayoutState, FunctionParameter) {
170fd4e5da5Sopenharmony_ci  state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDeclarations);
171fd4e5da5Sopenharmony_ci  EXPECT_TRUE(
172fd4e5da5Sopenharmony_ci      state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpFunctionParameter));
173fd4e5da5Sopenharmony_ci
174fd4e5da5Sopenharmony_ci  state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDefinitions);
175fd4e5da5Sopenharmony_ci  EXPECT_TRUE(
176fd4e5da5Sopenharmony_ci      state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpFunctionParameter));
177fd4e5da5Sopenharmony_ci}
178fd4e5da5Sopenharmony_ci
179fd4e5da5Sopenharmony_ciTEST_F(ValidationState_InLayoutState, FunctionEnd) {
180fd4e5da5Sopenharmony_ci  state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDeclarations);
181fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpFunctionEnd));
182fd4e5da5Sopenharmony_ci
183fd4e5da5Sopenharmony_ci  state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDefinitions);
184fd4e5da5Sopenharmony_ci  EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpFunctionEnd));
185fd4e5da5Sopenharmony_ci}
186fd4e5da5Sopenharmony_ci
187fd4e5da5Sopenharmony_ci}  // namespace
188fd4e5da5Sopenharmony_ci}  // namespace val
189fd4e5da5Sopenharmony_ci}  // namespace spvtools
190