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