1 // Copyright (c) 2015-2016 The Khronos Group 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 "source/spirv_target_env.h" 16 17 #include <cstring> 18 19 #include "source/spirv_constant.h" 20 #include "spirv-tools/libspirv.h" 21 22 const char* spvTargetEnvDescription(spv_target_env env) { 23 switch (env) { 24 case SPV_ENV_UNIVERSAL_1_0: 25 return "SPIR-V 1.0"; 26 case SPV_ENV_VULKAN_1_0: 27 return "SPIR-V 1.0 (under Vulkan 1.0 semantics)"; 28 case SPV_ENV_UNIVERSAL_1_1: 29 return "SPIR-V 1.1"; 30 case SPV_ENV_OPENCL_1_2: 31 return "SPIR-V 1.0 (under OpenCL 1.2 Full Profile semantics)"; 32 case SPV_ENV_OPENCL_EMBEDDED_1_2: 33 return "SPIR-V 1.0 (under OpenCL 1.2 Embedded Profile semantics)"; 34 case SPV_ENV_OPENCL_2_0: 35 return "SPIR-V 1.0 (under OpenCL 2.0 Full Profile semantics)"; 36 case SPV_ENV_OPENCL_EMBEDDED_2_0: 37 return "SPIR-V 1.0 (under OpenCL 2.0 Embedded Profile semantics)"; 38 case SPV_ENV_OPENCL_2_1: 39 return "SPIR-V 1.0 (under OpenCL 2.1 Full Profile semantics)"; 40 case SPV_ENV_OPENCL_EMBEDDED_2_1: 41 return "SPIR-V 1.0 (under OpenCL 2.1 Embedded Profile semantics)"; 42 case SPV_ENV_OPENCL_2_2: 43 return "SPIR-V 1.2 (under OpenCL 2.2 Full Profile semantics)"; 44 case SPV_ENV_OPENCL_EMBEDDED_2_2: 45 return "SPIR-V 1.2 (under OpenCL 2.2 Embedded Profile semantics)"; 46 case SPV_ENV_OPENGL_4_0: 47 return "SPIR-V 1.0 (under OpenGL 4.0 semantics)"; 48 case SPV_ENV_OPENGL_4_1: 49 return "SPIR-V 1.0 (under OpenGL 4.1 semantics)"; 50 case SPV_ENV_OPENGL_4_2: 51 return "SPIR-V 1.0 (under OpenGL 4.2 semantics)"; 52 case SPV_ENV_OPENGL_4_3: 53 return "SPIR-V 1.0 (under OpenGL 4.3 semantics)"; 54 case SPV_ENV_OPENGL_4_5: 55 return "SPIR-V 1.0 (under OpenGL 4.5 semantics)"; 56 case SPV_ENV_UNIVERSAL_1_2: 57 return "SPIR-V 1.2"; 58 case SPV_ENV_UNIVERSAL_1_3: 59 return "SPIR-V 1.3"; 60 case SPV_ENV_VULKAN_1_1: 61 return "SPIR-V 1.3 (under Vulkan 1.1 semantics)"; 62 case SPV_ENV_WEBGPU_0: 63 return "SPIR-V 1.3 (under WIP WebGPU semantics)"; 64 } 65 return ""; 66 } 67 68 uint32_t spvVersionForTargetEnv(spv_target_env env) { 69 switch (env) { 70 case SPV_ENV_UNIVERSAL_1_0: 71 case SPV_ENV_VULKAN_1_0: 72 case SPV_ENV_OPENCL_1_2: 73 case SPV_ENV_OPENCL_EMBEDDED_1_2: 74 case SPV_ENV_OPENCL_2_0: 75 case SPV_ENV_OPENCL_EMBEDDED_2_0: 76 case SPV_ENV_OPENCL_2_1: 77 case SPV_ENV_OPENCL_EMBEDDED_2_1: 78 case SPV_ENV_OPENGL_4_0: 79 case SPV_ENV_OPENGL_4_1: 80 case SPV_ENV_OPENGL_4_2: 81 case SPV_ENV_OPENGL_4_3: 82 case SPV_ENV_OPENGL_4_5: 83 return SPV_SPIRV_VERSION_WORD(1, 0); 84 case SPV_ENV_UNIVERSAL_1_1: 85 return SPV_SPIRV_VERSION_WORD(1, 1); 86 case SPV_ENV_UNIVERSAL_1_2: 87 case SPV_ENV_OPENCL_2_2: 88 case SPV_ENV_OPENCL_EMBEDDED_2_2: 89 return SPV_SPIRV_VERSION_WORD(1, 2); 90 case SPV_ENV_UNIVERSAL_1_3: 91 case SPV_ENV_VULKAN_1_1: 92 case SPV_ENV_WEBGPU_0: 93 return SPV_SPIRV_VERSION_WORD(1, 3); 94 } 95 return SPV_SPIRV_VERSION_WORD(0, 0); 96 } 97 98 bool spvParseTargetEnv(const char* s, spv_target_env* env) { 99 auto match = [s](const char* b) { 100 return s && (0 == strncmp(s, b, strlen(b))); 101 }; 102 if (match("vulkan1.0")) { 103 if (env) *env = SPV_ENV_VULKAN_1_0; 104 return true; 105 } else if (match("vulkan1.1")) { 106 if (env) *env = SPV_ENV_VULKAN_1_1; 107 return true; 108 } else if (match("spv1.0")) { 109 if (env) *env = SPV_ENV_UNIVERSAL_1_0; 110 return true; 111 } else if (match("spv1.1")) { 112 if (env) *env = SPV_ENV_UNIVERSAL_1_1; 113 return true; 114 } else if (match("spv1.2")) { 115 if (env) *env = SPV_ENV_UNIVERSAL_1_2; 116 return true; 117 } else if (match("spv1.3")) { 118 if (env) *env = SPV_ENV_UNIVERSAL_1_3; 119 return true; 120 } else if (match("opencl1.2embedded")) { 121 if (env) *env = SPV_ENV_OPENCL_EMBEDDED_1_2; 122 return true; 123 } else if (match("opencl1.2")) { 124 if (env) *env = SPV_ENV_OPENCL_1_2; 125 return true; 126 } else if (match("opencl2.0embedded")) { 127 if (env) *env = SPV_ENV_OPENCL_EMBEDDED_2_0; 128 return true; 129 } else if (match("opencl2.0")) { 130 if (env) *env = SPV_ENV_OPENCL_2_0; 131 return true; 132 } else if (match("opencl2.1embedded")) { 133 if (env) *env = SPV_ENV_OPENCL_EMBEDDED_2_1; 134 return true; 135 } else if (match("opencl2.1")) { 136 if (env) *env = SPV_ENV_OPENCL_2_1; 137 return true; 138 } else if (match("opencl2.2embedded")) { 139 if (env) *env = SPV_ENV_OPENCL_EMBEDDED_2_2; 140 return true; 141 } else if (match("opencl2.2")) { 142 if (env) *env = SPV_ENV_OPENCL_2_2; 143 return true; 144 } else if (match("opengl4.0")) { 145 if (env) *env = SPV_ENV_OPENGL_4_0; 146 return true; 147 } else if (match("opengl4.1")) { 148 if (env) *env = SPV_ENV_OPENGL_4_1; 149 return true; 150 } else if (match("opengl4.2")) { 151 if (env) *env = SPV_ENV_OPENGL_4_2; 152 return true; 153 } else if (match("opengl4.3")) { 154 if (env) *env = SPV_ENV_OPENGL_4_3; 155 return true; 156 } else if (match("opengl4.5")) { 157 if (env) *env = SPV_ENV_OPENGL_4_5; 158 return true; 159 } else if (match("webgpu0")) { 160 if (env) *env = SPV_ENV_WEBGPU_0; 161 return true; 162 } else { 163 if (env) *env = SPV_ENV_UNIVERSAL_1_0; 164 return false; 165 } 166 } 167 168 bool spvIsVulkanEnv(spv_target_env env) { 169 switch (env) { 170 case SPV_ENV_UNIVERSAL_1_0: 171 case SPV_ENV_OPENCL_1_2: 172 case SPV_ENV_OPENCL_EMBEDDED_1_2: 173 case SPV_ENV_OPENCL_2_0: 174 case SPV_ENV_OPENCL_EMBEDDED_2_0: 175 case SPV_ENV_OPENCL_2_1: 176 case SPV_ENV_OPENCL_EMBEDDED_2_1: 177 case SPV_ENV_OPENGL_4_0: 178 case SPV_ENV_OPENGL_4_1: 179 case SPV_ENV_OPENGL_4_2: 180 case SPV_ENV_OPENGL_4_3: 181 case SPV_ENV_OPENGL_4_5: 182 case SPV_ENV_UNIVERSAL_1_1: 183 case SPV_ENV_UNIVERSAL_1_2: 184 case SPV_ENV_OPENCL_2_2: 185 case SPV_ENV_OPENCL_EMBEDDED_2_2: 186 case SPV_ENV_UNIVERSAL_1_3: 187 case SPV_ENV_WEBGPU_0: 188 return false; 189 case SPV_ENV_VULKAN_1_0: 190 case SPV_ENV_VULKAN_1_1: 191 return true; 192 } 193 return false; 194 } 195 196 bool spvIsOpenCLEnv(spv_target_env env) { 197 switch (env) { 198 case SPV_ENV_UNIVERSAL_1_0: 199 case SPV_ENV_VULKAN_1_0: 200 case SPV_ENV_UNIVERSAL_1_1: 201 case SPV_ENV_OPENGL_4_0: 202 case SPV_ENV_OPENGL_4_1: 203 case SPV_ENV_OPENGL_4_2: 204 case SPV_ENV_OPENGL_4_3: 205 case SPV_ENV_OPENGL_4_5: 206 case SPV_ENV_UNIVERSAL_1_2: 207 case SPV_ENV_UNIVERSAL_1_3: 208 case SPV_ENV_VULKAN_1_1: 209 case SPV_ENV_WEBGPU_0: 210 return false; 211 case SPV_ENV_OPENCL_1_2: 212 case SPV_ENV_OPENCL_EMBEDDED_1_2: 213 case SPV_ENV_OPENCL_2_0: 214 case SPV_ENV_OPENCL_EMBEDDED_2_0: 215 case SPV_ENV_OPENCL_EMBEDDED_2_1: 216 case SPV_ENV_OPENCL_EMBEDDED_2_2: 217 case SPV_ENV_OPENCL_2_1: 218 case SPV_ENV_OPENCL_2_2: 219 return true; 220 } 221 return false; 222 } 223 224 bool spvIsWebGPUEnv(spv_target_env env) { 225 switch (env) { 226 case SPV_ENV_UNIVERSAL_1_0: 227 case SPV_ENV_VULKAN_1_0: 228 case SPV_ENV_UNIVERSAL_1_1: 229 case SPV_ENV_OPENGL_4_0: 230 case SPV_ENV_OPENGL_4_1: 231 case SPV_ENV_OPENGL_4_2: 232 case SPV_ENV_OPENGL_4_3: 233 case SPV_ENV_OPENGL_4_5: 234 case SPV_ENV_UNIVERSAL_1_2: 235 case SPV_ENV_UNIVERSAL_1_3: 236 case SPV_ENV_VULKAN_1_1: 237 case SPV_ENV_OPENCL_1_2: 238 case SPV_ENV_OPENCL_EMBEDDED_1_2: 239 case SPV_ENV_OPENCL_2_0: 240 case SPV_ENV_OPENCL_EMBEDDED_2_0: 241 case SPV_ENV_OPENCL_EMBEDDED_2_1: 242 case SPV_ENV_OPENCL_EMBEDDED_2_2: 243 case SPV_ENV_OPENCL_2_1: 244 case SPV_ENV_OPENCL_2_2: 245 return false; 246 case SPV_ENV_WEBGPU_0: 247 return true; 248 } 249 return false; 250 } 251