yum-mirror/slang

Making it easier to work with shaders

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

cheneym2Add -dump-module command to slangc (#6638)de6cc94e3

master
8.0 KiB255 linesraw
1#include "slang-module.h"
2
3#include "../util/record-utility.h"
4#include "slang-session.h"
5
6namespace SlangRecord
7{
8ModuleRecorder::ModuleRecorder(
9    SessionRecorder* sessionRecorder,
10    slang::IModule* module,
11    RecordManager* recordManager)
12    : IComponentTypeRecorder(module, recordManager)
13    , m_sessionRecorder(sessionRecorder)
14    , m_actualModule(module)
15    , m_recordManager(recordManager)
16{
17    SLANG_RECORD_ASSERT(m_actualModule != nullptr);
18    SLANG_RECORD_ASSERT(m_recordManager != nullptr);
19
20    m_moduleHandle = reinterpret_cast<uint64_t>(m_actualModule.get());
21    slangRecordLog(LogLevel::Verbose, "%s: %p\n", __PRETTY_FUNCTION__, module);
22}
23
24ISlangUnknown* ModuleRecorder::getInterface(const Guid& guid)
25{
26    if (guid == IModuleRecorder::getTypeGuid())
27        return static_cast<IModuleRecorder*>(this);
28    else
29        return nullptr;
30}
31
32SLANG_NO_THROW slang::DeclReflection* ModuleRecorder::getModuleReflection()
33{
34    // No need to record this call as it is just a query.
35    slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__);
36    slang::DeclReflection* res = (slang::DeclReflection*)m_actualModule->getModuleReflection();
37    return res;
38}
39
40SLANG_NO_THROW SlangResult
41ModuleRecorder::findEntryPointByName(char const* name, slang::IEntryPoint** outEntryPoint)
42{
43    slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__);
44
45    ParameterRecorder* recorder{};
46    {
47        recorder = m_recordManager->beginMethodRecord(
48            ApiCallId::IModule_findEntryPointByName,
49            m_moduleHandle);
50        recorder->recordString(name);
51        recorder = m_recordManager->endMethodRecord();
52    }
53
54    SlangResult res = m_actualModule->findEntryPointByName(name, outEntryPoint);
55
56    {
57        recorder->recordAddress(*outEntryPoint);
58        m_recordManager->apendOutput();
59    }
60
61    if (SLANG_OK == res)
62    {
63        IEntryPointRecorder* entryPointRecord = getEntryPointRecorder(*outEntryPoint);
64        *outEntryPoint = static_cast<slang::IEntryPoint*>(entryPointRecord);
65    }
66    return res;
67}
68
69SLANG_NO_THROW SlangInt32 ModuleRecorder::getDefinedEntryPointCount()
70{
71    // No need to record this call as it is just a query.
72    slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__);
73    SlangInt32 res = m_actualModule->getDefinedEntryPointCount();
74    return res;
75}
76
77SLANG_NO_THROW SlangResult
78ModuleRecorder::getDefinedEntryPoint(SlangInt32 index, slang::IEntryPoint** outEntryPoint)
79{
80    // This call is to find the existing entry point, so it has been created already. Therefore, we
81    // don't create a new one and assert the error if it is not found in our map.
82    slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__);
83
84    ParameterRecorder* recorder{};
85    {
86        recorder = m_recordManager->beginMethodRecord(
87            ApiCallId::IModule_getDefinedEntryPoint,
88            m_moduleHandle);
89        recorder->recordInt32(index);
90        recorder = m_recordManager->endMethodRecord();
91    }
92
93    SlangResult res = m_actualModule->getDefinedEntryPoint(index, outEntryPoint);
94
95    {
96        recorder->recordAddress(*outEntryPoint);
97        m_recordManager->apendOutput();
98    }
99
100    if (*outEntryPoint)
101    {
102        IEntryPointRecorder* entryPointRecord = nullptr;
103        bool ret = m_mapEntryPointToRecord.tryGetValue(*outEntryPoint, entryPointRecord);
104        if (!ret)
105        {
106            SLANG_RECORD_ASSERT(!"Entrypoint not found in mapEntryPointToRecord");
107        }
108        ComPtr<slang::IEntryPoint> result(static_cast<slang::IEntryPoint*>(entryPointRecord));
109        *outEntryPoint = result.detach();
110    }
111    else
112        *outEntryPoint = nullptr;
113
114    return res;
115}
116
117SLANG_NO_THROW SlangResult ModuleRecorder::serialize(ISlangBlob** outSerializedBlob)
118{
119    slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__);
120
121    ParameterRecorder* recorder{};
122    {
123        recorder = m_recordManager->beginMethodRecord(ApiCallId::IModule_serialize, m_moduleHandle);
124        recorder = m_recordManager->endMethodRecord();
125    }
126
127    SlangResult res = m_actualModule->serialize(outSerializedBlob);
128
129    {
130        recorder->recordAddress(*outSerializedBlob);
131        m_recordManager->apendOutput();
132    }
133
134    return res;
135}
136
137SLANG_NO_THROW SlangResult ModuleRecorder::writeToFile(char const* fileName)
138{
139    slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__);
140
141    ParameterRecorder* recorder{};
142    {
143        recorder =
144            m_recordManager->beginMethodRecord(ApiCallId::IModule_writeToFile, m_moduleHandle);
145        recorder->recordString(fileName);
146        recorder = m_recordManager->endMethodRecord();
147    }
148
149    SlangResult res = m_actualModule->writeToFile(fileName);
150    return res;
151}
152
153SLANG_NO_THROW const char* ModuleRecorder::getName()
154{
155    // No need to record this call as it is just a query.
156    slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__);
157    const char* res = m_actualModule->getName();
158    return res;
159}
160
161SLANG_NO_THROW const char* ModuleRecorder::getFilePath()
162{
163    // No need to record this call as it is just a query.
164    slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__);
165    const char* res = m_actualModule->getFilePath();
166    return res;
167}
168
169SLANG_NO_THROW const char* ModuleRecorder::getUniqueIdentity()
170{
171    // No need to record this call as it is just a query.
172    slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__);
173    const char* res = m_actualModule->getUniqueIdentity();
174    return res;
175}
176
177SLANG_NO_THROW SlangResult ModuleRecorder::findAndCheckEntryPoint(
178    char const* name,
179    SlangStage stage,
180    slang::IEntryPoint** outEntryPoint,
181    ISlangBlob** outDiagnostics)
182{
183    slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__);
184
185    ParameterRecorder* recorder{};
186    {
187        recorder = m_recordManager->beginMethodRecord(
188            ApiCallId::IModule_findAndCheckEntryPoint,
189            m_moduleHandle);
190        recorder->recordString(name);
191        recorder->recordEnumValue(stage);
192        recorder = m_recordManager->endMethodRecord();
193    }
194
195    SlangResult res =
196        m_actualModule->findAndCheckEntryPoint(name, stage, outEntryPoint, outDiagnostics);
197
198    {
199        recorder->recordAddress(*outEntryPoint);
200        recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
201        m_recordManager->apendOutput();
202    }
203
204    if (SLANG_OK == res)
205    {
206        IEntryPointRecorder* entryPointRecord = getEntryPointRecorder(*outEntryPoint);
207        *outEntryPoint = static_cast<slang::IEntryPoint*>(entryPointRecord);
208    }
209    return res;
210}
211
212SLANG_NO_THROW SlangInt32 ModuleRecorder::getDependencyFileCount()
213{
214    // No need to record this call as it is just a query.
215    slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__);
216    SlangInt32 res = m_actualModule->getDependencyFileCount();
217    return res;
218}
219
220SLANG_NO_THROW char const* ModuleRecorder::getDependencyFilePath(SlangInt32 index)
221{
222    // No need to record this call as it is just a query.
223    slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__);
224    const char* res = m_actualModule->getDependencyFilePath(index);
225    return res;
226}
227
228IEntryPointRecorder* ModuleRecorder::getEntryPointRecorder(slang::IEntryPoint* entryPoint)
229{
230    IEntryPointRecorder* entryPointRecord = nullptr;
231    bool ret = m_mapEntryPointToRecord.tryGetValue(entryPoint, entryPointRecord);
232    if (!ret)
233    {
234        entryPointRecord = new EntryPointRecorder(m_sessionRecorder, entryPoint, m_recordManager);
235        Slang::ComPtr<IEntryPointRecorder> result(entryPointRecord);
236
237        m_entryPointsRecordAllocation.add(result);
238        m_mapEntryPointToRecord.add(entryPoint, result.detach());
239        return entryPointRecord;
240    }
241    else
242    {
243        Slang::ComPtr<IEntryPointRecorder> result(entryPointRecord);
244        return result.detach();
245    }
246}
247
248SlangResult ModuleRecorder::disassemble(ISlangBlob** outBlob)
249{
250    // No need to record this call as it is just a query.
251    slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__);
252    auto res = m_actualModule->disassemble(outBlob);
253    return res;
254}
255} // namespace SlangRecord