yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1#include "slang-tint-compiler.h" 2 3#include "../../external/slang-tint-headers/slang-tint.h" 4#include "slang-artifact-associated-impl.h" 5 6namespace Slang 7{ 8 9class TintDownstreamCompiler :public DownstreamCompilerBase 10{ 11 12public : 13// IDownstreamCompiler 14virtual SLANG_NO_THROW SlangResult SLANG_MCALL 15compile (const CompileOptions & options ,IArtifact ** outResult )SLANG_OVERRIDE ; 16 17virtual SLANG_NO_THROW bool SLANG_MCALL 18canConvert (const ArtifactDesc & from ,const ArtifactDesc & to )SLANG_OVERRIDE ; 19 20virtual SLANG_NO_THROW SlangResult SLANG_MCALL 21convert (IArtifact * from ,const ArtifactDesc & to ,IArtifact ** outArtifact )SLANG_OVERRIDE ; 22 23virtual SLANG_NO_THROW bool SLANG_MCALL isFileBased ()SLANG_OVERRIDE {return false; } 24 25virtual SLANG_NO_THROW SlangResult SLANG_MCALL getVersionString (slang::IBlob ** outVersionString ) 26SLANG_OVERRIDE ; 27 28SlangResult compile (IArtifact * const sourceArtifact ,IArtifact ** outArtifact ); 29 30SlangResult init (ISlangSharedLibrary * library ); 31 32protected : 33ComPtr < ISlangSharedLibrary > m_sharedLibrary ; 34 35private : 36tint_CompileFunc m_compile ; 37tint_FreeResultFunc m_freeResult ; 38}; 39 40SlangResult TintDownstreamCompiler ::init (ISlangSharedLibrary * library ) 41{ 42tint_CompileFunc compile = (tint_CompileFunc )library -> findFuncByName ("tint_compile" ); 43if (compile == nullptr ) 44 { 45return SLANG_FAIL ; 46 } 47 48tint_FreeResultFunc freeResult = 49 (tint_FreeResultFunc )library -> findFuncByName ("tint_free_result" ); 50if (freeResult == nullptr ) 51 { 52return SLANG_FAIL ; 53 } 54 55m_sharedLibrary = library ; 56m_desc = Desc (SLANG_PASS_THROUGH_TINT ); 57m_compile = compile ; 58m_freeResult = freeResult ; 59return SLANG_OK ; 60} 61 62SlangResult TintDownstreamCompilerUtil ::locateCompilers ( 63const String & path , 64ISlangSharedLibraryLoader * loader , 65DownstreamCompilerSet * set ) 66{ 67ComPtr < ISlangSharedLibrary > library ; 68SLANG_RETURN_ON_FAIL ( 69DownstreamCompilerUtil ::loadSharedLibrary (path ,loader ,nullptr ,"slang-tint" ,library )); 70SLANG_ASSERT (library ); 71 72ComPtr < IDownstreamCompiler > compiler = 73ComPtr < IDownstreamCompiler > (new TintDownstreamCompiler ()); 74SLANG_RETURN_ON_FAIL (static_cast < TintDownstreamCompiler *> (compiler .get ())-> init (library )); 75 76set -> addCompiler (compiler ); 77return SLANG_OK ; 78} 79 80SlangResult TintDownstreamCompiler ::compile (const CompileOptions & options ,IArtifact ** outArtifact ) 81{ 82IArtifact * sourceArtifact = options .sourceArtifacts [0 ]; 83return compile (sourceArtifact ,outArtifact ); 84} 85 86SlangResult TintDownstreamCompiler ::compile ( 87IArtifact * const sourceArtifact , 88IArtifact ** outArtifact ) 89{ 90tint_CompileRequest req = {}; 91 92if (sourceArtifact == nullptr ) 93return SLANG_FAIL ; 94 95ComPtr < ISlangBlob > sourceBlob ; 96SLANG_RETURN_FALSE_ON_FAIL (sourceArtifact -> loadBlob (ArtifactKeep ::Yes ,sourceBlob .writeRef ())); 97 98String wgslCode ( 99 (char * )sourceBlob -> getBufferPointer (), 100 (char * )sourceBlob -> getBufferPointer ()+ sourceBlob -> getBufferSize ()); 101req .wgslCode = wgslCode .begin (); 102req .wgslCodeLength = wgslCode .getLength (); 103 104tint_CompileResult result = {}; 105SLANG_DEFER (m_freeResult (& result )); 106bool compileSucceeded = m_compile (& req ,& result )== 0 ; 107 108ComPtr < ISlangBlob > spirvBlob = RawBlob ::create (result .buffer ,result .bufferSize ); 109result .buffer = nullptr ; 110 111ComPtr < IArtifact > resultArtifact = 112ArtifactUtil ::createArtifactForCompileTarget (SlangCompileTarget ::SLANG_WGSL_SPIRV ); 113auto diagnostics = ArtifactDiagnostics ::create (); 114diagnostics -> setResult (compileSucceeded ?SLANG_OK :SLANG_FAIL ); 115ArtifactUtil ::addAssociated (resultArtifact ,diagnostics ); 116if (compileSucceeded ) 117 { 118resultArtifact -> addRepresentationUnknown (spirvBlob ); 119 } 120else 121 { 122diagnostics -> setRaw (CharSlice (result .error )); 123diagnostics -> requireErrorDiagnostic (); 124 } 125 126* outArtifact = resultArtifact .detach (); 127return SLANG_OK ; 128} 129 130bool TintDownstreamCompiler ::canConvert (const ArtifactDesc & from ,const ArtifactDesc & to ) 131{ 132return (from .payload == ArtifactPayload ::WGSL )&& (to .payload == ArtifactPayload ::SPIRV ); 133} 134 135SlangResult TintDownstreamCompiler ::convert ( 136IArtifact * from , 137const ArtifactDesc & to , 138IArtifact ** outArtifact ) 139{ 140if (!canConvert (from -> getDesc (),to )) 141return SLANG_FAIL ; 142return compile (from ,outArtifact ); 143} 144 145SlangResult TintDownstreamCompiler ::getVersionString (slang::IBlob ** /* outVersionString */ ) 146{ 147// We just use Tint at whatever version is in our Dawn fork, so nobody should 148// depend on the particular version at the moment. 149return SLANG_FAIL ; 150} 151 152}// namespace Slang