1 /*
2 * Copyright 2019-2021 Hans-Kristian Arntzen
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 /*
18 * At your option, you may choose to accept this material under either:
19 * 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
20 * 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
21 * SPDX-License-Identifier: Apache-2.0 OR MIT.
22 */
23
24 #include "spirv_cross_c.h"
25
26 #if SPIRV_CROSS_C_API_CPP
27 #include "spirv_cpp.hpp"
28 #endif
29 #if SPIRV_CROSS_C_API_GLSL
30 #include "spirv_glsl.hpp"
31 #else
32 #include "spirv_cross.hpp"
33 #endif
34 #if SPIRV_CROSS_C_API_HLSL
35 #include "spirv_hlsl.hpp"
36 #endif
37 #if SPIRV_CROSS_C_API_MSL
38 #include "spirv_msl.hpp"
39 #endif
40 #if SPIRV_CROSS_C_API_REFLECT
41 #include "spirv_reflect.hpp"
42 #endif
43
44 #ifdef HAVE_SPIRV_CROSS_GIT_VERSION
45 #include "gitversion.h"
46 #endif
47
48 #include "spirv_parser.hpp"
49 #include <memory>
50 #include <new>
51 #include <string.h>
52
53 // clang-format off
54
55 #ifdef _MSC_VER
56 #pragma warning(push)
57 #pragma warning(disable : 4996)
58 #endif
59
60 #ifndef SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
61 #define SPVC_BEGIN_SAFE_SCOPE try
62 #else
63 #define SPVC_BEGIN_SAFE_SCOPE
64 #endif
65
66 #ifndef SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
67 #define SPVC_END_SAFE_SCOPE(context, error) \
68 catch (const std::exception &e) \
69 { \
70 (context)->report_error(e.what()); \
71 return (error); \
72 }
73 #else
74 #define SPVC_END_SAFE_SCOPE(context, error)
75 #endif
76
77 using namespace std;
78 using namespace SPIRV_CROSS_NAMESPACE;
79
80 struct ScratchMemoryAllocation
81 {
82 virtual ~ScratchMemoryAllocation() = default;
83 };
84
85 struct StringAllocation : ScratchMemoryAllocation
86 {
StringAllocationStringAllocation87 explicit StringAllocation(const char *name)
88 : str(name)
89 {
90 }
91
StringAllocationStringAllocation92 explicit StringAllocation(std::string name)
93 : str(std::move(name))
94 {
95 }
96
97 std::string str;
98 };
99
100 template <typename T>
101 struct TemporaryBuffer : ScratchMemoryAllocation
102 {
103 SmallVector<T> buffer;
104 };
105
106 template <typename T, typename... Ts>
spvc_allocate(Ts &&...ts)107 static inline std::unique_ptr<T> spvc_allocate(Ts &&... ts)
108 {
109 return std::unique_ptr<T>(new T(std::forward<Ts>(ts)...));
110 }
111
112 struct spvc_context_s
113 {
114 string last_error;
115 SmallVector<unique_ptr<ScratchMemoryAllocation>> allocations;
116 const char *allocate_name(const std::string &name);
117
118 spvc_error_callback callback = nullptr;
119 void *callback_userdata = nullptr;
120 void report_error(std::string msg);
121 };
122
report_error(std::string msg)123 void spvc_context_s::report_error(std::string msg)
124 {
125 last_error = std::move(msg);
126 if (callback)
127 callback(callback_userdata, last_error.c_str());
128 }
129
allocate_name(const std::string & name)130 const char *spvc_context_s::allocate_name(const std::string &name)
131 {
132 SPVC_BEGIN_SAFE_SCOPE
133 {
134 auto alloc = spvc_allocate<StringAllocation>(name);
135 auto *ret = alloc->str.c_str();
136 allocations.emplace_back(std::move(alloc));
137 return ret;
138 }
139 SPVC_END_SAFE_SCOPE(this, nullptr)
140 }
141
142 struct spvc_parsed_ir_s : ScratchMemoryAllocation
143 {
144 spvc_context context = nullptr;
145 ParsedIR parsed;
146 };
147
148 struct spvc_compiler_s : ScratchMemoryAllocation
149 {
150 spvc_context context = nullptr;
151 unique_ptr<Compiler> compiler;
152 spvc_backend backend = SPVC_BACKEND_NONE;
153 };
154
155 struct spvc_compiler_options_s : ScratchMemoryAllocation
156 {
157 spvc_context context = nullptr;
158 uint32_t backend_flags = 0;
159 #if SPIRV_CROSS_C_API_GLSL
160 CompilerGLSL::Options glsl;
161 #endif
162 #if SPIRV_CROSS_C_API_MSL
163 CompilerMSL::Options msl;
164 #endif
165 #if SPIRV_CROSS_C_API_HLSL
166 CompilerHLSL::Options hlsl;
167 #endif
168 };
169
170 struct spvc_set_s : ScratchMemoryAllocation
171 {
172 std::unordered_set<VariableID> set;
173 };
174
175 // Dummy-inherit to we can keep our opaque type handle type safe in C-land as well,
176 // and avoid just throwing void * around.
177 struct spvc_type_s : SPIRType
178 {
179 };
180
181 struct spvc_constant_s : SPIRConstant
182 {
183 };
184
185 struct spvc_resources_s : ScratchMemoryAllocation
186 {
187 spvc_context context = nullptr;
188 SmallVector<spvc_reflected_resource> uniform_buffers;
189 SmallVector<spvc_reflected_resource> storage_buffers;
190 SmallVector<spvc_reflected_resource> stage_inputs;
191 SmallVector<spvc_reflected_resource> stage_outputs;
192 SmallVector<spvc_reflected_resource> subpass_inputs;
193 SmallVector<spvc_reflected_resource> storage_images;
194 SmallVector<spvc_reflected_resource> sampled_images;
195 SmallVector<spvc_reflected_resource> atomic_counters;
196 SmallVector<spvc_reflected_resource> push_constant_buffers;
197 SmallVector<spvc_reflected_resource> separate_images;
198 SmallVector<spvc_reflected_resource> separate_samplers;
199 SmallVector<spvc_reflected_resource> acceleration_structures;
200
201 bool copy_resources(SmallVector<spvc_reflected_resource> &outputs, const SmallVector<Resource> &inputs);
202 bool copy_resources(const ShaderResources &resources);
203 };
204
spvc_context_create(spvc_context * context)205 spvc_result spvc_context_create(spvc_context *context)
206 {
207 auto *ctx = new (std::nothrow) spvc_context_s;
208 if (!ctx)
209 return SPVC_ERROR_OUT_OF_MEMORY;
210
211 *context = ctx;
212 return SPVC_SUCCESS;
213 }
214
spvc_context_destroy(spvc_context context)215 void spvc_context_destroy(spvc_context context)
216 {
217 delete context;
218 }
219
spvc_context_release_allocations(spvc_context context)220 void spvc_context_release_allocations(spvc_context context)
221 {
222 context->allocations.clear();
223 }
224
spvc_context_get_last_error_string(spvc_context context)225 const char *spvc_context_get_last_error_string(spvc_context context)
226 {
227 return context->last_error.c_str();
228 }
229
spvc_context_set_error_callback(spvc_context context,spvc_error_callback cb,void * userdata)230 SPVC_PUBLIC_API void spvc_context_set_error_callback(spvc_context context, spvc_error_callback cb, void *userdata)
231 {
232 context->callback = cb;
233 context->callback_userdata = userdata;
234 }
235
spvc_context_parse_spirv(spvc_context context,const SpvId * spirv,size_t word_count,spvc_parsed_ir * parsed_ir)236 spvc_result spvc_context_parse_spirv(spvc_context context, const SpvId *spirv, size_t word_count,
237 spvc_parsed_ir *parsed_ir)
238 {
239 SPVC_BEGIN_SAFE_SCOPE
240 {
241 std::unique_ptr<spvc_parsed_ir_s> pir(new (std::nothrow) spvc_parsed_ir_s);
242 if (!pir)
243 {
244 context->report_error("Out of memory.");
245 return SPVC_ERROR_OUT_OF_MEMORY;
246 }
247
248 pir->context = context;
249 Parser parser(spirv, word_count);
250 parser.parse();
251 pir->parsed = move(parser.get_parsed_ir());
252 *parsed_ir = pir.get();
253 context->allocations.push_back(std::move(pir));
254 }
255 SPVC_END_SAFE_SCOPE(context, SPVC_ERROR_INVALID_SPIRV)
256 return SPVC_SUCCESS;
257 }
258
spvc_context_create_compiler(spvc_context context,spvc_backend backend,spvc_parsed_ir parsed_ir,spvc_capture_mode mode,spvc_compiler * compiler)259 spvc_result spvc_context_create_compiler(spvc_context context, spvc_backend backend, spvc_parsed_ir parsed_ir,
260 spvc_capture_mode mode, spvc_compiler *compiler)
261 {
262 SPVC_BEGIN_SAFE_SCOPE
263 {
264 std::unique_ptr<spvc_compiler_s> comp(new (std::nothrow) spvc_compiler_s);
265 if (!comp)
266 {
267 context->report_error("Out of memory.");
268 return SPVC_ERROR_OUT_OF_MEMORY;
269 }
270 comp->backend = backend;
271 comp->context = context;
272
273 if (mode != SPVC_CAPTURE_MODE_COPY && mode != SPVC_CAPTURE_MODE_TAKE_OWNERSHIP)
274 {
275 context->report_error("Invalid argument for capture mode.");
276 return SPVC_ERROR_INVALID_ARGUMENT;
277 }
278
279 switch (backend)
280 {
281 case SPVC_BACKEND_NONE:
282 if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP)
283 comp->compiler.reset(new Compiler(move(parsed_ir->parsed)));
284 else if (mode == SPVC_CAPTURE_MODE_COPY)
285 comp->compiler.reset(new Compiler(parsed_ir->parsed));
286 break;
287
288 #if SPIRV_CROSS_C_API_GLSL
289 case SPVC_BACKEND_GLSL:
290 if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP)
291 comp->compiler.reset(new CompilerGLSL(move(parsed_ir->parsed)));
292 else if (mode == SPVC_CAPTURE_MODE_COPY)
293 comp->compiler.reset(new CompilerGLSL(parsed_ir->parsed));
294 break;
295 #endif
296
297 #if SPIRV_CROSS_C_API_HLSL
298 case SPVC_BACKEND_HLSL:
299 if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP)
300 comp->compiler.reset(new CompilerHLSL(move(parsed_ir->parsed)));
301 else if (mode == SPVC_CAPTURE_MODE_COPY)
302 comp->compiler.reset(new CompilerHLSL(parsed_ir->parsed));
303 break;
304 #endif
305
306 #if SPIRV_CROSS_C_API_MSL
307 case SPVC_BACKEND_MSL:
308 if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP)
309 comp->compiler.reset(new CompilerMSL(move(parsed_ir->parsed)));
310 else if (mode == SPVC_CAPTURE_MODE_COPY)
311 comp->compiler.reset(new CompilerMSL(parsed_ir->parsed));
312 break;
313 #endif
314
315 #if SPIRV_CROSS_C_API_CPP
316 case SPVC_BACKEND_CPP:
317 if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP)
318 comp->compiler.reset(new CompilerCPP(move(parsed_ir->parsed)));
319 else if (mode == SPVC_CAPTURE_MODE_COPY)
320 comp->compiler.reset(new CompilerCPP(parsed_ir->parsed));
321 break;
322 #endif
323
324 #if SPIRV_CROSS_C_API_REFLECT
325 case SPVC_BACKEND_JSON:
326 if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP)
327 comp->compiler.reset(new CompilerReflection(move(parsed_ir->parsed)));
328 else if (mode == SPVC_CAPTURE_MODE_COPY)
329 comp->compiler.reset(new CompilerReflection(parsed_ir->parsed));
330 break;
331 #endif
332
333 default:
334 context->report_error("Invalid backend.");
335 return SPVC_ERROR_INVALID_ARGUMENT;
336 }
337
338 *compiler = comp.get();
339 context->allocations.push_back(std::move(comp));
340 }
341 SPVC_END_SAFE_SCOPE(context, SPVC_ERROR_OUT_OF_MEMORY)
342 return SPVC_SUCCESS;
343 }
344
spvc_compiler_create_compiler_options(spvc_compiler compiler,spvc_compiler_options * options)345 spvc_result spvc_compiler_create_compiler_options(spvc_compiler compiler, spvc_compiler_options *options)
346 {
347 SPVC_BEGIN_SAFE_SCOPE
348 {
349 std::unique_ptr<spvc_compiler_options_s> opt(new (std::nothrow) spvc_compiler_options_s);
350 if (!opt)
351 {
352 compiler->context->report_error("Out of memory.");
353 return SPVC_ERROR_OUT_OF_MEMORY;
354 }
355
356 opt->context = compiler->context;
357 opt->backend_flags = 0;
358 switch (compiler->backend)
359 {
360 #if SPIRV_CROSS_C_API_MSL
361 case SPVC_BACKEND_MSL:
362 opt->backend_flags |= SPVC_COMPILER_OPTION_MSL_BIT | SPVC_COMPILER_OPTION_COMMON_BIT;
363 opt->glsl = static_cast<CompilerMSL *>(compiler->compiler.get())->get_common_options();
364 opt->msl = static_cast<CompilerMSL *>(compiler->compiler.get())->get_msl_options();
365 break;
366 #endif
367
368 #if SPIRV_CROSS_C_API_HLSL
369 case SPVC_BACKEND_HLSL:
370 opt->backend_flags |= SPVC_COMPILER_OPTION_HLSL_BIT | SPVC_COMPILER_OPTION_COMMON_BIT;
371 opt->glsl = static_cast<CompilerHLSL *>(compiler->compiler.get())->get_common_options();
372 opt->hlsl = static_cast<CompilerHLSL *>(compiler->compiler.get())->get_hlsl_options();
373 break;
374 #endif
375
376 #if SPIRV_CROSS_C_API_GLSL
377 case SPVC_BACKEND_GLSL:
378 opt->backend_flags |= SPVC_COMPILER_OPTION_GLSL_BIT | SPVC_COMPILER_OPTION_COMMON_BIT;
379 opt->glsl = static_cast<CompilerGLSL *>(compiler->compiler.get())->get_common_options();
380 break;
381 #endif
382
383 default:
384 break;
385 }
386
387 *options = opt.get();
388 compiler->context->allocations.push_back(std::move(opt));
389 }
390 SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_OUT_OF_MEMORY)
391 return SPVC_SUCCESS;
392 }
393
spvc_compiler_options_set_bool(spvc_compiler_options options,spvc_compiler_option option,spvc_bool value)394 spvc_result spvc_compiler_options_set_bool(spvc_compiler_options options, spvc_compiler_option option,
395 spvc_bool value)
396 {
397 return spvc_compiler_options_set_uint(options, option, value ? 1 : 0);
398 }
399
spvc_compiler_options_set_uint(spvc_compiler_options options,spvc_compiler_option option,unsigned value)400 spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_compiler_option option, unsigned value)
401 {
402 (void)value;
403 (void)option;
404 uint32_t supported_mask = options->backend_flags;
405 uint32_t required_mask = option & SPVC_COMPILER_OPTION_LANG_BITS;
406 if ((required_mask | supported_mask) != supported_mask)
407 {
408 options->context->report_error("Option is not supported by current backend.");
409 return SPVC_ERROR_INVALID_ARGUMENT;
410 }
411
412 switch (option)
413 {
414 #if SPIRV_CROSS_C_API_GLSL
415 case SPVC_COMPILER_OPTION_FORCE_TEMPORARY:
416 options->glsl.force_temporary = value != 0;
417 break;
418 case SPVC_COMPILER_OPTION_FLATTEN_MULTIDIMENSIONAL_ARRAYS:
419 options->glsl.flatten_multidimensional_arrays = value != 0;
420 break;
421 case SPVC_COMPILER_OPTION_FIXUP_DEPTH_CONVENTION:
422 options->glsl.vertex.fixup_clipspace = value != 0;
423 break;
424 case SPVC_COMPILER_OPTION_FLIP_VERTEX_Y:
425 options->glsl.vertex.flip_vert_y = value != 0;
426 break;
427 case SPVC_COMPILER_OPTION_EMIT_LINE_DIRECTIVES:
428 options->glsl.emit_line_directives = value != 0;
429 break;
430 case SPVC_COMPILER_OPTION_ENABLE_STORAGE_IMAGE_QUALIFIER_DEDUCTION:
431 options->glsl.enable_storage_image_qualifier_deduction = value != 0;
432 break;
433 case SPVC_COMPILER_OPTION_FORCE_ZERO_INITIALIZED_VARIABLES:
434 options->glsl.force_zero_initialized_variables = value != 0;
435 break;
436
437 case SPVC_COMPILER_OPTION_GLSL_SUPPORT_NONZERO_BASE_INSTANCE:
438 options->glsl.vertex.support_nonzero_base_instance = value != 0;
439 break;
440 case SPVC_COMPILER_OPTION_GLSL_SEPARATE_SHADER_OBJECTS:
441 options->glsl.separate_shader_objects = value != 0;
442 break;
443 case SPVC_COMPILER_OPTION_GLSL_ENABLE_420PACK_EXTENSION:
444 options->glsl.enable_420pack_extension = value != 0;
445 break;
446 case SPVC_COMPILER_OPTION_GLSL_VERSION:
447 options->glsl.version = value;
448 break;
449 case SPVC_COMPILER_OPTION_GLSL_ES:
450 options->glsl.es = value != 0;
451 break;
452 case SPVC_COMPILER_OPTION_GLSL_VULKAN_SEMANTICS:
453 options->glsl.vulkan_semantics = value != 0;
454 break;
455 case SPVC_COMPILER_OPTION_GLSL_ES_DEFAULT_FLOAT_PRECISION_HIGHP:
456 options->glsl.fragment.default_float_precision =
457 value != 0 ? CompilerGLSL::Options::Precision::Highp : CompilerGLSL::Options::Precision::Mediump;
458 break;
459 case SPVC_COMPILER_OPTION_GLSL_ES_DEFAULT_INT_PRECISION_HIGHP:
460 options->glsl.fragment.default_int_precision =
461 value != 0 ? CompilerGLSL::Options::Precision::Highp : CompilerGLSL::Options::Precision::Mediump;
462 break;
463 case SPVC_COMPILER_OPTION_GLSL_EMIT_PUSH_CONSTANT_AS_UNIFORM_BUFFER:
464 options->glsl.emit_push_constant_as_uniform_buffer = value != 0;
465 break;
466 case SPVC_COMPILER_OPTION_GLSL_EMIT_UNIFORM_BUFFER_AS_PLAIN_UNIFORMS:
467 options->glsl.emit_uniform_buffer_as_plain_uniforms = value != 0;
468 break;
469 case SPVC_COMPILER_OPTION_GLSL_FORCE_FLATTENED_IO_BLOCKS:
470 options->glsl.force_flattened_io_blocks = value != 0;
471 break;
472 #endif
473
474 #if SPIRV_CROSS_C_API_HLSL
475 case SPVC_COMPILER_OPTION_HLSL_SHADER_MODEL:
476 options->hlsl.shader_model = value;
477 break;
478
479 case SPVC_COMPILER_OPTION_HLSL_POINT_SIZE_COMPAT:
480 options->hlsl.point_size_compat = value != 0;
481 break;
482
483 case SPVC_COMPILER_OPTION_HLSL_POINT_COORD_COMPAT:
484 options->hlsl.point_coord_compat = value != 0;
485 break;
486
487 case SPVC_COMPILER_OPTION_HLSL_SUPPORT_NONZERO_BASE_VERTEX_BASE_INSTANCE:
488 options->hlsl.support_nonzero_base_vertex_base_instance = value != 0;
489 break;
490
491 case SPVC_COMPILER_OPTION_HLSL_FORCE_STORAGE_BUFFER_AS_UAV:
492 options->hlsl.force_storage_buffer_as_uav = value != 0;
493 break;
494
495 case SPVC_COMPILER_OPTION_HLSL_NONWRITABLE_UAV_TEXTURE_AS_SRV:
496 options->hlsl.nonwritable_uav_texture_as_srv = value != 0;
497 break;
498
499 case SPVC_COMPILER_OPTION_HLSL_ENABLE_16BIT_TYPES:
500 options->hlsl.enable_16bit_types = value != 0;
501 break;
502
503 case SPVC_COMPILER_OPTION_HLSL_FLATTEN_MATRIX_VERTEX_INPUT_SEMANTICS:
504 options->hlsl.flatten_matrix_vertex_input_semantics = value != 0;
505 break;
506 #endif
507
508 #if SPIRV_CROSS_C_API_MSL
509 case SPVC_COMPILER_OPTION_MSL_VERSION:
510 options->msl.msl_version = value;
511 break;
512
513 case SPVC_COMPILER_OPTION_MSL_TEXEL_BUFFER_TEXTURE_WIDTH:
514 options->msl.texel_buffer_texture_width = value;
515 break;
516
517 case SPVC_COMPILER_OPTION_MSL_SWIZZLE_BUFFER_INDEX:
518 options->msl.swizzle_buffer_index = value;
519 break;
520
521 case SPVC_COMPILER_OPTION_MSL_INDIRECT_PARAMS_BUFFER_INDEX:
522 options->msl.indirect_params_buffer_index = value;
523 break;
524
525 case SPVC_COMPILER_OPTION_MSL_SHADER_OUTPUT_BUFFER_INDEX:
526 options->msl.shader_output_buffer_index = value;
527 break;
528
529 case SPVC_COMPILER_OPTION_MSL_SHADER_PATCH_OUTPUT_BUFFER_INDEX:
530 options->msl.shader_patch_output_buffer_index = value;
531 break;
532
533 case SPVC_COMPILER_OPTION_MSL_SHADER_TESS_FACTOR_OUTPUT_BUFFER_INDEX:
534 options->msl.shader_tess_factor_buffer_index = value;
535 break;
536
537 case SPVC_COMPILER_OPTION_MSL_SHADER_INPUT_WORKGROUP_INDEX:
538 options->msl.shader_input_wg_index = value;
539 break;
540
541 case SPVC_COMPILER_OPTION_MSL_ENABLE_POINT_SIZE_BUILTIN:
542 options->msl.enable_point_size_builtin = value != 0;
543 break;
544
545 case SPVC_COMPILER_OPTION_MSL_DISABLE_RASTERIZATION:
546 options->msl.disable_rasterization = value != 0;
547 break;
548
549 case SPVC_COMPILER_OPTION_MSL_CAPTURE_OUTPUT_TO_BUFFER:
550 options->msl.capture_output_to_buffer = value != 0;
551 break;
552
553 case SPVC_COMPILER_OPTION_MSL_SWIZZLE_TEXTURE_SAMPLES:
554 options->msl.swizzle_texture_samples = value != 0;
555 break;
556
557 case SPVC_COMPILER_OPTION_MSL_PAD_FRAGMENT_OUTPUT_COMPONENTS:
558 options->msl.pad_fragment_output_components = value != 0;
559 break;
560
561 case SPVC_COMPILER_OPTION_MSL_TESS_DOMAIN_ORIGIN_LOWER_LEFT:
562 options->msl.tess_domain_origin_lower_left = value != 0;
563 break;
564
565 case SPVC_COMPILER_OPTION_MSL_PLATFORM:
566 options->msl.platform = static_cast<CompilerMSL::Options::Platform>(value);
567 break;
568
569 case SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS:
570 options->msl.argument_buffers = value != 0;
571 break;
572
573 case SPVC_COMPILER_OPTION_MSL_TEXTURE_BUFFER_NATIVE:
574 options->msl.texture_buffer_native = value != 0;
575 break;
576
577 case SPVC_COMPILER_OPTION_MSL_BUFFER_SIZE_BUFFER_INDEX:
578 options->msl.buffer_size_buffer_index = value;
579 break;
580
581 case SPVC_COMPILER_OPTION_MSL_MULTIVIEW:
582 options->msl.multiview = value != 0;
583 break;
584
585 case SPVC_COMPILER_OPTION_MSL_VIEW_MASK_BUFFER_INDEX:
586 options->msl.view_mask_buffer_index = value;
587 break;
588
589 case SPVC_COMPILER_OPTION_MSL_DEVICE_INDEX:
590 options->msl.device_index = value;
591 break;
592
593 case SPVC_COMPILER_OPTION_MSL_VIEW_INDEX_FROM_DEVICE_INDEX:
594 options->msl.view_index_from_device_index = value != 0;
595 break;
596
597 case SPVC_COMPILER_OPTION_MSL_DISPATCH_BASE:
598 options->msl.dispatch_base = value != 0;
599 break;
600
601 case SPVC_COMPILER_OPTION_MSL_DYNAMIC_OFFSETS_BUFFER_INDEX:
602 options->msl.dynamic_offsets_buffer_index = value;
603 break;
604
605 case SPVC_COMPILER_OPTION_MSL_TEXTURE_1D_AS_2D:
606 options->msl.texture_1D_as_2D = value != 0;
607 break;
608
609 case SPVC_COMPILER_OPTION_MSL_ENABLE_BASE_INDEX_ZERO:
610 options->msl.enable_base_index_zero = value != 0;
611 break;
612
613 case SPVC_COMPILER_OPTION_MSL_FRAMEBUFFER_FETCH_SUBPASS:
614 options->msl.use_framebuffer_fetch_subpasses = value != 0;
615 break;
616
617 case SPVC_COMPILER_OPTION_MSL_INVARIANT_FP_MATH:
618 options->msl.invariant_float_math = value != 0;
619 break;
620
621 case SPVC_COMPILER_OPTION_MSL_EMULATE_CUBEMAP_ARRAY:
622 options->msl.emulate_cube_array = value != 0;
623 break;
624
625 case SPVC_COMPILER_OPTION_MSL_ENABLE_DECORATION_BINDING:
626 options->msl.enable_decoration_binding = value != 0;
627 break;
628
629 case SPVC_COMPILER_OPTION_MSL_FORCE_ACTIVE_ARGUMENT_BUFFER_RESOURCES:
630 options->msl.force_active_argument_buffer_resources = value != 0;
631 break;
632
633 case SPVC_COMPILER_OPTION_MSL_FORCE_NATIVE_ARRAYS:
634 options->msl.force_native_arrays = value != 0;
635 break;
636
637 case SPVC_COMPILER_OPTION_MSL_ENABLE_FRAG_OUTPUT_MASK:
638 options->msl.enable_frag_output_mask = value;
639 break;
640
641 case SPVC_COMPILER_OPTION_MSL_ENABLE_FRAG_DEPTH_BUILTIN:
642 options->msl.enable_frag_depth_builtin = value != 0;
643 break;
644
645 case SPVC_COMPILER_OPTION_MSL_ENABLE_FRAG_STENCIL_REF_BUILTIN:
646 options->msl.enable_frag_stencil_ref_builtin = value != 0;
647 break;
648
649 case SPVC_COMPILER_OPTION_MSL_ENABLE_CLIP_DISTANCE_USER_VARYING:
650 options->msl.enable_clip_distance_user_varying = value != 0;
651 break;
652
653 case SPVC_COMPILER_OPTION_MSL_MULTI_PATCH_WORKGROUP:
654 options->msl.multi_patch_workgroup = value != 0;
655 break;
656
657 case SPVC_COMPILER_OPTION_MSL_SHADER_INPUT_BUFFER_INDEX:
658 options->msl.shader_input_buffer_index = value;
659 break;
660
661 case SPVC_COMPILER_OPTION_MSL_SHADER_INDEX_BUFFER_INDEX:
662 options->msl.shader_index_buffer_index = value;
663 break;
664
665 case SPVC_COMPILER_OPTION_MSL_VERTEX_FOR_TESSELLATION:
666 options->msl.vertex_for_tessellation = value != 0;
667 break;
668
669 case SPVC_COMPILER_OPTION_MSL_VERTEX_INDEX_TYPE:
670 options->msl.vertex_index_type = static_cast<CompilerMSL::Options::IndexType>(value);
671 break;
672
673 case SPVC_COMPILER_OPTION_MSL_MULTIVIEW_LAYERED_RENDERING:
674 options->msl.multiview_layered_rendering = value != 0;
675 break;
676
677 case SPVC_COMPILER_OPTION_MSL_ARRAYED_SUBPASS_INPUT:
678 options->msl.arrayed_subpass_input = value != 0;
679 break;
680
681 case SPVC_COMPILER_OPTION_MSL_R32UI_LINEAR_TEXTURE_ALIGNMENT:
682 options->msl.r32ui_linear_texture_alignment = value;
683 break;
684
685 case SPVC_COMPILER_OPTION_MSL_R32UI_ALIGNMENT_CONSTANT_ID:
686 options->msl.r32ui_alignment_constant_id = value;
687 break;
688
689 case SPVC_COMPILER_OPTION_MSL_IOS_USE_SIMDGROUP_FUNCTIONS:
690 options->msl.ios_use_simdgroup_functions = value != 0;
691 break;
692
693 case SPVC_COMPILER_OPTION_MSL_EMULATE_SUBGROUPS:
694 options->msl.emulate_subgroups = value != 0;
695 break;
696
697 case SPVC_COMPILER_OPTION_MSL_FIXED_SUBGROUP_SIZE:
698 options->msl.fixed_subgroup_size = value;
699 break;
700
701 case SPVC_COMPILER_OPTION_MSL_FORCE_SAMPLE_RATE_SHADING:
702 options->msl.force_sample_rate_shading = value != 0;
703 break;
704 #endif
705
706 default:
707 options->context->report_error("Unknown option.");
708 return SPVC_ERROR_INVALID_ARGUMENT;
709 }
710
711 return SPVC_SUCCESS;
712 }
713
spvc_compiler_install_compiler_options(spvc_compiler compiler,spvc_compiler_options options)714 spvc_result spvc_compiler_install_compiler_options(spvc_compiler compiler, spvc_compiler_options options)
715 {
716 (void)options;
717 switch (compiler->backend)
718 {
719 #if SPIRV_CROSS_C_API_GLSL
720 case SPVC_BACKEND_GLSL:
721 static_cast<CompilerGLSL &>(*compiler->compiler).set_common_options(options->glsl);
722 break;
723 #endif
724
725 #if SPIRV_CROSS_C_API_HLSL
726 case SPVC_BACKEND_HLSL:
727 static_cast<CompilerHLSL &>(*compiler->compiler).set_common_options(options->glsl);
728 static_cast<CompilerHLSL &>(*compiler->compiler).set_hlsl_options(options->hlsl);
729 break;
730 #endif
731
732 #if SPIRV_CROSS_C_API_MSL
733 case SPVC_BACKEND_MSL:
734 static_cast<CompilerMSL &>(*compiler->compiler).set_common_options(options->glsl);
735 static_cast<CompilerMSL &>(*compiler->compiler).set_msl_options(options->msl);
736 break;
737 #endif
738
739 default:
740 break;
741 }
742
743 return SPVC_SUCCESS;
744 }
745
spvc_compiler_add_header_line(spvc_compiler compiler,const char * line)746 spvc_result spvc_compiler_add_header_line(spvc_compiler compiler, const char *line)
747 {
748 #if SPIRV_CROSS_C_API_GLSL
749 if (compiler->backend == SPVC_BACKEND_NONE)
750 {
751 compiler->context->report_error("Cross-compilation related option used on NONE backend which only supports reflection.");
752 return SPVC_ERROR_INVALID_ARGUMENT;
753 }
754
755 static_cast<CompilerGLSL *>(compiler->compiler.get())->add_header_line(line);
756 return SPVC_SUCCESS;
757 #else
758 (void)line;
759 compiler->context->report_error("Cross-compilation related option used on NONE backend which only supports reflection.");
760 return SPVC_ERROR_INVALID_ARGUMENT;
761 #endif
762 }
763
spvc_compiler_require_extension(spvc_compiler compiler,const char * line)764 spvc_result spvc_compiler_require_extension(spvc_compiler compiler, const char *line)
765 {
766 #if SPIRV_CROSS_C_API_GLSL
767 if (compiler->backend == SPVC_BACKEND_NONE)
768 {
769 compiler->context->report_error("Cross-compilation related option used on NONE backend which only supports reflection.");
770 return SPVC_ERROR_INVALID_ARGUMENT;
771 }
772
773 static_cast<CompilerGLSL *>(compiler->compiler.get())->require_extension(line);
774 return SPVC_SUCCESS;
775 #else
776 (void)line;
777 compiler->context->report_error("Cross-compilation related option used on NONE backend which only supports reflection.");
778 return SPVC_ERROR_INVALID_ARGUMENT;
779 #endif
780 }
781
spvc_compiler_flatten_buffer_block(spvc_compiler compiler,spvc_variable_id id)782 spvc_result spvc_compiler_flatten_buffer_block(spvc_compiler compiler, spvc_variable_id id)
783 {
784 #if SPIRV_CROSS_C_API_GLSL
785 if (compiler->backend == SPVC_BACKEND_NONE)
786 {
787 compiler->context->report_error("Cross-compilation related option used on NONE backend which only supports reflection.");
788 return SPVC_ERROR_INVALID_ARGUMENT;
789 }
790
791 static_cast<CompilerGLSL *>(compiler->compiler.get())->flatten_buffer_block(id);
792 return SPVC_SUCCESS;
793 #else
794 (void)id;
795 compiler->context->report_error("Cross-compilation related option used on NONE backend which only supports reflection.");
796 return SPVC_ERROR_INVALID_ARGUMENT;
797 #endif
798 }
799
spvc_compiler_variable_is_depth_or_compare(spvc_compiler compiler,spvc_variable_id id)800 spvc_bool spvc_compiler_variable_is_depth_or_compare(spvc_compiler compiler, spvc_variable_id id)
801 {
802 #if SPIRV_CROSS_C_API_GLSL
803 if (compiler->backend == SPVC_BACKEND_NONE)
804 {
805 compiler->context->report_error("Cross-compilation related option used on NONE backend which only supports reflection.");
806 return SPVC_ERROR_INVALID_ARGUMENT;
807 }
808
809 return static_cast<CompilerGLSL *>(compiler->compiler.get())->variable_is_depth_or_compare(id) ? SPVC_TRUE : SPVC_FALSE;
810 #else
811 (void)id;
812 compiler->context->report_error("Cross-compilation related option used on NONE backend which only supports reflection.");
813 return SPVC_FALSE;
814 #endif
815 }
816
spvc_compiler_hlsl_set_root_constants_layout(spvc_compiler compiler,const spvc_hlsl_root_constants * constant_info,size_t count)817 spvc_result spvc_compiler_hlsl_set_root_constants_layout(spvc_compiler compiler,
818 const spvc_hlsl_root_constants *constant_info,
819 size_t count)
820 {
821 #if SPIRV_CROSS_C_API_HLSL
822 if (compiler->backend != SPVC_BACKEND_HLSL)
823 {
824 compiler->context->report_error("HLSL function used on a non-HLSL backend.");
825 return SPVC_ERROR_INVALID_ARGUMENT;
826 }
827
828 auto &hlsl = *static_cast<CompilerHLSL *>(compiler->compiler.get());
829 vector<RootConstants> roots;
830 roots.reserve(count);
831 for (size_t i = 0; i < count; i++)
832 {
833 RootConstants root;
834 root.binding = constant_info[i].binding;
835 root.space = constant_info[i].space;
836 root.start = constant_info[i].start;
837 root.end = constant_info[i].end;
838 roots.push_back(root);
839 }
840
841 hlsl.set_root_constant_layouts(std::move(roots));
842 return SPVC_SUCCESS;
843 #else
844 (void)constant_info;
845 (void)count;
846 compiler->context->report_error("HLSL function used on a non-HLSL backend.");
847 return SPVC_ERROR_INVALID_ARGUMENT;
848 #endif
849 }
850
spvc_compiler_hlsl_add_vertex_attribute_remap(spvc_compiler compiler,const spvc_hlsl_vertex_attribute_remap * remap,size_t count)851 spvc_result spvc_compiler_hlsl_add_vertex_attribute_remap(spvc_compiler compiler,
852 const spvc_hlsl_vertex_attribute_remap *remap,
853 size_t count)
854 {
855 #if SPIRV_CROSS_C_API_HLSL
856 if (compiler->backend != SPVC_BACKEND_HLSL)
857 {
858 compiler->context->report_error("HLSL function used on a non-HLSL backend.");
859 return SPVC_ERROR_INVALID_ARGUMENT;
860 }
861
862 HLSLVertexAttributeRemap re;
863 auto &hlsl = *static_cast<CompilerHLSL *>(compiler->compiler.get());
864 for (size_t i = 0; i < count; i++)
865 {
866 re.location = remap[i].location;
867 re.semantic = remap[i].semantic;
868 hlsl.add_vertex_attribute_remap(re);
869 }
870
871 return SPVC_SUCCESS;
872 #else
873 (void)remap;
874 (void)count;
875 compiler->context->report_error("HLSL function used on a non-HLSL backend.");
876 return SPVC_ERROR_INVALID_ARGUMENT;
877 #endif
878 }
879
spvc_compiler_hlsl_remap_num_workgroups_builtin(spvc_compiler compiler)880 spvc_variable_id spvc_compiler_hlsl_remap_num_workgroups_builtin(spvc_compiler compiler)
881 {
882 #if SPIRV_CROSS_C_API_HLSL
883 if (compiler->backend != SPVC_BACKEND_HLSL)
884 {
885 compiler->context->report_error("HLSL function used on a non-HLSL backend.");
886 return 0;
887 }
888
889 auto &hlsl = *static_cast<CompilerHLSL *>(compiler->compiler.get());
890 return hlsl.remap_num_workgroups_builtin();
891 #else
892 compiler->context->report_error("HLSL function used on a non-HLSL backend.");
893 return 0;
894 #endif
895 }
896
spvc_compiler_hlsl_set_resource_binding_flags(spvc_compiler compiler,spvc_hlsl_binding_flags flags)897 spvc_result spvc_compiler_hlsl_set_resource_binding_flags(spvc_compiler compiler,
898 spvc_hlsl_binding_flags flags)
899 {
900 #if SPIRV_CROSS_C_API_HLSL
901 if (compiler->backend != SPVC_BACKEND_HLSL)
902 {
903 compiler->context->report_error("HLSL function used on a non-HLSL backend.");
904 return SPVC_ERROR_INVALID_ARGUMENT;
905 }
906
907 auto &hlsl = *static_cast<CompilerHLSL *>(compiler->compiler.get());
908 hlsl.set_resource_binding_flags(flags);
909 return SPVC_SUCCESS;
910 #else
911 (void)flags;
912 compiler->context->report_error("HLSL function used on a non-HLSL backend.");
913 return SPVC_ERROR_INVALID_ARGUMENT;
914 #endif
915 }
916
spvc_compiler_hlsl_add_resource_binding(spvc_compiler compiler,const spvc_hlsl_resource_binding * binding)917 spvc_result spvc_compiler_hlsl_add_resource_binding(spvc_compiler compiler,
918 const spvc_hlsl_resource_binding *binding)
919 {
920 #if SPIRV_CROSS_C_API_HLSL
921 if (compiler->backend != SPVC_BACKEND_HLSL)
922 {
923 compiler->context->report_error("HLSL function used on a non-HLSL backend.");
924 return SPVC_ERROR_INVALID_ARGUMENT;
925 }
926
927 auto &hlsl = *static_cast<CompilerHLSL *>(compiler->compiler.get());
928 HLSLResourceBinding bind;
929 bind.binding = binding->binding;
930 bind.desc_set = binding->desc_set;
931 bind.stage = static_cast<spv::ExecutionModel>(binding->stage);
932 bind.cbv.register_binding = binding->cbv.register_binding;
933 bind.cbv.register_space = binding->cbv.register_space;
934 bind.uav.register_binding = binding->uav.register_binding;
935 bind.uav.register_space = binding->uav.register_space;
936 bind.srv.register_binding = binding->srv.register_binding;
937 bind.srv.register_space = binding->srv.register_space;
938 bind.sampler.register_binding = binding->sampler.register_binding;
939 bind.sampler.register_space = binding->sampler.register_space;
940 hlsl.add_hlsl_resource_binding(bind);
941 return SPVC_SUCCESS;
942 #else
943 (void)binding;
944 compiler->context->report_error("HLSL function used on a non-HLSL backend.");
945 return SPVC_ERROR_INVALID_ARGUMENT;
946 #endif
947 }
948
spvc_compiler_hlsl_is_resource_used(spvc_compiler compiler,SpvExecutionModel model,unsigned set,unsigned binding)949 spvc_bool spvc_compiler_hlsl_is_resource_used(spvc_compiler compiler, SpvExecutionModel model, unsigned set,
950 unsigned binding)
951 {
952 #if SPIRV_CROSS_C_API_HLSL
953 if (compiler->backend != SPVC_BACKEND_HLSL)
954 {
955 compiler->context->report_error("HLSL function used on a non-HLSL backend.");
956 return SPVC_FALSE;
957 }
958
959 auto &hlsl = *static_cast<CompilerHLSL *>(compiler->compiler.get());
960 return hlsl.is_hlsl_resource_binding_used(static_cast<spv::ExecutionModel>(model), set, binding) ? SPVC_TRUE :
961 SPVC_FALSE;
962 #else
963 (void)model;
964 (void)set;
965 (void)binding;
966 compiler->context->report_error("HLSL function used on a non-HLSL backend.");
967 return SPVC_FALSE;
968 #endif
969 }
970
spvc_compiler_msl_is_rasterization_disabled(spvc_compiler compiler)971 spvc_bool spvc_compiler_msl_is_rasterization_disabled(spvc_compiler compiler)
972 {
973 #if SPIRV_CROSS_C_API_MSL
974 if (compiler->backend != SPVC_BACKEND_MSL)
975 {
976 compiler->context->report_error("MSL function used on a non-MSL backend.");
977 return SPVC_FALSE;
978 }
979
980 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
981 return msl.get_is_rasterization_disabled() ? SPVC_TRUE : SPVC_FALSE;
982 #else
983 compiler->context->report_error("MSL function used on a non-MSL backend.");
984 return SPVC_FALSE;
985 #endif
986 }
987
spvc_compiler_msl_needs_swizzle_buffer(spvc_compiler compiler)988 spvc_bool spvc_compiler_msl_needs_swizzle_buffer(spvc_compiler compiler)
989 {
990 #if SPIRV_CROSS_C_API_MSL
991 if (compiler->backend != SPVC_BACKEND_MSL)
992 {
993 compiler->context->report_error("MSL function used on a non-MSL backend.");
994 return SPVC_FALSE;
995 }
996
997 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
998 return msl.needs_swizzle_buffer() ? SPVC_TRUE : SPVC_FALSE;
999 #else
1000 compiler->context->report_error("MSL function used on a non-MSL backend.");
1001 return SPVC_FALSE;
1002 #endif
1003 }
1004
spvc_compiler_msl_needs_buffer_size_buffer(spvc_compiler compiler)1005 spvc_bool spvc_compiler_msl_needs_buffer_size_buffer(spvc_compiler compiler)
1006 {
1007 #if SPIRV_CROSS_C_API_MSL
1008 if (compiler->backend != SPVC_BACKEND_MSL)
1009 {
1010 compiler->context->report_error("MSL function used on a non-MSL backend.");
1011 return SPVC_FALSE;
1012 }
1013
1014 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
1015 return msl.needs_buffer_size_buffer() ? SPVC_TRUE : SPVC_FALSE;
1016 #else
1017 compiler->context->report_error("MSL function used on a non-MSL backend.");
1018 return SPVC_FALSE;
1019 #endif
1020 }
1021
spvc_compiler_msl_needs_aux_buffer(spvc_compiler compiler)1022 spvc_bool spvc_compiler_msl_needs_aux_buffer(spvc_compiler compiler)
1023 {
1024 return spvc_compiler_msl_needs_swizzle_buffer(compiler);
1025 }
1026
spvc_compiler_msl_needs_output_buffer(spvc_compiler compiler)1027 spvc_bool spvc_compiler_msl_needs_output_buffer(spvc_compiler compiler)
1028 {
1029 #if SPIRV_CROSS_C_API_MSL
1030 if (compiler->backend != SPVC_BACKEND_MSL)
1031 {
1032 compiler->context->report_error("MSL function used on a non-MSL backend.");
1033 return SPVC_FALSE;
1034 }
1035
1036 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
1037 return msl.needs_output_buffer() ? SPVC_TRUE : SPVC_FALSE;
1038 #else
1039 compiler->context->report_error("MSL function used on a non-MSL backend.");
1040 return SPVC_FALSE;
1041 #endif
1042 }
1043
spvc_compiler_msl_needs_patch_output_buffer(spvc_compiler compiler)1044 spvc_bool spvc_compiler_msl_needs_patch_output_buffer(spvc_compiler compiler)
1045 {
1046 #if SPIRV_CROSS_C_API_MSL
1047 if (compiler->backend != SPVC_BACKEND_MSL)
1048 {
1049 compiler->context->report_error("MSL function used on a non-MSL backend.");
1050 return SPVC_FALSE;
1051 }
1052
1053 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
1054 return msl.needs_patch_output_buffer() ? SPVC_TRUE : SPVC_FALSE;
1055 #else
1056 compiler->context->report_error("MSL function used on a non-MSL backend.");
1057 return SPVC_FALSE;
1058 #endif
1059 }
1060
spvc_compiler_msl_needs_input_threadgroup_mem(spvc_compiler compiler)1061 spvc_bool spvc_compiler_msl_needs_input_threadgroup_mem(spvc_compiler compiler)
1062 {
1063 #if SPIRV_CROSS_C_API_MSL
1064 if (compiler->backend != SPVC_BACKEND_MSL)
1065 {
1066 compiler->context->report_error("MSL function used on a non-MSL backend.");
1067 return SPVC_FALSE;
1068 }
1069
1070 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
1071 return msl.needs_input_threadgroup_mem() ? SPVC_TRUE : SPVC_FALSE;
1072 #else
1073 compiler->context->report_error("MSL function used on a non-MSL backend.");
1074 return SPVC_FALSE;
1075 #endif
1076 }
1077
spvc_compiler_msl_add_vertex_attribute(spvc_compiler compiler,const spvc_msl_vertex_attribute * va)1078 spvc_result spvc_compiler_msl_add_vertex_attribute(spvc_compiler compiler, const spvc_msl_vertex_attribute *va)
1079 {
1080 #if SPIRV_CROSS_C_API_MSL
1081 if (compiler->backend != SPVC_BACKEND_MSL)
1082 {
1083 compiler->context->report_error("MSL function used on a non-MSL backend.");
1084 return SPVC_ERROR_INVALID_ARGUMENT;
1085 }
1086
1087 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
1088 MSLShaderInput attr;
1089 attr.location = va->location;
1090 attr.format = static_cast<MSLShaderInputFormat>(va->format);
1091 attr.builtin = static_cast<spv::BuiltIn>(va->builtin);
1092 msl.add_msl_shader_input(attr);
1093 return SPVC_SUCCESS;
1094 #else
1095 (void)va;
1096 compiler->context->report_error("MSL function used on a non-MSL backend.");
1097 return SPVC_ERROR_INVALID_ARGUMENT;
1098 #endif
1099 }
1100
spvc_compiler_msl_add_shader_input(spvc_compiler compiler,const spvc_msl_shader_input * si)1101 spvc_result spvc_compiler_msl_add_shader_input(spvc_compiler compiler, const spvc_msl_shader_input *si)
1102 {
1103 #if SPIRV_CROSS_C_API_MSL
1104 if (compiler->backend != SPVC_BACKEND_MSL)
1105 {
1106 compiler->context->report_error("MSL function used on a non-MSL backend.");
1107 return SPVC_ERROR_INVALID_ARGUMENT;
1108 }
1109
1110 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
1111 MSLShaderInput input;
1112 input.location = si->location;
1113 input.format = static_cast<MSLShaderInputFormat>(si->format);
1114 input.builtin = static_cast<spv::BuiltIn>(si->builtin);
1115 input.vecsize = si->vecsize;
1116 msl.add_msl_shader_input(input);
1117 return SPVC_SUCCESS;
1118 #else
1119 (void)si;
1120 compiler->context->report_error("MSL function used on a non-MSL backend.");
1121 return SPVC_ERROR_INVALID_ARGUMENT;
1122 #endif
1123 }
1124
spvc_compiler_msl_add_resource_binding(spvc_compiler compiler,const spvc_msl_resource_binding * binding)1125 spvc_result spvc_compiler_msl_add_resource_binding(spvc_compiler compiler,
1126 const spvc_msl_resource_binding *binding)
1127 {
1128 #if SPIRV_CROSS_C_API_MSL
1129 if (compiler->backend != SPVC_BACKEND_MSL)
1130 {
1131 compiler->context->report_error("MSL function used on a non-MSL backend.");
1132 return SPVC_ERROR_INVALID_ARGUMENT;
1133 }
1134
1135 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
1136 MSLResourceBinding bind;
1137 bind.binding = binding->binding;
1138 bind.desc_set = binding->desc_set;
1139 bind.stage = static_cast<spv::ExecutionModel>(binding->stage);
1140 bind.msl_buffer = binding->msl_buffer;
1141 bind.msl_texture = binding->msl_texture;
1142 bind.msl_sampler = binding->msl_sampler;
1143 msl.add_msl_resource_binding(bind);
1144 return SPVC_SUCCESS;
1145 #else
1146 (void)binding;
1147 compiler->context->report_error("MSL function used on a non-MSL backend.");
1148 return SPVC_ERROR_INVALID_ARGUMENT;
1149 #endif
1150 }
1151
spvc_compiler_msl_add_dynamic_buffer(spvc_compiler compiler,unsigned desc_set,unsigned binding,unsigned index)1152 spvc_result spvc_compiler_msl_add_dynamic_buffer(spvc_compiler compiler, unsigned desc_set, unsigned binding, unsigned index)
1153 {
1154 #if SPIRV_CROSS_C_API_MSL
1155 if (compiler->backend != SPVC_BACKEND_MSL)
1156 {
1157 compiler->context->report_error("MSL function used on a non-MSL backend.");
1158 return SPVC_ERROR_INVALID_ARGUMENT;
1159 }
1160
1161 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
1162 msl.add_dynamic_buffer(desc_set, binding, index);
1163 return SPVC_SUCCESS;
1164 #else
1165 (void)binding;
1166 (void)desc_set;
1167 (void)index;
1168 compiler->context->report_error("MSL function used on a non-MSL backend.");
1169 return SPVC_ERROR_INVALID_ARGUMENT;
1170 #endif
1171 }
1172
spvc_compiler_msl_add_inline_uniform_block(spvc_compiler compiler,unsigned desc_set,unsigned binding)1173 spvc_result spvc_compiler_msl_add_inline_uniform_block(spvc_compiler compiler, unsigned desc_set, unsigned binding)
1174 {
1175 #if SPIRV_CROSS_C_API_MSL
1176 if (compiler->backend != SPVC_BACKEND_MSL)
1177 {
1178 compiler->context->report_error("MSL function used on a non-MSL backend.");
1179 return SPVC_ERROR_INVALID_ARGUMENT;
1180 }
1181
1182 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
1183 msl.add_inline_uniform_block(desc_set, binding);
1184 return SPVC_SUCCESS;
1185 #else
1186 (void)binding;
1187 (void)desc_set;
1188 compiler->context->report_error("MSL function used on a non-MSL backend.");
1189 return SPVC_ERROR_INVALID_ARGUMENT;
1190 #endif
1191 }
1192
spvc_compiler_msl_add_discrete_descriptor_set(spvc_compiler compiler,unsigned desc_set)1193 spvc_result spvc_compiler_msl_add_discrete_descriptor_set(spvc_compiler compiler, unsigned desc_set)
1194 {
1195 #if SPIRV_CROSS_C_API_MSL
1196 if (compiler->backend != SPVC_BACKEND_MSL)
1197 {
1198 compiler->context->report_error("MSL function used on a non-MSL backend.");
1199 return SPVC_ERROR_INVALID_ARGUMENT;
1200 }
1201
1202 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
1203 msl.add_discrete_descriptor_set(desc_set);
1204 return SPVC_SUCCESS;
1205 #else
1206 (void)desc_set;
1207 compiler->context->report_error("MSL function used on a non-MSL backend.");
1208 return SPVC_ERROR_INVALID_ARGUMENT;
1209 #endif
1210 }
1211
spvc_compiler_msl_set_argument_buffer_device_address_space(spvc_compiler compiler,unsigned desc_set,spvc_bool device_address)1212 spvc_result spvc_compiler_msl_set_argument_buffer_device_address_space(spvc_compiler compiler, unsigned desc_set, spvc_bool device_address)
1213 {
1214 #if SPIRV_CROSS_C_API_MSL
1215 if (compiler->backend != SPVC_BACKEND_MSL)
1216 {
1217 compiler->context->report_error("MSL function used on a non-MSL backend.");
1218 return SPVC_ERROR_INVALID_ARGUMENT;
1219 }
1220
1221 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
1222 msl.set_argument_buffer_device_address_space(desc_set, bool(device_address));
1223 return SPVC_SUCCESS;
1224 #else
1225 (void)desc_set;
1226 (void)device_address;
1227 compiler->context->report_error("MSL function used on a non-MSL backend.");
1228 return SPVC_ERROR_INVALID_ARGUMENT;
1229 #endif
1230 }
1231
spvc_compiler_msl_is_shader_input_used(spvc_compiler compiler,unsigned location)1232 spvc_bool spvc_compiler_msl_is_shader_input_used(spvc_compiler compiler, unsigned location)
1233 {
1234 #if SPIRV_CROSS_C_API_MSL
1235 if (compiler->backend != SPVC_BACKEND_MSL)
1236 {
1237 compiler->context->report_error("MSL function used on a non-MSL backend.");
1238 return SPVC_FALSE;
1239 }
1240
1241 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
1242 return msl.is_msl_shader_input_used(location) ? SPVC_TRUE : SPVC_FALSE;
1243 #else
1244 (void)location;
1245 compiler->context->report_error("MSL function used on a non-MSL backend.");
1246 return SPVC_FALSE;
1247 #endif
1248 }
1249
spvc_compiler_msl_is_vertex_attribute_used(spvc_compiler compiler,unsigned location)1250 spvc_bool spvc_compiler_msl_is_vertex_attribute_used(spvc_compiler compiler, unsigned location)
1251 {
1252 return spvc_compiler_msl_is_shader_input_used(compiler, location);
1253 }
1254
spvc_compiler_msl_is_resource_used(spvc_compiler compiler,SpvExecutionModel model,unsigned set,unsigned binding)1255 spvc_bool spvc_compiler_msl_is_resource_used(spvc_compiler compiler, SpvExecutionModel model, unsigned set,
1256 unsigned binding)
1257 {
1258 #if SPIRV_CROSS_C_API_MSL
1259 if (compiler->backend != SPVC_BACKEND_MSL)
1260 {
1261 compiler->context->report_error("MSL function used on a non-MSL backend.");
1262 return SPVC_FALSE;
1263 }
1264
1265 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
1266 return msl.is_msl_resource_binding_used(static_cast<spv::ExecutionModel>(model), set, binding) ? SPVC_TRUE :
1267 SPVC_FALSE;
1268 #else
1269 (void)model;
1270 (void)set;
1271 (void)binding;
1272 compiler->context->report_error("MSL function used on a non-MSL backend.");
1273 return SPVC_FALSE;
1274 #endif
1275 }
1276
spvc_compiler_msl_set_combined_sampler_suffix(spvc_compiler compiler,const char * suffix)1277 spvc_result spvc_compiler_msl_set_combined_sampler_suffix(spvc_compiler compiler, const char *suffix)
1278 {
1279 #if SPIRV_CROSS_C_API_MSL
1280 if (compiler->backend != SPVC_BACKEND_MSL)
1281 {
1282 compiler->context->report_error("MSL function used on a non-MSL backend.");
1283 return SPVC_ERROR_INVALID_ARGUMENT;
1284 }
1285
1286 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
1287 msl.set_combined_sampler_suffix(suffix);
1288 return SPVC_SUCCESS;
1289 #else
1290 (void)suffix;
1291 compiler->context->report_error("MSL function used on a non-MSL backend.");
1292 return SPVC_ERROR_INVALID_ARGUMENT;
1293 #endif
1294 }
1295
spvc_compiler_msl_get_combined_sampler_suffix(spvc_compiler compiler)1296 const char *spvc_compiler_msl_get_combined_sampler_suffix(spvc_compiler compiler)
1297 {
1298 #if SPIRV_CROSS_C_API_MSL
1299 if (compiler->backend != SPVC_BACKEND_MSL)
1300 {
1301 compiler->context->report_error("MSL function used on a non-MSL backend.");
1302 return "";
1303 }
1304
1305 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
1306 return msl.get_combined_sampler_suffix();
1307 #else
1308 compiler->context->report_error("MSL function used on a non-MSL backend.");
1309 return "";
1310 #endif
1311 }
1312
1313 #if SPIRV_CROSS_C_API_MSL
spvc_convert_msl_sampler(MSLConstexprSampler & samp,const spvc_msl_constexpr_sampler * sampler)1314 static void spvc_convert_msl_sampler(MSLConstexprSampler &samp, const spvc_msl_constexpr_sampler *sampler)
1315 {
1316 samp.s_address = static_cast<MSLSamplerAddress>(sampler->s_address);
1317 samp.t_address = static_cast<MSLSamplerAddress>(sampler->t_address);
1318 samp.r_address = static_cast<MSLSamplerAddress>(sampler->r_address);
1319 samp.lod_clamp_min = sampler->lod_clamp_min;
1320 samp.lod_clamp_max = sampler->lod_clamp_max;
1321 samp.lod_clamp_enable = sampler->lod_clamp_enable != 0;
1322 samp.min_filter = static_cast<MSLSamplerFilter>(sampler->min_filter);
1323 samp.mag_filter = static_cast<MSLSamplerFilter>(sampler->mag_filter);
1324 samp.mip_filter = static_cast<MSLSamplerMipFilter>(sampler->mip_filter);
1325 samp.compare_enable = sampler->compare_enable != 0;
1326 samp.anisotropy_enable = sampler->anisotropy_enable != 0;
1327 samp.max_anisotropy = sampler->max_anisotropy;
1328 samp.compare_func = static_cast<MSLSamplerCompareFunc>(sampler->compare_func);
1329 samp.coord = static_cast<MSLSamplerCoord>(sampler->coord);
1330 samp.border_color = static_cast<MSLSamplerBorderColor>(sampler->border_color);
1331 }
1332
spvc_convert_msl_sampler_ycbcr_conversion(MSLConstexprSampler & samp,const spvc_msl_sampler_ycbcr_conversion * conv)1333 static void spvc_convert_msl_sampler_ycbcr_conversion(MSLConstexprSampler &samp, const spvc_msl_sampler_ycbcr_conversion *conv)
1334 {
1335 samp.ycbcr_conversion_enable = conv != nullptr;
1336 if (conv == nullptr) return;
1337 samp.planes = conv->planes;
1338 samp.resolution = static_cast<MSLFormatResolution>(conv->resolution);
1339 samp.chroma_filter = static_cast<MSLSamplerFilter>(conv->chroma_filter);
1340 samp.x_chroma_offset = static_cast<MSLChromaLocation>(conv->x_chroma_offset);
1341 samp.y_chroma_offset = static_cast<MSLChromaLocation>(conv->y_chroma_offset);
1342 for (int i = 0; i < 4; i++)
1343 samp.swizzle[i] = static_cast<MSLComponentSwizzle>(conv->swizzle[i]);
1344 samp.ycbcr_model = static_cast<MSLSamplerYCbCrModelConversion>(conv->ycbcr_model);
1345 samp.ycbcr_range = static_cast<MSLSamplerYCbCrRange>(conv->ycbcr_range);
1346 samp.bpc = conv->bpc;
1347 }
1348 #endif
1349
spvc_compiler_msl_remap_constexpr_sampler(spvc_compiler compiler,spvc_variable_id id,const spvc_msl_constexpr_sampler * sampler)1350 spvc_result spvc_compiler_msl_remap_constexpr_sampler(spvc_compiler compiler, spvc_variable_id id,
1351 const spvc_msl_constexpr_sampler *sampler)
1352 {
1353 #if SPIRV_CROSS_C_API_MSL
1354 if (compiler->backend != SPVC_BACKEND_MSL)
1355 {
1356 compiler->context->report_error("MSL function used on a non-MSL backend.");
1357 return SPVC_ERROR_INVALID_ARGUMENT;
1358 }
1359
1360 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
1361 MSLConstexprSampler samp;
1362 spvc_convert_msl_sampler(samp, sampler);
1363 msl.remap_constexpr_sampler(id, samp);
1364 return SPVC_SUCCESS;
1365 #else
1366 (void)id;
1367 (void)sampler;
1368 compiler->context->report_error("MSL function used on a non-MSL backend.");
1369 return SPVC_ERROR_INVALID_ARGUMENT;
1370 #endif
1371 }
1372
spvc_compiler_msl_remap_constexpr_sampler_by_binding(spvc_compiler compiler,unsigned desc_set,unsigned binding,const spvc_msl_constexpr_sampler * sampler)1373 spvc_result spvc_compiler_msl_remap_constexpr_sampler_by_binding(spvc_compiler compiler,
1374 unsigned desc_set, unsigned binding,
1375 const spvc_msl_constexpr_sampler *sampler)
1376 {
1377 #if SPIRV_CROSS_C_API_MSL
1378 if (compiler->backend != SPVC_BACKEND_MSL)
1379 {
1380 compiler->context->report_error("MSL function used on a non-MSL backend.");
1381 return SPVC_ERROR_INVALID_ARGUMENT;
1382 }
1383
1384 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
1385 MSLConstexprSampler samp;
1386 spvc_convert_msl_sampler(samp, sampler);
1387 msl.remap_constexpr_sampler_by_binding(desc_set, binding, samp);
1388 return SPVC_SUCCESS;
1389 #else
1390 (void)desc_set;
1391 (void)binding;
1392 (void)sampler;
1393 compiler->context->report_error("MSL function used on a non-MSL backend.");
1394 return SPVC_ERROR_INVALID_ARGUMENT;
1395 #endif
1396 }
1397
spvc_compiler_msl_remap_constexpr_sampler_ycbcr(spvc_compiler compiler,spvc_variable_id id,const spvc_msl_constexpr_sampler * sampler,const spvc_msl_sampler_ycbcr_conversion * conv)1398 spvc_result spvc_compiler_msl_remap_constexpr_sampler_ycbcr(spvc_compiler compiler, spvc_variable_id id,
1399 const spvc_msl_constexpr_sampler *sampler,
1400 const spvc_msl_sampler_ycbcr_conversion *conv)
1401 {
1402 #if SPIRV_CROSS_C_API_MSL
1403 if (compiler->backend != SPVC_BACKEND_MSL)
1404 {
1405 compiler->context->report_error("MSL function used on a non-MSL backend.");
1406 return SPVC_ERROR_INVALID_ARGUMENT;
1407 }
1408
1409 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
1410 MSLConstexprSampler samp;
1411 spvc_convert_msl_sampler(samp, sampler);
1412 spvc_convert_msl_sampler_ycbcr_conversion(samp, conv);
1413 msl.remap_constexpr_sampler(id, samp);
1414 return SPVC_SUCCESS;
1415 #else
1416 (void)id;
1417 (void)sampler;
1418 (void)conv;
1419 compiler->context->report_error("MSL function used on a non-MSL backend.");
1420 return SPVC_ERROR_INVALID_ARGUMENT;
1421 #endif
1422 }
1423
spvc_compiler_msl_remap_constexpr_sampler_by_binding_ycbcr(spvc_compiler compiler,unsigned desc_set,unsigned binding,const spvc_msl_constexpr_sampler * sampler,const spvc_msl_sampler_ycbcr_conversion * conv)1424 spvc_result spvc_compiler_msl_remap_constexpr_sampler_by_binding_ycbcr(spvc_compiler compiler,
1425 unsigned desc_set, unsigned binding,
1426 const spvc_msl_constexpr_sampler *sampler,
1427 const spvc_msl_sampler_ycbcr_conversion *conv)
1428 {
1429 #if SPIRV_CROSS_C_API_MSL
1430 if (compiler->backend != SPVC_BACKEND_MSL)
1431 {
1432 compiler->context->report_error("MSL function used on a non-MSL backend.");
1433 return SPVC_ERROR_INVALID_ARGUMENT;
1434 }
1435
1436 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
1437 MSLConstexprSampler samp;
1438 spvc_convert_msl_sampler(samp, sampler);
1439 spvc_convert_msl_sampler_ycbcr_conversion(samp, conv);
1440 msl.remap_constexpr_sampler_by_binding(desc_set, binding, samp);
1441 return SPVC_SUCCESS;
1442 #else
1443 (void)desc_set;
1444 (void)binding;
1445 (void)sampler;
1446 (void)conv;
1447 compiler->context->report_error("MSL function used on a non-MSL backend.");
1448 return SPVC_ERROR_INVALID_ARGUMENT;
1449 #endif
1450 }
1451
spvc_compiler_msl_set_fragment_output_components(spvc_compiler compiler,unsigned location,unsigned components)1452 spvc_result spvc_compiler_msl_set_fragment_output_components(spvc_compiler compiler, unsigned location,
1453 unsigned components)
1454 {
1455 #if SPIRV_CROSS_C_API_MSL
1456 if (compiler->backend != SPVC_BACKEND_MSL)
1457 {
1458 compiler->context->report_error("MSL function used on a non-MSL backend.");
1459 return SPVC_ERROR_INVALID_ARGUMENT;
1460 }
1461
1462 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
1463 msl.set_fragment_output_components(location, components);
1464 return SPVC_SUCCESS;
1465 #else
1466 (void)location;
1467 (void)components;
1468 compiler->context->report_error("MSL function used on a non-MSL backend.");
1469 return SPVC_ERROR_INVALID_ARGUMENT;
1470 #endif
1471 }
1472
spvc_compiler_msl_get_automatic_resource_binding(spvc_compiler compiler,spvc_variable_id id)1473 unsigned spvc_compiler_msl_get_automatic_resource_binding(spvc_compiler compiler, spvc_variable_id id)
1474 {
1475 #if SPIRV_CROSS_C_API_MSL
1476 if (compiler->backend != SPVC_BACKEND_MSL)
1477 {
1478 compiler->context->report_error("MSL function used on a non-MSL backend.");
1479 return uint32_t(-1);
1480 }
1481
1482 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
1483 return msl.get_automatic_msl_resource_binding(id);
1484 #else
1485 (void)id;
1486 compiler->context->report_error("MSL function used on a non-MSL backend.");
1487 return uint32_t(-1);
1488 #endif
1489 }
1490
spvc_compiler_msl_get_automatic_resource_binding_secondary(spvc_compiler compiler,spvc_variable_id id)1491 unsigned spvc_compiler_msl_get_automatic_resource_binding_secondary(spvc_compiler compiler, spvc_variable_id id)
1492 {
1493 #if SPIRV_CROSS_C_API_MSL
1494 if (compiler->backend != SPVC_BACKEND_MSL)
1495 {
1496 compiler->context->report_error("MSL function used on a non-MSL backend.");
1497 return uint32_t(-1);
1498 }
1499
1500 auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
1501 return msl.get_automatic_msl_resource_binding_secondary(id);
1502 #else
1503 (void)id;
1504 compiler->context->report_error("MSL function used on a non-MSL backend.");
1505 return uint32_t(-1);
1506 #endif
1507 }
1508
spvc_compiler_compile(spvc_compiler compiler,const char ** source)1509 spvc_result spvc_compiler_compile(spvc_compiler compiler, const char **source)
1510 {
1511 SPVC_BEGIN_SAFE_SCOPE
1512 {
1513 auto result = compiler->compiler->compile();
1514 if (result.empty())
1515 {
1516 compiler->context->report_error("Unsupported SPIR-V.");
1517 return SPVC_ERROR_UNSUPPORTED_SPIRV;
1518 }
1519
1520 *source = compiler->context->allocate_name(result);
1521 if (!*source)
1522 {
1523 compiler->context->report_error("Out of memory.");
1524 return SPVC_ERROR_OUT_OF_MEMORY;
1525 }
1526 return SPVC_SUCCESS;
1527 }
1528 SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_UNSUPPORTED_SPIRV)
1529 }
1530
copy_resources(SmallVector<spvc_reflected_resource> & outputs,const SmallVector<Resource> & inputs)1531 bool spvc_resources_s::copy_resources(SmallVector<spvc_reflected_resource> &outputs,
1532 const SmallVector<Resource> &inputs)
1533 {
1534 for (auto &i : inputs)
1535 {
1536 spvc_reflected_resource r;
1537 r.base_type_id = i.base_type_id;
1538 r.type_id = i.type_id;
1539 r.id = i.id;
1540 r.name = context->allocate_name(i.name);
1541 if (!r.name)
1542 return false;
1543
1544 outputs.push_back(r);
1545 }
1546
1547 return true;
1548 }
1549
copy_resources(const ShaderResources & resources)1550 bool spvc_resources_s::copy_resources(const ShaderResources &resources)
1551 {
1552 if (!copy_resources(uniform_buffers, resources.uniform_buffers))
1553 return false;
1554 if (!copy_resources(storage_buffers, resources.storage_buffers))
1555 return false;
1556 if (!copy_resources(stage_inputs, resources.stage_inputs))
1557 return false;
1558 if (!copy_resources(stage_outputs, resources.stage_outputs))
1559 return false;
1560 if (!copy_resources(subpass_inputs, resources.subpass_inputs))
1561 return false;
1562 if (!copy_resources(storage_images, resources.storage_images))
1563 return false;
1564 if (!copy_resources(sampled_images, resources.sampled_images))
1565 return false;
1566 if (!copy_resources(atomic_counters, resources.atomic_counters))
1567 return false;
1568 if (!copy_resources(push_constant_buffers, resources.push_constant_buffers))
1569 return false;
1570 if (!copy_resources(separate_images, resources.separate_images))
1571 return false;
1572 if (!copy_resources(separate_samplers, resources.separate_samplers))
1573 return false;
1574 if (!copy_resources(acceleration_structures, resources.acceleration_structures))
1575 return false;
1576
1577 return true;
1578 }
1579
spvc_compiler_get_active_interface_variables(spvc_compiler compiler,spvc_set * set)1580 spvc_result spvc_compiler_get_active_interface_variables(spvc_compiler compiler, spvc_set *set)
1581 {
1582 SPVC_BEGIN_SAFE_SCOPE
1583 {
1584 std::unique_ptr<spvc_set_s> ptr(new (std::nothrow) spvc_set_s);
1585 if (!ptr)
1586 {
1587 compiler->context->report_error("Out of memory.");
1588 return SPVC_ERROR_OUT_OF_MEMORY;
1589 }
1590
1591 auto active = compiler->compiler->get_active_interface_variables();
1592 ptr->set = std::move(active);
1593 *set = ptr.get();
1594 compiler->context->allocations.push_back(std::move(ptr));
1595 }
1596 SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT)
1597 return SPVC_SUCCESS;
1598 }
1599
spvc_compiler_set_enabled_interface_variables(spvc_compiler compiler,spvc_set set)1600 spvc_result spvc_compiler_set_enabled_interface_variables(spvc_compiler compiler, spvc_set set)
1601 {
1602 SPVC_BEGIN_SAFE_SCOPE
1603 {
1604 compiler->compiler->set_enabled_interface_variables(set->set);
1605 }
1606 SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT)
1607 return SPVC_SUCCESS;
1608 }
1609
spvc_compiler_create_shader_resources_for_active_variables(spvc_compiler compiler,spvc_resources * resources,spvc_set set)1610 spvc_result spvc_compiler_create_shader_resources_for_active_variables(spvc_compiler compiler, spvc_resources *resources,
1611 spvc_set set)
1612 {
1613 SPVC_BEGIN_SAFE_SCOPE
1614 {
1615 std::unique_ptr<spvc_resources_s> res(new (std::nothrow) spvc_resources_s);
1616 if (!res)
1617 {
1618 compiler->context->report_error("Out of memory.");
1619 return SPVC_ERROR_OUT_OF_MEMORY;
1620 }
1621
1622 res->context = compiler->context;
1623 auto accessed_resources = compiler->compiler->get_shader_resources(set->set);
1624
1625 if (!res->copy_resources(accessed_resources))
1626 {
1627 res->context->report_error("Out of memory.");
1628 return SPVC_ERROR_OUT_OF_MEMORY;
1629 }
1630 *resources = res.get();
1631 compiler->context->allocations.push_back(std::move(res));
1632 }
1633 SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_OUT_OF_MEMORY)
1634 return SPVC_SUCCESS;
1635 }
1636
spvc_compiler_create_shader_resources(spvc_compiler compiler,spvc_resources * resources)1637 spvc_result spvc_compiler_create_shader_resources(spvc_compiler compiler, spvc_resources *resources)
1638 {
1639 SPVC_BEGIN_SAFE_SCOPE
1640 {
1641 std::unique_ptr<spvc_resources_s> res(new (std::nothrow) spvc_resources_s);
1642 if (!res)
1643 {
1644 compiler->context->report_error("Out of memory.");
1645 return SPVC_ERROR_OUT_OF_MEMORY;
1646 }
1647
1648 res->context = compiler->context;
1649 auto accessed_resources = compiler->compiler->get_shader_resources();
1650
1651 if (!res->copy_resources(accessed_resources))
1652 {
1653 res->context->report_error("Out of memory.");
1654 return SPVC_ERROR_OUT_OF_MEMORY;
1655 }
1656
1657 *resources = res.get();
1658 compiler->context->allocations.push_back(std::move(res));
1659 }
1660 SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_OUT_OF_MEMORY)
1661 return SPVC_SUCCESS;
1662 }
1663
spvc_resources_get_resource_list_for_type(spvc_resources resources,spvc_resource_type type,const spvc_reflected_resource ** resource_list,size_t * resource_size)1664 spvc_result spvc_resources_get_resource_list_for_type(spvc_resources resources, spvc_resource_type type,
1665 const spvc_reflected_resource **resource_list,
1666 size_t *resource_size)
1667 {
1668 const SmallVector<spvc_reflected_resource> *list = nullptr;
1669 switch (type)
1670 {
1671 case SPVC_RESOURCE_TYPE_UNIFORM_BUFFER:
1672 list = &resources->uniform_buffers;
1673 break;
1674
1675 case SPVC_RESOURCE_TYPE_STORAGE_BUFFER:
1676 list = &resources->storage_buffers;
1677 break;
1678
1679 case SPVC_RESOURCE_TYPE_STAGE_INPUT:
1680 list = &resources->stage_inputs;
1681 break;
1682
1683 case SPVC_RESOURCE_TYPE_STAGE_OUTPUT:
1684 list = &resources->stage_outputs;
1685 break;
1686
1687 case SPVC_RESOURCE_TYPE_SUBPASS_INPUT:
1688 list = &resources->subpass_inputs;
1689 break;
1690
1691 case SPVC_RESOURCE_TYPE_STORAGE_IMAGE:
1692 list = &resources->storage_images;
1693 break;
1694
1695 case SPVC_RESOURCE_TYPE_SAMPLED_IMAGE:
1696 list = &resources->sampled_images;
1697 break;
1698
1699 case SPVC_RESOURCE_TYPE_ATOMIC_COUNTER:
1700 list = &resources->atomic_counters;
1701 break;
1702
1703 case SPVC_RESOURCE_TYPE_PUSH_CONSTANT:
1704 list = &resources->push_constant_buffers;
1705 break;
1706
1707 case SPVC_RESOURCE_TYPE_SEPARATE_IMAGE:
1708 list = &resources->separate_images;
1709 break;
1710
1711 case SPVC_RESOURCE_TYPE_SEPARATE_SAMPLERS:
1712 list = &resources->separate_samplers;
1713 break;
1714
1715 case SPVC_RESOURCE_TYPE_ACCELERATION_STRUCTURE:
1716 list = &resources->acceleration_structures;
1717 break;
1718
1719 default:
1720 break;
1721 }
1722
1723 if (!list)
1724 {
1725 resources->context->report_error("Invalid argument.");
1726 return SPVC_ERROR_INVALID_ARGUMENT;
1727 }
1728
1729 *resource_size = list->size();
1730 *resource_list = list->data();
1731 return SPVC_SUCCESS;
1732 }
1733
spvc_compiler_set_decoration(spvc_compiler compiler,SpvId id,SpvDecoration decoration,unsigned argument)1734 void spvc_compiler_set_decoration(spvc_compiler compiler, SpvId id, SpvDecoration decoration, unsigned argument)
1735 {
1736 compiler->compiler->set_decoration(id, static_cast<spv::Decoration>(decoration), argument);
1737 }
1738
spvc_compiler_set_decoration_string(spvc_compiler compiler,SpvId id,SpvDecoration decoration,const char * argument)1739 void spvc_compiler_set_decoration_string(spvc_compiler compiler, SpvId id, SpvDecoration decoration,
1740 const char *argument)
1741 {
1742 compiler->compiler->set_decoration_string(id, static_cast<spv::Decoration>(decoration), argument);
1743 }
1744
spvc_compiler_set_name(spvc_compiler compiler,SpvId id,const char * argument)1745 void spvc_compiler_set_name(spvc_compiler compiler, SpvId id, const char *argument)
1746 {
1747 compiler->compiler->set_name(id, argument);
1748 }
1749
spvc_compiler_set_member_decoration(spvc_compiler compiler,spvc_type_id id,unsigned member_index,SpvDecoration decoration,unsigned argument)1750 void spvc_compiler_set_member_decoration(spvc_compiler compiler, spvc_type_id id, unsigned member_index,
1751 SpvDecoration decoration, unsigned argument)
1752 {
1753 compiler->compiler->set_member_decoration(id, member_index, static_cast<spv::Decoration>(decoration), argument);
1754 }
1755
spvc_compiler_set_member_decoration_string(spvc_compiler compiler,spvc_type_id id,unsigned member_index,SpvDecoration decoration,const char * argument)1756 void spvc_compiler_set_member_decoration_string(spvc_compiler compiler, spvc_type_id id, unsigned member_index,
1757 SpvDecoration decoration, const char *argument)
1758 {
1759 compiler->compiler->set_member_decoration_string(id, member_index, static_cast<spv::Decoration>(decoration),
1760 argument);
1761 }
1762
spvc_compiler_set_member_name(spvc_compiler compiler,spvc_type_id id,unsigned member_index,const char * argument)1763 void spvc_compiler_set_member_name(spvc_compiler compiler, spvc_type_id id, unsigned member_index, const char *argument)
1764 {
1765 compiler->compiler->set_member_name(id, member_index, argument);
1766 }
1767
spvc_compiler_unset_decoration(spvc_compiler compiler,SpvId id,SpvDecoration decoration)1768 void spvc_compiler_unset_decoration(spvc_compiler compiler, SpvId id, SpvDecoration decoration)
1769 {
1770 compiler->compiler->unset_decoration(id, static_cast<spv::Decoration>(decoration));
1771 }
1772
spvc_compiler_unset_member_decoration(spvc_compiler compiler,spvc_type_id id,unsigned member_index,SpvDecoration decoration)1773 void spvc_compiler_unset_member_decoration(spvc_compiler compiler, spvc_type_id id, unsigned member_index,
1774 SpvDecoration decoration)
1775 {
1776 compiler->compiler->unset_member_decoration(id, member_index, static_cast<spv::Decoration>(decoration));
1777 }
1778
spvc_compiler_has_decoration(spvc_compiler compiler,SpvId id,SpvDecoration decoration)1779 spvc_bool spvc_compiler_has_decoration(spvc_compiler compiler, SpvId id, SpvDecoration decoration)
1780 {
1781 return compiler->compiler->has_decoration(id, static_cast<spv::Decoration>(decoration)) ? SPVC_TRUE : SPVC_FALSE;
1782 }
1783
spvc_compiler_has_member_decoration(spvc_compiler compiler,spvc_type_id id,unsigned member_index,SpvDecoration decoration)1784 spvc_bool spvc_compiler_has_member_decoration(spvc_compiler compiler, spvc_type_id id, unsigned member_index,
1785 SpvDecoration decoration)
1786 {
1787 return compiler->compiler->has_member_decoration(id, member_index, static_cast<spv::Decoration>(decoration)) ?
1788 SPVC_TRUE :
1789 SPVC_FALSE;
1790 }
1791
spvc_compiler_get_name(spvc_compiler compiler,SpvId id)1792 const char *spvc_compiler_get_name(spvc_compiler compiler, SpvId id)
1793 {
1794 return compiler->compiler->get_name(id).c_str();
1795 }
1796
spvc_compiler_get_decoration(spvc_compiler compiler,SpvId id,SpvDecoration decoration)1797 unsigned spvc_compiler_get_decoration(spvc_compiler compiler, SpvId id, SpvDecoration decoration)
1798 {
1799 return compiler->compiler->get_decoration(id, static_cast<spv::Decoration>(decoration));
1800 }
1801
spvc_compiler_get_decoration_string(spvc_compiler compiler,SpvId id,SpvDecoration decoration)1802 const char *spvc_compiler_get_decoration_string(spvc_compiler compiler, SpvId id, SpvDecoration decoration)
1803 {
1804 return compiler->compiler->get_decoration_string(id, static_cast<spv::Decoration>(decoration)).c_str();
1805 }
1806
spvc_compiler_get_member_decoration(spvc_compiler compiler,spvc_type_id id,unsigned member_index,SpvDecoration decoration)1807 unsigned spvc_compiler_get_member_decoration(spvc_compiler compiler, spvc_type_id id, unsigned member_index,
1808 SpvDecoration decoration)
1809 {
1810 return compiler->compiler->get_member_decoration(id, member_index, static_cast<spv::Decoration>(decoration));
1811 }
1812
spvc_compiler_get_member_decoration_string(spvc_compiler compiler,spvc_type_id id,unsigned member_index,SpvDecoration decoration)1813 const char *spvc_compiler_get_member_decoration_string(spvc_compiler compiler, spvc_type_id id, unsigned member_index,
1814 SpvDecoration decoration)
1815 {
1816 return compiler->compiler->get_member_decoration_string(id, member_index, static_cast<spv::Decoration>(decoration))
1817 .c_str();
1818 }
1819
spvc_compiler_get_member_name(spvc_compiler compiler,spvc_type_id id,unsigned member_index)1820 const char *spvc_compiler_get_member_name(spvc_compiler compiler, spvc_type_id id, unsigned member_index)
1821 {
1822 return compiler->compiler->get_member_name(id, member_index).c_str();
1823 }
1824
spvc_compiler_get_entry_points(spvc_compiler compiler,const spvc_entry_point ** entry_points,size_t * num_entry_points)1825 spvc_result spvc_compiler_get_entry_points(spvc_compiler compiler, const spvc_entry_point **entry_points,
1826 size_t *num_entry_points)
1827 {
1828 SPVC_BEGIN_SAFE_SCOPE
1829 {
1830 auto entries = compiler->compiler->get_entry_points_and_stages();
1831 SmallVector<spvc_entry_point> translated;
1832 translated.reserve(entries.size());
1833
1834 for (auto &entry : entries)
1835 {
1836 spvc_entry_point new_entry;
1837 new_entry.execution_model = static_cast<SpvExecutionModel>(entry.execution_model);
1838 new_entry.name = compiler->context->allocate_name(entry.name);
1839 if (!new_entry.name)
1840 {
1841 compiler->context->report_error("Out of memory.");
1842 return SPVC_ERROR_OUT_OF_MEMORY;
1843 }
1844 translated.push_back(new_entry);
1845 }
1846
1847 auto ptr = spvc_allocate<TemporaryBuffer<spvc_entry_point>>();
1848 ptr->buffer = std::move(translated);
1849 *entry_points = ptr->buffer.data();
1850 *num_entry_points = ptr->buffer.size();
1851 compiler->context->allocations.push_back(std::move(ptr));
1852 }
1853 SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_OUT_OF_MEMORY)
1854 return SPVC_SUCCESS;
1855 }
1856
spvc_compiler_set_entry_point(spvc_compiler compiler,const char * name,SpvExecutionModel model)1857 spvc_result spvc_compiler_set_entry_point(spvc_compiler compiler, const char *name, SpvExecutionModel model)
1858 {
1859 compiler->compiler->set_entry_point(name, static_cast<spv::ExecutionModel>(model));
1860 return SPVC_SUCCESS;
1861 }
1862
spvc_compiler_rename_entry_point(spvc_compiler compiler,const char * old_name,const char * new_name,SpvExecutionModel model)1863 spvc_result spvc_compiler_rename_entry_point(spvc_compiler compiler, const char *old_name, const char *new_name,
1864 SpvExecutionModel model)
1865 {
1866 SPVC_BEGIN_SAFE_SCOPE
1867 {
1868 compiler->compiler->rename_entry_point(old_name, new_name, static_cast<spv::ExecutionModel>(model));
1869 }
1870 SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT)
1871 return SPVC_SUCCESS;
1872 }
1873
spvc_compiler_get_cleansed_entry_point_name(spvc_compiler compiler,const char * name,SpvExecutionModel model)1874 const char *spvc_compiler_get_cleansed_entry_point_name(spvc_compiler compiler, const char *name,
1875 SpvExecutionModel model)
1876 {
1877 SPVC_BEGIN_SAFE_SCOPE
1878 {
1879 auto cleansed_name =
1880 compiler->compiler->get_cleansed_entry_point_name(name, static_cast<spv::ExecutionModel>(model));
1881 return compiler->context->allocate_name(cleansed_name);
1882 }
1883 SPVC_END_SAFE_SCOPE(compiler->context, nullptr)
1884 }
1885
spvc_compiler_set_execution_mode(spvc_compiler compiler,SpvExecutionMode mode)1886 void spvc_compiler_set_execution_mode(spvc_compiler compiler, SpvExecutionMode mode)
1887 {
1888 compiler->compiler->set_execution_mode(static_cast<spv::ExecutionMode>(mode));
1889 }
1890
spvc_compiler_set_execution_mode_with_arguments(spvc_compiler compiler,SpvExecutionMode mode,unsigned arg0,unsigned arg1,unsigned arg2)1891 void spvc_compiler_set_execution_mode_with_arguments(spvc_compiler compiler, SpvExecutionMode mode, unsigned arg0,
1892 unsigned arg1,
1893 unsigned arg2)
1894 {
1895 compiler->compiler->set_execution_mode(static_cast<spv::ExecutionMode>(mode), arg0, arg1, arg2);
1896 }
1897
spvc_compiler_unset_execution_mode(spvc_compiler compiler,SpvExecutionMode mode)1898 void spvc_compiler_unset_execution_mode(spvc_compiler compiler, SpvExecutionMode mode)
1899 {
1900 compiler->compiler->unset_execution_mode(static_cast<spv::ExecutionMode>(mode));
1901 }
1902
spvc_compiler_get_execution_modes(spvc_compiler compiler,const SpvExecutionMode ** modes,size_t * num_modes)1903 spvc_result spvc_compiler_get_execution_modes(spvc_compiler compiler, const SpvExecutionMode **modes, size_t *num_modes)
1904 {
1905 SPVC_BEGIN_SAFE_SCOPE
1906 {
1907 auto ptr = spvc_allocate<TemporaryBuffer<SpvExecutionMode>>();
1908
1909 compiler->compiler->get_execution_mode_bitset().for_each_bit(
1910 [&](uint32_t bit) { ptr->buffer.push_back(static_cast<SpvExecutionMode>(bit)); });
1911
1912 *modes = ptr->buffer.data();
1913 *num_modes = ptr->buffer.size();
1914 compiler->context->allocations.push_back(std::move(ptr));
1915 }
1916 SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_OUT_OF_MEMORY)
1917 return SPVC_SUCCESS;
1918 }
1919
spvc_compiler_get_execution_mode_argument(spvc_compiler compiler,SpvExecutionMode mode)1920 unsigned spvc_compiler_get_execution_mode_argument(spvc_compiler compiler, SpvExecutionMode mode)
1921 {
1922 return compiler->compiler->get_execution_mode_argument(static_cast<spv::ExecutionMode>(mode));
1923 }
1924
spvc_compiler_get_execution_mode_argument_by_index(spvc_compiler compiler,SpvExecutionMode mode,unsigned index)1925 unsigned spvc_compiler_get_execution_mode_argument_by_index(spvc_compiler compiler, SpvExecutionMode mode,
1926 unsigned index)
1927 {
1928 return compiler->compiler->get_execution_mode_argument(static_cast<spv::ExecutionMode>(mode), index);
1929 }
1930
spvc_compiler_get_execution_model(spvc_compiler compiler)1931 SpvExecutionModel spvc_compiler_get_execution_model(spvc_compiler compiler)
1932 {
1933 return static_cast<SpvExecutionModel>(compiler->compiler->get_execution_model());
1934 }
1935
spvc_compiler_get_type_handle(spvc_compiler compiler,spvc_type_id id)1936 spvc_type spvc_compiler_get_type_handle(spvc_compiler compiler, spvc_type_id id)
1937 {
1938 // Should only throw if an intentionally garbage ID is passed, but the IDs are not type-safe.
1939 SPVC_BEGIN_SAFE_SCOPE
1940 {
1941 return static_cast<spvc_type>(&compiler->compiler->get_type(id));
1942 }
1943 SPVC_END_SAFE_SCOPE(compiler->context, nullptr)
1944 }
1945
spvc_type_get_base_type_id(spvc_type type)1946 spvc_type_id spvc_type_get_base_type_id(spvc_type type)
1947 {
1948 return type->self;
1949 }
1950
convert_basetype(SPIRType::BaseType type)1951 static spvc_basetype convert_basetype(SPIRType::BaseType type)
1952 {
1953 // For now the enums match up.
1954 return static_cast<spvc_basetype>(type);
1955 }
1956
spvc_type_get_basetype(spvc_type type)1957 spvc_basetype spvc_type_get_basetype(spvc_type type)
1958 {
1959 return convert_basetype(type->basetype);
1960 }
1961
spvc_type_get_bit_width(spvc_type type)1962 unsigned spvc_type_get_bit_width(spvc_type type)
1963 {
1964 return type->width;
1965 }
1966
spvc_type_get_vector_size(spvc_type type)1967 unsigned spvc_type_get_vector_size(spvc_type type)
1968 {
1969 return type->vecsize;
1970 }
1971
spvc_type_get_columns(spvc_type type)1972 unsigned spvc_type_get_columns(spvc_type type)
1973 {
1974 return type->columns;
1975 }
1976
spvc_type_get_num_array_dimensions(spvc_type type)1977 unsigned spvc_type_get_num_array_dimensions(spvc_type type)
1978 {
1979 return unsigned(type->array.size());
1980 }
1981
spvc_type_array_dimension_is_literal(spvc_type type,unsigned dimension)1982 spvc_bool spvc_type_array_dimension_is_literal(spvc_type type, unsigned dimension)
1983 {
1984 return type->array_size_literal[dimension] ? SPVC_TRUE : SPVC_FALSE;
1985 }
1986
spvc_type_get_array_dimension(spvc_type type,unsigned dimension)1987 SpvId spvc_type_get_array_dimension(spvc_type type, unsigned dimension)
1988 {
1989 return type->array[dimension];
1990 }
1991
spvc_type_get_num_member_types(spvc_type type)1992 unsigned spvc_type_get_num_member_types(spvc_type type)
1993 {
1994 return unsigned(type->member_types.size());
1995 }
1996
spvc_type_get_member_type(spvc_type type,unsigned index)1997 spvc_type_id spvc_type_get_member_type(spvc_type type, unsigned index)
1998 {
1999 return type->member_types[index];
2000 }
2001
spvc_type_get_storage_class(spvc_type type)2002 SpvStorageClass spvc_type_get_storage_class(spvc_type type)
2003 {
2004 return static_cast<SpvStorageClass>(type->storage);
2005 }
2006
2007 // Image type query.
spvc_type_get_image_sampled_type(spvc_type type)2008 spvc_type_id spvc_type_get_image_sampled_type(spvc_type type)
2009 {
2010 return type->image.type;
2011 }
2012
spvc_type_get_image_dimension(spvc_type type)2013 SpvDim spvc_type_get_image_dimension(spvc_type type)
2014 {
2015 return static_cast<SpvDim>(type->image.dim);
2016 }
2017
spvc_type_get_image_is_depth(spvc_type type)2018 spvc_bool spvc_type_get_image_is_depth(spvc_type type)
2019 {
2020 return type->image.depth ? SPVC_TRUE : SPVC_FALSE;
2021 }
2022
spvc_type_get_image_arrayed(spvc_type type)2023 spvc_bool spvc_type_get_image_arrayed(spvc_type type)
2024 {
2025 return type->image.arrayed ? SPVC_TRUE : SPVC_FALSE;
2026 }
2027
spvc_type_get_image_multisampled(spvc_type type)2028 spvc_bool spvc_type_get_image_multisampled(spvc_type type)
2029 {
2030 return type->image.ms ? SPVC_TRUE : SPVC_FALSE;
2031 }
2032
spvc_type_get_image_is_storage(spvc_type type)2033 spvc_bool spvc_type_get_image_is_storage(spvc_type type)
2034 {
2035 return type->image.sampled == 2 ? SPVC_TRUE : SPVC_FALSE;
2036 }
2037
spvc_type_get_image_storage_format(spvc_type type)2038 SpvImageFormat spvc_type_get_image_storage_format(spvc_type type)
2039 {
2040 return static_cast<SpvImageFormat>(static_cast<const SPIRType *>(type)->image.format);
2041 }
2042
spvc_type_get_image_access_qualifier(spvc_type type)2043 SpvAccessQualifier spvc_type_get_image_access_qualifier(spvc_type type)
2044 {
2045 return static_cast<SpvAccessQualifier>(static_cast<const SPIRType *>(type)->image.access);
2046 }
2047
spvc_compiler_get_declared_struct_size(spvc_compiler compiler,spvc_type struct_type,size_t * size)2048 spvc_result spvc_compiler_get_declared_struct_size(spvc_compiler compiler, spvc_type struct_type, size_t *size)
2049 {
2050 SPVC_BEGIN_SAFE_SCOPE
2051 {
2052 *size = compiler->compiler->get_declared_struct_size(*static_cast<const SPIRType *>(struct_type));
2053 }
2054 SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT)
2055 return SPVC_SUCCESS;
2056 }
2057
spvc_compiler_get_declared_struct_size_runtime_array(spvc_compiler compiler,spvc_type struct_type,size_t array_size,size_t * size)2058 spvc_result spvc_compiler_get_declared_struct_size_runtime_array(spvc_compiler compiler, spvc_type struct_type,
2059 size_t array_size, size_t *size)
2060 {
2061 SPVC_BEGIN_SAFE_SCOPE
2062 {
2063 *size = compiler->compiler->get_declared_struct_size_runtime_array(*static_cast<const SPIRType *>(struct_type),
2064 array_size);
2065 }
2066 SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT)
2067 return SPVC_SUCCESS;
2068 }
2069
spvc_compiler_get_declared_struct_member_size(spvc_compiler compiler,spvc_type struct_type,unsigned index,size_t * size)2070 spvc_result spvc_compiler_get_declared_struct_member_size(spvc_compiler compiler, spvc_type struct_type, unsigned index, size_t *size)
2071 {
2072 SPVC_BEGIN_SAFE_SCOPE
2073 {
2074 *size = compiler->compiler->get_declared_struct_member_size(*static_cast<const SPIRType *>(struct_type), index);
2075 }
2076 SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT)
2077 return SPVC_SUCCESS;
2078 }
2079
spvc_compiler_type_struct_member_offset(spvc_compiler compiler,spvc_type type,unsigned index,unsigned * offset)2080 spvc_result spvc_compiler_type_struct_member_offset(spvc_compiler compiler, spvc_type type, unsigned index, unsigned *offset)
2081 {
2082 SPVC_BEGIN_SAFE_SCOPE
2083 {
2084 *offset = compiler->compiler->type_struct_member_offset(*static_cast<const SPIRType *>(type), index);
2085 }
2086 SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT)
2087 return SPVC_SUCCESS;
2088 }
2089
spvc_compiler_type_struct_member_array_stride(spvc_compiler compiler,spvc_type type,unsigned index,unsigned * stride)2090 spvc_result spvc_compiler_type_struct_member_array_stride(spvc_compiler compiler, spvc_type type, unsigned index, unsigned *stride)
2091 {
2092 SPVC_BEGIN_SAFE_SCOPE
2093 {
2094 *stride = compiler->compiler->type_struct_member_array_stride(*static_cast<const SPIRType *>(type), index);
2095 }
2096 SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT)
2097 return SPVC_SUCCESS;
2098 }
2099
spvc_compiler_type_struct_member_matrix_stride(spvc_compiler compiler,spvc_type type,unsigned index,unsigned * stride)2100 spvc_result spvc_compiler_type_struct_member_matrix_stride(spvc_compiler compiler, spvc_type type, unsigned index, unsigned *stride)
2101 {
2102 SPVC_BEGIN_SAFE_SCOPE
2103 {
2104 *stride = compiler->compiler->type_struct_member_matrix_stride(*static_cast<const SPIRType *>(type), index);
2105 }
2106 SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT)
2107 return SPVC_SUCCESS;
2108 }
2109
spvc_compiler_build_dummy_sampler_for_combined_images(spvc_compiler compiler,spvc_variable_id * id)2110 spvc_result spvc_compiler_build_dummy_sampler_for_combined_images(spvc_compiler compiler, spvc_variable_id *id)
2111 {
2112 SPVC_BEGIN_SAFE_SCOPE
2113 {
2114 *id = compiler->compiler->build_dummy_sampler_for_combined_images();
2115 }
2116 SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT)
2117 return SPVC_SUCCESS;
2118 }
2119
spvc_compiler_build_combined_image_samplers(spvc_compiler compiler)2120 spvc_result spvc_compiler_build_combined_image_samplers(spvc_compiler compiler)
2121 {
2122 SPVC_BEGIN_SAFE_SCOPE
2123 {
2124 compiler->compiler->build_combined_image_samplers();
2125 }
2126 SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_UNSUPPORTED_SPIRV)
2127 return SPVC_SUCCESS;
2128 }
2129
spvc_compiler_get_combined_image_samplers(spvc_compiler compiler,const spvc_combined_image_sampler ** samplers,size_t * num_samplers)2130 spvc_result spvc_compiler_get_combined_image_samplers(spvc_compiler compiler,
2131 const spvc_combined_image_sampler **samplers,
2132 size_t *num_samplers)
2133 {
2134 SPVC_BEGIN_SAFE_SCOPE
2135 {
2136 auto combined = compiler->compiler->get_combined_image_samplers();
2137 SmallVector<spvc_combined_image_sampler> translated;
2138 translated.reserve(combined.size());
2139 for (auto &c : combined)
2140 {
2141 spvc_combined_image_sampler trans = { c.combined_id, c.image_id, c.sampler_id };
2142 translated.push_back(trans);
2143 }
2144
2145 auto ptr = spvc_allocate<TemporaryBuffer<spvc_combined_image_sampler>>();
2146 ptr->buffer = std::move(translated);
2147 *samplers = ptr->buffer.data();
2148 *num_samplers = ptr->buffer.size();
2149 compiler->context->allocations.push_back(std::move(ptr));
2150 }
2151 SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_OUT_OF_MEMORY)
2152 return SPVC_SUCCESS;
2153 }
2154
spvc_compiler_get_specialization_constants(spvc_compiler compiler,const spvc_specialization_constant ** constants,size_t * num_constants)2155 spvc_result spvc_compiler_get_specialization_constants(spvc_compiler compiler,
2156 const spvc_specialization_constant **constants,
2157 size_t *num_constants)
2158 {
2159 SPVC_BEGIN_SAFE_SCOPE
2160 {
2161 auto spec_constants = compiler->compiler->get_specialization_constants();
2162 SmallVector<spvc_specialization_constant> translated;
2163 translated.reserve(spec_constants.size());
2164 for (auto &c : spec_constants)
2165 {
2166 spvc_specialization_constant trans = { c.id, c.constant_id };
2167 translated.push_back(trans);
2168 }
2169
2170 auto ptr = spvc_allocate<TemporaryBuffer<spvc_specialization_constant>>();
2171 ptr->buffer = std::move(translated);
2172 *constants = ptr->buffer.data();
2173 *num_constants = ptr->buffer.size();
2174 compiler->context->allocations.push_back(std::move(ptr));
2175 }
2176 SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_OUT_OF_MEMORY)
2177 return SPVC_SUCCESS;
2178 }
2179
spvc_compiler_get_constant_handle(spvc_compiler compiler,spvc_variable_id id)2180 spvc_constant spvc_compiler_get_constant_handle(spvc_compiler compiler, spvc_variable_id id)
2181 {
2182 SPVC_BEGIN_SAFE_SCOPE
2183 {
2184 return static_cast<spvc_constant>(&compiler->compiler->get_constant(id));
2185 }
2186 SPVC_END_SAFE_SCOPE(compiler->context, nullptr)
2187 }
2188
spvc_compiler_get_work_group_size_specialization_constants(spvc_compiler compiler,spvc_specialization_constant * x,spvc_specialization_constant * y,spvc_specialization_constant * z)2189 spvc_constant_id spvc_compiler_get_work_group_size_specialization_constants(spvc_compiler compiler,
2190 spvc_specialization_constant *x,
2191 spvc_specialization_constant *y,
2192 spvc_specialization_constant *z)
2193 {
2194 SpecializationConstant tmpx;
2195 SpecializationConstant tmpy;
2196 SpecializationConstant tmpz;
2197 spvc_constant_id ret = compiler->compiler->get_work_group_size_specialization_constants(tmpx, tmpy, tmpz);
2198 x->id = tmpx.id;
2199 x->constant_id = tmpx.constant_id;
2200 y->id = tmpy.id;
2201 y->constant_id = tmpy.constant_id;
2202 z->id = tmpz.id;
2203 z->constant_id = tmpz.constant_id;
2204 return ret;
2205 }
2206
spvc_compiler_get_active_buffer_ranges(spvc_compiler compiler,spvc_variable_id id,const spvc_buffer_range ** ranges,size_t * num_ranges)2207 spvc_result spvc_compiler_get_active_buffer_ranges(spvc_compiler compiler,
2208 spvc_variable_id id,
2209 const spvc_buffer_range **ranges,
2210 size_t *num_ranges)
2211 {
2212 SPVC_BEGIN_SAFE_SCOPE
2213 {
2214 auto active_ranges = compiler->compiler->get_active_buffer_ranges(id);
2215 SmallVector<spvc_buffer_range> translated;
2216 translated.reserve(active_ranges.size());
2217 for (auto &r : active_ranges)
2218 {
2219 spvc_buffer_range trans = { r.index, r.offset, r.range };
2220 translated.push_back(trans);
2221 }
2222
2223 auto ptr = spvc_allocate<TemporaryBuffer<spvc_buffer_range>>();
2224 ptr->buffer = std::move(translated);
2225 *ranges = ptr->buffer.data();
2226 *num_ranges = ptr->buffer.size();
2227 compiler->context->allocations.push_back(std::move(ptr));
2228 }
2229 SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_OUT_OF_MEMORY)
2230 return SPVC_SUCCESS;
2231 }
2232
spvc_constant_get_scalar_fp16(spvc_constant constant,unsigned column,unsigned row)2233 float spvc_constant_get_scalar_fp16(spvc_constant constant, unsigned column, unsigned row)
2234 {
2235 return constant->scalar_f16(column, row);
2236 }
2237
spvc_constant_get_scalar_fp32(spvc_constant constant,unsigned column,unsigned row)2238 float spvc_constant_get_scalar_fp32(spvc_constant constant, unsigned column, unsigned row)
2239 {
2240 return constant->scalar_f32(column, row);
2241 }
2242
spvc_constant_get_scalar_fp64(spvc_constant constant,unsigned column,unsigned row)2243 double spvc_constant_get_scalar_fp64(spvc_constant constant, unsigned column, unsigned row)
2244 {
2245 return constant->scalar_f64(column, row);
2246 }
2247
spvc_constant_get_scalar_u32(spvc_constant constant,unsigned column,unsigned row)2248 unsigned spvc_constant_get_scalar_u32(spvc_constant constant, unsigned column, unsigned row)
2249 {
2250 return constant->scalar(column, row);
2251 }
2252
spvc_constant_get_scalar_i32(spvc_constant constant,unsigned column,unsigned row)2253 int spvc_constant_get_scalar_i32(spvc_constant constant, unsigned column, unsigned row)
2254 {
2255 return constant->scalar_i32(column, row);
2256 }
2257
spvc_constant_get_scalar_u16(spvc_constant constant,unsigned column,unsigned row)2258 unsigned spvc_constant_get_scalar_u16(spvc_constant constant, unsigned column, unsigned row)
2259 {
2260 return constant->scalar_u16(column, row);
2261 }
2262
spvc_constant_get_scalar_i16(spvc_constant constant,unsigned column,unsigned row)2263 int spvc_constant_get_scalar_i16(spvc_constant constant, unsigned column, unsigned row)
2264 {
2265 return constant->scalar_i16(column, row);
2266 }
2267
spvc_constant_get_scalar_u8(spvc_constant constant,unsigned column,unsigned row)2268 unsigned spvc_constant_get_scalar_u8(spvc_constant constant, unsigned column, unsigned row)
2269 {
2270 return constant->scalar_u8(column, row);
2271 }
2272
spvc_constant_get_scalar_i8(spvc_constant constant,unsigned column,unsigned row)2273 int spvc_constant_get_scalar_i8(spvc_constant constant, unsigned column, unsigned row)
2274 {
2275 return constant->scalar_i8(column, row);
2276 }
2277
spvc_constant_get_subconstants(spvc_constant constant,const spvc_constant_id ** constituents,size_t * count)2278 void spvc_constant_get_subconstants(spvc_constant constant, const spvc_constant_id **constituents, size_t *count)
2279 {
2280 static_assert(sizeof(spvc_constant_id) == sizeof(constant->subconstants.front()), "ID size is not consistent.");
2281 *constituents = reinterpret_cast<spvc_constant_id *>(constant->subconstants.data());
2282 *count = constant->subconstants.size();
2283 }
2284
spvc_constant_get_type(spvc_constant constant)2285 spvc_type_id spvc_constant_get_type(spvc_constant constant)
2286 {
2287 return constant->constant_type;
2288 }
2289
spvc_compiler_get_binary_offset_for_decoration(spvc_compiler compiler,spvc_variable_id id,SpvDecoration decoration,unsigned * word_offset)2290 spvc_bool spvc_compiler_get_binary_offset_for_decoration(spvc_compiler compiler, spvc_variable_id id,
2291 SpvDecoration decoration,
2292 unsigned *word_offset)
2293 {
2294 uint32_t off = 0;
2295 bool ret = compiler->compiler->get_binary_offset_for_decoration(id, static_cast<spv::Decoration>(decoration), off);
2296 if (ret)
2297 {
2298 *word_offset = off;
2299 return SPVC_TRUE;
2300 }
2301 else
2302 return SPVC_FALSE;
2303 }
2304
spvc_compiler_buffer_is_hlsl_counter_buffer(spvc_compiler compiler,spvc_variable_id id)2305 spvc_bool spvc_compiler_buffer_is_hlsl_counter_buffer(spvc_compiler compiler, spvc_variable_id id)
2306 {
2307 return compiler->compiler->buffer_is_hlsl_counter_buffer(id) ? SPVC_TRUE : SPVC_FALSE;
2308 }
2309
spvc_compiler_buffer_get_hlsl_counter_buffer(spvc_compiler compiler,spvc_variable_id id,spvc_variable_id * counter_id)2310 spvc_bool spvc_compiler_buffer_get_hlsl_counter_buffer(spvc_compiler compiler, spvc_variable_id id,
2311 spvc_variable_id *counter_id)
2312 {
2313 uint32_t buffer;
2314 bool ret = compiler->compiler->buffer_get_hlsl_counter_buffer(id, buffer);
2315 if (ret)
2316 {
2317 *counter_id = buffer;
2318 return SPVC_TRUE;
2319 }
2320 else
2321 return SPVC_FALSE;
2322 }
2323
spvc_compiler_get_declared_capabilities(spvc_compiler compiler,const SpvCapability ** capabilities,size_t * num_capabilities)2324 spvc_result spvc_compiler_get_declared_capabilities(spvc_compiler compiler, const SpvCapability **capabilities,
2325 size_t *num_capabilities)
2326 {
2327 auto &caps = compiler->compiler->get_declared_capabilities();
2328 static_assert(sizeof(SpvCapability) == sizeof(spv::Capability), "Enum size mismatch.");
2329 *capabilities = reinterpret_cast<const SpvCapability *>(caps.data());
2330 *num_capabilities = caps.size();
2331 return SPVC_SUCCESS;
2332 }
2333
spvc_compiler_get_declared_extensions(spvc_compiler compiler,const char *** extensions,size_t * num_extensions)2334 spvc_result spvc_compiler_get_declared_extensions(spvc_compiler compiler, const char ***extensions,
2335 size_t *num_extensions)
2336 {
2337 SPVC_BEGIN_SAFE_SCOPE
2338 {
2339 auto &exts = compiler->compiler->get_declared_extensions();
2340 SmallVector<const char *> duped;
2341 duped.reserve(exts.size());
2342 for (auto &ext : exts)
2343 duped.push_back(compiler->context->allocate_name(ext));
2344
2345 auto ptr = spvc_allocate<TemporaryBuffer<const char *>>();
2346 ptr->buffer = std::move(duped);
2347 *extensions = ptr->buffer.data();
2348 *num_extensions = ptr->buffer.size();
2349 compiler->context->allocations.push_back(std::move(ptr));
2350 }
2351 SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_OUT_OF_MEMORY)
2352 return SPVC_SUCCESS;
2353 }
2354
spvc_compiler_get_remapped_declared_block_name(spvc_compiler compiler,spvc_variable_id id)2355 const char *spvc_compiler_get_remapped_declared_block_name(spvc_compiler compiler, spvc_variable_id id)
2356 {
2357 SPVC_BEGIN_SAFE_SCOPE
2358 {
2359 auto name = compiler->compiler->get_remapped_declared_block_name(id);
2360 return compiler->context->allocate_name(name);
2361 }
2362 SPVC_END_SAFE_SCOPE(compiler->context, nullptr)
2363 }
2364
spvc_compiler_get_buffer_block_decorations(spvc_compiler compiler,spvc_variable_id id,const SpvDecoration ** decorations,size_t * num_decorations)2365 spvc_result spvc_compiler_get_buffer_block_decorations(spvc_compiler compiler, spvc_variable_id id,
2366 const SpvDecoration **decorations, size_t *num_decorations)
2367 {
2368 SPVC_BEGIN_SAFE_SCOPE
2369 {
2370 auto flags = compiler->compiler->get_buffer_block_flags(id);
2371 auto bitset = spvc_allocate<TemporaryBuffer<SpvDecoration>>();
2372
2373 flags.for_each_bit([&](uint32_t bit) { bitset->buffer.push_back(static_cast<SpvDecoration>(bit)); });
2374
2375 *decorations = bitset->buffer.data();
2376 *num_decorations = bitset->buffer.size();
2377 compiler->context->allocations.push_back(std::move(bitset));
2378 }
2379 SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT)
2380 return SPVC_SUCCESS;
2381 }
2382
spvc_msl_get_aux_buffer_struct_version(void)2383 unsigned spvc_msl_get_aux_buffer_struct_version(void)
2384 {
2385 return SPVC_MSL_AUX_BUFFER_STRUCT_VERSION;
2386 }
2387
spvc_msl_vertex_attribute_init(spvc_msl_vertex_attribute * attr)2388 void spvc_msl_vertex_attribute_init(spvc_msl_vertex_attribute *attr)
2389 {
2390 #if SPIRV_CROSS_C_API_MSL
2391 // Crude, but works.
2392 MSLShaderInput attr_default;
2393 attr->location = attr_default.location;
2394 attr->format = static_cast<spvc_msl_vertex_format>(attr_default.format);
2395 attr->builtin = static_cast<SpvBuiltIn>(attr_default.builtin);
2396 #else
2397 memset(attr, 0, sizeof(*attr));
2398 #endif
2399 }
2400
spvc_msl_shader_input_init(spvc_msl_shader_input * input)2401 void spvc_msl_shader_input_init(spvc_msl_shader_input *input)
2402 {
2403 #if SPIRV_CROSS_C_API_MSL
2404 MSLShaderInput input_default;
2405 input->location = input_default.location;
2406 input->format = static_cast<spvc_msl_shader_input_format>(input_default.format);
2407 input->builtin = static_cast<SpvBuiltIn>(input_default.builtin);
2408 input->vecsize = input_default.vecsize;
2409 #else
2410 memset(input, 0, sizeof(*input));
2411 #endif
2412 }
2413
spvc_msl_resource_binding_init(spvc_msl_resource_binding * binding)2414 void spvc_msl_resource_binding_init(spvc_msl_resource_binding *binding)
2415 {
2416 #if SPIRV_CROSS_C_API_MSL
2417 MSLResourceBinding binding_default;
2418 binding->desc_set = binding_default.desc_set;
2419 binding->binding = binding_default.binding;
2420 binding->msl_buffer = binding_default.msl_buffer;
2421 binding->msl_texture = binding_default.msl_texture;
2422 binding->msl_sampler = binding_default.msl_sampler;
2423 binding->stage = static_cast<SpvExecutionModel>(binding_default.stage);
2424 #else
2425 memset(binding, 0, sizeof(*binding));
2426 #endif
2427 }
2428
spvc_hlsl_resource_binding_init(spvc_hlsl_resource_binding * binding)2429 void spvc_hlsl_resource_binding_init(spvc_hlsl_resource_binding *binding)
2430 {
2431 #if SPIRV_CROSS_C_API_HLSL
2432 HLSLResourceBinding binding_default;
2433 binding->desc_set = binding_default.desc_set;
2434 binding->binding = binding_default.binding;
2435 binding->cbv.register_binding = binding_default.cbv.register_binding;
2436 binding->cbv.register_space = binding_default.cbv.register_space;
2437 binding->srv.register_binding = binding_default.srv.register_binding;
2438 binding->srv.register_space = binding_default.srv.register_space;
2439 binding->uav.register_binding = binding_default.uav.register_binding;
2440 binding->uav.register_space = binding_default.uav.register_space;
2441 binding->sampler.register_binding = binding_default.sampler.register_binding;
2442 binding->sampler.register_space = binding_default.sampler.register_space;
2443 binding->stage = static_cast<SpvExecutionModel>(binding_default.stage);
2444 #else
2445 memset(binding, 0, sizeof(*binding));
2446 #endif
2447 }
2448
spvc_msl_constexpr_sampler_init(spvc_msl_constexpr_sampler * sampler)2449 void spvc_msl_constexpr_sampler_init(spvc_msl_constexpr_sampler *sampler)
2450 {
2451 #if SPIRV_CROSS_C_API_MSL
2452 MSLConstexprSampler defaults;
2453 sampler->anisotropy_enable = defaults.anisotropy_enable ? SPVC_TRUE : SPVC_FALSE;
2454 sampler->border_color = static_cast<spvc_msl_sampler_border_color>(defaults.border_color);
2455 sampler->compare_enable = defaults.compare_enable ? SPVC_TRUE : SPVC_FALSE;
2456 sampler->coord = static_cast<spvc_msl_sampler_coord>(defaults.coord);
2457 sampler->compare_func = static_cast<spvc_msl_sampler_compare_func>(defaults.compare_func);
2458 sampler->lod_clamp_enable = defaults.lod_clamp_enable ? SPVC_TRUE : SPVC_FALSE;
2459 sampler->lod_clamp_max = defaults.lod_clamp_max;
2460 sampler->lod_clamp_min = defaults.lod_clamp_min;
2461 sampler->mag_filter = static_cast<spvc_msl_sampler_filter>(defaults.mag_filter);
2462 sampler->min_filter = static_cast<spvc_msl_sampler_filter>(defaults.min_filter);
2463 sampler->mip_filter = static_cast<spvc_msl_sampler_mip_filter>(defaults.mip_filter);
2464 sampler->max_anisotropy = defaults.max_anisotropy;
2465 sampler->s_address = static_cast<spvc_msl_sampler_address>(defaults.s_address);
2466 sampler->t_address = static_cast<spvc_msl_sampler_address>(defaults.t_address);
2467 sampler->r_address = static_cast<spvc_msl_sampler_address>(defaults.r_address);
2468 #else
2469 memset(sampler, 0, sizeof(*sampler));
2470 #endif
2471 }
2472
spvc_msl_sampler_ycbcr_conversion_init(spvc_msl_sampler_ycbcr_conversion * conv)2473 void spvc_msl_sampler_ycbcr_conversion_init(spvc_msl_sampler_ycbcr_conversion *conv)
2474 {
2475 #if SPIRV_CROSS_C_API_MSL
2476 MSLConstexprSampler defaults;
2477 conv->planes = defaults.planes;
2478 conv->resolution = static_cast<spvc_msl_format_resolution>(defaults.resolution);
2479 conv->chroma_filter = static_cast<spvc_msl_sampler_filter>(defaults.chroma_filter);
2480 conv->x_chroma_offset = static_cast<spvc_msl_chroma_location>(defaults.x_chroma_offset);
2481 conv->y_chroma_offset = static_cast<spvc_msl_chroma_location>(defaults.y_chroma_offset);
2482 for (int i = 0; i < 4; i++)
2483 conv->swizzle[i] = static_cast<spvc_msl_component_swizzle>(defaults.swizzle[i]);
2484 conv->ycbcr_model = static_cast<spvc_msl_sampler_ycbcr_model_conversion>(defaults.ycbcr_model);
2485 conv->ycbcr_range = static_cast<spvc_msl_sampler_ycbcr_range>(defaults.ycbcr_range);
2486 #else
2487 memset(conv, 0, sizeof(*conv));
2488 #endif
2489 }
2490
spvc_compiler_get_current_id_bound(spvc_compiler compiler)2491 unsigned spvc_compiler_get_current_id_bound(spvc_compiler compiler)
2492 {
2493 return compiler->compiler->get_current_id_bound();
2494 }
2495
spvc_get_version(unsigned * major,unsigned * minor,unsigned * patch)2496 void spvc_get_version(unsigned *major, unsigned *minor, unsigned *patch)
2497 {
2498 *major = SPVC_C_API_VERSION_MAJOR;
2499 *minor = SPVC_C_API_VERSION_MINOR;
2500 *patch = SPVC_C_API_VERSION_PATCH;
2501 }
2502
spvc_get_commit_revision_and_timestamp(void)2503 const char *spvc_get_commit_revision_and_timestamp(void)
2504 {
2505 #ifdef HAVE_SPIRV_CROSS_GIT_VERSION
2506 return SPIRV_CROSS_GIT_REVISION;
2507 #else
2508 return "";
2509 #endif
2510 }
2511
2512 #ifdef _MSC_VER
2513 #pragma warning(pop)
2514 #endif
2515