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