yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
c39c29bf4
master
1namespace SlangITool 2{ 3static void printCallback (const char * message ,void * userData ) 4{ 5 autostdWriters = (StdWriters * )userData ; 6if (stdWriters ) 7 { 8stdWriters -> getOut ()."%s" ,message ); 9 } 10} 11 12static SlangResult compileAndInterpret ( 13slang ::IGlobalSession * sharedSession , 14StdWriters * stdWriters , 15UnownedStringSlice fileName , 16const char * entryPointName , 17bool disasm , 18int argc , 19const char * const * argv ) 20{ 21 automaybePrintDiagnostic = [& ](const ComPtr < slang ::IBlob >& diagnosticBlob ) 22 { 23if (diagnosticBlob ) 24 { 25const char * diagText = (const char * )diagnosticBlob -> getBufferPointer (); 26stdWriters -> getError ()."%s\n" ,diagText ); 27 } 28 }; 29 30ComPtr < slang ::IGlobalSession > globalSession ; 31SLANG_RETURN_ON_FAIL (slang_createGlobalSession (SLANG_API_VERSION ,globalSession .writeRef ())); 32slang ::TargetDesc targetDesc = {}; 33targetDesc .format = SLANG_HOST_VM ; 34slang ::SessionDesc sessionDesc = {}; 35sessionDesc .targetCount = 1 ; 36sessionDesc .targets = & targetDesc ; 37sessionDesc .compilerOptionEntryCount = 0 ; 38String pathName = Path ::getParentDirectory (fileName ); 39String moduleName = Path ::getFileNameWithoutExt (fileName ); 40const char * searchPaths []= {pathName .getBuffer ()}; 41if (pathName .getLength ()) 42 { 43sessionDesc .searchPathCount = 1 ; 44sessionDesc .searchPaths = searchPaths ; 45 } 46ComPtr < slang ::ISession > session ; 47SLANG_RETURN_ON_FAIL (globalSession -> createSession (sessionDesc ,session .writeRef ())); 48 49ComPtr < slang ::IBlob > diagnosticBlob ; 50 automodule = session -> loadModule (moduleName. getBuffer (), diagnosticBlob. writeRef ()); 51if (!module) 52{ 53maybePrintDiagnostic (diagnosticBlob); 54return SLANG_FAIL ; 55} 56ComPtr < slang::IEntryPoint > entryPoint; 57if ( SLANG_FAILED (module -> findAndCheckEntryPoint ( 58entryPointName, 59SLANG_STAGE_DISPATCH , 60entryPoint. writeRef (), 61diagnosticBlob. writeRef ()))) 62{ 63maybePrintDiagnostic (diagnosticBlob); 64return SLANG_FAIL ; 65} 66 67ComPtr < slang::IComponentType > compositeComponent; 68slang :: IComponentType * components[] = {module, entryPoint. get ()}; 69if ( SLANG_FAILED (session -> createCompositeComponentType ( 70components, 712 , 72compositeComponent. writeRef (), 73diagnosticBlob. writeRef ()))) 74{ 75maybePrintDiagnostic (diagnosticBlob); 76return SLANG_FAIL ; 77} 78 79ComPtr < slang::IComponentType > linkedProgram; 80if ( SLANG_FAILED (compositeComponent -> link (linkedProgram. writeRef (), diagnosticBlob. writeRef ()))) 81{ 82maybePrintDiagnostic (diagnosticBlob); 83return SLANG_FAIL ; 84} 85ComPtr < slang::IBlob > code; 86 87if ( SLANG_FAILED (linkedProgram -> getTargetCode ( 0 , code. writeRef (), diagnosticBlob. writeRef ()))) 88{ 89maybePrintDiagnostic (diagnosticBlob); 90return SLANG_FAIL ; 91} 92 93if (code -> getBufferSize () == 0 ) 94{ 95return SLANG_FAIL ; 96} 97 98if (disasm) 99{ 100ComPtr < slang::IBlob > disasmBlob; 101if ( SLANG_FAILED ( slang_disassembleByteCode (code, disasmBlob. writeRef ()))) 102{ 103maybePrintDiagnostic (diagnosticBlob); 104return SLANG_FAIL ; 105} 106const char * disasmText = ( const char * )disasmBlob -> getBufferPointer (); 107stdWriters -> getOut (). ( "%s\n" , disasmText); 108return SLANG_OK ; 109} 110 111// Create a byte code runner and interpret the code. 112ComPtr < slang::IByteCodeRunner > runner; 113slang :: ByteCodeRunnerDesc runnerDesc = {}; 114SLANG_RETURN_ON_FAIL ( slang_createByteCodeRunner ( & runnerDesc, runner. writeRef ())); 115runner -> setPrintCallback (printCallback, stdWriters); 116 117if ( SLANG_FAILED (runner -> loadModule (code))) 118{ 119runner -> getErrorString (diagnosticBlob. writeRef ()); 120maybePrintDiagnostic (diagnosticBlob); 121} 122auto funcIndex = runner -> findFunctionByName (entryPointName); 123if (funcIndex < 0 ) 124{ 125stdWriters -> getError (). ( "Function '%s' not found in byte code.\n" , entryPointName); 126return SLANG_FAIL ; 127} 128 129if ( SLANG_FAILED (runner -> selectFunctionByIndex (( uint32_t )funcIndex))) 130{ 131runner -> getErrorString (diagnosticBlob. writeRef ()); 132maybePrintDiagnostic (diagnosticBlob); 133return SLANG_FAIL ; 134} 135 136struct Arguments 137{ 138uint32_t argc ; 139const char * const * argv ; 140}; 141Arguments args; 142args. argc = argc; 143args. argv = argv; 144void * arguments = nullptr ; 145size_t argSize = 0 ; 146slang :: ByteCodeFuncInfo funcInfo; 147if ( SLANG_FAILED (runner -> getFunctionInfo (( uint32_t )funcIndex, & funcInfo))) 148{ 149runner -> getErrorString (diagnosticBlob. writeRef ()); 150maybePrintDiagnostic (diagnosticBlob); 151return SLANG_FAIL ; 152} 153if (funcInfo. parameterCount == 2 ) 154{ 155arguments = & args; 156argSize = sizeof (Arguments); 157} 158if ( SLANG_FAILED (runner -> execute (arguments, argSize))) 159{ 160runner -> getErrorString (diagnosticBlob. writeRef ()); 161maybePrintDiagnostic (diagnosticBlob); 162return SLANG_FAIL ; 163} 164return SLANG_OK ; 165} 166 167SlangResult innerMain ( 168StdWriters * stdWriters, 169slang ::IGlobalSession * sharedSession, 170int argc, 171const char * const * argv) 172{ 173StdWriters :: setSingleton (stdWriters); 174 175// Assume we will used the shared session 176ComPtr < slang::IGlobalSession > session (sharedSession); 177 178// The sharedSession always has a pre-loaded core module. 179// This differed test checks if the command line has an option to setup the core module. 180// If so we *don't* use the sharedSession, and create a new session without the core module just 181// for this compilation. 182if (TestToolUtil:: hasDeferredCoreModule ( Index (argc - 1 ), argv + 1 )) 183{ 184SLANG_RETURN_ON_FAIL ( 185slang_createGlobalSessionWithoutCoreModule ( SLANG_API_VERSION , session. writeRef ())); 186} 187 188String entryPointName = toSlice ( "main" ); 189UnownedStringSlice fileName; 190bool disasm = false; 191int innerArgIndex = 0 ; 192if (argc < 2 ) 193{ 194return SLANG_FAIL ; 195} 196for (auto i = 1 ; i < argc; i ++ ) 197{ 198auto arg = UnownedStringSlice ( argv [i]); 199if (arg == "-entry" ) 200{ 201entryPointName = UnownedStringSlice (argv[ ++ i]); 202} 203else if (arg == "-disasm" ) 204{ 205disasm = true; 206} 207else if (arg. startsWith ( "-" )) 208{ 209return SLANG_FAIL ; 210} 211else 212{ 213fileName = arg; 214innerArgIndex = i; 215break ; 216} 217} 218if (!fileName. getLength ()) 219{ 220return SLANG_FAIL ; 221} 222 223auto result = compileAndInterpret ( 224session, 225stdWriters, 226fileName, 227entryPointName. getBuffer (), 228disasm, 229argc - innerArgIndex, 230argv + innerArgIndex); 231 232return result; 233} 234} // namespace SlangITool