summaryrefslogtreecommitdiffstats
path: root/tools/render-test/slang-support.cpp
blob: 5aafc562e4bab7108813019ed92c969352b78a6e (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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// slang-support.cpp

#define SLANG_INCLUDE_IMPLEMENTATION

#include "slang-support.h"

#include <stdio.h>

namespace renderer_test {

struct SlangShaderCompilerWrapper : public ShaderCompiler
{
    ShaderCompiler*     innerCompiler;
    SlangCompileTarget  target;

    virtual ShaderProgram* compileProgram(ShaderCompileRequest const& request) override
    {
        SlangSession* slangSession = spCreateSession(NULL);
        SlangCompileRequest* slangRequest = spCreateCompileRequest(slangSession);

        spSetCodeGenTarget(slangRequest, target);

        int translationUnitIndex = spAddTranslationUnit(slangRequest, SLANG_SOURCE_LANGUAGE_SLANG, nullptr);

        spAddTranslationUnitSourceString(slangRequest, translationUnitIndex, request.source.path, request.source.text);

        int vertexEntryPoint = spAddTranslationUnitEntryPoint(slangRequest, translationUnitIndex, request.vertexShader.name,   spFindProfile(slangSession, request.vertexShader.profile));
        int fragmentEntryPoint = spAddTranslationUnitEntryPoint(slangRequest, translationUnitIndex, request.fragmentShader.name, spFindProfile(slangSession, request.fragmentShader.profile));

        int compileErr = spCompile(slangRequest);
        if(auto diagnostics = spGetDiagnosticOutput(slangRequest))
        {
            // TODO(tfoley): re-enable when I get a logging solution in place
//            OutputDebugStringA(diagnostics);
            fprintf(stderr, "%s", diagnostics);
        }
        if(compileErr)
        {
            return nullptr;
        }

        char const* translatedCode = spGetTranslationUnitSource(slangRequest, translationUnitIndex);
        char const* vertexCode = spGetEntryPointSource(slangRequest, translationUnitIndex, vertexEntryPoint);
        char const* fragmentCode = spGetEntryPointSource(slangRequest, translationUnitIndex, fragmentEntryPoint);

        ShaderCompileRequest innerRequest = request;
        innerRequest.source.text = translatedCode;
        innerRequest.vertexShader.source.text = vertexCode;
        innerRequest.fragmentShader.source.text = fragmentCode;


        auto result = innerCompiler->compileProgram(innerRequest);

        // We clean up the Slang compilation context and result *after*
        // we have run the downstream compiler, because Slang
        // owns the memory allocation for the generated text, and will
        // free it when we destroy the compilation result.
        spDestroyCompileRequest(slangRequest);
        spDestroySession(slangSession);

        return result;
    }
};

ShaderCompiler* createSlangShaderCompiler(ShaderCompiler* innerCompiler, SlangCompileTarget target)
{
    auto result = new SlangShaderCompilerWrapper();
    result->innerCompiler = innerCompiler;
    result->target = target;

    return result;

}


} // renderer_test

//
// In order to actually use Slang in our application, we need to link in its
// implementation. The easiest way to accomplish this is by directly inlcuding
// the (concatenated) Slang source code into our app.
//

#include <slang.h>