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