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