yum-mirror/slang

Making it easier to work with shaders

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

Gangzheng TongConvert gfx unit tests and examples to use slang-rhi (#7577)43d0c2100

master
4.2 KiB147 linesraw
1// main.cpp
2#include "slang-com-ptr.h"
3#include "slang.h"
4
5#include <string>
6using Slang::ComPtr;
7
8#include "core/slang-basic.h"
9#include "examples/example-base/example-base.h"
10#include "gpu-printing.h"
11#include "platform/window.h"
12#include "slang-rhi.h"
13
14#include <slang-rhi/shader-cursor.h>
15
16using namespace rhi;
17
18static const ExampleResources resourceBase("gpu-printing");
19
20ComPtr<slang::ISession> createSlangSession(IDevice* device)
21{
22    ComPtr<slang::ISession> slangSession = device->getSlangSession();
23    return slangSession;
24}
25
26ComPtr<slang::IModule> compileShaderModuleFromFile(
27    slang::ISession* slangSession,
28    char const* filePath)
29{
30    ComPtr<slang::IModule> slangModule;
31    ComPtr<slang::IBlob> diagnosticBlob;
32    Slang::String path = resourceBase.resolveResource(filePath);
33    slangModule = slangSession->loadModule(path.getBuffer(), diagnosticBlob.writeRef());
34    diagnoseIfNeeded(diagnosticBlob);
35
36    return slangModule;
37}
38
39struct ExampleProgram : public TestBase
40{
41    int gWindowWidth = 640;
42    int gWindowHeight = 480;
43
44    ComPtr<IDevice> gDevice;
45
46    ComPtr<slang::ISession> gSlangSession;
47    ComPtr<slang::IModule> gSlangModule;
48    ComPtr<IShaderProgram> gProgram;
49
50    ComPtr<IComputePipeline> gPipelineState;
51
52    Slang::Dictionary<int, std::string> gHashedStrings;
53
54    GPUPrinting gGPUPrinting;
55
56    ComPtr<IShaderProgram> loadComputeProgram(
57        slang::IModule* slangModule,
58        char const* entryPointName)
59    {
60        ComPtr<slang::IEntryPoint> entryPoint;
61        slangModule->findEntryPointByName(entryPointName, entryPoint.writeRef());
62
63        ComPtr<slang::IComponentType> linkedProgram;
64        entryPoint->link(linkedProgram.writeRef());
65
66        if (isTestMode())
67        {
68            printEntrypointHashes(1, 1, linkedProgram);
69        }
70
71        gGPUPrinting.loadStrings(linkedProgram->getLayout());
72
73        ShaderProgramDesc programDesc = {};
74        programDesc.slangGlobalScope = linkedProgram;
75
76        auto shaderProgram = gDevice->createShaderProgram(programDesc);
77
78        return shaderProgram;
79    }
80
81    Result execute(int argc, char* argv[])
82    {
83        parseOption(argc, argv);
84        DeviceDesc deviceDesc;
85        gDevice = getRHI()->createDevice(deviceDesc);
86        if (!gDevice)
87            return SLANG_FAIL;
88
89        Slang::String path = resourceBase.resolveResource("kernels.slang");
90
91        gSlangSession = createSlangSession(gDevice);
92        gSlangModule = compileShaderModuleFromFile(gSlangSession, path.getBuffer());
93        if (!gSlangModule)
94            return SLANG_FAIL;
95
96        gProgram = loadComputeProgram(gSlangModule, "computeMain");
97        if (!gProgram)
98            return SLANG_FAIL;
99
100        ComputePipelineDesc desc;
101        desc.program = gProgram;
102        auto pipelineState = gDevice->createComputePipeline(desc);
103        if (!pipelineState)
104            return SLANG_FAIL;
105
106        gPipelineState = pipelineState;
107
108        size_t printBufferSize = 4 * 1024; // use a small-ish (4KB) buffer for print output
109
110        BufferDesc printBufferDesc = {};
111        printBufferDesc.size = printBufferSize;
112        printBufferDesc.elementSize = sizeof(uint32_t);
113        printBufferDesc.usage =
114            BufferUsage::UnorderedAccess | BufferUsage::CopySource | BufferUsage::CopyDestination;
115        printBufferDesc.memoryType = MemoryType::DeviceLocal;
116        auto printBuffer = gDevice->createBuffer(printBufferDesc);
117
118        auto queue = gDevice->getQueue(QueueType::Graphics);
119        auto commandEncoder = queue->createCommandEncoder();
120        auto computeEncoder = commandEncoder->beginComputePass();
121        auto rootShaderObject = computeEncoder->bindPipeline(gPipelineState);
122        auto cursor = ShaderCursor(rootShaderObject);
123        cursor["gPrintBuffer"].setBinding(printBuffer);
124
125        computeEncoder->dispatchCompute(1, 1, 1);
126
127        computeEncoder->end();
128        queue->submit(commandEncoder->finish());
129
130        ComPtr<ISlangBlob> blob;
131        gDevice->readBuffer(printBuffer, 0, printBufferSize, blob.writeRef());
132
133        gGPUPrinting.processGPUPrintCommands(blob->getBufferPointer(), printBufferSize);
134
135        return SLANG_OK;
136    }
137};
138
139int exampleMain(int argc, char** argv)
140{
141    ExampleProgram app;
142    if (SLANG_FAILED(app.execute(argc, argv)))
143    {
144        return -1;
145    }
146    return 0;
147}