yum-mirror/slang

Making it easier to work with shaders

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

Anders LeinoAdd backtraces to examples (#5973)5b9931456

master
5.5 KiB181 linesraw
1// main.cpp
2
3#include "slang-com-helper.h"
4#include "slang-com-ptr.h"
5#include "slang.h"
6
7#include <stdio.h>
8
9// This includes a useful small function for setting up the prelude (described more further below).
10#include "../../source/core/slang-test-tool-util.h"
11#include "examples/example-base/example-base.h"
12
13// Slang namespace is used for elements support code (like core) which we use here
14// for ComPtr<> and TestToolUtil
15using namespace Slang;
16
17static const ExampleResources resourceBase("cpu-com-example");
18
19// For the moment we have to explicitly write the Slang COM interface in C++ code. It *MUST* match
20// the interface in the slang source
21// As it stands all interfaces need to derive from ISlangUnknown (or IUnknown).
22class IDoThings : public ISlangUnknown
23{
24public:
25    virtual SLANG_NO_THROW int SLANG_MCALL doThing(int a, int b) = 0;
26    virtual SLANG_NO_THROW int SLANG_MCALL calcHash(const char* in) = 0;
27    virtual SLANG_NO_THROW void SLANG_MCALL printMessage(const char* in) = 0;
28};
29
30static int _calcHash(const char* in)
31{
32    int hash = 0;
33    for (; *in; ++in)
34    {
35        // A very poor hash function
36        hash = hash * 13 + *in;
37    }
38    return hash;
39}
40
41class DoThings : public IDoThings
42{
43public:
44    // We don't need queryInterface for this impl, or ref counting
45    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
46    queryInterface(SlangUUID const& uuid, void** outObject) SLANG_OVERRIDE
47    {
48        return SLANG_E_NOT_IMPLEMENTED;
49    }
50    virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE { return 1; }
51    virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return 1; }
52
53    // IDoThings
54    virtual SLANG_NO_THROW int SLANG_MCALL doThing(int a, int b) SLANG_OVERRIDE
55    {
56        return a + b + 1;
57    }
58    virtual SLANG_NO_THROW int SLANG_MCALL calcHash(const char* in) SLANG_OVERRIDE
59    {
60        return (int)_calcHash(in);
61    }
62    virtual SLANG_NO_THROW void SLANG_MCALL printMessage(const char* in) SLANG_OVERRIDE
63    {
64        printf("%s\n", in);
65    }
66};
67
68static SlangResult _innerMain(int argc, char** argv)
69{
70    // NOTE! This example only works if `slang-llvm` or a C++ compiler that Slang supports is
71    // available.
72
73    // Create the session
74    ComPtr<slang::IGlobalSession> slangSession;
75    slangSession.attach(spCreateSession(NULL));
76
77    // Set up the prelude
78    // NOTE: This isn't strictly necessary, as preludes are embedded in the binary.
79    TestToolUtil::setSessionDefaultPreludeFromExePath(argv[0], slangSession);
80
81    // Create a compile request
82    Slang::ComPtr<slang::ICompileRequest> request;
83    SLANG_ALLOW_DEPRECATED_BEGIN
84    SLANG_RETURN_ON_FAIL(slangSession->createCompileRequest(request.writeRef()));
85    SLANG_ALLOW_DEPRECATED_END
86
87    // We want to compile to 'HOST_CALLABLE' here such that we can execute the Slang code.
88    //
89    // Note that it is possible to use HOST_HOST_CALLABLE, but this currently only works with
90    // 'regular' C++ compilers not with `slang-llvm`.
91    const int targetIndex = request->addCodeGenTarget(SLANG_SHADER_HOST_CALLABLE);
92
93    // Set the target flag to indicate that we want to compile all into a library.
94    request->setTargetFlags(targetIndex, SLANG_TARGET_FLAG_GENERATE_WHOLE_PROGRAM);
95
96    // Add the translation unit
97    const int translationUnitIndex =
98        request->addTranslationUnit(SLANG_SOURCE_LANGUAGE_SLANG, nullptr);
99
100    // Set the source file for the translation unit
101    Slang::String path = resourceBase.resolveResource("shader.slang");
102    request->addTranslationUnitSourceFile(translationUnitIndex, path.getBuffer());
103
104    const SlangResult compileRes = request->compile();
105
106    // Even if there were no errors that forced compilation to fail, the
107    // compiler may have produced "diagnostic" output such as warnings.
108    // We will go ahead and print that output here.
109    //
110    if (auto diagnostics = request->getDiagnosticOutput())
111    {
112        printf("%s", diagnostics);
113    }
114
115    // Get the 'shared library' (note that this doesn't necessarily have to be implemented as a
116    // shared library it's just an interface to executable code).
117    ComPtr<ISlangSharedLibrary> sharedLibrary;
118    SLANG_RETURN_ON_FAIL(request->getTargetHostCallable(0, sharedLibrary.writeRef()));
119
120    DoThings doThings;
121
122    {
123        auto doThingsPtr = (IDoThings**)sharedLibrary->findSymbolAddressByName("globalDoThings");
124        if (!doThingsPtr)
125        {
126            return SLANG_FAIL;
127        }
128        // Set the global interface
129        *doThingsPtr = &doThings;
130    }
131
132    // Test a free function
133    {
134        typedef const char* (*Func)(const char*);
135        Func func = (Func)sharedLibrary->findFuncByName("getString");
136
137        if (!func)
138        {
139            return SLANG_FAIL;
140        }
141
142        String text = "Hello World!";
143        String returnedText = func(text.getBuffer());
144
145        SLANG_ASSERT(text == returnedText);
146    }
147
148    // Test hash
149    {
150        typedef int (*Func)(const char* text);
151        Func func = (Func)sharedLibrary->findFuncByName("calcHash");
152        if (!func)
153        {
154            return SLANG_FAIL;
155        }
156
157        String text("Hello");
158        const int hash = func(text.getBuffer());
159        SLANG_ASSERT(hash == _calcHash(text.getBuffer()));
160    }
161
162    // Test printing
163    {
164        typedef void (*Func)(const char* text);
165
166        Func func = (Func)sharedLibrary->findFuncByName("printMessage");
167
168        if (!func)
169        {
170            return SLANG_FAIL;
171        }
172        func("Hello World!");
173    }
174
175    return SLANG_OK;
176}
177
178int exampleMain(int argc, char** argv)
179{
180    return SLANG_SUCCEEDED(_innerMain(argc, argv)) ? 0 : -1;
181}