yum-mirror/slang

Making it easier to work with shaders

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

Jay KwakAdding slang-test option to ignore abort popup message (#8492)979e16a34

master
11.0 KiB349 linesraw
1// options.cpp
2
3#include "options.h"
4
5#include "../../source/core/slang-list.h"
6#include "../../source/core/slang-render-api-util.h"
7#include "../../source/core/slang-string-util.h"
8#include "../../source/core/slang-writer.h"
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13// #include "../../source/core/slang-downstream-compiler.h"
14
15#include "../../source/compiler-core/slang-command-line-args.h"
16#include "../../source/core/slang-type-text-util.h"
17#include "diagnostics.h"
18
19namespace renderer_test
20{
21using namespace Slang;
22
23static rhi::DeviceType _toRenderType(Slang::RenderApiType apiType)
24{
25    using namespace Slang;
26    switch (apiType)
27    {
28    case RenderApiType::D3D11:
29        return rhi::DeviceType::D3D11;
30    case RenderApiType::D3D12:
31        return rhi::DeviceType::D3D12;
32    case RenderApiType::Vulkan:
33        return rhi::DeviceType::Vulkan;
34    case RenderApiType::Metal:
35        return rhi::DeviceType::Metal;
36    case RenderApiType::CPU:
37        return rhi::DeviceType::CPU;
38    case RenderApiType::CUDA:
39        return rhi::DeviceType::CUDA;
40    case RenderApiType::WebGPU:
41        return rhi::DeviceType::WGPU;
42    default:
43        return rhi::DeviceType::Default;
44    }
45}
46
47/* static */ SlangResult Options::parse(
48    int argc,
49    const char* const* argv,
50    Slang::WriterHelper stdError,
51    Options& outOptions)
52{
53    using namespace Slang;
54
55    RefPtr<CommandLineContext> cmdLineContext(new CommandLineContext);
56
57    DiagnosticSink sink(cmdLineContext->getSourceManager(), nullptr);
58    sink.writer = stdError.getWriter();
59    sink.setFlag(DiagnosticSink::Flag::SourceLocationLine);
60
61    outOptions = Options();
62
63    CommandLineArgs args(cmdLineContext);
64
65    if (argc > 0)
66    {
67        // first argument is the application name
68        outOptions.appName = argv[0];
69        args.setArgs(argv + 1, argc - 1);
70    }
71    else
72    {
73        args.setArgs(argv, argc);
74    }
75    SLANG_RETURN_ON_FAIL(outOptions.downstreamArgs.stripDownstreamArgs(args, 0, &sink));
76
77    CommandLineReader reader(&args, &sink);
78
79    List<CommandLineArg> positionalArgs;
80
81    typedef Options::ShaderProgramType ShaderProgramType;
82    typedef Options::InputLanguageID InputLanguageID;
83
84    // now iterate over arguments to collect options
85    while (reader.hasArg())
86    {
87        CommandLineArg arg = reader.getArgAndAdvance();
88        const auto& argValue = arg.value;
89
90        if (!argValue.startsWith("-"))
91        {
92            positionalArgs.add(arg);
93            continue;
94        }
95
96        if (argValue == "--")
97        {
98            while (reader.hasArg())
99            {
100                positionalArgs.add(reader.getArgAndAdvance());
101            }
102            break;
103        }
104        else if (argValue == "-o")
105        {
106            SLANG_RETURN_ON_FAIL(reader.expectArg(outOptions.outputPath));
107        }
108        else if (argValue == "-profile")
109        {
110            SLANG_RETURN_ON_FAIL(reader.expectArg(outOptions.profileName));
111        }
112        else if (argValue == "-render-features" || argValue == "-render-feature")
113        {
114            String features;
115            SLANG_RETURN_ON_FAIL(reader.expectArg(features));
116
117            List<UnownedStringSlice> values;
118            StringUtil::split(features.getUnownedSlice(), ',', values);
119
120            for (const auto& value : values)
121            {
122                outOptions.renderFeatures.add(value);
123            }
124        }
125        else if (argValue == "-xslang" || argValue == "-compile-arg")
126        {
127            // This is legacy support, should use -Xslang now
128            // This is an option that we want to pass along to Slang
129            CommandLineArg slangArg;
130            SLANG_RETURN_ON_FAIL(reader.expectArg(slangArg));
131            outOptions.downstreamArgs.getArgsByName("slang").add(slangArg);
132        }
133        else if (argValue == "-compute")
134        {
135            outOptions.shaderType = ShaderProgramType::Compute;
136        }
137        else if (argValue == "-graphics")
138        {
139            outOptions.shaderType = ShaderProgramType::Graphics;
140        }
141        else if (argValue == "-gcompute")
142        {
143            outOptions.shaderType = ShaderProgramType::GraphicsCompute;
144        }
145        else if (argValue == "-rt")
146        {
147            outOptions.shaderType = ShaderProgramType::RayTracing;
148        }
149        else if (argValue == "-mesh")
150        {
151            outOptions.shaderType = ShaderProgramType::GraphicsMeshCompute;
152        }
153        else if (argValue == "-task")
154        {
155            outOptions.shaderType = ShaderProgramType::GraphicsTaskMeshCompute;
156        }
157        else if (argValue == "-use-dxbc")
158        {
159            outOptions.useDXBC = true;
160        }
161        else if (argValue == "-skip-spirv-validation")
162        {
163            outOptions.skipSPIRVValidation = true;
164        }
165        else if (argValue == "-emit-spirv-directly")
166        {
167            outOptions.generateSPIRVDirectly = true;
168        }
169        else if (argValue == "-emit-spirv-via-glsl")
170        {
171            outOptions.generateSPIRVDirectly = false;
172        }
173        else if (argValue == "-capability" || argValue == "-capabilities")
174        {
175            String capabilities;
176            SLANG_RETURN_ON_FAIL(reader.expectArg(capabilities));
177
178            List<UnownedStringSlice> values;
179            StringUtil::split(capabilities.getUnownedSlice(), ',', values);
180
181            for (const auto& value : values)
182            {
183                outOptions.capabilities.add(value);
184            }
185        }
186        else if (argValue == "-only-startup")
187        {
188            outOptions.onlyStartup = true;
189        }
190        else if (argValue == "-performance-profile")
191        {
192            outOptions.performanceProfile = true;
193        }
194        else if (argValue == "-output-using-type")
195        {
196            outOptions.outputUsingType = true;
197        }
198        else if (argValue == "-compute-dispatch")
199        {
200            CommandLineArg dispatchSize;
201            SLANG_RETURN_ON_FAIL(reader.expectArg(dispatchSize));
202
203            List<UnownedStringSlice> slices;
204            StringUtil::split(dispatchSize.value.getUnownedSlice(), ',', slices);
205            if (slices.getCount() != 3)
206            {
207                sink.diagnose(
208                    dispatchSize.loc,
209                    RenderTestDiagnostics::expectingCommaComputeDispatch);
210                return SLANG_FAIL;
211            }
212
213            String string;
214            for (Index i = 0; i < 3; ++i)
215            {
216                string = slices[i];
217                int v = stringToInt(string);
218                if (v < 1)
219                {
220                    sink.diagnose(
221                        dispatchSize.loc,
222                        RenderTestDiagnostics::expectingPositiveComputeDispatch);
223                    return SLANG_FAIL;
224                }
225                outOptions.computeDispatchSize[i] = v;
226            }
227        }
228        else if (argValue == "-source-language")
229        {
230            CommandLineArg sourceLanguageName;
231            SLANG_RETURN_ON_FAIL(reader.expectArg(sourceLanguageName));
232
233            const SlangSourceLanguage sourceLanguage =
234                TypeTextUtil::findSourceLanguage(sourceLanguageName.value.getUnownedSlice());
235            if (sourceLanguage == SLANG_SOURCE_LANGUAGE_UNKNOWN)
236            {
237                sink.diagnose(sourceLanguageName.loc, RenderTestDiagnostics::unknownSourceLanguage);
238                return SLANG_FAIL;
239            }
240
241            outOptions.sourceLanguage = sourceLanguage;
242        }
243        else if (argValue == "-no-default-entry-point")
244        {
245            outOptions.dontAddDefaultEntryPoints = true;
246        }
247        else if (argValue == "-nvapi-slot")
248        {
249            SLANG_RETURN_ON_FAIL(reader.expectArg(outOptions.nvapiExtnSlot));
250        }
251        else if (argValue == "-shaderobj")
252        {
253            // Note: We ignore this option because it is always enabled now.
254            //
255            // TODO: At some point we could warn/error and deprecate this option.
256        }
257        else if (argValue == "-g0")
258        {
259            outOptions.disableDebugInfo = true;
260        }
261        else if (argValue == "-allow-glsl")
262        {
263            outOptions.allowGLSL = true;
264        }
265        else if (argValue == "-entry")
266        {
267            SLANG_RETURN_ON_FAIL(reader.expectArg(outOptions.entryPointName));
268        }
269        else if (argValue == "-enable-debug-layers")
270        {
271            outOptions.enableDebugLayers = true;
272        }
273        else if (argValue == "-dx12-experimental")
274        {
275            outOptions.dx12Experimental = true;
276        }
277        else if (argValue == "-show-adapter-info")
278        {
279            outOptions.showAdapterInfo = true;
280        }
281        else if (argValue == "-ignore-abort-msg")
282        {
283#ifdef _MSC_VER
284            _set_abort_behavior(0, _WRITE_ABORT_MSG);
285#endif
286        }
287        else if (argValue == "-cache-rhi-device")
288        {
289            outOptions.cacheRhiDevice = true;
290        }
291        else
292        {
293            // Lookup
294            Slang::UnownedStringSlice argSlice = arg.value.getUnownedSlice();
295            if (argSlice.getLength() && argSlice[0] == '-')
296            {
297                // Look up the rendering API if set
298                UnownedStringSlice argName = argSlice.tail(1);
299                DeviceType deviceType = _toRenderType(RenderApiUtil::findApiTypeByName(argName));
300
301                if (deviceType != DeviceType::Default)
302                {
303                    outOptions.deviceType = deviceType;
304                    continue;
305                }
306
307                // Lookup the target language type
308                DeviceType targetLanguageDeviceType =
309                    _toRenderType(RenderApiUtil::findImplicitLanguageRenderApiType(argName));
310
311                if (targetLanguageDeviceType != DeviceType::Default || argName == "glsl")
312                {
313                    outOptions.targetLanguageDeviceType = targetLanguageDeviceType;
314                    outOptions.inputLanguageID =
315                        (argName == "hlsl" || argName == "glsl" || argName == "cpp" ||
316                         argName == "cxx" || argName == "c")
317                            ? InputLanguageID::Native
318                            : InputLanguageID::Slang;
319                    continue;
320                }
321            }
322            sink.diagnose(arg.loc, RenderTestDiagnostics::unknownCommandLineOption, arg.value);
323            return SLANG_FAIL;
324        }
325    }
326
327    // If a render option isn't set use defaultRenderType
328    outOptions.deviceType = (outOptions.deviceType == DeviceType::Default)
329                                ? outOptions.targetLanguageDeviceType
330                                : outOptions.deviceType;
331
332    // first positional argument is source shader path
333    if (positionalArgs.getCount())
334    {
335        outOptions.sourcePath = positionalArgs[0].value;
336        positionalArgs.removeAt(0);
337    }
338
339    // any remaining arguments represent an error
340    if (positionalArgs.getCount() != 0)
341    {
342        sink.diagnose(positionalArgs[0].loc, RenderTestDiagnostics::unexpectedPositionalArg);
343        return SLANG_FAIL;
344    }
345
346    return SLANG_OK;
347}
348
349} // namespace renderer_test