yum-mirror/slang

Making it easier to work with shaders

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

Sami Kiminki (NVIDIA)Add check for NVRTC backend in unit test cudaCodeGenBug (#8611)f4449d937

master
5.0 KiB144 linesraw
1// unit-test-translation-unit-import.cpp
2
3#include "../../source/core/slang-io.h"
4#include "../../source/core/slang-process.h"
5#include "slang-com-ptr.h"
6#include "slang.h"
7#include "unit-test/slang-unit-test.h"
8
9#include <stdio.h>
10#include <stdlib.h>
11
12using namespace Slang;
13
14// Test that the IModule::findAndCheckEntryPoint API supports discovering
15// entrypoints without a [shader] attribute.
16
17SLANG_UNIT_TEST(findAndCheckEntryPoint)
18{
19    // Source for a module that contains an undecorated entrypoint.
20    const char* userSourceBody = R"(
21        float4 fragMain(float4 pos:SV_Position) : SV_Target
22        {
23            return pos;
24        }
25        )";
26
27    auto moduleName = "moduleG" + String(Process::getId());
28    String userSource = "import " + moduleName + ";\n" + userSourceBody;
29    ComPtr<slang::IGlobalSession> globalSession;
30    SLANG_CHECK(slang_createGlobalSession(SLANG_API_VERSION, globalSession.writeRef()) == SLANG_OK);
31    slang::TargetDesc targetDesc = {};
32    targetDesc.format = SLANG_SPIRV;
33    targetDesc.profile = globalSession->findProfile("spirv_1_5");
34    slang::SessionDesc sessionDesc = {};
35    sessionDesc.targetCount = 1;
36    sessionDesc.targets = &targetDesc;
37    ComPtr<slang::ISession> session;
38    SLANG_CHECK(globalSession->createSession(sessionDesc, session.writeRef()) == SLANG_OK);
39
40    ComPtr<slang::IBlob> diagnosticBlob;
41    auto module = session->loadModuleFromSourceString(
42        "m",
43        "m.slang",
44        userSourceBody,
45        diagnosticBlob.writeRef());
46    SLANG_CHECK(module != nullptr);
47
48    ComPtr<slang::IEntryPoint> entryPoint;
49    module->findAndCheckEntryPoint(
50        "fragMain",
51        SLANG_STAGE_FRAGMENT,
52        entryPoint.writeRef(),
53        diagnosticBlob.writeRef());
54    SLANG_CHECK(entryPoint != nullptr);
55
56    ComPtr<slang::IComponentType> compositeProgram;
57    slang::IComponentType* components[] = {module, entryPoint.get()};
58    session->createCompositeComponentType(
59        components,
60        2,
61        compositeProgram.writeRef(),
62        diagnosticBlob.writeRef());
63    SLANG_CHECK(compositeProgram != nullptr);
64
65    ComPtr<slang::IComponentType> linkedProgram;
66    compositeProgram->link(linkedProgram.writeRef(), diagnosticBlob.writeRef());
67    SLANG_CHECK(linkedProgram != nullptr);
68
69    ComPtr<slang::IBlob> code;
70    linkedProgram->getEntryPointCode(0, 0, code.writeRef(), diagnosticBlob.writeRef());
71    SLANG_CHECK(code != nullptr);
72    SLANG_CHECK(code->getBufferSize() != 0);
73}
74
75// This test reproduces issue #6507, where it was noticed that compilation of
76// tests/compute/simple.slang for PTX target generates invalid code.
77// TODO: Remove this when issue #4760 is resolved, because at that point
78// tests/compute/simple.slang should cover the same issue.
79SLANG_UNIT_TEST(cudaCodeGenBug)
80{
81    // We need the CUDA backend for this test
82    if (!SLANG_SUCCEEDED(
83            unitTestContext->slangGlobalSession->checkPassThroughSupport(SLANG_PASS_THROUGH_NVRTC)))
84    {
85        SLANG_IGNORE_TEST;
86    }
87
88    // Source for a module that contains an undecorated entrypoint.
89    const char* userSourceBody = R"(
90        RWStructuredBuffer<float> outputBuffer;
91
92        [numthreads(4, 1, 1)]
93        void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
94        {
95            outputBuffer[dispatchThreadID.x] = float(dispatchThreadID.x);
96        }
97        )";
98
99    auto moduleName = "moduleG" + String(Process::getId());
100    String userSource = "import " + moduleName + ";\n" + userSourceBody;
101    ComPtr<slang::IGlobalSession> globalSession;
102    SLANG_CHECK(slang_createGlobalSession(SLANG_API_VERSION, globalSession.writeRef()) == SLANG_OK);
103    slang::TargetDesc targetDesc = {};
104    targetDesc.format = SLANG_PTX;
105    slang::SessionDesc sessionDesc = {};
106    sessionDesc.targetCount = 1;
107    sessionDesc.targets = &targetDesc;
108    ComPtr<slang::ISession> session;
109    SLANG_CHECK(globalSession->createSession(sessionDesc, session.writeRef()) == SLANG_OK);
110
111    ComPtr<slang::IBlob> diagnosticBlob;
112    auto module = session->loadModuleFromSourceString(
113        "m",
114        "m.slang",
115        userSourceBody,
116        diagnosticBlob.writeRef());
117    SLANG_CHECK(module != nullptr);
118
119    ComPtr<slang::IEntryPoint> entryPoint;
120    module->findAndCheckEntryPoint(
121        "computeMain",
122        SLANG_STAGE_COMPUTE,
123        entryPoint.writeRef(),
124        diagnosticBlob.writeRef());
125    SLANG_CHECK(entryPoint != nullptr);
126
127    ComPtr<slang::IComponentType> compositeProgram;
128    slang::IComponentType* components[] = {module, entryPoint.get()};
129    session->createCompositeComponentType(
130        components,
131        2,
132        compositeProgram.writeRef(),
133        diagnosticBlob.writeRef());
134    SLANG_CHECK(compositeProgram != nullptr);
135
136    ComPtr<slang::IComponentType> linkedProgram;
137    compositeProgram->link(linkedProgram.writeRef(), diagnosticBlob.writeRef());
138    SLANG_CHECK(linkedProgram != nullptr);
139
140    ComPtr<slang::IBlob> code;
141    auto res = linkedProgram->getEntryPointCode(0, 0, code.writeRef(), diagnosticBlob.writeRef());
142    SLANG_CHECK(res == SLANG_OK);
143    SLANG_CHECK(code != nullptr && code->getBufferSize() != 0);
144}