yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Ellie Hermaszewskaformatf65d756bf

master
3.8 KiB111 linesraw
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    //
18    ComPtr<IDownstreamCompiler> cppCompiler;
19    String executablePath;
20
21    MetalDownstreamCompiler(ComPtr<IDownstreamCompiler>& innerCompiler, String path)
22        : DownstreamCompilerBase(innerCompiler->getDesc())
23        , cppCompiler(innerCompiler)
24        , executablePath(path)
25    {
26    }
27
28    virtual SLANG_NO_THROW bool SLANG_MCALL isFileBased() override { return true; }
29
30    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
31    compile(const CompileOptions& options, IArtifact** outArtifact) override
32    {
33        // All compile requests should be routed directly to the inner compiler.
34        return cppCompiler->compile(options, outArtifact);
35    }
36
37    virtual SLANG_NO_THROW bool SLANG_MCALL
38    canConvert(const ArtifactDesc& from, const ArtifactDesc& to) override
39    {
40        // Report that we can convert Metal IR to disassembly.
41        return ArtifactDescUtil::isDisassembly(from, to) &&
42               from.payload == ArtifactPayload::MetalAIR;
43    }
44
45    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
46    convert(IArtifact* from, const ArtifactDesc& to, IArtifact** outArtifact) override
47    {
48        // Use metal-objdump to disassemble the Metal IR.
49
50        ExecutableLocation exeLocation(executablePath, "metal-objdump");
51        CommandLine cmdLine;
52        cmdLine.setExecutableLocation(exeLocation);
53        cmdLine.addArg("--disassemble");
54        ComPtr<IOSFileArtifactRepresentation> srcFile;
55        SLANG_RETURN_ON_FAIL(from->requireFile(IArtifact::Keep::No, srcFile.writeRef()));
56        cmdLine.addArg(String(srcFile->getPath()));
57
58        ExecuteResult exeRes;
59        SLANG_RETURN_ON_FAIL(ProcessUtil::execute(cmdLine, exeRes));
60        auto artifact = ArtifactUtil::createArtifact(to);
61        artifact->addRepresentationUnknown(StringBlob::create(exeRes.standardOutput));
62        *outArtifact = artifact.detach();
63        return SLANG_OK;
64    }
65};
66
67static SlangResult locateMetalCompiler(const String& path, DownstreamCompilerSet* set)
68{
69    ComPtr<IDownstreamCompiler> innerCppCompiler;
70
71    ExecutableLocation metalcLocation = ExecutableLocation(path, "metal");
72
73    String metalSDKPath = path;
74
75#if defined(SLANG_APPLE_FAMILY)
76    // Use xcrun command to find the metal compiler.
77    CommandLine xcrunCmdLine;
78    ExecutableLocation xcrunLocation("xcrun");
79    xcrunCmdLine.setExecutableLocation(xcrunLocation);
80    xcrunCmdLine.addArg("--sdk");
81    xcrunCmdLine.addArg("macosx");
82    xcrunCmdLine.addArg("--find");
83    xcrunCmdLine.addArg("metal");
84    ExecuteResult exeRes;
85    if (SLANG_SUCCEEDED(ProcessUtil::execute(xcrunCmdLine, exeRes)))
86    {
87        String metalPath = exeRes.standardOutput.trim();
88        metalcLocation = ExecutableLocation(ExecutableLocation::Type::Path, metalPath);
89        metalSDKPath = Path::getParentDirectory(metalcLocation.m_pathOrName);
90    }
91#endif
92
93    SLANG_RETURN_ON_FAIL(
94        GCCDownstreamCompilerUtil::createCompiler(metalcLocation, innerCppCompiler));
95
96    ComPtr<IDownstreamCompiler> compiler =
97        ComPtr<IDownstreamCompiler>(new MetalDownstreamCompiler(innerCppCompiler, metalSDKPath));
98    set->addCompiler(compiler);
99    return SLANG_OK;
100}
101
102SlangResult MetalDownstreamCompilerUtil::locateCompilers(
103    const String& path,
104    ISlangSharedLibraryLoader* loader,
105    DownstreamCompilerSet* set)
106{
107    SLANG_UNUSED(loader);
108    return locateMetalCompiler(path, set);
109}
110
111} // namespace Slang