1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
|
#include "slang-type-text-util.h"
#include "slang-array-view.h"
#include "slang-string-util.h"
namespace Slang
{
namespace
{ // anonymous
// clang-format off
#define SLANG_SCALAR_TYPES(x) \
x(None, none) \
x(Void, void) \
x(Bool, bool) \
x(Float16, half) \
x(UInt32, uint32_t) \
x(Int32, int32_t) \
x(Int64, int64_t) \
x(UInt64, uint64_t) \
x(Float32, float) \
x(Float64, double)
// clang-format on
struct ScalarTypeInfo
{
slang::TypeReflection::ScalarType type;
UnownedStringSlice text;
};
static const ScalarTypeInfo s_scalarTypeInfos[] = {
#define SLANG_SCALAR_TYPE_INFO(value, text) \
{slang::TypeReflection::ScalarType::value, UnownedStringSlice::fromLiteral(#text)},
SLANG_SCALAR_TYPES(SLANG_SCALAR_TYPE_INFO)};
// Make sure to keep this table in sync with that in slang/slang-options.cpp getHelpText
static const TypeTextUtil::CompileTargetInfo s_compileTargetInfos[] = {
{SLANG_TARGET_UNKNOWN, "", "unknown"},
{SLANG_TARGET_NONE, "", "none"},
{SLANG_HLSL, "hlsl,fx", "hlsl", "HLSL source code"},
{SLANG_DXBC, "dxbc", "dxbc", "DirectX shader bytecode binary"},
{SLANG_DXBC_ASM, "dxbc-asm", "dxbc-asm,dxbc-assembly", "DirectX shader bytecode assembly"},
{SLANG_DXIL, "dxil", "dxil", "DirectX Intermediate Language binary"},
{SLANG_DXIL_ASM,
"dxil-asm",
"dxil-asm,dxil-assembly",
"DirectX Intermediate Language assembly"},
{SLANG_GLSL, "glsl,vert,frag,geom,tesc,tese,comp", "glsl", "GLSL(Vulkan) source code"},
{SLANG_SPIRV, "spv", "spirv", "SPIR-V binary"},
{SLANG_SPIRV_ASM, "spv-asm", "spirv-asm,spirv-assembly", "SPIR-V assembly"},
{SLANG_C_SOURCE, "c", "c", "C source code"},
{SLANG_CPP_SOURCE, "cpp,c++,cxx", "cpp,c++,cxx", "C++ source code"},
{SLANG_CPP_PYTORCH_BINDING,
"cpp,c++,cxx",
"torch,torch-binding,torch-cpp,torch-cpp-binding",
"C++ for pytorch binding"},
{SLANG_HOST_CPP_SOURCE,
"cpp,c++,cxx",
"host-cpp,host-c++,host-cxx",
"C++ source for host execution"},
{SLANG_HOST_EXECUTABLE, "exe", "exe,executable", "Executable binary"},
{SLANG_SHADER_SHARED_LIBRARY,
"shader-dll,shader-so",
"shader-sharedlib,shader-sharedlibrary,shader-dll",
"Shared library/Dll for shader kernel"},
{SLANG_HOST_SHARED_LIBRARY,
"dll,so",
"sharedlib,sharedlibrary,dll",
"Shared library/Dll for host execution"},
{SLANG_CUDA_SOURCE, "cu", "cuda,cu", "CUDA source code"},
{SLANG_PTX, "ptx", "ptx", "PTX assembly"},
{SLANG_CUDA_OBJECT_CODE, "obj,o", "cuobj,cubin", "CUDA binary"},
{SLANG_SHADER_HOST_CALLABLE, "", "host-callable,callable", "Host callable"},
{SLANG_OBJECT_CODE, "obj,o", "object-code", "Object code"},
{SLANG_HOST_HOST_CALLABLE, "", "host-host-callable", "Host callable for host execution"},
{SLANG_METAL, "metal", "metal", "Metal shader source"},
{SLANG_METAL_LIB, "metallib", "metallib", "Metal Library Bytecode"},
{SLANG_METAL_LIB_ASM, "metallib-asm", "metallib-asm", "Metal Library Bytecode assembly"},
{SLANG_WGSL, "wgsl", "wgsl", "WebGPU shading language source"},
{SLANG_WGSL_SPIRV_ASM,
"wgsl-spirv-asm",
"wgsl-spirv-asm,wgsl-spirv-assembly",
"SPIR-V assembly via WebGPU shading language"},
{SLANG_WGSL_SPIRV, "wgsl-spirv", "wgsl-spirv", "SPIR-V via WebGPU shading language"},
{SLANG_HOST_VM, "slang-vm", "slangvm,slang-vm", "Slang VM byte code"},
};
static const NamesDescriptionValue s_languageInfos[] = {
{SLANG_SOURCE_LANGUAGE_C, "c,C", "C language"},
{SLANG_SOURCE_LANGUAGE_CPP, "cpp,c++,C++,cxx", "C++ language"},
{SLANG_SOURCE_LANGUAGE_SLANG, "slang", "Slang language"},
{SLANG_SOURCE_LANGUAGE_GLSL, "glsl", "GLSL language"},
{SLANG_SOURCE_LANGUAGE_HLSL, "hlsl", "HLSL language"},
{SLANG_SOURCE_LANGUAGE_CUDA, "cu,cuda", "CUDA"},
};
static const NamesDescriptionValue s_languageVersionInfos[] = {
{SLANG_LANGUAGE_VERSION_LEGACY, "legacy,default,2018", "Legacy Slang language"},
{SLANG_LANGUAGE_VERSION_2025, "2025", "Slang language rules for 2025 and older"},
{SLANG_LANGUAGE_VERSION_2026, "2026,latest", "Slang language rules for 2026 and newer"},
};
static const NamesDescriptionValue s_compilerInfos[] = {
{SLANG_PASS_THROUGH_NONE, "none", "Unknown"},
{SLANG_PASS_THROUGH_FXC, "fxc", "FXC HLSL compiler"},
{SLANG_PASS_THROUGH_DXC, "dxc", "DXC HLSL compiler"},
{SLANG_PASS_THROUGH_GLSLANG, "glslang", "GLSLANG GLSL compiler"},
{SLANG_PASS_THROUGH_SPIRV_DIS, "spirv-dis", "spirv-tools SPIRV disassembler"},
{SLANG_PASS_THROUGH_CLANG, "clang", "Clang C/C++ compiler"},
{SLANG_PASS_THROUGH_VISUAL_STUDIO, "visualstudio,vs", "Visual Studio C/C++ compiler"},
{SLANG_PASS_THROUGH_GCC, "gcc", "GCC C/C++ compiler"},
{SLANG_PASS_THROUGH_GENERIC_C_CPP,
"genericcpp,c,cpp",
"A generic C++ compiler (can be any one of visual studio, clang or gcc depending on system "
"and availability)"},
{SLANG_PASS_THROUGH_NVRTC, "nvrtc", "NVRTC CUDA compiler"},
{SLANG_PASS_THROUGH_LLVM, "llvm", "LLVM/Clang `slang-llvm`"},
{SLANG_PASS_THROUGH_SPIRV_OPT, "spirv-opt", "spirv-tools SPIRV optimizer"},
{SLANG_PASS_THROUGH_METAL, "metal", "Metal shader compiler"},
{SLANG_PASS_THROUGH_TINT, "tint", "Tint compiler"},
};
static const NamesDescriptionValue s_archiveTypeInfos[] = {
{SLANG_ARCHIVE_TYPE_RIFF_DEFLATE, "riff-deflate", "Slang RIFF using deflate compression"},
{SLANG_ARCHIVE_TYPE_RIFF_LZ4, "riff-lz4", "Slang RIFF using LZ4 compression"},
{SLANG_ARCHIVE_TYPE_ZIP, "zip", "Zip file"},
{SLANG_ARCHIVE_TYPE_RIFF, "riff", "Slang RIFF without compression"},
};
static const NamesDescriptionValue s_debugInfoFormatInfos[] = {
{SLANG_DEBUG_INFO_FORMAT_DEFAULT,
"default-format",
"Use the default debugging format for the target"},
{SLANG_DEBUG_INFO_FORMAT_C7,
"c7",
"CodeView C7 format (typically means debugging infomation is embedded in the binary)"},
{SLANG_DEBUG_INFO_FORMAT_PDB, "pdb", "Program database"},
{SLANG_DEBUG_INFO_FORMAT_STABS, "stabs", "STABS debug format"},
{SLANG_DEBUG_INFO_FORMAT_COFF, "coff", "COFF debug format"},
{SLANG_DEBUG_INFO_FORMAT_DWARF, "dwarf", "DWARF debug format"},
};
static const NamesDescriptionValue s_lineDirectiveInfos[] = {
{SLANG_LINE_DIRECTIVE_MODE_NONE, "none", "Don't emit `#line` directives at all"},
{SLANG_LINE_DIRECTIVE_MODE_SOURCE_MAP,
"source-map",
"Use source map to track line associations (doen't emit #line)"},
{SLANG_LINE_DIRECTIVE_MODE_DEFAULT, "default", "Default behavior"},
{SLANG_LINE_DIRECTIVE_MODE_STANDARD, "standard", "Emit standard C-style `#line` directives."},
{SLANG_LINE_DIRECTIVE_MODE_GLSL,
"glsl",
"Emit GLSL-style directives with file *number* instead of name."},
};
static const NamesDescriptionValue s_floatingPointModes[] = {
{SLANG_FLOATING_POINT_MODE_PRECISE,
"precise",
"Disable optimization that could change the output of floating-"
"point computations, including around infinities, NaNs, denormalized "
"values, and negative zero. Prefer the most precise versions of special "
"functions supported by the target."},
{SLANG_FLOATING_POINT_MODE_FAST,
"fast",
"Allow optimizations that may change results of floating-point "
"computations. Prefer the fastest version of special functions supported "
"by the target."},
{SLANG_FLOATING_POINT_MODE_DEFAULT, "default", "Default floating point mode"}};
static const NamesDescriptionValue s_fpDenormalModes[] = {
{SLANG_FP_DENORM_MODE_ANY,
"any",
"Use any denormal handling mode (default). The mode used is implementation defined."},
{SLANG_FP_DENORM_MODE_PRESERVE, "preserve", "Preserve denormal values"},
{SLANG_FP_DENORM_MODE_FTZ, "ftz", "Flush denormals to zero"},
};
static const NamesDescriptionValue s_optimizationLevels[] = {
{SLANG_OPTIMIZATION_LEVEL_NONE, "0,none", "Disable all optimizations"},
{SLANG_OPTIMIZATION_LEVEL_DEFAULT,
"1,default",
"Enable a default level of optimization.This is the default if no -o options are used."},
{SLANG_OPTIMIZATION_LEVEL_HIGH, "2,high", "Enable aggressive optimizations for speed."},
{SLANG_OPTIMIZATION_LEVEL_MAXIMAL,
"3,maximal",
"Enable further optimizations, which might have a significant impact on compile time, or "
"involve unwanted tradeoffs in terms of code size."},
};
static const NamesDescriptionValue s_debugLevels[] = {
{SLANG_DEBUG_INFO_LEVEL_NONE, "0,none", "Don't emit debug information at all."},
{SLANG_DEBUG_INFO_LEVEL_MINIMAL,
"1,minimal",
"Emit as little debug information as possible, while still supporting stack traces."},
{SLANG_DEBUG_INFO_LEVEL_STANDARD,
"2,standard",
"Emit whatever is the standard level of debug information for each target."},
{SLANG_DEBUG_INFO_LEVEL_MAXIMAL,
"3,maximal",
"Emit as much debug information as possible for each target."},
};
static const NamesDescriptionValue s_fileSystemTypes[] = {
{ValueInt(TypeTextUtil::FileSystemType::Default), "default", "Default file system."},
{ValueInt(TypeTextUtil::FileSystemType::LoadFile),
"load-file",
"Just implements loadFile interface, so will be wrapped with CacheFileSystem internally."},
{ValueInt(TypeTextUtil::FileSystemType::Os),
"os",
"Use the OS based file system directly (without file system caching)"},
};
} // namespace
/* static */ ConstArrayView<NamesDescriptionValue> TypeTextUtil::getFileSystemTypeInfos()
{
return makeConstArrayView(s_fileSystemTypes);
}
/* static */ ConstArrayView<TypeTextUtil::CompileTargetInfo> TypeTextUtil::getCompileTargetInfos()
{
return makeConstArrayView(s_compileTargetInfos);
}
/* static */ ConstArrayView<NamesDescriptionValue> TypeTextUtil::getLanguageInfos()
{
return makeConstArrayView(s_languageInfos);
}
/* static */ ConstArrayView<NamesDescriptionValue> TypeTextUtil::getLanguageVersionInfos()
{
return makeConstArrayView(s_languageVersionInfos);
}
/* static */ ConstArrayView<NamesDescriptionValue> TypeTextUtil::getCompilerInfos()
{
return makeConstArrayView(s_compilerInfos);
}
/* static */ ConstArrayView<NamesDescriptionValue> TypeTextUtil::getArchiveTypeInfos()
{
return makeConstArrayView(s_archiveTypeInfos);
}
/* static */ ConstArrayView<NamesDescriptionValue> TypeTextUtil::getDebugInfoFormatInfos()
{
return makeConstArrayView(s_debugInfoFormatInfos);
}
/* static */ ConstArrayView<NamesDescriptionValue> TypeTextUtil::getLineDirectiveInfos()
{
return makeConstArrayView(s_lineDirectiveInfos);
}
/* static */ ConstArrayView<NamesDescriptionValue> TypeTextUtil::getFloatingPointModeInfos()
{
return makeConstArrayView(s_floatingPointModes);
}
/* static */ ConstArrayView<NamesDescriptionValue> TypeTextUtil::getFpDenormalModeInfos()
{
return makeConstArrayView(s_fpDenormalModes);
}
/* static */ ConstArrayView<NamesDescriptionValue> TypeTextUtil::getOptimizationLevelInfos()
{
return makeConstArrayView(s_optimizationLevels);
}
/* static */ ConstArrayView<NamesDescriptionValue> TypeTextUtil::getDebugLevelInfos()
{
return makeConstArrayView(s_debugLevels);
}
/* static */ SlangArchiveType TypeTextUtil::findArchiveType(const UnownedStringSlice& slice)
{
return NameValueUtil::findValue(getArchiveTypeInfos(), slice, SLANG_ARCHIVE_TYPE_UNDEFINED);
}
/* static */ SlangResult TypeTextUtil::findDebugInfoFormat(
const Slang::UnownedStringSlice& text,
SlangDebugInfoFormat& out)
{
const ValueInt value = NameValueUtil::findValue(getDebugInfoFormatInfos(), text, -1);
if (value >= 0)
{
out = SlangDebugInfoFormat(value);
return SLANG_OK;
}
return SLANG_FAIL;
}
/* static */ UnownedStringSlice TypeTextUtil::getDebugInfoFormatName(SlangDebugInfoFormat format)
{
return NameValueUtil::findName(getDebugInfoFormatInfos(), format, toSlice("unknown"));
}
/* static */ UnownedStringSlice TypeTextUtil::getScalarTypeName(
slang::TypeReflection::ScalarType scalarType)
{
typedef slang::TypeReflection::ScalarType ScalarType;
switch (scalarType)
{
#define SLANG_SCALAR_TYPE_TO_TEXT(value, text) \
case ScalarType::value: \
return UnownedStringSlice::fromLiteral(#text);
SLANG_SCALAR_TYPES(SLANG_SCALAR_TYPE_TO_TEXT)
default:
break;
}
return UnownedStringSlice();
}
/* static */ slang::TypeReflection::ScalarType TypeTextUtil::findScalarType(
const UnownedStringSlice& inText)
{
for (Index i = 0; i < SLANG_COUNT_OF(s_scalarTypeInfos); ++i)
{
const auto& info = s_scalarTypeInfos[i];
if (info.text == inText)
{
return info.type;
}
}
return slang::TypeReflection::ScalarType::None;
}
/* static */ UnownedStringSlice TypeTextUtil::getPassThroughAsHumanText(SlangPassThrough type)
{
return NameValueUtil::findName(getCompilerInfos(), type, toSlice("unknown"));
}
/* static */ SlangSourceLanguage TypeTextUtil::findSourceLanguage(const UnownedStringSlice& text)
{
return NameValueUtil::findValue(getLanguageInfos(), text, SLANG_SOURCE_LANGUAGE_UNKNOWN);
}
/* static */ SlangLanguageVersion TypeTextUtil::findLanguageVersion(const UnownedStringSlice& text)
{
return NameValueUtil::findValue(
getLanguageVersionInfos(),
text,
SLANG_LANGUAGE_VERSION_UNKNOWN);
}
/* static */ SlangPassThrough TypeTextUtil::findPassThrough(const UnownedStringSlice& slice)
{
return NameValueUtil::findValue(getCompilerInfos(), slice, SLANG_PASS_THROUGH_NONE);
}
/* static */ SlangResult TypeTextUtil::findPassThrough(
const UnownedStringSlice& slice,
SlangPassThrough& outPassThrough)
{
outPassThrough = findPassThrough(slice);
// It could be none on error - if it's not equal to "none" then it must be an error
if (outPassThrough == SLANG_PASS_THROUGH_NONE &&
slice != UnownedStringSlice::fromLiteral("none"))
{
return SLANG_FAIL;
}
return SLANG_OK;
}
/* static */ UnownedStringSlice TypeTextUtil::getPassThroughName(SlangPassThrough passThru)
{
return NameValueUtil::findName(getCompilerInfos(), passThru, toSlice("unknown"));
}
/* static */ SlangCompileTarget TypeTextUtil::findCompileTargetFromExtension(
const UnownedStringSlice& slice)
{
if (slice.getLength())
{
for (const auto& info : s_compileTargetInfos)
{
if (StringUtil::indexOfInSplit(UnownedStringSlice(info.extensions), ',', slice) >= 0)
{
return info.target;
}
}
}
return SLANG_TARGET_UNKNOWN;
}
/* static */ SlangCompileTarget TypeTextUtil::findCompileTargetFromName(
const UnownedStringSlice& slice)
{
if (slice.getLength())
{
for (const auto& info : s_compileTargetInfos)
{
if (StringUtil::indexOfInSplit(UnownedStringSlice(info.names), ',', slice) >= 0)
{
return info.target;
}
}
}
return SLANG_TARGET_UNKNOWN;
}
static Index _getTargetInfoIndex(SlangCompileTarget target)
{
for (Index i = 0; i < SLANG_COUNT_OF(s_compileTargetInfos); ++i)
{
if (s_compileTargetInfos[i].target == target)
{
return i;
}
}
return -1;
}
UnownedStringSlice TypeTextUtil::getCompileTargetName(SlangCompileTarget target)
{
const Index index = _getTargetInfoIndex(target);
// Return the first name
return index >= 0 ? StringUtil::getAtInSplit(
UnownedStringSlice(s_compileTargetInfos[index].names),
',',
0)
: UnownedStringSlice();
}
} // namespace Slang
|