1 // Copyright (c) 2017 Google Inc.
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 <algorithm>
16 #include <memory>
17
18 #include "gtest/gtest.h"
19 #include "source/opt/build_module.h"
20 #include "source/opt/ir_context.h"
21
22 namespace spvtools {
23 namespace opt {
24 namespace {
25
26 using FeatureManagerTest = ::testing::Test;
27
TEST_F(FeatureManagerTest,MissingExtension)28 TEST_F(FeatureManagerTest, MissingExtension) {
29 const std::string text = R"(
30 OpCapability Shader
31 OpMemoryModel Logical GLSL450
32 )";
33
34 std::unique_ptr<IRContext> context =
35 BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
36 ASSERT_NE(context, nullptr);
37
38 EXPECT_FALSE(context->get_feature_mgr()->HasExtension(
39 Extension::kSPV_KHR_variable_pointers));
40 }
41
TEST_F(FeatureManagerTest,OneExtension)42 TEST_F(FeatureManagerTest, OneExtension) {
43 const std::string text = R"(
44 OpCapability Shader
45 OpMemoryModel Logical GLSL450
46 OpExtension "SPV_KHR_variable_pointers"
47 )";
48
49 std::unique_ptr<IRContext> context =
50 BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
51 ASSERT_NE(context, nullptr);
52
53 EXPECT_TRUE(context->get_feature_mgr()->HasExtension(
54 Extension::kSPV_KHR_variable_pointers));
55 }
56
TEST_F(FeatureManagerTest,NotADifferentExtension)57 TEST_F(FeatureManagerTest, NotADifferentExtension) {
58 const std::string text = R"(
59 OpCapability Shader
60 OpMemoryModel Logical GLSL450
61 OpExtension "SPV_KHR_variable_pointers"
62 )";
63
64 std::unique_ptr<IRContext> context =
65 BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
66 ASSERT_NE(context, nullptr);
67
68 EXPECT_FALSE(context->get_feature_mgr()->HasExtension(
69 Extension::kSPV_KHR_storage_buffer_storage_class));
70 }
71
TEST_F(FeatureManagerTest,TwoExtensions)72 TEST_F(FeatureManagerTest, TwoExtensions) {
73 const std::string text = R"(
74 OpCapability Shader
75 OpMemoryModel Logical GLSL450
76 OpExtension "SPV_KHR_variable_pointers"
77 OpExtension "SPV_KHR_storage_buffer_storage_class"
78 )";
79
80 std::unique_ptr<IRContext> context =
81 BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
82 ASSERT_NE(context, nullptr);
83
84 EXPECT_TRUE(context->get_feature_mgr()->HasExtension(
85 Extension::kSPV_KHR_variable_pointers));
86 EXPECT_TRUE(context->get_feature_mgr()->HasExtension(
87 Extension::kSPV_KHR_storage_buffer_storage_class));
88 }
89
TEST_F(FeatureManagerTest,GetExtensionsReturnsExtensions)90 TEST_F(FeatureManagerTest, GetExtensionsReturnsExtensions) {
91 const std::string text = R"(
92 OpCapability Shader
93 OpMemoryModel Logical GLSL450
94 OpExtension "SPV_KHR_variable_pointers"
95 OpExtension "SPV_KHR_storage_buffer_storage_class"
96 )";
97
98 std::unique_ptr<IRContext> context =
99 BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
100 ASSERT_NE(context, nullptr);
101
102 const auto& extensions = context->get_feature_mgr()->GetExtensions();
103 EXPECT_EQ(extensions.size(), 2);
104 EXPECT_TRUE(extensions.contains(Extension::kSPV_KHR_variable_pointers));
105 EXPECT_TRUE(
106 extensions.contains(Extension::kSPV_KHR_storage_buffer_storage_class));
107 }
108
109 // Test capability checks.
TEST_F(FeatureManagerTest,ExplicitlyPresent1)110 TEST_F(FeatureManagerTest, ExplicitlyPresent1) {
111 const std::string text = R"(
112 OpCapability Shader
113 OpMemoryModel Logical GLSL450
114 )";
115
116 std::unique_ptr<IRContext> context =
117 BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
118 ASSERT_NE(context, nullptr);
119
120 EXPECT_TRUE(
121 context->get_feature_mgr()->HasCapability(spv::Capability::Shader));
122 EXPECT_FALSE(
123 context->get_feature_mgr()->HasCapability(spv::Capability::Kernel));
124 }
125
TEST_F(FeatureManagerTest,ExplicitlyPresent2)126 TEST_F(FeatureManagerTest, ExplicitlyPresent2) {
127 const std::string text = R"(
128 OpCapability Kernel
129 OpMemoryModel Logical GLSL450
130 )";
131
132 std::unique_ptr<IRContext> context =
133 BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
134 ASSERT_NE(context, nullptr);
135
136 EXPECT_FALSE(
137 context->get_feature_mgr()->HasCapability(spv::Capability::Shader));
138 EXPECT_TRUE(
139 context->get_feature_mgr()->HasCapability(spv::Capability::Kernel));
140 }
141
TEST_F(FeatureManagerTest,ImplicitlyPresent)142 TEST_F(FeatureManagerTest, ImplicitlyPresent) {
143 const std::string text = R"(
144 OpCapability Tessellation
145 OpMemoryModel Logical GLSL450
146 )";
147
148 std::unique_ptr<IRContext> context =
149 BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
150 ASSERT_NE(context, nullptr);
151
152 // Check multiple levels of indirection. Tessellation implies Shader, which
153 // implies Matrix.
154 EXPECT_TRUE(
155 context->get_feature_mgr()->HasCapability(spv::Capability::Tessellation));
156 EXPECT_TRUE(
157 context->get_feature_mgr()->HasCapability(spv::Capability::Shader));
158 EXPECT_TRUE(
159 context->get_feature_mgr()->HasCapability(spv::Capability::Matrix));
160 EXPECT_FALSE(
161 context->get_feature_mgr()->HasCapability(spv::Capability::Kernel));
162 }
163
TEST_F(FeatureManagerTest,GetCapabilitiesReturnsImplicitCapabilities)164 TEST_F(FeatureManagerTest, GetCapabilitiesReturnsImplicitCapabilities) {
165 const std::string text = R"(
166 OpCapability Tessellation
167 OpMemoryModel Logical GLSL450
168 )";
169
170 std::unique_ptr<IRContext> context =
171 BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
172 ASSERT_NE(context, nullptr);
173
174 const auto& capabilities = context->get_feature_mgr()->GetCapabilities();
175 // Tesselation implies Shader, which implies Matrix.
176 EXPECT_EQ(capabilities.size(), 3);
177 EXPECT_TRUE(capabilities.contains(spv::Capability::Tessellation));
178 EXPECT_TRUE(capabilities.contains(spv::Capability::Shader));
179 EXPECT_TRUE(capabilities.contains(spv::Capability::Matrix));
180 }
181
182 } // namespace
183 } // namespace opt
184 } // namespace spvtools
185