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/latest_version_spirv_header.h"
22 
23 #include "source/enum_set.h"
24 #include "source/extensions.h"
25 #include "source/spirv_validator_options.h"
26 #include "source/val/construct.h"
27 #include "source/val/function.h"
28 #include "source/val/validate.h"
29 #include "source/val/validation_state.h"
30 
31 namespace spvtools {
32 namespace val {
33 namespace {
34 
35 // This is all we need for these tests.
36 static uint32_t kFakeBinary[] = {0};
37 
38 // A test with a ValidationState_t member transparently.
39 class ValidationStateTest : public testing::Test {
40  public:
ValidationStateTest()41   ValidationStateTest()
42       : context_(spvContextCreate(SPV_ENV_UNIVERSAL_1_0)),
43         options_(spvValidatorOptionsCreate()),
44         state_(context_, options_, kFakeBinary, 0, 1) {}
45 
~ValidationStateTest()46   ~ValidationStateTest() {
47     spvContextDestroy(context_);
48     spvValidatorOptionsDestroy(options_);
49   }
50 
51  protected:
52   spv_context context_;
53   spv_validator_options options_;
54   ValidationState_t state_;
55 };
56 
57 // A test of ValidationState_t::HasAnyOfCapabilities().
58 using ValidationState_HasAnyOfCapabilities = ValidationStateTest;
59 
TEST_F(ValidationState_HasAnyOfCapabilities,EmptyMask)60 TEST_F(ValidationState_HasAnyOfCapabilities, EmptyMask) {
61   EXPECT_TRUE(state_.HasAnyOfCapabilities({}));
62   state_.RegisterCapability(SpvCapabilityMatrix);
63   EXPECT_TRUE(state_.HasAnyOfCapabilities({}));
64   state_.RegisterCapability(SpvCapabilityImageMipmap);
65   EXPECT_TRUE(state_.HasAnyOfCapabilities({}));
66   state_.RegisterCapability(SpvCapabilityPipes);
67   EXPECT_TRUE(state_.HasAnyOfCapabilities({}));
68   state_.RegisterCapability(SpvCapabilityStorageImageArrayDynamicIndexing);
69   EXPECT_TRUE(state_.HasAnyOfCapabilities({}));
70   state_.RegisterCapability(SpvCapabilityClipDistance);
71   EXPECT_TRUE(state_.HasAnyOfCapabilities({}));
72   state_.RegisterCapability(SpvCapabilityStorageImageWriteWithoutFormat);
73   EXPECT_TRUE(state_.HasAnyOfCapabilities({}));
74 }
75 
TEST_F(ValidationState_HasAnyOfCapabilities,SingleCapMask)76 TEST_F(ValidationState_HasAnyOfCapabilities, SingleCapMask) {
77   EXPECT_FALSE(state_.HasAnyOfCapabilities({SpvCapabilityMatrix}));
78   EXPECT_FALSE(state_.HasAnyOfCapabilities({SpvCapabilityImageMipmap}));
79   state_.RegisterCapability(SpvCapabilityMatrix);
80   EXPECT_TRUE(state_.HasAnyOfCapabilities({SpvCapabilityMatrix}));
81   EXPECT_FALSE(state_.HasAnyOfCapabilities({SpvCapabilityImageMipmap}));
82   state_.RegisterCapability(SpvCapabilityImageMipmap);
83   EXPECT_TRUE(state_.HasAnyOfCapabilities({SpvCapabilityMatrix}));
84   EXPECT_TRUE(state_.HasAnyOfCapabilities({SpvCapabilityImageMipmap}));
85 }
86 
TEST_F(ValidationState_HasAnyOfCapabilities,MultiCapMask)87 TEST_F(ValidationState_HasAnyOfCapabilities, MultiCapMask) {
88   const auto set1 =
89       CapabilitySet{SpvCapabilitySampledRect, SpvCapabilityImageBuffer};
90   const auto set2 = CapabilitySet{SpvCapabilityStorageImageWriteWithoutFormat,
91                                   SpvCapabilityStorageImageReadWithoutFormat,
92                                   SpvCapabilityGeometryStreams};
93   EXPECT_FALSE(state_.HasAnyOfCapabilities(set1));
94   EXPECT_FALSE(state_.HasAnyOfCapabilities(set2));
95   state_.RegisterCapability(SpvCapabilityImageBuffer);
96   EXPECT_TRUE(state_.HasAnyOfCapabilities(set1));
97   EXPECT_FALSE(state_.HasAnyOfCapabilities(set2));
98 }
99 
100 // A test of ValidationState_t::HasAnyOfExtensions().
101 using ValidationState_HasAnyOfExtensions = ValidationStateTest;
102 
TEST_F(ValidationState_HasAnyOfExtensions,EmptyMask)103 TEST_F(ValidationState_HasAnyOfExtensions, EmptyMask) {
104   EXPECT_TRUE(state_.HasAnyOfExtensions({}));
105   state_.RegisterExtension(Extension::kSPV_KHR_shader_ballot);
106   EXPECT_TRUE(state_.HasAnyOfExtensions({}));
107   state_.RegisterExtension(Extension::kSPV_KHR_16bit_storage);
108   EXPECT_TRUE(state_.HasAnyOfExtensions({}));
109   state_.RegisterExtension(Extension::kSPV_NV_viewport_array2);
110   EXPECT_TRUE(state_.HasAnyOfExtensions({}));
111 }
112 
TEST_F(ValidationState_HasAnyOfExtensions,SingleCapMask)113 TEST_F(ValidationState_HasAnyOfExtensions, SingleCapMask) {
114   EXPECT_FALSE(state_.HasAnyOfExtensions({Extension::kSPV_KHR_shader_ballot}));
115   EXPECT_FALSE(state_.HasAnyOfExtensions({Extension::kSPV_KHR_16bit_storage}));
116   state_.RegisterExtension(Extension::kSPV_KHR_shader_ballot);
117   EXPECT_TRUE(state_.HasAnyOfExtensions({Extension::kSPV_KHR_shader_ballot}));
118   EXPECT_FALSE(state_.HasAnyOfExtensions({Extension::kSPV_KHR_16bit_storage}));
119   state_.RegisterExtension(Extension::kSPV_KHR_16bit_storage);
120   EXPECT_TRUE(state_.HasAnyOfExtensions({Extension::kSPV_KHR_shader_ballot}));
121   EXPECT_TRUE(state_.HasAnyOfExtensions({Extension::kSPV_KHR_16bit_storage}));
122 }
123 
TEST_F(ValidationState_HasAnyOfExtensions,MultiCapMask)124 TEST_F(ValidationState_HasAnyOfExtensions, MultiCapMask) {
125   const auto set1 = ExtensionSet{Extension::kSPV_KHR_multiview,
126                                  Extension::kSPV_KHR_16bit_storage};
127   const auto set2 = ExtensionSet{Extension::kSPV_KHR_shader_draw_parameters,
128                                  Extension::kSPV_NV_stereo_view_rendering,
129                                  Extension::kSPV_KHR_shader_ballot};
130   EXPECT_FALSE(state_.HasAnyOfExtensions(set1));
131   EXPECT_FALSE(state_.HasAnyOfExtensions(set2));
132   state_.RegisterExtension(Extension::kSPV_KHR_multiview);
133   EXPECT_TRUE(state_.HasAnyOfExtensions(set1));
134   EXPECT_FALSE(state_.HasAnyOfExtensions(set2));
135 }
136 
137 // A test of ValidationState_t::IsOpcodeInCurrentLayoutSection().
138 using ValidationState_InLayoutState = ValidationStateTest;
139 
TEST_F(ValidationState_InLayoutState,Variable)140 TEST_F(ValidationState_InLayoutState, Variable) {
141   state_.SetCurrentLayoutSectionForTesting(kLayoutTypes);
142   EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpVariable));
143 
144   state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDefinitions);
145   EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpVariable));
146 }
147 
TEST_F(ValidationState_InLayoutState,ExtInst)148 TEST_F(ValidationState_InLayoutState, ExtInst) {
149   state_.SetCurrentLayoutSectionForTesting(kLayoutTypes);
150   EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpExtInst));
151 
152   state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDefinitions);
153   EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpExtInst));
154 }
155 
TEST_F(ValidationState_InLayoutState,Undef)156 TEST_F(ValidationState_InLayoutState, Undef) {
157   state_.SetCurrentLayoutSectionForTesting(kLayoutTypes);
158   EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpUndef));
159 
160   state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDefinitions);
161   EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpUndef));
162 }
163 
TEST_F(ValidationState_InLayoutState,Function)164 TEST_F(ValidationState_InLayoutState, Function) {
165   state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDeclarations);
166   EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpFunction));
167 
168   state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDefinitions);
169   EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpFunction));
170 }
171 
TEST_F(ValidationState_InLayoutState,FunctionParameter)172 TEST_F(ValidationState_InLayoutState, FunctionParameter) {
173   state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDeclarations);
174   EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpFunctionParameter));
175 
176   state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDefinitions);
177   EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpFunctionParameter));
178 }
179 
TEST_F(ValidationState_InLayoutState,FunctionEnd)180 TEST_F(ValidationState_InLayoutState, FunctionEnd) {
181   state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDeclarations);
182   EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpFunctionEnd));
183 
184   state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDefinitions);
185   EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpFunctionEnd));
186 }
187 
188 }  // namespace
189 }  // namespace val
190 }  // namespace spvtools
191