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