yum-mirror/slang

Making it easier to work with shaders

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

Yong HeAdd Slang Byte Code generation and interpreter. (#6896)c39c29bf4

master
3.0 KiB102 linesraw
1// unit-test-slang-vm.cpp
2
3#include "core/slang-memory-file-system.h"
4#include "slang-com-ptr.h"
5#include "slang.h"
6#include "unit-test/slang-unit-test.h"
7
8#include <stdio.h>
9#include <stdlib.h>
10
11using namespace Slang;
12
13SLANG_UNIT_TEST(slangVM)
14{
15    const char* testSource = R"(
16        int one() { return 1; }
17        int sum(int x)
18        {
19            int result = 0;
20            for (int i = 0; i <= x; i++)
21            {
22                result += i;
23            }
24            return result + one();
25        }
26        [shader("dispatch")]
27        int dispatchMain(uniform int2 v, out int c)
28        {
29            int a = v.x;
30            int b = v.y;
31            int tmp = 0;
32            if (a > 0)
33                tmp = a + b;
34            else
35                tmp = b - a;
36            tmp += sum(b);
37            c = tmp;
38            return 100;
39        }
40    )";
41
42    // Create Slang session and compile code.
43    ComPtr<slang::IBlob> code;
44    String disasmText;
45    {
46        ComPtr<slang::IGlobalSession> globalSession;
47        SLANG_CHECK(
48            slang_createGlobalSession(SLANG_API_VERSION, globalSession.writeRef()) == SLANG_OK);
49        slang::TargetDesc targetDesc = {};
50        targetDesc.format = SLANG_HOST_VM;
51        slang::SessionDesc sessionDesc = {};
52        sessionDesc.targetCount = 1;
53        sessionDesc.targets = &targetDesc;
54        sessionDesc.compilerOptionEntryCount = 0;
55
56        ComPtr<slang::ISession> session;
57        SLANG_CHECK(globalSession->createSession(sessionDesc, session.writeRef()) == SLANG_OK);
58
59        ComPtr<slang::IBlob> diagnosticBlob;
60        auto module = session->loadModuleFromSourceString(
61            "test",
62            "test.slang",
63            testSource,
64            diagnosticBlob.writeRef());
65        SLANG_CHECK(module != nullptr);
66
67        ComPtr<slang::IComponentType> linkedProgram;
68        module->link(linkedProgram.writeRef());
69
70
71        linkedProgram->getTargetCode(0, code.writeRef(), diagnosticBlob.writeRef());
72
73        SLANG_CHECK(code->getBufferSize() > 0);
74
75        ComPtr<slang::IBlob> disasmBlob;
76        SLANG_CHECK(slang_disassembleByteCode(code, disasmBlob.writeRef()) == SLANG_OK);
77        disasmText = (const char*)disasmBlob->getBufferPointer();
78        SLANG_CHECK(disasmText.indexOf("ret") != -1);
79    }
80
81    // Create a byte code runner and interpret the code.
82    ComPtr<slang::IByteCodeRunner> runner;
83    slang::ByteCodeRunnerDesc runnerDesc = {};
84    SLANG_CHECK(slang_createByteCodeRunner(&runnerDesc, runner.writeRef()) == SLANG_OK);
85    SLANG_CHECK(runner->loadModule(code) == SLANG_OK);
86    SLANG_CHECK(runner->selectFunctionByIndex(0) == SLANG_OK);
87    struct Params
88    {
89        int a;
90        int b;
91        int* result;
92    };
93    int result = 0;
94    Params params = {1, 2, &result};
95    SLANG_CHECK(runner->execute(&params, sizeof(params)) == SLANG_OK);
96    SLANG_CHECK(result == 7);
97
98    size_t returnValSize = 0;
99    int* returnVal = (int*)runner->getReturnValue(&returnValSize);
100    SLANG_CHECK(returnValSize == sizeof(int));
101    SLANG_CHECK(*returnVal == 100);
102}