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