yum-mirror/slang

Making it easier to work with shaders

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

Ellie Hermaszewskaformatf65d756bf

master
6.0 KiB182 linesraw
1#include "vk-pipeline-dump-layer.h"
2
3#include "core/slang-basic.h"
4#include "core/slang-stream.h"
5namespace gfx
6{
7using namespace Slang;
8
9struct PipelineDumpContext
10{
11    Dictionary<VkPipelineLayout, Index> pipelineLayouts;
12    Dictionary<VkShaderModule, Index> shaderModules;
13    Dictionary<VkDescriptorSetLayout, Index> descriptorSets;
14    Dictionary<VkPipeline, Index> computePipelines;
15
16    List<uint8_t> serializedBytes;
17
18    VulkanApi api;
19
20    template<typename T>
21    void writeRaw(T v)
22    {
23        auto startIndex = serializedBytes.getCount();
24        serializedBytes.growToCount(startIndex + sizeof(T));
25        memcpy(serializedBytes.getBuffer() + startIndex, &v, sizeof(T));
26    }
27
28    template<typename T>
29    void writeArray(uint32_t elementCount, const T* data)
30    {
31        writeRaw(elementCount);
32
33        auto startIndex = serializedBytes.getCount();
34        serializedBytes.growToCount(startIndex + sizeof(T) * elementCount);
35        memcpy(serializedBytes.getBuffer() + startIndex, data, sizeof(T) * elementCount);
36    }
37
38    void writeStr(const char* str)
39    {
40        auto len = (uint32_t)strlen(str) + 1;
41        writeRaw(len);
42
43        auto startIndex = serializedBytes.getCount();
44        serializedBytes.growToCount(startIndex + len);
45        memcpy(serializedBytes.getBuffer() + startIndex, str, len - 1);
46        serializedBytes[startIndex + len - 1] = 0;
47    }
48
49    void writePipelineLayout(VkPipelineLayout layout, const VkPipelineLayoutCreateInfo* createInfo)
50    {
51        auto startIndex = serializedBytes.getCount();
52        writeRaw(createInfo->sType);
53        writeRaw(createInfo->flags);
54        writeRaw(createInfo->setLayoutCount);
55        for (uint32_t i = 0; i < createInfo->setLayoutCount; i++)
56            writeRaw(descriptorSets.getValue(createInfo->pSetLayouts[i]));
57        writeArray(createInfo->pushConstantRangeCount, createInfo->pPushConstantRanges);
58        pipelineLayouts[layout] = startIndex;
59    }
60
61    void writeShaderModule(VkShaderModule module, const VkShaderModuleCreateInfo* createInfo)
62    {
63        auto startIndex = serializedBytes.getCount();
64        writeRaw(createInfo->sType);
65        writeRaw(createInfo->flags);
66        writeArray((uint32_t)(createInfo->codeSize / sizeof(uint32_t)), createInfo->pCode);
67        shaderModules[module] = startIndex;
68    }
69
70    void writeDescriptorSetLayout(
71        VkDescriptorSetLayout layout,
72        const VkDescriptorSetLayoutCreateInfo* createInfo)
73    {
74        auto startIndex = serializedBytes.getCount();
75        writeRaw(createInfo->sType);
76        writeRaw(createInfo->flags);
77        writeArray(createInfo->bindingCount, createInfo->pBindings);
78        descriptorSets[layout] = startIndex;
79    }
80
81    void writePipeline(VkPipeline pipeline, const VkComputePipelineCreateInfo* createInfo)
82    {
83        auto startIndex = serializedBytes.getCount();
84        writeRaw(createInfo->sType);
85        writeRaw(createInfo->flags);
86        writeRaw(createInfo->stage.sType);
87        writeRaw(createInfo->stage.flags);
88        writeRaw(createInfo->stage.stage);
89        writeRaw(shaderModules.getValue(createInfo->stage.module));
90        writeStr(createInfo->stage.pName);
91        writeRaw(pipelineLayouts.getValue(createInfo->layout));
92        computePipelines[pipeline] = startIndex;
93    }
94
95    void writeToFile(UnownedStringSlice path)
96    {
97        RefPtr<FileStream> fs = new FileStream();
98        fs->init(path, FileMode::Create);
99        uint32_t pipelineCount = (uint32_t)computePipelines.getCount();
100        fs->write(&pipelineCount, sizeof(uint32_t));
101        for (auto& pair : computePipelines)
102        {
103            fs->write(KeyValueDetail::getValue(&pair), sizeof(Index));
104        }
105        Index blobSize = serializedBytes.getCount();
106        fs->write(&blobSize, sizeof(blobSize));
107        fs->write(serializedBytes.getBuffer(), serializedBytes.getCount());
108        fs->close();
109    }
110};
111
112PipelineDumpContext dumpContext;
113
114VkResult SLANG_MCALL createPipelineLayout(
115    VkDevice device,
116    const VkPipelineLayoutCreateInfo* createInfo,
117    const VkAllocationCallbacks* callbacks,
118    VkPipelineLayout* outLayout)
119{
120    auto result = dumpContext.api.vkCreatePipelineLayout(device, createInfo, callbacks, outLayout);
121    dumpContext.writePipelineLayout(*outLayout, createInfo);
122    return result;
123}
124
125VkResult SLANG_MCALL createComputePipelines(
126    VkDevice device,
127    VkPipelineCache cache,
128    uint32_t createInfoCount,
129    const VkComputePipelineCreateInfo* createInfos,
130    const VkAllocationCallbacks* callbacks,
131    VkPipeline* outPipelines)
132{
133    auto result = dumpContext.api.vkCreateComputePipelines(
134        device,
135        cache,
136        createInfoCount,
137        createInfos,
138        callbacks,
139        outPipelines);
140    for (uint32_t i = 0; i < createInfoCount; i++)
141        dumpContext.writePipeline(outPipelines[i], createInfos + i);
142    return result;
143}
144
145VkResult SLANG_MCALL createShaderModule(
146    VkDevice device,
147    const VkShaderModuleCreateInfo* createInfo,
148    const VkAllocationCallbacks* callbacks,
149    VkShaderModule* outShaderModule)
150{
151    auto result =
152        dumpContext.api.vkCreateShaderModule(device, createInfo, callbacks, outShaderModule);
153    dumpContext.writeShaderModule(*outShaderModule, createInfo);
154    return result;
155}
156
157VkResult SLANG_MCALL createDescriptorSetLayout(
158    VkDevice device,
159    const VkDescriptorSetLayoutCreateInfo* createInfo,
160    const VkAllocationCallbacks* callbacks,
161    VkDescriptorSetLayout* outDescSetLayout)
162{
163    auto result = dumpContext.api
164                      .vkCreateDescriptorSetLayout(device, createInfo, callbacks, outDescSetLayout);
165    dumpContext.writeDescriptorSetLayout(*outDescSetLayout, createInfo);
166    return result;
167}
168
169void installPipelineDumpLayer(VulkanApi& api)
170{
171    dumpContext.api = api;
172    api.vkCreatePipelineLayout = createPipelineLayout;
173    api.vkCreateComputePipelines = createComputePipelines;
174    api.vkCreateShaderModule = createShaderModule;
175    api.vkCreateDescriptorSetLayout = createDescriptorSetLayout;
176}
177
178void writePipelineDump(UnownedStringSlice path)
179{
180    dumpContext.writeToFile(path);
181}
182} // namespace gfx