yum-mirror/slang

Making it easier to work with shaders

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

Yong HeFix Conditioanl<T, false> fields with a semantic. (#7855)9d47a3529

master
5.6 KiB146 linesraw
1// unit-test-unit-test-conditional-vertex-input.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 the compilation API for compiling an entrypoint that uses `Conditional<T>` to
15// represent conditional vertex attribute input that can be specialized away.
16
17SLANG_UNIT_TEST(conditionalVertexInput)
18{
19    const char* userSourceBody = R"(
20            struct Vertex<bool hasColor> {
21                float3 pos : POSITION;
22                Conditional<float3, hasColor> color : COLOR;
23                float3 normal : NORMAL;
24            }
25
26            extern static const bool vertexHasColor = true;
27
28            [shader("vertex")]
29            float4 vertMain(Vertex<vertexHasColor> o) {
30                if (let color = o.color.get())
31                {
32                    // If `vertexHasColor` is true, we can use `color`.
33                    return float4(o.pos + color + o.normal, 1);
34                }
35                return float4(o.pos + o.normal, 1);
36            }
37        )";
38    const char* userSourceBodyNoColor = R"(export static const bool vertexHasColor = false;)";
39
40    ComPtr<slang::IGlobalSession> globalSession;
41    SLANG_CHECK(slang_createGlobalSession(SLANG_API_VERSION, globalSession.writeRef()) == SLANG_OK);
42    slang::TargetDesc targetDesc = {};
43    targetDesc.format = SLANG_GLSL;
44    slang::SessionDesc sessionDesc = {};
45    sessionDesc.targetCount = 1;
46    sessionDesc.targets = &targetDesc;
47    ComPtr<slang::ISession> session;
48    SLANG_CHECK(globalSession->createSession(sessionDesc, session.writeRef()) == SLANG_OK);
49
50    ComPtr<slang::IBlob> diagnosticBlob;
51    auto module = session->loadModuleFromSourceString(
52        "m",
53        "m.slang",
54        userSourceBody,
55        diagnosticBlob.writeRef());
56    SLANG_CHECK(module != nullptr);
57
58    ComPtr<slang::IEntryPoint> entryPoint;
59    module->findAndCheckEntryPoint(
60        "vertMain",
61        SLANG_STAGE_VERTEX,
62        entryPoint.writeRef(),
63        diagnosticBlob.writeRef());
64
65    // Check the program with `vertexHasColor = true`.
66    {
67        slang::IComponentType* componentTypes[2] = {module, entryPoint.get()};
68        ComPtr<slang::IComponentType> composedProgram;
69        session->createCompositeComponentType(
70            componentTypes,
71            2,
72            composedProgram.writeRef(),
73            diagnosticBlob.writeRef());
74
75        ComPtr<slang::IComponentType> linkedProgram;
76        composedProgram->link(linkedProgram.writeRef(), diagnosticBlob.writeRef());
77
78        auto paramLayout = linkedProgram->getLayout()
79                               ->getEntryPointByIndex(0)
80                               ->getParameterByIndex(0)
81                               ->getTypeLayout();
82
83        // Total number of varying inputs should be 3. (pos, color and normal)
84        SLANG_CHECK(paramLayout->getSize(slang::ParameterCategory::VaryingInput) == 3);
85
86        // Offset of `normal` should be 2.
87        SLANG_CHECK(
88            paramLayout
89                ->getFieldByIndex(2) // `o.normal`
90                ->getOffset(slang::ParameterCategory::VaryingInput) == 2);
91        ComPtr<slang::IBlob> code;
92        SLANG_CHECK(
93            linkedProgram->getEntryPointCode(0, 0, code.writeRef(), diagnosticBlob.writeRef()) ==
94            SLANG_OK);
95        auto codeStr = Slang::UnownedStringSlice((const char*)code->getBufferPointer());
96        SLANG_CHECK(codeStr.indexOf(toSlice("layout(location = 0)")) != -1);
97        SLANG_CHECK(codeStr.indexOf(toSlice("layout(location = 1)")) != -1);
98        SLANG_CHECK(codeStr.indexOf(toSlice("layout(location = 2)")) != -1);
99    }
100
101    // Check the program with `vertexHashColor = false`.
102    {
103        auto configModule = session->loadModuleFromSourceString(
104            "config",
105            "config.slang",
106            userSourceBodyNoColor,
107            diagnosticBlob.writeRef());
108        SLANG_CHECK(module != nullptr);
109
110        slang::IComponentType* componentTypes[3] = {module, entryPoint.get(), configModule};
111        ComPtr<slang::IComponentType> composedProgram;
112        session->createCompositeComponentType(
113            componentTypes,
114            3,
115            composedProgram.writeRef(),
116            diagnosticBlob.writeRef());
117
118        ComPtr<slang::IComponentType> linkedProgram;
119        composedProgram->link(linkedProgram.writeRef(), diagnosticBlob.writeRef());
120
121        auto paramLayout = linkedProgram->getLayout()
122                               ->getEntryPointByIndex(0)
123                               ->getParameterByIndex(0)
124                               ->getTypeLayout();
125
126        // Total number of varying inputs should be 2. (pos and normal)
127        SLANG_CHECK(paramLayout->getSize(slang::ParameterCategory::VaryingInput) == 2);
128
129        // Offset of `normal` should be 1.
130        SLANG_CHECK(
131            paramLayout
132                ->getFieldByIndex(2) // `o.normal`
133                ->getOffset(slang::ParameterCategory::VaryingInput) == 1);
134        ComPtr<slang::IBlob> code;
135        SLANG_CHECK(
136            linkedProgram->getEntryPointCode(0, 0, code.writeRef(), diagnosticBlob.writeRef()) ==
137            SLANG_OK);
138
139        auto codeStr = Slang::UnownedStringSlice((const char*)code->getBufferPointer());
140
141        SLANG_CHECK(codeStr.indexOf(toSlice("layout(location = 0)")) != -1);
142        SLANG_CHECK(codeStr.indexOf(toSlice("layout(location = 1)")) != -1);
143        // Resulting code should not contain `layout(location = 1)` since `color` is not used.
144        SLANG_CHECK(codeStr.indexOf(toSlice("layout(location = 2)")) == -1);
145    }
146}