summaryrefslogtreecommitdiff
path: root/source/slang/slang-spirv-opt.cpp
blob: 786358324e1ae575922f3c581a9deaeb7caaf75f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include "slang-spirv-opt.h"
#include "slang-spirv-val.h"

namespace Slang
{

struct RemoveFileRAII
{
    String fileName;

    RemoveFileRAII(String inFileName)
        :fileName(inFileName)
    {}

    ~RemoveFileRAII()
    {
        File::remove(fileName);
    }
};

SlangResult optimizeSPIRV(const List<uint8_t>& spirv, String& outErr, List<uint8_t>& outSpv)
{
    // Set up our process
    CommandLine commandLine;
    commandLine.m_executableLocation.setName("spirv-opt");
    commandLine.addArg("--eliminate-dead-functions");
    commandLine.addArg("--eliminate-local-single-block");
    commandLine.addArg("--eliminate-local-single-store");
    commandLine.addArg("--eliminate-dead-code-aggressive");

    commandLine.addArg("-o");
    String outFileName;
    File::generateTemporary(UnownedStringSlice("out_spv"), outFileName);
    RemoveFileRAII removeFile(outFileName);

    commandLine.addArg(outFileName);

    RefPtr<Process> p;

    // If we failed to even start the process, then spirv-opt isn't available
    SLANG_RETURN_ON_FAIL(Process::create(commandLine, 0, p));
    const auto in = p->getStream(StdStreamType::In);
    const auto out = p->getStream(StdStreamType::Out);
    const auto err = p->getStream(StdStreamType::ErrorOut);

    List<Byte> outErrData;
    SLANG_RETURN_ON_FAIL(StreamUtil::readAndWrite(in, spirv.getArrayView(), out, outSpv, err, outErrData));

    outSpv.clear();
    File::readAllBytes(outFileName, outSpv);

    SLANG_RETURN_ON_FAIL(p->waitForTermination(3600000));

    outErr = String(
        reinterpret_cast<const char*>(outErrData.begin()),
        reinterpret_cast<const char*>(outErrData.end())
    );

    const auto ret = p->getReturnValue();
    if (ret != 0)
        return SLANG_FAIL;

    return debugValidateSPIRV(outSpv);
}

}