1// Copyright (c) 2016 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 <vector> 16 17#include "gmock/gmock.h" 18#include "source/spirv_target_env.h" 19#include "test/unit_spirv.h" 20 21namespace spvtools { 22namespace { 23 24using ::testing::AnyOf; 25using ::testing::Eq; 26using ::testing::StartsWith; 27using ::testing::ValuesIn; 28 29using TargetEnvTest = ::testing::TestWithParam<spv_target_env>; 30TEST_P(TargetEnvTest, CreateContext) { 31 spv_target_env env = GetParam(); 32 spv_context context = spvContextCreate(env); 33 ASSERT_NE(nullptr, context); 34 spvContextDestroy(context); // Avoid leaking 35} 36 37TEST_P(TargetEnvTest, ValidDescription) { 38 const char* description = spvTargetEnvDescription(GetParam()); 39 ASSERT_NE(nullptr, description); 40 ASSERT_THAT(description, StartsWith("SPIR-V ")); 41} 42 43TEST_P(TargetEnvTest, ValidSpirvVersion) { 44 auto spirv_version = spvVersionForTargetEnv(GetParam()); 45 ASSERT_THAT(spirv_version, AnyOf(0x10000, 0x10100, 0x10200, 0x10300)); 46} 47 48INSTANTIATE_TEST_SUITE_P(AllTargetEnvs, TargetEnvTest, 49 ValuesIn(spvtest::AllTargetEnvironments())); 50 51TEST(GetContextTest, InvalidTargetEnvProducesNull) { 52 // Use a value beyond the last valid enum value. 53 spv_context context = spvContextCreate(static_cast<spv_target_env>(30)); 54 EXPECT_EQ(context, nullptr); 55} 56 57// A test case for parsing an environment string. 58struct ParseCase { 59 const char* input; 60 bool success; // Expect to successfully parse? 61 spv_target_env env; // The parsed environment, if successful. 62}; 63 64using TargetParseTest = ::testing::TestWithParam<ParseCase>; 65 66TEST_P(TargetParseTest, Samples) { 67 spv_target_env env; 68 bool parsed = spvParseTargetEnv(GetParam().input, &env); 69 EXPECT_THAT(parsed, Eq(GetParam().success)); 70 if (parsed) { 71 EXPECT_THAT(env, Eq(GetParam().env)); 72 } 73} 74 75INSTANTIATE_TEST_SUITE_P( 76 TargetParsing, TargetParseTest, 77 ValuesIn(std::vector<ParseCase>{ 78 {"spv1.0", true, SPV_ENV_UNIVERSAL_1_0}, 79 {"spv1.1", true, SPV_ENV_UNIVERSAL_1_1}, 80 {"spv1.2", true, SPV_ENV_UNIVERSAL_1_2}, 81 {"spv1.3", true, SPV_ENV_UNIVERSAL_1_3}, 82 {"vulkan1.0", true, SPV_ENV_VULKAN_1_0}, 83 {"vulkan1.1", true, SPV_ENV_VULKAN_1_1}, 84 {"vulkan1.2", true, SPV_ENV_VULKAN_1_2}, 85 {"opencl2.1", true, SPV_ENV_OPENCL_2_1}, 86 {"opencl2.2", true, SPV_ENV_OPENCL_2_2}, 87 {"opengl4.0", true, SPV_ENV_OPENGL_4_0}, 88 {"opengl4.1", true, SPV_ENV_OPENGL_4_1}, 89 {"opengl4.2", true, SPV_ENV_OPENGL_4_2}, 90 {"opengl4.3", true, SPV_ENV_OPENGL_4_3}, 91 {"opengl4.5", true, SPV_ENV_OPENGL_4_5}, 92 {"opencl1.2", true, SPV_ENV_OPENCL_1_2}, 93 {"opencl1.2embedded", true, SPV_ENV_OPENCL_EMBEDDED_1_2}, 94 {"opencl2.0", true, SPV_ENV_OPENCL_2_0}, 95 {"opencl2.0embedded", true, SPV_ENV_OPENCL_EMBEDDED_2_0}, 96 {"opencl2.1embedded", true, SPV_ENV_OPENCL_EMBEDDED_2_1}, 97 {"opencl2.2embedded", true, SPV_ENV_OPENCL_EMBEDDED_2_2}, 98 {"opencl2.3", false, SPV_ENV_UNIVERSAL_1_0}, 99 {"opencl3.0", false, SPV_ENV_UNIVERSAL_1_0}, 100 {"vulkan1.9", false, SPV_ENV_UNIVERSAL_1_0}, 101 {"vulkan2.0", false, SPV_ENV_UNIVERSAL_1_0}, 102 {nullptr, false, SPV_ENV_UNIVERSAL_1_0}, 103 {"", false, SPV_ENV_UNIVERSAL_1_0}, 104 {"abc", false, SPV_ENV_UNIVERSAL_1_0}, 105 })); 106 107// A test case for parsing an environment string. 108struct ParseVulkanCase { 109 uint32_t vulkan; 110 uint32_t spirv; 111 bool success; // Expect to successfully parse? 112 spv_target_env env; // The parsed environment, if successful. 113}; 114 115using TargetParseVulkanTest = ::testing::TestWithParam<ParseVulkanCase>; 116 117TEST_P(TargetParseVulkanTest, Samples) { 118 spv_target_env env; 119 bool parsed = spvParseVulkanEnv(GetParam().vulkan, GetParam().spirv, &env); 120 EXPECT_THAT(parsed, Eq(GetParam().success)); 121 if (parsed) { 122 EXPECT_THAT(env, Eq(GetParam().env)); 123 } 124} 125 126#define VK(MAJ, MIN) ((MAJ << 22) | (MIN << 12)) 127#define SPV(MAJ, MIN) ((MAJ << 16) | (MIN << 8)) 128INSTANTIATE_TEST_SUITE_P( 129 TargetVulkanParsing, TargetParseVulkanTest, 130 ValuesIn(std::vector<ParseVulkanCase>{ 131 // Vulkan 1.0 cases 132 {VK(1, 0), SPV(1, 0), true, SPV_ENV_VULKAN_1_0}, 133 {VK(1, 0), SPV(1, 1), true, SPV_ENV_VULKAN_1_1}, 134 {VK(1, 0), SPV(1, 2), true, SPV_ENV_VULKAN_1_1}, 135 {VK(1, 0), SPV(1, 3), true, SPV_ENV_VULKAN_1_1}, 136 {VK(1, 0), SPV(1, 4), true, SPV_ENV_VULKAN_1_1_SPIRV_1_4}, 137 {VK(1, 0), SPV(1, 5), true, SPV_ENV_VULKAN_1_2}, 138 {VK(1, 0), SPV(1, 6), true, SPV_ENV_VULKAN_1_3}, 139 {VK(1, 0), SPV(1, 7), false, SPV_ENV_UNIVERSAL_1_0}, 140 // Vulkan 1.1 cases 141 {VK(1, 1), SPV(1, 0), true, SPV_ENV_VULKAN_1_1}, 142 {VK(1, 1), SPV(1, 1), true, SPV_ENV_VULKAN_1_1}, 143 {VK(1, 1), SPV(1, 2), true, SPV_ENV_VULKAN_1_1}, 144 {VK(1, 1), SPV(1, 3), true, SPV_ENV_VULKAN_1_1}, 145 {VK(1, 1), SPV(1, 4), true, SPV_ENV_VULKAN_1_1_SPIRV_1_4}, 146 {VK(1, 1), SPV(1, 5), true, SPV_ENV_VULKAN_1_2}, 147 {VK(1, 1), SPV(1, 6), true, SPV_ENV_VULKAN_1_3}, 148 {VK(1, 1), SPV(1, 7), false, SPV_ENV_UNIVERSAL_1_0}, 149 // Vulkan 1.2 cases 150 {VK(1, 2), SPV(1, 0), true, SPV_ENV_VULKAN_1_2}, 151 {VK(1, 2), SPV(1, 1), true, SPV_ENV_VULKAN_1_2}, 152 {VK(1, 2), SPV(1, 2), true, SPV_ENV_VULKAN_1_2}, 153 {VK(1, 2), SPV(1, 3), true, SPV_ENV_VULKAN_1_2}, 154 {VK(1, 2), SPV(1, 4), true, SPV_ENV_VULKAN_1_2}, 155 {VK(1, 2), SPV(1, 5), true, SPV_ENV_VULKAN_1_2}, 156 {VK(1, 2), SPV(1, 6), true, SPV_ENV_VULKAN_1_3}, 157 {VK(1, 2), SPV(1, 7), false, SPV_ENV_UNIVERSAL_1_0}, 158 // Vulkan 1.3 cases 159 {VK(1, 3), SPV(1, 0), true, SPV_ENV_VULKAN_1_3}, 160 {VK(1, 3), SPV(1, 1), true, SPV_ENV_VULKAN_1_3}, 161 {VK(1, 3), SPV(1, 2), true, SPV_ENV_VULKAN_1_3}, 162 {VK(1, 3), SPV(1, 3), true, SPV_ENV_VULKAN_1_3}, 163 {VK(1, 3), SPV(1, 4), true, SPV_ENV_VULKAN_1_3}, 164 {VK(1, 3), SPV(1, 5), true, SPV_ENV_VULKAN_1_3}, 165 {VK(1, 3), SPV(1, 6), true, SPV_ENV_VULKAN_1_3}, 166 {VK(1, 3), SPV(1, 7), false, SPV_ENV_UNIVERSAL_1_0}, 167 // Vulkan 2.0 cases 168 {VK(2, 0), SPV(1, 0), false, SPV_ENV_UNIVERSAL_1_0}, 169 // Vulkan 99.0 cases 170 {VK(99, 0), SPV(1, 0), false, SPV_ENV_UNIVERSAL_1_0}, 171 })); 172 173} // namespace 174} // namespace spvtools 175