yum-mirror/slang

Making it easier to work with shaders

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

jarcherNVFix API changes from separate debugging support (#7397)9c8fab83a

master
5.8 KiB155 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 separate debug info is generated when requested and contains the
15// correct instructions.
16
17SLANG_UNIT_TEST(separateDebug)
18{
19    // Source for a basic slang shader to compile to spirv.
20    const char* userSourceBody = R"(
21        struct TestType
22        {
23            float memberA;
24            float3 memberB;
25            RWStructuredBuffer<float> memberC;
26            float getValue()
27            {
28                return memberA;
29            }
30        }
31        RWStructuredBuffer<float> result;
32        void main()
33        {
34            TestType t;
35            t.memberA = 1.0;
36            t.memberB = float3(1, 2, 3);
37            t.memberC = result;
38            var val = t.getValue();
39            result[0] = val + t.memberB.x;
40        }
41    )";
42    String userSource = userSourceBody;
43    ComPtr<slang::IGlobalSession> globalSession;
44    SLANG_CHECK(slang_createGlobalSession(SLANG_API_VERSION, globalSession.writeRef()) == SLANG_OK);
45
46    // Setup the target descriptor.
47    slang::TargetDesc targetDesc = {};
48    targetDesc.format = SLANG_SPIRV_ASM;
49    targetDesc.profile = globalSession->findProfile("spirv_1_5");
50
51    // Setup the session descriptor.
52    slang::SessionDesc sessionDesc = {};
53    sessionDesc.targetCount = 1;
54    sessionDesc.targets = &targetDesc;
55
56    // Set the compile options.
57    slang::CompilerOptionEntry compilerOptions[2];
58    compilerOptions[0].name = slang::CompilerOptionName::DebugInformation;
59    compilerOptions[0].value.kind = slang::CompilerOptionValueKind::Int;
60    compilerOptions[0].value.intValue0 = 2;
61
62    compilerOptions[1].name = slang::CompilerOptionName::EmitSeparateDebug;
63    compilerOptions[1].value.kind = slang::CompilerOptionValueKind::Int;
64    compilerOptions[1].value.intValue0 = 1;
65
66    sessionDesc.compilerOptionEntries = compilerOptions;
67    sessionDesc.compilerOptionEntryCount = 2;
68
69    ComPtr<slang::ISession> session;
70    SLANG_CHECK(globalSession->createSession(sessionDesc, session.writeRef()) == SLANG_OK);
71
72    // Compile the module.
73    ComPtr<slang::IBlob> diagnosticBlob;
74    auto module = session->loadModuleFromSourceString(
75        "m",
76        "m.slang",
77        userSourceBody,
78        diagnosticBlob.writeRef());
79    SLANG_CHECK(module != nullptr);
80
81    ComPtr<slang::IEntryPoint> entryPoint;
82    module->findAndCheckEntryPoint(
83        "main",
84        SLANG_STAGE_COMPUTE,
85        entryPoint.writeRef(),
86        diagnosticBlob.writeRef());
87    SLANG_CHECK(entryPoint != nullptr);
88
89    ComPtr<slang::IComponentType> compositeProgram;
90    slang::IComponentType* components[] = {module, entryPoint.get()};
91    session->createCompositeComponentType(
92        components,
93        2,
94        compositeProgram.writeRef(),
95        diagnosticBlob.writeRef());
96    SLANG_CHECK(compositeProgram != nullptr);
97
98    ComPtr<slang::IComponentType> linkedProgram;
99    compositeProgram->link(linkedProgram.writeRef(), diagnosticBlob.writeRef());
100    SLANG_CHECK(linkedProgram != nullptr);
101
102    // Use getEntryPointCompileResult to get the base and debug spirv, and metadata
103    // containing the debug build identifier.
104    ComPtr<slang::IBlob> code;
105    ComPtr<slang::IBlob> debugCode;
106    ComPtr<slang::IMetadata> metadata;
107    const char* debugBuildIdentifier = nullptr;
108
109    // IComponentType2 is a separate interface from IComponentType, so we need
110    // to query for it, and then use it to get the results.
111    ComPtr<slang::ICompileResult> compileResult;
112    ComPtr<slang::IComponentType2> linkedProgram2;
113    SLANG_CHECK(
114        linkedProgram->queryInterface(SLANG_IID_PPV_ARGS(linkedProgram2.writeRef())) == SLANG_OK);
115    auto result = linkedProgram2->getEntryPointCompileResult(
116        0,
117        0,
118        compileResult.writeRef(),
119        diagnosticBlob.writeRef());
120    SLANG_CHECK(result == SLANG_OK);
121    SLANG_CHECK(compileResult != nullptr);
122    SLANG_CHECK(compileResult->getItemCount() == 2);
123    SLANG_CHECK(compileResult->getItemData(0, code.writeRef()) == SLANG_OK);
124    SLANG_CHECK(compileResult->getItemData(1, debugCode.writeRef()) == SLANG_OK);
125    SLANG_CHECK(compileResult->getMetadata(metadata.writeRef()) == SLANG_OK);
126
127    debugBuildIdentifier = metadata->getDebugBuildIdentifier();
128    SLANG_CHECK(debugBuildIdentifier != nullptr);
129
130    // Get the data for the stripped SPIRV.
131    // This is already verified by the separate-debug.slang test but we
132    // check it here to again to verify that the API is working.
133    String codeString = static_cast<const char*>(code->getBufferPointer());
134
135    // Verify that the code contains DebugBuildIdentifier instruction
136    // and the correct hash.
137    SLANG_CHECK(codeString.indexOf("DebugBuildIdentifier") != -1);
138    SLANG_CHECK(codeString.indexOf(debugBuildIdentifier) != -1);
139
140    // Verify that it does not contain any other debug instructions.
141    SLANG_CHECK(codeString.indexOf("DebugExpression") == -1);
142    SLANG_CHECK(codeString.indexOf("DebugTypeMember") == -1);
143    SLANG_CHECK(codeString.indexOf("DebugScope") == -1);
144    SLANG_CHECK(codeString.indexOf("DebugLine") == -1);
145
146    // Get the data for the non-stripped debug SPIRV and verify
147    // that it contains the correct debug instructions.
148    String debugCodeString = static_cast<const char*>(debugCode->getBufferPointer());
149    SLANG_CHECK(debugCodeString.indexOf("DebugBuildIdentifier") != -1);
150    SLANG_CHECK(debugCodeString.indexOf(debugBuildIdentifier) != -1);
151    SLANG_CHECK(debugCodeString.indexOf("DebugExpression") != -1);
152    SLANG_CHECK(debugCodeString.indexOf("DebugFunctionDefinition") != -1);
153    SLANG_CHECK(debugCodeString.indexOf("DebugScope") != -1);
154    SLANG_CHECK(debugCodeString.indexOf("DebugLine") != -1);
155}