diff options
| author | kaizhangNV <149626564+kaizhangNV@users.noreply.github.com> | 2024-06-20 20:59:33 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-20 20:59:33 -0700 |
| commit | d349fd9e1f65fd32b2f4ea0e38c5084256d0dd04 (patch) | |
| tree | 3e4869c01b041830f06b953abbb835284abcb89f | |
| parent | c3c1cb6776eacdc01ea5bc197b635471960994e4 (diff) | |
Add capture logic to other interfaces. (#4412)
* Add capture logic to other interfaces.
Add capture logics to ISession, IModule, ITypeConformance, IEntryPoint
ICompositeComponentType.
Add few encode methods to encode the array.
Fix some capture logic in global session. We will not need to encode
the null_ptr output before actual actual of the captured APIs.
Previously we used this as a place holder, but it's actually not
necessary, it can be detected if the output is not captured during
replay.
* capture/replay: dump the shader files to disk
Dump the shader files to disk.
Also set a default directory for the capture files.
18 files changed, 1158 insertions, 84 deletions
diff --git a/source/slang-capture-replay/api_callId.h b/source/slang-capture-replay/api_callId.h index 0a96ef4a7..a0fae73a6 100644 --- a/source/slang-capture-replay/api_callId.h +++ b/source/slang-capture-replay/api_callId.h @@ -99,49 +99,53 @@ namespace SlangCapture IModule_getLayout = makeApiCallId(Class_IModule, 0x000B), IModule_getSpecializationParamCount = makeApiCallId(Class_IModule, 0x000C), IModule_getEntryPointCode = makeApiCallId(Class_IModule, 0x000D), - IModule_getResultAsFileSystem = makeApiCallId(Class_IModule, 0x000E), - IModule_getEntryPointHash = makeApiCallId(Class_IModule, 0x000F), - IModule_specialize = makeApiCallId(Class_IModule, 0x0010), - IModule_link = makeApiCallId(Class_IModule, 0x0011), - IModule_getEntryPointHostCallable = makeApiCallId(Class_IModule, 0x0012), - IModule_renameEntryPoint = makeApiCallId(Class_IModule, 0x0013), - IModule_linkWithOptions = makeApiCallId(Class_IModule, 0x0014), + IModule_getTargetCode = makeApiCallId(Class_IModule, 0x000E), + IModule_getResultAsFileSystem = makeApiCallId(Class_IModule, 0x000F), + IModule_getEntryPointHash = makeApiCallId(Class_IModule, 0x0010), + IModule_specialize = makeApiCallId(Class_IModule, 0x0011), + IModule_link = makeApiCallId(Class_IModule, 0x0012), + IModule_getEntryPointHostCallable = makeApiCallId(Class_IModule, 0x0013), + IModule_renameEntryPoint = makeApiCallId(Class_IModule, 0x0014), + IModule_linkWithOptions = makeApiCallId(Class_IModule, 0x0015), IEntryPoint_getSession = makeApiCallId(Class_IEntryPoint, 0x0001), IEntryPoint_getLayout = makeApiCallId(Class_IEntryPoint, 0x0002), IEntryPoint_getSpecializationParamCount = makeApiCallId(Class_IEntryPoint, 0x0003), IEntryPoint_getEntryPointCode = makeApiCallId(Class_IEntryPoint, 0x0004), - IEntryPoint_getResultAsFileSystem = makeApiCallId(Class_IEntryPoint, 0x0005), - IEntryPoint_getEntryPointHash = makeApiCallId(Class_IEntryPoint, 0x0006), - IEntryPoint_specialize = makeApiCallId(Class_IEntryPoint, 0x0007), - IEntryPoint_link = makeApiCallId(Class_IEntryPoint, 0x0008), - IEntryPoint_getEntryPointHostCallable = makeApiCallId(Class_IEntryPoint, 0x0009), - IEntryPoint_renameEntryPoint = makeApiCallId(Class_IEntryPoint, 0x000A), - IEntryPoint_linkWithOptions = makeApiCallId(Class_IEntryPoint, 0x000B), + IEntryPoint_getTargetCode = makeApiCallId(Class_IEntryPoint, 0x0005), + IEntryPoint_getResultAsFileSystem = makeApiCallId(Class_IEntryPoint, 0x0006), + IEntryPoint_getEntryPointHash = makeApiCallId(Class_IEntryPoint, 0x0007), + IEntryPoint_specialize = makeApiCallId(Class_IEntryPoint, 0x0008), + IEntryPoint_link = makeApiCallId(Class_IEntryPoint, 0x0009), + IEntryPoint_getEntryPointHostCallable = makeApiCallId(Class_IEntryPoint, 0x000A), + IEntryPoint_renameEntryPoint = makeApiCallId(Class_IEntryPoint, 0x000B), + IEntryPoint_linkWithOptions = makeApiCallId(Class_IEntryPoint, 0x000C), ICompositeComponentType_getSession = makeApiCallId(Class_ICompositeComponentType, 0x0001), ICompositeComponentType_getLayout = makeApiCallId(Class_ICompositeComponentType, 0x0002), ICompositeComponentType_getSpecializationParamCount = makeApiCallId(Class_ICompositeComponentType, 0x0003), ICompositeComponentType_getEntryPointCode = makeApiCallId(Class_ICompositeComponentType, 0x0004), - ICompositeComponentType_getResultAsFileSystem = makeApiCallId(Class_ICompositeComponentType, 0x0005), - ICompositeComponentType_getEntryPointHash = makeApiCallId(Class_ICompositeComponentType, 0x0006), - ICompositeComponentType_specialize = makeApiCallId(Class_ICompositeComponentType, 0x0007), - ICompositeComponentType_link = makeApiCallId(Class_ICompositeComponentType, 0x0008), - ICompositeComponentType_getEntryPointHostCallable = makeApiCallId(Class_ICompositeComponentType, 0x0009), - ICompositeComponentType_renameEntryPoint = makeApiCallId(Class_ICompositeComponentType, 0x000A), - ICompositeComponentType_linkWithOptions = makeApiCallId(Class_ICompositeComponentType, 0x000B), + ICompositeComponentType_getTargetCode = makeApiCallId(Class_ICompositeComponentType, 0x0005), + ICompositeComponentType_getResultAsFileSystem = makeApiCallId(Class_ICompositeComponentType, 0x0006), + ICompositeComponentType_getEntryPointHash = makeApiCallId(Class_ICompositeComponentType, 0x0007), + ICompositeComponentType_specialize = makeApiCallId(Class_ICompositeComponentType, 0x0008), + ICompositeComponentType_link = makeApiCallId(Class_ICompositeComponentType, 0x0009), + ICompositeComponentType_getEntryPointHostCallable = makeApiCallId(Class_ICompositeComponentType, 0x000A), + ICompositeComponentType_renameEntryPoint = makeApiCallId(Class_ICompositeComponentType, 0x000B), + ICompositeComponentType_linkWithOptions = makeApiCallId(Class_ICompositeComponentType, 0x000C), ITypeConformance_getSession = makeApiCallId(Class_ITypeConformance, 0x0001), ITypeConformance_getLayout = makeApiCallId(Class_ITypeConformance, 0x0002), ITypeConformance_getSpecializationParamCount = makeApiCallId(Class_ITypeConformance, 0x0003), ITypeConformance_getEntryPointCode = makeApiCallId(Class_ITypeConformance, 0x0004), - ITypeConformance_getResultAsFileSystem = makeApiCallId(Class_ITypeConformance, 0x0005), - ITypeConformance_getEntryPointHash = makeApiCallId(Class_ITypeConformance, 0x0006), - ITypeConformance_specialize = makeApiCallId(Class_ITypeConformance, 0x0007), - ITypeConformance_link = makeApiCallId(Class_ITypeConformance, 0x0008), - ITypeConformance_getEntryPointHostCallable = makeApiCallId(Class_ITypeConformance, 0x0009), - ITypeConformance_renameEntryPoint = makeApiCallId(Class_ITypeConformance, 0x000A), - ITypeConformance_linkWithOptions = makeApiCallId(Class_ITypeConformance, 0x000B) + ITypeConformance_getTargetCode = makeApiCallId(Class_ITypeConformance, 0x0005), + ITypeConformance_getResultAsFileSystem = makeApiCallId(Class_ITypeConformance, 0x0006), + ITypeConformance_getEntryPointHash = makeApiCallId(Class_ITypeConformance, 0x0007), + ITypeConformance_specialize = makeApiCallId(Class_ITypeConformance, 0x0008), + ITypeConformance_link = makeApiCallId(Class_ITypeConformance, 0x0009), + ITypeConformance_getEntryPointHostCallable = makeApiCallId(Class_ITypeConformance, 0x000A), + ITypeConformance_renameEntryPoint = makeApiCallId(Class_ITypeConformance, 0x000B), + ITypeConformance_linkWithOptions = makeApiCallId(Class_ITypeConformance, 0x000C) }; } #endif diff --git a/source/slang-capture-replay/capture-manager.cpp b/source/slang-capture-replay/capture-manager.cpp index 2d04b077a..5ab40d93c 100644 --- a/source/slang-capture-replay/capture-manager.cpp +++ b/source/slang-capture-replay/capture-manager.cpp @@ -2,6 +2,7 @@ #include <string> #include <sstream> #include <thread> +#include "capture_utility.h" #include "capture-manager.h" namespace SlangCapture @@ -11,7 +12,21 @@ namespace SlangCapture { std::stringstream ss; ss << "gs-"<< globalSessionHandle <<"-t-"<<std::this_thread::get_id() << ".cap"; - m_fileStream = std::make_unique<FileOutputStream>(ss.str()); + + m_captureFileDirectory = m_captureFileDirectory / "slang-capture"; + + if (!std::filesystem::exists(m_captureFileDirectory)) + { + std::error_code ec; + if (!std::filesystem::create_directory(m_captureFileDirectory, ec)) + { + slangCaptureLog(LogLevel::Error, "Fail to create directory: %s, error (%d): %s\n", + m_captureFileDirectory.string().c_str(), ec.value(), ec.message().c_str()); + } + } + + std::filesystem::path captureFilePath = m_captureFileDirectory / ss.str(); + m_fileStream = std::make_unique<FileOutputStream>(captureFilePath.string()); } void CaptureManager::clearWithHeader(const ApiCallId& callId, uint64_t handleId) diff --git a/source/slang-capture-replay/capture-manager.h b/source/slang-capture-replay/capture-manager.h index 721986066..ca06d70a8 100644 --- a/source/slang-capture-replay/capture-manager.h +++ b/source/slang-capture-replay/capture-manager.h @@ -1,8 +1,10 @@ #ifndef CAPTURE_MANAGER_H #define CAPTURE_MANAGER_H +#include <filesystem> #include "parameter-encoder.h" #include "api_callId.h" + namespace SlangCapture { class CaptureManager @@ -17,6 +19,9 @@ namespace SlangCapture // endMethodCaptureAppendOutput is an optional call that can be used to append output to // the end of the capture. It has to start with a FunctionTailer void endMethodCaptureAppendOutput(); + + std::filesystem::path const& getCaptureFileDirectory() const { return m_captureFileDirectory; } + private: void clearWithHeader(const ApiCallId& callId, uint64_t handleId); void clearWithTailer(); @@ -38,6 +43,7 @@ namespace SlangCapture MemoryStream m_memoryStream; std::unique_ptr<FileOutputStream> m_fileStream; + std::filesystem::path m_captureFileDirectory = std::filesystem::current_path(); ParameterEncoder m_encoder; }; } // namespace SlangCapture diff --git a/source/slang-capture-replay/parameter-encoder.cpp b/source/slang-capture-replay/parameter-encoder.cpp index 8c77884a9..c73a97b08 100644 --- a/source/slang-capture-replay/parameter-encoder.cpp +++ b/source/slang-capture-replay/parameter-encoder.cpp @@ -73,6 +73,12 @@ namespace SlangCapture } } + void ParameterEncoder::encodeStruct(slang::SpecializationArg const& specializationArg) + { + encodeEnumValue(specializationArg.kind); + encodeAddress(specializationArg.type); + } + void ParameterEncoder::encodePointer(const void* value, bool omitData, size_t size) { encodeAddress(value); @@ -114,13 +120,4 @@ namespace SlangCapture m_stream->write(value, size); } } - - void ParameterEncoder::encodeStringArray(const char* const* strArray, size_t count) - { - encodeUint64(count); - for (size_t i = 0; i < count; i++) - { - encodeString(strArray[i]); - } - } } diff --git a/source/slang-capture-replay/parameter-encoder.h b/source/slang-capture-replay/parameter-encoder.h index 2b7abab45..d5a6ea510 100644 --- a/source/slang-capture-replay/parameter-encoder.h +++ b/source/slang-capture-replay/parameter-encoder.h @@ -29,7 +29,6 @@ namespace SlangCapture void encodeEnumValue(T value) { encodeValue(static_cast<uint32_t>(value)); } void encodeString(const char* value); - void encodeStringArray(const char* const* strArray, size_t count); void encodePointer(const void* value, bool omitData = false, size_t size = 0); void encodePointer(ISlangBlob* blob); void encodeAddress(const void* value) { encodeValue(reinterpret_cast<uint64_t>(value)); } @@ -39,6 +38,43 @@ namespace SlangCapture void encodeStruct(slang::CompilerOptionEntry const& entry); void encodeStruct(slang::CompilerOptionValue const& value); void encodeStruct(slang::TargetDesc const& targetDesc); + void encodeStruct(slang::SpecializationArg const& specializationArg); + + template <typename T> + void encodeValueArray(const T* array, size_t count) + { + for (size_t i = 0; i < count; ++i) + { + encodeValue(array[i]); + } + } + + void encodeStringArray(const char* const* array, size_t count) + { + for (size_t i = 0; i < count; ++i) + { + encodeString(array[i]); + } + } + + template <typename T> + void encodeStructArray(T const* array, size_t count) + { + for (size_t i = 0; i < count; ++i) + { + encodeStruct(array[i]); + } + } + + template <typename T> + void encodeAddressArray(T* const* array, size_t count) + { + for (size_t i = 0; i < count; ++i) + { + encodeAddress(array[i]); + } + } + private: template <typename T> diff --git a/source/slang-capture-replay/slang-composite-component-type.cpp b/source/slang-capture-replay/slang-composite-component-type.cpp index f18f4b9cb..a0699e27a 100644 --- a/source/slang-capture-replay/slang-composite-component-type.cpp +++ b/source/slang-capture-replay/slang-composite-component-type.cpp @@ -3,10 +3,15 @@ namespace SlangCapture { - CompositeComponentTypeCapture::CompositeComponentTypeCapture(slang::IComponentType* componentType) - : m_actualCompositeComponentType(componentType) + CompositeComponentTypeCapture::CompositeComponentTypeCapture( + slang::IComponentType* componentType, CaptureManager* captureManager) + : m_actualCompositeComponentType(componentType), + m_captureManager(captureManager) { SLANG_CAPTURE_ASSERT(m_actualCompositeComponentType != nullptr); + SLANG_CAPTURE_ASSERT(m_captureManager != nullptr); + + m_compositeComponentHandle = reinterpret_cast<uint64_t>(m_actualCompositeComponentType.get()); slangCaptureLog(LogLevel::Verbose, "%s: %p\n", __PRETTY_FUNCTION__, componentType); } @@ -27,7 +32,20 @@ namespace SlangCapture SLANG_NO_THROW slang::ISession* CompositeComponentTypeCapture::getSession() { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ICompositeComponentType_getSession, m_compositeComponentHandle); + encoder = m_captureManager->endMethodCapture(); + } + slang::ISession* res = m_actualCompositeComponentType->getSession(); + + { + encoder->encodeAddress(res); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -36,12 +54,28 @@ namespace SlangCapture slang::IBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); - slang::ProgramLayout* res = m_actualCompositeComponentType->getLayout(targetIndex, outDiagnostics); - return res; + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ICompositeComponentType_getLayout, m_compositeComponentHandle); + encoder->encodeInt64(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + + slang::ProgramLayout* programLayout = m_actualCompositeComponentType->getLayout(targetIndex, outDiagnostics); + + { + encoder->encodeAddress(*outDiagnostics); + encoder->encodeAddress(programLayout); + m_captureManager->endMethodCaptureAppendOutput(); + } + + return programLayout; } SLANG_NO_THROW SlangInt CompositeComponentTypeCapture::getSpecializationParamCount() { + // No need to capture this call as it is just a query. slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); SlangInt res = m_actualCompositeComponentType->getSpecializationParamCount(); return res; @@ -54,7 +88,23 @@ namespace SlangCapture slang::IBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ICompositeComponentType_getEntryPointCode, m_compositeComponentHandle); + encoder->encodeInt64(entryPointIndex); + encoder->encodeInt64(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualCompositeComponentType->getEntryPointCode(entryPointIndex, targetIndex, outCode, outDiagnostics); + + { + encoder->encodeAddress(*outCode); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -64,7 +114,22 @@ namespace SlangCapture slang::IBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ICompositeComponentType_getTargetCode, m_compositeComponentHandle); + encoder->encodeInt64(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualCompositeComponentType->getTargetCode(targetIndex, outCode, outDiagnostics); + + { + encoder->encodeAddress(*outCode); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -74,7 +139,22 @@ namespace SlangCapture ISlangMutableFileSystem** outFileSystem) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ICompositeComponentType_getResultAsFileSystem, m_compositeComponentHandle); + encoder->encodeInt64(entryPointIndex); + encoder->encodeInt64(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualCompositeComponentType->getResultAsFileSystem(entryPointIndex, targetIndex, outFileSystem); + + { + encoder->encodeAddress(*outFileSystem); + } + + // TODO: We might need to wrap the file system object. return res; } @@ -84,7 +164,21 @@ namespace SlangCapture slang::IBlob** outHash) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ICompositeComponentType_getEntryPointHash, m_compositeComponentHandle); + encoder->encodeInt64(entryPointIndex); + encoder->encodeInt64(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + m_actualCompositeComponentType->getEntryPointHash(entryPointIndex, targetIndex, outHash); + + { + encoder->encodeAddress(*outHash); + m_captureManager->endMethodCaptureAppendOutput(); + } } SLANG_NO_THROW SlangResult CompositeComponentTypeCapture::specialize( @@ -94,7 +188,23 @@ namespace SlangCapture ISlangBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ICompositeComponentType_specialize, m_compositeComponentHandle); + encoder->encodeInt64(specializationArgCount); + encoder->encodeStructArray(specializationArgs, specializationArgCount); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualCompositeComponentType->specialize(specializationArgs, specializationArgCount, outSpecializedComponentType, outDiagnostics); + + { + encoder->encodeAddress(*outSpecializedComponentType); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -103,7 +213,21 @@ namespace SlangCapture ISlangBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ICompositeComponentType_link, m_compositeComponentHandle); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualCompositeComponentType->link(outLinkedComponentType, outDiagnostics); + + { + encoder->encodeAddress(*outLinkedComponentType); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -114,7 +238,23 @@ namespace SlangCapture slang::IBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ICompositeComponentType_getEntryPointHostCallable, m_compositeComponentHandle); + encoder->encodeInt32(entryPointIndex); + encoder->encodeInt32(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualCompositeComponentType->getEntryPointHostCallable(entryPointIndex, targetIndex, outSharedLibrary, outDiagnostics); + + { + encoder->encodeAddress(*outSharedLibrary); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -122,7 +262,21 @@ namespace SlangCapture const char* newName, IComponentType** outEntryPoint) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ICompositeComponentType_renameEntryPoint, m_compositeComponentHandle); + encoder->encodeString(newName); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualCompositeComponentType->renameEntryPoint(newName, outEntryPoint); + + { + encoder->encodeAddress(*outEntryPoint); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -133,7 +287,23 @@ namespace SlangCapture ISlangBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ICompositeComponentType_linkWithOptions, m_compositeComponentHandle); + encoder->encodeUint32(compilerOptionEntryCount); + encoder->encodeStructArray(compilerOptionEntries, compilerOptionEntryCount); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualCompositeComponentType->linkWithOptions(outLinkedComponentType, compilerOptionEntryCount, compilerOptionEntries, outDiagnostics); + + { + encoder->encodeAddress(*outLinkedComponentType); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } } diff --git a/source/slang-capture-replay/slang-composite-component-type.h b/source/slang-capture-replay/slang-composite-component-type.h index 17b11f2c1..adafe5b11 100644 --- a/source/slang-capture-replay/slang-composite-component-type.h +++ b/source/slang-capture-replay/slang-composite-component-type.h @@ -7,6 +7,7 @@ #include "../core/slang-smart-pointer.h" #include "../core/slang-dictionary.h" #include "../slang/slang-compiler.h" +#include "capture-manager.h" namespace SlangCapture { @@ -17,7 +18,7 @@ namespace SlangCapture SLANG_REF_OBJECT_IUNKNOWN_ALL ISlangUnknown* getInterface(const Guid& guid); - explicit CompositeComponentTypeCapture(slang::IComponentType* componentType); + explicit CompositeComponentTypeCapture(slang::IComponentType* componentType, CaptureManager* captureManager); ~CompositeComponentTypeCapture(); // Interfaces for `IComponentType` @@ -67,6 +68,9 @@ namespace SlangCapture slang::IComponentType* getActualCompositeComponentType() const { return m_actualCompositeComponentType; } private: Slang::ComPtr<slang::IComponentType> m_actualCompositeComponentType; + uint64_t m_compositeComponentHandle = 0; + CaptureManager* m_captureManager = nullptr; + }; } #endif // SLANG_COMPOSITE_COMPONENT_TYPE_H diff --git a/source/slang-capture-replay/slang-entrypoint.cpp b/source/slang-capture-replay/slang-entrypoint.cpp index 1a975bacb..c8ce7a663 100644 --- a/source/slang-capture-replay/slang-entrypoint.cpp +++ b/source/slang-capture-replay/slang-entrypoint.cpp @@ -3,10 +3,14 @@ namespace SlangCapture { - EntryPointCapture::EntryPointCapture(slang::IEntryPoint* entryPoint) - : m_actualEntryPoint(entryPoint) + EntryPointCapture::EntryPointCapture(slang::IEntryPoint* entryPoint, CaptureManager* captureManager) + : m_actualEntryPoint(entryPoint), + m_captureManager(captureManager) { SLANG_CAPTURE_ASSERT(m_actualEntryPoint != nullptr); + SLANG_CAPTURE_ASSERT(m_captureManager != nullptr); + + m_entryPointHandle = reinterpret_cast<uint64_t>(m_actualEntryPoint.get()); slangCaptureLog(LogLevel::Verbose, "%s: %p\n", __PRETTY_FUNCTION__, entryPoint); } @@ -26,8 +30,21 @@ namespace SlangCapture SLANG_NO_THROW slang::ISession* EntryPointCapture::getSession() { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); - slang::ISession* res = m_actualEntryPoint->getSession(); - return res; + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IEntryPoint_getSession, m_entryPointHandle); + encoder = m_captureManager->endMethodCapture(); + } + + slang::ISession* session = m_actualEntryPoint->getSession(); + + { + encoder->encodeAddress(session); + m_captureManager->endMethodCaptureAppendOutput(); + } + + return session; } SLANG_NO_THROW slang::ProgramLayout* EntryPointCapture::getLayout( @@ -35,12 +52,28 @@ namespace SlangCapture slang::IBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); - slang::ProgramLayout* res = m_actualEntryPoint->getLayout(targetIndex, outDiagnostics); - return res; + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IEntryPoint_getLayout, m_entryPointHandle); + encoder->encodeInt64(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + + slang::ProgramLayout* programLayout = m_actualEntryPoint->getLayout(targetIndex, outDiagnostics); + + { + encoder->encodeAddress(*outDiagnostics); + encoder->encodeAddress(programLayout); + m_captureManager->endMethodCaptureAppendOutput(); + } + + return programLayout; } SLANG_NO_THROW SlangInt EntryPointCapture::getSpecializationParamCount() { + // No need to capture this call as it is just a query. slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); SlangInt res = m_actualEntryPoint->getSpecializationParamCount(); return res; @@ -53,7 +86,23 @@ namespace SlangCapture slang::IBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IEntryPoint_getEntryPointCode, m_entryPointHandle); + encoder->encodeInt64(entryPointIndex); + encoder->encodeInt64(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualEntryPoint->getEntryPointCode(entryPointIndex, targetIndex, outCode, outDiagnostics); + + { + encoder->encodeAddress(*outCode); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -63,7 +112,22 @@ namespace SlangCapture slang::IBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IEntryPoint_getTargetCode, m_entryPointHandle); + encoder->encodeInt64(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualEntryPoint->getTargetCode(targetIndex, outCode, outDiagnostics); + + { + encoder->encodeAddress(*outCode); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -73,7 +137,22 @@ namespace SlangCapture ISlangMutableFileSystem** outFileSystem) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IEntryPoint_getResultAsFileSystem, m_entryPointHandle); + encoder->encodeInt64(entryPointIndex); + encoder->encodeInt64(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualEntryPoint->getResultAsFileSystem(entryPointIndex, targetIndex, outFileSystem); + + { + encoder->encodeAddress(*outFileSystem); + } + + // TODO: We might need to wrap the file system object. return res; } @@ -83,7 +162,21 @@ namespace SlangCapture slang::IBlob** outHash) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IEntryPoint_getEntryPointHash, m_entryPointHandle); + encoder->encodeInt64(entryPointIndex); + encoder->encodeInt64(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + m_actualEntryPoint->getEntryPointHash(entryPointIndex, targetIndex, outHash); + + { + encoder->encodeAddress(*outHash); + m_captureManager->endMethodCaptureAppendOutput(); + } } SLANG_NO_THROW SlangResult EntryPointCapture::specialize( @@ -93,7 +186,23 @@ namespace SlangCapture ISlangBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IEntryPoint_specialize, m_entryPointHandle); + encoder->encodeInt64(specializationArgCount); + encoder->encodeStructArray(specializationArgs, specializationArgCount); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualEntryPoint->specialize(specializationArgs, specializationArgCount, outSpecializedComponentType, outDiagnostics); + + { + encoder->encodeAddress(*outSpecializedComponentType); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -102,7 +211,21 @@ namespace SlangCapture ISlangBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IEntryPoint_link, m_entryPointHandle); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualEntryPoint->link(outLinkedComponentType, outDiagnostics); + + { + encoder->encodeAddress(*outLinkedComponentType); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -113,7 +236,23 @@ namespace SlangCapture slang::IBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IEntryPoint_getEntryPointHostCallable, m_entryPointHandle); + encoder->encodeInt32(entryPointIndex); + encoder->encodeInt32(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualEntryPoint->getEntryPointHostCallable(entryPointIndex, targetIndex, outSharedLibrary, outDiagnostics); + + { + encoder->encodeAddress(*outSharedLibrary); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -121,7 +260,21 @@ namespace SlangCapture const char* newName, IComponentType** outEntryPoint) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IEntryPoint_renameEntryPoint, m_entryPointHandle); + encoder->encodeString(newName); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualEntryPoint->renameEntryPoint(newName, outEntryPoint); + + { + encoder->encodeAddress(*outEntryPoint); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -132,7 +285,23 @@ namespace SlangCapture ISlangBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IEntryPoint_linkWithOptions, m_entryPointHandle); + encoder->encodeUint32(compilerOptionEntryCount); + encoder->encodeStructArray(compilerOptionEntries, compilerOptionEntryCount); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualEntryPoint->linkWithOptions(outLinkedComponentType, compilerOptionEntryCount, compilerOptionEntries, outDiagnostics); + + { + encoder->encodeAddress(*outLinkedComponentType); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } } diff --git a/source/slang-capture-replay/slang-entrypoint.h b/source/slang-capture-replay/slang-entrypoint.h index 98501284b..87b3cc430 100644 --- a/source/slang-capture-replay/slang-entrypoint.h +++ b/source/slang-capture-replay/slang-entrypoint.h @@ -7,6 +7,7 @@ #include "../core/slang-smart-pointer.h" #include "../core/slang-dictionary.h" #include "../slang/slang-compiler.h" +#include "capture-manager.h" namespace SlangCapture { @@ -19,7 +20,7 @@ namespace SlangCapture SLANG_REF_OBJECT_IUNKNOWN_ALL ISlangUnknown* getInterface(const Guid& guid); - explicit EntryPointCapture(slang::IEntryPoint* entryPoint); + explicit EntryPointCapture(slang::IEntryPoint* entryPoint, CaptureManager* captureManager); ~EntryPointCapture(); // Interfaces for `IComponentType` @@ -68,7 +69,9 @@ namespace SlangCapture slang::IEntryPoint* getActualEntryPoint() const { return m_actualEntryPoint; } private: - Slang::ComPtr<slang::IEntryPoint> m_actualEntryPoint; + Slang::ComPtr<slang::IEntryPoint> m_actualEntryPoint; + uint64_t m_entryPointHandle = 0; + CaptureManager* m_captureManager = nullptr; }; } #endif // SLANG_ENTRY_POINT_H diff --git a/source/slang-capture-replay/slang-filesystem.cpp b/source/slang-capture-replay/slang-filesystem.cpp index fac6cf66e..0de17162e 100644 --- a/source/slang-capture-replay/slang-filesystem.cpp +++ b/source/slang-capture-replay/slang-filesystem.cpp @@ -1,12 +1,17 @@ #include "slang-filesystem.h" #include "capture_utility.h" +#include "output-stream.h" namespace SlangCapture { - FileSystemCapture::FileSystemCapture(ISlangFileSystemExt* fileSystem) - : m_actualFileSystem(fileSystem) + // We don't actually need to capture the methods of ISlangFileSystemExt, we just want to capture the file content + // and save them into disk. + FileSystemCapture::FileSystemCapture(ISlangFileSystemExt* fileSystem, CaptureManager* captureManager) + : m_actualFileSystem(fileSystem), + m_captureManager(captureManager) { SLANG_CAPTURE_ASSERT(m_actualFileSystem); + SLANG_CAPTURE_ASSERT(m_captureManager); slangCaptureLog(LogLevel::Verbose, "%s: %p\n", __PRETTY_FUNCTION__, m_actualFileSystem.get()); } @@ -27,12 +32,31 @@ namespace SlangCapture return nullptr; } + // TODO: There could be a potential issue that could not be able to dump the generated file content correctly. + // Details: https://github.com/shader-slang/slang/issues/4423. SLANG_NO_THROW SlangResult FileSystemCapture::loadFile( char const* path, ISlangBlob** outBlob) { slangCaptureLog(LogLevel::Verbose, "%p: %s, :%s\n", m_actualFileSystem.get(), __PRETTY_FUNCTION__, path); SlangResult res = m_actualFileSystem->loadFile(path, outBlob); + + // Since the loadFile method could be implemented by client, we can't guarantee the result is always as expected, + // we will check every thing to make sure we won't crash at writing file. + // + // We can only dump the file content after this 'loadFile' call, no matter this call crashes or file is not + // found, we can't save the file anyway, so we don't need to pay special care to the crash recovery. We will + // know something wrong with the loadFile call if we can't find the file in the capture directory. + if ((res == SLANG_OK) && (*outBlob != nullptr) && ((*outBlob)->getBufferSize() != 0)) + { + std::filesystem::path filePath = m_captureManager->getCaptureFileDirectory(); + filePath = filePath / path; + + FileOutputStream fileStream(filePath.string().c_str()); + + fileStream.write((*outBlob)->getBufferPointer(), (*outBlob)->getBufferSize()); + fileStream.flush(); + } return res; } diff --git a/source/slang-capture-replay/slang-filesystem.h b/source/slang-capture-replay/slang-filesystem.h index 1d0d8be3e..f4435c994 100644 --- a/source/slang-capture-replay/slang-filesystem.h +++ b/source/slang-capture-replay/slang-filesystem.h @@ -4,6 +4,7 @@ #include "../core/slang-com-object.h" #include "../../slang-com-helper.h" #include "../../slang-com-ptr.h" +#include "capture-manager.h" namespace SlangCapture { @@ -16,7 +17,7 @@ namespace SlangCapture class FileSystemCapture : public RefObject, public ISlangFileSystemExt { public: - explicit FileSystemCapture(ISlangFileSystemExt* fileSystem); + explicit FileSystemCapture(ISlangFileSystemExt* fileSystem, CaptureManager* captureManager); ~FileSystemCapture(); // ISlangUnknown @@ -61,7 +62,8 @@ namespace SlangCapture virtual SLANG_NO_THROW OSPathKind SLANG_MCALL getOSPathKind() override; private: - Slang::ComPtr<ISlangFileSystemExt> m_actualFileSystem; + Slang::ComPtr<ISlangFileSystemExt> m_actualFileSystem; + CaptureManager* m_captureManager = nullptr; }; } diff --git a/source/slang-capture-replay/slang-global-session.cpp b/source/slang-capture-replay/slang-global-session.cpp index b90d7611d..b8dfd7d40 100644 --- a/source/slang-capture-replay/slang-global-session.cpp +++ b/source/slang-capture-replay/slang-global-session.cpp @@ -46,7 +46,6 @@ namespace SlangCapture { encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_createSession, m_globalSessionHandle); encoder->encodeStruct(desc); - encoder->encodeAddress(nullptr); encoder = m_captureManager->endMethodCapture(); } @@ -63,12 +62,12 @@ namespace SlangCapture // the Linkage will set to user provided file system or slang default file system. // We need to reset it to our capture file system Slang::Linkage* linkage = static_cast<Linkage*>(actualSession); - FileSystemCapture* fileSystemCapture = new FileSystemCapture(linkage->getFileSystemExt()); + FileSystemCapture* fileSystemCapture = new FileSystemCapture(linkage->getFileSystemExt(), m_captureManager.get()); Slang::ComPtr<FileSystemCapture> resultFileSystemCapture(fileSystemCapture); linkage->setFileSystem(resultFileSystemCapture.detach()); - SessionCapture* sessionCapture = new SessionCapture(actualSession); + SessionCapture* sessionCapture = new SessionCapture(actualSession, m_captureManager.get()); Slang::ComPtr<SessionCapture> result(sessionCapture); *outSession = result.detach(); } @@ -129,7 +128,6 @@ namespace SlangCapture { encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_getDownstreamCompilerPrelude, m_globalSessionHandle); encoder->encodeEnumValue(inPassThrough); - encoder->encodeAddress(nullptr); encoder = m_captureManager->endMethodCapture(); } @@ -204,7 +202,6 @@ namespace SlangCapture { encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_getLanguagePrelude, m_globalSessionHandle); encoder->encodeEnumValue(inSourceLanguage); - encoder->encodeAddress(nullptr); encoder = m_captureManager->endMethodCapture(); } @@ -223,7 +220,6 @@ namespace SlangCapture ParameterEncoder* encoder {}; { encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_createCompileRequest, m_globalSessionHandle); - encoder->encodeAddress(nullptr); encoder = m_captureManager->endMethodCapture(); } @@ -267,13 +263,14 @@ namespace SlangCapture ParameterEncoder* encoder {}; { encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_getSharedLibraryLoader, m_globalSessionHandle); - encoder->encodeAddress(nullptr); + encoder = m_captureManager->endMethodCapture(); } ISlangSharedLibraryLoader* loader = m_actualGlobalSession->getSharedLibraryLoader(); { encoder->encodeAddress(loader); + m_captureManager->endMethodCaptureAppendOutput(); } return loader; } @@ -302,6 +299,7 @@ namespace SlangCapture { encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_compileStdLib, m_globalSessionHandle); encoder->encodeEnumValue(flags); + m_captureManager->endMethodCapture(); } SlangResult res = m_actualGlobalSession->compileStdLib(flags); @@ -331,11 +329,15 @@ namespace SlangCapture { encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_saveStdLib, m_globalSessionHandle); encoder->encodeEnumValue(archiveType); - encoder->encodeAddress(outBlob); - m_captureManager->endMethodCapture(); + encoder = m_captureManager->endMethodCapture(); } SlangResult res = m_actualGlobalSession->saveStdLib(archiveType, outBlob); + + { + encoder->encodeAddress(*outBlob); + m_captureManager->endMethodCaptureAppendOutput(); + } return res; } @@ -410,6 +412,7 @@ namespace SlangCapture { encoder->encodeStruct(*outSessionDesc); encoder->encodeAddress(*outAllocation); + m_captureManager->endMethodCaptureAppendOutput(); } return res; } diff --git a/source/slang-capture-replay/slang-module.cpp b/source/slang-capture-replay/slang-module.cpp index 55743dd78..0b5ed47f1 100644 --- a/source/slang-capture-replay/slang-module.cpp +++ b/source/slang-capture-replay/slang-module.cpp @@ -3,10 +3,14 @@ namespace SlangCapture { - ModuleCapture::ModuleCapture(slang::IModule* module) - : m_actualModule(module) + ModuleCapture::ModuleCapture(slang::IModule* module, CaptureManager* captureManager) + : m_actualModule(module), + m_captureManager(captureManager) { SLANG_CAPTURE_ASSERT(m_actualModule != nullptr); + SLANG_CAPTURE_ASSERT(m_captureManager != nullptr); + + m_moduleHandle = reinterpret_cast<uint64_t>(m_actualModule.get()); slangCaptureLog(LogLevel::Verbose, "%s: %p\n", __PRETTY_FUNCTION__, module); } @@ -29,8 +33,20 @@ namespace SlangCapture { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IModule_findEntryPointByName, m_moduleHandle); + encoder->encodeString(name); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualModule->findEntryPointByName(name, outEntryPoint); + { + encoder->encodeAddress(*outEntryPoint); + m_captureManager->endMethodCaptureAppendOutput(); + } + if (SLANG_OK == res) { EntryPointCapture* entryPointCapture = getEntryPointCapture(*outEntryPoint); @@ -41,6 +57,7 @@ namespace SlangCapture SLANG_NO_THROW SlangInt32 ModuleCapture::getDefinedEntryPointCount() { + // No need to capture this call as it is just a query. slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); SlangInt32 res = m_actualModule->getDefinedEntryPointCount(); return res; @@ -51,8 +68,21 @@ namespace SlangCapture // This call is to find the existing entry point, so it has been created already. Therefore, we don't create a new one // and assert the error if it is not found in our map. slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IModule_getDefinedEntryPoint, m_moduleHandle); + encoder->encodeInt32(index); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualModule->getDefinedEntryPoint(index, outEntryPoint); + { + encoder->encodeAddress(*outEntryPoint); + m_captureManager->endMethodCaptureAppendOutput(); + } + if (*outEntryPoint) { EntryPointCapture* entryPointCapture = m_mapEntryPointToCapture.tryGetValue(*outEntryPoint); @@ -71,19 +101,41 @@ namespace SlangCapture SLANG_NO_THROW SlangResult ModuleCapture::serialize(ISlangBlob** outSerializedBlob) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IModule_serialize, m_moduleHandle); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualModule->serialize(outSerializedBlob); + + { + encoder->encodeAddress(*outSerializedBlob); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } SLANG_NO_THROW SlangResult ModuleCapture::writeToFile(char const* fileName) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IModule_writeToFile, m_moduleHandle); + encoder->encodeString(fileName); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualModule->writeToFile(fileName); return res; } SLANG_NO_THROW const char* ModuleCapture::getName() { + // No need to capture this call as it is just a query. slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); const char* res = m_actualModule->getName(); return res; @@ -91,6 +143,7 @@ namespace SlangCapture SLANG_NO_THROW const char* ModuleCapture::getFilePath() { + // No need to capture this call as it is just a query. slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); const char* res = m_actualModule->getFilePath(); return res; @@ -98,6 +151,7 @@ namespace SlangCapture SLANG_NO_THROW const char* ModuleCapture::getUniqueIdentity() { + // No need to capture this call as it is just a query. slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); const char* res = m_actualModule->getUniqueIdentity(); return res; @@ -111,8 +165,22 @@ namespace SlangCapture { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IModule_findAndCheckEntryPoint, m_moduleHandle); + encoder->encodeString(name); + encoder->encodeEnumValue(stage); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualModule->findAndCheckEntryPoint(name, stage, outEntryPoint, outDiagnostics); + { + encoder->encodeAddress(*outEntryPoint); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + if (SLANG_OK == res) { EntryPointCapture* entryPointCapture = getEntryPointCapture(*outEntryPoint); @@ -124,7 +192,20 @@ namespace SlangCapture SLANG_NO_THROW slang::ISession* ModuleCapture::getSession() { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IModule_getSession, m_moduleHandle); + encoder = m_captureManager->endMethodCapture(); + } + slang::ISession* session = m_actualModule->getSession(); + + { + encoder->encodeAddress(session); + m_captureManager->endMethodCaptureAppendOutput(); + } + return session; } @@ -133,12 +214,28 @@ namespace SlangCapture slang::IBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IModule_getLayout, m_moduleHandle); + encoder->encodeInt64(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + slang::ProgramLayout* programLayout = m_actualModule->getLayout(targetIndex, outDiagnostics); + + { + encoder->encodeAddress(*outDiagnostics); + encoder->encodeAddress(programLayout); + m_captureManager->endMethodCaptureAppendOutput(); + } + return programLayout; } SLANG_NO_THROW SlangInt ModuleCapture::getSpecializationParamCount() { + // No need to capture this call as it is just a query. slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); SlangInt res = m_actualModule->getSpecializationParamCount(); return res; @@ -151,7 +248,23 @@ namespace SlangCapture slang::IBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IModule_getEntryPointCode, m_moduleHandle); + encoder->encodeInt64(entryPointIndex); + encoder->encodeInt64(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualModule->getEntryPointCode(entryPointIndex, targetIndex, outCode, outDiagnostics); + + { + encoder->encodeAddress(*outCode); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -161,7 +274,22 @@ namespace SlangCapture slang::IBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IModule_getTargetCode, m_moduleHandle); + encoder->encodeInt64(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualModule->getTargetCode(targetIndex, outCode, outDiagnostics); + + { + encoder->encodeAddress(*outCode); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -171,7 +299,22 @@ namespace SlangCapture ISlangMutableFileSystem** outFileSystem) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IModule_getResultAsFileSystem, m_moduleHandle); + encoder->encodeInt64(entryPointIndex); + encoder->encodeInt64(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualModule->getResultAsFileSystem(entryPointIndex, targetIndex, outFileSystem); + + { + encoder->encodeAddress(*outFileSystem); + } + + // TODO: We might need to wrap the file system object. return res; } @@ -181,7 +324,21 @@ namespace SlangCapture slang::IBlob** outHash) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IModule_getEntryPointHash, m_moduleHandle); + encoder->encodeInt64(entryPointIndex); + encoder->encodeInt64(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + m_actualModule->getEntryPointHash(entryPointIndex, targetIndex, outHash); + + { + encoder->encodeAddress(*outHash); + m_captureManager->endMethodCaptureAppendOutput(); + } } SLANG_NO_THROW SlangResult ModuleCapture::specialize( @@ -191,7 +348,23 @@ namespace SlangCapture ISlangBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IModule_specialize, m_moduleHandle); + encoder->encodeInt64(specializationArgCount); + encoder->encodeStructArray(specializationArgs, specializationArgCount); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualModule->specialize(specializationArgs, specializationArgCount, outSpecializedComponentType, outDiagnostics); + + { + encoder->encodeAddress(*outSpecializedComponentType); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -200,7 +373,21 @@ namespace SlangCapture ISlangBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IModule_link, m_moduleHandle); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualModule->link(outLinkedComponentType, outDiagnostics); + + { + encoder->encodeAddress(*outLinkedComponentType); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -211,7 +398,23 @@ namespace SlangCapture slang::IBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IModule_getEntryPointHostCallable, m_moduleHandle); + encoder->encodeInt32(entryPointIndex); + encoder->encodeInt32(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualModule->getEntryPointHostCallable(entryPointIndex, targetIndex, outSharedLibrary, outDiagnostics); + + { + encoder->encodeAddress(*outSharedLibrary); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -219,7 +422,21 @@ namespace SlangCapture const char* newName, IComponentType** outEntryPoint) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IModule_renameEntryPoint, m_moduleHandle); + encoder->encodeString(newName); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualModule->renameEntryPoint(newName, outEntryPoint); + + { + encoder->encodeAddress(*outEntryPoint); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -230,7 +447,23 @@ namespace SlangCapture ISlangBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::IModule_linkWithOptions, m_moduleHandle); + encoder->encodeUint32(compilerOptionEntryCount); + encoder->encodeStructArray(compilerOptionEntries, compilerOptionEntryCount); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualModule->linkWithOptions(outLinkedComponentType, compilerOptionEntryCount, compilerOptionEntries, outDiagnostics); + + { + encoder->encodeAddress(*outLinkedComponentType); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -240,7 +473,7 @@ namespace SlangCapture entryPointCapture = m_mapEntryPointToCapture.tryGetValue(entryPoint); if (!entryPointCapture) { - entryPointCapture = new EntryPointCapture(entryPoint); + entryPointCapture = new EntryPointCapture(entryPoint, m_captureManager); Slang::ComPtr<EntryPointCapture> result(entryPointCapture); m_mapEntryPointToCapture.add(entryPoint, *result.detach()); } diff --git a/source/slang-capture-replay/slang-module.h b/source/slang-capture-replay/slang-module.h index 5350bc066..dd19a0b71 100644 --- a/source/slang-capture-replay/slang-module.h +++ b/source/slang-capture-replay/slang-module.h @@ -7,6 +7,7 @@ #include "../core/slang-smart-pointer.h" #include "../slang/slang-compiler.h" #include "slang-entrypoint.h" +#include "capture-manager.h" namespace SlangCapture { @@ -19,7 +20,7 @@ namespace SlangCapture SLANG_REF_OBJECT_IUNKNOWN_ALL ISlangUnknown* getInterface(const Guid& guid); - explicit ModuleCapture(slang::IModule* module); + explicit ModuleCapture(slang::IModule* module, CaptureManager* captureManager); ~ModuleCapture(); // Interfaces for `IModule` @@ -84,6 +85,8 @@ namespace SlangCapture private: EntryPointCapture* getEntryPointCapture(slang::IEntryPoint* entryPoint); Slang::ComPtr<slang::IModule> m_actualModule; + uint64_t m_moduleHandle = 0; + CaptureManager* m_captureManager = nullptr; // `IEntryPoint` can only be created from 'IModule', so we need to capture it in // this class, and create a map such that we don't create new `EntryPointCapture` diff --git a/source/slang-capture-replay/slang-session.cpp b/source/slang-capture-replay/slang-session.cpp index 5cf029629..ee9fd9549 100644 --- a/source/slang-capture-replay/slang-session.cpp +++ b/source/slang-capture-replay/slang-session.cpp @@ -7,10 +7,13 @@ namespace SlangCapture { - SessionCapture::SessionCapture(slang::ISession* session) - : m_actualSession(session) + SessionCapture::SessionCapture(slang::ISession* session, CaptureManager* captureManager) + : m_actualSession(session), + m_captureManager(captureManager) { SLANG_CAPTURE_ASSERT(m_actualSession); + SLANG_CAPTURE_ASSERT(m_captureManager); + m_sessionHandle = reinterpret_cast<uint64_t>(m_actualSession.get()); slangCaptureLog(LogLevel::Verbose, "%s: %p\n", "SessionCapture create:", session); } @@ -29,6 +32,7 @@ namespace SlangCapture SLANG_NO_THROW slang::IGlobalSession* SessionCapture::getGlobalSession() { + // No need to capture this function. slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); slang::IGlobalSession* pGlobalSession = m_actualSession->getGlobalSession(); return pGlobalSession; @@ -39,7 +43,22 @@ namespace SlangCapture slang::IBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ISession_loadModule, m_sessionHandle); + encoder->encodeString(moduleName); + encoder = m_captureManager->endMethodCapture(); + } + slang::IModule* pModule = m_actualSession->loadModule(moduleName, outDiagnostics); + + { + encoder->encodeAddress(*outDiagnostics); + encoder->encodeAddress(pModule); + m_captureManager->endMethodCaptureAppendOutput(); + } + ModuleCapture* pModuleCapture = getModuleCapture(pModule); return static_cast<slang::IModule*>(pModuleCapture); } @@ -51,7 +70,24 @@ namespace SlangCapture slang::IBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ISession_loadModuleFromIRBlob, m_sessionHandle); + encoder->encodeString(moduleName); + encoder->encodeString(path); + encoder->encodePointer(source); + encoder = m_captureManager->endMethodCapture(); + } + slang::IModule* pModule = m_actualSession->loadModuleFromIRBlob(moduleName, path, source, outDiagnostics); + + { + encoder->encodeAddress(*outDiagnostics); + encoder->encodeAddress(pModule); + m_captureManager->endMethodCaptureAppendOutput(); + } + ModuleCapture* pModuleCapture = getModuleCapture(pModule); return static_cast<slang::IModule*>(pModuleCapture); } @@ -63,7 +99,24 @@ namespace SlangCapture slang::IBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ISession_loadModuleFromSource, m_sessionHandle); + encoder->encodeString(moduleName); + encoder->encodeString(path); + encoder->encodePointer(source); + encoder = m_captureManager->endMethodCapture(); + } + slang::IModule* pModule = m_actualSession->loadModuleFromSource(moduleName, path, source, outDiagnostics); + + { + encoder->encodeAddress(*outDiagnostics); + encoder->encodeAddress(pModule); + m_captureManager->endMethodCaptureAppendOutput(); + } + ModuleCapture* pModuleCapture = getModuleCapture(pModule); return static_cast<slang::IModule*>(pModuleCapture); } @@ -75,7 +128,25 @@ namespace SlangCapture slang::IBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ISession_loadModuleFromSourceString, m_sessionHandle); + encoder->encodeString(moduleName); + encoder->encodeString(path); + encoder->encodeString(string); + encoder = m_captureManager->endMethodCapture(); + } + slang::IModule* pModule = m_actualSession->loadModuleFromSourceString(moduleName, path, string, outDiagnostics); + + { + // TODO: Not sure if we need to capture the diagnostics blob. + encoder->encodeAddress(*outDiagnostics); + encoder->encodeAddress(pModule); + m_captureManager->endMethodCaptureAppendOutput(); + } + ModuleCapture* pModuleCapture = getModuleCapture(pModule); return static_cast<slang::IModule*>(pModuleCapture); } @@ -96,12 +167,26 @@ namespace SlangCapture SLANG_CAPTURE_ASSERT(!"Failed to get actual component types"); } + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ISession_createCompositeComponentType, m_sessionHandle); + encoder->encodeAddressArray(componentTypeList.getBuffer(), componentTypeCount); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult result = m_actualSession->createCompositeComponentType( componentTypeList.getBuffer(), componentTypeCount, outCompositeComponentType, outDiagnostics); + { + encoder->encodeAddress(*outCompositeComponentType); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + if (SLANG_OK == result) { - CompositeComponentTypeCapture* compositeComponentTypeCapture = new CompositeComponentTypeCapture(*outCompositeComponentType); + CompositeComponentTypeCapture* compositeComponentTypeCapture = + new CompositeComponentTypeCapture(*outCompositeComponentType, m_captureManager); Slang::ComPtr<CompositeComponentTypeCapture> resultCapture(compositeComponentTypeCapture); *outCompositeComponentType = resultCapture.detach(); } @@ -116,7 +201,23 @@ namespace SlangCapture ISlangBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ISession_specializeType, m_sessionHandle); + encoder->encodeAddress(type); + encoder->encodeStructArray(specializationArgs, specializationArgCount); + encoder = m_captureManager->endMethodCapture(); + } + slang::TypeReflection* pTypeReflection = m_actualSession->specializeType(type, specializationArgs, specializationArgCount, outDiagnostics); + + { + encoder->encodeAddress(*outDiagnostics); + encoder->encodeAddress(pTypeReflection); + m_captureManager->endMethodCaptureAppendOutput(); + } + return pTypeReflection; } @@ -127,7 +228,24 @@ namespace SlangCapture ISlangBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ISession_getTypeLayout, m_sessionHandle); + encoder->encodeAddress(type); + encoder->encodeInt64(targetIndex); + encoder->encodeEnumValue(rules); + encoder = m_captureManager->endMethodCapture(); + } + slang::TypeLayoutReflection* pTypeLayoutReflection = m_actualSession->getTypeLayout(type, targetIndex, rules, outDiagnostics); + + { + encoder->encodeAddress(*outDiagnostics); + encoder->encodeAddress(pTypeLayoutReflection); + m_captureManager->endMethodCaptureAppendOutput(); + } + return pTypeLayoutReflection; } @@ -137,14 +255,43 @@ namespace SlangCapture ISlangBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ISession_getContainerType, m_sessionHandle); + encoder->encodeAddress(elementType); + encoder->encodeEnumValue(containerType); + encoder = m_captureManager->endMethodCapture(); + } + slang::TypeReflection* pTypeReflection = m_actualSession->getContainerType(elementType, containerType, outDiagnostics); + + { + encoder->encodeAddress(*outDiagnostics); + encoder->encodeAddress(pTypeReflection); + m_captureManager->endMethodCaptureAppendOutput(); + } + return pTypeReflection; } SLANG_NO_THROW slang::TypeReflection* SessionCapture::getDynamicType() { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ISession_getDynamicType, m_sessionHandle); + encoder = m_captureManager->endMethodCapture(); + } + slang::TypeReflection* pTypeReflection = m_actualSession->getDynamicType(); + + { + encoder->encodeAddress(pTypeReflection); + m_captureManager->endMethodCaptureAppendOutput(); + } + return pTypeReflection; } @@ -153,7 +300,21 @@ namespace SlangCapture ISlangBlob** outNameBlob) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ISession_getTypeRTTIMangledName, m_sessionHandle); + encoder->encodeAddress(type); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult result = m_actualSession->getTypeRTTIMangledName(type, outNameBlob); + + { + encoder->encodeAddress(outNameBlob); + m_captureManager->endMethodCaptureAppendOutput(); + } + return result; } @@ -163,7 +324,22 @@ namespace SlangCapture ISlangBlob** outNameBlob) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ISession_getTypeConformanceWitnessMangledName, m_sessionHandle); + encoder->encodeAddress(type); + encoder->encodeAddress(interfaceType); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult result = m_actualSession->getTypeConformanceWitnessMangledName(type, interfaceType, outNameBlob); + + { + encoder->encodeAddress(outNameBlob); + m_captureManager->endMethodCaptureAppendOutput(); + } + return result; } @@ -173,7 +349,18 @@ namespace SlangCapture uint32_t* outId) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ISession_getTypeConformanceWitnessSequentialID, m_sessionHandle); + encoder->encodeAddress(type); + encoder->encodeAddress(interfaceType); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult result = m_actualSession->getTypeConformanceWitnessSequentialID(type, interfaceType, outId); + + // No need to capture outId, it's not slang allocation return result; } @@ -186,11 +373,26 @@ namespace SlangCapture { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ISession_createTypeConformanceComponentType, m_sessionHandle); + encoder->encodeAddress(type); + encoder->encodeAddress(interfaceType); + encoder->encodeInt64(conformanceIdOverride); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult result = m_actualSession->createTypeConformanceComponentType(type, interfaceType, outConformance, conformanceIdOverride, outDiagnostics); + { + encoder->encodeAddress(*outConformance); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + if (SLANG_OK != result) { - TypeConformanceCapture* conformanceCapture = new TypeConformanceCapture(*outConformance); + TypeConformanceCapture* conformanceCapture = new TypeConformanceCapture(*outConformance, m_captureManager); Slang::ComPtr<TypeConformanceCapture> resultCapture(conformanceCapture); *outConformance = resultCapture.detach(); } @@ -202,12 +404,26 @@ namespace SlangCapture SlangCompileRequest** outCompileRequest) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ISession_createCompileRequest, m_sessionHandle); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult result = m_actualSession->createCompileRequest(outCompileRequest); + + { + encoder->encodeAddress(*outCompileRequest); + m_captureManager->endMethodCaptureAppendOutput(); + } + return result; } SLANG_NO_THROW SlangInt SessionCapture::getLoadedModuleCount() { + // No need to capture this function, it's just a query. slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); SlangInt count = m_actualSession->getLoadedModuleCount(); return count; @@ -216,8 +432,21 @@ namespace SlangCapture SLANG_NO_THROW slang::IModule* SessionCapture::getLoadedModule(SlangInt index) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ISession_getLoadedModule, m_sessionHandle); + encoder->encodeInt64(index); + encoder = m_captureManager->endMethodCapture(); + } + slang::IModule* pModule = m_actualSession->getLoadedModule(index); + { + encoder->encodeAddress(pModule); + m_captureManager->endMethodCaptureAppendOutput(); + } + if (pModule) { ModuleCapture* moduleCapture = m_mapModuleToCapture.tryGetValue(pModule); @@ -233,6 +462,7 @@ namespace SlangCapture SLANG_NO_THROW bool SessionCapture::isBinaryModuleUpToDate(const char* modulePath, slang::IBlob* binaryModuleBlob) { + // No need to capture this function, it's a query function and doesn't impact slang internal state. slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); bool result = m_actualSession->isBinaryModuleUpToDate(modulePath, binaryModuleBlob); return result; @@ -244,7 +474,7 @@ namespace SlangCapture moduleCapture = m_mapModuleToCapture.tryGetValue(module); if (!moduleCapture) { - moduleCapture = new ModuleCapture(module); + moduleCapture = new ModuleCapture(module, m_captureManager); Slang::ComPtr<ModuleCapture> result(moduleCapture); m_mapModuleToCapture.add(module, *result.detach()); } diff --git a/source/slang-capture-replay/slang-session.h b/source/slang-capture-replay/slang-session.h index f099108b0..161500172 100644 --- a/source/slang-capture-replay/slang-session.h +++ b/source/slang-capture-replay/slang-session.h @@ -8,6 +8,7 @@ #include "../core/slang-dictionary.h" #include "../slang/slang-compiler.h" #include "slang-module.h" +#include "capture-manager.h" namespace SlangCapture { @@ -18,7 +19,7 @@ namespace SlangCapture SLANG_REF_OBJECT_IUNKNOWN_ALL ISlangUnknown* getInterface(const Guid& guid); - explicit SessionCapture(slang::ISession* session); + explicit SessionCapture(slang::ISession* session, CaptureManager* captureManager); ~SessionCapture(); SLANG_NO_THROW slang::IGlobalSession* SLANG_MCALL getGlobalSession() override; @@ -105,8 +106,10 @@ namespace SlangCapture ModuleCapture* getModuleCapture(slang::IModule* module); Slang::ComPtr<slang::ISession> m_actualSession; + uint64_t m_sessionHandle = 0; Dictionary<slang::IModule*, ModuleCapture> m_mapModuleToCapture; + CaptureManager* m_captureManager = nullptr; }; } diff --git a/source/slang-capture-replay/slang-type-conformance.cpp b/source/slang-capture-replay/slang-type-conformance.cpp index 747ed119e..3eb108510 100644 --- a/source/slang-capture-replay/slang-type-conformance.cpp +++ b/source/slang-capture-replay/slang-type-conformance.cpp @@ -3,12 +3,17 @@ namespace SlangCapture { - TypeConformanceCapture::TypeConformanceCapture(slang::ITypeConformance* typeConformance) - : m_actualTypeConformance(typeConformance) + TypeConformanceCapture::TypeConformanceCapture(slang::ITypeConformance* typeConformance, CaptureManager* captureManager) + : m_actualTypeConformance(typeConformance), + m_captureManager(captureManager) { SLANG_CAPTURE_ASSERT(m_actualTypeConformance != nullptr); + SLANG_CAPTURE_ASSERT(m_captureManager != nullptr); + + m_typeConformanceHandle = reinterpret_cast<uint64_t>(m_actualTypeConformance.get()); slangCaptureLog(LogLevel::Verbose, "%s: %p\n", __PRETTY_FUNCTION__, typeConformance); } + TypeConformanceCapture::~TypeConformanceCapture() { m_actualTypeConformance->release(); @@ -29,7 +34,20 @@ namespace SlangCapture SLANG_NO_THROW slang::ISession* TypeConformanceCapture::getSession() { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ITypeConformance_getSession, m_typeConformanceHandle); + encoder = m_captureManager->endMethodCapture(); + } + slang::ISession* res = m_actualTypeConformance->getSession(); + + { + encoder->encodeAddress(res); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -38,8 +56,23 @@ namespace SlangCapture slang::IBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); - slang::ProgramLayout* res = m_actualTypeConformance->getLayout(targetIndex, outDiagnostics); - return res; + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ICompositeComponentType_getLayout, m_typeConformanceHandle); + encoder->encodeInt64(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + + slang::ProgramLayout* programLayout = m_actualTypeConformance->getLayout(targetIndex, outDiagnostics); + + { + encoder->encodeAddress(*outDiagnostics); + encoder->encodeAddress(programLayout); + m_captureManager->endMethodCaptureAppendOutput(); + } + + return programLayout; } SLANG_NO_THROW SlangInt TypeConformanceCapture::getSpecializationParamCount() @@ -56,7 +89,23 @@ namespace SlangCapture slang::IBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ITypeConformance_getEntryPointCode, m_typeConformanceHandle); + encoder->encodeInt64(entryPointIndex); + encoder->encodeInt64(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualTypeConformance->getEntryPointCode(entryPointIndex, targetIndex, outCode, outDiagnostics); + + { + encoder->encodeAddress(*outCode); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -66,7 +115,22 @@ namespace SlangCapture slang::IBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ITypeConformance_getTargetCode, m_typeConformanceHandle); + encoder->encodeInt64(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualTypeConformance->getTargetCode(targetIndex, outCode, outDiagnostics); + + { + encoder->encodeAddress(*outCode); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -76,7 +140,22 @@ namespace SlangCapture ISlangMutableFileSystem** outFileSystem) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ITypeConformance_getResultAsFileSystem, m_typeConformanceHandle); + encoder->encodeInt64(entryPointIndex); + encoder->encodeInt64(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualTypeConformance->getResultAsFileSystem(entryPointIndex, targetIndex, outFileSystem); + + { + encoder->encodeAddress(*outFileSystem); + } + + // TODO: We might need to wrap the file system object. return res; } @@ -86,17 +165,47 @@ namespace SlangCapture slang::IBlob** outHash) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ITypeConformance_getEntryPointHash, m_typeConformanceHandle); + encoder->encodeInt64(entryPointIndex); + encoder->encodeInt64(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + m_actualTypeConformance->getEntryPointHash(entryPointIndex, targetIndex, outHash); + + { + encoder->encodeAddress(*outHash); + m_captureManager->endMethodCaptureAppendOutput(); + } } SLANG_NO_THROW SlangResult TypeConformanceCapture::specialize( - slang::SpecializationArg const* specializationArgs, - SlangInt specializationArgCount, - slang::IComponentType** outSpecializedComponentType, - ISlangBlob** outDiagnostics) + slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, + slang::IComponentType** outSpecializedComponentType, + ISlangBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ITypeConformance_specialize, m_typeConformanceHandle); + encoder->encodeInt64(specializationArgCount); + encoder->encodeStructArray(specializationArgs, specializationArgCount); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualTypeConformance->specialize(specializationArgs, specializationArgCount, outSpecializedComponentType, outDiagnostics); + + { + encoder->encodeAddress(*outSpecializedComponentType); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -105,7 +214,21 @@ namespace SlangCapture ISlangBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ITypeConformance_link, m_typeConformanceHandle); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualTypeConformance->link(outLinkedComponentType, outDiagnostics); + + { + encoder->encodeAddress(*outLinkedComponentType); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -116,7 +239,23 @@ namespace SlangCapture slang::IBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ITypeConformance_getEntryPointHostCallable, m_typeConformanceHandle); + encoder->encodeInt32(entryPointIndex); + encoder->encodeInt32(targetIndex); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualTypeConformance->getEntryPointHostCallable(entryPointIndex, targetIndex, outSharedLibrary, outDiagnostics); + + { + encoder->encodeAddress(*outSharedLibrary); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -124,7 +263,21 @@ namespace SlangCapture const char* newName, IComponentType** outEntryPoint) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ITypeConformance_renameEntryPoint, m_typeConformanceHandle); + encoder->encodeString(newName); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualTypeConformance->renameEntryPoint(newName, outEntryPoint); + + { + encoder->encodeAddress(*outEntryPoint); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } @@ -135,7 +288,23 @@ namespace SlangCapture ISlangBlob** outDiagnostics) { slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterEncoder* encoder {}; + { + encoder = m_captureManager->beginMethodCapture(ApiCallId::ITypeConformance_linkWithOptions, m_typeConformanceHandle); + encoder->encodeUint32(compilerOptionEntryCount); + encoder->encodeStructArray(compilerOptionEntries, compilerOptionEntryCount); + encoder = m_captureManager->endMethodCapture(); + } + SlangResult res = m_actualTypeConformance->linkWithOptions(outLinkedComponentType, compilerOptionEntryCount, compilerOptionEntries, outDiagnostics); + + { + encoder->encodeAddress(*outLinkedComponentType); + encoder->encodeAddress(*outDiagnostics); + m_captureManager->endMethodCaptureAppendOutput(); + } + return res; } } diff --git a/source/slang-capture-replay/slang-type-conformance.h b/source/slang-capture-replay/slang-type-conformance.h index c9e5f12a3..a37fd8daf 100644 --- a/source/slang-capture-replay/slang-type-conformance.h +++ b/source/slang-capture-replay/slang-type-conformance.h @@ -7,6 +7,7 @@ #include "../core/slang-smart-pointer.h" #include "../core/slang-dictionary.h" #include "../slang/slang-compiler.h" +#include "capture-manager.h" namespace SlangCapture { @@ -19,7 +20,7 @@ namespace SlangCapture SLANG_REF_OBJECT_IUNKNOWN_ALL ISlangUnknown* getInterface(const Guid& guid); - explicit TypeConformanceCapture(slang::ITypeConformance* typeConformance); + explicit TypeConformanceCapture(slang::ITypeConformance* typeConformance, CaptureManager* captureManager); ~TypeConformanceCapture(); // Interfaces for `IComponentType` @@ -69,6 +70,8 @@ namespace SlangCapture slang::ITypeConformance* getActualTypeConformance() const { return m_actualTypeConformance; } private: Slang::ComPtr<slang::ITypeConformance> m_actualTypeConformance; + uint64_t m_typeConformanceHandle = 0; + CaptureManager* m_captureManager = nullptr; }; } #endif // SLANG_TYPE_CONFORMANCE_H |
