1 // Copyright (c) 2015-2016 The Khronos Group Inc.
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
15 #include "source/spirv_target_env.h"
22 #include "source/spirv_constant.h"
23 #include "spirv-tools/libspirv.h"
25 const char* spvTargetEnvDescription(spv_target_env env
) {
27 case SPV_ENV_UNIVERSAL_1_0
:
29 case SPV_ENV_VULKAN_1_0
:
30 return "SPIR-V 1.0 (under Vulkan 1.0 semantics)";
31 case SPV_ENV_UNIVERSAL_1_1
:
33 case SPV_ENV_OPENCL_1_2
:
34 return "SPIR-V 1.0 (under OpenCL 1.2 Full Profile semantics)";
35 case SPV_ENV_OPENCL_EMBEDDED_1_2
:
36 return "SPIR-V 1.0 (under OpenCL 1.2 Embedded Profile semantics)";
37 case SPV_ENV_OPENCL_2_0
:
38 return "SPIR-V 1.0 (under OpenCL 2.0 Full Profile semantics)";
39 case SPV_ENV_OPENCL_EMBEDDED_2_0
:
40 return "SPIR-V 1.0 (under OpenCL 2.0 Embedded Profile semantics)";
41 case SPV_ENV_OPENCL_2_1
:
42 return "SPIR-V 1.0 (under OpenCL 2.1 Full Profile semantics)";
43 case SPV_ENV_OPENCL_EMBEDDED_2_1
:
44 return "SPIR-V 1.0 (under OpenCL 2.1 Embedded Profile semantics)";
45 case SPV_ENV_OPENCL_2_2
:
46 return "SPIR-V 1.2 (under OpenCL 2.2 Full Profile semantics)";
47 case SPV_ENV_OPENCL_EMBEDDED_2_2
:
48 return "SPIR-V 1.2 (under OpenCL 2.2 Embedded Profile semantics)";
49 case SPV_ENV_OPENGL_4_0
:
50 return "SPIR-V 1.0 (under OpenGL 4.0 semantics)";
51 case SPV_ENV_OPENGL_4_1
:
52 return "SPIR-V 1.0 (under OpenGL 4.1 semantics)";
53 case SPV_ENV_OPENGL_4_2
:
54 return "SPIR-V 1.0 (under OpenGL 4.2 semantics)";
55 case SPV_ENV_OPENGL_4_3
:
56 return "SPIR-V 1.0 (under OpenGL 4.3 semantics)";
57 case SPV_ENV_OPENGL_4_5
:
58 return "SPIR-V 1.0 (under OpenGL 4.5 semantics)";
59 case SPV_ENV_UNIVERSAL_1_2
:
61 case SPV_ENV_UNIVERSAL_1_3
:
63 case SPV_ENV_VULKAN_1_1
:
64 return "SPIR-V 1.3 (under Vulkan 1.1 semantics)";
65 case SPV_ENV_WEBGPU_0
:
66 assert(false && "Deprecated target environment value.");
68 case SPV_ENV_UNIVERSAL_1_4
:
70 case SPV_ENV_VULKAN_1_1_SPIRV_1_4
:
71 return "SPIR-V 1.4 (under Vulkan 1.1 semantics)";
72 case SPV_ENV_UNIVERSAL_1_5
:
74 case SPV_ENV_VULKAN_1_2
:
75 return "SPIR-V 1.5 (under Vulkan 1.2 semantics)";
76 case SPV_ENV_UNIVERSAL_1_6
:
78 case SPV_ENV_VULKAN_1_3
:
79 return "SPIR-V 1.6 (under Vulkan 1.3 semantics)";
81 assert(false && "Invalid target environment value.");
87 uint32_t spvVersionForTargetEnv(spv_target_env env
) {
89 case SPV_ENV_UNIVERSAL_1_0
:
90 case SPV_ENV_VULKAN_1_0
:
91 case SPV_ENV_OPENCL_1_2
:
92 case SPV_ENV_OPENCL_EMBEDDED_1_2
:
93 case SPV_ENV_OPENCL_2_0
:
94 case SPV_ENV_OPENCL_EMBEDDED_2_0
:
95 case SPV_ENV_OPENCL_2_1
:
96 case SPV_ENV_OPENCL_EMBEDDED_2_1
:
97 case SPV_ENV_OPENGL_4_0
:
98 case SPV_ENV_OPENGL_4_1
:
99 case SPV_ENV_OPENGL_4_2
:
100 case SPV_ENV_OPENGL_4_3
:
101 case SPV_ENV_OPENGL_4_5
:
102 return SPV_SPIRV_VERSION_WORD(1, 0);
103 case SPV_ENV_UNIVERSAL_1_1
:
104 return SPV_SPIRV_VERSION_WORD(1, 1);
105 case SPV_ENV_UNIVERSAL_1_2
:
106 case SPV_ENV_OPENCL_2_2
:
107 case SPV_ENV_OPENCL_EMBEDDED_2_2
:
108 return SPV_SPIRV_VERSION_WORD(1, 2);
109 case SPV_ENV_UNIVERSAL_1_3
:
110 case SPV_ENV_VULKAN_1_1
:
111 return SPV_SPIRV_VERSION_WORD(1, 3);
112 case SPV_ENV_WEBGPU_0
:
113 assert(false && "Deprecated target environment value.");
115 case SPV_ENV_UNIVERSAL_1_4
:
116 case SPV_ENV_VULKAN_1_1_SPIRV_1_4
:
117 return SPV_SPIRV_VERSION_WORD(1, 4);
118 case SPV_ENV_UNIVERSAL_1_5
:
119 case SPV_ENV_VULKAN_1_2
:
120 return SPV_SPIRV_VERSION_WORD(1, 5);
121 case SPV_ENV_UNIVERSAL_1_6
:
122 case SPV_ENV_VULKAN_1_3
:
123 return SPV_SPIRV_VERSION_WORD(1, 6);
125 assert(false && "Invalid target environment value.");
128 return SPV_SPIRV_VERSION_WORD(0, 0);
131 static const std::pair
<const char*, spv_target_env
> spvTargetEnvNameMap
[] = {
132 {"vulkan1.1spv1.4", SPV_ENV_VULKAN_1_1_SPIRV_1_4
},
133 {"vulkan1.0", SPV_ENV_VULKAN_1_0
},
134 {"vulkan1.1", SPV_ENV_VULKAN_1_1
},
135 {"vulkan1.2", SPV_ENV_VULKAN_1_2
},
136 {"vulkan1.3", SPV_ENV_VULKAN_1_3
},
137 {"spv1.0", SPV_ENV_UNIVERSAL_1_0
},
138 {"spv1.1", SPV_ENV_UNIVERSAL_1_1
},
139 {"spv1.2", SPV_ENV_UNIVERSAL_1_2
},
140 {"spv1.3", SPV_ENV_UNIVERSAL_1_3
},
141 {"spv1.4", SPV_ENV_UNIVERSAL_1_4
},
142 {"spv1.5", SPV_ENV_UNIVERSAL_1_5
},
143 {"spv1.6", SPV_ENV_UNIVERSAL_1_6
},
144 {"opencl1.2embedded", SPV_ENV_OPENCL_EMBEDDED_1_2
},
145 {"opencl1.2", SPV_ENV_OPENCL_1_2
},
146 {"opencl2.0embedded", SPV_ENV_OPENCL_EMBEDDED_2_0
},
147 {"opencl2.0", SPV_ENV_OPENCL_2_0
},
148 {"opencl2.1embedded", SPV_ENV_OPENCL_EMBEDDED_2_1
},
149 {"opencl2.1", SPV_ENV_OPENCL_2_1
},
150 {"opencl2.2embedded", SPV_ENV_OPENCL_EMBEDDED_2_2
},
151 {"opencl2.2", SPV_ENV_OPENCL_2_2
},
152 {"opengl4.0", SPV_ENV_OPENGL_4_0
},
153 {"opengl4.1", SPV_ENV_OPENGL_4_1
},
154 {"opengl4.2", SPV_ENV_OPENGL_4_2
},
155 {"opengl4.3", SPV_ENV_OPENGL_4_3
},
156 {"opengl4.5", SPV_ENV_OPENGL_4_5
},
159 bool spvParseTargetEnv(const char* s
, spv_target_env
* env
) {
160 auto match
= [s
](const char* b
) {
161 return s
&& (0 == strncmp(s
, b
, strlen(b
)));
163 for (auto& name_env
: spvTargetEnvNameMap
) {
164 if (match(name_env
.first
)) {
166 *env
= name_env
.second
;
171 if (env
) *env
= SPV_ENV_UNIVERSAL_1_0
;
175 #define VULKAN_VER(MAJOR, MINOR) ((MAJOR << 22) | (MINOR << 12))
176 #define SPIRV_VER(MAJOR, MINOR) ((MAJOR << 16) | (MINOR << 8))
179 spv_target_env vulkan_env
;
183 // Maps each Vulkan target environment enum to the Vulkan version, and the
184 // maximum supported SPIR-V version for that Vulkan environment.
185 // Keep this ordered from least capable to most capable.
186 static const VulkanEnv ordered_vulkan_envs
[] = {
187 {SPV_ENV_VULKAN_1_0
, VULKAN_VER(1, 0), SPIRV_VER(1, 0)},
188 {SPV_ENV_VULKAN_1_1
, VULKAN_VER(1, 1), SPIRV_VER(1, 3)},
189 {SPV_ENV_VULKAN_1_1_SPIRV_1_4
, VULKAN_VER(1, 1), SPIRV_VER(1, 4)},
190 {SPV_ENV_VULKAN_1_2
, VULKAN_VER(1, 2), SPIRV_VER(1, 5)},
191 {SPV_ENV_VULKAN_1_3
, VULKAN_VER(1, 3), SPIRV_VER(1, 6)}};
193 bool spvParseVulkanEnv(uint32_t vulkan_ver
, uint32_t spirv_ver
,
194 spv_target_env
* env
) {
195 for (auto triple
: ordered_vulkan_envs
) {
196 if (triple
.vulkan_ver
>= vulkan_ver
&& triple
.spirv_ver
>= spirv_ver
) {
197 *env
= triple
.vulkan_env
;
204 bool spvIsVulkanEnv(spv_target_env env
) {
206 case SPV_ENV_UNIVERSAL_1_0
:
207 case SPV_ENV_OPENCL_1_2
:
208 case SPV_ENV_OPENCL_EMBEDDED_1_2
:
209 case SPV_ENV_OPENCL_2_0
:
210 case SPV_ENV_OPENCL_EMBEDDED_2_0
:
211 case SPV_ENV_OPENCL_2_1
:
212 case SPV_ENV_OPENCL_EMBEDDED_2_1
:
213 case SPV_ENV_OPENGL_4_0
:
214 case SPV_ENV_OPENGL_4_1
:
215 case SPV_ENV_OPENGL_4_2
:
216 case SPV_ENV_OPENGL_4_3
:
217 case SPV_ENV_OPENGL_4_5
:
218 case SPV_ENV_UNIVERSAL_1_1
:
219 case SPV_ENV_UNIVERSAL_1_2
:
220 case SPV_ENV_OPENCL_2_2
:
221 case SPV_ENV_OPENCL_EMBEDDED_2_2
:
222 case SPV_ENV_UNIVERSAL_1_3
:
223 case SPV_ENV_UNIVERSAL_1_4
:
224 case SPV_ENV_UNIVERSAL_1_5
:
225 case SPV_ENV_UNIVERSAL_1_6
:
227 case SPV_ENV_VULKAN_1_0
:
228 case SPV_ENV_VULKAN_1_1
:
229 case SPV_ENV_VULKAN_1_1_SPIRV_1_4
:
230 case SPV_ENV_VULKAN_1_2
:
231 case SPV_ENV_VULKAN_1_3
:
233 case SPV_ENV_WEBGPU_0
:
234 assert(false && "Deprecated target environment value.");
237 assert(false && "Invalid target environment value.");
243 bool spvIsOpenCLEnv(spv_target_env env
) {
245 case SPV_ENV_UNIVERSAL_1_0
:
246 case SPV_ENV_VULKAN_1_0
:
247 case SPV_ENV_UNIVERSAL_1_1
:
248 case SPV_ENV_OPENGL_4_0
:
249 case SPV_ENV_OPENGL_4_1
:
250 case SPV_ENV_OPENGL_4_2
:
251 case SPV_ENV_OPENGL_4_3
:
252 case SPV_ENV_OPENGL_4_5
:
253 case SPV_ENV_UNIVERSAL_1_2
:
254 case SPV_ENV_UNIVERSAL_1_3
:
255 case SPV_ENV_VULKAN_1_1
:
256 case SPV_ENV_UNIVERSAL_1_4
:
257 case SPV_ENV_VULKAN_1_1_SPIRV_1_4
:
258 case SPV_ENV_UNIVERSAL_1_5
:
259 case SPV_ENV_VULKAN_1_2
:
260 case SPV_ENV_UNIVERSAL_1_6
:
261 case SPV_ENV_VULKAN_1_3
:
263 case SPV_ENV_OPENCL_1_2
:
264 case SPV_ENV_OPENCL_EMBEDDED_1_2
:
265 case SPV_ENV_OPENCL_2_0
:
266 case SPV_ENV_OPENCL_EMBEDDED_2_0
:
267 case SPV_ENV_OPENCL_EMBEDDED_2_1
:
268 case SPV_ENV_OPENCL_EMBEDDED_2_2
:
269 case SPV_ENV_OPENCL_2_1
:
270 case SPV_ENV_OPENCL_2_2
:
272 case SPV_ENV_WEBGPU_0
:
273 assert(false && "Deprecated target environment value.");
276 assert(false && "Invalid target environment value.");
282 bool spvIsOpenGLEnv(spv_target_env env
) {
284 case SPV_ENV_UNIVERSAL_1_0
:
285 case SPV_ENV_VULKAN_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_VULKAN_1_1
:
290 case SPV_ENV_OPENCL_1_2
:
291 case SPV_ENV_OPENCL_EMBEDDED_1_2
:
292 case SPV_ENV_OPENCL_2_0
:
293 case SPV_ENV_OPENCL_EMBEDDED_2_0
:
294 case SPV_ENV_OPENCL_EMBEDDED_2_1
:
295 case SPV_ENV_OPENCL_EMBEDDED_2_2
:
296 case SPV_ENV_OPENCL_2_1
:
297 case SPV_ENV_OPENCL_2_2
:
298 case SPV_ENV_UNIVERSAL_1_4
:
299 case SPV_ENV_VULKAN_1_1_SPIRV_1_4
:
300 case SPV_ENV_UNIVERSAL_1_5
:
301 case SPV_ENV_VULKAN_1_2
:
302 case SPV_ENV_UNIVERSAL_1_6
:
303 case SPV_ENV_VULKAN_1_3
:
305 case SPV_ENV_OPENGL_4_0
:
306 case SPV_ENV_OPENGL_4_1
:
307 case SPV_ENV_OPENGL_4_2
:
308 case SPV_ENV_OPENGL_4_3
:
309 case SPV_ENV_OPENGL_4_5
:
311 case SPV_ENV_WEBGPU_0
:
312 assert(false && "Deprecated target environment value.");
315 assert(false && "Invalid target environment value.");
321 bool spvIsValidEnv(spv_target_env env
) {
323 case SPV_ENV_UNIVERSAL_1_0
:
324 case SPV_ENV_VULKAN_1_0
:
325 case SPV_ENV_UNIVERSAL_1_1
:
326 case SPV_ENV_UNIVERSAL_1_2
:
327 case SPV_ENV_UNIVERSAL_1_3
:
328 case SPV_ENV_VULKAN_1_1
:
329 case SPV_ENV_OPENCL_1_2
:
330 case SPV_ENV_OPENCL_EMBEDDED_1_2
:
331 case SPV_ENV_OPENCL_2_0
:
332 case SPV_ENV_OPENCL_EMBEDDED_2_0
:
333 case SPV_ENV_OPENCL_EMBEDDED_2_1
:
334 case SPV_ENV_OPENCL_EMBEDDED_2_2
:
335 case SPV_ENV_OPENCL_2_1
:
336 case SPV_ENV_OPENCL_2_2
:
337 case SPV_ENV_UNIVERSAL_1_4
:
338 case SPV_ENV_VULKAN_1_1_SPIRV_1_4
:
339 case SPV_ENV_UNIVERSAL_1_5
:
340 case SPV_ENV_VULKAN_1_2
:
341 case SPV_ENV_UNIVERSAL_1_6
:
342 case SPV_ENV_VULKAN_1_3
:
343 case SPV_ENV_OPENGL_4_0
:
344 case SPV_ENV_OPENGL_4_1
:
345 case SPV_ENV_OPENGL_4_2
:
346 case SPV_ENV_OPENGL_4_3
:
347 case SPV_ENV_OPENGL_4_5
:
349 case SPV_ENV_WEBGPU_0
:
356 std::string
spvLogStringForEnv(spv_target_env env
) {
358 case SPV_ENV_OPENCL_1_2
:
359 case SPV_ENV_OPENCL_2_0
:
360 case SPV_ENV_OPENCL_2_1
:
361 case SPV_ENV_OPENCL_2_2
:
362 case SPV_ENV_OPENCL_EMBEDDED_1_2
:
363 case SPV_ENV_OPENCL_EMBEDDED_2_0
:
364 case SPV_ENV_OPENCL_EMBEDDED_2_1
:
365 case SPV_ENV_OPENCL_EMBEDDED_2_2
: {
368 case SPV_ENV_OPENGL_4_0
:
369 case SPV_ENV_OPENGL_4_1
:
370 case SPV_ENV_OPENGL_4_2
:
371 case SPV_ENV_OPENGL_4_3
:
372 case SPV_ENV_OPENGL_4_5
: {
375 case SPV_ENV_VULKAN_1_0
:
376 case SPV_ENV_VULKAN_1_1
:
377 case SPV_ENV_VULKAN_1_1_SPIRV_1_4
:
378 case SPV_ENV_VULKAN_1_2
:
379 case SPV_ENV_VULKAN_1_3
: {
382 case SPV_ENV_UNIVERSAL_1_0
:
383 case SPV_ENV_UNIVERSAL_1_1
:
384 case SPV_ENV_UNIVERSAL_1_2
:
385 case SPV_ENV_UNIVERSAL_1_3
:
386 case SPV_ENV_UNIVERSAL_1_4
:
387 case SPV_ENV_UNIVERSAL_1_5
:
388 case SPV_ENV_UNIVERSAL_1_6
: {
391 case SPV_ENV_WEBGPU_0
:
392 assert(false && "Deprecated target environment value.");
395 assert(false && "Invalid target environment value.");
401 std::string
spvTargetEnvList(const int pad
, const int wrap
) {
403 size_t max_line_len
= wrap
- pad
; // The first line isn't padded
405 std::string sep
= "";
407 for (auto& name_env
: spvTargetEnvNameMap
) {
408 std::string word
= sep
+ name_env
.first
;
409 if (line
.length() + word
.length() > max_line_len
) {
410 // Adding one word wouldn't fit, commit the line in progress and
413 line
.assign(pad
, ' ');
414 // The first line is done. The max length now comprises the