diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/core/slang-stream.h | 5 | ||||
| -rw-r--r-- | source/slang-capture-replay/api_callId.h | 147 | ||||
| -rw-r--r-- | source/slang-capture-replay/capture-manager.cpp | 53 | ||||
| -rw-r--r-- | source/slang-capture-replay/capture-manager.h | 30 | ||||
| -rw-r--r-- | source/slang-capture-replay/output-stream.cpp | 52 | ||||
| -rw-r--r-- | source/slang-capture-replay/output-stream.h | 46 | ||||
| -rw-r--r-- | source/slang-capture-replay/parameter-encoder.cpp | 72 | ||||
| -rw-r--r-- | source/slang-capture-replay/parameter-encoder.h | 51 | ||||
| -rw-r--r-- | source/slang-capture-replay/slang-global-session.cpp | 13 | ||||
| -rw-r--r-- | source/slang-capture-replay/slang-global-session.h | 13 |
10 files changed, 479 insertions, 3 deletions
diff --git a/source/core/slang-stream.h b/source/core/slang-stream.h index 9f405dbb0..a62c18838 100644 --- a/source/core/slang-stream.h +++ b/source/core/slang-stream.h @@ -138,7 +138,10 @@ public: void setContent(const void* contents, size_t contentsSize) { m_ownedContents.setCount(contentsSize); - ::memcpy(m_ownedContents.getBuffer(), contents, contentsSize); + if (contentsSize > 0) + { + ::memcpy(m_ownedContents.getBuffer(), contents, contentsSize); + } _setContents(m_ownedContents.getBuffer(), m_ownedContents.getCount()); } diff --git a/source/slang-capture-replay/api_callId.h b/source/slang-capture-replay/api_callId.h new file mode 100644 index 000000000..0a96ef4a7 --- /dev/null +++ b/source/slang-capture-replay/api_callId.h @@ -0,0 +1,147 @@ +#ifndef API_CALL_ID_H +#define API_CALL_ID_H + +#include <cstdint> + +namespace SlangCapture +{ + constexpr uint32_t makeApiCallId(uint16_t classId, uint16_t memberFunctionId) + { + return ((static_cast<uint32_t>(classId) << 16) & 0xffff0000) | (static_cast<uint32_t>(memberFunctionId) & 0x0000ffff); + } + + constexpr uint16_t getClassId(uint32_t callId) + { + return static_cast<uint16_t>((callId >> 16) & 0x0000ffff); + } + + constexpr uint16_t getMemberFunctionId(uint32_t callId) + { + return static_cast<uint16_t>(callId & 0x0000ffff); + } + + enum ApiClassId : uint16_t + { + GlobalFunction = 1, + Class_IGlobalSession = 2, + Class_ISession = 3, + Class_IModule = 4, + Class_IEntryPoint = 5, + Class_ICompositeComponentType = 6, + Class_ITypeConformance = 7, + }; + + typedef uint64_t AddressFormat; + + constexpr uint64_t g_globalFunctionHandle = 0; + + enum ApiCallId : uint32_t + { + InvalidCallId = 0x00000000, + ICreateGlobalSession = makeApiCallId(GlobalFunction, 0x0000), + IGlobalSession_createSession = makeApiCallId(Class_IGlobalSession, 0x0001), + IGlobalSession_findProfile = makeApiCallId(Class_IGlobalSession, 0x0002), + IGlobalSession_setDownstreamCompilerPath = makeApiCallId(Class_IGlobalSession, 0x0003), + IGlobalSession_setDownstreamCompilerPrelude = makeApiCallId(Class_IGlobalSession, 0x0004), + IGlobalSession_getDownstreamCompilerPrelude = makeApiCallId(Class_IGlobalSession, 0x0005), + IGlobalSession_getBuildTagString = makeApiCallId(Class_IGlobalSession, 0x0006), + IGlobalSession_setDefaultDownstreamCompiler = makeApiCallId(Class_IGlobalSession, 0x0007), + IGlobalSession_getDefaultDownstreamCompiler = makeApiCallId(Class_IGlobalSession, 0x0008), + IGlobalSession_setLanguagePrelude = makeApiCallId(Class_IGlobalSession, 0x0009), + IGlobalSession_getLanguagePrelude = makeApiCallId(Class_IGlobalSession, 0x000A), + IGlobalSession_createCompileRequest = makeApiCallId(Class_IGlobalSession, 0x000B), + IGlobalSession_addBuiltins = makeApiCallId(Class_IGlobalSession, 0x000C), + IGlobalSession_setSharedLibraryLoader = makeApiCallId(Class_IGlobalSession, 0x000D), + IGlobalSession_getSharedLibraryLoader = makeApiCallId(Class_IGlobalSession, 0x000E), + IGlobalSession_checkCompileTargetSupport = makeApiCallId(Class_IGlobalSession, 0x000F), + IGlobalSession_checkPassThroughSupport = makeApiCallId(Class_IGlobalSession, 0x0010), + IGlobalSession_compileStdLib = makeApiCallId(Class_IGlobalSession, 0x0011), + IGlobalSession_loadStdLib = makeApiCallId(Class_IGlobalSession, 0x0012), + IGlobalSession_saveStdLib = makeApiCallId(Class_IGlobalSession, 0x0013), + IGlobalSession_findCapability = makeApiCallId(Class_IGlobalSession, 0x0014), + IGlobalSession_setDownstreamCompilerForTransition = makeApiCallId(Class_IGlobalSession, 0x0015), + IGlobalSession_getDownstreamCompilerForTransition = makeApiCallId(Class_IGlobalSession, 0x0016), + IGlobalSession_getCompilerElapsedTime = makeApiCallId(Class_IGlobalSession, 0x0017), + IGlobalSession_setSPIRVCoreGrammar = makeApiCallId(Class_IGlobalSession, 0x0018), + IGlobalSession_parseCommandLineArguments = makeApiCallId(Class_IGlobalSession, 0x0019), + IGlobalSession_getSessionDescDigest = makeApiCallId(Class_IGlobalSession, 0x001A), + + ISession_getGlobalSession = makeApiCallId(Class_ISession, 0x0001), + ISession_loadModule = makeApiCallId(Class_ISession, 0x0002), + ISession_loadModuleFromBlob = makeApiCallId(Class_ISession, 0x0003), + ISession_loadModuleFromIRBlob = makeApiCallId(Class_ISession, 0x0004), + ISession_loadModuleFromSource = makeApiCallId(Class_ISession, 0x0005), + ISession_loadModuleFromSourceString = makeApiCallId(Class_ISession, 0x0006), + ISession_createCompositeComponentType = makeApiCallId(Class_ISession, 0x0007), + ISession_specializeType = makeApiCallId(Class_ISession, 0x0008), + ISession_getTypeLayout = makeApiCallId(Class_ISession, 0x0009), + ISession_getContainerType = makeApiCallId(Class_ISession, 0x000A), + ISession_getDynamicType = makeApiCallId(Class_ISession, 0x000B), + ISession_getTypeRTTIMangledName = makeApiCallId(Class_ISession, 0x000C), + ISession_getTypeConformanceWitnessMangledName = makeApiCallId(Class_ISession, 0x000D), + ISession_getTypeConformanceWitnessSequentialID = makeApiCallId(Class_ISession, 0x000E), + ISession_createTypeConformanceComponentType = makeApiCallId(Class_ISession, 0x000F), + ISession_createCompileRequest = makeApiCallId(Class_ISession, 0x0010), + ISession_getLoadedModuleCount = makeApiCallId(Class_ISession, 0x0011), + ISession_getLoadedModule = makeApiCallId(Class_ISession, 0x0012), + ISession_isBinaryModuleUpToDate = makeApiCallId(Class_ISession, 0x0013), + + IModule_findEntryPointByName = makeApiCallId(Class_IModule, 0x0001), + IModule_getDefinedEntryPointCount = makeApiCallId(Class_IModule, 0x0002), + IModule_getDefinedEntryPoint = makeApiCallId(Class_IModule, 0x0003), + IModule_serialize = makeApiCallId(Class_IModule, 0x0004), + IModule_writeToFile = makeApiCallId(Class_IModule, 0x0005), + IModule_getName = makeApiCallId(Class_IModule, 0x0006), + IModule_getFilePath = makeApiCallId(Class_IModule, 0x0007), + IModule_getUniqueIdentity = makeApiCallId(Class_IModule, 0x0008), + IModule_findAndCheckEntryPoint = makeApiCallId(Class_IModule, 0x0009), + IModule_getSession = makeApiCallId(Class_IModule, 0x000A), + 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), + + 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), + + 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), + + 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) + }; +} +#endif diff --git a/source/slang-capture-replay/capture-manager.cpp b/source/slang-capture-replay/capture-manager.cpp new file mode 100644 index 000000000..be5615e00 --- /dev/null +++ b/source/slang-capture-replay/capture-manager.cpp @@ -0,0 +1,53 @@ + +#include <string> +#include <sstream> +#include <thread> +#include "capture-manager.h" + +namespace SlangCapture +{ + CaptureManager::CaptureManager(uint64_t globalSessionHandle) + : m_encoder(&m_memoryStream) + { + std::stringstream ss; + ss << "gs-"<< globalSessionHandle <<"t-"<<std::this_thread::get_id() << ".cap"; + m_fileStream = std::make_unique<FileOutputStream>(ss.str()); + } + + void CaptureManager::clearWithHeader(const ApiCallId& callId, uint64_t handleId) + { + m_memoryStream.flush(); + FunctionHeader header {}; + header.callId = callId; + header.handleId = handleId; + + // write header to memory stream + m_memoryStream.write(&header, sizeof(FunctionHeader)); + } + + ParameterEncoder* CaptureManager::beginMethodCapture(const ApiCallId& callId, uint64_t handleId) + { + clearWithHeader(callId, handleId); + return &m_encoder; + } + + void CaptureManager::endMethodCapture() + { + FunctionHeader* pHeader = const_cast<FunctionHeader*>( + reinterpret_cast<const FunctionHeader*>(m_memoryStream.getData())); + + pHeader->dataSizeInBytes = m_memoryStream.getSizeInBytes() - sizeof(FunctionHeader); + + std::hash<std::thread::id> hasher; + pHeader->threadId = hasher(std::this_thread::get_id()); + + // write capture data to file + m_fileStream->write(m_memoryStream.getData(), m_memoryStream.getSizeInBytes()); + + // take effect of the write + m_fileStream->flush(); + + // clear the memory stream + m_memoryStream.flush(); + } +} diff --git a/source/slang-capture-replay/capture-manager.h b/source/slang-capture-replay/capture-manager.h new file mode 100644 index 000000000..55d42c458 --- /dev/null +++ b/source/slang-capture-replay/capture-manager.h @@ -0,0 +1,30 @@ +#ifndef CAPTURE_MANAGER_H +#define CAPTURE_MANAGER_H + +#include "parameter-encoder.h" +#include "api_callId.h" +namespace SlangCapture +{ + class CaptureManager + { + public: + CaptureManager(uint64_t globalSessionHandle); + ParameterEncoder* beginMethodCapture(const ApiCallId& callId, uint64_t handleId); + void endMethodCapture(); + private: + void clearWithHeader(const ApiCallId& callId, uint64_t handleId); + + struct FunctionHeader + { + ApiCallId callId {InvalidCallId}; + uint64_t handleId {0}; + uint64_t dataSizeInBytes {0}; + uint64_t threadId {0}; + }; + + MemoryStream m_memoryStream; + std::unique_ptr<FileOutputStream> m_fileStream; + ParameterEncoder m_encoder; + }; +} // namespace SlangCapture +#endif // CAPTURE_MANAGER_H diff --git a/source/slang-capture-replay/output-stream.cpp b/source/slang-capture-replay/output-stream.cpp new file mode 100644 index 000000000..acde6fbf1 --- /dev/null +++ b/source/slang-capture-replay/output-stream.cpp @@ -0,0 +1,52 @@ +#include "output-stream.h" +#include "capture_utility.h" + +namespace SlangCapture +{ + FileOutputStream::FileOutputStream(const std::string& filename, bool append) + { + Slang::String path(filename.c_str()); + Slang::FileMode fileMode = append ? Slang::FileMode::Append : Slang::FileMode::Create; + Slang::FileAccess fileAccess = Slang::FileAccess::Write; + Slang::FileShare fileShare = Slang::FileShare::None; + + SlangResult res = m_fileStream.init(path, fileMode, fileAccess, fileShare); + + if (res != SLANG_OK) + { + SlangCapture::slangCaptureLog(SlangCapture::LogLevel::Error, "Failed to open file %s\n", filename.c_str()); + std::abort(); + } + } + + FileOutputStream::~FileOutputStream() + { + m_fileStream.close(); + } + + void FileOutputStream::write(const void* data, size_t len) + { + SLANG_CAPTURE_ASSERT(m_fileStream.write(data, len)); + } + + MemoryStream::MemoryStream() + : m_memoryStream(Slang::FileAccess::Write) + { } + + void FileOutputStream::flush() + { + SLANG_CAPTURE_ASSERT(m_fileStream.flush()); + } + + void MemoryStream::write(const void* data, size_t len) + { + SLANG_CAPTURE_ASSERT(m_memoryStream.write(data, len)); + } + + void MemoryStream::flush() + { + // This call will reset the underlying buffer to size 0, + // and reset the write position to 0. + m_memoryStream.setContent(nullptr, 0); + } +} diff --git a/source/slang-capture-replay/output-stream.h b/source/slang-capture-replay/output-stream.h new file mode 100644 index 000000000..1f2c882b0 --- /dev/null +++ b/source/slang-capture-replay/output-stream.h @@ -0,0 +1,46 @@ +#ifndef OUTPUT_STREAM_H +#define OUTPUT_STREAM_H + +#include <string> +#include "../core/slang-stream.h" + +namespace SlangCapture +{ + class OutputStream + { + public: + virtual ~OutputStream() {} + virtual void write(const void* data, size_t len) = 0; + virtual void flush() {} + }; + + class FileOutputStream : public OutputStream + { + public: + FileOutputStream(const std::string& filename, bool append = false); + virtual ~FileOutputStream() override; + virtual void write(const void* data, size_t len) override; + virtual void flush() override; + + private: + Slang::FileStream m_fileStream; + }; + + // The reason we inherit from OwnedMemoryStream instead of declaring it + // as a member is because OwnedMemoryStream lacks some of the functionality + // of operating on the underlying buffer directly. + class MemoryStream : public OutputStream + { + public: + MemoryStream(); + virtual ~MemoryStream() { } + virtual void write(const void* data, size_t len) override; + virtual void flush() override; + const void* getData() { return m_memoryStream.getContents().getBuffer(); } + size_t getSizeInBytes() { return m_memoryStream.getContents().getCount(); } + + private: + Slang::OwnedMemoryStream m_memoryStream; + }; +} // namespace SlangCapture +#endif // OUTPUT_STREAM_H diff --git a/source/slang-capture-replay/parameter-encoder.cpp b/source/slang-capture-replay/parameter-encoder.cpp new file mode 100644 index 000000000..5167cc2ab --- /dev/null +++ b/source/slang-capture-replay/parameter-encoder.cpp @@ -0,0 +1,72 @@ +#include "parameter-encoder.h" + +namespace SlangCapture +{ + void ParameterEncoder::encodeStruct(slang::SessionDesc const& desc) + { + encodeUint64(desc.structureSize); + encodeInt64(desc.targetCount); + + for (SlangInt i = 0; i < desc.targetCount; i++) + { + encodeStruct(desc.targets[i]); + } + + encodeUint32(desc.flags); + encodeUint32(desc.defaultMatrixLayoutMode); + encodeInt64(desc.searchPathCount); + for (SlangInt i = 0; i < desc.searchPathCount; i++) + { + encodeString(desc.searchPaths[i]); + } + + encodeInt64(desc.preprocessorMacroCount); + for (SlangInt i = 0; i < desc.preprocessorMacroCount; i++) + { + encodeStruct(desc.preprocessorMacros[i]); + } + + encodeBool(desc.enableEffectAnnotations); + encodeBool(desc.allowGLSLSyntax); + + encodeUint32(desc.compilerOptionEntryCount); + for (uint32_t i = 0; i < desc.compilerOptionEntryCount; i++) + { + encodeStruct(desc.compilerOptionEntries[i]); + } + } + + void ParameterEncoder::encodeStruct(slang::PreprocessorMacroDesc const& desc) + { + encodeString(desc.name); + encodeString(desc.value); + } + + void ParameterEncoder::encodeStruct(slang::CompilerOptionEntry const& entry) + { + encodeInt32((int32_t)(entry.name)); + encodeStruct(entry.value); + } + + void ParameterEncoder::encodeStruct(slang::CompilerOptionValue const& value) + { + (void)value; + } + + void ParameterEncoder::encodeStruct(slang::TargetDesc const& targetDesc) + { + (void)targetDesc; + } + + void ParameterEncoder::encodePointer(const void* value, bool omitData, size_t size) + { + (void)value; + (void)omitData; + (void)size; + } + // first 4-bytes is the length of the string + void ParameterEncoder::encodeString(const char* value) + { + (void)value; + } +} diff --git a/source/slang-capture-replay/parameter-encoder.h b/source/slang-capture-replay/parameter-encoder.h new file mode 100644 index 000000000..c7c2d959a --- /dev/null +++ b/source/slang-capture-replay/parameter-encoder.h @@ -0,0 +1,51 @@ +#ifndef PARAMETER_ENCODER_H +#define PARAMETER_ENCODER_H + +#include <cstdio> +#include <cinttypes> +#include <cstdint> + +#include "output-stream.h" + +namespace SlangCapture +{ + class ParameterEncoder + { + public: + ParameterEncoder(OutputStream* stream) : m_stream(stream) {}; + void encodeInt8(int8_t value) { encodeValue(value); } + void encodeUint8(uint8_t value) { encodeValue(value); } + void encodeInt16(int16_t value) { encodeValue(value); } + void encodeUint16(uint16_t value) { encodeValue(value); } + void encodeInt32(int32_t value) { encodeValue(value); } + void encodeUint32(uint32_t value) { encodeValue(value); } + void encodeInt64(int64_t value) { encodeValue(value); } + void encodeUint64(uint64_t value) { encodeValue(value); } + void encodeFloat(float value) { encodeValue(value); } + void encodeDouble(double value) { encodeValue(value); } + void encodeBool(bool value) { encodeValue(value); } + + template<typename T> + void encodeEnumValue(T value) { encodeValue(static_cast<uint32_t>(value)); } + + void encodeString(const char* value); + void encodePointer(const void* value, bool omitData = false, size_t size = 0); + void encodeAddress(const void* value) { encodeValue(reinterpret_cast<uint64_t>(value)); } + + void encodeStruct(slang::SessionDesc const& desc); + void encodeStruct(slang::PreprocessorMacroDesc const& desc); + void encodeStruct(slang::CompilerOptionEntry const& entry); + void encodeStruct(slang::CompilerOptionValue const& value); + void encodeStruct(slang::TargetDesc const& targetDesc); + + private: + template <typename T> + void encodeValue(T value) + { + m_stream->write(&value, sizeof(T)); + } + OutputStream* m_stream; + }; +} // namespace SlangCapture + +#endif // PARAMETER_ENCODER_H diff --git a/source/slang-capture-replay/slang-global-session.cpp b/source/slang-capture-replay/slang-global-session.cpp index 05a2b93ec..45ea0b58d 100644 --- a/source/slang-capture-replay/slang-global-session.cpp +++ b/source/slang-capture-replay/slang-global-session.cpp @@ -1,5 +1,3 @@ - -#include <vector> #include "slang-global-session.h" #include "slang-session.h" #include "slang-filesystem.h" @@ -8,10 +6,21 @@ namespace SlangCapture { + // constructor is called in slang_createGlobalSession GlobalSessionCapture::GlobalSessionCapture(slang::IGlobalSession* session): m_actualGlobalSession(session) { SLANG_CAPTURE_ASSERT(m_actualGlobalSession != nullptr); + + m_thisHandle = reinterpret_cast<SlangCapture::AddressFormat>(this); + m_captureManager = std::make_unique<CaptureManager>(m_thisHandle); + + // We will use the address of the global session as the filename for the capture manager + // to make it unique for each global session. + // capture slang::createGlobalSession + ParameterEncoder* encoder = m_captureManager->beginMethodCapture(ApiCallId::ICreateGlobalSession, g_globalFunctionHandle); + encoder->encodeAddress(m_actualGlobalSession); + m_captureManager->endMethodCapture(); } GlobalSessionCapture::~GlobalSessionCapture() diff --git a/source/slang-capture-replay/slang-global-session.h b/source/slang-capture-replay/slang-global-session.h index 52260ba21..6923ddf11 100644 --- a/source/slang-capture-replay/slang-global-session.h +++ b/source/slang-capture-replay/slang-global-session.h @@ -5,6 +5,7 @@ #include "../../slang.h" #include "../../slang-com-helper.h" #include "../core/slang-smart-pointer.h" +#include "capture-manager.h" namespace SlangCapture { @@ -58,6 +59,8 @@ namespace SlangCapture SLANG_NO_THROW SlangResult SLANG_MCALL getSessionDescDigest(slang::SessionDesc* sessionDesc, ISlangBlob** outBlob) override; + CaptureManager* getCaptureManager() { return m_captureManager.get(); } + private: SLANG_FORCE_INLINE slang::IGlobalSession* asExternal(GlobalSessionCapture* session) { @@ -65,6 +68,16 @@ namespace SlangCapture } Slang::ComPtr<slang::IGlobalSession> m_actualGlobalSession; + + // we will create one capture file per IGlobalSession. + // We don't try to reproduce the user application's threading model, because it requires lots of effort and it's not necessary. + // Instead, we record all the compilation jobs associated with the session in the same capture file, so that during replay, + // those jobs will be executed sequentially. This might violate the user application's threading model, because those jobs might + // be executed in different threads. But it's not a big problem, because slang doesn't allow multiple threads to access the same + // session at the same time. So even if there is one session used by multiple threads, those threads will execute the compile jobs + // sequentially. + std::unique_ptr<CaptureManager> m_captureManager; + uint64_t m_thisHandle = 0; }; } // namespace Slang |
