#include <algorithm>
#include <memory>
#include "gtest/gtest.h"
#include "source/opt/build_module.h"
#include "source/opt/ir_context.h"
namespace spvtools {
namespace opt {
namespace {
using FeatureManagerTest = ::testing::Test;
TEST_F(FeatureManagerTest, MissingExtension) {
const std::string text = R"(
OpCapability Shader
OpMemoryModel Logical GLSL450
)";
std::unique_ptr<IRContext> context =
BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
ASSERT_NE(context, nullptr);
EXPECT_FALSE(context->get_feature_mgr()->HasExtension(
Extension::kSPV_KHR_variable_pointers));
}
TEST_F(FeatureManagerTest, OneExtension) {
const std::string text = R"(
OpCapability Shader
OpMemoryModel Logical GLSL450
OpExtension "SPV_KHR_variable_pointers"
)";
std::unique_ptr<IRContext> context =
BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
ASSERT_NE(context, nullptr);
EXPECT_TRUE(context->get_feature_mgr()->HasExtension(
Extension::kSPV_KHR_variable_pointers));
}
TEST_F(FeatureManagerTest, NotADifferentExtension) {
const std::string text = R"(
OpCapability Shader
OpMemoryModel Logical GLSL450
OpExtension "SPV_KHR_variable_pointers"
)";
std::unique_ptr<IRContext> context =
BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
ASSERT_NE(context, nullptr);
EXPECT_FALSE(context->get_feature_mgr()->HasExtension(
Extension::kSPV_KHR_storage_buffer_storage_class));
}
TEST_F(FeatureManagerTest, TwoExtensions) {
const std::string text = R"(
OpCapability Shader
OpMemoryModel Logical GLSL450
OpExtension "SPV_KHR_variable_pointers"
OpExtension "SPV_KHR_storage_buffer_storage_class"
)";
std::unique_ptr<IRContext> context =
BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
ASSERT_NE(context, nullptr);
EXPECT_TRUE(context->get_feature_mgr()->HasExtension(
Extension::kSPV_KHR_variable_pointers));
EXPECT_TRUE(context->get_feature_mgr()->HasExtension(
Extension::kSPV_KHR_storage_buffer_storage_class));
}
TEST_F(FeatureManagerTest, GetExtensionsReturnsExtensions) {
const std::string text = R"(
OpCapability Shader
OpMemoryModel Logical GLSL450
OpExtension "SPV_KHR_variable_pointers"
OpExtension "SPV_KHR_storage_buffer_storage_class"
)";
std::unique_ptr<IRContext> context =
BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
ASSERT_NE(context, nullptr);
const auto& extensions = context->get_feature_mgr()->GetExtensions();
EXPECT_EQ(extensions.size(), 2);
EXPECT_TRUE(extensions.contains(Extension::kSPV_KHR_variable_pointers));
EXPECT_TRUE(
extensions.contains(Extension::kSPV_KHR_storage_buffer_storage_class));
}
TEST_F(FeatureManagerTest, ExplicitlyPresent1) {
const std::string text = R"(
OpCapability Shader
OpMemoryModel Logical GLSL450
)";
std::unique_ptr<IRContext> context =
BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
ASSERT_NE(context, nullptr);
EXPECT_TRUE(
context->get_feature_mgr()->HasCapability(spv::Capability::Shader));
EXPECT_FALSE(
context->get_feature_mgr()->HasCapability(spv::Capability::Kernel));
}
TEST_F(FeatureManagerTest, ExplicitlyPresent2) {
const std::string text = R"(
OpCapability Kernel
OpMemoryModel Logical GLSL450
)";
std::unique_ptr<IRContext> context =
BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
ASSERT_NE(context, nullptr);
EXPECT_FALSE(
context->get_feature_mgr()->HasCapability(spv::Capability::Shader));
EXPECT_TRUE(
context->get_feature_mgr()->HasCapability(spv::Capability::Kernel));
}
TEST_F(FeatureManagerTest, ImplicitlyPresent) {
const std::string text = R"(
OpCapability Tessellation
OpMemoryModel Logical GLSL450
)";
std::unique_ptr<IRContext> context =
BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
ASSERT_NE(context, nullptr);
EXPECT_TRUE(
context->get_feature_mgr()->HasCapability(spv::Capability::Tessellation));
EXPECT_TRUE(
context->get_feature_mgr()->HasCapability(spv::Capability::Shader));
EXPECT_TRUE(
context->get_feature_mgr()->HasCapability(spv::Capability::Matrix));
EXPECT_FALSE(
context->get_feature_mgr()->HasCapability(spv::Capability::Kernel));
}
TEST_F(FeatureManagerTest, GetCapabilitiesReturnsImplicitCapabilities) {
const std::string text = R"(
OpCapability Tessellation
OpMemoryModel Logical GLSL450
)";
std::unique_ptr<IRContext> context =
BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
ASSERT_NE(context, nullptr);
const auto& capabilities = context->get_feature_mgr()->GetCapabilities();
EXPECT_EQ(capabilities.size(), 3);
EXPECT_TRUE(capabilities.contains(spv::Capability::Tessellation));
EXPECT_TRUE(capabilities.contains(spv::Capability::Shader));
EXPECT_TRUE(capabilities.contains(spv::Capability::Matrix));
}
TEST_F(FeatureManagerTest, HasConditionalExtension) {
const std::string text = R"(
OpCapability Linkage
OpCapability Shader
OpCapability SpecConditionalINTEL
OpExtension "SPV_INTEL_function_variants"
OpConditionalExtensionINTEL %1 "SPV_KHR_variable_pointers"
OpMemoryModel Logical GLSL450
%bool = OpTypeBool
%1 = OpSpecConstantTrue %bool
)";
std::unique_ptr<IRContext> context =
BuildModule(SPV_ENV_UNIVERSAL_1_6, nullptr, text);
ASSERT_NE(context, nullptr);
EXPECT_TRUE(context->get_feature_mgr()->HasExtension(
Extension::kSPV_KHR_variable_pointers));
}
TEST_F(FeatureManagerTest, HasConditionalCapability) {
const std::string text = R"(
OpCapability Linkage
OpCapability Shader
OpCapability SpecConditionalINTEL
OpConditionalCapabilityINTEL %1 Int8
OpExtension "SPV_INTEL_function_variants"
OpMemoryModel Logical GLSL450
%bool = OpTypeBool
%1 = OpSpecConstantTrue %bool
)";
std::unique_ptr<IRContext> context =
BuildModule(SPV_ENV_UNIVERSAL_1_6, nullptr, text);
ASSERT_NE(context, nullptr);
EXPECT_TRUE(context->get_feature_mgr()->HasCapability(spv::Capability::Int8));
}
}
}
}