yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1#include "slang-metal-compiler.h" 2 3#include "slang-artifact-desc-util.h" 4#include "slang-artifact-representation.h" 5#include "slang-artifact-util.h" 6#include "slang-gcc-compiler-util.h" 7 8namespace Slang 9{ 10 11class MetalDownstreamCompiler :public DownstreamCompilerBase 12{ 13public : 14// Because the metal compiler shares the same commandline interface with clang, 15// we will use GccDownstreamCompilerUtil, which implements both gcc and clang, 16// to create the inner compiler and wrap it here. 17// 18ComPtr < IDownstreamCompiler > cppCompiler ; 19String executablePath ; 20 21MetalDownstreamCompiler (ComPtr < IDownstreamCompiler >& innerCompiler ,String path ) 22 :DownstreamCompilerBase (innerCompiler -> getDesc ()) 23 ,cppCompiler (innerCompiler ) 24 ,executablePath (path ) 25 { 26 } 27 28virtual SLANG_NO_THROW bool SLANG_MCALL isFileBased ()override {return true; } 29 30virtual SLANG_NO_THROW SlangResult SLANG_MCALL 31compile (const CompileOptions & options ,IArtifact ** outArtifact )override 32 { 33// All compile requests should be routed directly to the inner compiler. 34return cppCompiler -> compile (options ,outArtifact ); 35 } 36 37virtual SLANG_NO_THROW bool SLANG_MCALL 38canConvert (const ArtifactDesc & from ,const ArtifactDesc & to )override 39 { 40// Report that we can convert Metal IR to disassembly. 41return ArtifactDescUtil ::isDisassembly (from ,to )&& 42from .payload == ArtifactPayload ::MetalAIR ; 43 } 44 45virtual SLANG_NO_THROW SlangResult SLANG_MCALL 46convert (IArtifact * from ,const ArtifactDesc & to ,IArtifact ** outArtifact )override 47 { 48// Use metal-objdump to disassemble the Metal IR. 49 50ExecutableLocation exeLocation (executablePath ,"metal-objdump" ); 51CommandLine cmdLine ; 52cmdLine .setExecutableLocation (exeLocation ); 53cmdLine .addArg ("--disassemble" ); 54ComPtr < IOSFileArtifactRepresentation > srcFile ; 55SLANG_RETURN_ON_FAIL (from -> requireFile (IArtifact ::Keep ::No ,srcFile .writeRef ())); 56cmdLine .addArg (String (srcFile -> getPath ())); 57 58ExecuteResult exeRes ; 59SLANG_RETURN_ON_FAIL (ProcessUtil ::execute (cmdLine ,exeRes )); 60auto artifact = ArtifactUtil ::createArtifact (to ); 61artifact -> addRepresentationUnknown (StringBlob ::create (exeRes .standardOutput )); 62* outArtifact = artifact .detach (); 63return SLANG_OK ; 64 } 65}; 66 67static SlangResult locateMetalCompiler (const String & path ,DownstreamCompilerSet * set ) 68{ 69ComPtr < IDownstreamCompiler > innerCppCompiler ; 70 71ExecutableLocation metalcLocation = ExecutableLocation (path ,"metal" ); 72 73String metalSDKPath = path ; 74 75#if defined(SLANG_APPLE_FAMILY ) 76// Use xcrun command to find the metal compiler. 77CommandLine xcrunCmdLine ; 78ExecutableLocation xcrunLocation ("xcrun" ); 79xcrunCmdLine .setExecutableLocation (xcrunLocation ); 80xcrunCmdLine .addArg ("--sdk" ); 81xcrunCmdLine .addArg ("macosx" ); 82xcrunCmdLine .addArg ("--find" ); 83xcrunCmdLine .addArg ("metal" ); 84ExecuteResult exeRes ; 85if (SLANG_SUCCEEDED (ProcessUtil ::execute (xcrunCmdLine ,exeRes ))) 86 { 87String metalPath = exeRes .standardOutput .trim (); 88metalcLocation = ExecutableLocation (ExecutableLocation ::Type ::Path ,metalPath ); 89metalSDKPath = Path ::getParentDirectory (metalcLocation .m_pathOrName ); 90 } 91#endif 92 93SLANG_RETURN_ON_FAIL ( 94GCCDownstreamCompilerUtil ::createCompiler (metalcLocation ,innerCppCompiler )); 95 96ComPtr < IDownstreamCompiler > compiler = 97ComPtr < IDownstreamCompiler > (new MetalDownstreamCompiler (innerCppCompiler ,metalSDKPath )); 98set -> addCompiler (compiler ); 99return SLANG_OK ; 100} 101 102SlangResult MetalDownstreamCompilerUtil ::locateCompilers ( 103const String & path , 104ISlangSharedLibraryLoader * loader , 105DownstreamCompilerSet * set ) 106{ 107SLANG_UNUSED (loader ); 108return locateMetalCompiler (path ,set ); 109} 110 111}// namespace Slang