yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

yumOptionally disable entry point param cbuffer transform482914e1b

master
174.9 KiB4968 linesraw
1#ifndef SLANG_H
2#define SLANG_H
3
4#ifdef SLANG_USER_CONFIG
5    #include SLANG_USER_CONFIG
6#endif
7
8/** \file slang.h
9
10The Slang API provides services to compile, reflect, and specialize code
11written in the Slang shading language.
12*/
13
14/*
15The following section attempts to detect the compiler and version in use.
16
17If an application defines `SLANG_COMPILER` before including this header,
18they take responsibility for setting any compiler-dependent macros
19used later in the file.
20
21Most applications should not need to touch this section.
22*/
23#ifndef SLANG_COMPILER
24    #define SLANG_COMPILER
25
26    /*
27    Compiler defines, see http://sourceforge.net/p/predef/wiki/Compilers/
28    NOTE that SLANG_VC holds the compiler version - not just 1 or 0
29    */
30    #if defined(_MSC_VER)
31        #if _MSC_VER >= 1900
32            #define SLANG_VC 14
33        #elif _MSC_VER >= 1800
34            #define SLANG_VC 12
35        #elif _MSC_VER >= 1700
36            #define SLANG_VC 11
37        #elif _MSC_VER >= 1600
38            #define SLANG_VC 10
39        #elif _MSC_VER >= 1500
40            #define SLANG_VC 9
41        #else
42            #error "unknown version of Visual C++ compiler"
43        #endif
44    #elif defined(__clang__)
45        #define SLANG_CLANG 1
46    #elif defined(__SNC__)
47        #define SLANG_SNC 1
48    #elif defined(__ghs__)
49        #define SLANG_GHS 1
50    #elif defined(__GNUC__) /* note: __clang__, __SNC__, or __ghs__ imply __GNUC__ */
51        #define SLANG_GCC 1
52    #else
53        #error "unknown compiler"
54    #endif
55    /*
56    Any compilers not detected by the above logic are now now explicitly zeroed out.
57    */
58    #ifndef SLANG_VC
59        #define SLANG_VC 0
60    #endif
61    #ifndef SLANG_CLANG
62        #define SLANG_CLANG 0
63    #endif
64    #ifndef SLANG_SNC
65        #define SLANG_SNC 0
66    #endif
67    #ifndef SLANG_GHS
68        #define SLANG_GHS 0
69    #endif
70    #ifndef SLANG_GCC
71        #define SLANG_GCC 0
72    #endif
73#endif /* SLANG_COMPILER */
74
75/*
76The following section attempts to detect the target platform being compiled for.
77
78If an application defines `SLANG_PLATFORM` before including this header,
79they take responsibility for setting any compiler-dependent macros
80used later in the file.
81
82Most applications should not need to touch this section.
83*/
84#ifndef SLANG_PLATFORM
85    #define SLANG_PLATFORM
86    /**
87    Operating system defines, see http://sourceforge.net/p/predef/wiki/OperatingSystems/
88    */
89    #if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_PARTITION_APP
90        #define SLANG_WINRT 1 /* Windows Runtime, either on Windows RT or Windows 8 */
91    #elif defined(XBOXONE)
92        #define SLANG_XBOXONE 1
93    #elif defined(_WIN64) /* note: XBOXONE implies _WIN64 */
94        #define SLANG_WIN64 1
95    #elif defined(_M_PPC)
96        #define SLANG_X360 1
97    #elif defined(_WIN32) /* note: _M_PPC implies _WIN32 */
98        #define SLANG_WIN32 1
99    #elif defined(__ANDROID__)
100        #define SLANG_ANDROID 1
101    #elif defined(__linux__) || defined(__CYGWIN__) /* note: __ANDROID__ implies __linux__ */
102        #define SLANG_LINUX 1
103    #elif defined(__APPLE__)
104        #include "TargetConditionals.h"
105        #if TARGET_OS_MAC
106            #define SLANG_OSX 1
107        #else
108            #define SLANG_IOS 1
109        #endif
110    #elif defined(__CELLOS_LV2__)
111        #define SLANG_PS3 1
112    #elif defined(__ORBIS__)
113        #define SLANG_PS4 1
114    #elif defined(__SNC__) && defined(__arm__)
115        #define SLANG_PSP2 1
116    #elif defined(__ghs__)
117        #define SLANG_WIIU 1
118    #elif defined(__EMSCRIPTEN__)
119        #define SLANG_WASM 1
120    #else
121        #error "unknown target platform"
122    #endif
123    /*
124    Any platforms not detected by the above logic are now now explicitly zeroed out.
125    */
126    #ifndef SLANG_WINRT
127        #define SLANG_WINRT 0
128    #endif
129    #ifndef SLANG_XBOXONE
130        #define SLANG_XBOXONE 0
131    #endif
132    #ifndef SLANG_WIN64
133        #define SLANG_WIN64 0
134    #endif
135    #ifndef SLANG_X360
136        #define SLANG_X360 0
137    #endif
138    #ifndef SLANG_WIN32
139        #define SLANG_WIN32 0
140    #endif
141    #ifndef SLANG_ANDROID
142        #define SLANG_ANDROID 0
143    #endif
144    #ifndef SLANG_LINUX
145        #define SLANG_LINUX 0
146    #endif
147    #ifndef SLANG_IOS
148        #define SLANG_IOS 0
149    #endif
150    #ifndef SLANG_OSX
151        #define SLANG_OSX 0
152    #endif
153    #ifndef SLANG_PS3
154        #define SLANG_PS3 0
155    #endif
156    #ifndef SLANG_PS4
157        #define SLANG_PS4 0
158    #endif
159    #ifndef SLANG_PSP2
160        #define SLANG_PSP2 0
161    #endif
162    #ifndef SLANG_WIIU
163        #define SLANG_WIIU 0
164    #endif
165#endif /* SLANG_PLATFORM */
166
167/* Shorthands for "families" of compilers/platforms */
168#define SLANG_GCC_FAMILY (SLANG_CLANG || SLANG_SNC || SLANG_GHS || SLANG_GCC)
169#define SLANG_WINDOWS_FAMILY (SLANG_WINRT || SLANG_WIN32 || SLANG_WIN64)
170#define SLANG_MICROSOFT_FAMILY (SLANG_XBOXONE || SLANG_X360 || SLANG_WINDOWS_FAMILY)
171#define SLANG_LINUX_FAMILY (SLANG_LINUX || SLANG_ANDROID)
172#define SLANG_APPLE_FAMILY (SLANG_IOS || SLANG_OSX) /* equivalent to #if __APPLE__ */
173#define SLANG_UNIX_FAMILY \
174    (SLANG_LINUX_FAMILY || SLANG_APPLE_FAMILY) /* shortcut for unix/posix platforms */
175
176/* Macros concerning DirectX */
177#if !defined(SLANG_CONFIG_DX_ON_VK) || !SLANG_CONFIG_DX_ON_VK
178    #define SLANG_ENABLE_DXVK 0
179    #define SLANG_ENABLE_VKD3D 0
180#else
181    #define SLANG_ENABLE_DXVK 1
182    #define SLANG_ENABLE_VKD3D 1
183#endif
184
185#if SLANG_WINDOWS_FAMILY
186    #define SLANG_ENABLE_DIRECTX 1
187    #define SLANG_ENABLE_DXGI_DEBUG 1
188    #define SLANG_ENABLE_DXBC_SUPPORT 1
189    #define SLANG_ENABLE_PIX 1
190#elif SLANG_LINUX_FAMILY
191    #define SLANG_ENABLE_DIRECTX (SLANG_ENABLE_DXVK || SLANG_ENABLE_VKD3D)
192    #define SLANG_ENABLE_DXGI_DEBUG 0
193    #define SLANG_ENABLE_DXBC_SUPPORT 0
194    #define SLANG_ENABLE_PIX 0
195#else
196    #define SLANG_ENABLE_DIRECTX 0
197    #define SLANG_ENABLE_DXGI_DEBUG 0
198    #define SLANG_ENABLE_DXBC_SUPPORT 0
199    #define SLANG_ENABLE_PIX 0
200#endif
201
202/* Macro for declaring if a method is no throw. Should be set before the return parameter. */
203#ifndef SLANG_NO_THROW
204    #if SLANG_WINDOWS_FAMILY && !defined(SLANG_DISABLE_EXCEPTIONS)
205        #define SLANG_NO_THROW __declspec(nothrow)
206    #endif
207#endif
208#ifndef SLANG_NO_THROW
209    #define SLANG_NO_THROW
210#endif
211
212/* The `SLANG_STDCALL` and `SLANG_MCALL` defines are used to set the calling
213convention for interface methods.
214*/
215#ifndef SLANG_STDCALL
216    #if SLANG_MICROSOFT_FAMILY
217        #define SLANG_STDCALL __stdcall
218    #else
219        #define SLANG_STDCALL
220    #endif
221#endif
222#ifndef SLANG_MCALL
223    #define SLANG_MCALL SLANG_STDCALL
224#endif
225
226
227#if !defined(SLANG_STATIC) && !defined(SLANG_DYNAMIC)
228    #define SLANG_DYNAMIC
229#endif
230
231#if defined(_MSC_VER)
232    #define SLANG_DLL_EXPORT __declspec(dllexport)
233#else
234    #if SLANG_WINDOWS_FAMILY
235        #define SLANG_DLL_EXPORT \
236            __attribute__((dllexport)) __attribute__((__visibility__("default")))
237    #else
238        #define SLANG_DLL_EXPORT __attribute__((__visibility__("default")))
239    #endif
240#endif
241
242#if defined(SLANG_DYNAMIC)
243    #if defined(_MSC_VER)
244        #ifdef SLANG_DYNAMIC_EXPORT
245            #define SLANG_API SLANG_DLL_EXPORT
246        #else
247            #define SLANG_API __declspec(dllimport)
248        #endif
249    #else
250        // TODO: need to consider compiler capabilities
251        // #     ifdef SLANG_DYNAMIC_EXPORT
252        #define SLANG_API SLANG_DLL_EXPORT
253    // #     endif
254    #endif
255#endif
256
257#ifndef SLANG_API
258    #define SLANG_API
259#endif
260
261// GCC Specific
262#if SLANG_GCC_FAMILY
263    #define SLANG_NO_INLINE __attribute__((noinline))
264    #define SLANG_FORCE_INLINE inline __attribute__((always_inline))
265    #define SLANG_BREAKPOINT(id) __builtin_trap();
266#endif // SLANG_GCC_FAMILY
267
268#if SLANG_GCC_FAMILY || defined(__clang__)
269    // Use the builtin directly so we don't need to have an include of stddef.h
270    #define SLANG_OFFSET_OF(T, ELEMENT) __builtin_offsetof(T, ELEMENT)
271#endif
272
273#ifndef SLANG_OFFSET_OF
274    #define SLANG_OFFSET_OF(T, ELEMENT) (size_t(&((T*)1)->ELEMENT) - 1)
275#endif
276
277// Microsoft VC specific
278#if SLANG_VC
279    #define SLANG_NO_INLINE __declspec(noinline)
280    #define SLANG_FORCE_INLINE __forceinline
281    #define SLANG_BREAKPOINT(id) __debugbreak();
282
283    #define SLANG_INT64(x) (x##i64)
284    #define SLANG_UINT64(x) (x##ui64)
285#endif // SLANG_MICROSOFT_FAMILY
286
287#ifndef SLANG_FORCE_INLINE
288    #define SLANG_FORCE_INLINE inline
289#endif
290#ifndef SLANG_NO_INLINE
291    #define SLANG_NO_INLINE
292#endif
293
294#ifndef SLANG_COMPILE_TIME_ASSERT
295    #define SLANG_COMPILE_TIME_ASSERT(x) static_assert(x)
296#endif
297
298#ifndef SLANG_BREAKPOINT
299    // Make it crash with a write to 0!
300    #define SLANG_BREAKPOINT(id) (*((int*)0) = int(id));
301#endif
302
303// Use for getting the amount of members of a standard C array.
304// Use 0[x] here to catch the case where x has an overloaded subscript operator
305#define SLANG_COUNT_OF(x) (SlangSSizeT(sizeof(x) / sizeof(0 [x])))
306/// SLANG_INLINE exists to have a way to inline consistent with SLANG_ALWAYS_INLINE
307#define SLANG_INLINE inline
308
309// If explicitly disabled and not set, set to not available
310#if !defined(SLANG_HAS_EXCEPTIONS) && defined(SLANG_DISABLE_EXCEPTIONS)
311    #define SLANG_HAS_EXCEPTIONS 0
312#endif
313
314// If not set, the default is exceptions are available
315#ifndef SLANG_HAS_EXCEPTIONS
316    #define SLANG_HAS_EXCEPTIONS 1
317#endif
318
319// Other defines
320#define SLANG_STRINGIZE_HELPER(X) #X
321#define SLANG_STRINGIZE(X) SLANG_STRINGIZE_HELPER(X)
322
323#define SLANG_CONCAT_HELPER(X, Y) X##Y
324#define SLANG_CONCAT(X, Y) SLANG_CONCAT_HELPER(X, Y)
325
326#ifndef SLANG_UNUSED
327    #define SLANG_UNUSED(v) (void)v;
328#endif
329
330#if defined(__llvm__)
331    #define SLANG_MAYBE_UNUSED [[maybe_unused]]
332#else
333    #define SLANG_MAYBE_UNUSED
334#endif
335
336// Used for doing constant literals
337#ifndef SLANG_INT64
338    #define SLANG_INT64(x) (x##ll)
339#endif
340#ifndef SLANG_UINT64
341    #define SLANG_UINT64(x) (x##ull)
342#endif
343
344
345#ifdef __cplusplus
346    #define SLANG_EXTERN_C extern "C"
347#else
348    #define SLANG_EXTERN_C
349#endif
350
351#ifdef __cplusplus
352    // C++ specific macros
353    // Clang
354    #if SLANG_CLANG
355        #if (__clang_major__ * 10 + __clang_minor__) >= 33
356            #define SLANG_HAS_MOVE_SEMANTICS 1
357            #define SLANG_HAS_ENUM_CLASS 1
358            #define SLANG_OVERRIDE override
359        #endif
360
361    // Gcc
362    #elif SLANG_GCC_FAMILY
363        // Check for C++11
364        #if (__cplusplus >= 201103L)
365            #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405
366                #define SLANG_HAS_MOVE_SEMANTICS 1
367            #endif
368            #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406
369                #define SLANG_HAS_ENUM_CLASS 1
370            #endif
371            #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 407
372                #define SLANG_OVERRIDE override
373            #endif
374        #endif
375    #endif // SLANG_GCC_FAMILY
376
377    // Visual Studio
378
379    #if SLANG_VC
380        // C4481: nonstandard extension used: override specifier 'override'
381        #if _MSC_VER < 1700
382            #pragma warning(disable : 4481)
383        #endif
384        #define SLANG_OVERRIDE override
385        #if _MSC_VER >= 1600
386            #define SLANG_HAS_MOVE_SEMANTICS 1
387        #endif
388        #if _MSC_VER >= 1700
389            #define SLANG_HAS_ENUM_CLASS 1
390        #endif
391    #endif // SLANG_VC
392
393    // Set non set
394    #ifndef SLANG_OVERRIDE
395        #define SLANG_OVERRIDE
396    #endif
397    #ifndef SLANG_HAS_ENUM_CLASS
398        #define SLANG_HAS_ENUM_CLASS 0
399    #endif
400    #ifndef SLANG_HAS_MOVE_SEMANTICS
401        #define SLANG_HAS_MOVE_SEMANTICS 0
402    #endif
403
404#endif // __cplusplus
405
406/* Macros for detecting processor */
407#if defined(_M_ARM) || defined(__ARM_EABI__)
408    // This is special case for nVidia tegra
409    #define SLANG_PROCESSOR_ARM 1
410#elif defined(__i386__) || defined(_M_IX86)
411    #define SLANG_PROCESSOR_X86 1
412#elif defined(_M_AMD64) || defined(_M_X64) || defined(__amd64) || defined(__x86_64)
413    #define SLANG_PROCESSOR_X86_64 1
414#elif defined(_PPC_) || defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC)
415    #if defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) || \
416        defined(__64BIT__) || defined(_LP64) || defined(__LP64__)
417        #define SLANG_PROCESSOR_POWER_PC_64 1
418    #else
419        #define SLANG_PROCESSOR_POWER_PC 1
420    #endif
421#elif defined(__arm__)
422    #define SLANG_PROCESSOR_ARM 1
423#elif defined(_M_ARM64) || defined(__aarch64__) || defined(__ARM_ARCH_ISA_A64)
424    #define SLANG_PROCESSOR_ARM_64 1
425#elif defined(__EMSCRIPTEN__)
426    #define SLANG_PROCESSOR_WASM 1
427#endif
428
429#ifndef SLANG_PROCESSOR_ARM
430    #define SLANG_PROCESSOR_ARM 0
431#endif
432
433#ifndef SLANG_PROCESSOR_ARM_64
434    #define SLANG_PROCESSOR_ARM_64 0
435#endif
436
437#ifndef SLANG_PROCESSOR_X86
438    #define SLANG_PROCESSOR_X86 0
439#endif
440
441#ifndef SLANG_PROCESSOR_X86_64
442    #define SLANG_PROCESSOR_X86_64 0
443#endif
444
445#ifndef SLANG_PROCESSOR_POWER_PC
446    #define SLANG_PROCESSOR_POWER_PC 0
447#endif
448
449#ifndef SLANG_PROCESSOR_POWER_PC_64
450    #define SLANG_PROCESSOR_POWER_PC_64 0
451#endif
452
453// Processor families
454
455#define SLANG_PROCESSOR_FAMILY_X86 (SLANG_PROCESSOR_X86_64 | SLANG_PROCESSOR_X86)
456#define SLANG_PROCESSOR_FAMILY_ARM (SLANG_PROCESSOR_ARM | SLANG_PROCESSOR_ARM_64)
457#define SLANG_PROCESSOR_FAMILY_POWER_PC (SLANG_PROCESSOR_POWER_PC_64 | SLANG_PROCESSOR_POWER_PC)
458
459// Pointer size
460#define SLANG_PTR_IS_64 \
461    (SLANG_PROCESSOR_ARM_64 | SLANG_PROCESSOR_X86_64 | SLANG_PROCESSOR_POWER_PC_64)
462#define SLANG_PTR_IS_32 (SLANG_PTR_IS_64 ^ 1)
463
464// Processor features
465#if SLANG_PROCESSOR_FAMILY_X86
466    #define SLANG_LITTLE_ENDIAN 1
467    #define SLANG_UNALIGNED_ACCESS 1
468#elif SLANG_PROCESSOR_FAMILY_ARM
469    #if defined(__ARMEB__)
470        #define SLANG_BIG_ENDIAN 1
471    #else
472        #define SLANG_LITTLE_ENDIAN 1
473    #endif
474#elif SLANG_PROCESSOR_FAMILY_POWER_PC
475    #define SLANG_BIG_ENDIAN 1
476#elif SLANG_WASM
477    #define SLANG_LITTLE_ENDIAN 1
478#endif
479
480#ifndef SLANG_LITTLE_ENDIAN
481    #define SLANG_LITTLE_ENDIAN 0
482#endif
483
484#ifndef SLANG_BIG_ENDIAN
485    #define SLANG_BIG_ENDIAN 0
486#endif
487
488#ifndef SLANG_UNALIGNED_ACCESS
489    #define SLANG_UNALIGNED_ACCESS 0
490#endif
491
492// Backtrace
493#if SLANG_LINUX_FAMILY
494    #include <features.h> // for __GLIBC__ define, if using GNU libc
495    #if defined(__GLIBC__) || (__ANDROID_API__ >= 33)
496        #define SLANG_HAS_BACKTRACE 1
497    #else
498        #define SLANG_HAS_BACKTRACE 0
499    #endif
500#else
501    #define SLANG_HAS_BACKTRACE 0
502#endif
503
504// One endianness must be set
505#if ((SLANG_BIG_ENDIAN | SLANG_LITTLE_ENDIAN) == 0)
506    #error "Couldn't determine endianness"
507#endif
508
509#ifndef SLANG_NO_INTTYPES
510    #include <inttypes.h>
511#endif // ! SLANG_NO_INTTYPES
512
513#ifndef SLANG_NO_STDDEF
514    #include <stddef.h>
515#endif // ! SLANG_NO_STDDEF
516
517#ifdef SLANG_NO_DEPRECATION
518    #define SLANG_DEPRECATED
519#else
520    #define SLANG_DEPRECATED [[deprecated]]
521#endif
522
523#ifdef __cplusplus
524extern "C"
525{
526#endif
527    /*!
528    @mainpage Introduction
529
530    API Reference: slang.h
531
532    @file slang.h
533    */
534
535    typedef uint32_t SlangUInt32;
536    typedef int32_t SlangInt32;
537
538    // Use SLANG_PTR_ macros to determine SlangInt/SlangUInt types.
539    // This is used over say using size_t/ptrdiff_t/intptr_t/uintptr_t, because on some targets,
540    // these types are distinct from their uint_t/int_t equivalents and so produce ambiguity with
541    // function overloading.
542    //
543    // SlangSizeT is helpful as on some compilers size_t is distinct from a regular integer type and
544    // so overloading doesn't work. Casting to SlangSizeT works around this.
545#if SLANG_PTR_IS_64
546    typedef int64_t SlangInt;
547    typedef uint64_t SlangUInt;
548
549    typedef int64_t SlangSSizeT;
550    typedef uint64_t SlangSizeT;
551#else
552typedef int32_t SlangInt;
553typedef uint32_t SlangUInt;
554
555typedef int32_t SlangSSizeT;
556typedef uint32_t SlangSizeT;
557#endif
558
559    typedef bool SlangBool;
560
561
562    /*!
563    @brief Severity of a diagnostic generated by the compiler.
564    Values come from the enum below, with higher values representing more severe
565    conditions, and all values >= SLANG_SEVERITY_ERROR indicating compilation
566    failure.
567    */
568    typedef int SlangSeverityIntegral;
569    enum SlangSeverity : SlangSeverityIntegral
570    {
571        SLANG_SEVERITY_DISABLED = 0, /**< A message that is disabled, filtered out. */
572        SLANG_SEVERITY_NOTE,         /**< An informative message. */
573        SLANG_SEVERITY_WARNING,      /**< A warning, which indicates a possible problem. */
574        SLANG_SEVERITY_ERROR,        /**< An error, indicating that compilation failed. */
575        SLANG_SEVERITY_FATAL,    /**< An unrecoverable error, which forced compilation to abort. */
576        SLANG_SEVERITY_INTERNAL, /**< An internal error, indicating a logic error in the compiler.
577                                  */
578    };
579
580    typedef int SlangDiagnosticFlags;
581    enum
582    {
583        SLANG_DIAGNOSTIC_FLAG_VERBOSE_PATHS = 0x01,
584        SLANG_DIAGNOSTIC_FLAG_TREAT_WARNINGS_AS_ERRORS = 0x02
585    };
586
587    typedef int SlangBindableResourceIntegral;
588    enum SlangBindableResourceType : SlangBindableResourceIntegral
589    {
590        SLANG_NON_BINDABLE = 0,
591        SLANG_TEXTURE,
592        SLANG_SAMPLER,
593        SLANG_UNIFORM_BUFFER,
594        SLANG_STORAGE_BUFFER,
595    };
596
597    /* NOTE! To keep binary compatibility care is needed with this enum!
598
599    * To add value, only add at the bottom (before COUNT_OF)
600    * To remove a value, add _DEPRECATED as a suffix, but leave in the list
601
602    This will make the enum values stable, and compatible with libraries that might not use the
603    latest enum values.
604    */
605    typedef int SlangCompileTargetIntegral;
606    enum SlangCompileTarget : SlangCompileTargetIntegral
607    {
608        SLANG_TARGET_UNKNOWN,
609        SLANG_TARGET_NONE,
610        SLANG_GLSL,
611        SLANG_GLSL_VULKAN_DEPRECATED,          //< deprecated and removed: just use `SLANG_GLSL`.
612        SLANG_GLSL_VULKAN_ONE_DESC_DEPRECATED, //< deprecated and removed.
613        SLANG_HLSL,
614        SLANG_SPIRV,
615        SLANG_SPIRV_ASM,
616        SLANG_DXBC,
617        SLANG_DXBC_ASM,
618        SLANG_DXIL,
619        SLANG_DXIL_ASM,
620        SLANG_C_SOURCE,              ///< The C language
621        SLANG_CPP_SOURCE,            ///< C++ code for shader kernels.
622        SLANG_HOST_EXECUTABLE,       ///< Standalone binary executable (for hosting CPU/OS)
623        SLANG_SHADER_SHARED_LIBRARY, ///< A shared library/Dll for shader kernels (for hosting
624                                     ///< CPU/OS)
625        SLANG_SHADER_HOST_CALLABLE,  ///< A CPU target that makes the compiled shader code available
626                                     ///< to be run immediately
627        SLANG_CUDA_SOURCE,           ///< Cuda source
628        SLANG_PTX,                   ///< PTX
629        SLANG_CUDA_OBJECT_CODE,      ///< Object code that contains CUDA functions.
630        SLANG_OBJECT_CODE,           ///< Object code that can be used for later linking
631        SLANG_HOST_CPP_SOURCE,       ///< C++ code for host library or executable.
632        SLANG_HOST_HOST_CALLABLE,    ///< Host callable host code (ie non kernel/shader)
633        SLANG_CPP_PYTORCH_BINDING,   ///< C++ PyTorch binding code.
634        SLANG_METAL,                 ///< Metal shading language
635        SLANG_METAL_LIB,             ///< Metal library
636        SLANG_METAL_LIB_ASM,         ///< Metal library assembly
637        SLANG_HOST_SHARED_LIBRARY,   ///< A shared library/Dll for host code (for hosting CPU/OS)
638        SLANG_WGSL,                  ///< WebGPU shading language
639        SLANG_WGSL_SPIRV_ASM,        ///< SPIR-V assembly via WebGPU shading language
640        SLANG_WGSL_SPIRV,            ///< SPIR-V via WebGPU shading language
641
642        SLANG_HOST_VM, ///< Bytecode that can be interpreted by the Slang VM
643        SLANG_TARGET_COUNT_OF,
644    };
645
646    /* A "container format" describes the way that the outputs
647    for multiple files, entry points, targets, etc. should be
648    combined into a single artifact for output. */
649    typedef int SlangContainerFormatIntegral;
650    enum SlangContainerFormat : SlangContainerFormatIntegral
651    {
652        /* Don't generate a container. */
653        SLANG_CONTAINER_FORMAT_NONE,
654
655        /* Generate a container in the `.slang-module` format,
656        which includes reflection information, compiled kernels, etc. */
657        SLANG_CONTAINER_FORMAT_SLANG_MODULE,
658    };
659
660    typedef int SlangPassThroughIntegral;
661    enum SlangPassThrough : SlangPassThroughIntegral
662    {
663        SLANG_PASS_THROUGH_NONE,
664        SLANG_PASS_THROUGH_FXC,
665        SLANG_PASS_THROUGH_DXC,
666        SLANG_PASS_THROUGH_GLSLANG,
667        SLANG_PASS_THROUGH_SPIRV_DIS,
668        SLANG_PASS_THROUGH_CLANG,         ///< Clang C/C++ compiler
669        SLANG_PASS_THROUGH_VISUAL_STUDIO, ///< Visual studio C/C++ compiler
670        SLANG_PASS_THROUGH_GCC,           ///< GCC C/C++ compiler
671        SLANG_PASS_THROUGH_GENERIC_C_CPP, ///< Generic C or C++ compiler, which is decided by the
672                                          ///< source type
673        SLANG_PASS_THROUGH_NVRTC,         ///< NVRTC Cuda compiler
674        SLANG_PASS_THROUGH_LLVM,          ///< LLVM 'compiler' - includes LLVM and Clang
675        SLANG_PASS_THROUGH_SPIRV_OPT,     ///< SPIRV-opt
676        SLANG_PASS_THROUGH_METAL,         ///< Metal compiler
677        SLANG_PASS_THROUGH_TINT,          ///< Tint WGSL compiler
678        SLANG_PASS_THROUGH_SPIRV_LINK,    ///< SPIRV-link
679        SLANG_PASS_THROUGH_COUNT_OF,
680    };
681
682    /* Defines an archive type used to holds a 'file system' type structure. */
683    typedef int SlangArchiveTypeIntegral;
684    enum SlangArchiveType : SlangArchiveTypeIntegral
685    {
686        SLANG_ARCHIVE_TYPE_UNDEFINED,
687        SLANG_ARCHIVE_TYPE_ZIP,
688        SLANG_ARCHIVE_TYPE_RIFF, ///< Riff container with no compression
689        SLANG_ARCHIVE_TYPE_RIFF_DEFLATE,
690        SLANG_ARCHIVE_TYPE_RIFF_LZ4,
691        SLANG_ARCHIVE_TYPE_COUNT_OF,
692    };
693
694    /*!
695    Flags to control compilation behavior.
696    */
697    typedef unsigned int SlangCompileFlags;
698    enum
699    {
700        /* Do as little mangling of names as possible, to try to preserve original names */
701        SLANG_COMPILE_FLAG_NO_MANGLING = 1 << 3,
702
703        /* Skip code generation step, just check the code and generate layout */
704        SLANG_COMPILE_FLAG_NO_CODEGEN = 1 << 4,
705
706        /* Obfuscate shader names on release products */
707        SLANG_COMPILE_FLAG_OBFUSCATE = 1 << 5,
708
709        /* Deprecated flags: kept around to allow existing applications to
710        compile. Note that the relevant features will still be left in
711        their default state. */
712        SLANG_COMPILE_FLAG_NO_CHECKING = 0,
713        SLANG_COMPILE_FLAG_SPLIT_MIXED_TYPES = 0,
714    };
715
716    /*!
717    @brief Flags to control code generation behavior of a compilation target */
718    typedef unsigned int SlangTargetFlags;
719    enum
720    {
721        /* When compiling for a D3D Shader Model 5.1 or higher target, allocate
722           distinct register spaces for parameter blocks.
723
724           @deprecated This behavior is now enabled unconditionally.
725        */
726        SLANG_TARGET_FLAG_PARAMETER_BLOCKS_USE_REGISTER_SPACES = 1 << 4,
727
728        /* When set, will generate target code that contains all entrypoints defined
729           in the input source or specified via the `spAddEntryPoint` function in a
730           single output module (library/source file).
731        */
732        SLANG_TARGET_FLAG_GENERATE_WHOLE_PROGRAM = 1 << 8,
733
734        /* When set, will dump out the IR between intermediate compilation steps.*/
735        SLANG_TARGET_FLAG_DUMP_IR = 1 << 9,
736
737        /* When set, will generate SPIRV directly rather than via glslang. */
738        // This flag will be deprecated, use CompilerOption instead.
739        SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY = 1 << 10,
740    };
741    inline constexpr SlangTargetFlags kDefaultTargetFlags =
742        SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY;
743
744    /*!
745    @brief Options to control floating-point precision guarantees for a target.
746    */
747    typedef unsigned int SlangFloatingPointModeIntegral;
748    enum SlangFloatingPointMode : SlangFloatingPointModeIntegral
749    {
750        SLANG_FLOATING_POINT_MODE_DEFAULT = 0,
751        SLANG_FLOATING_POINT_MODE_FAST,
752        SLANG_FLOATING_POINT_MODE_PRECISE,
753    };
754
755    /*!
756    @brief Options to control floating-point denormal handling mode for a target.
757    */
758    typedef unsigned int SlangFpDenormalModeIntegral;
759    enum SlangFpDenormalMode : SlangFpDenormalModeIntegral
760    {
761        SLANG_FP_DENORM_MODE_ANY = 0,
762        SLANG_FP_DENORM_MODE_PRESERVE,
763        SLANG_FP_DENORM_MODE_FTZ,
764    };
765
766    /*!
767    @brief Options to control emission of `#line` directives
768    */
769    typedef unsigned int SlangLineDirectiveModeIntegral;
770    enum SlangLineDirectiveMode : SlangLineDirectiveModeIntegral
771    {
772        SLANG_LINE_DIRECTIVE_MODE_DEFAULT =
773            0,                              /**< Default behavior: pick behavior base on target. */
774        SLANG_LINE_DIRECTIVE_MODE_NONE,     /**< Don't emit line directives at all. */
775        SLANG_LINE_DIRECTIVE_MODE_STANDARD, /**< Emit standard C-style `#line` directives. */
776        SLANG_LINE_DIRECTIVE_MODE_GLSL, /**< Emit GLSL-style directives with file *number* instead
777                                           of name */
778        SLANG_LINE_DIRECTIVE_MODE_SOURCE_MAP, /**< Use a source map to track line mappings (ie no
779                                                 #line will appear in emitting source) */
780    };
781
782    typedef int SlangSourceLanguageIntegral;
783    enum SlangSourceLanguage : SlangSourceLanguageIntegral
784    {
785        SLANG_SOURCE_LANGUAGE_UNKNOWN,
786        SLANG_SOURCE_LANGUAGE_SLANG,
787        SLANG_SOURCE_LANGUAGE_HLSL,
788        SLANG_SOURCE_LANGUAGE_GLSL,
789        SLANG_SOURCE_LANGUAGE_C,
790        SLANG_SOURCE_LANGUAGE_CPP,
791        SLANG_SOURCE_LANGUAGE_CUDA,
792        SLANG_SOURCE_LANGUAGE_SPIRV,
793        SLANG_SOURCE_LANGUAGE_METAL,
794        SLANG_SOURCE_LANGUAGE_WGSL,
795        SLANG_SOURCE_LANGUAGE_COUNT_OF,
796    };
797
798    typedef unsigned int SlangProfileIDIntegral;
799    enum SlangProfileID : SlangProfileIDIntegral
800    {
801        SLANG_PROFILE_UNKNOWN,
802    };
803
804
805    typedef SlangInt32 SlangCapabilityIDIntegral;
806    enum SlangCapabilityID : SlangCapabilityIDIntegral
807    {
808        SLANG_CAPABILITY_UNKNOWN = 0,
809    };
810
811    typedef unsigned int SlangMatrixLayoutModeIntegral;
812    enum SlangMatrixLayoutMode : SlangMatrixLayoutModeIntegral
813    {
814        SLANG_MATRIX_LAYOUT_MODE_UNKNOWN = 0,
815        SLANG_MATRIX_LAYOUT_ROW_MAJOR,
816        SLANG_MATRIX_LAYOUT_COLUMN_MAJOR,
817    };
818
819    typedef SlangUInt32 SlangStageIntegral;
820    enum SlangStage : SlangStageIntegral
821    {
822        SLANG_STAGE_NONE,
823        SLANG_STAGE_VERTEX,
824        SLANG_STAGE_HULL,
825        SLANG_STAGE_DOMAIN,
826        SLANG_STAGE_GEOMETRY,
827        SLANG_STAGE_FRAGMENT,
828        SLANG_STAGE_COMPUTE,
829        SLANG_STAGE_RAY_GENERATION,
830        SLANG_STAGE_INTERSECTION,
831        SLANG_STAGE_ANY_HIT,
832        SLANG_STAGE_CLOSEST_HIT,
833        SLANG_STAGE_MISS,
834        SLANG_STAGE_CALLABLE,
835        SLANG_STAGE_MESH,
836        SLANG_STAGE_AMPLIFICATION,
837        SLANG_STAGE_DISPATCH,
838        //
839        SLANG_STAGE_COUNT,
840
841        // alias:
842        SLANG_STAGE_PIXEL = SLANG_STAGE_FRAGMENT,
843    };
844
845    typedef SlangUInt32 SlangDebugInfoLevelIntegral;
846    enum SlangDebugInfoLevel : SlangDebugInfoLevelIntegral
847    {
848        SLANG_DEBUG_INFO_LEVEL_NONE = 0, /**< Don't emit debug information at all. */
849        SLANG_DEBUG_INFO_LEVEL_MINIMAL,  /**< Emit as little debug information as possible, while
850                                            still supporting stack trackers. */
851        SLANG_DEBUG_INFO_LEVEL_STANDARD, /**< Emit whatever is the standard level of debug
852                                            information for each target. */
853        SLANG_DEBUG_INFO_LEVEL_MAXIMAL,  /**< Emit as much debug information as possible for each
854                                            target. */
855    };
856
857    /* Describes the debugging information format produced during a compilation. */
858    typedef SlangUInt32 SlangDebugInfoFormatIntegral;
859    enum SlangDebugInfoFormat : SlangDebugInfoFormatIntegral
860    {
861        SLANG_DEBUG_INFO_FORMAT_DEFAULT, ///< Use the default debugging format for the target
862        SLANG_DEBUG_INFO_FORMAT_C7,  ///< CodeView C7 format (typically means debugging information
863                                     ///< is embedded in the binary)
864        SLANG_DEBUG_INFO_FORMAT_PDB, ///< Program database
865
866        SLANG_DEBUG_INFO_FORMAT_STABS, ///< Stabs
867        SLANG_DEBUG_INFO_FORMAT_COFF,  ///< COFF debug info
868        SLANG_DEBUG_INFO_FORMAT_DWARF, ///< DWARF debug info (we may want to support specifying the
869                                       ///< version)
870
871        SLANG_DEBUG_INFO_FORMAT_COUNT_OF,
872    };
873
874    typedef SlangUInt32 SlangOptimizationLevelIntegral;
875    enum SlangOptimizationLevel : SlangOptimizationLevelIntegral
876    {
877        SLANG_OPTIMIZATION_LEVEL_NONE = 0, /**< Don't optimize at all. */
878        SLANG_OPTIMIZATION_LEVEL_DEFAULT,  /**< Default optimization level: balance code quality and
879                                              compilation time. */
880        SLANG_OPTIMIZATION_LEVEL_HIGH,     /**< Optimize aggressively. */
881        SLANG_OPTIMIZATION_LEVEL_MAXIMAL, /**< Include optimizations that may take a very long time,
882                                             or may involve severe space-vs-speed tradeoffs */
883    };
884
885    enum SlangEmitSpirvMethod
886    {
887        SLANG_EMIT_SPIRV_DEFAULT = 0,
888        SLANG_EMIT_SPIRV_VIA_GLSL,
889        SLANG_EMIT_SPIRV_DIRECTLY,
890    };
891
892    // All compiler option names supported by Slang.
893    namespace slang
894    {
895    enum class CompilerOptionName
896    {
897        MacroDefine, // stringValue0: macro name;  stringValue1: macro value
898        DepFile,
899        EntryPointName,
900        Specialize,
901        Help,
902        HelpStyle,
903        Include, // stringValue: additional include path.
904        Language,
905        MatrixLayoutColumn,         // bool
906        MatrixLayoutRow,            // bool
907        ZeroInitialize,             // bool
908        IgnoreCapabilities,         // bool
909        RestrictiveCapabilityCheck, // bool
910        ModuleName,                 // stringValue0: module name.
911        Output,
912        Profile, // intValue0: profile
913        Stage,   // intValue0: stage
914        Target,  // intValue0: CodeGenTarget
915        Version,
916        WarningsAsErrors, // stringValue0: "all" or comma separated list of warning codes or names.
917        DisableWarnings,  // stringValue0: comma separated list of warning codes or names.
918        EnableWarning,    // stringValue0: warning code or name.
919        DisableWarning,   // stringValue0: warning code or name.
920        DumpWarningDiagnostics,
921        InputFilesRemain,
922        EmitIr,                        // bool
923        ReportDownstreamTime,          // bool
924        ReportPerfBenchmark,           // bool
925        ReportCheckpointIntermediates, // bool
926        SkipSPIRVValidation,           // bool
927        SourceEmbedStyle,
928        SourceEmbedName,
929        SourceEmbedLanguage,
930        DisableShortCircuit,            // bool
931        MinimumSlangOptimization,       // bool
932        DisableNonEssentialValidations, // bool
933        DisableSourceMap,               // bool
934        UnscopedEnum,                   // bool
935        PreserveParameters, // bool: preserve all resource parameters in the output code.
936        // Target
937
938        Capability,                // intValue0: CapabilityName
939        DefaultImageFormatUnknown, // bool
940        DisableDynamicDispatch,    // bool
941        DisableSpecialization,     // bool
942        FloatingPointMode,         // intValue0: FloatingPointMode
943        DebugInformation,          // intValue0: DebugInfoLevel
944        LineDirectiveMode,
945        Optimization, // intValue0: OptimizationLevel
946        Obfuscate,    // bool
947
948        VulkanBindShift, // intValue0 (higher 8 bits): kind; intValue0(lower bits): set; intValue1:
949                         // shift
950        VulkanBindGlobals,       // intValue0: index; intValue1: set
951        VulkanInvertY,           // bool
952        VulkanUseDxPositionW,    // bool
953        VulkanUseEntryPointName, // bool
954        VulkanUseGLLayout,       // bool
955        VulkanEmitReflection,    // bool
956
957        GLSLForceScalarLayout,   // bool
958        EnableEffectAnnotations, // bool
959
960        EmitSpirvViaGLSL,     // bool (will be deprecated)
961        EmitSpirvDirectly,    // bool (will be deprecated)
962        SPIRVCoreGrammarJSON, // stringValue0: json path
963        IncompleteLibrary,    // bool, when set, will not issue an error when the linked program has
964                              // unresolved extern function symbols.
965
966        // Downstream
967
968        CompilerPath,
969        DefaultDownstreamCompiler,
970        DownstreamArgs, // stringValue0: downstream compiler name. stringValue1: argument list, one
971                        // per line.
972        PassThrough,
973
974        // Repro
975
976        DumpRepro,
977        DumpReproOnError,
978        ExtractRepro,
979        LoadRepro,
980        LoadReproDirectory,
981        ReproFallbackDirectory,
982
983        // Debugging
984
985        DumpAst,
986        DumpIntermediatePrefix,
987        DumpIntermediates, // bool
988        DumpIr,            // bool
989        DumpIrIds,
990        PreprocessorOutput,
991        OutputIncludes,
992        ReproFileSystem,
993        REMOVED_SerialIR, // deprecated and removed
994        SkipCodeGen,      // bool
995        ValidateIr,       // bool
996        VerbosePaths,
997        VerifyDebugSerialIr,
998        NoCodeGen, // Not used.
999
1000        // Experimental
1001
1002        FileSystem,
1003        Heterogeneous,
1004        NoMangle,
1005        NoHLSLBinding,
1006        NoHLSLPackConstantBufferElements,
1007        PlainFunctionEntryPoints,
1008        ValidateUniformity,
1009        AllowGLSL,
1010        EnableExperimentalPasses,
1011        BindlessSpaceIndex, // int
1012
1013        // Internal
1014
1015        ArchiveType,
1016        CompileCoreModule,
1017        Doc,
1018
1019        IrCompression, //< deprecated
1020
1021        LoadCoreModule,
1022        ReferenceModule,
1023        SaveCoreModule,
1024        SaveCoreModuleBinSource,
1025        TrackLiveness,
1026        LoopInversion, // bool, enable loop inversion optimization
1027
1028        ParameterBlocksUseRegisterSpaces, // Deprecated
1029        LanguageVersion,                  // intValue0: SlangLanguageVersion
1030        TypeConformance, // stringValue0: additional type conformance to link, in the format of
1031                         // "<TypeName>:<IInterfaceName>[=<sequentialId>]", for example
1032                         // "Impl:IFoo=3" or "Impl:IFoo".
1033        EnableExperimentalDynamicDispatch, // bool, experimental
1034        EmitReflectionJSON,                // bool
1035
1036        CountOfParsableOptions,
1037
1038        // Used in parsed options only.
1039        DebugInformationFormat,  // intValue0: DebugInfoFormat
1040        VulkanBindShiftAll,      // intValue0: kind; intValue1: shift
1041        GenerateWholeProgram,    // bool
1042        UseUpToDateBinaryModule, // bool, when set, will only load
1043                                 // precompiled modules if it is up-to-date with its source.
1044        EmbedDownstreamIR,       // bool
1045        ForceDXLayout,           // bool
1046
1047        // Add this new option to the end of the list to avoid breaking ABI as much as possible.
1048        // Setting of EmitSpirvDirectly or EmitSpirvViaGLSL will turn into this option internally.
1049        EmitSpirvMethod, // enum SlangEmitSpirvMethod
1050
1051        SaveGLSLModuleBinSource,
1052
1053        SkipDownstreamLinking, // bool, experimental
1054        DumpModule,
1055
1056        GetModuleInfo,              // Print serialized module version and name
1057        GetSupportedModuleVersions, // Print the min and max module versions this compiler supports
1058
1059        EmitSeparateDebug, // bool
1060
1061        // Floating point denormal handling modes
1062        DenormalModeFp16,
1063        DenormalModeFp32,
1064        DenormalModeFp64,
1065
1066        // Bitfield options
1067        UseMSVCStyleBitfieldPacking, // bool
1068
1069        ForceCLayout, // bool
1070
1071        CountOf,
1072    };
1073
1074    enum class CompilerOptionValueKind
1075    {
1076        Int,
1077        String
1078    };
1079
1080    struct CompilerOptionValue
1081    {
1082        CompilerOptionValueKind kind = CompilerOptionValueKind::Int;
1083        int32_t intValue0 = 0;
1084        int32_t intValue1 = 0;
1085        const char* stringValue0 = nullptr;
1086        const char* stringValue1 = nullptr;
1087    };
1088
1089    struct CompilerOptionEntry
1090    {
1091        CompilerOptionName name;
1092        CompilerOptionValue value;
1093    };
1094    } // namespace slang
1095
1096    /** A result code for a Slang API operation.
1097
1098    This type is generally compatible with the Windows API `HRESULT` type. In particular, negative
1099    values indicate failure results, while zero or positive results indicate success.
1100
1101    In general, Slang APIs always return a zero result on success, unless documented otherwise.
1102    Strictly speaking a negative value indicates an error, a positive (or 0) value indicates
1103    success. This can be tested for with the macros SLANG_SUCCEEDED(x) or SLANG_FAILED(x).
1104
1105    It can represent if the call was successful or not. It can also specify in an extensible manner
1106    what facility produced the result (as the integral 'facility') as well as what caused it (as an
1107    integral 'code'). Under the covers SlangResult is represented as a int32_t.
1108
1109    SlangResult is designed to be compatible with COM HRESULT.
1110
1111    It's layout in bits is as follows
1112
1113    Severity | Facility | Code
1114    ---------|----------|-----
1115    31       |    30-16 | 15-0
1116
1117    Severity - 1 fail, 0 is success - as SlangResult is signed 32 bits, means negative number
1118    indicates failure. Facility is where the error originated from. Code is the code specific to the
1119    facility.
1120
1121    Result codes have the following styles,
1122    1) SLANG_name
1123    2) SLANG_s_f_name
1124    3) SLANG_s_name
1125
1126    where s is S for success, E for error
1127    f is the short version of the facility name
1128
1129    Style 1 is reserved for SLANG_OK and SLANG_FAIL as they are so commonly used.
1130
1131    It is acceptable to expand 'f' to a longer name to differentiate a name or drop if unique
1132    without it. ie for a facility 'DRIVER' it might make sense to have an error of the form
1133    SLANG_E_DRIVER_OUT_OF_MEMORY
1134    */
1135
1136    typedef int32_t SlangResult;
1137
1138    //! Use to test if a result was failure. Never use result != SLANG_OK to test for failure, as
1139    //! there may be successful codes != SLANG_OK.
1140#define SLANG_FAILED(status) ((status) < 0)
1141    //! Use to test if a result succeeded. Never use result == SLANG_OK to test for success, as will
1142    //! detect other successful codes as a failure.
1143#define SLANG_SUCCEEDED(status) ((status) >= 0)
1144
1145    //! Get the facility the result is associated with
1146#define SLANG_GET_RESULT_FACILITY(r) ((int32_t)(((r) >> 16) & 0x7fff))
1147    //! Get the result code for the facility
1148#define SLANG_GET_RESULT_CODE(r) ((int32_t)((r) & 0xffff))
1149
1150#define SLANG_MAKE_ERROR(fac, code) \
1151    ((((int32_t)(fac)) << 16) | ((int32_t)(code)) | int32_t(0x80000000))
1152#define SLANG_MAKE_SUCCESS(fac, code) ((((int32_t)(fac)) << 16) | ((int32_t)(code)))
1153
1154    /*************************** Facilities ************************************/
1155
1156    //! Facilities compatible with windows COM - only use if known code is compatible
1157#define SLANG_FACILITY_WIN_GENERAL 0
1158#define SLANG_FACILITY_WIN_INTERFACE 4
1159#define SLANG_FACILITY_WIN_API 7
1160
1161    //! Base facility -> so as to not clash with HRESULT values (values in 0x200 range do not appear
1162    //! used)
1163#define SLANG_FACILITY_BASE 0x200
1164
1165    /*! Facilities numbers must be unique across a project to make the resulting result a unique
1166    number. It can be useful to have a consistent short name for a facility, as used in the name
1167    prefix */
1168#define SLANG_FACILITY_CORE SLANG_FACILITY_BASE
1169    /* Facility for codes, that are not uniquely defined/protected. Can be used to pass back a
1170    specific error without requiring system wide facility uniqueness. Codes should never be part of
1171    a public API. */
1172#define SLANG_FACILITY_INTERNAL SLANG_FACILITY_BASE + 1
1173
1174    /// Base for external facilities. Facilities should be unique across modules.
1175#define SLANG_FACILITY_EXTERNAL_BASE 0x210
1176
1177    /* ************************ Win COM compatible Results ******************************/
1178    // https://msdn.microsoft.com/en-us/library/windows/desktop/aa378137(v=vs.85).aspx
1179
1180    //! SLANG_OK indicates success, and is equivalent to
1181    //! SLANG_MAKE_SUCCESS(SLANG_FACILITY_WIN_GENERAL, 0)
1182#define SLANG_OK 0
1183    //! SLANG_FAIL is the generic failure code - meaning a serious error occurred and the call
1184    //! couldn't complete
1185#define SLANG_FAIL SLANG_MAKE_ERROR(SLANG_FACILITY_WIN_GENERAL, 0x4005)
1186
1187#define SLANG_MAKE_WIN_GENERAL_ERROR(code) SLANG_MAKE_ERROR(SLANG_FACILITY_WIN_GENERAL, code)
1188
1189    //! Functionality is not implemented
1190#define SLANG_E_NOT_IMPLEMENTED SLANG_MAKE_WIN_GENERAL_ERROR(0x4001)
1191    //! Interface not be found
1192#define SLANG_E_NO_INTERFACE SLANG_MAKE_WIN_GENERAL_ERROR(0x4002)
1193    //! Operation was aborted (did not correctly complete)
1194#define SLANG_E_ABORT SLANG_MAKE_WIN_GENERAL_ERROR(0x4004)
1195
1196    //! Indicates that a handle passed in as parameter to a method is invalid.
1197#define SLANG_E_INVALID_HANDLE SLANG_MAKE_ERROR(SLANG_FACILITY_WIN_API, 6)
1198    //! Indicates that an argument passed in as parameter to a method is invalid.
1199#define SLANG_E_INVALID_ARG SLANG_MAKE_ERROR(SLANG_FACILITY_WIN_API, 0x57)
1200    //! Operation could not complete - ran out of memory
1201#define SLANG_E_OUT_OF_MEMORY SLANG_MAKE_ERROR(SLANG_FACILITY_WIN_API, 0xe)
1202
1203    /* *************************** other Results **************************************/
1204
1205#define SLANG_MAKE_CORE_ERROR(code) SLANG_MAKE_ERROR(SLANG_FACILITY_CORE, code)
1206
1207    // Supplied buffer is too small to be able to complete
1208#define SLANG_E_BUFFER_TOO_SMALL SLANG_MAKE_CORE_ERROR(1)
1209    //! Used to identify a Result that has yet to be initialized.
1210    //! It defaults to failure such that if used incorrectly will fail, as similar in concept to
1211    //! using an uninitialized variable.
1212#define SLANG_E_UNINITIALIZED SLANG_MAKE_CORE_ERROR(2)
1213    //! Returned from an async method meaning the output is invalid (thus an error), but a result
1214    //! for the request is pending, and will be returned on a subsequent call with the async handle.
1215#define SLANG_E_PENDING SLANG_MAKE_CORE_ERROR(3)
1216    //! Indicates a file/resource could not be opened
1217#define SLANG_E_CANNOT_OPEN SLANG_MAKE_CORE_ERROR(4)
1218    //! Indicates a file/resource could not be found
1219#define SLANG_E_NOT_FOUND SLANG_MAKE_CORE_ERROR(5)
1220    //! An unhandled internal failure (typically from unhandled exception)
1221#define SLANG_E_INTERNAL_FAIL SLANG_MAKE_CORE_ERROR(6)
1222    //! Could not complete because some underlying feature (hardware or software) was not available
1223#define SLANG_E_NOT_AVAILABLE SLANG_MAKE_CORE_ERROR(7)
1224    //! Could not complete because the operation times out.
1225#define SLANG_E_TIME_OUT SLANG_MAKE_CORE_ERROR(8)
1226
1227    /** A "Universally Unique Identifier" (UUID)
1228
1229    The Slang API uses UUIDs to identify interfaces when
1230    using `queryInterface`.
1231
1232    This type is compatible with the `GUID` type defined
1233    by the Component Object Model (COM), but Slang is
1234    not dependent on COM.
1235    */
1236    struct SlangUUID
1237    {
1238        uint32_t data1;
1239        uint16_t data2;
1240        uint16_t data3;
1241        uint8_t data4[8];
1242    };
1243
1244// Place at the start of an interface with the guid.
1245// Guid should be specified as SLANG_COM_INTERFACE(0x00000000, 0x0000, 0x0000, { 0xC0, 0x00, 0x00,
1246// 0x00, 0x00, 0x00, 0x00, 0x46 }) NOTE: it's the typical guid struct definition, without the
1247// surrounding {} It is not necessary to use the multiple parameters (we can wrap in parens), but
1248// this is simple.
1249#define SLANG_COM_INTERFACE(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
1250public:                                                              \
1251    SLANG_FORCE_INLINE constexpr static SlangUUID getTypeGuid()      \
1252    {                                                                \
1253        return {a, b, c, d0, d1, d2, d3, d4, d5, d6, d7};            \
1254    }
1255
1256// Sometimes it's useful to associate a guid with a class to identify it. This macro can used for
1257// this, and the guid extracted via the getTypeGuid() function defined in the type
1258#define SLANG_CLASS_GUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
1259    SLANG_FORCE_INLINE constexpr static SlangUUID getTypeGuid()   \
1260    {                                                             \
1261        return {a, b, c, d0, d1, d2, d3, d4, d5, d6, d7};         \
1262    }
1263
1264// Helper to fill in pairs of GUIDs and return pointers. This ensures that the
1265// type of the GUID passed matches the pointer type, and that it is derived
1266// from ISlangUnknown,
1267// TODO(c++20): would is_derived_from be more appropriate here for private inheritance of
1268// ISlangUnknown?
1269//
1270// with     : void createFoo(SlangUUID, void**);
1271//            Slang::ComPtr<Bar> myBar;
1272// call with: createFoo(SLANG_IID_PPV_ARGS(myBar.writeRef()))
1273// to call  : createFoo(Bar::getTypeGuid(), (void**)(myBar.writeRef()))
1274#define SLANG_IID_PPV_ARGS(ppType)                                                         \
1275    std::decay_t<decltype(**(ppType))>::getTypeGuid(),                                     \
1276        (                                                                                  \
1277            (void)[] {                                                                     \
1278                static_assert(                                                             \
1279                    std::is_base_of_v<ISlangUnknown, std::decay_t<decltype(**(ppType))>>); \
1280            },                                                                             \
1281            reinterpret_cast<void**>(ppType))
1282
1283
1284    /** Base interface for components exchanged through the API.
1285
1286    This interface definition is compatible with the COM `IUnknown`,
1287    and uses the same UUID, but Slang does not require applications
1288    to use or initialize COM.
1289    */
1290    struct ISlangUnknown
1291    {
1292        SLANG_COM_INTERFACE(
1293            0x00000000,
1294            0x0000,
1295            0x0000,
1296            {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46})
1297
1298        virtual SLANG_NO_THROW SlangResult SLANG_MCALL
1299        queryInterface(SlangUUID const& uuid, void** outObject) = 0;
1300        virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() = 0;
1301        virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() = 0;
1302
1303        /*
1304        Inline methods are provided to allow the above operations to be called
1305        using their traditional COM names/signatures:
1306        */
1307        SlangResult QueryInterface(struct _GUID const& uuid, void** outObject)
1308        {
1309            return queryInterface(*(SlangUUID const*)&uuid, outObject);
1310        }
1311        uint32_t AddRef() { return addRef(); }
1312        uint32_t Release() { return release(); }
1313    };
1314#define SLANG_UUID_ISlangUnknown ISlangUnknown::getTypeGuid()
1315
1316
1317    /* An interface to provide a mechanism to cast, that doesn't require ref counting
1318    and doesn't have to return a pointer to a ISlangUnknown derived class */
1319    class ISlangCastable : public ISlangUnknown
1320    {
1321        SLANG_COM_INTERFACE(
1322            0x87ede0e1,
1323            0x4852,
1324            0x44b0,
1325            {0x8b, 0xf2, 0xcb, 0x31, 0x87, 0x4d, 0xe2, 0x39});
1326
1327        /// Can be used to cast to interfaces without reference counting.
1328        /// Also provides access to internal implementations, when they provide a guid
1329        /// Can simulate a 'generated' interface as long as kept in scope by cast from.
1330        virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) = 0;
1331    };
1332
1333    class ISlangClonable : public ISlangCastable
1334    {
1335        SLANG_COM_INTERFACE(
1336            0x1ec36168,
1337            0xe9f4,
1338            0x430d,
1339            {0xbb, 0x17, 0x4, 0x8a, 0x80, 0x46, 0xb3, 0x1f});
1340
1341        /// Note the use of guid is for the desired interface/object.
1342        /// The object is returned *not* ref counted. Any type that can implements the interface,
1343        /// derives from ICastable, and so (not withstanding some other issue) will always return
1344        /// an ICastable interface which other interfaces/types are accessible from via castAs
1345        SLANG_NO_THROW virtual void* SLANG_MCALL clone(const SlangUUID& guid) = 0;
1346    };
1347
1348    /** A "blob" of binary data.
1349
1350    This interface definition is compatible with the `ID3DBlob` and `ID3D10Blob` interfaces.
1351    */
1352    struct ISlangBlob : public ISlangUnknown
1353    {
1354        SLANG_COM_INTERFACE(
1355            0x8BA5FB08,
1356            0x5195,
1357            0x40e2,
1358            {0xAC, 0x58, 0x0D, 0x98, 0x9C, 0x3A, 0x01, 0x02})
1359
1360        virtual SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() = 0;
1361        virtual SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() = 0;
1362    };
1363#define SLANG_UUID_ISlangBlob ISlangBlob::getTypeGuid()
1364
1365    /* Can be requested from ISlangCastable cast to indicate the contained chars are null
1366     * terminated.
1367     */
1368    struct SlangTerminatedChars
1369    {
1370        SLANG_CLASS_GUID(
1371            0xbe0db1a8,
1372            0x3594,
1373            0x4603,
1374            {0xa7, 0x8b, 0xc4, 0x86, 0x84, 0x30, 0xdf, 0xbb});
1375        operator const char*() const { return chars; }
1376        char chars[1];
1377    };
1378
1379    /** A (real or virtual) file system.
1380
1381    Slang can make use of this interface whenever it would otherwise try to load files
1382    from disk, allowing applications to hook and/or override filesystem access from
1383    the compiler.
1384
1385    It is the responsibility of
1386    the caller of any method that returns a ISlangBlob to release the blob when it is no
1387    longer used (using 'release').
1388    */
1389
1390    struct ISlangFileSystem : public ISlangCastable
1391    {
1392        SLANG_COM_INTERFACE(
1393            0x003A09FC,
1394            0x3A4D,
1395            0x4BA0,
1396            {0xAD, 0x60, 0x1F, 0xD8, 0x63, 0xA9, 0x15, 0xAB})
1397
1398        /** Load a file from `path` and return a blob of its contents
1399        @param path The path to load from, as a null-terminated UTF-8 string.
1400        @param outBlob A destination pointer to receive the blob of the file contents.
1401        @returns A `SlangResult` to indicate success or failure in loading the file.
1402
1403        NOTE! This is a *binary* load - the blob should contain the exact same bytes
1404        as are found in the backing file.
1405
1406        If load is successful, the implementation should create a blob to hold
1407        the file's content, store it to `outBlob`, and return 0.
1408        If the load fails, the implementation should return a failure status
1409        (any negative value will do).
1410        */
1411        virtual SLANG_NO_THROW SlangResult SLANG_MCALL
1412        loadFile(char const* path, ISlangBlob** outBlob) = 0;
1413    };
1414#define SLANG_UUID_ISlangFileSystem ISlangFileSystem::getTypeGuid()
1415
1416
1417    typedef void (*SlangFuncPtr)(void);
1418
1419    /**
1420    (DEPRECATED) ISlangSharedLibrary
1421    */
1422    struct ISlangSharedLibrary_Dep1 : public ISlangUnknown
1423    {
1424        SLANG_COM_INTERFACE(
1425            0x9c9d5bc5,
1426            0xeb61,
1427            0x496f,
1428            {0x80, 0xd7, 0xd1, 0x47, 0xc4, 0xa2, 0x37, 0x30})
1429
1430        virtual SLANG_NO_THROW void* SLANG_MCALL findSymbolAddressByName(char const* name) = 0;
1431    };
1432#define SLANG_UUID_ISlangSharedLibrary_Dep1 ISlangSharedLibrary_Dep1::getTypeGuid()
1433
1434    /** An interface that can be used to encapsulate access to a shared library. An implementation
1435    does not have to implement the library as a shared library
1436    */
1437    struct ISlangSharedLibrary : public ISlangCastable
1438    {
1439        SLANG_COM_INTERFACE(
1440            0x70dbc7c4,
1441            0xdc3b,
1442            0x4a07,
1443            {0xae, 0x7e, 0x75, 0x2a, 0xf6, 0xa8, 0x15, 0x55})
1444
1445        /** Get a function by name. If the library is unloaded will only return nullptr.
1446        @param name The name of the function
1447        @return The function pointer related to the name or nullptr if not found
1448        */
1449        SLANG_FORCE_INLINE SlangFuncPtr findFuncByName(char const* name)
1450        {
1451            return (SlangFuncPtr)findSymbolAddressByName(name);
1452        }
1453
1454        /** Get a symbol by name. If the library is unloaded will only return nullptr.
1455        @param name The name of the symbol
1456        @return The pointer related to the name or nullptr if not found
1457        */
1458        virtual SLANG_NO_THROW void* SLANG_MCALL findSymbolAddressByName(char const* name) = 0;
1459    };
1460#define SLANG_UUID_ISlangSharedLibrary ISlangSharedLibrary::getTypeGuid()
1461
1462    struct ISlangSharedLibraryLoader : public ISlangUnknown
1463    {
1464        SLANG_COM_INTERFACE(
1465            0x6264ab2b,
1466            0xa3e8,
1467            0x4a06,
1468            {0x97, 0xf1, 0x49, 0xbc, 0x2d, 0x2a, 0xb1, 0x4d})
1469
1470        /** Load a shared library. In typical usage the library name should *not* contain any
1471        platform specific elements. For example on windows a dll name should *not* be passed with a
1472        '.dll' extension, and similarly on linux a shared library should *not* be passed with the
1473        'lib' prefix and '.so' extension
1474        @path path The unadorned filename and/or path for the shared library
1475        @ param sharedLibraryOut Holds the shared library if successfully loaded */
1476        virtual SLANG_NO_THROW SlangResult SLANG_MCALL
1477        loadSharedLibrary(const char* path, ISlangSharedLibrary** sharedLibraryOut) = 0;
1478    };
1479#define SLANG_UUID_ISlangSharedLibraryLoader ISlangSharedLibraryLoader::getTypeGuid()
1480
1481    /* Type that identifies how a path should be interpreted */
1482    typedef unsigned int SlangPathTypeIntegral;
1483    enum SlangPathType : SlangPathTypeIntegral
1484    {
1485        SLANG_PATH_TYPE_DIRECTORY, /**< Path specified specifies a directory. */
1486        SLANG_PATH_TYPE_FILE,      /**< Path specified is to a file. */
1487    };
1488
1489    /* Callback to enumerate the contents of of a directory in a ISlangFileSystemExt.
1490    The name is the name of a file system object (directory/file) in the specified path (ie it is
1491    without a path) */
1492    typedef void (
1493        *FileSystemContentsCallBack)(SlangPathType pathType, const char* name, void* userData);
1494
1495    /* Determines how paths map to files on the OS file system */
1496    enum class OSPathKind : uint8_t
1497    {
1498        None,            ///< Paths do not map to the file system
1499        Direct,          ///< Paths map directly to the file system
1500        OperatingSystem, ///< Only paths gained via PathKind::OperatingSystem map to the operating
1501                         ///< system file system
1502    };
1503
1504    /* Used to determine what kind of path is required from an input path */
1505    enum class PathKind
1506    {
1507        /// Given a path, returns a simplified version of that path.
1508        /// This typically means removing '..' and/or '.' from the path.
1509        /// A simplified path must point to the same object as the original.
1510        Simplified,
1511
1512        /// Given a path, returns a 'canonical path' to the item.
1513        /// This may be the operating system 'canonical path' that is the unique path to the item.
1514        ///
1515        /// If the item exists the returned canonical path should always be usable to access the
1516        /// item.
1517        ///
1518        /// If the item the path specifies doesn't exist, the canonical path may not be returnable
1519        /// or be a path simplification.
1520        /// Not all file systems support canonical paths.
1521        Canonical,
1522
1523        /// Given a path returns a path such that it is suitable to be displayed to the user.
1524        ///
1525        /// For example if the file system is a zip file - it might include the path to the zip
1526        /// container as well as the path to the specific file.
1527        ///
1528        /// NOTE! The display path won't necessarily work on the file system to access the item
1529        Display,
1530
1531        /// Get the path to the item on the *operating system* file system, if available.
1532        OperatingSystem,
1533
1534        CountOf,
1535    };
1536
1537    /** An extended file system abstraction.
1538
1539    Implementing and using this interface over ISlangFileSystem gives much more control over how
1540    paths are managed, as well as how it is determined if two files 'are the same'.
1541
1542    All paths as input char*, or output as ISlangBlobs are always encoded as UTF-8 strings.
1543    Blobs that contain strings are always zero terminated.
1544    */
1545    struct ISlangFileSystemExt : public ISlangFileSystem
1546    {
1547        SLANG_COM_INTERFACE(
1548            0x5fb632d2,
1549            0x979d,
1550            0x4481,
1551            {0x9f, 0xee, 0x66, 0x3c, 0x3f, 0x14, 0x49, 0xe1})
1552
1553        /** Get a uniqueIdentity which uniquely identifies an object of the file system.
1554
1555        Given a path, returns a 'uniqueIdentity' which ideally is the same value for the same object
1556        on the file system.
1557
1558        The uniqueIdentity is used to compare if two paths are the same - which amongst other things
1559        allows Slang to cache source contents internally. It is also used for #pragma once
1560        functionality.
1561
1562        A *requirement* is for any implementation is that two paths can only return the same
1563        uniqueIdentity if the contents of the two files are *identical*. If an implementation breaks
1564        this constraint it can produce incorrect compilation. If an implementation cannot *strictly*
1565        identify *the same* files, this will only have an effect on #pragma once behavior.
1566
1567        The string for the uniqueIdentity is held zero terminated in the ISlangBlob of
1568        outUniqueIdentity.
1569
1570        Note that there are many ways a uniqueIdentity may be generated for a file. For example it
1571        could be the 'canonical path' - assuming it is available and unambiguous for a file system.
1572        Another possible mechanism could be to store the filename combined with the file date time
1573        to uniquely identify it.
1574
1575        The client must ensure the blob be released when no longer used, otherwise memory will leak.
1576
1577        NOTE! Ideally this method would be called 'getPathUniqueIdentity' but for historical reasons
1578        and backward compatibility it's name remains with 'File' even though an implementation
1579        should be made to work with directories too.
1580
1581        @param path
1582        @param outUniqueIdentity
1583        @returns A `SlangResult` to indicate success or failure getting the uniqueIdentity.
1584        */
1585        virtual SLANG_NO_THROW SlangResult SLANG_MCALL
1586        getFileUniqueIdentity(const char* path, ISlangBlob** outUniqueIdentity) = 0;
1587
1588        /** Calculate a path combining the 'fromPath' with 'path'
1589
1590        The client must ensure the blob be released when no longer used, otherwise memory will leak.
1591
1592        @param fromPathType How to interpret the from path - as a file or a directory.
1593        @param fromPath The from path.
1594        @param path Path to be determined relative to the fromPath
1595        @param pathOut Holds the string which is the relative path. The string is held in the blob
1596        zero terminated.
1597        @returns A `SlangResult` to indicate success or failure in loading the file.
1598        */
1599        virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcCombinedPath(
1600            SlangPathType fromPathType,
1601            const char* fromPath,
1602            const char* path,
1603            ISlangBlob** pathOut) = 0;
1604
1605        /** Gets the type of path that path is on the file system.
1606        @param path
1607        @param pathTypeOut
1608        @returns SLANG_OK if located and type is known, else an error. SLANG_E_NOT_FOUND if not
1609        found.
1610        */
1611        virtual SLANG_NO_THROW SlangResult SLANG_MCALL
1612        getPathType(const char* path, SlangPathType* pathTypeOut) = 0;
1613
1614        /** Get a path based on the kind.
1615
1616        @param kind The kind of path wanted
1617        @param path The input path
1618        @param outPath The output path held in a blob
1619        @returns SLANG_OK if successfully simplified the path (SLANG_E_NOT_IMPLEMENTED if not
1620        implemented, or some other error code)
1621        */
1622        virtual SLANG_NO_THROW SlangResult SLANG_MCALL
1623        getPath(PathKind kind, const char* path, ISlangBlob** outPath) = 0;
1624
1625        /** Clears any cached information */
1626        virtual SLANG_NO_THROW void SLANG_MCALL clearCache() = 0;
1627
1628        /** Enumerate the contents of the path
1629
1630        Note that for normal Slang operation it isn't necessary to enumerate contents this can
1631        return SLANG_E_NOT_IMPLEMENTED.
1632
1633        @param The path to enumerate
1634        @param callback This callback is called for each entry in the path.
1635        @param userData This is passed to the callback
1636        @returns SLANG_OK if successful
1637        */
1638        virtual SLANG_NO_THROW SlangResult SLANG_MCALL enumeratePathContents(
1639            const char* path,
1640            FileSystemContentsCallBack callback,
1641            void* userData) = 0;
1642
1643        /** Returns how paths map to the OS file system
1644
1645        @returns OSPathKind that describes how paths map to the Operating System file system
1646        */
1647        virtual SLANG_NO_THROW OSPathKind SLANG_MCALL getOSPathKind() = 0;
1648    };
1649
1650#define SLANG_UUID_ISlangFileSystemExt ISlangFileSystemExt::getTypeGuid()
1651
1652    struct ISlangMutableFileSystem : public ISlangFileSystemExt
1653    {
1654        SLANG_COM_INTERFACE(
1655            0xa058675c,
1656            0x1d65,
1657            0x452a,
1658            {0x84, 0x58, 0xcc, 0xde, 0xd1, 0x42, 0x71, 0x5})
1659
1660        /** Write data to the specified path.
1661
1662        @param path The path for data to be saved to
1663        @param data The data to be saved
1664        @param size The size of the data in bytes
1665        @returns SLANG_OK if successful (SLANG_E_NOT_IMPLEMENTED if not implemented, or some other
1666        error code)
1667        */
1668        virtual SLANG_NO_THROW SlangResult SLANG_MCALL
1669        saveFile(const char* path, const void* data, size_t size) = 0;
1670
1671        /** Write data in the form of a blob to the specified path.
1672
1673        Depending on the implementation writing a blob might be faster/use less memory. It is
1674        assumed the blob is *immutable* and that an implementation can reference count it.
1675
1676        It is not guaranteed loading the same file will return the *same* blob - just a blob with
1677        same contents.
1678
1679        @param path The path for data to be saved to
1680        @param dataBlob The data to be saved
1681        @returns SLANG_OK if successful (SLANG_E_NOT_IMPLEMENTED if not implemented, or some other
1682        error code)
1683        */
1684        virtual SLANG_NO_THROW SlangResult SLANG_MCALL
1685        saveFileBlob(const char* path, ISlangBlob* dataBlob) = 0;
1686
1687        /** Remove the entry in the path (directory of file). Will only delete an empty directory,
1688        if not empty will return an error.
1689
1690        @param path The path to remove
1691        @returns SLANG_OK if successful
1692        */
1693        virtual SLANG_NO_THROW SlangResult SLANG_MCALL remove(const char* path) = 0;
1694
1695        /** Create a directory.
1696
1697        The path to the directory must exist
1698
1699        @param path To the directory to create. The parent path *must* exist otherwise will return
1700        an error.
1701        @returns SLANG_OK if successful
1702        */
1703        virtual SLANG_NO_THROW SlangResult SLANG_MCALL createDirectory(const char* path) = 0;
1704    };
1705
1706#define SLANG_UUID_ISlangMutableFileSystem ISlangMutableFileSystem::getTypeGuid()
1707
1708    /* Identifies different types of writer target*/
1709    typedef unsigned int SlangWriterChannelIntegral;
1710    enum SlangWriterChannel : SlangWriterChannelIntegral
1711    {
1712        SLANG_WRITER_CHANNEL_DIAGNOSTIC,
1713        SLANG_WRITER_CHANNEL_STD_OUTPUT,
1714        SLANG_WRITER_CHANNEL_STD_ERROR,
1715        SLANG_WRITER_CHANNEL_COUNT_OF,
1716    };
1717
1718    typedef unsigned int SlangWriterModeIntegral;
1719    enum SlangWriterMode : SlangWriterModeIntegral
1720    {
1721        SLANG_WRITER_MODE_TEXT,
1722        SLANG_WRITER_MODE_BINARY,
1723    };
1724
1725    /** A stream typically of text, used for outputting diagnostic as well as other information.
1726     */
1727    struct ISlangWriter : public ISlangUnknown
1728    {
1729        SLANG_COM_INTERFACE(
1730            0xec457f0e,
1731            0x9add,
1732            0x4e6b,
1733            {0x85, 0x1c, 0xd7, 0xfa, 0x71, 0x6d, 0x15, 0xfd})
1734
1735        /** Begin an append buffer.
1736        NOTE! Only one append buffer can be active at any time.
1737        @param maxNumChars The maximum of chars that will be appended
1738        @returns The start of the buffer for appending to. */
1739        virtual SLANG_NO_THROW char* SLANG_MCALL beginAppendBuffer(size_t maxNumChars) = 0;
1740        /** Ends the append buffer, and is equivalent to a write of the append buffer.
1741        NOTE! That an endAppendBuffer is not necessary if there are no characters to write.
1742        @param buffer is the start of the data to append and must be identical to last value
1743        returned from beginAppendBuffer
1744        @param numChars must be a value less than or equal to what was returned from last call to
1745        beginAppendBuffer
1746        @returns Result, will be SLANG_OK on success */
1747        virtual SLANG_NO_THROW SlangResult SLANG_MCALL
1748        endAppendBuffer(char* buffer, size_t numChars) = 0;
1749        /** Write text to the writer
1750        @param chars The characters to write out
1751        @param numChars The amount of characters
1752        @returns SLANG_OK on success */
1753        virtual SLANG_NO_THROW SlangResult SLANG_MCALL
1754        write(const char* chars, size_t numChars) = 0;
1755        /** Flushes any content to the output */
1756        virtual SLANG_NO_THROW void SLANG_MCALL flush() = 0;
1757        /** Determines if the writer stream is to the console, and can be used to alter the output
1758        @returns Returns true if is a console writer */
1759        virtual SLANG_NO_THROW SlangBool SLANG_MCALL isConsole() = 0;
1760        /** Set the mode for the writer to use
1761        @param mode The mode to use
1762        @returns SLANG_OK on success */
1763        virtual SLANG_NO_THROW SlangResult SLANG_MCALL setMode(SlangWriterMode mode) = 0;
1764    };
1765
1766#define SLANG_UUID_ISlangWriter ISlangWriter::getTypeGuid()
1767
1768    struct ISlangProfiler : public ISlangUnknown
1769    {
1770        SLANG_COM_INTERFACE(
1771            0x197772c7,
1772            0x0155,
1773            0x4b91,
1774            {0x84, 0xe8, 0x66, 0x68, 0xba, 0xff, 0x06, 0x19})
1775        virtual SLANG_NO_THROW size_t SLANG_MCALL getEntryCount() = 0;
1776        virtual SLANG_NO_THROW const char* SLANG_MCALL getEntryName(uint32_t index) = 0;
1777        virtual SLANG_NO_THROW long SLANG_MCALL getEntryTimeMS(uint32_t index) = 0;
1778        virtual SLANG_NO_THROW uint32_t SLANG_MCALL getEntryInvocationTimes(uint32_t index) = 0;
1779    };
1780#define SLANG_UUID_ISlangProfiler ISlangProfiler::getTypeGuid()
1781
1782    namespace slang
1783    {
1784    struct IGlobalSession;
1785    struct ICompileRequest;
1786
1787    } // namespace slang
1788
1789    /*!
1790    @brief An instance of the Slang library.
1791    */
1792    typedef slang::IGlobalSession SlangSession;
1793
1794
1795    typedef struct SlangProgramLayout SlangProgramLayout;
1796
1797    /*!
1798    @brief A request for one or more compilation actions to be performed.
1799    */
1800    typedef struct slang::ICompileRequest SlangCompileRequest;
1801
1802
1803    /*!
1804@brief Callback type used for diagnostic output.
1805*/
1806    typedef void (*SlangDiagnosticCallback)(char const* message, void* userData);
1807
1808    /*!
1809    @brief Get the build version 'tag' string. The string is the same as
1810    produced via `git describe --tags --match v*` for the project. If such a
1811    version could not be determined at build time then the contents will be
1812    0.0.0-unknown. Any string can be set by passing
1813    -DSLANG_VERSION_FULL=whatever during the cmake invocation.
1814
1815    This function will return exactly the same result as the method
1816    getBuildTagString on IGlobalSession.
1817
1818    An advantage of using this function over the method is that doing so does
1819    not require the creation of a session, which can be a fairly costly
1820    operation.
1821
1822    @return The build tag string
1823    */
1824    SLANG_API const char* spGetBuildTagString();
1825
1826    /*
1827    Forward declarations of types used in the reflection interface;
1828    */
1829
1830    typedef struct SlangProgramLayout SlangProgramLayout;
1831    typedef struct SlangEntryPoint SlangEntryPoint;
1832    typedef struct SlangEntryPointLayout SlangEntryPointLayout;
1833
1834    typedef struct SlangReflectionDecl SlangReflectionDecl;
1835    typedef struct SlangReflectionModifier SlangReflectionModifier;
1836    typedef struct SlangReflectionType SlangReflectionType;
1837    typedef struct SlangReflectionTypeLayout SlangReflectionTypeLayout;
1838    typedef struct SlangReflectionVariable SlangReflectionVariable;
1839    typedef struct SlangReflectionVariableLayout SlangReflectionVariableLayout;
1840    typedef struct SlangReflectionTypeParameter SlangReflectionTypeParameter;
1841    typedef struct SlangReflectionUserAttribute SlangReflectionUserAttribute;
1842    typedef SlangReflectionUserAttribute SlangReflectionAttribute;
1843    typedef struct SlangReflectionFunction SlangReflectionFunction;
1844    typedef struct SlangReflectionGeneric SlangReflectionGeneric;
1845
1846    union SlangReflectionGenericArg
1847    {
1848        SlangReflectionType* typeVal;
1849        int64_t intVal;
1850        bool boolVal;
1851    };
1852
1853    enum SlangReflectionGenericArgType
1854    {
1855        SLANG_GENERIC_ARG_TYPE = 0,
1856        SLANG_GENERIC_ARG_INT = 1,
1857        SLANG_GENERIC_ARG_BOOL = 2
1858    };
1859
1860    /*
1861    Type aliases to maintain backward compatibility.
1862    */
1863    typedef SlangProgramLayout SlangReflection;
1864    typedef SlangEntryPointLayout SlangReflectionEntryPoint;
1865
1866    // type reflection
1867
1868    typedef unsigned int SlangTypeKindIntegral;
1869    enum SlangTypeKind : SlangTypeKindIntegral
1870    {
1871        SLANG_TYPE_KIND_NONE,
1872        SLANG_TYPE_KIND_STRUCT,
1873        SLANG_TYPE_KIND_ARRAY,
1874        SLANG_TYPE_KIND_MATRIX,
1875        SLANG_TYPE_KIND_VECTOR,
1876        SLANG_TYPE_KIND_SCALAR,
1877        SLANG_TYPE_KIND_CONSTANT_BUFFER,
1878        SLANG_TYPE_KIND_RESOURCE,
1879        SLANG_TYPE_KIND_SAMPLER_STATE,
1880        SLANG_TYPE_KIND_TEXTURE_BUFFER,
1881        SLANG_TYPE_KIND_SHADER_STORAGE_BUFFER,
1882        SLANG_TYPE_KIND_PARAMETER_BLOCK,
1883        SLANG_TYPE_KIND_GENERIC_TYPE_PARAMETER,
1884        SLANG_TYPE_KIND_INTERFACE,
1885        SLANG_TYPE_KIND_OUTPUT_STREAM,
1886        SLANG_TYPE_KIND_MESH_OUTPUT,
1887        SLANG_TYPE_KIND_SPECIALIZED,
1888        SLANG_TYPE_KIND_FEEDBACK,
1889        SLANG_TYPE_KIND_POINTER,
1890        SLANG_TYPE_KIND_DYNAMIC_RESOURCE,
1891        SLANG_TYPE_KIND_COUNT,
1892    };
1893
1894    typedef unsigned int SlangScalarTypeIntegral;
1895    enum SlangScalarType : SlangScalarTypeIntegral
1896    {
1897        SLANG_SCALAR_TYPE_NONE,
1898        SLANG_SCALAR_TYPE_VOID,
1899        SLANG_SCALAR_TYPE_BOOL,
1900        SLANG_SCALAR_TYPE_INT32,
1901        SLANG_SCALAR_TYPE_UINT32,
1902        SLANG_SCALAR_TYPE_INT64,
1903        SLANG_SCALAR_TYPE_UINT64,
1904        SLANG_SCALAR_TYPE_FLOAT16,
1905        SLANG_SCALAR_TYPE_FLOAT32,
1906        SLANG_SCALAR_TYPE_FLOAT64,
1907        SLANG_SCALAR_TYPE_INT8,
1908        SLANG_SCALAR_TYPE_UINT8,
1909        SLANG_SCALAR_TYPE_INT16,
1910        SLANG_SCALAR_TYPE_UINT16,
1911        SLANG_SCALAR_TYPE_INTPTR,
1912        SLANG_SCALAR_TYPE_UINTPTR
1913    };
1914
1915    // abstract decl reflection
1916    typedef unsigned int SlangDeclKindIntegral;
1917    enum SlangDeclKind : SlangDeclKindIntegral
1918    {
1919        SLANG_DECL_KIND_UNSUPPORTED_FOR_REFLECTION,
1920        SLANG_DECL_KIND_STRUCT,
1921        SLANG_DECL_KIND_FUNC,
1922        SLANG_DECL_KIND_MODULE,
1923        SLANG_DECL_KIND_GENERIC,
1924        SLANG_DECL_KIND_VARIABLE,
1925        SLANG_DECL_KIND_NAMESPACE
1926    };
1927
1928#ifndef SLANG_RESOURCE_SHAPE
1929    #define SLANG_RESOURCE_SHAPE
1930    typedef unsigned int SlangResourceShapeIntegral;
1931    enum SlangResourceShape : SlangResourceShapeIntegral
1932    {
1933        SLANG_RESOURCE_BASE_SHAPE_MASK = 0x0F,
1934
1935        SLANG_RESOURCE_NONE = 0x00,
1936
1937        SLANG_TEXTURE_1D = 0x01,
1938        SLANG_TEXTURE_2D = 0x02,
1939        SLANG_TEXTURE_3D = 0x03,
1940        SLANG_TEXTURE_CUBE = 0x04,
1941        SLANG_TEXTURE_BUFFER = 0x05,
1942
1943        SLANG_STRUCTURED_BUFFER = 0x06,
1944        SLANG_BYTE_ADDRESS_BUFFER = 0x07,
1945        SLANG_RESOURCE_UNKNOWN = 0x08,
1946        SLANG_ACCELERATION_STRUCTURE = 0x09,
1947        SLANG_TEXTURE_SUBPASS = 0x0A,
1948
1949        SLANG_RESOURCE_EXT_SHAPE_MASK = 0x1F0,
1950
1951        SLANG_TEXTURE_FEEDBACK_FLAG = 0x10,
1952        SLANG_TEXTURE_SHADOW_FLAG = 0x20,
1953        SLANG_TEXTURE_ARRAY_FLAG = 0x40,
1954        SLANG_TEXTURE_MULTISAMPLE_FLAG = 0x80,
1955        SLANG_TEXTURE_COMBINED_FLAG = 0x100,
1956
1957        SLANG_TEXTURE_1D_ARRAY = SLANG_TEXTURE_1D | SLANG_TEXTURE_ARRAY_FLAG,
1958        SLANG_TEXTURE_2D_ARRAY = SLANG_TEXTURE_2D | SLANG_TEXTURE_ARRAY_FLAG,
1959        SLANG_TEXTURE_CUBE_ARRAY = SLANG_TEXTURE_CUBE | SLANG_TEXTURE_ARRAY_FLAG,
1960
1961        SLANG_TEXTURE_2D_MULTISAMPLE = SLANG_TEXTURE_2D | SLANG_TEXTURE_MULTISAMPLE_FLAG,
1962        SLANG_TEXTURE_2D_MULTISAMPLE_ARRAY =
1963            SLANG_TEXTURE_2D | SLANG_TEXTURE_MULTISAMPLE_FLAG | SLANG_TEXTURE_ARRAY_FLAG,
1964        SLANG_TEXTURE_SUBPASS_MULTISAMPLE = SLANG_TEXTURE_SUBPASS | SLANG_TEXTURE_MULTISAMPLE_FLAG,
1965    };
1966#endif
1967    typedef unsigned int SlangResourceAccessIntegral;
1968    enum SlangResourceAccess : SlangResourceAccessIntegral
1969    {
1970        SLANG_RESOURCE_ACCESS_NONE,
1971        SLANG_RESOURCE_ACCESS_READ,
1972        SLANG_RESOURCE_ACCESS_READ_WRITE,
1973        SLANG_RESOURCE_ACCESS_RASTER_ORDERED,
1974        SLANG_RESOURCE_ACCESS_APPEND,
1975        SLANG_RESOURCE_ACCESS_CONSUME,
1976        SLANG_RESOURCE_ACCESS_WRITE,
1977        SLANG_RESOURCE_ACCESS_FEEDBACK,
1978        SLANG_RESOURCE_ACCESS_UNKNOWN = 0x7FFFFFFF,
1979    };
1980
1981    typedef unsigned int SlangParameterCategoryIntegral;
1982    enum SlangParameterCategory : SlangParameterCategoryIntegral
1983    {
1984        SLANG_PARAMETER_CATEGORY_NONE,
1985        SLANG_PARAMETER_CATEGORY_MIXED,
1986        SLANG_PARAMETER_CATEGORY_CONSTANT_BUFFER,
1987        SLANG_PARAMETER_CATEGORY_SHADER_RESOURCE,
1988        SLANG_PARAMETER_CATEGORY_UNORDERED_ACCESS,
1989        SLANG_PARAMETER_CATEGORY_VARYING_INPUT,
1990        SLANG_PARAMETER_CATEGORY_VARYING_OUTPUT,
1991        SLANG_PARAMETER_CATEGORY_SAMPLER_STATE,
1992        SLANG_PARAMETER_CATEGORY_UNIFORM,
1993        SLANG_PARAMETER_CATEGORY_DESCRIPTOR_TABLE_SLOT,
1994        SLANG_PARAMETER_CATEGORY_SPECIALIZATION_CONSTANT,
1995        SLANG_PARAMETER_CATEGORY_PUSH_CONSTANT_BUFFER,
1996
1997        // HLSL register `space`, Vulkan GLSL `set`
1998        SLANG_PARAMETER_CATEGORY_REGISTER_SPACE,
1999
2000        // TODO: Ellie, Both APIs treat mesh outputs as more or less varying output,
2001        // Does it deserve to be represented here??
2002
2003        // A parameter whose type is to be specialized by a global generic type argument
2004        SLANG_PARAMETER_CATEGORY_GENERIC,
2005
2006        SLANG_PARAMETER_CATEGORY_RAY_PAYLOAD,
2007        SLANG_PARAMETER_CATEGORY_HIT_ATTRIBUTES,
2008        SLANG_PARAMETER_CATEGORY_CALLABLE_PAYLOAD,
2009        SLANG_PARAMETER_CATEGORY_SHADER_RECORD,
2010
2011        // An existential type parameter represents a "hole" that
2012        // needs to be filled with a concrete type to enable
2013        // generation of specialized code.
2014        //
2015        // Consider this example:
2016        //
2017        //      struct MyParams
2018        //      {
2019        //          IMaterial material;
2020        //          ILight lights[3];
2021        //      };
2022        //
2023        // This `MyParams` type introduces two existential type parameters:
2024        // one for `material` and one for `lights`. Even though `lights`
2025        // is an array, it only introduces one type parameter, because
2026        // we need to have a *single* concrete type for all the array
2027        // elements to be able to generate specialized code.
2028        //
2029        SLANG_PARAMETER_CATEGORY_EXISTENTIAL_TYPE_PARAM,
2030
2031        // An existential object parameter represents a value
2032        // that needs to be passed in to provide data for some
2033        // interface-type shader parameter.
2034        //
2035        // Consider this example:
2036        //
2037        //      struct MyParams
2038        //      {
2039        //          IMaterial material;
2040        //          ILight lights[3];
2041        //      };
2042        //
2043        // This `MyParams` type introduces four existential object parameters:
2044        // one for `material` and three for `lights` (one for each array
2045        // element). This is consistent with the number of interface-type
2046        // "objects" that are being passed through to the shader.
2047        //
2048        SLANG_PARAMETER_CATEGORY_EXISTENTIAL_OBJECT_PARAM,
2049
2050        // The register space offset for the sub-elements that occupies register spaces.
2051        SLANG_PARAMETER_CATEGORY_SUB_ELEMENT_REGISTER_SPACE,
2052
2053        // The input_attachment_index subpass occupancy tracker
2054        SLANG_PARAMETER_CATEGORY_SUBPASS,
2055
2056        // Metal tier-1 argument buffer element [[id]].
2057        SLANG_PARAMETER_CATEGORY_METAL_ARGUMENT_BUFFER_ELEMENT,
2058
2059        // Metal [[attribute]] inputs.
2060        SLANG_PARAMETER_CATEGORY_METAL_ATTRIBUTE,
2061
2062        // Metal [[payload]] inputs
2063        SLANG_PARAMETER_CATEGORY_METAL_PAYLOAD,
2064
2065        //
2066        SLANG_PARAMETER_CATEGORY_COUNT,
2067
2068        // Aliases for Metal-specific categories.
2069        SLANG_PARAMETER_CATEGORY_METAL_BUFFER = SLANG_PARAMETER_CATEGORY_CONSTANT_BUFFER,
2070        SLANG_PARAMETER_CATEGORY_METAL_TEXTURE = SLANG_PARAMETER_CATEGORY_SHADER_RESOURCE,
2071        SLANG_PARAMETER_CATEGORY_METAL_SAMPLER = SLANG_PARAMETER_CATEGORY_SAMPLER_STATE,
2072
2073        // DEPRECATED:
2074        SLANG_PARAMETER_CATEGORY_VERTEX_INPUT = SLANG_PARAMETER_CATEGORY_VARYING_INPUT,
2075        SLANG_PARAMETER_CATEGORY_FRAGMENT_OUTPUT = SLANG_PARAMETER_CATEGORY_VARYING_OUTPUT,
2076        SLANG_PARAMETER_CATEGORY_COUNT_V1 = SLANG_PARAMETER_CATEGORY_SUBPASS,
2077    };
2078
2079    /** Types of API-managed bindings that a parameter might use.
2080
2081    `SlangBindingType` represents the distinct types of binding ranges that might be
2082    understood by an underlying graphics API or cross-API abstraction layer.
2083    Several of the enumeration cases here correspond to cases of `VkDescriptorType`
2084    defined by the Vulkan API. Note however that the values of this enumeration
2085    are not the same as those of any particular API.
2086
2087    The `SlangBindingType` enumeration is distinct from `SlangParameterCategory`
2088    because `SlangParameterCategory` differentiates the types of parameters for
2089    the purposes of layout, where the layout rules of some targets will treat
2090    parameters of different types as occupying the same binding space for layout
2091    (e.g., in SPIR-V both a `Texture2D` and `SamplerState` use the same space of
2092    `binding` indices, and are not allowed to overlap), while those same types
2093    map to different types of bindings in the API (e.g., both textures and samplers
2094    use different `VkDescriptorType` values).
2095
2096    When you want to answer "what register/binding did this parameter use?" you
2097    should use `SlangParameterCategory`.
2098
2099    When you want to answer "what type of descriptor range should this parameter use?"
2100    you should use `SlangBindingType`.
2101    */
2102    typedef SlangUInt32 SlangBindingTypeIntegral;
2103    enum SlangBindingType : SlangBindingTypeIntegral
2104    {
2105        SLANG_BINDING_TYPE_UNKNOWN = 0,
2106
2107        SLANG_BINDING_TYPE_SAMPLER,
2108        SLANG_BINDING_TYPE_TEXTURE,
2109        SLANG_BINDING_TYPE_CONSTANT_BUFFER,
2110        SLANG_BINDING_TYPE_PARAMETER_BLOCK,
2111        SLANG_BINDING_TYPE_TYPED_BUFFER,
2112        SLANG_BINDING_TYPE_RAW_BUFFER,
2113        SLANG_BINDING_TYPE_COMBINED_TEXTURE_SAMPLER,
2114        SLANG_BINDING_TYPE_INPUT_RENDER_TARGET,
2115        SLANG_BINDING_TYPE_INLINE_UNIFORM_DATA,
2116        SLANG_BINDING_TYPE_RAY_TRACING_ACCELERATION_STRUCTURE,
2117
2118        SLANG_BINDING_TYPE_VARYING_INPUT,
2119        SLANG_BINDING_TYPE_VARYING_OUTPUT,
2120
2121        SLANG_BINDING_TYPE_EXISTENTIAL_VALUE,
2122        SLANG_BINDING_TYPE_PUSH_CONSTANT,
2123
2124        SLANG_BINDING_TYPE_MUTABLE_FLAG = 0x100,
2125
2126        SLANG_BINDING_TYPE_MUTABLE_TETURE =
2127            SLANG_BINDING_TYPE_TEXTURE | SLANG_BINDING_TYPE_MUTABLE_FLAG,
2128        SLANG_BINDING_TYPE_MUTABLE_TYPED_BUFFER =
2129            SLANG_BINDING_TYPE_TYPED_BUFFER | SLANG_BINDING_TYPE_MUTABLE_FLAG,
2130        SLANG_BINDING_TYPE_MUTABLE_RAW_BUFFER =
2131            SLANG_BINDING_TYPE_RAW_BUFFER | SLANG_BINDING_TYPE_MUTABLE_FLAG,
2132
2133        SLANG_BINDING_TYPE_BASE_MASK = 0x00FF,
2134        SLANG_BINDING_TYPE_EXT_MASK = 0xFF00,
2135    };
2136
2137    typedef SlangUInt32 SlangLayoutRulesIntegral;
2138    enum SlangLayoutRules : SlangLayoutRulesIntegral
2139    {
2140        SLANG_LAYOUT_RULES_DEFAULT,
2141        SLANG_LAYOUT_RULES_METAL_ARGUMENT_BUFFER_TIER_2,
2142    };
2143
2144    typedef SlangUInt32 SlangModifierIDIntegral;
2145    enum SlangModifierID : SlangModifierIDIntegral
2146    {
2147        SLANG_MODIFIER_SHARED,
2148        SLANG_MODIFIER_NO_DIFF,
2149        SLANG_MODIFIER_STATIC,
2150        SLANG_MODIFIER_CONST,
2151        SLANG_MODIFIER_EXPORT,
2152        SLANG_MODIFIER_EXTERN,
2153        SLANG_MODIFIER_DIFFERENTIABLE,
2154        SLANG_MODIFIER_MUTATING,
2155        SLANG_MODIFIER_IN,
2156        SLANG_MODIFIER_OUT,
2157        SLANG_MODIFIER_INOUT
2158    };
2159
2160    typedef SlangUInt32 SlangImageFormatIntegral;
2161    enum SlangImageFormat : SlangImageFormatIntegral
2162    {
2163#define SLANG_FORMAT(NAME, DESC) SLANG_IMAGE_FORMAT_##NAME,
2164#include "slang-image-format-defs.h"
2165#undef SLANG_FORMAT
2166    };
2167
2168#define SLANG_UNBOUNDED_SIZE (~size_t(0))
2169
2170    // Shader Parameter Reflection
2171
2172    typedef SlangReflectionVariableLayout SlangReflectionParameter;
2173
2174#ifdef __cplusplus
2175}
2176#endif
2177
2178#ifdef __cplusplus
2179namespace slang
2180{
2181struct ISession;
2182}
2183#endif
2184
2185#include "slang-deprecated.h"
2186
2187#ifdef __cplusplus
2188
2189/* Helper interfaces for C++ users */
2190namespace slang
2191{
2192struct BufferReflection;
2193struct DeclReflection;
2194struct TypeLayoutReflection;
2195struct TypeReflection;
2196struct VariableLayoutReflection;
2197struct VariableReflection;
2198struct FunctionReflection;
2199struct GenericReflection;
2200
2201union GenericArgReflection
2202{
2203    TypeReflection* typeVal;
2204    int64_t intVal;
2205    bool boolVal;
2206};
2207
2208struct Attribute
2209{
2210    char const* getName()
2211    {
2212        return spReflectionUserAttribute_GetName((SlangReflectionAttribute*)this);
2213    }
2214    uint32_t getArgumentCount()
2215    {
2216        return (uint32_t)spReflectionUserAttribute_GetArgumentCount(
2217            (SlangReflectionAttribute*)this);
2218    }
2219    TypeReflection* getArgumentType(uint32_t index)
2220    {
2221        return (TypeReflection*)spReflectionUserAttribute_GetArgumentType(
2222            (SlangReflectionAttribute*)this,
2223            index);
2224    }
2225    SlangResult getArgumentValueInt(uint32_t index, int* value)
2226    {
2227        return spReflectionUserAttribute_GetArgumentValueInt(
2228            (SlangReflectionAttribute*)this,
2229            index,
2230            value);
2231    }
2232    SlangResult getArgumentValueFloat(uint32_t index, float* value)
2233    {
2234        return spReflectionUserAttribute_GetArgumentValueFloat(
2235            (SlangReflectionAttribute*)this,
2236            index,
2237            value);
2238    }
2239    const char* getArgumentValueString(uint32_t index, size_t* outSize)
2240    {
2241        return spReflectionUserAttribute_GetArgumentValueString(
2242            (SlangReflectionAttribute*)this,
2243            index,
2244            outSize);
2245    }
2246};
2247
2248typedef Attribute UserAttribute;
2249
2250struct TypeReflection
2251{
2252    enum class Kind
2253    {
2254        None = SLANG_TYPE_KIND_NONE,
2255        Struct = SLANG_TYPE_KIND_STRUCT,
2256        Array = SLANG_TYPE_KIND_ARRAY,
2257        Matrix = SLANG_TYPE_KIND_MATRIX,
2258        Vector = SLANG_TYPE_KIND_VECTOR,
2259        Scalar = SLANG_TYPE_KIND_SCALAR,
2260        ConstantBuffer = SLANG_TYPE_KIND_CONSTANT_BUFFER,
2261        Resource = SLANG_TYPE_KIND_RESOURCE,
2262        SamplerState = SLANG_TYPE_KIND_SAMPLER_STATE,
2263        TextureBuffer = SLANG_TYPE_KIND_TEXTURE_BUFFER,
2264        ShaderStorageBuffer = SLANG_TYPE_KIND_SHADER_STORAGE_BUFFER,
2265        ParameterBlock = SLANG_TYPE_KIND_PARAMETER_BLOCK,
2266        GenericTypeParameter = SLANG_TYPE_KIND_GENERIC_TYPE_PARAMETER,
2267        Interface = SLANG_TYPE_KIND_INTERFACE,
2268        OutputStream = SLANG_TYPE_KIND_OUTPUT_STREAM,
2269        Specialized = SLANG_TYPE_KIND_SPECIALIZED,
2270        Feedback = SLANG_TYPE_KIND_FEEDBACK,
2271        Pointer = SLANG_TYPE_KIND_POINTER,
2272        DynamicResource = SLANG_TYPE_KIND_DYNAMIC_RESOURCE,
2273        MeshOutput = SLANG_TYPE_KIND_MESH_OUTPUT,
2274    };
2275
2276    enum ScalarType : SlangScalarTypeIntegral
2277    {
2278        None = SLANG_SCALAR_TYPE_NONE,
2279        Void = SLANG_SCALAR_TYPE_VOID,
2280        Bool = SLANG_SCALAR_TYPE_BOOL,
2281        Int32 = SLANG_SCALAR_TYPE_INT32,
2282        UInt32 = SLANG_SCALAR_TYPE_UINT32,
2283        Int64 = SLANG_SCALAR_TYPE_INT64,
2284        UInt64 = SLANG_SCALAR_TYPE_UINT64,
2285        Float16 = SLANG_SCALAR_TYPE_FLOAT16,
2286        Float32 = SLANG_SCALAR_TYPE_FLOAT32,
2287        Float64 = SLANG_SCALAR_TYPE_FLOAT64,
2288        Int8 = SLANG_SCALAR_TYPE_INT8,
2289        UInt8 = SLANG_SCALAR_TYPE_UINT8,
2290        Int16 = SLANG_SCALAR_TYPE_INT16,
2291        UInt16 = SLANG_SCALAR_TYPE_UINT16,
2292    };
2293
2294    Kind getKind() { return (Kind)spReflectionType_GetKind((SlangReflectionType*)this); }
2295
2296    // only useful if `getKind() == Kind::Struct`
2297    unsigned int getFieldCount()
2298    {
2299        return spReflectionType_GetFieldCount((SlangReflectionType*)this);
2300    }
2301
2302    VariableReflection* getFieldByIndex(unsigned int index)
2303    {
2304        return (
2305            VariableReflection*)spReflectionType_GetFieldByIndex((SlangReflectionType*)this, index);
2306    }
2307
2308    bool isArray() { return getKind() == TypeReflection::Kind::Array; }
2309
2310    TypeReflection* unwrapArray()
2311    {
2312        TypeReflection* type = this;
2313        while (type->isArray())
2314        {
2315            type = type->getElementType();
2316        }
2317        return type;
2318    }
2319
2320    // only useful if `getKind() == Kind::Array`
2321    size_t getElementCount(SlangReflection* reflection = nullptr)
2322    {
2323        return spReflectionType_GetSpecializedElementCount((SlangReflectionType*)this, reflection);
2324    }
2325
2326    size_t getTotalArrayElementCount()
2327    {
2328        if (!isArray())
2329            return 0;
2330        size_t result = 1;
2331        TypeReflection* type = this;
2332        for (;;)
2333        {
2334            if (!type->isArray())
2335                return result;
2336
2337            result *= type->getElementCount();
2338            type = type->getElementType();
2339        }
2340    }
2341
2342    TypeReflection* getElementType()
2343    {
2344        return (TypeReflection*)spReflectionType_GetElementType((SlangReflectionType*)this);
2345    }
2346
2347    unsigned getRowCount() { return spReflectionType_GetRowCount((SlangReflectionType*)this); }
2348
2349    unsigned getColumnCount()
2350    {
2351        return spReflectionType_GetColumnCount((SlangReflectionType*)this);
2352    }
2353
2354    ScalarType getScalarType()
2355    {
2356        return (ScalarType)spReflectionType_GetScalarType((SlangReflectionType*)this);
2357    }
2358
2359    TypeReflection* getResourceResultType()
2360    {
2361        return (TypeReflection*)spReflectionType_GetResourceResultType((SlangReflectionType*)this);
2362    }
2363
2364    SlangResourceShape getResourceShape()
2365    {
2366        return spReflectionType_GetResourceShape((SlangReflectionType*)this);
2367    }
2368
2369    SlangResourceAccess getResourceAccess()
2370    {
2371        return spReflectionType_GetResourceAccess((SlangReflectionType*)this);
2372    }
2373
2374    char const* getName() { return spReflectionType_GetName((SlangReflectionType*)this); }
2375
2376    SlangResult getFullName(ISlangBlob** outNameBlob)
2377    {
2378        return spReflectionType_GetFullName((SlangReflectionType*)this, outNameBlob);
2379    }
2380
2381    unsigned int getUserAttributeCount()
2382    {
2383        return spReflectionType_GetUserAttributeCount((SlangReflectionType*)this);
2384    }
2385
2386    UserAttribute* getUserAttributeByIndex(unsigned int index)
2387    {
2388        return (UserAttribute*)spReflectionType_GetUserAttribute((SlangReflectionType*)this, index);
2389    }
2390
2391    UserAttribute* findAttributeByName(char const* name)
2392    {
2393        return (UserAttribute*)spReflectionType_FindUserAttributeByName(
2394            (SlangReflectionType*)this,
2395            name);
2396    }
2397
2398    UserAttribute* findUserAttributeByName(char const* name) { return findAttributeByName(name); }
2399
2400    TypeReflection* applySpecializations(GenericReflection* generic)
2401    {
2402        return (TypeReflection*)spReflectionType_applySpecializations(
2403            (SlangReflectionType*)this,
2404            (SlangReflectionGeneric*)generic);
2405    }
2406
2407    GenericReflection* getGenericContainer()
2408    {
2409        return (GenericReflection*)spReflectionType_GetGenericContainer((SlangReflectionType*)this);
2410    }
2411};
2412
2413enum ParameterCategory : SlangParameterCategoryIntegral
2414{
2415    // TODO: these aren't scoped...
2416    None = SLANG_PARAMETER_CATEGORY_NONE,
2417    Mixed = SLANG_PARAMETER_CATEGORY_MIXED,
2418    ConstantBuffer = SLANG_PARAMETER_CATEGORY_CONSTANT_BUFFER,
2419    ShaderResource = SLANG_PARAMETER_CATEGORY_SHADER_RESOURCE,
2420    UnorderedAccess = SLANG_PARAMETER_CATEGORY_UNORDERED_ACCESS,
2421    VaryingInput = SLANG_PARAMETER_CATEGORY_VARYING_INPUT,
2422    VaryingOutput = SLANG_PARAMETER_CATEGORY_VARYING_OUTPUT,
2423    SamplerState = SLANG_PARAMETER_CATEGORY_SAMPLER_STATE,
2424    Uniform = SLANG_PARAMETER_CATEGORY_UNIFORM,
2425    DescriptorTableSlot = SLANG_PARAMETER_CATEGORY_DESCRIPTOR_TABLE_SLOT,
2426    SpecializationConstant = SLANG_PARAMETER_CATEGORY_SPECIALIZATION_CONSTANT,
2427    PushConstantBuffer = SLANG_PARAMETER_CATEGORY_PUSH_CONSTANT_BUFFER,
2428    RegisterSpace = SLANG_PARAMETER_CATEGORY_REGISTER_SPACE,
2429    GenericResource = SLANG_PARAMETER_CATEGORY_GENERIC,
2430
2431    RayPayload = SLANG_PARAMETER_CATEGORY_RAY_PAYLOAD,
2432    HitAttributes = SLANG_PARAMETER_CATEGORY_HIT_ATTRIBUTES,
2433    CallablePayload = SLANG_PARAMETER_CATEGORY_CALLABLE_PAYLOAD,
2434
2435    ShaderRecord = SLANG_PARAMETER_CATEGORY_SHADER_RECORD,
2436
2437    ExistentialTypeParam = SLANG_PARAMETER_CATEGORY_EXISTENTIAL_TYPE_PARAM,
2438    ExistentialObjectParam = SLANG_PARAMETER_CATEGORY_EXISTENTIAL_OBJECT_PARAM,
2439
2440    SubElementRegisterSpace = SLANG_PARAMETER_CATEGORY_SUB_ELEMENT_REGISTER_SPACE,
2441
2442    InputAttachmentIndex = SLANG_PARAMETER_CATEGORY_SUBPASS,
2443
2444    MetalBuffer = SLANG_PARAMETER_CATEGORY_CONSTANT_BUFFER,
2445    MetalTexture = SLANG_PARAMETER_CATEGORY_METAL_TEXTURE,
2446    MetalArgumentBufferElement = SLANG_PARAMETER_CATEGORY_METAL_ARGUMENT_BUFFER_ELEMENT,
2447    MetalAttribute = SLANG_PARAMETER_CATEGORY_METAL_ATTRIBUTE,
2448    MetalPayload = SLANG_PARAMETER_CATEGORY_METAL_PAYLOAD,
2449
2450    // DEPRECATED:
2451    VertexInput = SLANG_PARAMETER_CATEGORY_VERTEX_INPUT,
2452    FragmentOutput = SLANG_PARAMETER_CATEGORY_FRAGMENT_OUTPUT,
2453};
2454
2455enum class BindingType : SlangBindingTypeIntegral
2456{
2457    Unknown = SLANG_BINDING_TYPE_UNKNOWN,
2458
2459    Sampler = SLANG_BINDING_TYPE_SAMPLER,
2460    Texture = SLANG_BINDING_TYPE_TEXTURE,
2461    ConstantBuffer = SLANG_BINDING_TYPE_CONSTANT_BUFFER,
2462    ParameterBlock = SLANG_BINDING_TYPE_PARAMETER_BLOCK,
2463    TypedBuffer = SLANG_BINDING_TYPE_TYPED_BUFFER,
2464    RawBuffer = SLANG_BINDING_TYPE_RAW_BUFFER,
2465    CombinedTextureSampler = SLANG_BINDING_TYPE_COMBINED_TEXTURE_SAMPLER,
2466    InputRenderTarget = SLANG_BINDING_TYPE_INPUT_RENDER_TARGET,
2467    InlineUniformData = SLANG_BINDING_TYPE_INLINE_UNIFORM_DATA,
2468    RayTracingAccelerationStructure = SLANG_BINDING_TYPE_RAY_TRACING_ACCELERATION_STRUCTURE,
2469    VaryingInput = SLANG_BINDING_TYPE_VARYING_INPUT,
2470    VaryingOutput = SLANG_BINDING_TYPE_VARYING_OUTPUT,
2471    ExistentialValue = SLANG_BINDING_TYPE_EXISTENTIAL_VALUE,
2472    PushConstant = SLANG_BINDING_TYPE_PUSH_CONSTANT,
2473
2474    MutableFlag = SLANG_BINDING_TYPE_MUTABLE_FLAG,
2475
2476    MutableTexture = SLANG_BINDING_TYPE_MUTABLE_TETURE,
2477    MutableTypedBuffer = SLANG_BINDING_TYPE_MUTABLE_TYPED_BUFFER,
2478    MutableRawBuffer = SLANG_BINDING_TYPE_MUTABLE_RAW_BUFFER,
2479
2480    BaseMask = SLANG_BINDING_TYPE_BASE_MASK,
2481    ExtMask = SLANG_BINDING_TYPE_EXT_MASK,
2482};
2483
2484struct ShaderReflection;
2485
2486struct TypeLayoutReflection
2487{
2488    TypeReflection* getType()
2489    {
2490        return (TypeReflection*)spReflectionTypeLayout_GetType((SlangReflectionTypeLayout*)this);
2491    }
2492
2493    TypeReflection::Kind getKind()
2494    {
2495        return (TypeReflection::Kind)spReflectionTypeLayout_getKind(
2496            (SlangReflectionTypeLayout*)this);
2497    }
2498
2499    size_t getSize(SlangParameterCategory category)
2500    {
2501        return spReflectionTypeLayout_GetSize((SlangReflectionTypeLayout*)this, category);
2502    }
2503
2504    size_t getStride(SlangParameterCategory category)
2505    {
2506        return spReflectionTypeLayout_GetStride((SlangReflectionTypeLayout*)this, category);
2507    }
2508
2509    int32_t getAlignment(SlangParameterCategory category)
2510    {
2511        return spReflectionTypeLayout_getAlignment((SlangReflectionTypeLayout*)this, category);
2512    }
2513
2514    size_t getSize(slang::ParameterCategory category = slang::ParameterCategory::Uniform)
2515    {
2516        return spReflectionTypeLayout_GetSize(
2517            (SlangReflectionTypeLayout*)this,
2518            (SlangParameterCategory)category);
2519    }
2520
2521    size_t getStride(slang::ParameterCategory category = slang::ParameterCategory::Uniform)
2522    {
2523        return spReflectionTypeLayout_GetStride(
2524            (SlangReflectionTypeLayout*)this,
2525            (SlangParameterCategory)category);
2526    }
2527
2528    int32_t getAlignment(slang::ParameterCategory category = slang::ParameterCategory::Uniform)
2529    {
2530        return spReflectionTypeLayout_getAlignment(
2531            (SlangReflectionTypeLayout*)this,
2532            (SlangParameterCategory)category);
2533    }
2534
2535
2536    unsigned int getFieldCount()
2537    {
2538        return spReflectionTypeLayout_GetFieldCount((SlangReflectionTypeLayout*)this);
2539    }
2540
2541    VariableLayoutReflection* getFieldByIndex(unsigned int index)
2542    {
2543        return (VariableLayoutReflection*)spReflectionTypeLayout_GetFieldByIndex(
2544            (SlangReflectionTypeLayout*)this,
2545            index);
2546    }
2547
2548    SlangInt findFieldIndexByName(char const* nameBegin, char const* nameEnd = nullptr)
2549    {
2550        return spReflectionTypeLayout_findFieldIndexByName(
2551            (SlangReflectionTypeLayout*)this,
2552            nameBegin,
2553            nameEnd);
2554    }
2555
2556    VariableLayoutReflection* getExplicitCounter()
2557    {
2558        return (VariableLayoutReflection*)spReflectionTypeLayout_GetExplicitCounter(
2559            (SlangReflectionTypeLayout*)this);
2560    }
2561
2562    bool isArray() { return getType()->isArray(); }
2563
2564    TypeLayoutReflection* unwrapArray()
2565    {
2566        TypeLayoutReflection* typeLayout = this;
2567        while (typeLayout->isArray())
2568        {
2569            typeLayout = typeLayout->getElementTypeLayout();
2570        }
2571        return typeLayout;
2572    }
2573
2574    // only useful if `getKind() == Kind::Array`
2575    size_t getElementCount(ShaderReflection* reflection = nullptr)
2576    {
2577        return getType()->getElementCount((SlangReflection*)reflection);
2578    }
2579
2580    size_t getTotalArrayElementCount() { return getType()->getTotalArrayElementCount(); }
2581
2582    size_t getElementStride(SlangParameterCategory category)
2583    {
2584        return spReflectionTypeLayout_GetElementStride((SlangReflectionTypeLayout*)this, category);
2585    }
2586
2587    TypeLayoutReflection* getElementTypeLayout()
2588    {
2589        return (TypeLayoutReflection*)spReflectionTypeLayout_GetElementTypeLayout(
2590            (SlangReflectionTypeLayout*)this);
2591    }
2592
2593    VariableLayoutReflection* getElementVarLayout()
2594    {
2595        return (VariableLayoutReflection*)spReflectionTypeLayout_GetElementVarLayout(
2596            (SlangReflectionTypeLayout*)this);
2597    }
2598
2599    VariableLayoutReflection* getContainerVarLayout()
2600    {
2601        return (VariableLayoutReflection*)spReflectionTypeLayout_getContainerVarLayout(
2602            (SlangReflectionTypeLayout*)this);
2603    }
2604
2605    // How is this type supposed to be bound?
2606    ParameterCategory getParameterCategory()
2607    {
2608        return (ParameterCategory)spReflectionTypeLayout_GetParameterCategory(
2609            (SlangReflectionTypeLayout*)this);
2610    }
2611
2612    unsigned int getCategoryCount()
2613    {
2614        return spReflectionTypeLayout_GetCategoryCount((SlangReflectionTypeLayout*)this);
2615    }
2616
2617    ParameterCategory getCategoryByIndex(unsigned int index)
2618    {
2619        return (ParameterCategory)spReflectionTypeLayout_GetCategoryByIndex(
2620            (SlangReflectionTypeLayout*)this,
2621            index);
2622    }
2623
2624    unsigned getRowCount() { return getType()->getRowCount(); }
2625
2626    unsigned getColumnCount() { return getType()->getColumnCount(); }
2627
2628    TypeReflection::ScalarType getScalarType() { return getType()->getScalarType(); }
2629
2630    TypeReflection* getResourceResultType() { return getType()->getResourceResultType(); }
2631
2632    SlangResourceShape getResourceShape() { return getType()->getResourceShape(); }
2633
2634    SlangResourceAccess getResourceAccess() { return getType()->getResourceAccess(); }
2635
2636    char const* getName() { return getType()->getName(); }
2637
2638    SlangMatrixLayoutMode getMatrixLayoutMode()
2639    {
2640        return spReflectionTypeLayout_GetMatrixLayoutMode((SlangReflectionTypeLayout*)this);
2641    }
2642
2643    int getGenericParamIndex()
2644    {
2645        return spReflectionTypeLayout_getGenericParamIndex((SlangReflectionTypeLayout*)this);
2646    }
2647
2648    TypeLayoutReflection* getPendingDataTypeLayout()
2649    {
2650        return (TypeLayoutReflection*)spReflectionTypeLayout_getPendingDataTypeLayout(
2651            (SlangReflectionTypeLayout*)this);
2652    }
2653
2654    VariableLayoutReflection* getSpecializedTypePendingDataVarLayout()
2655    {
2656        return (VariableLayoutReflection*)
2657            spReflectionTypeLayout_getSpecializedTypePendingDataVarLayout(
2658                (SlangReflectionTypeLayout*)this);
2659    }
2660
2661    SlangInt getBindingRangeCount()
2662    {
2663        return spReflectionTypeLayout_getBindingRangeCount((SlangReflectionTypeLayout*)this);
2664    }
2665
2666    BindingType getBindingRangeType(SlangInt index)
2667    {
2668        return (BindingType)spReflectionTypeLayout_getBindingRangeType(
2669            (SlangReflectionTypeLayout*)this,
2670            index);
2671    }
2672
2673    bool isBindingRangeSpecializable(SlangInt index)
2674    {
2675        return (bool)spReflectionTypeLayout_isBindingRangeSpecializable(
2676            (SlangReflectionTypeLayout*)this,
2677            index);
2678    }
2679
2680    SlangInt getBindingRangeBindingCount(SlangInt index)
2681    {
2682        return spReflectionTypeLayout_getBindingRangeBindingCount(
2683            (SlangReflectionTypeLayout*)this,
2684            index);
2685    }
2686
2687    /*
2688    SlangInt getBindingRangeIndexOffset(SlangInt index)
2689    {
2690        return spReflectionTypeLayout_getBindingRangeIndexOffset(
2691            (SlangReflectionTypeLayout*) this,
2692            index);
2693    }
2694
2695    SlangInt getBindingRangeSpaceOffset(SlangInt index)
2696    {
2697        return spReflectionTypeLayout_getBindingRangeSpaceOffset(
2698            (SlangReflectionTypeLayout*) this,
2699            index);
2700    }
2701    */
2702
2703    SlangInt getFieldBindingRangeOffset(SlangInt fieldIndex)
2704    {
2705        return spReflectionTypeLayout_getFieldBindingRangeOffset(
2706            (SlangReflectionTypeLayout*)this,
2707            fieldIndex);
2708    }
2709
2710    SlangInt getExplicitCounterBindingRangeOffset()
2711    {
2712        return spReflectionTypeLayout_getExplicitCounterBindingRangeOffset(
2713            (SlangReflectionTypeLayout*)this);
2714    }
2715
2716    TypeLayoutReflection* getBindingRangeLeafTypeLayout(SlangInt index)
2717    {
2718        return (TypeLayoutReflection*)spReflectionTypeLayout_getBindingRangeLeafTypeLayout(
2719            (SlangReflectionTypeLayout*)this,
2720            index);
2721    }
2722
2723    VariableReflection* getBindingRangeLeafVariable(SlangInt index)
2724    {
2725        return (VariableReflection*)spReflectionTypeLayout_getBindingRangeLeafVariable(
2726            (SlangReflectionTypeLayout*)this,
2727            index);
2728    }
2729
2730    SlangImageFormat getBindingRangeImageFormat(SlangInt index)
2731    {
2732        return spReflectionTypeLayout_getBindingRangeImageFormat(
2733            (SlangReflectionTypeLayout*)this,
2734            index);
2735    }
2736
2737    SlangInt getBindingRangeDescriptorSetIndex(SlangInt index)
2738    {
2739        return spReflectionTypeLayout_getBindingRangeDescriptorSetIndex(
2740            (SlangReflectionTypeLayout*)this,
2741            index);
2742    }
2743
2744    SlangInt getBindingRangeFirstDescriptorRangeIndex(SlangInt index)
2745    {
2746        return spReflectionTypeLayout_getBindingRangeFirstDescriptorRangeIndex(
2747            (SlangReflectionTypeLayout*)this,
2748            index);
2749    }
2750
2751    SlangInt getBindingRangeDescriptorRangeCount(SlangInt index)
2752    {
2753        return spReflectionTypeLayout_getBindingRangeDescriptorRangeCount(
2754            (SlangReflectionTypeLayout*)this,
2755            index);
2756    }
2757
2758    SlangInt getDescriptorSetCount()
2759    {
2760        return spReflectionTypeLayout_getDescriptorSetCount((SlangReflectionTypeLayout*)this);
2761    }
2762
2763    SlangInt getDescriptorSetSpaceOffset(SlangInt setIndex)
2764    {
2765        return spReflectionTypeLayout_getDescriptorSetSpaceOffset(
2766            (SlangReflectionTypeLayout*)this,
2767            setIndex);
2768    }
2769
2770    SlangInt getDescriptorSetDescriptorRangeCount(SlangInt setIndex)
2771    {
2772        return spReflectionTypeLayout_getDescriptorSetDescriptorRangeCount(
2773            (SlangReflectionTypeLayout*)this,
2774            setIndex);
2775    }
2776
2777    SlangInt getDescriptorSetDescriptorRangeIndexOffset(SlangInt setIndex, SlangInt rangeIndex)
2778    {
2779        return spReflectionTypeLayout_getDescriptorSetDescriptorRangeIndexOffset(
2780            (SlangReflectionTypeLayout*)this,
2781            setIndex,
2782            rangeIndex);
2783    }
2784
2785    SlangInt getDescriptorSetDescriptorRangeDescriptorCount(SlangInt setIndex, SlangInt rangeIndex)
2786    {
2787        return spReflectionTypeLayout_getDescriptorSetDescriptorRangeDescriptorCount(
2788            (SlangReflectionTypeLayout*)this,
2789            setIndex,
2790            rangeIndex);
2791    }
2792
2793    BindingType getDescriptorSetDescriptorRangeType(SlangInt setIndex, SlangInt rangeIndex)
2794    {
2795        return (BindingType)spReflectionTypeLayout_getDescriptorSetDescriptorRangeType(
2796            (SlangReflectionTypeLayout*)this,
2797            setIndex,
2798            rangeIndex);
2799    }
2800
2801    ParameterCategory getDescriptorSetDescriptorRangeCategory(
2802        SlangInt setIndex,
2803        SlangInt rangeIndex)
2804    {
2805        return (ParameterCategory)spReflectionTypeLayout_getDescriptorSetDescriptorRangeCategory(
2806            (SlangReflectionTypeLayout*)this,
2807            setIndex,
2808            rangeIndex);
2809    }
2810
2811    SlangInt getSubObjectRangeCount()
2812    {
2813        return spReflectionTypeLayout_getSubObjectRangeCount((SlangReflectionTypeLayout*)this);
2814    }
2815
2816    SlangInt getSubObjectRangeBindingRangeIndex(SlangInt subObjectRangeIndex)
2817    {
2818        return spReflectionTypeLayout_getSubObjectRangeBindingRangeIndex(
2819            (SlangReflectionTypeLayout*)this,
2820            subObjectRangeIndex);
2821    }
2822
2823    SlangInt getSubObjectRangeSpaceOffset(SlangInt subObjectRangeIndex)
2824    {
2825        return spReflectionTypeLayout_getSubObjectRangeSpaceOffset(
2826            (SlangReflectionTypeLayout*)this,
2827            subObjectRangeIndex);
2828    }
2829
2830    VariableLayoutReflection* getSubObjectRangeOffset(SlangInt subObjectRangeIndex)
2831    {
2832        return (VariableLayoutReflection*)spReflectionTypeLayout_getSubObjectRangeOffset(
2833            (SlangReflectionTypeLayout*)this,
2834            subObjectRangeIndex);
2835    }
2836};
2837
2838struct Modifier
2839{
2840    enum ID : SlangModifierIDIntegral
2841    {
2842        Shared = SLANG_MODIFIER_SHARED,
2843        NoDiff = SLANG_MODIFIER_NO_DIFF,
2844        Static = SLANG_MODIFIER_STATIC,
2845        Const = SLANG_MODIFIER_CONST,
2846        Export = SLANG_MODIFIER_EXPORT,
2847        Extern = SLANG_MODIFIER_EXTERN,
2848        Differentiable = SLANG_MODIFIER_DIFFERENTIABLE,
2849        Mutating = SLANG_MODIFIER_MUTATING,
2850        In = SLANG_MODIFIER_IN,
2851        Out = SLANG_MODIFIER_OUT,
2852        InOut = SLANG_MODIFIER_INOUT
2853    };
2854};
2855
2856struct VariableReflection
2857{
2858    char const* getName() { return spReflectionVariable_GetName((SlangReflectionVariable*)this); }
2859
2860    TypeReflection* getType()
2861    {
2862        return (TypeReflection*)spReflectionVariable_GetType((SlangReflectionVariable*)this);
2863    }
2864
2865    Modifier* findModifier(Modifier::ID id)
2866    {
2867        return (Modifier*)spReflectionVariable_FindModifier(
2868            (SlangReflectionVariable*)this,
2869            (SlangModifierID)id);
2870    }
2871
2872    unsigned int getUserAttributeCount()
2873    {
2874        return spReflectionVariable_GetUserAttributeCount((SlangReflectionVariable*)this);
2875    }
2876
2877    Attribute* getUserAttributeByIndex(unsigned int index)
2878    {
2879        return (UserAttribute*)spReflectionVariable_GetUserAttribute(
2880            (SlangReflectionVariable*)this,
2881            index);
2882    }
2883
2884    Attribute* findAttributeByName(SlangSession* globalSession, char const* name)
2885    {
2886        return (UserAttribute*)spReflectionVariable_FindUserAttributeByName(
2887            (SlangReflectionVariable*)this,
2888            globalSession,
2889            name);
2890    }
2891
2892    Attribute* findUserAttributeByName(SlangSession* globalSession, char const* name)
2893    {
2894        return findAttributeByName(globalSession, name);
2895    }
2896
2897    bool hasDefaultValue()
2898    {
2899        return spReflectionVariable_HasDefaultValue((SlangReflectionVariable*)this);
2900    }
2901
2902    SlangResult getDefaultValueInt(int64_t* value)
2903    {
2904        return spReflectionVariable_GetDefaultValueInt((SlangReflectionVariable*)this, value);
2905    }
2906
2907    GenericReflection* getGenericContainer()
2908    {
2909        return (GenericReflection*)spReflectionVariable_GetGenericContainer(
2910            (SlangReflectionVariable*)this);
2911    }
2912
2913    VariableReflection* applySpecializations(GenericReflection* generic)
2914    {
2915        return (VariableReflection*)spReflectionVariable_applySpecializations(
2916            (SlangReflectionVariable*)this,
2917            (SlangReflectionGeneric*)generic);
2918    }
2919};
2920
2921struct VariableLayoutReflection
2922{
2923    VariableReflection* getVariable()
2924    {
2925        return (VariableReflection*)spReflectionVariableLayout_GetVariable(
2926            (SlangReflectionVariableLayout*)this);
2927    }
2928
2929    char const* getName() { return getVariable()->getName(); }
2930
2931    Modifier* findModifier(Modifier::ID id) { return getVariable()->findModifier(id); }
2932
2933    TypeLayoutReflection* getTypeLayout()
2934    {
2935        return (TypeLayoutReflection*)spReflectionVariableLayout_GetTypeLayout(
2936            (SlangReflectionVariableLayout*)this);
2937    }
2938
2939    ParameterCategory getCategory() { return getTypeLayout()->getParameterCategory(); }
2940
2941    unsigned int getCategoryCount() { return getTypeLayout()->getCategoryCount(); }
2942
2943    ParameterCategory getCategoryByIndex(unsigned int index)
2944    {
2945        return getTypeLayout()->getCategoryByIndex(index);
2946    }
2947
2948
2949    size_t getOffset(SlangParameterCategory category)
2950    {
2951        return spReflectionVariableLayout_GetOffset((SlangReflectionVariableLayout*)this, category);
2952    }
2953    size_t getOffset(slang::ParameterCategory category = slang::ParameterCategory::Uniform)
2954    {
2955        return spReflectionVariableLayout_GetOffset(
2956            (SlangReflectionVariableLayout*)this,
2957            (SlangParameterCategory)category);
2958    }
2959
2960
2961    TypeReflection* getType() { return getVariable()->getType(); }
2962
2963    unsigned getBindingIndex()
2964    {
2965        return spReflectionParameter_GetBindingIndex((SlangReflectionVariableLayout*)this);
2966    }
2967
2968    unsigned getBindingSpace()
2969    {
2970        return spReflectionParameter_GetBindingSpace((SlangReflectionVariableLayout*)this);
2971    }
2972
2973    size_t getBindingSpace(SlangParameterCategory category)
2974    {
2975        return spReflectionVariableLayout_GetSpace((SlangReflectionVariableLayout*)this, category);
2976    }
2977    size_t getBindingSpace(slang::ParameterCategory category)
2978    {
2979        return spReflectionVariableLayout_GetSpace(
2980            (SlangReflectionVariableLayout*)this,
2981            (SlangParameterCategory)category);
2982    }
2983
2984    SlangImageFormat getImageFormat()
2985    {
2986        return spReflectionVariableLayout_GetImageFormat((SlangReflectionVariableLayout*)this);
2987    }
2988
2989    char const* getSemanticName()
2990    {
2991        return spReflectionVariableLayout_GetSemanticName((SlangReflectionVariableLayout*)this);
2992    }
2993
2994    size_t getSemanticIndex()
2995    {
2996        return spReflectionVariableLayout_GetSemanticIndex((SlangReflectionVariableLayout*)this);
2997    }
2998
2999    SlangStage getStage()
3000    {
3001        return spReflectionVariableLayout_getStage((SlangReflectionVariableLayout*)this);
3002    }
3003
3004    VariableLayoutReflection* getPendingDataLayout()
3005    {
3006        return (VariableLayoutReflection*)spReflectionVariableLayout_getPendingDataLayout(
3007            (SlangReflectionVariableLayout*)this);
3008    }
3009};
3010
3011struct FunctionReflection
3012{
3013    char const* getName() { return spReflectionFunction_GetName((SlangReflectionFunction*)this); }
3014
3015    TypeReflection* getReturnType()
3016    {
3017        return (TypeReflection*)spReflectionFunction_GetResultType((SlangReflectionFunction*)this);
3018    }
3019
3020    unsigned int getParameterCount()
3021    {
3022        return spReflectionFunction_GetParameterCount((SlangReflectionFunction*)this);
3023    }
3024
3025    VariableReflection* getParameterByIndex(unsigned int index)
3026    {
3027        return (VariableReflection*)spReflectionFunction_GetParameter(
3028            (SlangReflectionFunction*)this,
3029            index);
3030    }
3031
3032    unsigned int getUserAttributeCount()
3033    {
3034        return spReflectionFunction_GetUserAttributeCount((SlangReflectionFunction*)this);
3035    }
3036    Attribute* getUserAttributeByIndex(unsigned int index)
3037    {
3038        return (
3039            Attribute*)spReflectionFunction_GetUserAttribute((SlangReflectionFunction*)this, index);
3040    }
3041    Attribute* findAttributeByName(SlangSession* globalSession, char const* name)
3042    {
3043        return (Attribute*)spReflectionFunction_FindUserAttributeByName(
3044            (SlangReflectionFunction*)this,
3045            globalSession,
3046            name);
3047    }
3048    Attribute* findUserAttributeByName(SlangSession* globalSession, char const* name)
3049    {
3050        return findAttributeByName(globalSession, name);
3051    }
3052    Modifier* findModifier(Modifier::ID id)
3053    {
3054        return (Modifier*)spReflectionFunction_FindModifier(
3055            (SlangReflectionFunction*)this,
3056            (SlangModifierID)id);
3057    }
3058
3059    GenericReflection* getGenericContainer()
3060    {
3061        return (GenericReflection*)spReflectionFunction_GetGenericContainer(
3062            (SlangReflectionFunction*)this);
3063    }
3064
3065    FunctionReflection* applySpecializations(GenericReflection* generic)
3066    {
3067        return (FunctionReflection*)spReflectionFunction_applySpecializations(
3068            (SlangReflectionFunction*)this,
3069            (SlangReflectionGeneric*)generic);
3070    }
3071
3072    FunctionReflection* specializeWithArgTypes(unsigned int argCount, TypeReflection* const* types)
3073    {
3074        return (FunctionReflection*)spReflectionFunction_specializeWithArgTypes(
3075            (SlangReflectionFunction*)this,
3076            argCount,
3077            (SlangReflectionType* const*)types);
3078    }
3079
3080    bool isOverloaded()
3081    {
3082        return spReflectionFunction_isOverloaded((SlangReflectionFunction*)this);
3083    }
3084
3085    unsigned int getOverloadCount()
3086    {
3087        return spReflectionFunction_getOverloadCount((SlangReflectionFunction*)this);
3088    }
3089
3090    FunctionReflection* getOverload(unsigned int index)
3091    {
3092        return (FunctionReflection*)spReflectionFunction_getOverload(
3093            (SlangReflectionFunction*)this,
3094            index);
3095    }
3096};
3097
3098struct GenericReflection
3099{
3100
3101    DeclReflection* asDecl()
3102    {
3103        return (DeclReflection*)spReflectionGeneric_asDecl((SlangReflectionGeneric*)this);
3104    }
3105
3106    char const* getName() { return spReflectionGeneric_GetName((SlangReflectionGeneric*)this); }
3107
3108    unsigned int getTypeParameterCount()
3109    {
3110        return spReflectionGeneric_GetTypeParameterCount((SlangReflectionGeneric*)this);
3111    }
3112
3113    VariableReflection* getTypeParameter(unsigned index)
3114    {
3115        return (VariableReflection*)spReflectionGeneric_GetTypeParameter(
3116            (SlangReflectionGeneric*)this,
3117            index);
3118    }
3119
3120    unsigned int getValueParameterCount()
3121    {
3122        return spReflectionGeneric_GetValueParameterCount((SlangReflectionGeneric*)this);
3123    }
3124
3125    VariableReflection* getValueParameter(unsigned index)
3126    {
3127        return (VariableReflection*)spReflectionGeneric_GetValueParameter(
3128            (SlangReflectionGeneric*)this,
3129            index);
3130    }
3131
3132    unsigned int getTypeParameterConstraintCount(VariableReflection* typeParam)
3133    {
3134        return spReflectionGeneric_GetTypeParameterConstraintCount(
3135            (SlangReflectionGeneric*)this,
3136            (SlangReflectionVariable*)typeParam);
3137    }
3138
3139    TypeReflection* getTypeParameterConstraintType(VariableReflection* typeParam, unsigned index)
3140    {
3141        return (TypeReflection*)spReflectionGeneric_GetTypeParameterConstraintType(
3142            (SlangReflectionGeneric*)this,
3143            (SlangReflectionVariable*)typeParam,
3144            index);
3145    }
3146
3147    DeclReflection* getInnerDecl()
3148    {
3149        return (DeclReflection*)spReflectionGeneric_GetInnerDecl((SlangReflectionGeneric*)this);
3150    }
3151
3152    SlangDeclKind getInnerKind()
3153    {
3154        return spReflectionGeneric_GetInnerKind((SlangReflectionGeneric*)this);
3155    }
3156
3157    GenericReflection* getOuterGenericContainer()
3158    {
3159        return (GenericReflection*)spReflectionGeneric_GetOuterGenericContainer(
3160            (SlangReflectionGeneric*)this);
3161    }
3162
3163    TypeReflection* getConcreteType(VariableReflection* typeParam)
3164    {
3165        return (TypeReflection*)spReflectionGeneric_GetConcreteType(
3166            (SlangReflectionGeneric*)this,
3167            (SlangReflectionVariable*)typeParam);
3168    }
3169
3170    int64_t getConcreteIntVal(VariableReflection* valueParam)
3171    {
3172        return spReflectionGeneric_GetConcreteIntVal(
3173            (SlangReflectionGeneric*)this,
3174            (SlangReflectionVariable*)valueParam);
3175    }
3176
3177    GenericReflection* applySpecializations(GenericReflection* generic)
3178    {
3179        return (GenericReflection*)spReflectionGeneric_applySpecializations(
3180            (SlangReflectionGeneric*)this,
3181            (SlangReflectionGeneric*)generic);
3182    }
3183};
3184
3185struct EntryPointReflection
3186{
3187    char const* getName()
3188    {
3189        return spReflectionEntryPoint_getName((SlangReflectionEntryPoint*)this);
3190    }
3191
3192    char const* getNameOverride()
3193    {
3194        return spReflectionEntryPoint_getNameOverride((SlangReflectionEntryPoint*)this);
3195    }
3196
3197    unsigned getParameterCount()
3198    {
3199        return spReflectionEntryPoint_getParameterCount((SlangReflectionEntryPoint*)this);
3200    }
3201
3202    FunctionReflection* getFunction()
3203    {
3204        return (FunctionReflection*)spReflectionEntryPoint_getFunction(
3205            (SlangReflectionEntryPoint*)this);
3206    }
3207
3208    VariableLayoutReflection* getParameterByIndex(unsigned index)
3209    {
3210        return (VariableLayoutReflection*)spReflectionEntryPoint_getParameterByIndex(
3211            (SlangReflectionEntryPoint*)this,
3212            index);
3213    }
3214
3215    SlangStage getStage()
3216    {
3217        return spReflectionEntryPoint_getStage((SlangReflectionEntryPoint*)this);
3218    }
3219
3220    void getComputeThreadGroupSize(SlangUInt axisCount, SlangUInt* outSizeAlongAxis)
3221    {
3222        return spReflectionEntryPoint_getComputeThreadGroupSize(
3223            (SlangReflectionEntryPoint*)this,
3224            axisCount,
3225            outSizeAlongAxis);
3226    }
3227
3228    void getComputeWaveSize(SlangUInt* outWaveSize)
3229    {
3230        return spReflectionEntryPoint_getComputeWaveSize(
3231            (SlangReflectionEntryPoint*)this,
3232            outWaveSize);
3233    }
3234
3235    bool usesAnySampleRateInput()
3236    {
3237        return 0 != spReflectionEntryPoint_usesAnySampleRateInput((SlangReflectionEntryPoint*)this);
3238    }
3239
3240    VariableLayoutReflection* getVarLayout()
3241    {
3242        return (VariableLayoutReflection*)spReflectionEntryPoint_getVarLayout(
3243            (SlangReflectionEntryPoint*)this);
3244    }
3245
3246    TypeLayoutReflection* getTypeLayout() { return getVarLayout()->getTypeLayout(); }
3247
3248    VariableLayoutReflection* getResultVarLayout()
3249    {
3250        return (VariableLayoutReflection*)spReflectionEntryPoint_getResultVarLayout(
3251            (SlangReflectionEntryPoint*)this);
3252    }
3253
3254    bool hasDefaultConstantBuffer()
3255    {
3256        return spReflectionEntryPoint_hasDefaultConstantBuffer((SlangReflectionEntryPoint*)this) !=
3257               0;
3258    }
3259};
3260
3261typedef EntryPointReflection EntryPointLayout;
3262
3263struct TypeParameterReflection
3264{
3265    char const* getName()
3266    {
3267        return spReflectionTypeParameter_GetName((SlangReflectionTypeParameter*)this);
3268    }
3269    unsigned getIndex()
3270    {
3271        return spReflectionTypeParameter_GetIndex((SlangReflectionTypeParameter*)this);
3272    }
3273    unsigned getConstraintCount()
3274    {
3275        return spReflectionTypeParameter_GetConstraintCount((SlangReflectionTypeParameter*)this);
3276    }
3277    TypeReflection* getConstraintByIndex(int index)
3278    {
3279        return (TypeReflection*)spReflectionTypeParameter_GetConstraintByIndex(
3280            (SlangReflectionTypeParameter*)this,
3281            index);
3282    }
3283};
3284
3285enum class LayoutRules : SlangLayoutRulesIntegral
3286{
3287    Default = SLANG_LAYOUT_RULES_DEFAULT,
3288    MetalArgumentBufferTier2 = SLANG_LAYOUT_RULES_METAL_ARGUMENT_BUFFER_TIER_2,
3289};
3290
3291typedef struct ShaderReflection ProgramLayout;
3292typedef enum SlangReflectionGenericArgType GenericArgType;
3293
3294struct ShaderReflection
3295{
3296    unsigned getParameterCount() { return spReflection_GetParameterCount((SlangReflection*)this); }
3297
3298    unsigned getTypeParameterCount()
3299    {
3300        return spReflection_GetTypeParameterCount((SlangReflection*)this);
3301    }
3302
3303    slang::ISession* getSession() { return spReflection_GetSession((SlangReflection*)this); }
3304
3305    TypeParameterReflection* getTypeParameterByIndex(unsigned index)
3306    {
3307        return (TypeParameterReflection*)spReflection_GetTypeParameterByIndex(
3308            (SlangReflection*)this,
3309            index);
3310    }
3311
3312    TypeParameterReflection* findTypeParameter(char const* name)
3313    {
3314        return (
3315            TypeParameterReflection*)spReflection_FindTypeParameter((SlangReflection*)this, name);
3316    }
3317
3318    VariableLayoutReflection* getParameterByIndex(unsigned index)
3319    {
3320        return (VariableLayoutReflection*)spReflection_GetParameterByIndex(
3321            (SlangReflection*)this,
3322            index);
3323    }
3324
3325    static ProgramLayout* get(SlangCompileRequest* request)
3326    {
3327        return (ProgramLayout*)spGetReflection(request);
3328    }
3329
3330    SlangUInt getEntryPointCount()
3331    {
3332        return spReflection_getEntryPointCount((SlangReflection*)this);
3333    }
3334
3335    EntryPointReflection* getEntryPointByIndex(SlangUInt index)
3336    {
3337        return (
3338            EntryPointReflection*)spReflection_getEntryPointByIndex((SlangReflection*)this, index);
3339    }
3340
3341    SlangUInt getGlobalConstantBufferBinding()
3342    {
3343        return spReflection_getGlobalConstantBufferBinding((SlangReflection*)this);
3344    }
3345
3346    size_t getGlobalConstantBufferSize()
3347    {
3348        return spReflection_getGlobalConstantBufferSize((SlangReflection*)this);
3349    }
3350
3351    TypeReflection* findTypeByName(const char* name)
3352    {
3353        return (TypeReflection*)spReflection_FindTypeByName((SlangReflection*)this, name);
3354    }
3355
3356    FunctionReflection* findFunctionByName(const char* name)
3357    {
3358        return (FunctionReflection*)spReflection_FindFunctionByName((SlangReflection*)this, name);
3359    }
3360
3361    FunctionReflection* findFunctionByNameInType(TypeReflection* type, const char* name)
3362    {
3363        return (FunctionReflection*)spReflection_FindFunctionByNameInType(
3364            (SlangReflection*)this,
3365            (SlangReflectionType*)type,
3366            name);
3367    }
3368
3369    SLANG_DEPRECATED FunctionReflection* tryResolveOverloadedFunction(
3370        uint32_t candidateCount,
3371        FunctionReflection** candidates)
3372    {
3373        return (FunctionReflection*)spReflection_TryResolveOverloadedFunction(
3374            (SlangReflection*)this,
3375            candidateCount,
3376            (SlangReflectionFunction**)candidates);
3377    }
3378
3379    VariableReflection* findVarByNameInType(TypeReflection* type, const char* name)
3380    {
3381        return (VariableReflection*)spReflection_FindVarByNameInType(
3382            (SlangReflection*)this,
3383            (SlangReflectionType*)type,
3384            name);
3385    }
3386
3387    TypeLayoutReflection* getTypeLayout(
3388        TypeReflection* type,
3389        LayoutRules rules = LayoutRules::Default)
3390    {
3391        return (TypeLayoutReflection*)spReflection_GetTypeLayout(
3392            (SlangReflection*)this,
3393            (SlangReflectionType*)type,
3394            SlangLayoutRules(rules));
3395    }
3396
3397    EntryPointReflection* findEntryPointByName(const char* name)
3398    {
3399        return (
3400            EntryPointReflection*)spReflection_findEntryPointByName((SlangReflection*)this, name);
3401    }
3402
3403    TypeReflection* specializeType(
3404        TypeReflection* type,
3405        SlangInt specializationArgCount,
3406        TypeReflection* const* specializationArgs,
3407        ISlangBlob** outDiagnostics)
3408    {
3409        return (TypeReflection*)spReflection_specializeType(
3410            (SlangReflection*)this,
3411            (SlangReflectionType*)type,
3412            specializationArgCount,
3413            (SlangReflectionType* const*)specializationArgs,
3414            outDiagnostics);
3415    }
3416
3417    GenericReflection* specializeGeneric(
3418        GenericReflection* generic,
3419        SlangInt specializationArgCount,
3420        GenericArgType const* specializationArgTypes,
3421        GenericArgReflection const* specializationArgVals,
3422        ISlangBlob** outDiagnostics)
3423    {
3424        return (GenericReflection*)spReflection_specializeGeneric(
3425            (SlangReflection*)this,
3426            (SlangReflectionGeneric*)generic,
3427            specializationArgCount,
3428            (SlangReflectionGenericArgType const*)specializationArgTypes,
3429            (SlangReflectionGenericArg const*)specializationArgVals,
3430            outDiagnostics);
3431    }
3432
3433    bool isSubType(TypeReflection* subType, TypeReflection* superType)
3434    {
3435        return spReflection_isSubType(
3436            (SlangReflection*)this,
3437            (SlangReflectionType*)subType,
3438            (SlangReflectionType*)superType);
3439    }
3440
3441    SlangUInt getHashedStringCount() const
3442    {
3443        return spReflection_getHashedStringCount((SlangReflection*)this);
3444    }
3445
3446    const char* getHashedString(SlangUInt index, size_t* outCount) const
3447    {
3448        return spReflection_getHashedString((SlangReflection*)this, index, outCount);
3449    }
3450
3451    TypeLayoutReflection* getGlobalParamsTypeLayout()
3452    {
3453        return (TypeLayoutReflection*)spReflection_getGlobalParamsTypeLayout(
3454            (SlangReflection*)this);
3455    }
3456
3457    VariableLayoutReflection* getGlobalParamsVarLayout()
3458    {
3459        return (VariableLayoutReflection*)spReflection_getGlobalParamsVarLayout(
3460            (SlangReflection*)this);
3461    }
3462
3463    SlangResult toJson(ISlangBlob** outBlob)
3464    {
3465        return spReflection_ToJson((SlangReflection*)this, nullptr, outBlob);
3466    }
3467};
3468
3469
3470struct DeclReflection
3471{
3472    enum class Kind
3473    {
3474        Unsupported = SLANG_DECL_KIND_UNSUPPORTED_FOR_REFLECTION,
3475        Struct = SLANG_DECL_KIND_STRUCT,
3476        Func = SLANG_DECL_KIND_FUNC,
3477        Module = SLANG_DECL_KIND_MODULE,
3478        Generic = SLANG_DECL_KIND_GENERIC,
3479        Variable = SLANG_DECL_KIND_VARIABLE,
3480        Namespace = SLANG_DECL_KIND_NAMESPACE,
3481    };
3482
3483    char const* getName() { return spReflectionDecl_getName((SlangReflectionDecl*)this); }
3484
3485    Kind getKind() { return (Kind)spReflectionDecl_getKind((SlangReflectionDecl*)this); }
3486
3487    unsigned int getChildrenCount()
3488    {
3489        return spReflectionDecl_getChildrenCount((SlangReflectionDecl*)this);
3490    }
3491
3492    DeclReflection* getChild(unsigned int index)
3493    {
3494        return (DeclReflection*)spReflectionDecl_getChild((SlangReflectionDecl*)this, index);
3495    }
3496
3497    TypeReflection* getType()
3498    {
3499        return (TypeReflection*)spReflection_getTypeFromDecl((SlangReflectionDecl*)this);
3500    }
3501
3502    VariableReflection* asVariable()
3503    {
3504        return (VariableReflection*)spReflectionDecl_castToVariable((SlangReflectionDecl*)this);
3505    }
3506
3507    FunctionReflection* asFunction()
3508    {
3509        return (FunctionReflection*)spReflectionDecl_castToFunction((SlangReflectionDecl*)this);
3510    }
3511
3512    GenericReflection* asGeneric()
3513    {
3514        return (GenericReflection*)spReflectionDecl_castToGeneric((SlangReflectionDecl*)this);
3515    }
3516
3517    DeclReflection* getParent()
3518    {
3519        return (DeclReflection*)spReflectionDecl_getParent((SlangReflectionDecl*)this);
3520    }
3521
3522    Modifier* findModifier(Modifier::ID id)
3523    {
3524        return (Modifier*)spReflectionDecl_findModifier(
3525            (SlangReflectionDecl*)this,
3526            (SlangModifierID)id);
3527    }
3528
3529    template<Kind K>
3530    struct FilteredList
3531    {
3532        unsigned int count;
3533        DeclReflection* parent;
3534
3535        struct FilteredIterator
3536        {
3537            DeclReflection* parent;
3538            unsigned int count;
3539            unsigned int index;
3540
3541            DeclReflection* operator*() { return parent->getChild(index); }
3542            void operator++()
3543            {
3544                index++;
3545                while (index < count && !(parent->getChild(index)->getKind() == K))
3546                {
3547                    index++;
3548                }
3549            }
3550            bool operator!=(FilteredIterator const& other) { return index != other.index; }
3551        };
3552
3553        // begin/end for range-based for that checks the kind
3554        FilteredIterator begin()
3555        {
3556            // Find the first child of the right kind
3557            unsigned int index = 0;
3558            while (index < count && !(parent->getChild(index)->getKind() == K))
3559            {
3560                index++;
3561            }
3562            return FilteredIterator{parent, count, index};
3563        }
3564
3565        FilteredIterator end() { return FilteredIterator{parent, count, count}; }
3566    };
3567
3568    template<Kind K>
3569    FilteredList<K> getChildrenOfKind()
3570    {
3571        return FilteredList<K>{getChildrenCount(), (DeclReflection*)this};
3572    }
3573
3574    struct IteratedList
3575    {
3576        unsigned int count;
3577        DeclReflection* parent;
3578
3579        struct Iterator
3580        {
3581            DeclReflection* parent;
3582            unsigned int count;
3583            unsigned int index;
3584
3585            DeclReflection* operator*() { return parent->getChild(index); }
3586            void operator++() { index++; }
3587            bool operator!=(Iterator const& other) { return index != other.index; }
3588        };
3589
3590        // begin/end for range-based for that checks the kind
3591        IteratedList::Iterator begin() { return IteratedList::Iterator{parent, count, 0}; }
3592        IteratedList::Iterator end() { return IteratedList::Iterator{parent, count, count}; }
3593    };
3594
3595    IteratedList getChildren() { return IteratedList{getChildrenCount(), (DeclReflection*)this}; }
3596};
3597
3598typedef uint32_t CompileCoreModuleFlags;
3599struct CompileCoreModuleFlag
3600{
3601    enum Enum : CompileCoreModuleFlags
3602    {
3603        WriteDocumentation = 0x1,
3604    };
3605};
3606
3607typedef ISlangBlob IBlob;
3608
3609struct IComponentType;
3610struct ITypeConformance;
3611struct IGlobalSession;
3612struct IModule;
3613
3614struct SessionDesc;
3615struct SpecializationArg;
3616struct TargetDesc;
3617
3618enum class BuiltinModuleName
3619{
3620    Core,
3621    GLSL
3622};
3623
3624/** A global session for interaction with the Slang library.
3625
3626An application may create and re-use a single global session across
3627multiple sessions, in order to amortize startups costs (in current
3628Slang this is mostly the cost of loading the Slang standard library).
3629
3630The global session is currently *not* thread-safe and objects created from
3631a single global session should only be used from a single thread at
3632a time.
3633*/
3634struct IGlobalSession : public ISlangUnknown
3635{
3636    SLANG_COM_INTERFACE(0xc140b5fd, 0xc78, 0x452e, {0xba, 0x7c, 0x1a, 0x1e, 0x70, 0xc7, 0xf7, 0x1c})
3637
3638    /** Create a new session for loading and compiling code.
3639     */
3640    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
3641    createSession(SessionDesc const& desc, ISession** outSession) = 0;
3642
3643    /** Look up the internal ID of a profile by its `name`.
3644
3645    Profile IDs are *not* guaranteed to be stable across versions
3646    of the Slang library, so clients are expected to look up
3647    profiles by name at runtime.
3648    */
3649    virtual SLANG_NO_THROW SlangProfileID SLANG_MCALL findProfile(char const* name) = 0;
3650
3651    /** Set the path that downstream compilers (aka back end compilers) will
3652    be looked from.
3653    @param passThrough Identifies the downstream compiler
3654    @param path The path to find the downstream compiler (shared library/dll/executable)
3655
3656    For back ends that are dlls/shared libraries, it will mean the path will
3657    be prefixed with the path when calls are made out to ISlangSharedLibraryLoader.
3658    For executables - it will look for executables along the path */
3659    virtual SLANG_NO_THROW void SLANG_MCALL
3660    setDownstreamCompilerPath(SlangPassThrough passThrough, char const* path) = 0;
3661
3662    /** DEPRECATED: Use setLanguagePrelude
3663
3664    Set the 'prelude' for generated code for a 'downstream compiler'.
3665    @param passThrough The downstream compiler for generated code that will have the prelude applied
3666    to it.
3667    @param preludeText The text added pre-pended verbatim before the generated source
3668
3669    That for pass-through usage, prelude is not pre-pended, preludes are for code generation only.
3670    */
3671    virtual SLANG_NO_THROW void SLANG_MCALL
3672    setDownstreamCompilerPrelude(SlangPassThrough passThrough, const char* preludeText) = 0;
3673
3674    /** DEPRECATED: Use getLanguagePrelude
3675
3676    Get the 'prelude' for generated code for a 'downstream compiler'.
3677    @param passThrough The downstream compiler for generated code that will have the prelude applied
3678    to it.
3679    @param outPrelude  On exit holds a blob that holds the string of the prelude.
3680    */
3681    virtual SLANG_NO_THROW void SLANG_MCALL
3682    getDownstreamCompilerPrelude(SlangPassThrough passThrough, ISlangBlob** outPrelude) = 0;
3683
3684    /** Get the build version 'tag' string. The string is the same as produced via `git describe
3685    --tags` for the project. If Slang is built separately from the automated build scripts the
3686    contents will by default be 'unknown'. Any string can be set by changing the contents of
3687    'slang-tag-version.h' file and recompiling the project.
3688
3689    This method will return exactly the same result as the free function spGetBuildTagString.
3690
3691    @return The build tag string
3692    */
3693    virtual SLANG_NO_THROW const char* SLANG_MCALL getBuildTagString() = 0;
3694
3695    /* For a given source language set the default compiler.
3696    If a default cannot be chosen (for example the target cannot be achieved by the default),
3697    the default will not be used.
3698
3699    @param sourceLanguage the source language
3700    @param defaultCompiler the default compiler for that language
3701    @return
3702    */
3703    virtual SLANG_NO_THROW SlangResult SLANG_MCALL setDefaultDownstreamCompiler(
3704        SlangSourceLanguage sourceLanguage,
3705        SlangPassThrough defaultCompiler) = 0;
3706
3707    /* For a source type get the default compiler
3708
3709    @param sourceLanguage the source language
3710    @return The downstream compiler for that source language */
3711    virtual SlangPassThrough SLANG_MCALL
3712    getDefaultDownstreamCompiler(SlangSourceLanguage sourceLanguage) = 0;
3713
3714    /* Set the 'prelude' placed before generated code for a specific language type.
3715
3716    @param sourceLanguage The language the prelude should be inserted on.
3717    @param preludeText The text added pre-pended verbatim before the generated source
3718
3719    Note! That for pass-through usage, prelude is not pre-pended, preludes are for code generation
3720    only.
3721    */
3722    virtual SLANG_NO_THROW void SLANG_MCALL
3723    setLanguagePrelude(SlangSourceLanguage sourceLanguage, const char* preludeText) = 0;
3724
3725    /** Get the 'prelude' associated with a specific source language.
3726    @param sourceLanguage The language the prelude should be inserted on.
3727    @param outPrelude  On exit holds a blob that holds the string of the prelude.
3728    */
3729    virtual SLANG_NO_THROW void SLANG_MCALL
3730    getLanguagePrelude(SlangSourceLanguage sourceLanguage, ISlangBlob** outPrelude) = 0;
3731
3732    /** Create a compile request.
3733     */
3734    [[deprecated]] virtual SLANG_NO_THROW SlangResult SLANG_MCALL
3735    createCompileRequest(slang::ICompileRequest** outCompileRequest) = 0;
3736
3737    /** Add new builtin declarations to be used in subsequent compiles.
3738     */
3739    virtual SLANG_NO_THROW void SLANG_MCALL
3740    addBuiltins(char const* sourcePath, char const* sourceString) = 0;
3741
3742    /** Set the session shared library loader. If this changes the loader, it may cause shared
3743    libraries to be unloaded
3744    @param loader The loader to set. Setting nullptr sets the default loader.
3745    */
3746    virtual SLANG_NO_THROW void SLANG_MCALL
3747    setSharedLibraryLoader(ISlangSharedLibraryLoader* loader) = 0;
3748
3749    /** Gets the currently set shared library loader
3750    @return Gets the currently set loader. If returns nullptr, it's the default loader
3751    */
3752    virtual SLANG_NO_THROW ISlangSharedLibraryLoader* SLANG_MCALL getSharedLibraryLoader() = 0;
3753
3754    /** Returns SLANG_OK if the compilation target is supported for this session
3755
3756    @param target The compilation target to test
3757    @return SLANG_OK if the target is available
3758    SLANG_E_NOT_IMPLEMENTED if not implemented in this build
3759    SLANG_E_NOT_FOUND if other resources (such as shared libraries) required to make target work
3760    could not be found SLANG_FAIL other kinds of failures */
3761    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
3762    checkCompileTargetSupport(SlangCompileTarget target) = 0;
3763
3764    /** Returns SLANG_OK if the pass through support is supported for this session
3765    @param session Session
3766    @param target The compilation target to test
3767    @return SLANG_OK if the target is available
3768    SLANG_E_NOT_IMPLEMENTED if not implemented in this build
3769    SLANG_E_NOT_FOUND if other resources (such as shared libraries) required to make target work
3770    could not be found SLANG_FAIL other kinds of failures */
3771    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
3772    checkPassThroughSupport(SlangPassThrough passThrough) = 0;
3773
3774    /** Compile from (embedded source) the core module on the session.
3775    Will return a failure if there is already a core module available
3776    NOTE! API is experimental and not ready for production code
3777    @param flags to control compilation
3778    */
3779    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
3780    compileCoreModule(CompileCoreModuleFlags flags) = 0;
3781
3782    /** Load the core module. Currently loads modules from the file system.
3783    @param coreModule Start address of the serialized core module
3784    @param coreModuleSizeInBytes The size in bytes of the serialized core module
3785
3786    NOTE! API is experimental and not ready for production code
3787    */
3788    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
3789    loadCoreModule(const void* coreModule, size_t coreModuleSizeInBytes) = 0;
3790
3791    /** Save the core module to the file system
3792    @param archiveType The type of archive used to hold the core module
3793    @param outBlob The serialized blob containing the core module
3794
3795    NOTE! API is experimental and not ready for production code  */
3796    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
3797    saveCoreModule(SlangArchiveType archiveType, ISlangBlob** outBlob) = 0;
3798
3799    /** Look up the internal ID of a capability by its `name`.
3800
3801    Capability IDs are *not* guaranteed to be stable across versions
3802    of the Slang library, so clients are expected to look up
3803    capabilities by name at runtime.
3804    */
3805    virtual SLANG_NO_THROW SlangCapabilityID SLANG_MCALL findCapability(char const* name) = 0;
3806
3807    /** Set the downstream/pass through compiler to be used for a transition from the source type to
3808    the target type
3809    @param source The source 'code gen target'
3810    @param target The target 'code gen target'
3811    @param compiler The compiler/pass through to use for the transition from source to target
3812    */
3813    virtual SLANG_NO_THROW void SLANG_MCALL setDownstreamCompilerForTransition(
3814        SlangCompileTarget source,
3815        SlangCompileTarget target,
3816        SlangPassThrough compiler) = 0;
3817
3818    /** Get the downstream/pass through compiler for a transition specified by source and target
3819    @param source The source 'code gen target'
3820    @param target The target 'code gen target'
3821    @return The compiler that is used for the transition. Returns SLANG_PASS_THROUGH_NONE it is not
3822    defined
3823    */
3824    virtual SLANG_NO_THROW SlangPassThrough SLANG_MCALL
3825    getDownstreamCompilerForTransition(SlangCompileTarget source, SlangCompileTarget target) = 0;
3826
3827    /** Get the time in seconds spent in the slang and downstream compiler.
3828     */
3829    virtual SLANG_NO_THROW void SLANG_MCALL
3830    getCompilerElapsedTime(double* outTotalTime, double* outDownstreamTime) = 0;
3831
3832    /** Specify a spirv.core.grammar.json file to load and use when
3833     * parsing and checking any SPIR-V code
3834     */
3835    virtual SLANG_NO_THROW SlangResult SLANG_MCALL setSPIRVCoreGrammar(char const* jsonPath) = 0;
3836
3837    /** Parse slangc command line options into a SessionDesc that can be used to create a session
3838     *   with all the compiler options specified in the command line.
3839     *   @param argc The number of command line arguments.
3840     *   @param argv An input array of command line arguments to parse.
3841     *   @param outSessionDesc A pointer to a SessionDesc struct to receive parsed session desc.
3842     *   @param outAuxAllocation Auxiliary memory allocated to hold data used in the session desc.
3843     */
3844    virtual SLANG_NO_THROW SlangResult SLANG_MCALL parseCommandLineArguments(
3845        int argc,
3846        const char* const* argv,
3847        SessionDesc* outSessionDesc,
3848        ISlangUnknown** outAuxAllocation) = 0;
3849
3850    /** Computes a digest that uniquely identifies the session description.
3851     */
3852    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
3853    getSessionDescDigest(SessionDesc* sessionDesc, ISlangBlob** outBlob) = 0;
3854
3855    /** Compile from (embedded source) the builtin module on the session.
3856    Will return a failure if there is already a builtin module available.
3857    NOTE! API is experimental and not ready for production code.
3858    @param module The builtin module name.
3859    @param flags to control compilation
3860    */
3861    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
3862    compileBuiltinModule(BuiltinModuleName module, CompileCoreModuleFlags flags) = 0;
3863
3864    /** Load a builtin module. Currently loads modules from the file system.
3865    @param module The builtin module name
3866    @param moduleData Start address of the serialized core module
3867    @param sizeInBytes The size in bytes of the serialized builtin module
3868
3869    NOTE! API is experimental and not ready for production code
3870    */
3871    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
3872    loadBuiltinModule(BuiltinModuleName module, const void* moduleData, size_t sizeInBytes) = 0;
3873
3874    /** Save the builtin module to the file system
3875    @param module The builtin module name
3876    @param archiveType The type of archive used to hold the builtin module
3877    @param outBlob The serialized blob containing the builtin module
3878
3879    NOTE! API is experimental and not ready for production code  */
3880    virtual SLANG_NO_THROW SlangResult SLANG_MCALL saveBuiltinModule(
3881        BuiltinModuleName module,
3882        SlangArchiveType archiveType,
3883        ISlangBlob** outBlob) = 0;
3884};
3885
3886    #define SLANG_UUID_IGlobalSession IGlobalSession::getTypeGuid()
3887
3888/** Description of a code generation target.
3889 */
3890struct TargetDesc
3891{
3892    /** The size of this structure, in bytes.
3893     */
3894    size_t structureSize = sizeof(TargetDesc);
3895
3896    /** The target format to generate code for (e.g., SPIR-V, DXIL, etc.)
3897     */
3898    SlangCompileTarget format = SLANG_TARGET_UNKNOWN;
3899
3900    /** The compilation profile supported by the target (e.g., "Shader Model 5.1")
3901     */
3902    SlangProfileID profile = SLANG_PROFILE_UNKNOWN;
3903
3904    /** Flags for the code generation target. Currently unused. */
3905    SlangTargetFlags flags = kDefaultTargetFlags;
3906
3907    /** Default mode to use for floating-point operations on the target.
3908     */
3909    SlangFloatingPointMode floatingPointMode = SLANG_FLOATING_POINT_MODE_DEFAULT;
3910
3911    /** The line directive mode for output source code.
3912     */
3913    SlangLineDirectiveMode lineDirectiveMode = SLANG_LINE_DIRECTIVE_MODE_DEFAULT;
3914
3915    /** Whether to force `scalar` layout for glsl shader storage buffers.
3916     */
3917    bool forceGLSLScalarBufferLayout = false;
3918
3919    /** Pointer to an array of compiler option entries, whose size is compilerOptionEntryCount.
3920     */
3921    CompilerOptionEntry* compilerOptionEntries = nullptr;
3922
3923    /** Number of additional compiler option entries.
3924     */
3925    uint32_t compilerOptionEntryCount = 0;
3926};
3927
3928typedef uint32_t SessionFlags;
3929enum
3930{
3931    kSessionFlags_None = 0
3932};
3933
3934struct PreprocessorMacroDesc
3935{
3936    const char* name;
3937    const char* value;
3938};
3939
3940struct SessionDesc
3941{
3942    /** The size of this structure, in bytes.
3943     */
3944    size_t structureSize = sizeof(SessionDesc);
3945
3946    /** Code generation targets to include in the session.
3947     */
3948    TargetDesc const* targets = nullptr;
3949    SlangInt targetCount = 0;
3950
3951    /** Flags to configure the session.
3952     */
3953    SessionFlags flags = kSessionFlags_None;
3954
3955    /** Default layout to assume for variables with matrix types.
3956     */
3957    SlangMatrixLayoutMode defaultMatrixLayoutMode = SLANG_MATRIX_LAYOUT_ROW_MAJOR;
3958
3959    /** Paths to use when searching for `#include`d or `import`ed files.
3960     */
3961    char const* const* searchPaths = nullptr;
3962    SlangInt searchPathCount = 0;
3963
3964    PreprocessorMacroDesc const* preprocessorMacros = nullptr;
3965    SlangInt preprocessorMacroCount = 0;
3966
3967    ISlangFileSystem* fileSystem = nullptr;
3968
3969    bool enableEffectAnnotations = false;
3970    bool allowGLSLSyntax = false;
3971
3972    /** Pointer to an array of compiler option entries, whose size is compilerOptionEntryCount.
3973     */
3974    CompilerOptionEntry* compilerOptionEntries = nullptr;
3975
3976    /** Number of additional compiler option entries.
3977     */
3978    uint32_t compilerOptionEntryCount = 0;
3979
3980    /** Whether to skip SPIRV validation.
3981     */
3982    bool skipSPIRVValidation = false;
3983};
3984
3985enum class ContainerType
3986{
3987    None,
3988    UnsizedArray,
3989    StructuredBuffer,
3990    ConstantBuffer,
3991    ParameterBlock
3992};
3993
3994/** A session provides a scope for code that is loaded.
3995
3996A session can be used to load modules of Slang source code,
3997and to request target-specific compiled binaries and layout
3998information.
3999
4000In order to be able to load code, the session owns a set
4001of active "search paths" for resolving `#include` directives
4002and `import` declarations, as well as a set of global
4003preprocessor definitions that will be used for all code
4004that gets `import`ed in the session.
4005
4006If multiple user shaders are loaded in the same session,
4007and import the same module (e.g., two source files do `import X`)
4008then there will only be one copy of `X` loaded within the session.
4009
4010In order to be able to generate target code, the session
4011owns a list of available compilation targets, which specify
4012code generation options.
4013
4014Code loaded and compiled within a session is owned by the session
4015and will remain resident in memory until the session is released.
4016Applications wishing to control the memory usage for compiled
4017and loaded code should use multiple sessions.
4018*/
4019struct ISession : public ISlangUnknown
4020{
4021    SLANG_COM_INTERFACE(0x67618701, 0xd116, 0x468f, {0xab, 0x3b, 0x47, 0x4b, 0xed, 0xce, 0xe, 0x3d})
4022
4023    /** Get the global session thas was used to create this session.
4024     */
4025    virtual SLANG_NO_THROW IGlobalSession* SLANG_MCALL getGlobalSession() = 0;
4026
4027    /** Load a module as it would be by code using `import`.
4028     */
4029    virtual SLANG_NO_THROW IModule* SLANG_MCALL
4030    loadModule(const char* moduleName, IBlob** outDiagnostics = nullptr) = 0;
4031
4032    /** Load a module from Slang source code.
4033     */
4034    virtual SLANG_NO_THROW IModule* SLANG_MCALL loadModuleFromSource(
4035        const char* moduleName,
4036        const char* path,
4037        slang::IBlob* source,
4038        slang::IBlob** outDiagnostics = nullptr) = 0;
4039
4040    /** Combine multiple component types to create a composite component type.
4041
4042    The `componentTypes` array must contain `componentTypeCount` pointers
4043    to component types that were loaded or created using the same session.
4044
4045    The shader parameters and specialization parameters of the composite will
4046    be the union of those in `componentTypes`. The relative order of child
4047    component types is significant, and will affect the order in which
4048    parameters are reflected and laid out.
4049
4050    The entry-point functions of the composite will be the union of those in
4051    `componentTypes`, and will follow the ordering of `componentTypes`.
4052
4053    The requirements of the composite component type will be a subset of
4054    those in `componentTypes`. If an entry in `componentTypes` has a requirement
4055    that can be satisfied by another entry, then the composition will
4056    satisfy the requirement and it will not appear as a requirement of
4057    the composite. If multiple entries in `componentTypes` have a requirement
4058    for the same type, then only the first such requirement will be retained
4059    on the composite. The relative ordering of requirements on the composite
4060    will otherwise match that of `componentTypes`.
4061
4062    If any diagnostics are generated during creation of the composite, they
4063    will be written to `outDiagnostics`. If an error is encountered, the
4064    function will return null.
4065
4066    It is an error to create a composite component type that recursively
4067    aggregates a single module more than once.
4068    */
4069    virtual SLANG_NO_THROW SlangResult SLANG_MCALL createCompositeComponentType(
4070        IComponentType* const* componentTypes,
4071        SlangInt componentTypeCount,
4072        IComponentType** outCompositeComponentType,
4073        ISlangBlob** outDiagnostics = nullptr) = 0;
4074
4075    /** Specialize a type based on type arguments.
4076     */
4077    virtual SLANG_NO_THROW TypeReflection* SLANG_MCALL specializeType(
4078        TypeReflection* type,
4079        SpecializationArg const* specializationArgs,
4080        SlangInt specializationArgCount,
4081        ISlangBlob** outDiagnostics = nullptr) = 0;
4082
4083
4084    /** Get the layout `type` on the chosen `target`.
4085     */
4086    virtual SLANG_NO_THROW TypeLayoutReflection* SLANG_MCALL getTypeLayout(
4087        TypeReflection* type,
4088        SlangInt targetIndex = 0,
4089        LayoutRules rules = LayoutRules::Default,
4090        ISlangBlob** outDiagnostics = nullptr) = 0;
4091
4092    /** Get a container type from `elementType`. For example, given type `T`, returns
4093        a type that represents `StructuredBuffer<T>`.
4094
4095        @param `elementType`: the element type to wrap around.
4096        @param `containerType`: the type of the container to wrap `elementType` in.
4097        @param `outDiagnostics`: a blob to receive diagnostic messages.
4098    */
4099    virtual SLANG_NO_THROW TypeReflection* SLANG_MCALL getContainerType(
4100        TypeReflection* elementType,
4101        ContainerType containerType,
4102        ISlangBlob** outDiagnostics = nullptr) = 0;
4103
4104    /** Return a `TypeReflection` that represents the `__Dynamic` type.
4105        This type can be used as a specialization argument to indicate using
4106        dynamic dispatch.
4107    */
4108    virtual SLANG_NO_THROW TypeReflection* SLANG_MCALL getDynamicType() = 0;
4109
4110    /** Get the mangled name for a type RTTI object.
4111     */
4112    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
4113    getTypeRTTIMangledName(TypeReflection* type, ISlangBlob** outNameBlob) = 0;
4114
4115    /** Get the mangled name for a type witness.
4116     */
4117    virtual SLANG_NO_THROW SlangResult SLANG_MCALL getTypeConformanceWitnessMangledName(
4118        TypeReflection* type,
4119        TypeReflection* interfaceType,
4120        ISlangBlob** outNameBlob) = 0;
4121
4122    /** Get the sequential ID used to identify a type witness in a dynamic object.
4123        The sequential ID is part of the RTTI bytes returned by `getDynamicObjectRTTIBytes`.
4124     */
4125    virtual SLANG_NO_THROW SlangResult SLANG_MCALL getTypeConformanceWitnessSequentialID(
4126        slang::TypeReflection* type,
4127        slang::TypeReflection* interfaceType,
4128        uint32_t* outId) = 0;
4129
4130    /** Create a request to load/compile front-end code.
4131     */
4132    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
4133    createCompileRequest(SlangCompileRequest** outCompileRequest) = 0;
4134
4135
4136    /** Creates a `IComponentType` that represents a type's conformance to an interface.
4137        The retrieved `ITypeConformance` objects can be included in a composite `IComponentType`
4138        to explicitly specify which implementation types should be included in the final compiled
4139        code. For example, if an module defines `IMaterial` interface and `AMaterial`,
4140        `BMaterial`, `CMaterial` types that implements the interface, the user can exclude
4141        `CMaterial` implementation from the resulting shader code by explicitly adding
4142        `AMaterial:IMaterial` and `BMaterial:IMaterial` conformances to a composite
4143        `IComponentType` and get entry point code from it. The resulting code will not have
4144        anything related to `CMaterial` in the dynamic dispatch logic. If the user does not
4145        explicitly include any `TypeConformances` to an interface type, all implementations to
4146        that interface will be included by default. By linking a `ITypeConformance`, the user is
4147        also given the opportunity to specify the dispatch ID of the implementation type. If
4148        `conformanceIdOverride` is -1, there will be no override behavior and Slang will
4149        automatically assign IDs to implementation types. The automatically assigned IDs can be
4150        queried via `ISession::getTypeConformanceWitnessSequentialID`.
4151
4152        Returns SLANG_OK if succeeds, or SLANG_FAIL if `type` does not conform to `interfaceType`.
4153    */
4154    virtual SLANG_NO_THROW SlangResult SLANG_MCALL createTypeConformanceComponentType(
4155        slang::TypeReflection* type,
4156        slang::TypeReflection* interfaceType,
4157        ITypeConformance** outConformance,
4158        SlangInt conformanceIdOverride,
4159        ISlangBlob** outDiagnostics) = 0;
4160
4161    /** Load a module from a Slang module blob.
4162     */
4163    virtual SLANG_NO_THROW IModule* SLANG_MCALL loadModuleFromIRBlob(
4164        const char* moduleName,
4165        const char* path,
4166        slang::IBlob* source,
4167        slang::IBlob** outDiagnostics = nullptr) = 0;
4168
4169    virtual SLANG_NO_THROW SlangInt SLANG_MCALL getLoadedModuleCount() = 0;
4170    virtual SLANG_NO_THROW IModule* SLANG_MCALL getLoadedModule(SlangInt index) = 0;
4171
4172    /** Checks if a precompiled binary module is up-to-date with the current compiler
4173     *   option settings and the source file contents.
4174     */
4175    virtual SLANG_NO_THROW bool SLANG_MCALL
4176    isBinaryModuleUpToDate(const char* modulePath, slang::IBlob* binaryModuleBlob) = 0;
4177
4178    /** Load a module from a string.
4179     */
4180    virtual SLANG_NO_THROW IModule* SLANG_MCALL loadModuleFromSourceString(
4181        const char* moduleName,
4182        const char* path,
4183        const char* string,
4184        slang::IBlob** outDiagnostics = nullptr) = 0;
4185
4186
4187    /** Get the 16-byte RTTI header to fill into a dynamic object.
4188        This header is used to identify the type of the object for dynamic dispatch purpose.
4189        For example, given the following shader:
4190
4191        ```slang
4192        [anyValueSize(32)] dyn interface IFoo { int eval(); }
4193        struct Impl : IFoo { int eval() { return 1; } }
4194
4195        ConstantBuffer<dyn IFoo> cb0;
4196
4197        [numthreads(1,1,1)
4198        void main()
4199        {
4200            cb0.eval();
4201        }
4202        ```
4203
4204        The constant buffer `cb0` should be filled with 16+32=48 bytes of data, where the first
4205        16 bytes should be the RTTI bytes returned by calling `getDynamicObjectRTTIBytes(type_Impl,
4206        type_IFoo)`, and the rest 32 bytes should hold the actual data of the dynamic object (in
4207        this case, fields in the `Impl` type).
4208
4209        `bufferSizeInBytes` must be greater than 16.
4210     */
4211    virtual SLANG_NO_THROW SlangResult SLANG_MCALL getDynamicObjectRTTIBytes(
4212        slang::TypeReflection* type,
4213        slang::TypeReflection* interfaceType,
4214        uint32_t* outRTTIDataBuffer,
4215        uint32_t bufferSizeInBytes) = 0;
4216
4217    /** Read module info (name and version) from a module blob
4218     *
4219     * The returned pointers are valid for as long as the session.
4220     */
4221    virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadModuleInfoFromIRBlob(
4222        slang::IBlob* source,
4223        SlangInt& outModuleVersion,
4224        const char*& outModuleCompilerVersion,
4225        const char*& outModuleName) = 0;
4226};
4227
4228    #define SLANG_UUID_ISession ISession::getTypeGuid()
4229
4230struct IMetadata : public ISlangCastable
4231{
4232    SLANG_COM_INTERFACE(0x8044a8a3, 0xddc0, 0x4b7f, {0xaf, 0x8e, 0x2, 0x6e, 0x90, 0x5d, 0x73, 0x32})
4233
4234    /*
4235    Returns whether a resource parameter at the specified binding location is actually being used
4236    in the compiled shader.
4237    */
4238    virtual SlangResult isParameterLocationUsed(
4239        SlangParameterCategory category, // is this a `t` register? `s` register?
4240        SlangUInt spaceIndex,            // `space` for D3D12, `set` for Vulkan
4241        SlangUInt registerIndex,         // `register` for D3D12, `binding` for Vulkan
4242        bool& outUsed) = 0;
4243
4244    /*
4245    Returns the debug build identifier for a base and debug spirv pair.
4246    */
4247    virtual const char* SLANG_MCALL getDebugBuildIdentifier() = 0;
4248};
4249    #define SLANG_UUID_IMetadata IMetadata::getTypeGuid()
4250
4251/** Compile result for storing and retrieving multiple output blobs.
4252    This is needed for features such as separate debug compilation which
4253    output both base and debug spirv.
4254 */
4255struct ICompileResult : public ISlangCastable
4256{
4257    SLANG_COM_INTERFACE(
4258        0x5fa9380e,
4259        0xb62f,
4260        0x41e5,
4261        {0x9f, 0x12, 0x4b, 0xad, 0x4d, 0x9e, 0xaa, 0xe4})
4262
4263    virtual uint32_t SLANG_MCALL getItemCount() = 0;
4264    virtual SlangResult SLANG_MCALL getItemData(uint32_t index, IBlob** outblob) = 0;
4265    virtual SlangResult SLANG_MCALL getMetadata(IMetadata** outMetadata) = 0;
4266};
4267    #define SLANG_UUID_ICompileResult ICompileResult::getTypeGuid()
4268
4269/** A component type is a unit of shader code layout, reflection, and linking.
4270
4271A component type is a unit of shader code that can be included into
4272a linked and compiled shader program. Each component type may have:
4273
4274* Zero or more uniform shader parameters, representing textures,
4275  buffers, etc. that the code in the component depends on.
4276
4277* Zero or more *specialization* parameters, which are type or
4278  value parameters that can be used to synthesize specialized
4279  versions of the component type.
4280
4281* Zero or more entry points, which are the individually invocable
4282  kernels that can have final code generated.
4283
4284* Zero or more *requirements*, which are other component
4285  types on which the component type depends.
4286
4287One example of a component type is a module of Slang code:
4288
4289* The global-scope shader parameters declared in the module are
4290  the parameters when considered as a component type.
4291
4292* Any global-scope generic or interface type parameters introduce
4293  specialization parameters for the module.
4294
4295* A module does not by default include any entry points when
4296  considered as a component type (although the code of the
4297  module might *declare* some entry points).
4298
4299* Any other modules that are `import`ed in the source code
4300  become requirements of the module, when considered as a
4301  component type.
4302
4303An entry point is another example of a component type:
4304
4305* The `uniform` parameters of the entry point function are
4306  its shader parameters when considered as a component type.
4307
4308* Any generic or interface-type parameters of the entry point
4309  introduce specialization parameters.
4310
4311* An entry point component type exposes a single entry point (itself).
4312
4313* An entry point has one requirement for the module in which
4314  it was defined.
4315
4316Component types can be manipulated in a few ways:
4317
4318* Multiple component types can be combined into a composite, which
4319  combines all of their code, parameters, etc.
4320
4321* A component type can be specialized, by "plugging in" types and
4322  values for its specialization parameters.
4323
4324* A component type can be laid out for a particular target, giving
4325  offsets/bindings to the shader parameters it contains.
4326
4327* Generated kernel code can be requested for entry points.
4328
4329*/
4330struct IComponentType : public ISlangUnknown
4331{
4332    SLANG_COM_INTERFACE(0x5bc42be8, 0x5c50, 0x4929, {0x9e, 0x5e, 0xd1, 0x5e, 0x7c, 0x24, 0x1, 0x5f})
4333
4334    /** Get the runtime session that this component type belongs to.
4335     */
4336    virtual SLANG_NO_THROW ISession* SLANG_MCALL getSession() = 0;
4337
4338    /** Get the layout for this program for the chosen `targetIndex`.
4339
4340    The resulting layout will establish offsets/bindings for all
4341    of the global and entry-point shader parameters in the
4342    component type.
4343
4344    If this component type has specialization parameters (that is,
4345    it is not fully specialized), then the resulting layout may
4346    be incomplete, and plugging in arguments for generic specialization
4347    parameters may result in a component type that doesn't have
4348    a compatible layout. If the component type only uses
4349    interface-type specialization parameters, then the layout
4350    for a specialization should be compatible with an unspecialized
4351    layout (all parameters in the unspecialized layout will have
4352    the same offset/binding in the specialized layout).
4353
4354    If this component type is combined into a composite, then
4355    the absolute offsets/bindings of parameters may not stay the same.
4356    If the shader parameters in a component type don't make
4357    use of explicit binding annotations (e.g., `register(...)`),
4358    then the *relative* offset of shader parameters will stay
4359    the same when it is used in a composition.
4360    */
4361    virtual SLANG_NO_THROW ProgramLayout* SLANG_MCALL
4362    getLayout(SlangInt targetIndex = 0, IBlob** outDiagnostics = nullptr) = 0;
4363
4364    /** Get the number of (unspecialized) specialization parameters for the component type.
4365     */
4366    virtual SLANG_NO_THROW SlangInt SLANG_MCALL getSpecializationParamCount() = 0;
4367
4368    /** Get the compiled code for the entry point at `entryPointIndex` for the chosen `targetIndex`
4369
4370    Entry point code can only be computed for a component type that
4371    has no specialization parameters (it must be fully specialized)
4372    and that has no requirements (it must be fully linked).
4373
4374    If code has not already been generated for the given entry point and target,
4375    then a compilation error may be detected, in which case `outDiagnostics`
4376    (if non-null) will be filled in with a blob of messages diagnosing the error.
4377    */
4378    virtual SLANG_NO_THROW SlangResult SLANG_MCALL getEntryPointCode(
4379        SlangInt entryPointIndex,
4380        SlangInt targetIndex,
4381        IBlob** outCode,
4382        IBlob** outDiagnostics = nullptr) = 0;
4383
4384    /** Get the compilation result as a file system.
4385
4386    Has the same requirements as getEntryPointCode.
4387
4388    The result is not written to the actual OS file system, but is made available as an
4389    in memory representation.
4390    */
4391    virtual SLANG_NO_THROW SlangResult SLANG_MCALL getResultAsFileSystem(
4392        SlangInt entryPointIndex,
4393        SlangInt targetIndex,
4394        ISlangMutableFileSystem** outFileSystem) = 0;
4395
4396    /** Compute a hash for the entry point at `entryPointIndex` for the chosen `targetIndex`.
4397
4398    This computes a hash based on all the dependencies for this component type as well as the
4399    target settings affecting the compiler backend. The computed hash is used as a key for caching
4400    the output of the compiler backend to implement shader caching.
4401    */
4402    virtual SLANG_NO_THROW void SLANG_MCALL
4403    getEntryPointHash(SlangInt entryPointIndex, SlangInt targetIndex, IBlob** outHash) = 0;
4404
4405    /** Specialize the component by binding its specialization parameters to concrete arguments.
4406
4407    The `specializationArgs` array must have `specializationArgCount` entries, and
4408    this must match the number of specialization parameters on this component type.
4409
4410    If any diagnostics (error or warnings) are produced, they will be written to `outDiagnostics`.
4411    */
4412    virtual SLANG_NO_THROW SlangResult SLANG_MCALL specialize(
4413        SpecializationArg const* specializationArgs,
4414        SlangInt specializationArgCount,
4415        IComponentType** outSpecializedComponentType,
4416        ISlangBlob** outDiagnostics = nullptr) = 0;
4417
4418    /** Link this component type against all of its unsatisfied dependencies.
4419
4420    A component type may have unsatisfied dependencies. For example, a module
4421    depends on any other modules it `import`s, and an entry point depends
4422    on the module that defined it.
4423
4424    A user can manually satisfy dependencies by creating a composite
4425    component type, and when doing so they retain full control over
4426    the relative ordering of shader parameters in the resulting layout.
4427
4428    It is an error to try to generate/access compiled kernel code for
4429    a component type with unresolved dependencies, so if dependencies
4430    remain after whatever manual composition steps an application
4431    cares to perform, the `link()` function can be used to automatically
4432    compose in any remaining dependencies. The order of parameters
4433    (and hence the global layout) that results will be deterministic,
4434    but is not currently documented.
4435    */
4436    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
4437    link(IComponentType** outLinkedComponentType, ISlangBlob** outDiagnostics = nullptr) = 0;
4438
4439    /** Get entry point 'callable' functions accessible through the ISlangSharedLibrary interface.
4440
4441    The functions remain in scope as long as the ISlangSharedLibrary interface is in scope.
4442
4443    NOTE! Requires a compilation target of SLANG_HOST_CALLABLE.
4444
4445    @param entryPointIndex  The index of the entry point to get code for.
4446    @param targetIndex      The index of the target to get code for (default: zero).
4447    @param outSharedLibrary A pointer to a ISharedLibrary interface which functions can be queried
4448    on.
4449    @returns                A `SlangResult` to indicate success or failure.
4450    */
4451    virtual SLANG_NO_THROW SlangResult SLANG_MCALL getEntryPointHostCallable(
4452        int entryPointIndex,
4453        int targetIndex,
4454        ISlangSharedLibrary** outSharedLibrary,
4455        slang::IBlob** outDiagnostics = 0) = 0;
4456
4457    /** Get a new ComponentType object that represents a renamed entry point.
4458
4459    The current object must be a single EntryPoint, or a CompositeComponentType or
4460    SpecializedComponentType that contains one EntryPoint component.
4461    */
4462    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
4463    renameEntryPoint(const char* newName, IComponentType** outEntryPoint) = 0;
4464
4465    /** Link and specify additional compiler options when generating code
4466     *   from the linked program.
4467     */
4468    virtual SLANG_NO_THROW SlangResult SLANG_MCALL linkWithOptions(
4469        IComponentType** outLinkedComponentType,
4470        uint32_t compilerOptionEntryCount,
4471        CompilerOptionEntry* compilerOptionEntries,
4472        ISlangBlob** outDiagnostics = nullptr) = 0;
4473
4474    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
4475    getTargetCode(SlangInt targetIndex, IBlob** outCode, IBlob** outDiagnostics = nullptr) = 0;
4476
4477    virtual SLANG_NO_THROW SlangResult SLANG_MCALL getTargetMetadata(
4478        SlangInt targetIndex,
4479        IMetadata** outMetadata,
4480        IBlob** outDiagnostics = nullptr) = 0;
4481
4482    virtual SLANG_NO_THROW SlangResult SLANG_MCALL getEntryPointMetadata(
4483        SlangInt entryPointIndex,
4484        SlangInt targetIndex,
4485        IMetadata** outMetadata,
4486        IBlob** outDiagnostics = nullptr) = 0;
4487};
4488    #define SLANG_UUID_IComponentType IComponentType::getTypeGuid()
4489
4490struct IEntryPoint : public IComponentType
4491{
4492    SLANG_COM_INTERFACE(0x8f241361, 0xf5bd, 0x4ca0, {0xa3, 0xac, 0x2, 0xf7, 0xfa, 0x24, 0x2, 0xb8})
4493
4494    virtual SLANG_NO_THROW FunctionReflection* SLANG_MCALL getFunctionReflection() = 0;
4495};
4496
4497    #define SLANG_UUID_IEntryPoint IEntryPoint::getTypeGuid()
4498
4499struct ITypeConformance : public IComponentType
4500{
4501    SLANG_COM_INTERFACE(0x73eb3147, 0xe544, 0x41b5, {0xb8, 0xf0, 0xa2, 0x44, 0xdf, 0x21, 0x94, 0xb})
4502};
4503    #define SLANG_UUID_ITypeConformance ITypeConformance::getTypeGuid()
4504
4505/** IComponentType2 is a component type used for getting separate debug data.
4506
4507This interface is used for getting separate debug data, introduced here to
4508avoid breaking backwards compatibility of the IComponentType interface.
4509
4510The `getTargetCompileResult` and `getEntryPointCompileResult` functions
4511are used to get the base and debug spirv, and metadata containing the
4512debug build identifier.
4513*/
4514struct IComponentType2 : public ISlangUnknown
4515{
4516    SLANG_COM_INTERFACE(
4517        0x9c2a4b3d,
4518        0x7f68,
4519        0x4e91,
4520        {0xa5, 0x2c, 0x8b, 0x19, 0x3e, 0x45, 0x7a, 0x9f})
4521
4522    virtual SLANG_NO_THROW SlangResult SLANG_MCALL getTargetCompileResult(
4523        SlangInt targetIndex,
4524        ICompileResult** outCompileResult,
4525        IBlob** outDiagnostics = nullptr) = 0;
4526    virtual SLANG_NO_THROW SlangResult SLANG_MCALL getEntryPointCompileResult(
4527        SlangInt entryPointIndex,
4528        SlangInt targetIndex,
4529        ICompileResult** outCompileResult,
4530        IBlob** outDiagnostics = nullptr) = 0;
4531};
4532    #define SLANG_UUID_IComponentType2 IComponentType2::getTypeGuid()
4533
4534/** A module is the granularity of shader code compilation and loading.
4535
4536In most cases a module corresponds to a single compile "translation unit."
4537This will often be a single `.slang` or `.hlsl` file and everything it
4538`#include`s.
4539
4540Notably, a module `M` does *not* include the things it `import`s, as these
4541as distinct modules that `M` depends on. There is a directed graph of
4542module dependencies, and all modules in the graph must belong to the
4543same session (`ISession`).
4544
4545A module establishes a namespace for looking up types, functions, etc.
4546*/
4547struct IModule : public IComponentType
4548{
4549    SLANG_COM_INTERFACE(0xc720e64, 0x8722, 0x4d31, {0x89, 0x90, 0x63, 0x8a, 0x98, 0xb1, 0xc2, 0x79})
4550
4551    /// Find and an entry point by name.
4552    /// Note that this does not work in case the function is not explicitly designated as an entry
4553    /// point, e.g. using a `[shader("...")]` attribute. In such cases, consider using
4554    /// `IModule::findAndCheckEntryPoint` instead.
4555    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
4556    findEntryPointByName(char const* name, IEntryPoint** outEntryPoint) = 0;
4557
4558    /// Get number of entry points defined in the module. An entry point defined in a module
4559    /// is by default not included in the linkage, so calls to `IComponentType::getEntryPointCount`
4560    /// on an `IModule` instance will always return 0. However `IModule::getDefinedEntryPointCount`
4561    /// will return the number of defined entry points.
4562    virtual SLANG_NO_THROW SlangInt32 SLANG_MCALL getDefinedEntryPointCount() = 0;
4563    /// Get the name of an entry point defined in the module.
4564    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
4565    getDefinedEntryPoint(SlangInt32 index, IEntryPoint** outEntryPoint) = 0;
4566
4567    /// Get a serialized representation of the checked module.
4568    virtual SLANG_NO_THROW SlangResult SLANG_MCALL serialize(ISlangBlob** outSerializedBlob) = 0;
4569
4570    /// Write the serialized representation of this module to a file.
4571    virtual SLANG_NO_THROW SlangResult SLANG_MCALL writeToFile(char const* fileName) = 0;
4572
4573    /// Get the name of the module.
4574    virtual SLANG_NO_THROW const char* SLANG_MCALL getName() = 0;
4575
4576    /// Get the path of the module.
4577    virtual SLANG_NO_THROW const char* SLANG_MCALL getFilePath() = 0;
4578
4579    /// Get the unique identity of the module.
4580    virtual SLANG_NO_THROW const char* SLANG_MCALL getUniqueIdentity() = 0;
4581
4582    /// Find and validate an entry point by name, even if the function is
4583    /// not marked with the `[shader("...")]` attribute.
4584    virtual SLANG_NO_THROW SlangResult SLANG_MCALL findAndCheckEntryPoint(
4585        char const* name,
4586        SlangStage stage,
4587        IEntryPoint** outEntryPoint,
4588        ISlangBlob** outDiagnostics) = 0;
4589
4590    /// Get the number of dependency files that this module depends on.
4591    /// This includes both the explicit source files, as well as any
4592    /// additional files that were transitively referenced (e.g., via
4593    /// a `#include` directive).
4594    virtual SLANG_NO_THROW SlangInt32 SLANG_MCALL getDependencyFileCount() = 0;
4595
4596    /// Get the path to a file this module depends on.
4597    virtual SLANG_NO_THROW char const* SLANG_MCALL getDependencyFilePath(SlangInt32 index) = 0;
4598
4599    virtual SLANG_NO_THROW DeclReflection* SLANG_MCALL getModuleReflection() = 0;
4600
4601    /** Disassemble a module.
4602     */
4603    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
4604    disassemble(slang::IBlob** outDisassembledBlob) = 0;
4605};
4606
4607    #define SLANG_UUID_IModule IModule::getTypeGuid()
4608
4609/* Experimental interface for doing target precompilation of slang modules */
4610struct IModulePrecompileService_Experimental : public ISlangUnknown
4611{
4612    // uuidgen output:     8e12e8e3 -  5fcd -  433e -    afcb -      13a088bc5ee5
4613    SLANG_COM_INTERFACE(
4614        0x8e12e8e3,
4615        0x5fcd,
4616        0x433e,
4617        {0xaf, 0xcb, 0x13, 0xa0, 0x88, 0xbc, 0x5e, 0xe5})
4618
4619    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
4620    precompileForTarget(SlangCompileTarget target, ISlangBlob** outDiagnostics) = 0;
4621
4622    virtual SLANG_NO_THROW SlangResult SLANG_MCALL getPrecompiledTargetCode(
4623        SlangCompileTarget target,
4624        IBlob** outCode,
4625        IBlob** outDiagnostics = nullptr) = 0;
4626
4627    virtual SLANG_NO_THROW SlangInt SLANG_MCALL getModuleDependencyCount() = 0;
4628
4629    virtual SLANG_NO_THROW SlangResult SLANG_MCALL getModuleDependency(
4630        SlangInt dependencyIndex,
4631        IModule** outModule,
4632        IBlob** outDiagnostics = nullptr) = 0;
4633};
4634
4635    #define SLANG_UUID_IModulePrecompileService_Experimental \
4636        IModulePrecompileService_Experimental::getTypeGuid()
4637
4638/** Argument used for specialization to types/values.
4639 */
4640struct SpecializationArg
4641{
4642    enum class Kind : int32_t
4643    {
4644        Unknown, /**< An invalid specialization argument. */
4645        Type,    /**< Specialize to a type. */
4646        Expr,    /**< An expression representing a type or value */
4647    };
4648
4649    /** The kind of specialization argument. */
4650    Kind kind;
4651    union
4652    {
4653        /** A type specialization argument, used for `Kind::Type`. */
4654        TypeReflection* type;
4655        /** An expression in Slang syntax, used for `Kind::Expr`. */
4656        const char* expr;
4657    };
4658
4659    static SpecializationArg fromType(TypeReflection* inType)
4660    {
4661        SpecializationArg rs;
4662        rs.kind = Kind::Type;
4663        rs.type = inType;
4664        return rs;
4665    }
4666
4667    static SpecializationArg fromExpr(const char* inExpr)
4668    {
4669        SpecializationArg rs;
4670        rs.kind = Kind::Expr;
4671        rs.expr = inExpr;
4672        return rs;
4673    }
4674};
4675} // namespace slang
4676
4677    // Passed into functions to create globalSession to identify the API version client code is
4678    // using.
4679    #define SLANG_API_VERSION 0
4680
4681enum SlangLanguageVersion
4682{
4683    SLANG_LANGUAGE_VERSION_UNKNOWN = 0,
4684    SLANG_LANGUAGE_VERSION_LEGACY = 2018,
4685    SLANG_LANGUAGE_VERSION_2025 = 2025,
4686    SLANG_LANGUAGE_VERSION_2026 = 2026,
4687    SLANG_LANGAUGE_VERSION_DEFAULT = SLANG_LANGUAGE_VERSION_LEGACY,
4688    SLANG_LANGUAGE_VERSION_LATEST = SLANG_LANGUAGE_VERSION_2026,
4689};
4690
4691
4692/* Description of a Slang global session.
4693 */
4694struct SlangGlobalSessionDesc
4695{
4696    /// Size of this struct.
4697    uint32_t structureSize = sizeof(SlangGlobalSessionDesc);
4698
4699    /// Slang API version.
4700    uint32_t apiVersion = SLANG_API_VERSION;
4701
4702    /// Specify the oldest Slang language version that any sessions will use.
4703    uint32_t minLanguageVersion = SLANG_LANGUAGE_VERSION_2025;
4704
4705    /// Whether to enable GLSL support.
4706    bool enableGLSL = false;
4707
4708    /// Reserved for future use.
4709    uint32_t reserved[16] = {};
4710};
4711
4712/* Create a blob from binary data.
4713 *
4714 * @param data Pointer to the binary data to store in the blob. Must not be null.
4715 * @param size Size of the data in bytes. Must be greater than 0.
4716 * @return The created blob on success, or nullptr on failure.
4717 */
4718SLANG_EXTERN_C SLANG_API ISlangBlob* slang_createBlob(const void* data, size_t size);
4719
4720/* Load a module from source code with size specification.
4721 *
4722 * @param session The session to load the module into.
4723 * @param moduleName The name of the module.
4724 * @param path The path for the module.
4725 * @param source Pointer to the source code data.
4726 * @param sourceSize Size of the source code data in bytes.
4727 * @param outDiagnostics (out, optional) Diagnostics output.
4728 * @return The loaded module on success, or nullptr on failure.
4729 */
4730SLANG_EXTERN_C SLANG_API slang::IModule* slang_loadModuleFromSource(
4731    slang::ISession* session,
4732    const char* moduleName,
4733    const char* path,
4734    const char* source,
4735    size_t sourceSize,
4736    ISlangBlob** outDiagnostics = nullptr);
4737
4738/** Load a module from IR data.
4739 * @param session The session to load the module into.
4740 * @param moduleName Name of the module to load.
4741 * @param path Path for the module (used for diagnostics).
4742 * @param source IR data containing the module.
4743 * @param sourceSize Size of the IR data in bytes.
4744 * @param outDiagnostics (out, optional) Diagnostics output.
4745 * @return The loaded module on success, or nullptr on failure.
4746 */
4747SLANG_EXTERN_C SLANG_API slang::IModule* slang_loadModuleFromIRBlob(
4748    slang::ISession* session,
4749    const char* moduleName,
4750    const char* path,
4751    const void* source,
4752    size_t sourceSize,
4753    ISlangBlob** outDiagnostics = nullptr);
4754
4755/** Read module info (name and version) from IR data.
4756 * @param session The session to use for loading module info.
4757 * @param source IR data containing the module.
4758 * @param sourceSize Size of the IR data in bytes.
4759 * @param outModuleVersion (out) Module version number.
4760 * @param outModuleCompilerVersion (out) Compiler version that created the module.
4761 * @param outModuleName (out) Name of the module.
4762 * @return SLANG_OK on success, or an error code on failure.
4763 */
4764SLANG_EXTERN_C SLANG_API SlangResult slang_loadModuleInfoFromIRBlob(
4765    slang::ISession* session,
4766    const void* source,
4767    size_t sourceSize,
4768    SlangInt& outModuleVersion,
4769    const char*& outModuleCompilerVersion,
4770    const char*& outModuleName);
4771
4772/* Create a global session, with the built-in core module.
4773
4774@param apiVersion Pass in SLANG_API_VERSION
4775@param outGlobalSession (out)The created global session.
4776*/
4777SLANG_EXTERN_C SLANG_API SlangResult
4778slang_createGlobalSession(SlangInt apiVersion, slang::IGlobalSession** outGlobalSession);
4779
4780
4781/* Create a global session, with the built-in core module.
4782
4783@param desc Description of the global session.
4784@param outGlobalSession (out)The created global session.
4785*/
4786SLANG_EXTERN_C SLANG_API SlangResult slang_createGlobalSession2(
4787    const SlangGlobalSessionDesc* desc,
4788    slang::IGlobalSession** outGlobalSession);
4789
4790/* Create a global session, but do not set up the core module. The core module can
4791then be loaded via loadCoreModule or compileCoreModule
4792
4793@param apiVersion Pass in SLANG_API_VERSION
4794@param outGlobalSession (out)The created global session that doesn't have a core module setup.
4795
4796NOTE! API is experimental and not ready for production code
4797*/
4798SLANG_EXTERN_C SLANG_API SlangResult slang_createGlobalSessionWithoutCoreModule(
4799    SlangInt apiVersion,
4800    slang::IGlobalSession** outGlobalSession);
4801
4802/* Returns a blob that contains the serialized core module.
4803Returns nullptr if there isn't an embedded core module.
4804
4805NOTE! API is experimental and not ready for production code
4806*/
4807SLANG_API ISlangBlob* slang_getEmbeddedCoreModule();
4808
4809
4810/* Cleanup all global allocations used by Slang, to prevent memory leak detectors from
4811 reporting them as leaks. This function should only be called after all Slang objects
4812 have been released. No other Slang functions such as `createGlobalSession`
4813 should be called after this function.
4814 */
4815SLANG_EXTERN_C SLANG_API void slang_shutdown();
4816
4817/* Return the last signaled internal error message.
4818 */
4819SLANG_EXTERN_C SLANG_API const char* slang_getLastInternalErrorMessage();
4820
4821// Slang VM
4822namespace slang
4823{
4824
4825enum class OperandDataType
4826{
4827    General = 0, // General data type, can be any type.
4828    Int32 = 1,   // 32-bit integer.
4829    Int64 = 2,   // 64-bit integer.
4830    Float32 = 3, // 32-bit floating-point number.
4831    Float64 = 4, // 64-bit floating-point number.
4832    String = 5,  // String data type, represented as a pointer to a null-terminated string.
4833};
4834
4835struct VMExecOperand
4836{
4837    uint8_t** section; // Pointer to the section start pointer.
4838    #if SLANG_PTR_IS_32
4839    uint32_t padding;
4840    #endif
4841    uint32_t type : 8; // type of the operand data.
4842    uint32_t size : 24;
4843    uint32_t offset;
4844    void* getPtr() const { return *section + offset; }
4845    OperandDataType getType() const { return (OperandDataType)type; }
4846};
4847
4848struct VMExecInstHeader;
4849class IByteCodeRunner;
4850
4851typedef void (*VMExtFunction)(IByteCodeRunner* context, VMExecInstHeader* inst, void* userData);
4852typedef void (*VMPrintFunc)(const char* message, void* userData);
4853
4854struct VMExecInstHeader
4855{
4856    VMExtFunction functionPtr; // Pointer to the function that executes this instruction.
4857    #if SLANG_PTR_IS_32
4858    uint32_t padding;
4859    #endif
4860    uint32_t opcodeExtension;
4861    uint32_t operandCount;
4862    VMExecInstHeader* getNextInst()
4863    {
4864        return (VMExecInstHeader*)((VMExecOperand*)(this + 1) + operandCount);
4865    }
4866    VMExecOperand& getOperand(SlangInt index) const
4867    {
4868        return *((VMExecOperand*)(this + 1) + index);
4869    }
4870};
4871
4872struct ByteCodeFuncInfo
4873{
4874    uint32_t parameterCount;
4875    uint32_t returnValueSize;
4876};
4877
4878struct ByteCodeRunnerDesc
4879{
4880    /** The size of this structure, in bytes.
4881     */
4882    size_t structSize = sizeof(ByteCodeRunnerDesc);
4883};
4884
4885/// Represents a byte code runner that can execute Slang byte code.
4886class IByteCodeRunner : public ISlangUnknown
4887{
4888public:
4889    // {AFDAB195-361F-42CB-9513-9006261DD8CD}
4890    SLANG_COM_INTERFACE(0xafdab195, 0x361f, 0x42cb, {0x95, 0x13, 0x90, 0x6, 0x26, 0x1d, 0xd8, 0xcd})
4891
4892    /// Load a byte code module into the execution context.
4893    virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadModule(IBlob* moduleBlob) = 0;
4894
4895    /// Select a function for execution.
4896    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
4897    selectFunctionByIndex(uint32_t functionIndex) = 0;
4898
4899    virtual SLANG_NO_THROW int SLANG_MCALL findFunctionByName(const char* name) = 0;
4900
4901    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
4902    getFunctionInfo(uint32_t index, ByteCodeFuncInfo* outInfo) = 0;
4903
4904    /// Obtain the current working set memory for the selected function.
4905    virtual SLANG_NO_THROW void* SLANG_MCALL getCurrentWorkingSet() = 0;
4906
4907    /// Execute the selected function.
4908    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
4909    execute(void* argumentData, size_t argumentSize) = 0;
4910
4911    /// Query the error string.
4912    virtual SLANG_NO_THROW void SLANG_MCALL getErrorString(IBlob** outBlob) = 0;
4913
4914    /// Retrieve the return value of the last executed function.
4915    virtual SLANG_NO_THROW void* SLANG_MCALL getReturnValue(size_t* outValueSize) = 0;
4916
4917    /// Set the user data for the external instruction handler.
4918    virtual SLANG_NO_THROW void SLANG_MCALL setExtInstHandlerUserData(void* userData) = 0;
4919
4920    /// Register an external function that can be called from the byte code.
4921    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
4922    registerExtCall(const char* name, VMExtFunction functionPtr) = 0;
4923
4924    /// Set a callback function to print messages from the byte code runner.
4925    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
4926    setPrintCallback(VMPrintFunc callback, void* userData) = 0;
4927};
4928
4929} // namespace slang
4930
4931/// Create a byte code runner that can execute Slang byte code.
4932SLANG_EXTERN_C SLANG_API SlangResult slang_createByteCodeRunner(
4933    const slang::ByteCodeRunnerDesc* desc,
4934    slang::IByteCodeRunner** outByteCodeRunner);
4935
4936/// Disassemble a Slang byte code blob into human-readable text.
4937SLANG_EXTERN_C SLANG_API SlangResult
4938slang_disassembleByteCode(slang::IBlob* moduleBlob, slang::IBlob** outDisassemblyBlob);
4939
4940namespace slang
4941{
4942inline SlangResult createGlobalSession(slang::IGlobalSession** outGlobalSession)
4943{
4944    SlangGlobalSessionDesc defaultDesc = {};
4945    return slang_createGlobalSession2(&defaultDesc, outGlobalSession);
4946}
4947inline SlangResult createGlobalSession(
4948    const SlangGlobalSessionDesc* desc,
4949    slang::IGlobalSession** outGlobalSession)
4950{
4951    return slang_createGlobalSession2(desc, outGlobalSession);
4952}
4953inline void shutdown()
4954{
4955    slang_shutdown();
4956}
4957inline const char* getLastInternalErrorMessage()
4958{
4959    return slang_getLastInternalErrorMessage();
4960}
4961} // namespace slang
4962
4963#endif // C++ helpers
4964
4965#define SLANG_ERROR_INSUFFICIENT_BUFFER SLANG_E_BUFFER_TOO_SMALL
4966#define SLANG_ERROR_INVALID_PARAMETER SLANG_E_INVALID_ARG
4967
4968#endif