spirv_target_env.cpp 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  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. #include "source/spirv_target_env.h"
  15. #include <cstring>
  16. #include <string>
  17. #include "source/spirv_constant.h"
  18. #include "spirv-tools/libspirv.h"
  19. const char* spvTargetEnvDescription(spv_target_env env) {
  20. switch (env) {
  21. case SPV_ENV_UNIVERSAL_1_0:
  22. return "SPIR-V 1.0";
  23. case SPV_ENV_VULKAN_1_0:
  24. return "SPIR-V 1.0 (under Vulkan 1.0 semantics)";
  25. case SPV_ENV_UNIVERSAL_1_1:
  26. return "SPIR-V 1.1";
  27. case SPV_ENV_OPENCL_1_2:
  28. return "SPIR-V 1.0 (under OpenCL 1.2 Full Profile semantics)";
  29. case SPV_ENV_OPENCL_EMBEDDED_1_2:
  30. return "SPIR-V 1.0 (under OpenCL 1.2 Embedded Profile semantics)";
  31. case SPV_ENV_OPENCL_2_0:
  32. return "SPIR-V 1.0 (under OpenCL 2.0 Full Profile semantics)";
  33. case SPV_ENV_OPENCL_EMBEDDED_2_0:
  34. return "SPIR-V 1.0 (under OpenCL 2.0 Embedded Profile semantics)";
  35. case SPV_ENV_OPENCL_2_1:
  36. return "SPIR-V 1.0 (under OpenCL 2.1 Full Profile semantics)";
  37. case SPV_ENV_OPENCL_EMBEDDED_2_1:
  38. return "SPIR-V 1.0 (under OpenCL 2.1 Embedded Profile semantics)";
  39. case SPV_ENV_OPENCL_2_2:
  40. return "SPIR-V 1.2 (under OpenCL 2.2 Full Profile semantics)";
  41. case SPV_ENV_OPENCL_EMBEDDED_2_2:
  42. return "SPIR-V 1.2 (under OpenCL 2.2 Embedded Profile semantics)";
  43. case SPV_ENV_OPENGL_4_0:
  44. return "SPIR-V 1.0 (under OpenGL 4.0 semantics)";
  45. case SPV_ENV_OPENGL_4_1:
  46. return "SPIR-V 1.0 (under OpenGL 4.1 semantics)";
  47. case SPV_ENV_OPENGL_4_2:
  48. return "SPIR-V 1.0 (under OpenGL 4.2 semantics)";
  49. case SPV_ENV_OPENGL_4_3:
  50. return "SPIR-V 1.0 (under OpenGL 4.3 semantics)";
  51. case SPV_ENV_OPENGL_4_5:
  52. return "SPIR-V 1.0 (under OpenGL 4.5 semantics)";
  53. case SPV_ENV_UNIVERSAL_1_2:
  54. return "SPIR-V 1.2";
  55. case SPV_ENV_UNIVERSAL_1_3:
  56. return "SPIR-V 1.3";
  57. case SPV_ENV_VULKAN_1_1:
  58. return "SPIR-V 1.3 (under Vulkan 1.1 semantics)";
  59. case SPV_ENV_WEBGPU_0:
  60. return "SPIR-V 1.3 (under WIP WebGPU semantics)";
  61. case SPV_ENV_UNIVERSAL_1_4:
  62. return "SPIR-V 1.4";
  63. case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
  64. return "SPIR-V 1.4 (under Vulkan 1.1 semantics)";
  65. }
  66. return "";
  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. case SPV_ENV_UNIVERSAL_1_4:
  95. case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
  96. return SPV_SPIRV_VERSION_WORD(1, 4);
  97. }
  98. return SPV_SPIRV_VERSION_WORD(0, 0);
  99. }
  100. static const std::pair<const char*, spv_target_env> spvTargetEnvNameMap[] = {
  101. {"vulkan1.1spv1.4", SPV_ENV_VULKAN_1_1_SPIRV_1_4},
  102. {"vulkan1.0", SPV_ENV_VULKAN_1_0},
  103. {"vulkan1.1", SPV_ENV_VULKAN_1_1},
  104. {"spv1.0", SPV_ENV_UNIVERSAL_1_0},
  105. {"spv1.1", SPV_ENV_UNIVERSAL_1_1},
  106. {"spv1.2", SPV_ENV_UNIVERSAL_1_2},
  107. {"spv1.3", SPV_ENV_UNIVERSAL_1_3},
  108. {"spv1.4", SPV_ENV_UNIVERSAL_1_4},
  109. {"opencl1.2embedded", SPV_ENV_OPENCL_EMBEDDED_1_2},
  110. {"opencl1.2", SPV_ENV_OPENCL_1_2},
  111. {"opencl2.0embedded", SPV_ENV_OPENCL_EMBEDDED_2_0},
  112. {"opencl2.0", SPV_ENV_OPENCL_2_0},
  113. {"opencl2.1embedded", SPV_ENV_OPENCL_EMBEDDED_2_1},
  114. {"opencl2.1", SPV_ENV_OPENCL_2_1},
  115. {"opencl2.2embedded", SPV_ENV_OPENCL_EMBEDDED_2_2},
  116. {"opencl2.2", SPV_ENV_OPENCL_2_2},
  117. {"opengl4.0", SPV_ENV_OPENGL_4_0},
  118. {"opengl4.1", SPV_ENV_OPENGL_4_1},
  119. {"opengl4.2", SPV_ENV_OPENGL_4_2},
  120. {"opengl4.3", SPV_ENV_OPENGL_4_3},
  121. {"opengl4.5", SPV_ENV_OPENGL_4_5},
  122. {"webgpu0", SPV_ENV_WEBGPU_0},
  123. };
  124. bool spvParseTargetEnv(const char* s, spv_target_env* env) {
  125. auto match = [s](const char* b) {
  126. return s && (0 == strncmp(s, b, strlen(b)));
  127. };
  128. for (auto& name_env : spvTargetEnvNameMap) {
  129. if (match(name_env.first)) {
  130. if (env) {
  131. *env = name_env.second;
  132. }
  133. return true;
  134. }
  135. }
  136. if (env) *env = SPV_ENV_UNIVERSAL_1_0;
  137. return false;
  138. }
  139. bool spvIsVulkanEnv(spv_target_env env) {
  140. switch (env) {
  141. case SPV_ENV_UNIVERSAL_1_0:
  142. case SPV_ENV_OPENCL_1_2:
  143. case SPV_ENV_OPENCL_EMBEDDED_1_2:
  144. case SPV_ENV_OPENCL_2_0:
  145. case SPV_ENV_OPENCL_EMBEDDED_2_0:
  146. case SPV_ENV_OPENCL_2_1:
  147. case SPV_ENV_OPENCL_EMBEDDED_2_1:
  148. case SPV_ENV_OPENGL_4_0:
  149. case SPV_ENV_OPENGL_4_1:
  150. case SPV_ENV_OPENGL_4_2:
  151. case SPV_ENV_OPENGL_4_3:
  152. case SPV_ENV_OPENGL_4_5:
  153. case SPV_ENV_UNIVERSAL_1_1:
  154. case SPV_ENV_UNIVERSAL_1_2:
  155. case SPV_ENV_OPENCL_2_2:
  156. case SPV_ENV_OPENCL_EMBEDDED_2_2:
  157. case SPV_ENV_UNIVERSAL_1_3:
  158. case SPV_ENV_WEBGPU_0:
  159. case SPV_ENV_UNIVERSAL_1_4:
  160. return false;
  161. case SPV_ENV_VULKAN_1_0:
  162. case SPV_ENV_VULKAN_1_1:
  163. case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
  164. return true;
  165. }
  166. return false;
  167. }
  168. bool spvIsOpenCLEnv(spv_target_env env) {
  169. switch (env) {
  170. case SPV_ENV_UNIVERSAL_1_0:
  171. case SPV_ENV_VULKAN_1_0:
  172. case SPV_ENV_UNIVERSAL_1_1:
  173. case SPV_ENV_OPENGL_4_0:
  174. case SPV_ENV_OPENGL_4_1:
  175. case SPV_ENV_OPENGL_4_2:
  176. case SPV_ENV_OPENGL_4_3:
  177. case SPV_ENV_OPENGL_4_5:
  178. case SPV_ENV_UNIVERSAL_1_2:
  179. case SPV_ENV_UNIVERSAL_1_3:
  180. case SPV_ENV_VULKAN_1_1:
  181. case SPV_ENV_WEBGPU_0:
  182. case SPV_ENV_UNIVERSAL_1_4:
  183. case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
  184. return false;
  185. case SPV_ENV_OPENCL_1_2:
  186. case SPV_ENV_OPENCL_EMBEDDED_1_2:
  187. case SPV_ENV_OPENCL_2_0:
  188. case SPV_ENV_OPENCL_EMBEDDED_2_0:
  189. case SPV_ENV_OPENCL_EMBEDDED_2_1:
  190. case SPV_ENV_OPENCL_EMBEDDED_2_2:
  191. case SPV_ENV_OPENCL_2_1:
  192. case SPV_ENV_OPENCL_2_2:
  193. return true;
  194. }
  195. return false;
  196. }
  197. bool spvIsWebGPUEnv(spv_target_env env) {
  198. switch (env) {
  199. case SPV_ENV_UNIVERSAL_1_0:
  200. case SPV_ENV_VULKAN_1_0:
  201. case SPV_ENV_UNIVERSAL_1_1:
  202. case SPV_ENV_OPENGL_4_0:
  203. case SPV_ENV_OPENGL_4_1:
  204. case SPV_ENV_OPENGL_4_2:
  205. case SPV_ENV_OPENGL_4_3:
  206. case SPV_ENV_OPENGL_4_5:
  207. case SPV_ENV_UNIVERSAL_1_2:
  208. case SPV_ENV_UNIVERSAL_1_3:
  209. case SPV_ENV_VULKAN_1_1:
  210. case SPV_ENV_OPENCL_1_2:
  211. case SPV_ENV_OPENCL_EMBEDDED_1_2:
  212. case SPV_ENV_OPENCL_2_0:
  213. case SPV_ENV_OPENCL_EMBEDDED_2_0:
  214. case SPV_ENV_OPENCL_EMBEDDED_2_1:
  215. case SPV_ENV_OPENCL_EMBEDDED_2_2:
  216. case SPV_ENV_OPENCL_2_1:
  217. case SPV_ENV_OPENCL_2_2:
  218. case SPV_ENV_UNIVERSAL_1_4:
  219. case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
  220. return false;
  221. case SPV_ENV_WEBGPU_0:
  222. return true;
  223. }
  224. return false;
  225. }
  226. bool spvIsOpenGLEnv(spv_target_env env) {
  227. switch (env) {
  228. case SPV_ENV_UNIVERSAL_1_0:
  229. case SPV_ENV_VULKAN_1_0:
  230. case SPV_ENV_UNIVERSAL_1_1:
  231. case SPV_ENV_UNIVERSAL_1_2:
  232. case SPV_ENV_UNIVERSAL_1_3:
  233. case SPV_ENV_VULKAN_1_1:
  234. case SPV_ENV_OPENCL_1_2:
  235. case SPV_ENV_OPENCL_EMBEDDED_1_2:
  236. case SPV_ENV_OPENCL_2_0:
  237. case SPV_ENV_OPENCL_EMBEDDED_2_0:
  238. case SPV_ENV_OPENCL_EMBEDDED_2_1:
  239. case SPV_ENV_OPENCL_EMBEDDED_2_2:
  240. case SPV_ENV_OPENCL_2_1:
  241. case SPV_ENV_OPENCL_2_2:
  242. case SPV_ENV_WEBGPU_0:
  243. case SPV_ENV_UNIVERSAL_1_4:
  244. case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
  245. return false;
  246. case SPV_ENV_OPENGL_4_0:
  247. case SPV_ENV_OPENGL_4_1:
  248. case SPV_ENV_OPENGL_4_2:
  249. case SPV_ENV_OPENGL_4_3:
  250. case SPV_ENV_OPENGL_4_5:
  251. return true;
  252. }
  253. return false;
  254. }
  255. bool spvIsVulkanOrWebGPUEnv(spv_target_env env) {
  256. return spvIsVulkanEnv(env) || spvIsWebGPUEnv(env);
  257. }
  258. std::string spvLogStringForEnv(spv_target_env env) {
  259. switch (env) {
  260. case SPV_ENV_OPENCL_1_2:
  261. case SPV_ENV_OPENCL_2_0:
  262. case SPV_ENV_OPENCL_2_1:
  263. case SPV_ENV_OPENCL_2_2:
  264. case SPV_ENV_OPENCL_EMBEDDED_1_2:
  265. case SPV_ENV_OPENCL_EMBEDDED_2_0:
  266. case SPV_ENV_OPENCL_EMBEDDED_2_1:
  267. case SPV_ENV_OPENCL_EMBEDDED_2_2: {
  268. return "OpenCL";
  269. }
  270. case SPV_ENV_OPENGL_4_0:
  271. case SPV_ENV_OPENGL_4_1:
  272. case SPV_ENV_OPENGL_4_2:
  273. case SPV_ENV_OPENGL_4_3:
  274. case SPV_ENV_OPENGL_4_5: {
  275. return "OpenGL";
  276. }
  277. case SPV_ENV_VULKAN_1_0:
  278. case SPV_ENV_VULKAN_1_1:
  279. case SPV_ENV_VULKAN_1_1_SPIRV_1_4: {
  280. return "Vulkan";
  281. }
  282. case SPV_ENV_WEBGPU_0: {
  283. return "WebGPU";
  284. }
  285. case SPV_ENV_UNIVERSAL_1_0:
  286. case SPV_ENV_UNIVERSAL_1_1:
  287. case SPV_ENV_UNIVERSAL_1_2:
  288. case SPV_ENV_UNIVERSAL_1_3:
  289. case SPV_ENV_UNIVERSAL_1_4: {
  290. return "Universal";
  291. }
  292. }
  293. return "Unknown";
  294. }
  295. std::string spvTargetEnvList(const int pad, const int wrap) {
  296. std::string ret;
  297. size_t max_line_len = wrap - pad; // The first line isn't padded
  298. std::string line;
  299. std::string sep = "";
  300. for (auto& name_env : spvTargetEnvNameMap) {
  301. std::string word = sep + name_env.first;
  302. if (line.length() + word.length() > max_line_len) {
  303. // Adding one word wouldn't fit, commit the line in progress and
  304. // start a new one.
  305. ret += line + "\n";
  306. line.assign(pad, ' ');
  307. // The first line is done. The max length now comprises the
  308. // padding.
  309. max_line_len = wrap;
  310. }
  311. line += word;
  312. sep = "|";
  313. }
  314. ret += line;
  315. return ret;
  316. }