diff options
| author | kaizhangNV <149626564+kaizhangNV@users.noreply.github.com> | 2024-07-23 10:45:26 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-23 08:45:26 -0700 |
| commit | 986256ffb92ab7c8fc7cf9f2c424919a439a824f (patch) | |
| tree | 260e37bd439275e3398d16fe238b20cd00d08cb7 /source | |
| parent | c28d8b6aec721fa3350fc52647f1572a353f6151 (diff) | |
Feature/capture (#4625)
* Add decoder
* Add a replay executable to consume the decoded content
Add file-processor.cpp/h where we implement the logic to process
the captured file block by block. Each block is:
function header + parameter buffer + function tailer + function
output[optional].
After reading one block, the block of data is sent to decoder module
to dispatch the corresponding API.
Add slang-decoder.cpp/h where we implement the logic to dispatch
the slang API according to the input block data.
- Rename api_callId.h to capture-format.h
- Renmae capture_utility.cpp to capture-utility.cpp
- Renmae capture_utility.h to capture-utility.h
- Change the #include file name accordingly.
* Reorganize source files structure
Move all the capture logic code into `capture` directory.
- the capture code will be build with slang dll.
Move all the replay logic code into `relay` directoy.
- the replay code is not part of slang dll, it will be built
as a stand alone binary and link against slang dll.
Change the #include file names accordingly.
Add tools/slang-replay/main.cpp for the slang-replay stand alone
binary place holder. Will implement it later.
Update premake5.lua accordingly.
* Update cmake files
Update cmake files to change the build process for
capture and relay system.
- capture component should be build with slang dll, so we
should not include replay component.
- replay component should be a separate executable tool, which
should not include capture component.
- In order to easy use our current cmake infrastructure, move
the shared files to a `util` folder
- change the header include path
* Redesgin the interfaces of consumers
Fix some issues in capture
Finish implementing all slang-decoder functions
* Fix the AppleClang build issue
* Address few comments
- Fix the weird indent issues.
- Correct the function name for CreateGlobalSession()
- Rename file-processor to captureFile-processor to be more specific.
- Use Slang::List instead of std::vector
* record/replay: name refactor change
Refactor the naming.
Change the name "encoder/capture" to "record".
Diffstat (limited to 'source')
48 files changed, 7145 insertions, 2837 deletions
diff --git a/source/slang-capture-replay/capture-manager.h b/source/slang-capture-replay/capture-manager.h deleted file mode 100644 index ca06d70a8..000000000 --- a/source/slang-capture-replay/capture-manager.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef CAPTURE_MANAGER_H -#define CAPTURE_MANAGER_H - -#include <filesystem> -#include "parameter-encoder.h" -#include "api_callId.h" - -namespace SlangCapture -{ - class CaptureManager - { - public: - CaptureManager(uint64_t globalSessionHandle); - - // Each method capture has to start with a FunctionHeader - ParameterEncoder* beginMethodCapture(const ApiCallId& callId, uint64_t handleId); - ParameterEncoder* endMethodCapture(); - - // 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(); - - struct FunctionHeader - { - uint32_t magic {0x44414548}; - ApiCallId callId {InvalidCallId}; - uint64_t handleId {0}; - uint64_t dataSizeInBytes {0}; - uint64_t threadId {0}; - }; - - struct FunctionTailer - { - uint32_t magic {0x4C494154}; - uint32_t dataSizeInBytes {0}; - }; - - MemoryStream m_memoryStream; - std::unique_ptr<FileOutputStream> m_fileStream; - std::filesystem::path m_captureFileDirectory = std::filesystem::current_path(); - ParameterEncoder m_encoder; - }; -} // namespace SlangCapture -#endif // CAPTURE_MANAGER_H diff --git a/source/slang-capture-replay/parameter-encoder.cpp b/source/slang-capture-replay/parameter-encoder.cpp deleted file mode 100644 index c73a97b08..000000000 --- a/source/slang-capture-replay/parameter-encoder.cpp +++ /dev/null @@ -1,123 +0,0 @@ -#include "parameter-encoder.h" -#include "api_callId.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); - encodeEnumValue(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) - { - encodeEnumValue(entry.name); - encodeStruct(entry.value); - } - - void ParameterEncoder::encodeStruct(slang::CompilerOptionValue const& value) - { - encodeEnumValue(value.kind); - encodeInt32(value.intValue0); - encodeString(value.stringValue0); - encodeString(value.stringValue1); - } - - void ParameterEncoder::encodeStruct(slang::TargetDesc const& targetDesc) - { - encodeUint64(targetDesc.structureSize); - encodeEnumValue(targetDesc.format); - encodeEnumValue(targetDesc.profile); - encodeEnumValue(targetDesc.flags); - encodeEnumValue(targetDesc.floatingPointMode); - encodeEnumValue(targetDesc.lineDirectiveMode); - encodeBool(targetDesc.forceGLSLScalarBufferLayout); - encodeUint32(targetDesc.compilerOptionEntryCount); - for (uint32_t i = 0; i < targetDesc.compilerOptionEntryCount; i++) - { - encodeStruct(targetDesc.compilerOptionEntries[i]); - } - } - - 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); - if (omitData) - { - return; - } - - encodeUint64(size); - if (size) - { - m_stream->write(value, size); - } - } - - void ParameterEncoder::encodePointer(ISlangBlob* blob) - { - encodeAddress(static_cast<const void*>(blob)); - - if (blob) - { - size_t size = blob->getBufferSize(); - const void* buffer = blob->getBufferPointer(); - encodePointer(buffer, false, size); - } - } - - // first 4-bytes is the length of the string - void ParameterEncoder::encodeString(const char* value) - { - if (value == nullptr) - { - encodeUint32(0); - } - else - { - uint32_t size = (uint32_t)strlen(value); - encodeUint32(size); - m_stream->write(value, size); - } - } -} diff --git a/source/slang-capture-replay/parameter-encoder.h b/source/slang-capture-replay/parameter-encoder.h deleted file mode 100644 index d5a6ea510..000000000 --- a/source/slang-capture-replay/parameter-encoder.h +++ /dev/null @@ -1,89 +0,0 @@ -#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 encodePointer(ISlangBlob* blob); - 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); - 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> - 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-composite-component-type.cpp b/source/slang-capture-replay/slang-composite-component-type.cpp deleted file mode 100644 index a0699e27a..000000000 --- a/source/slang-capture-replay/slang-composite-component-type.cpp +++ /dev/null @@ -1,309 +0,0 @@ -#include "capture_utility.h" -#include "slang-composite-component-type.h" - -namespace SlangCapture -{ - 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); - } - - CompositeComponentTypeCapture::~CompositeComponentTypeCapture() - { - m_actualCompositeComponentType->release(); - } - - ISlangUnknown* CompositeComponentTypeCapture::getInterface(const Guid& guid) - { - if (guid == IComponentType::getTypeGuid()) - { - return static_cast<ISlangUnknown*>(this); - } - return nullptr; - } - - 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; - } - - SLANG_NO_THROW slang::ProgramLayout* CompositeComponentTypeCapture::getLayout( - SlangInt targetIndex, - slang::IBlob** outDiagnostics) - { - slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); - - 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; - } - - SLANG_NO_THROW SlangResult CompositeComponentTypeCapture::getEntryPointCode( - SlangInt entryPointIndex, - SlangInt targetIndex, - slang::IBlob** outCode, - 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; - } - - SLANG_NO_THROW SlangResult CompositeComponentTypeCapture::getTargetCode( - SlangInt targetIndex, - slang::IBlob** outCode, - 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; - } - - SLANG_NO_THROW SlangResult CompositeComponentTypeCapture::getResultAsFileSystem( - SlangInt entryPointIndex, - SlangInt targetIndex, - 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; - } - - SLANG_NO_THROW void CompositeComponentTypeCapture::getEntryPointHash( - SlangInt entryPointIndex, - SlangInt targetIndex, - 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( - 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::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; - } - - SLANG_NO_THROW SlangResult CompositeComponentTypeCapture::link( - slang::IComponentType** outLinkedComponentType, - 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; - } - - SLANG_NO_THROW SlangResult CompositeComponentTypeCapture::getEntryPointHostCallable( - int entryPointIndex, - int targetIndex, - ISlangSharedLibrary** outSharedLibrary, - 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; - } - - SLANG_NO_THROW SlangResult CompositeComponentTypeCapture::renameEntryPoint( - 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; - } - - SLANG_NO_THROW SlangResult CompositeComponentTypeCapture::linkWithOptions( - IComponentType** outLinkedComponentType, - uint32_t compilerOptionEntryCount, - slang::CompilerOptionEntry* compilerOptionEntries, - 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-entrypoint.cpp b/source/slang-capture-replay/slang-entrypoint.cpp deleted file mode 100644 index 46d701f98..000000000 --- a/source/slang-capture-replay/slang-entrypoint.cpp +++ /dev/null @@ -1,313 +0,0 @@ -#include "capture_utility.h" -#include "slang-entrypoint.h" - -namespace SlangCapture -{ - 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); - } - - EntryPointCapture::~EntryPointCapture() - { - m_actualEntryPoint->release(); - } - - ISlangUnknown* EntryPointCapture::getInterface(const Guid& guid) - { - if(guid == EntryPointCapture::getTypeGuid()) - return static_cast<ISlangUnknown*>(this); - else - return nullptr; - } - - SLANG_NO_THROW slang::ISession* EntryPointCapture::getSession() - { - slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); - - 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( - SlangInt targetIndex, - slang::IBlob** outDiagnostics) - { - slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); - - 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; - } - - SLANG_NO_THROW SlangResult EntryPointCapture::getEntryPointCode( - SlangInt entryPointIndex, - SlangInt targetIndex, - slang::IBlob** outCode, - 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; - } - - SLANG_NO_THROW SlangResult EntryPointCapture::getTargetCode( - SlangInt targetIndex, - slang::IBlob** outCode, - 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; - } - - SLANG_NO_THROW SlangResult EntryPointCapture::getResultAsFileSystem( - SlangInt entryPointIndex, - SlangInt targetIndex, - 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; - } - - SLANG_NO_THROW void EntryPointCapture::getEntryPointHash( - SlangInt entryPointIndex, - SlangInt targetIndex, - 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( - 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::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; - } - - SLANG_NO_THROW SlangResult EntryPointCapture::link( - slang::IComponentType** outLinkedComponentType, - 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; - } - - SLANG_NO_THROW SlangResult EntryPointCapture::getEntryPointHostCallable( - int entryPointIndex, - int targetIndex, - ISlangSharedLibrary** outSharedLibrary, - 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; - } - - SLANG_NO_THROW SlangResult EntryPointCapture::renameEntryPoint( - 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; - } - - SLANG_NO_THROW SlangResult EntryPointCapture::linkWithOptions( - IComponentType** outLinkedComponentType, - uint32_t compilerOptionEntryCount, - slang::CompilerOptionEntry* compilerOptionEntries, - 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; - } - - SLANG_NO_THROW slang::FunctionReflection* EntryPointCapture::getFunctionReflection() - { - return m_actualEntryPoint->getFunctionReflection(); - } - -} diff --git a/source/slang-capture-replay/slang-global-session.cpp b/source/slang-capture-replay/slang-global-session.cpp deleted file mode 100644 index d8f1e361d..000000000 --- a/source/slang-capture-replay/slang-global-session.cpp +++ /dev/null @@ -1,451 +0,0 @@ -#include "slang-global-session.h" -#include "slang-session.h" -#include "slang-filesystem.h" -#include "../slang/slang-compiler.h" -#include "capture_utility.h" - -namespace SlangCapture -{ - // constructor is called in slang_createGlobalSession - GlobalSessionCapture::GlobalSessionCapture(slang::IGlobalSession* session): - m_actualGlobalSession(session) - { - SLANG_CAPTURE_ASSERT(m_actualGlobalSession != nullptr); - - m_globalSessionHandle = reinterpret_cast<SlangCapture::AddressFormat>(m_actualGlobalSession.get()); - m_captureManager = std::make_unique<CaptureManager>(m_globalSessionHandle); - - // 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() - { - m_actualGlobalSession->release(); - } - - SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionCapture::queryInterface(SlangUUID const& uuid, void** outObject) - { - if (uuid == Session::getTypeGuid()) - { - // no add-ref here, the query will cause the inner session to handle the add-ref. - this->m_actualGlobalSession->queryInterface(uuid, outObject); - return SLANG_OK; - } - - if (uuid == ISlangUnknown::getTypeGuid() && uuid == IGlobalSession::getTypeGuid()) - { - addReference(); - *outObject = static_cast<slang::IGlobalSession*>(this); - return SLANG_OK; - } - - return SLANG_E_NO_INTERFACE; - } - - SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionCapture::createSession(slang::SessionDesc const& desc, slang::ISession** outSession) - { - setLogLevel(); - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - - slang::ISession* actualSession = nullptr; - - ParameterEncoder* encoder{}; - { - encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_createSession, m_globalSessionHandle); - encoder->encodeStruct(desc); - encoder = m_captureManager->endMethodCapture(); - } - - SlangResult res = m_actualGlobalSession->createSession(desc, &actualSession); - - { // capture output - encoder->encodeAddress(actualSession); - m_captureManager->endMethodCaptureAppendOutput(); - } - - if (actualSession != nullptr) - { - // reset the file system to our capture file system. After createSession() call, - // 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(), m_captureManager.get()); - - Slang::ComPtr<FileSystemCapture> resultFileSystemCapture(fileSystemCapture); - linkage->setFileSystem(resultFileSystemCapture.detach()); - - SessionCapture* sessionCapture = new SessionCapture(actualSession, m_captureManager.get()); - Slang::ComPtr<SessionCapture> result(sessionCapture); - *outSession = result.detach(); - } - - return res; - } - - SLANG_NO_THROW SlangProfileID SLANG_MCALL GlobalSessionCapture::findProfile(char const* name) - { - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - - ParameterEncoder* encoder {}; - { - encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_findProfile, m_globalSessionHandle); - encoder->encodeString(name); - encoder = m_captureManager->endMethodCapture(); - } - - SlangProfileID profileId = m_actualGlobalSession->findProfile(name); - return profileId; - } - - SLANG_NO_THROW void SLANG_MCALL GlobalSessionCapture::setDownstreamCompilerPath(SlangPassThrough passThrough, char const* path) - { - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - - ParameterEncoder* encoder {}; - { - encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_setDownstreamCompilerPath, m_globalSessionHandle); - encoder->encodeEnumValue(passThrough); - encoder->encodeString(path); - m_captureManager->endMethodCapture(); - } - - m_actualGlobalSession->setDownstreamCompilerPath(passThrough, path); - } - - SLANG_NO_THROW void SLANG_MCALL GlobalSessionCapture::setDownstreamCompilerPrelude(SlangPassThrough inPassThrough, char const* prelude) - { - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - - ParameterEncoder* encoder {}; - { - encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_setDownstreamCompilerPrelude, m_globalSessionHandle); - encoder->encodeEnumValue(inPassThrough); - encoder->encodeString(prelude); - m_captureManager->endMethodCapture(); - } - - m_actualGlobalSession->setDownstreamCompilerPrelude(inPassThrough, prelude); - } - - SLANG_NO_THROW void SLANG_MCALL GlobalSessionCapture::getDownstreamCompilerPrelude(SlangPassThrough inPassThrough, ISlangBlob** outPrelude) - { - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - - ParameterEncoder* encoder {}; - { - encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_getDownstreamCompilerPrelude, m_globalSessionHandle); - encoder->encodeEnumValue(inPassThrough); - encoder = m_captureManager->endMethodCapture(); - } - - m_actualGlobalSession->getDownstreamCompilerPrelude(inPassThrough, outPrelude); - - { - encoder->encodeAddress(*outPrelude); - m_captureManager->endMethodCaptureAppendOutput(); - } - } - - SLANG_NO_THROW const char* SLANG_MCALL GlobalSessionCapture::getBuildTagString() - { - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - - // No need to capture this function. It's just a query function and it won't impact the internal state. - const char* resStr = m_actualGlobalSession->getBuildTagString(); - return resStr; - } - - SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionCapture::setDefaultDownstreamCompiler(SlangSourceLanguage sourceLanguage, SlangPassThrough defaultCompiler) - { - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - - ParameterEncoder* encoder {}; - { - encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_setDefaultDownstreamCompiler, m_globalSessionHandle); - encoder->encodeEnumValue(sourceLanguage); - encoder->encodeEnumValue(defaultCompiler); - encoder = m_captureManager->endMethodCapture(); - } - - SlangResult res = m_actualGlobalSession->setDefaultDownstreamCompiler(sourceLanguage, defaultCompiler); - return res; - } - - SLANG_NO_THROW SlangPassThrough SLANG_MCALL GlobalSessionCapture::getDefaultDownstreamCompiler(SlangSourceLanguage sourceLanguage) - { - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - - ParameterEncoder* encoder {}; - { - encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_getDefaultDownstreamCompiler, m_globalSessionHandle); - encoder->encodeEnumValue(sourceLanguage); - encoder = m_captureManager->endMethodCapture(); - } - - SlangPassThrough passThrough = m_actualGlobalSession->getDefaultDownstreamCompiler(sourceLanguage); - return passThrough; - } - - SLANG_NO_THROW void SLANG_MCALL GlobalSessionCapture::setLanguagePrelude(SlangSourceLanguage inSourceLanguage, char const* prelude) - { - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - - ParameterEncoder* encoder {}; - { - encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_setLanguagePrelude, m_globalSessionHandle); - encoder->encodeEnumValue(inSourceLanguage); - encoder->encodeString(prelude); - encoder = m_captureManager->endMethodCapture(); - } - - m_actualGlobalSession->setLanguagePrelude(inSourceLanguage, prelude); - } - - SLANG_NO_THROW void SLANG_MCALL GlobalSessionCapture::getLanguagePrelude(SlangSourceLanguage inSourceLanguage, ISlangBlob** outPrelude) - { - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - - ParameterEncoder* encoder {}; - { - encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_getLanguagePrelude, m_globalSessionHandle); - encoder->encodeEnumValue(inSourceLanguage); - encoder = m_captureManager->endMethodCapture(); - } - - m_actualGlobalSession->getLanguagePrelude(inSourceLanguage, outPrelude); - - { - encoder->encodeAddress(*outPrelude); - m_captureManager->endMethodCaptureAppendOutput(); - } - } - - SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionCapture::createCompileRequest(slang::ICompileRequest** outCompileRequest) - { - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - - ParameterEncoder* encoder {}; - { - encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_createCompileRequest, m_globalSessionHandle); - encoder = m_captureManager->endMethodCapture(); - } - - SlangResult res = m_actualGlobalSession->createCompileRequest(outCompileRequest); - - { - encoder->encodeAddress(*outCompileRequest); - m_captureManager->endMethodCaptureAppendOutput(); - } - - return res; - } - - SLANG_NO_THROW void SLANG_MCALL GlobalSessionCapture::addBuiltins(char const* sourcePath, char const* sourceString) - { - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - ParameterEncoder* encoder {}; - { - encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_addBuiltins, m_globalSessionHandle); - encoder->encodeString(sourcePath); - encoder->encodeString(sourceString); - encoder = m_captureManager->endMethodCapture(); - } - - m_actualGlobalSession->addBuiltins(sourcePath, sourceString); - } - - SLANG_NO_THROW void SLANG_MCALL GlobalSessionCapture::setSharedLibraryLoader(ISlangSharedLibraryLoader* loader) - { - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - // TODO: Not sure if we need to capture this function. Because this functions is something like the file system - // override, it's provided by user code. So capturing it makes no sense. The only way is to wrapper this interface - // by our own implementation, and capture it there. - m_actualGlobalSession->setSharedLibraryLoader(loader); - } - - SLANG_NO_THROW ISlangSharedLibraryLoader* SLANG_MCALL GlobalSessionCapture::getSharedLibraryLoader() - { - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - - ParameterEncoder* encoder {}; - { - encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_getSharedLibraryLoader, m_globalSessionHandle); - encoder = m_captureManager->endMethodCapture(); - } - - ISlangSharedLibraryLoader* loader = m_actualGlobalSession->getSharedLibraryLoader(); - - { - encoder->encodeAddress(loader); - m_captureManager->endMethodCaptureAppendOutput(); - } - return loader; - } - - SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionCapture::checkCompileTargetSupport(SlangCompileTarget target) - { - // No need to capture this function. It's just a query function and it won't impact the internal state. - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - SlangResult res = m_actualGlobalSession->checkCompileTargetSupport(target); - return res; - } - - SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionCapture::checkPassThroughSupport(SlangPassThrough passThrough) - { - // No need to capture this function. It's just a query function and it won't impact the internal state. - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - SlangResult res = m_actualGlobalSession->checkPassThroughSupport(passThrough); - return res; - } - - SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionCapture::compileStdLib(slang::CompileStdLibFlags flags) - { - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - - ParameterEncoder* encoder {}; - { - encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_compileStdLib, m_globalSessionHandle); - encoder->encodeEnumValue(flags); - m_captureManager->endMethodCapture(); - } - - SlangResult res = m_actualGlobalSession->compileStdLib(flags); - return res; - } - - SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionCapture::loadStdLib(const void* stdLib, size_t stdLibSizeInBytes) - { - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - - ParameterEncoder* encoder {}; - { - encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_loadStdLib, m_globalSessionHandle); - encoder->encodePointer(stdLib, false, stdLibSizeInBytes); - m_captureManager->endMethodCapture(); - } - - SlangResult res = m_actualGlobalSession->loadStdLib(stdLib, stdLibSizeInBytes); - return res; - } - - SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionCapture::saveStdLib(SlangArchiveType archiveType, ISlangBlob** outBlob) - { - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - - ParameterEncoder* encoder {}; - { - encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_saveStdLib, m_globalSessionHandle); - encoder->encodeEnumValue(archiveType); - encoder = m_captureManager->endMethodCapture(); - } - - SlangResult res = m_actualGlobalSession->saveStdLib(archiveType, outBlob); - - { - encoder->encodeAddress(*outBlob); - m_captureManager->endMethodCaptureAppendOutput(); - } - return res; - } - - SLANG_NO_THROW SlangCapabilityID SLANG_MCALL GlobalSessionCapture::findCapability(char const* name) - { - // No need to capture this function. It's just a query function and it won't impact the internal state. - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - SlangCapabilityID capId = m_actualGlobalSession->findCapability(name); - return capId; - } - - SLANG_NO_THROW void SLANG_MCALL GlobalSessionCapture::setDownstreamCompilerForTransition(SlangCompileTarget source, SlangCompileTarget target, SlangPassThrough compiler) - { - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - - ParameterEncoder* encoder {}; - { - encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_setDownstreamCompilerForTransition, m_globalSessionHandle); - encoder->encodeEnumValue(source); - encoder->encodeEnumValue(target); - encoder->encodeEnumValue(compiler); - m_captureManager->endMethodCapture(); - } - - m_actualGlobalSession->setDownstreamCompilerForTransition(source, target, compiler); - } - - SLANG_NO_THROW SlangPassThrough SLANG_MCALL GlobalSessionCapture::getDownstreamCompilerForTransition(SlangCompileTarget source, SlangCompileTarget target) - { - // No need to capture this function. It's just a query function and it won't impact the internal state. - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - SlangPassThrough passThrough = m_actualGlobalSession->getDownstreamCompilerForTransition(source, target); - return passThrough; - } - - SLANG_NO_THROW void SLANG_MCALL GlobalSessionCapture::getCompilerElapsedTime(double* outTotalTime, double* outDownstreamTime) - { - // No need to capture this function. It's just a query function and it won't impact the internal state. - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - m_actualGlobalSession->getCompilerElapsedTime(outTotalTime, outDownstreamTime); - } - - SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionCapture::setSPIRVCoreGrammar(char const* jsonPath) - { - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - - ParameterEncoder* encoder {}; - { - encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_setSPIRVCoreGrammar, m_globalSessionHandle); - encoder->encodeString(jsonPath); - m_captureManager->endMethodCapture(); - } - - SlangResult res = m_actualGlobalSession->setSPIRVCoreGrammar(jsonPath); - return res; - } - - SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionCapture::parseCommandLineArguments( - int argc, const char* const* argv, slang::SessionDesc* outSessionDesc, ISlangUnknown** outAllocation) - { - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - - ParameterEncoder* encoder {}; - { - encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_parseCommandLineArguments, m_globalSessionHandle); - encoder->encodeStringArray(argv, argc); - encoder = m_captureManager->endMethodCapture(); - } - - SlangResult res = m_actualGlobalSession->parseCommandLineArguments(argc, argv, outSessionDesc, outAllocation); - - { - encoder->encodeStruct(*outSessionDesc); - encoder->encodeAddress(*outAllocation); - m_captureManager->endMethodCaptureAppendOutput(); - } - return res; - } - - SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionCapture::getSessionDescDigest(slang::SessionDesc* sessionDesc, ISlangBlob** outBlob) - { - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); - - ParameterEncoder* encoder {}; - { - encoder = m_captureManager->beginMethodCapture(ApiCallId::IGlobalSession_getSessionDescDigest, m_globalSessionHandle); - encoder->encodeStruct(*sessionDesc); - encoder = m_captureManager->endMethodCapture(); - } - - SlangResult res = m_actualGlobalSession->getSessionDescDigest(sessionDesc, outBlob); - - { - encoder->encodeAddress(*outBlob); - m_captureManager->endMethodCaptureAppendOutput(); - } - return res; - } -} diff --git a/source/slang-capture-replay/slang-module.cpp b/source/slang-capture-replay/slang-module.cpp deleted file mode 100644 index 273faa59d..000000000 --- a/source/slang-capture-replay/slang-module.cpp +++ /dev/null @@ -1,506 +0,0 @@ -#include "capture_utility.h" -#include "slang-module.h" - -namespace SlangCapture -{ - 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); - } - - ModuleCapture::~ModuleCapture() - { - m_actualModule->release(); - } - - ISlangUnknown* ModuleCapture::getInterface(const Guid& guid) - { - if(guid == ModuleCapture::getTypeGuid()) - return static_cast<ISlangUnknown*>(this); - else - return nullptr; - } - - SLANG_NO_THROW slang::DeclReflection* ModuleCapture::getModuleReflection() - { - // No need to capture this call as it is just a query. - slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); - slang::DeclReflection* res = (slang::DeclReflection*)m_actualModule->getModuleReflection(); - return res; - } - - SLANG_NO_THROW SlangResult ModuleCapture::findEntryPointByName( - char const* name, - slang::IEntryPoint** outEntryPoint) - { - 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); - *outEntryPoint = static_cast<slang::IEntryPoint*>(entryPointCapture); - } - return res; - } - - 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; - } - - SLANG_NO_THROW SlangResult ModuleCapture::getDefinedEntryPoint(SlangInt32 index, slang::IEntryPoint** outEntryPoint) - { - // 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); - if (!entryPointCapture) - { - SLANG_CAPTURE_ASSERT(!"Entrypoint not found in mapEntryPointToCapture"); - } - *outEntryPoint = static_cast<slang::IEntryPoint*>(entryPointCapture); - } - else - *outEntryPoint = nullptr; - - return res; - } - - 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; - } - - 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; - } - - 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; - } - - SLANG_NO_THROW SlangResult ModuleCapture::findAndCheckEntryPoint( - char const* name, - SlangStage stage, - slang::IEntryPoint** outEntryPoint, - ISlangBlob** outDiagnostics) - { - 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); - *outEntryPoint = static_cast<slang::IEntryPoint*>(entryPointCapture); - } - return res; - } - - SLANG_NO_THROW SlangInt32 ModuleCapture::getDependencyFileCount() - { - // No need to capture this call as it is just a query. - slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); - SlangInt32 res = m_actualModule->getDependencyFileCount(); - return res; - } - - SLANG_NO_THROW char const* ModuleCapture::getDependencyFilePath(SlangInt32 index) - { - // No need to capture this call as it is just a query. - slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); - const char* res = m_actualModule->getDependencyFilePath(index); - return res; - } - - 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; - } - - SLANG_NO_THROW slang::ProgramLayout* ModuleCapture::getLayout( - SlangInt targetIndex, - 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; - } - - SLANG_NO_THROW SlangResult ModuleCapture::getEntryPointCode( - SlangInt entryPointIndex, - SlangInt targetIndex, - slang::IBlob** outCode, - 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; - } - - SLANG_NO_THROW SlangResult ModuleCapture::getTargetCode( - SlangInt targetIndex, - slang::IBlob** outCode, - 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; - } - - SLANG_NO_THROW SlangResult ModuleCapture::getResultAsFileSystem( - SlangInt entryPointIndex, - SlangInt targetIndex, - 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; - } - - SLANG_NO_THROW void ModuleCapture::getEntryPointHash( - SlangInt entryPointIndex, - SlangInt targetIndex, - 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( - 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::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; - } - - SLANG_NO_THROW SlangResult ModuleCapture::link( - IComponentType** outLinkedComponentType, - 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; - } - - SLANG_NO_THROW SlangResult ModuleCapture::getEntryPointHostCallable( - int entryPointIndex, - int targetIndex, - ISlangSharedLibrary** outSharedLibrary, - 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; - } - - SLANG_NO_THROW SlangResult ModuleCapture::renameEntryPoint( - 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; - } - - SLANG_NO_THROW SlangResult ModuleCapture::linkWithOptions( - IComponentType** outLinkedComponentType, - uint32_t compilerOptionEntryCount, - slang::CompilerOptionEntry* compilerOptionEntries, - 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; - } - - EntryPointCapture* ModuleCapture::getEntryPointCapture(slang::IEntryPoint* entryPoint) - { - EntryPointCapture* entryPointCapture = nullptr; - entryPointCapture = m_mapEntryPointToCapture.tryGetValue(entryPoint); - if (!entryPointCapture) - { - entryPointCapture = new EntryPointCapture(entryPoint, m_captureManager); - Slang::ComPtr<EntryPointCapture> result(entryPointCapture); - m_mapEntryPointToCapture.add(entryPoint, *result.detach()); - } - return entryPointCapture; - } -} diff --git a/source/slang-capture-replay/slang-session.cpp b/source/slang-capture-replay/slang-session.cpp deleted file mode 100644 index ee9fd9549..000000000 --- a/source/slang-capture-replay/slang-session.cpp +++ /dev/null @@ -1,517 +0,0 @@ -#include "capture_utility.h" -#include "slang-session.h" -#include "slang-entrypoint.h" -#include "slang-composite-component-type.h" -#include "slang-type-conformance.h" - -namespace SlangCapture -{ - - 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); - } - - SessionCapture::~SessionCapture() - { - m_actualSession->release(); - } - - ISlangUnknown* SessionCapture::getInterface(const Guid& guid) - { - if(guid == ISlangUnknown::getTypeGuid() || guid == ISession::getTypeGuid()) - return asExternal(this); - - return nullptr; - } - - 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; - } - - SLANG_NO_THROW slang::IModule* SessionCapture::loadModule( - const char* moduleName, - 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); - } - - SLANG_NO_THROW slang::IModule* SessionCapture::loadModuleFromIRBlob( - const char* moduleName, - const char* path, - slang::IBlob* source, - 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); - } - - SLANG_NO_THROW slang::IModule* SessionCapture::loadModuleFromSource( - const char* moduleName, - const char* path, - slang::IBlob* source, - 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); - } - - SLANG_NO_THROW slang::IModule* SessionCapture::loadModuleFromSourceString( - const char* moduleName, - const char* path, - const char* string, - 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); - } - - SLANG_NO_THROW SlangResult SessionCapture::createCompositeComponentType( - slang::IComponentType* const* componentTypes, - SlangInt componentTypeCount, - slang::IComponentType** outCompositeComponentType, - ISlangBlob** outDiagnostics) - { - slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); - - Slang::List<slang::IComponentType*> componentTypeList; - - // get the actual component types from our capture wrappers - if(SLANG_OK != getActualComponentTypes(componentTypes, componentTypeCount, componentTypeList)) - { - 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, m_captureManager); - Slang::ComPtr<CompositeComponentTypeCapture> resultCapture(compositeComponentTypeCapture); - *outCompositeComponentType = resultCapture.detach(); - } - - return result; - } - - SLANG_NO_THROW slang::TypeReflection* SessionCapture::specializeType( - slang::TypeReflection* type, - slang::SpecializationArg const* specializationArgs, - SlangInt specializationArgCount, - 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; - } - - SLANG_NO_THROW slang::TypeLayoutReflection* SessionCapture::getTypeLayout( - slang::TypeReflection* type, - SlangInt targetIndex, - slang::LayoutRules rules, - 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; - } - - SLANG_NO_THROW slang::TypeReflection* SessionCapture::getContainerType( - slang::TypeReflection* elementType, - slang::ContainerType containerType, - 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; - } - - SLANG_NO_THROW SlangResult SessionCapture::getTypeRTTIMangledName( - slang::TypeReflection* type, - 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; - } - - SLANG_NO_THROW SlangResult SessionCapture::getTypeConformanceWitnessMangledName( - slang::TypeReflection* type, - slang::TypeReflection* interfaceType, - 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; - } - - SLANG_NO_THROW SlangResult SessionCapture::getTypeConformanceWitnessSequentialID( - slang::TypeReflection* type, - slang::TypeReflection* interfaceType, - 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; - } - - SLANG_NO_THROW SlangResult SessionCapture::createTypeConformanceComponentType( - slang::TypeReflection* type, - slang::TypeReflection* interfaceType, - slang::ITypeConformance** outConformance, - SlangInt conformanceIdOverride, - ISlangBlob** outDiagnostics) - { - 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, m_captureManager); - Slang::ComPtr<TypeConformanceCapture> resultCapture(conformanceCapture); - *outConformance = resultCapture.detach(); - } - - return result; - } - - SLANG_NO_THROW SlangResult SessionCapture::createCompileRequest( - 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; - } - - 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); - if (!moduleCapture) - { - SLANG_CAPTURE_ASSERT(!"Module not found in mapModuleToCapture"); - } - return static_cast<slang::IModule*>(moduleCapture); - } - - return pModule; - } - - 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; - } - - ModuleCapture* SessionCapture::getModuleCapture(slang::IModule* module) - { - ModuleCapture* moduleCapture = nullptr; - moduleCapture = m_mapModuleToCapture.tryGetValue(module); - if (!moduleCapture) - { - moduleCapture = new ModuleCapture(module, m_captureManager); - Slang::ComPtr<ModuleCapture> result(moduleCapture); - m_mapModuleToCapture.add(module, *result.detach()); - } - return moduleCapture; - } - - SlangResult SessionCapture::getActualComponentTypes( - slang::IComponentType* const* componentTypes, - SlangInt componentTypeCount, - List<slang::IComponentType*>& outActualComponentTypes) - { - for (SlangInt i = 0; i < componentTypeCount; i++) - { - slang::IComponentType* const& componentType = componentTypes[i]; - void* outObj = nullptr; - - if (componentType->queryInterface(ModuleCapture::getTypeGuid(), &outObj) == SLANG_OK) - { - ModuleCapture* moduleCapture = static_cast<ModuleCapture*>(outObj); - outActualComponentTypes.add(moduleCapture->getActualModule()); - } - else if (componentType->queryInterface(EntryPointCapture::getTypeGuid(), &outObj) == SLANG_OK) - { - EntryPointCapture* entrypointCapture = static_cast<EntryPointCapture*>(outObj); - outActualComponentTypes.add(entrypointCapture->getActualEntryPoint()); - } - // will fall back to the actual component type, it means that we didn't capture this type. - else - { - outActualComponentTypes.add(componentType); - } - } - - if (componentTypeCount == outActualComponentTypes.getCount()) - { - return SLANG_OK; - } - return SLANG_FAIL; - } -} // namespace SlangCapture diff --git a/source/slang-capture-replay/slang-type-conformance.cpp b/source/slang-capture-replay/slang-type-conformance.cpp deleted file mode 100644 index 3eb108510..000000000 --- a/source/slang-capture-replay/slang-type-conformance.cpp +++ /dev/null @@ -1,310 +0,0 @@ -#include "capture_utility.h" -#include "slang-type-conformance.h" - -namespace SlangCapture -{ - 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(); - } - - ISlangUnknown* TypeConformanceCapture::getInterface(const Guid& guid) - { - if (guid == TypeConformanceCapture::getTypeGuid()) - { - return static_cast<ISlangUnknown*>(this); - } - else - { - return nullptr; - } - } - - 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; - } - - SLANG_NO_THROW slang::ProgramLayout* TypeConformanceCapture::getLayout( - SlangInt targetIndex, - slang::IBlob** outDiagnostics) - { - slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); - - 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() - { - slangCaptureLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); - SlangInt res = m_actualTypeConformance->getSpecializationParamCount(); - return res; - } - - SLANG_NO_THROW SlangResult TypeConformanceCapture::getEntryPointCode( - SlangInt entryPointIndex, - SlangInt targetIndex, - slang::IBlob** outCode, - 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; - } - - SLANG_NO_THROW SlangResult TypeConformanceCapture::getTargetCode( - SlangInt targetIndex, - slang::IBlob** outCode, - 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; - } - - SLANG_NO_THROW SlangResult TypeConformanceCapture::getResultAsFileSystem( - SlangInt entryPointIndex, - SlangInt targetIndex, - 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; - } - - SLANG_NO_THROW void TypeConformanceCapture::getEntryPointHash( - SlangInt entryPointIndex, - SlangInt targetIndex, - 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) - { - 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; - } - - SLANG_NO_THROW SlangResult TypeConformanceCapture::link( - slang::IComponentType** outLinkedComponentType, - 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; - } - - SLANG_NO_THROW SlangResult TypeConformanceCapture::getEntryPointHostCallable( - int entryPointIndex, - int targetIndex, - ISlangSharedLibrary** outSharedLibrary, - 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; - } - - SLANG_NO_THROW SlangResult TypeConformanceCapture::renameEntryPoint( - 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; - } - - SLANG_NO_THROW SlangResult TypeConformanceCapture::linkWithOptions( - IComponentType** outLinkedComponentType, - uint32_t compilerOptionEntryCount, - slang::CompilerOptionEntry* compilerOptionEntries, - 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/output-stream.cpp b/source/slang-record-replay/record/output-stream.cpp index 97c4b098b..8575d19d0 100644 --- a/source/slang-capture-replay/output-stream.cpp +++ b/source/slang-record-replay/record/output-stream.cpp @@ -1,7 +1,7 @@ #include "output-stream.h" -#include "capture_utility.h" +#include "../util/record-utility.h" -namespace SlangCapture +namespace SlangRecord { FileOutputStream::FileOutputStream(const std::string& filename, bool append) { @@ -14,7 +14,7 @@ namespace SlangCapture if (res != SLANG_OK) { - SlangCapture::slangCaptureLog(SlangCapture::LogLevel::Error, "Failed to open file %s\n", filename.c_str()); + SlangRecord::slangRecordLog(SlangRecord::LogLevel::Error, "Failed to open file %s\n", filename.c_str()); std::abort(); } } @@ -26,7 +26,7 @@ namespace SlangCapture void FileOutputStream::write(const void* data, size_t len) { - SLANG_CAPTURE_CHECK(m_fileStream.write(data, len)); + SLANG_RECORD_CHECK(m_fileStream.write(data, len)); } MemoryStream::MemoryStream() @@ -35,12 +35,12 @@ namespace SlangCapture void FileOutputStream::flush() { - SLANG_CAPTURE_CHECK(m_fileStream.flush()); + SLANG_RECORD_CHECK(m_fileStream.flush()); } void MemoryStream::write(const void* data, size_t len) { - SLANG_CAPTURE_CHECK(m_memoryStream.write(data, len)); + SLANG_RECORD_CHECK(m_memoryStream.write(data, len)); } void MemoryStream::flush() diff --git a/source/slang-capture-replay/output-stream.h b/source/slang-record-replay/record/output-stream.h index 1f2c882b0..770c2aeac 100644 --- a/source/slang-capture-replay/output-stream.h +++ b/source/slang-record-replay/record/output-stream.h @@ -2,9 +2,9 @@ #define OUTPUT_STREAM_H #include <string> -#include "../core/slang-stream.h" +#include "../../core/slang-stream.h" -namespace SlangCapture +namespace SlangRecord { class OutputStream { @@ -42,5 +42,5 @@ namespace SlangCapture private: Slang::OwnedMemoryStream m_memoryStream; }; -} // namespace SlangCapture +} // namespace SlangRecord #endif // OUTPUT_STREAM_H diff --git a/source/slang-record-replay/record/parameter-recorder.cpp b/source/slang-record-replay/record/parameter-recorder.cpp new file mode 100644 index 000000000..1c2fd9609 --- /dev/null +++ b/source/slang-record-replay/record/parameter-recorder.cpp @@ -0,0 +1,123 @@ +#include "parameter-recorder.h" + +namespace SlangRecord +{ + void ParameterRecorder::recordStruct(slang::SessionDesc const& desc) + { + recordUint64(desc.structureSize); + recordInt64(desc.targetCount); + + for (SlangInt i = 0; i < desc.targetCount; i++) + { + recordStruct(desc.targets[i]); + } + + recordUint32(desc.flags); + recordEnumValue(desc.defaultMatrixLayoutMode); + recordInt64(desc.searchPathCount); + for (SlangInt i = 0; i < desc.searchPathCount; i++) + { + recordString(desc.searchPaths[i]); + } + + recordInt64(desc.preprocessorMacroCount); + for (SlangInt i = 0; i < desc.preprocessorMacroCount; i++) + { + recordStruct(desc.preprocessorMacros[i]); + } + + recordBool(desc.enableEffectAnnotations); + recordBool(desc.allowGLSLSyntax); + + recordUint32(desc.compilerOptionEntryCount); + for (uint32_t i = 0; i < desc.compilerOptionEntryCount; i++) + { + recordStruct(desc.compilerOptionEntries[i]); + } + } + + void ParameterRecorder::recordStruct(slang::PreprocessorMacroDesc const& desc) + { + recordString(desc.name); + recordString(desc.value); + } + + void ParameterRecorder::recordStruct(slang::CompilerOptionEntry const& entry) + { + recordEnumValue(entry.name); + recordStruct(entry.value); + } + + void ParameterRecorder::recordStruct(slang::CompilerOptionValue const& value) + { + recordEnumValue(value.kind); + recordInt32(value.intValue0); + recordString(value.stringValue0); + recordString(value.stringValue1); + } + + void ParameterRecorder::recordStruct(slang::TargetDesc const& targetDesc) + { + recordUint64(targetDesc.structureSize); + recordEnumValue(targetDesc.format); + recordEnumValue(targetDesc.profile); + recordEnumValue(targetDesc.flags); + recordEnumValue(targetDesc.floatingPointMode); + recordEnumValue(targetDesc.lineDirectiveMode); + recordBool(targetDesc.forceGLSLScalarBufferLayout); + recordUint32(targetDesc.compilerOptionEntryCount); + for (uint32_t i = 0; i < targetDesc.compilerOptionEntryCount; i++) + { + recordStruct(targetDesc.compilerOptionEntries[i]); + } + } + + void ParameterRecorder::recordStruct(slang::SpecializationArg const& specializationArg) + { + recordEnumValue(specializationArg.kind); + recordAddress(specializationArg.type); + } + + void ParameterRecorder::recordPointer(const void* value, bool omitData, size_t size) + { + recordAddress(value); + if (omitData) + { + recordUint64(0llu); + return; + } + + recordUint64(size); + if (size) + { + m_stream->write(value, size); + } + } + + void ParameterRecorder::recordPointer(ISlangBlob* blob) + { + recordAddress(static_cast<const void*>(blob)); + + if (blob) + { + size_t size = blob->getBufferSize(); + const void* buffer = blob->getBufferPointer(); + recordPointer(buffer, false, size); + } + } + + // first 4-bytes is the length of the string + void ParameterRecorder::recordString(const char* value) + { + if (value == nullptr) + { + recordUint32(0); + } + else + { + uint32_t size = (uint32_t)strlen(value); + recordUint32(size); + m_stream->write(value, size); + } + } +} diff --git a/source/slang-record-replay/record/parameter-recorder.h b/source/slang-record-replay/record/parameter-recorder.h new file mode 100644 index 000000000..29bf39fb3 --- /dev/null +++ b/source/slang-record-replay/record/parameter-recorder.h @@ -0,0 +1,94 @@ +#ifndef PARAMETER_ENCODER_H +#define PARAMETER_ENCODER_H + +#include <cstdio> +#include <cinttypes> +#include <cstdint> + +#include "output-stream.h" +#include "../util/record-format.h" + +namespace SlangRecord +{ + class ParameterRecorder + { + public: + ParameterRecorder(OutputStream* stream) : m_stream(stream) {}; + void recordInt8(int8_t value) { recordValue(value); } + void recordUint8(uint8_t value) { recordValue(value); } + void recordInt16(int16_t value) { recordValue(value); } + void recordUint16(uint16_t value) { recordValue(value); } + void recordInt32(int32_t value) { recordValue(value); } + void recordUint32(uint32_t value) { recordValue(value); } + void recordInt64(int64_t value) { recordValue(value); } + void recordUint64(uint64_t value) { recordValue(value); } + void recordFloat(float value) { recordValue(value); } + void recordDouble(double value) { recordValue(value); } + void recordBool(bool value) { recordValue(value); } + + template<typename T> + void recordEnumValue(T value) { recordValue(static_cast<uint32_t>(value)); } + + void recordString(const char* value); + void recordPointer(const void* value, bool omitData = false, size_t size = 0); + void recordPointer(ISlangBlob* blob); + void recordAddress(const void* value) { recordValue(reinterpret_cast<SlangRecord::AddressFormat>(value)); } + + void recordStruct(slang::SessionDesc const& desc); + void recordStruct(slang::PreprocessorMacroDesc const& desc); + void recordStruct(slang::CompilerOptionEntry const& entry); + void recordStruct(slang::CompilerOptionValue const& value); + void recordStruct(slang::TargetDesc const& targetDesc); + void recordStruct(slang::SpecializationArg const& specializationArg); + + template <typename T> + void recordValueArray(const T* array, size_t count) + { + recordUint32((uint32_t)count); + for (size_t i = 0; i < count; ++i) + { + recordValue(array[i]); + } + } + + void recordStringArray(const char* const* array, size_t count) + { + recordUint32((uint32_t)count); + for (size_t i = 0; i < count; ++i) + { + recordString(array[i]); + } + } + + template <typename T> + void recordStructArray(T const* array, size_t count) + { + recordUint32((uint32_t)count); + for (size_t i = 0; i < count; ++i) + { + recordStruct(array[i]); + } + } + + template <typename T> + void recordAddressArray(T* const* array, size_t count) + { + recordUint32((uint32_t)count); + for (size_t i = 0; i < count; ++i) + { + recordAddress(array[i]); + } + } + + + private: + template <typename T> + void recordValue(T value) + { + m_stream->write(&value, sizeof(T)); + } + OutputStream* m_stream; + }; +} // namespace SlangRecord + +#endif // PARAMETER_ENCODER_H diff --git a/source/slang-capture-replay/capture-manager.cpp b/source/slang-record-replay/record/record-manager.cpp index 5ab40d93c..f10d2c704 100644 --- a/source/slang-capture-replay/capture-manager.cpp +++ b/source/slang-record-replay/record/record-manager.cpp @@ -2,34 +2,34 @@ #include <string> #include <sstream> #include <thread> -#include "capture_utility.h" -#include "capture-manager.h" +#include "../util/record-utility.h" +#include "record-manager.h" -namespace SlangCapture +namespace SlangRecord { - CaptureManager::CaptureManager(uint64_t globalSessionHandle) - : m_encoder(&m_memoryStream) + RecordManager::RecordManager(uint64_t globalSessionHandle) + : m_recorder(&m_memoryStream) { std::stringstream ss; ss << "gs-"<< globalSessionHandle <<"-t-"<<std::this_thread::get_id() << ".cap"; - m_captureFileDirectory = m_captureFileDirectory / "slang-capture"; + m_recordFileDirectory = m_recordFileDirectory / "slang-record"; - if (!std::filesystem::exists(m_captureFileDirectory)) + if (!std::filesystem::exists(m_recordFileDirectory)) { std::error_code ec; - if (!std::filesystem::create_directory(m_captureFileDirectory, ec)) + if (!std::filesystem::create_directory(m_recordFileDirectory, ec)) { - slangCaptureLog(LogLevel::Error, "Fail to create directory: %s, error (%d): %s\n", - m_captureFileDirectory.string().c_str(), ec.value(), ec.message().c_str()); + slangRecordLog(LogLevel::Error, "Fail to create directory: %s, error (%d): %s\n", + m_recordFileDirectory.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()); + std::filesystem::path recordFilePath = m_recordFileDirectory / ss.str(); + m_fileStream = std::make_unique<FileOutputStream>(recordFilePath.string()); } - void CaptureManager::clearWithHeader(const ApiCallId& callId, uint64_t handleId) + void RecordManager::clearWithHeader(const ApiCallId& callId, uint64_t handleId) { m_memoryStream.flush(); FunctionHeader header; @@ -40,7 +40,7 @@ namespace SlangCapture m_memoryStream.write(&header, sizeof(FunctionHeader)); } - void CaptureManager::clearWithTailer() + void RecordManager::clearWithTailer() { m_memoryStream.flush(); FunctionTailer tailer; @@ -49,13 +49,13 @@ namespace SlangCapture m_memoryStream.write(&tailer, sizeof(FunctionTailer)); } - ParameterEncoder* CaptureManager::beginMethodCapture(const ApiCallId& callId, uint64_t handleId) + ParameterRecorder* RecordManager::beginMethodRecord(const ApiCallId& callId, uint64_t handleId) { clearWithHeader(callId, handleId); - return &m_encoder; + return &m_recorder; } - ParameterEncoder* CaptureManager::endMethodCapture() + ParameterRecorder* RecordManager::endMethodRecord() { FunctionHeader* pHeader = const_cast<FunctionHeader*>( reinterpret_cast<const FunctionHeader*>(m_memoryStream.getData())); @@ -65,7 +65,7 @@ namespace SlangCapture std::hash<std::thread::id> hasher; pHeader->threadId = hasher(std::this_thread::get_id()); - // write capture data to file + // write record data to file m_fileStream->write(m_memoryStream.getData(), m_memoryStream.getSizeInBytes()); // take effect of the write @@ -75,17 +75,17 @@ namespace SlangCapture m_memoryStream.flush(); clearWithTailer(); - return &m_encoder; + return &m_recorder; } - void CaptureManager::endMethodCaptureAppendOutput() + void RecordManager::endMethodRecordAppendOutput() { FunctionTailer* pTailer = const_cast<FunctionTailer*>( reinterpret_cast<const FunctionTailer*>(m_memoryStream.getData())); pTailer->dataSizeInBytes = (uint32_t)(m_memoryStream.getSizeInBytes() - sizeof(FunctionTailer)); - // write capture data to file + // write record data to file m_fileStream->write(m_memoryStream.getData(), m_memoryStream.getSizeInBytes()); // take effect of the write diff --git a/source/slang-record-replay/record/record-manager.h b/source/slang-record-replay/record/record-manager.h new file mode 100644 index 000000000..40992e8ad --- /dev/null +++ b/source/slang-record-replay/record/record-manager.h @@ -0,0 +1,35 @@ +#ifndef RECORD_MANAGER_H +#define RECORD_MANAGER_H + +#include <filesystem> +#include "parameter-recorder.h" +#include "../util/record-format.h" + +namespace SlangRecord +{ + class RecordManager + { + public: + RecordManager(uint64_t globalSessionHandle); + + // Each method record has to start with a FunctionHeader + ParameterRecorder* beginMethodRecord(const ApiCallId& callId, uint64_t handleId); + ParameterRecorder* endMethodRecord(); + + // endMethodRecordAppendOutput is an optional call that can be used to append output to + // the end of the record. It has to start with a FunctionTailer + void endMethodRecordAppendOutput(); + + std::filesystem::path const& getRecordFileDirectory() const { return m_recordFileDirectory; } + + private: + void clearWithHeader(const ApiCallId& callId, uint64_t handleId); + void clearWithTailer(); + + MemoryStream m_memoryStream; + std::unique_ptr<FileOutputStream> m_fileStream; + std::filesystem::path m_recordFileDirectory = std::filesystem::current_path(); + ParameterRecorder m_recorder; + }; +} // namespace SlangRecord +#endif // RECORD_MANAGER_H diff --git a/source/slang-record-replay/record/slang-composite-component-type.cpp b/source/slang-record-replay/record/slang-composite-component-type.cpp new file mode 100644 index 000000000..ef594a893 --- /dev/null +++ b/source/slang-record-replay/record/slang-composite-component-type.cpp @@ -0,0 +1,309 @@ +#include "../util/record-utility.h" +#include "slang-composite-component-type.h" + +namespace SlangRecord +{ + CompositeComponentTypeRecorder::CompositeComponentTypeRecorder( + slang::IComponentType* componentType, RecordManager* recordManager) + : m_actualCompositeComponentType(componentType), + m_recordManager(recordManager) + { + SLANG_RECORD_ASSERT(m_actualCompositeComponentType != nullptr); + SLANG_RECORD_ASSERT(m_recordManager != nullptr); + + m_compositeComponentHandle = reinterpret_cast<uint64_t>(m_actualCompositeComponentType.get()); + slangRecordLog(LogLevel::Verbose, "%s: %p\n", __PRETTY_FUNCTION__, componentType); + } + + CompositeComponentTypeRecorder::~CompositeComponentTypeRecorder() + { + m_actualCompositeComponentType->release(); + } + + ISlangUnknown* CompositeComponentTypeRecorder::getInterface(const Guid& guid) + { + if (guid == IComponentType::getTypeGuid()) + { + return static_cast<ISlangUnknown*>(this); + } + return nullptr; + } + + SLANG_NO_THROW slang::ISession* CompositeComponentTypeRecorder::getSession() + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ICompositeComponentType_getSession, m_compositeComponentHandle); + recorder = m_recordManager->endMethodRecord(); + } + + slang::ISession* res = m_actualCompositeComponentType->getSession(); + + { + recorder->recordAddress(res); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW slang::ProgramLayout* CompositeComponentTypeRecorder::getLayout( + SlangInt targetIndex, + slang::IBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ICompositeComponentType_getLayout, m_compositeComponentHandle); + recorder->recordInt64(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + slang::ProgramLayout* programLayout = m_actualCompositeComponentType->getLayout(targetIndex, outDiagnostics); + + { + recorder->recordAddress(*outDiagnostics); + recorder->recordAddress(programLayout); + m_recordManager->endMethodRecordAppendOutput(); + } + + return programLayout; + } + + SLANG_NO_THROW SlangInt CompositeComponentTypeRecorder::getSpecializationParamCount() + { + // No need to record this call as it is just a query. + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + SlangInt res = m_actualCompositeComponentType->getSpecializationParamCount(); + return res; + } + + SLANG_NO_THROW SlangResult CompositeComponentTypeRecorder::getEntryPointCode( + SlangInt entryPointIndex, + SlangInt targetIndex, + slang::IBlob** outCode, + slang::IBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ICompositeComponentType_getEntryPointCode, m_compositeComponentHandle); + recorder->recordInt64(entryPointIndex); + recorder->recordInt64(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualCompositeComponentType->getEntryPointCode(entryPointIndex, targetIndex, outCode, outDiagnostics); + + { + recorder->recordAddress(*outCode); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult CompositeComponentTypeRecorder::getTargetCode( + SlangInt targetIndex, + slang::IBlob** outCode, + slang::IBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ICompositeComponentType_getTargetCode, m_compositeComponentHandle); + recorder->recordInt64(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualCompositeComponentType->getTargetCode(targetIndex, outCode, outDiagnostics); + + { + recorder->recordAddress(*outCode); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult CompositeComponentTypeRecorder::getResultAsFileSystem( + SlangInt entryPointIndex, + SlangInt targetIndex, + ISlangMutableFileSystem** outFileSystem) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ICompositeComponentType_getResultAsFileSystem, m_compositeComponentHandle); + recorder->recordInt64(entryPointIndex); + recorder->recordInt64(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualCompositeComponentType->getResultAsFileSystem(entryPointIndex, targetIndex, outFileSystem); + + { + recorder->recordAddress(*outFileSystem); + } + + // TODO: We might need to wrap the file system object. + return res; + } + + SLANG_NO_THROW void CompositeComponentTypeRecorder::getEntryPointHash( + SlangInt entryPointIndex, + SlangInt targetIndex, + slang::IBlob** outHash) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ICompositeComponentType_getEntryPointHash, m_compositeComponentHandle); + recorder->recordInt64(entryPointIndex); + recorder->recordInt64(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + m_actualCompositeComponentType->getEntryPointHash(entryPointIndex, targetIndex, outHash); + + { + recorder->recordAddress(*outHash); + m_recordManager->endMethodRecordAppendOutput(); + } + } + + SLANG_NO_THROW SlangResult CompositeComponentTypeRecorder::specialize( + slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, + slang::IComponentType** outSpecializedComponentType, + ISlangBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ICompositeComponentType_specialize, m_compositeComponentHandle); + recorder->recordInt64(specializationArgCount); + recorder->recordStructArray(specializationArgs, specializationArgCount); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualCompositeComponentType->specialize(specializationArgs, specializationArgCount, outSpecializedComponentType, outDiagnostics); + + { + recorder->recordAddress(*outSpecializedComponentType); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult CompositeComponentTypeRecorder::link( + slang::IComponentType** outLinkedComponentType, + ISlangBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ICompositeComponentType_link, m_compositeComponentHandle); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualCompositeComponentType->link(outLinkedComponentType, outDiagnostics); + + { + recorder->recordAddress(*outLinkedComponentType); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult CompositeComponentTypeRecorder::getEntryPointHostCallable( + int entryPointIndex, + int targetIndex, + ISlangSharedLibrary** outSharedLibrary, + slang::IBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ICompositeComponentType_getEntryPointHostCallable, m_compositeComponentHandle); + recorder->recordInt32(entryPointIndex); + recorder->recordInt32(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualCompositeComponentType->getEntryPointHostCallable(entryPointIndex, targetIndex, outSharedLibrary, outDiagnostics); + + { + recorder->recordAddress(*outSharedLibrary); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult CompositeComponentTypeRecorder::renameEntryPoint( + const char* newName, IComponentType** outEntryPoint) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ICompositeComponentType_renameEntryPoint, m_compositeComponentHandle); + recorder->recordString(newName); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualCompositeComponentType->renameEntryPoint(newName, outEntryPoint); + + { + recorder->recordAddress(*outEntryPoint); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult CompositeComponentTypeRecorder::linkWithOptions( + IComponentType** outLinkedComponentType, + uint32_t compilerOptionEntryCount, + slang::CompilerOptionEntry* compilerOptionEntries, + ISlangBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ICompositeComponentType_linkWithOptions, m_compositeComponentHandle); + recorder->recordUint32(compilerOptionEntryCount); + recorder->recordStructArray(compilerOptionEntries, compilerOptionEntryCount); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualCompositeComponentType->linkWithOptions(outLinkedComponentType, compilerOptionEntryCount, compilerOptionEntries, outDiagnostics); + + { + recorder->recordAddress(*outLinkedComponentType); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } +} diff --git a/source/slang-capture-replay/slang-composite-component-type.h b/source/slang-record-replay/record/slang-composite-component-type.h index 61ebe4cc0..758a59434 100644 --- a/source/slang-capture-replay/slang-composite-component-type.h +++ b/source/slang-record-replay/record/slang-composite-component-type.h @@ -4,22 +4,22 @@ #include "slang-com-ptr.h" #include "slang.h" #include "slang-com-helper.h" -#include "../core/slang-smart-pointer.h" -#include "../core/slang-dictionary.h" -#include "../slang/slang-compiler.h" -#include "capture-manager.h" +#include "../../core/slang-smart-pointer.h" +#include "../../core/slang-dictionary.h" +#include "../../slang/slang-compiler.h" +#include "record-manager.h" -namespace SlangCapture +namespace SlangRecord { using namespace Slang; - class CompositeComponentTypeCapture: public slang::IComponentType, public RefObject + class CompositeComponentTypeRecorder: public slang::IComponentType, public RefObject { public: SLANG_REF_OBJECT_IUNKNOWN_ALL ISlangUnknown* getInterface(const Guid& guid); - explicit CompositeComponentTypeCapture(slang::IComponentType* componentType, CaptureManager* captureManager); - ~CompositeComponentTypeCapture(); + explicit CompositeComponentTypeRecorder(slang::IComponentType* componentType, RecordManager* recordManager); + ~CompositeComponentTypeRecorder(); // Interfaces for `IComponentType` virtual SLANG_NO_THROW slang::ISession* SLANG_MCALL getSession() override; @@ -69,7 +69,7 @@ namespace SlangCapture private: Slang::ComPtr<slang::IComponentType> m_actualCompositeComponentType; uint64_t m_compositeComponentHandle = 0; - CaptureManager* m_captureManager = nullptr; + RecordManager* m_recordManager = nullptr; }; } diff --git a/source/slang-record-replay/record/slang-entrypoint.cpp b/source/slang-record-replay/record/slang-entrypoint.cpp new file mode 100644 index 000000000..d3bf3b47e --- /dev/null +++ b/source/slang-record-replay/record/slang-entrypoint.cpp @@ -0,0 +1,313 @@ +#include "../util/record-utility.h" +#include "slang-entrypoint.h" + +namespace SlangRecord +{ + EntryPointRecorder::EntryPointRecorder(slang::IEntryPoint* entryPoint, RecordManager* recordManager) + : m_actualEntryPoint(entryPoint), + m_recordManager(recordManager) + { + SLANG_RECORD_ASSERT(m_actualEntryPoint != nullptr); + SLANG_RECORD_ASSERT(m_recordManager != nullptr); + + m_entryPointHandle = reinterpret_cast<uint64_t>(m_actualEntryPoint.get()); + slangRecordLog(LogLevel::Verbose, "%s: %p\n", __PRETTY_FUNCTION__, entryPoint); + } + + EntryPointRecorder::~EntryPointRecorder() + { + m_actualEntryPoint->release(); + } + + ISlangUnknown* EntryPointRecorder::getInterface(const Guid& guid) + { + if(guid == EntryPointRecorder::getTypeGuid()) + return static_cast<ISlangUnknown*>(this); + else + return nullptr; + } + + SLANG_NO_THROW slang::ISession* EntryPointRecorder::getSession() + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IEntryPoint_getSession, m_entryPointHandle); + recorder = m_recordManager->endMethodRecord(); + } + + slang::ISession* session = m_actualEntryPoint->getSession(); + + { + recorder->recordAddress(session); + m_recordManager->endMethodRecordAppendOutput(); + } + + return session; + } + + SLANG_NO_THROW slang::ProgramLayout* EntryPointRecorder::getLayout( + SlangInt targetIndex, + slang::IBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IEntryPoint_getLayout, m_entryPointHandle); + recorder->recordInt64(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + slang::ProgramLayout* programLayout = m_actualEntryPoint->getLayout(targetIndex, outDiagnostics); + + { + recorder->recordAddress(*outDiagnostics); + recorder->recordAddress(programLayout); + m_recordManager->endMethodRecordAppendOutput(); + } + + return programLayout; + } + + SLANG_NO_THROW SlangInt EntryPointRecorder::getSpecializationParamCount() + { + // No need to record this call as it is just a query. + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + SlangInt res = m_actualEntryPoint->getSpecializationParamCount(); + return res; + } + + SLANG_NO_THROW SlangResult EntryPointRecorder::getEntryPointCode( + SlangInt entryPointIndex, + SlangInt targetIndex, + slang::IBlob** outCode, + slang::IBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IEntryPoint_getEntryPointCode, m_entryPointHandle); + recorder->recordInt64(entryPointIndex); + recorder->recordInt64(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualEntryPoint->getEntryPointCode(entryPointIndex, targetIndex, outCode, outDiagnostics); + + { + recorder->recordAddress(*outCode); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult EntryPointRecorder::getTargetCode( + SlangInt targetIndex, + slang::IBlob** outCode, + slang::IBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IEntryPoint_getTargetCode, m_entryPointHandle); + recorder->recordInt64(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualEntryPoint->getTargetCode(targetIndex, outCode, outDiagnostics); + + { + recorder->recordAddress(*outCode); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult EntryPointRecorder::getResultAsFileSystem( + SlangInt entryPointIndex, + SlangInt targetIndex, + ISlangMutableFileSystem** outFileSystem) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IEntryPoint_getResultAsFileSystem, m_entryPointHandle); + recorder->recordInt64(entryPointIndex); + recorder->recordInt64(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualEntryPoint->getResultAsFileSystem(entryPointIndex, targetIndex, outFileSystem); + + { + recorder->recordAddress(*outFileSystem); + } + + // TODO: We might need to wrap the file system object. + return res; + } + + SLANG_NO_THROW void EntryPointRecorder::getEntryPointHash( + SlangInt entryPointIndex, + SlangInt targetIndex, + slang::IBlob** outHash) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IEntryPoint_getEntryPointHash, m_entryPointHandle); + recorder->recordInt64(entryPointIndex); + recorder->recordInt64(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + m_actualEntryPoint->getEntryPointHash(entryPointIndex, targetIndex, outHash); + + { + recorder->recordAddress(*outHash); + m_recordManager->endMethodRecordAppendOutput(); + } + } + + SLANG_NO_THROW SlangResult EntryPointRecorder::specialize( + slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, + slang::IComponentType** outSpecializedComponentType, + ISlangBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IEntryPoint_specialize, m_entryPointHandle); + recorder->recordInt64(specializationArgCount); + recorder->recordStructArray(specializationArgs, specializationArgCount); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualEntryPoint->specialize(specializationArgs, specializationArgCount, outSpecializedComponentType, outDiagnostics); + + { + recorder->recordAddress(*outSpecializedComponentType); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult EntryPointRecorder::link( + slang::IComponentType** outLinkedComponentType, + ISlangBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IEntryPoint_link, m_entryPointHandle); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualEntryPoint->link(outLinkedComponentType, outDiagnostics); + + { + recorder->recordAddress(*outLinkedComponentType); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult EntryPointRecorder::getEntryPointHostCallable( + int entryPointIndex, + int targetIndex, + ISlangSharedLibrary** outSharedLibrary, + slang::IBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IEntryPoint_getEntryPointHostCallable, m_entryPointHandle); + recorder->recordInt32(entryPointIndex); + recorder->recordInt32(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualEntryPoint->getEntryPointHostCallable(entryPointIndex, targetIndex, outSharedLibrary, outDiagnostics); + + { + recorder->recordAddress(*outSharedLibrary); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult EntryPointRecorder::renameEntryPoint( + const char* newName, IComponentType** outEntryPoint) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IEntryPoint_renameEntryPoint, m_entryPointHandle); + recorder->recordString(newName); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualEntryPoint->renameEntryPoint(newName, outEntryPoint); + + { + recorder->recordAddress(*outEntryPoint); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult EntryPointRecorder::linkWithOptions( + IComponentType** outLinkedComponentType, + uint32_t compilerOptionEntryCount, + slang::CompilerOptionEntry* compilerOptionEntries, + ISlangBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IEntryPoint_linkWithOptions, m_entryPointHandle); + recorder->recordUint32(compilerOptionEntryCount); + recorder->recordStructArray(compilerOptionEntries, compilerOptionEntryCount); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualEntryPoint->linkWithOptions(outLinkedComponentType, compilerOptionEntryCount, compilerOptionEntries, outDiagnostics); + + { + recorder->recordAddress(*outLinkedComponentType); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW slang::FunctionReflection* EntryPointRecorder::getFunctionReflection() + { + return m_actualEntryPoint->getFunctionReflection(); + } + +} diff --git a/source/slang-capture-replay/slang-entrypoint.h b/source/slang-record-replay/record/slang-entrypoint.h index 5dbe9b14b..17c6fab6f 100644 --- a/source/slang-capture-replay/slang-entrypoint.h +++ b/source/slang-record-replay/record/slang-entrypoint.h @@ -4,15 +4,15 @@ #include "slang-com-ptr.h" #include "slang.h" #include "slang-com-helper.h" -#include "../core/slang-smart-pointer.h" -#include "../core/slang-dictionary.h" -#include "../slang/slang-compiler.h" -#include "capture-manager.h" +#include "../../core/slang-smart-pointer.h" +#include "../../core/slang-dictionary.h" +#include "../../slang/slang-compiler.h" +#include "record-manager.h" -namespace SlangCapture +namespace SlangRecord { using namespace Slang; - class EntryPointCapture : public slang::IEntryPoint, public RefObject + class EntryPointRecorder : public slang::IEntryPoint, public RefObject { public: SLANG_COM_INTERFACE(0xf4c1e23d, 0xb321, 0x4931, { 0x8f, 0x37, 0xf1, 0x22, 0x6a, 0xf9, 0x20, 0x85 }) @@ -20,8 +20,8 @@ namespace SlangCapture SLANG_REF_OBJECT_IUNKNOWN_ALL ISlangUnknown* getInterface(const Guid& guid); - explicit EntryPointCapture(slang::IEntryPoint* entryPoint, CaptureManager* captureManager); - ~EntryPointCapture(); + explicit EntryPointRecorder(slang::IEntryPoint* entryPoint, RecordManager* recordManager); + ~EntryPointRecorder(); // Interfaces for `IComponentType` virtual SLANG_NO_THROW slang::ISession* SLANG_MCALL getSession() override; @@ -71,7 +71,7 @@ namespace SlangCapture private: Slang::ComPtr<slang::IEntryPoint> m_actualEntryPoint; uint64_t m_entryPointHandle = 0; - CaptureManager* m_captureManager = nullptr; + RecordManager* m_recordManager = nullptr; }; } #endif // SLANG_ENTRY_POINT_H diff --git a/source/slang-capture-replay/slang-filesystem.cpp b/source/slang-record-replay/record/slang-filesystem.cpp index 0de17162e..1187a9aa6 100644 --- a/source/slang-capture-replay/slang-filesystem.cpp +++ b/source/slang-record-replay/record/slang-filesystem.cpp @@ -1,31 +1,31 @@ #include "slang-filesystem.h" -#include "capture_utility.h" +#include "../util/record-utility.h" #include "output-stream.h" -namespace SlangCapture +namespace SlangRecord { - // We don't actually need to capture the methods of ISlangFileSystemExt, we just want to capture the file content + // We don't actually need to record the methods of ISlangFileSystemExt, we just want to record the file content // and save them into disk. - FileSystemCapture::FileSystemCapture(ISlangFileSystemExt* fileSystem, CaptureManager* captureManager) + FileSystemRecorder::FileSystemRecorder(ISlangFileSystemExt* fileSystem, RecordManager* recordManager) : m_actualFileSystem(fileSystem), - m_captureManager(captureManager) + m_recordManager(recordManager) { - SLANG_CAPTURE_ASSERT(m_actualFileSystem); - SLANG_CAPTURE_ASSERT(m_captureManager); - slangCaptureLog(LogLevel::Verbose, "%s: %p\n", __PRETTY_FUNCTION__, m_actualFileSystem.get()); + SLANG_RECORD_ASSERT(m_actualFileSystem); + SLANG_RECORD_ASSERT(m_recordManager); + slangRecordLog(LogLevel::Verbose, "%s: %p\n", __PRETTY_FUNCTION__, m_actualFileSystem.get()); } - FileSystemCapture::~FileSystemCapture() + FileSystemRecorder::~FileSystemRecorder() { m_actualFileSystem->release(); } - void* FileSystemCapture::castAs(const Slang::Guid& guid) + void* FileSystemRecorder::castAs(const Slang::Guid& guid) { return getInterface(guid); } - ISlangUnknown* FileSystemCapture::getInterface(const Slang::Guid& guid) + ISlangUnknown* FileSystemRecorder::getInterface(const Slang::Guid& guid) { if(guid == ISlangUnknown::getTypeGuid() || guid == ISlangFileSystem::getTypeGuid()) return static_cast<ISlangFileSystem*>(this); @@ -34,11 +34,11 @@ namespace SlangCapture // 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( + SLANG_NO_THROW SlangResult FileSystemRecorder::loadFile( char const* path, ISlangBlob** outBlob) { - slangCaptureLog(LogLevel::Verbose, "%p: %s, :%s\n", m_actualFileSystem.get(), __PRETTY_FUNCTION__, path); + slangRecordLog(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, @@ -46,10 +46,10 @@ namespace SlangCapture // // 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. + // know something wrong with the loadFile call if we can't find the file in the record directory. if ((res == SLANG_OK) && (*outBlob != nullptr) && ((*outBlob)->getBufferSize() != 0)) { - std::filesystem::path filePath = m_captureManager->getCaptureFileDirectory(); + std::filesystem::path filePath = m_recordManager->getRecordFileDirectory(); filePath = filePath / path; FileOutputStream fileStream(filePath.string().c_str()); @@ -60,64 +60,64 @@ namespace SlangCapture return res; } - SLANG_NO_THROW SlangResult FileSystemCapture::getFileUniqueIdentity( + SLANG_NO_THROW SlangResult FileSystemRecorder::getFileUniqueIdentity( const char* path, ISlangBlob** outUniqueIdentity) { - slangCaptureLog(LogLevel::Verbose, "%p: %s :\"%s\"\n", m_actualFileSystem.get(), __PRETTY_FUNCTION__, path); + slangRecordLog(LogLevel::Verbose, "%p: %s :\"%s\"\n", m_actualFileSystem.get(), __PRETTY_FUNCTION__, path); SlangResult res = m_actualFileSystem->getFileUniqueIdentity(path, outUniqueIdentity); return res; } - SLANG_NO_THROW SlangResult FileSystemCapture::calcCombinedPath( + SLANG_NO_THROW SlangResult FileSystemRecorder::calcCombinedPath( SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut) { - slangCaptureLog(LogLevel::Verbose, "%p: %s, :%s\n", m_actualFileSystem.get(), __PRETTY_FUNCTION__, path); + slangRecordLog(LogLevel::Verbose, "%p: %s, :%s\n", m_actualFileSystem.get(), __PRETTY_FUNCTION__, path); SlangResult res = m_actualFileSystem->calcCombinedPath(fromPathType, fromPath, path, pathOut); return res; } - SLANG_NO_THROW SlangResult FileSystemCapture::getPathType( + SLANG_NO_THROW SlangResult FileSystemRecorder::getPathType( const char* path, SlangPathType* pathTypeOut) { - slangCaptureLog(LogLevel::Verbose, "%p: %s, :%s\n", m_actualFileSystem.get(), __PRETTY_FUNCTION__, path); + slangRecordLog(LogLevel::Verbose, "%p: %s, :%s\n", m_actualFileSystem.get(), __PRETTY_FUNCTION__, path); SlangResult res = m_actualFileSystem->getPathType(path, pathTypeOut); return res; } - SLANG_NO_THROW SlangResult FileSystemCapture::getPath( + SLANG_NO_THROW SlangResult FileSystemRecorder::getPath( PathKind kind, const char* path, ISlangBlob** outPath) { - slangCaptureLog(LogLevel::Verbose, "%p: %s, :%s\n", m_actualFileSystem.get(), __PRETTY_FUNCTION__, path); + slangRecordLog(LogLevel::Verbose, "%p: %s, :%s\n", m_actualFileSystem.get(), __PRETTY_FUNCTION__, path); SlangResult res = m_actualFileSystem->getPath(kind, path, outPath); return res; } - SLANG_NO_THROW void FileSystemCapture::clearCache() + SLANG_NO_THROW void FileSystemRecorder::clearCache() { - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualFileSystem.get(), __PRETTY_FUNCTION__); + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualFileSystem.get(), __PRETTY_FUNCTION__); m_actualFileSystem->clearCache(); } - SLANG_NO_THROW SlangResult FileSystemCapture::enumeratePathContents( + SLANG_NO_THROW SlangResult FileSystemRecorder::enumeratePathContents( const char* path, FileSystemContentsCallBack callback, void* userData) { - slangCaptureLog(LogLevel::Verbose, "%p: %s, :%s\n", m_actualFileSystem.get(), __PRETTY_FUNCTION__, path); + slangRecordLog(LogLevel::Verbose, "%p: %s, :%s\n", m_actualFileSystem.get(), __PRETTY_FUNCTION__, path); SlangResult res = m_actualFileSystem->enumeratePathContents(path, callback, userData); return res; } - SLANG_NO_THROW OSPathKind FileSystemCapture::getOSPathKind() + SLANG_NO_THROW OSPathKind FileSystemRecorder::getOSPathKind() { - slangCaptureLog(LogLevel::Verbose, "%p: %s\n", m_actualFileSystem.get(), __PRETTY_FUNCTION__); + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualFileSystem.get(), __PRETTY_FUNCTION__); OSPathKind pathKind = m_actualFileSystem->getOSPathKind(); return pathKind; } diff --git a/source/slang-capture-replay/slang-filesystem.h b/source/slang-record-replay/record/slang-filesystem.h index 1a7c8c2e2..ff7004fa1 100644 --- a/source/slang-capture-replay/slang-filesystem.h +++ b/source/slang-record-replay/record/slang-filesystem.h @@ -1,24 +1,24 @@ #ifndef SLANG_FILE_SYSTEM_H #define SLANG_FILE_SYSTEM_H -#include "../core/slang-com-object.h" #include "slang-com-helper.h" #include "slang-com-ptr.h" -#include "capture-manager.h" +#include "../../core/slang-com-object.h" +#include "record-manager.h" -namespace SlangCapture +namespace SlangRecord { using namespace Slang; // slang always requires ISlangFileSystemExt interface, even if user only provides ISlangFileSystem, - // slang will still wrap it with ISlangFileSystemExt. So we have to capture ISlangFileSystemExt, even + // slang will still wrap it with ISlangFileSystemExt. So we have to record ISlangFileSystemExt, even // though we only need to record loadFile() function. - class FileSystemCapture : public RefObject, public ISlangFileSystemExt + class FileSystemRecorder : public RefObject, public ISlangFileSystemExt { public: - explicit FileSystemCapture(ISlangFileSystemExt* fileSystem, CaptureManager* captureManager); - ~FileSystemCapture(); + explicit FileSystemRecorder(ISlangFileSystemExt* fileSystem, RecordManager* recordManager); + ~FileSystemRecorder(); // ISlangUnknown SLANG_REF_OBJECT_IUNKNOWN_ALL @@ -63,7 +63,7 @@ namespace SlangCapture virtual SLANG_NO_THROW OSPathKind SLANG_MCALL getOSPathKind() override; private: Slang::ComPtr<ISlangFileSystemExt> m_actualFileSystem; - CaptureManager* m_captureManager = nullptr; + RecordManager* m_recordManager = nullptr; }; } diff --git a/source/slang-record-replay/record/slang-global-session.cpp b/source/slang-record-replay/record/slang-global-session.cpp new file mode 100644 index 000000000..78fa8aaa2 --- /dev/null +++ b/source/slang-record-replay/record/slang-global-session.cpp @@ -0,0 +1,452 @@ +#include "slang-global-session.h" +#include "slang-session.h" +#include "slang-filesystem.h" +#include "../../slang/slang-compiler.h" +#include "../util/record-utility.h" + +namespace SlangRecord +{ + // constructor is called in slang_createGlobalSession + GlobalSessionRecorder::GlobalSessionRecorder(slang::IGlobalSession* session): + m_actualGlobalSession(session) + { + SLANG_RECORD_ASSERT(m_actualGlobalSession != nullptr); + + m_globalSessionHandle = reinterpret_cast<SlangRecord::AddressFormat>(m_actualGlobalSession.get()); + m_recordManager = std::make_unique<RecordManager>(m_globalSessionHandle); + + // We will use the address of the global session as the filename for the record manager + // to make it unique for each global session. + // record slang::createGlobalSession + ParameterRecorder* recorder = m_recordManager->beginMethodRecord(ApiCallId::CreateGlobalSession, g_globalFunctionHandle); + recorder->recordAddress(m_actualGlobalSession); + m_recordManager->endMethodRecord(); + } + + GlobalSessionRecorder::~GlobalSessionRecorder() + { + m_actualGlobalSession->release(); + } + + SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionRecorder::queryInterface(SlangUUID const& uuid, void** outObject) + { + if (uuid == Session::getTypeGuid()) + { + // no add-ref here, the query will cause the inner session to handle the add-ref. + this->m_actualGlobalSession->queryInterface(uuid, outObject); + return SLANG_OK; + } + + if (uuid == ISlangUnknown::getTypeGuid() && uuid == IGlobalSession::getTypeGuid()) + { + addReference(); + *outObject = static_cast<slang::IGlobalSession*>(this); + return SLANG_OK; + } + + return SLANG_E_NO_INTERFACE; + } + + SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionRecorder::createSession(slang::SessionDesc const& desc, slang::ISession** outSession) + { + setLogLevel(); + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + + slang::ISession* actualSession = nullptr; + + ParameterRecorder* recorder{}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IGlobalSession_createSession, m_globalSessionHandle); + recorder->recordStruct(desc); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualGlobalSession->createSession(desc, &actualSession); + + { // record output + recorder->recordAddress(actualSession); + m_recordManager->endMethodRecordAppendOutput(); + } + + if (actualSession != nullptr) + { + // reset the file system to our record file system. After createSession() call, + // the Linkage will set to user provided file system or slang default file system. + // We need to reset it to our record file system + Slang::Linkage* linkage = static_cast<Linkage*>(actualSession); + FileSystemRecorder* fileSystemRecord = new FileSystemRecorder(linkage->getFileSystemExt(), m_recordManager.get()); + + Slang::ComPtr<FileSystemRecorder> resultFileSystemRecorder(fileSystemRecord); + linkage->setFileSystem(resultFileSystemRecorder.detach()); + + SessionRecorder* sessionRecord = new SessionRecorder(actualSession, m_recordManager.get()); + Slang::ComPtr<SessionRecorder> result(sessionRecord); + *outSession = result.detach(); + } + + return res; + } + + SLANG_NO_THROW SlangProfileID SLANG_MCALL GlobalSessionRecorder::findProfile(char const* name) + { + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IGlobalSession_findProfile, m_globalSessionHandle); + recorder->recordString(name); + recorder = m_recordManager->endMethodRecord(); + } + + SlangProfileID profileId = m_actualGlobalSession->findProfile(name); + return profileId; + } + + SLANG_NO_THROW void SLANG_MCALL GlobalSessionRecorder::setDownstreamCompilerPath(SlangPassThrough passThrough, char const* path) + { + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IGlobalSession_setDownstreamCompilerPath, m_globalSessionHandle); + recorder->recordEnumValue(passThrough); + recorder->recordString(path); + m_recordManager->endMethodRecord(); + } + + m_actualGlobalSession->setDownstreamCompilerPath(passThrough, path); + } + + SLANG_NO_THROW void SLANG_MCALL GlobalSessionRecorder::setDownstreamCompilerPrelude(SlangPassThrough inPassThrough, char const* prelude) + { + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IGlobalSession_setDownstreamCompilerPrelude, m_globalSessionHandle); + recorder->recordEnumValue(inPassThrough); + recorder->recordString(prelude); + m_recordManager->endMethodRecord(); + } + + m_actualGlobalSession->setDownstreamCompilerPrelude(inPassThrough, prelude); + } + + SLANG_NO_THROW void SLANG_MCALL GlobalSessionRecorder::getDownstreamCompilerPrelude(SlangPassThrough inPassThrough, ISlangBlob** outPrelude) + { + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IGlobalSession_getDownstreamCompilerPrelude, m_globalSessionHandle); + recorder->recordEnumValue(inPassThrough); + recorder = m_recordManager->endMethodRecord(); + } + + m_actualGlobalSession->getDownstreamCompilerPrelude(inPassThrough, outPrelude); + + { + recorder->recordAddress(*outPrelude); + m_recordManager->endMethodRecordAppendOutput(); + } + } + + SLANG_NO_THROW const char* SLANG_MCALL GlobalSessionRecorder::getBuildTagString() + { + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + + // No need to record this function. It's just a query function and it won't impact the internal state. + const char* resStr = m_actualGlobalSession->getBuildTagString(); + return resStr; + } + + SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionRecorder::setDefaultDownstreamCompiler(SlangSourceLanguage sourceLanguage, SlangPassThrough defaultCompiler) + { + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IGlobalSession_setDefaultDownstreamCompiler, m_globalSessionHandle); + recorder->recordEnumValue(sourceLanguage); + recorder->recordEnumValue(defaultCompiler); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualGlobalSession->setDefaultDownstreamCompiler(sourceLanguage, defaultCompiler); + return res; + } + + SLANG_NO_THROW SlangPassThrough SLANG_MCALL GlobalSessionRecorder::getDefaultDownstreamCompiler(SlangSourceLanguage sourceLanguage) + { + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IGlobalSession_getDefaultDownstreamCompiler, m_globalSessionHandle); + recorder->recordEnumValue(sourceLanguage); + recorder = m_recordManager->endMethodRecord(); + } + + SlangPassThrough passThrough = m_actualGlobalSession->getDefaultDownstreamCompiler(sourceLanguage); + return passThrough; + } + + SLANG_NO_THROW void SLANG_MCALL GlobalSessionRecorder::setLanguagePrelude(SlangSourceLanguage inSourceLanguage, char const* prelude) + { + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IGlobalSession_setLanguagePrelude, m_globalSessionHandle); + recorder->recordEnumValue(inSourceLanguage); + recorder->recordString(prelude); + recorder = m_recordManager->endMethodRecord(); + } + + m_actualGlobalSession->setLanguagePrelude(inSourceLanguage, prelude); + } + + SLANG_NO_THROW void SLANG_MCALL GlobalSessionRecorder::getLanguagePrelude(SlangSourceLanguage inSourceLanguage, ISlangBlob** outPrelude) + { + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IGlobalSession_getLanguagePrelude, m_globalSessionHandle); + recorder->recordEnumValue(inSourceLanguage); + recorder = m_recordManager->endMethodRecord(); + } + + m_actualGlobalSession->getLanguagePrelude(inSourceLanguage, outPrelude); + + { + recorder->recordAddress(*outPrelude); + m_recordManager->endMethodRecordAppendOutput(); + } + } + + SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionRecorder::createCompileRequest(slang::ICompileRequest** outCompileRequest) + { + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IGlobalSession_createCompileRequest, m_globalSessionHandle); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualGlobalSession->createCompileRequest(outCompileRequest); + + { + recorder->recordAddress(*outCompileRequest); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW void SLANG_MCALL GlobalSessionRecorder::addBuiltins(char const* sourcePath, char const* sourceString) + { + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IGlobalSession_addBuiltins, m_globalSessionHandle); + recorder->recordString(sourcePath); + recorder->recordString(sourceString); + recorder = m_recordManager->endMethodRecord(); + } + + m_actualGlobalSession->addBuiltins(sourcePath, sourceString); + } + + SLANG_NO_THROW void SLANG_MCALL GlobalSessionRecorder::setSharedLibraryLoader(ISlangSharedLibraryLoader* loader) + { + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + // TODO: Not sure if we need to record this function. Because this functions is something like the file system + // override, it's provided by user code. So capturing it makes no sense. The only way is to wrapper this interface + // by our own implementation, and record it there. + m_actualGlobalSession->setSharedLibraryLoader(loader); + } + + SLANG_NO_THROW ISlangSharedLibraryLoader* SLANG_MCALL GlobalSessionRecorder::getSharedLibraryLoader() + { + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IGlobalSession_getSharedLibraryLoader, m_globalSessionHandle); + recorder = m_recordManager->endMethodRecord(); + } + + ISlangSharedLibraryLoader* loader = m_actualGlobalSession->getSharedLibraryLoader(); + + { + recorder->recordAddress(loader); + m_recordManager->endMethodRecordAppendOutput(); + } + return loader; + } + + SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionRecorder::checkCompileTargetSupport(SlangCompileTarget target) + { + // No need to record this function. It's just a query function and it won't impact the internal state. + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + SlangResult res = m_actualGlobalSession->checkCompileTargetSupport(target); + return res; + } + + SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionRecorder::checkPassThroughSupport(SlangPassThrough passThrough) + { + // No need to record this function. It's just a query function and it won't impact the internal state. + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + SlangResult res = m_actualGlobalSession->checkPassThroughSupport(passThrough); + return res; + } + + SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionRecorder::compileStdLib(slang::CompileStdLibFlags flags) + { + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IGlobalSession_compileStdLib, m_globalSessionHandle); + recorder->recordEnumValue(flags); + m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualGlobalSession->compileStdLib(flags); + return res; + } + + SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionRecorder::loadStdLib(const void* stdLib, size_t stdLibSizeInBytes) + { + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IGlobalSession_loadStdLib, m_globalSessionHandle); + recorder->recordPointer(stdLib, false, stdLibSizeInBytes); + m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualGlobalSession->loadStdLib(stdLib, stdLibSizeInBytes); + return res; + } + + SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionRecorder::saveStdLib(SlangArchiveType archiveType, ISlangBlob** outBlob) + { + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IGlobalSession_saveStdLib, m_globalSessionHandle); + recorder->recordEnumValue(archiveType); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualGlobalSession->saveStdLib(archiveType, outBlob); + + { + recorder->recordAddress(*outBlob); + m_recordManager->endMethodRecordAppendOutput(); + } + return res; + } + + SLANG_NO_THROW SlangCapabilityID SLANG_MCALL GlobalSessionRecorder::findCapability(char const* name) + { + // No need to record this function. It's just a query function and it won't impact the internal state. + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + SlangCapabilityID capId = m_actualGlobalSession->findCapability(name); + return capId; + } + + SLANG_NO_THROW void SLANG_MCALL GlobalSessionRecorder::setDownstreamCompilerForTransition(SlangCompileTarget source, SlangCompileTarget target, SlangPassThrough compiler) + { + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IGlobalSession_setDownstreamCompilerForTransition, m_globalSessionHandle); + recorder->recordEnumValue(source); + recorder->recordEnumValue(target); + recorder->recordEnumValue(compiler); + m_recordManager->endMethodRecord(); + } + + m_actualGlobalSession->setDownstreamCompilerForTransition(source, target, compiler); + } + + SLANG_NO_THROW SlangPassThrough SLANG_MCALL GlobalSessionRecorder::getDownstreamCompilerForTransition(SlangCompileTarget source, SlangCompileTarget target) + { + // No need to record this function. It's just a query function and it won't impact the internal state. + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + SlangPassThrough passThrough = m_actualGlobalSession->getDownstreamCompilerForTransition(source, target); + return passThrough; + } + + SLANG_NO_THROW void SLANG_MCALL GlobalSessionRecorder::getCompilerElapsedTime(double* outTotalTime, double* outDownstreamTime) + { + // No need to record this function. It's just a query function and it won't impact the internal state. + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + m_actualGlobalSession->getCompilerElapsedTime(outTotalTime, outDownstreamTime); + } + + SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionRecorder::setSPIRVCoreGrammar(char const* jsonPath) + { + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IGlobalSession_setSPIRVCoreGrammar, m_globalSessionHandle); + recorder->recordString(jsonPath); + m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualGlobalSession->setSPIRVCoreGrammar(jsonPath); + return res; + } + + SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionRecorder::parseCommandLineArguments( + int argc, const char* const* argv, slang::SessionDesc* outSessionDesc, ISlangUnknown** outAllocation) + { + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IGlobalSession_parseCommandLineArguments, m_globalSessionHandle); + recorder->recordInt32(argc); + recorder->recordStringArray(argv, argc); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualGlobalSession->parseCommandLineArguments(argc, argv, outSessionDesc, outAllocation); + + { + recorder->recordAddress(outSessionDesc); + recorder->recordAddress(*outAllocation); + m_recordManager->endMethodRecordAppendOutput(); + } + return res; + } + + SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionRecorder::getSessionDescDigest(slang::SessionDesc* sessionDesc, ISlangBlob** outBlob) + { + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IGlobalSession_getSessionDescDigest, m_globalSessionHandle); + recorder->recordStruct(*sessionDesc); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualGlobalSession->getSessionDescDigest(sessionDesc, outBlob); + + { + recorder->recordAddress(*outBlob); + m_recordManager->endMethodRecordAppendOutput(); + } + return res; + } +} diff --git a/source/slang-capture-replay/slang-global-session.h b/source/slang-record-replay/record/slang-global-session.h index f478e60db..3fd584ef4 100644 --- a/source/slang-capture-replay/slang-global-session.h +++ b/source/slang-record-replay/record/slang-global-session.h @@ -4,18 +4,18 @@ #include "slang-com-ptr.h" #include "slang.h" #include "slang-com-helper.h" -#include "../core/slang-smart-pointer.h" -#include "capture-manager.h" +#include "../../core/slang-smart-pointer.h" +#include "record-manager.h" -namespace SlangCapture +namespace SlangRecord { using namespace Slang; - class GlobalSessionCapture : public RefObject, public slang::IGlobalSession + class GlobalSessionRecorder : public RefObject, public slang::IGlobalSession { public: - explicit GlobalSessionCapture(slang::IGlobalSession* session); - virtual ~GlobalSessionCapture(); + explicit GlobalSessionRecorder(slang::IGlobalSession* session); + virtual ~GlobalSessionRecorder(); SLANG_REF_OBJECT_IUNKNOWN_ADD_REF SLANG_REF_OBJECT_IUNKNOWN_RELEASE @@ -60,24 +60,24 @@ namespace SlangCapture SLANG_NO_THROW SlangResult SLANG_MCALL getSessionDescDigest(slang::SessionDesc* sessionDesc, ISlangBlob** outBlob) override; - CaptureManager* getCaptureManager() { return m_captureManager.get(); } + RecordManager* getRecordManager() { return m_recordManager.get(); } private: - SLANG_FORCE_INLINE slang::IGlobalSession* asExternal(GlobalSessionCapture* session) + SLANG_FORCE_INLINE slang::IGlobalSession* asExternal(GlobalSessionRecorder* session) { return static_cast<slang::IGlobalSession*>(session); } Slang::ComPtr<slang::IGlobalSession> m_actualGlobalSession; - // we will create one capture file per IGlobalSession. + // we will create one record 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, + // Instead, we record all the compilation jobs associated with the session in the same record 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; + std::unique_ptr<RecordManager> m_recordManager; uint64_t m_globalSessionHandle = 0; }; } // namespace Slang diff --git a/source/slang-record-replay/record/slang-module.cpp b/source/slang-record-replay/record/slang-module.cpp new file mode 100644 index 000000000..1457e7cf1 --- /dev/null +++ b/source/slang-record-replay/record/slang-module.cpp @@ -0,0 +1,496 @@ +#include "../util/record-utility.h" +#include "slang-module.h" + +namespace SlangRecord +{ + ModuleRecorder::ModuleRecorder(slang::IModule* module, RecordManager* recordManager) + : m_actualModule(module), + m_recordManager(recordManager) + { + SLANG_RECORD_ASSERT(m_actualModule != nullptr); + SLANG_RECORD_ASSERT(m_recordManager != nullptr); + + m_moduleHandle = reinterpret_cast<uint64_t>(m_actualModule.get()); + slangRecordLog(LogLevel::Verbose, "%s: %p\n", __PRETTY_FUNCTION__, module); + } + + ModuleRecorder::~ModuleRecorder() + { + m_actualModule->release(); + } + + ISlangUnknown* ModuleRecorder::getInterface(const Guid& guid) + { + if(guid == ModuleRecorder::getTypeGuid()) + return static_cast<ISlangUnknown*>(this); + else + return nullptr; + } + + SLANG_NO_THROW slang::DeclReflection* ModuleRecorder::getModuleReflection() + { + // No need to record this call as it is just a query. + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + slang::DeclReflection* res = (slang::DeclReflection*)m_actualModule->getModuleReflection(); + return res; + } + + SLANG_NO_THROW SlangResult ModuleRecorder::findEntryPointByName( + char const* name, + slang::IEntryPoint** outEntryPoint) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IModule_findEntryPointByName, m_moduleHandle); + recorder->recordString(name); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualModule->findEntryPointByName(name, outEntryPoint); + + { + recorder->recordAddress(*outEntryPoint); + m_recordManager->endMethodRecordAppendOutput(); + } + + if (SLANG_OK == res) + { + EntryPointRecorder* entryPointRecord = getEntryPointRecorder(*outEntryPoint); + *outEntryPoint = static_cast<slang::IEntryPoint*>(entryPointRecord); + } + return res; + } + + SLANG_NO_THROW SlangInt32 ModuleRecorder::getDefinedEntryPointCount() + { + // No need to record this call as it is just a query. + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + SlangInt32 res = m_actualModule->getDefinedEntryPointCount(); + return res; + } + + SLANG_NO_THROW SlangResult ModuleRecorder::getDefinedEntryPoint(SlangInt32 index, slang::IEntryPoint** outEntryPoint) + { + // 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. + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IModule_getDefinedEntryPoint, m_moduleHandle); + recorder->recordInt32(index); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualModule->getDefinedEntryPoint(index, outEntryPoint); + + { + recorder->recordAddress(*outEntryPoint); + m_recordManager->endMethodRecordAppendOutput(); + } + + if (*outEntryPoint) + { + EntryPointRecorder* entryPointRecord = m_mapEntryPointToRecord.tryGetValue(*outEntryPoint); + if (!entryPointRecord) + { + SLANG_RECORD_ASSERT(!"Entrypoint not found in mapEntryPointToRecord"); + } + *outEntryPoint = static_cast<slang::IEntryPoint*>(entryPointRecord); + } + else + *outEntryPoint = nullptr; + + return res; + } + + SLANG_NO_THROW SlangResult ModuleRecorder::serialize(ISlangBlob** outSerializedBlob) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IModule_serialize, m_moduleHandle); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualModule->serialize(outSerializedBlob); + + { + recorder->recordAddress(*outSerializedBlob); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult ModuleRecorder::writeToFile(char const* fileName) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IModule_writeToFile, m_moduleHandle); + recorder->recordString(fileName); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualModule->writeToFile(fileName); + return res; + } + + SLANG_NO_THROW const char* ModuleRecorder::getName() + { + // No need to record this call as it is just a query. + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + const char* res = m_actualModule->getName(); + return res; + } + + SLANG_NO_THROW const char* ModuleRecorder::getFilePath() + { + // No need to record this call as it is just a query. + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + const char* res = m_actualModule->getFilePath(); + return res; + } + + SLANG_NO_THROW const char* ModuleRecorder::getUniqueIdentity() + { + // No need to record this call as it is just a query. + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + const char* res = m_actualModule->getUniqueIdentity(); + return res; + } + + SLANG_NO_THROW SlangResult ModuleRecorder::findAndCheckEntryPoint( + char const* name, + SlangStage stage, + slang::IEntryPoint** outEntryPoint, + ISlangBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IModule_findAndCheckEntryPoint, m_moduleHandle); + recorder->recordString(name); + recorder->recordEnumValue(stage); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualModule->findAndCheckEntryPoint(name, stage, outEntryPoint, outDiagnostics); + + { + recorder->recordAddress(*outEntryPoint); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + if (SLANG_OK == res) + { + EntryPointRecorder* entryPointRecord = getEntryPointRecorder(*outEntryPoint); + *outEntryPoint = static_cast<slang::IEntryPoint*>(entryPointRecord); + } + return res; + } + + SLANG_NO_THROW SlangInt32 ModuleRecorder::getDependencyFileCount() + { + // No need to record this call as it is just a query. + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + SlangInt32 res = m_actualModule->getDependencyFileCount(); + return res; + } + + SLANG_NO_THROW char const* ModuleRecorder::getDependencyFilePath(SlangInt32 index) + { + // No need to record this call as it is just a query. + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + const char* res = m_actualModule->getDependencyFilePath(index); + return res; + } + + SLANG_NO_THROW slang::ISession* ModuleRecorder::getSession() + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + slang::ISession* session = m_actualModule->getSession(); + + return session; + } + + SLANG_NO_THROW slang::ProgramLayout* ModuleRecorder::getLayout( + SlangInt targetIndex, + slang::IBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IModule_getLayout, m_moduleHandle); + recorder->recordInt64(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + slang::ProgramLayout* programLayout = m_actualModule->getLayout(targetIndex, outDiagnostics); + + { + recorder->recordAddress(*outDiagnostics); + recorder->recordAddress(programLayout); + m_recordManager->endMethodRecordAppendOutput(); + } + + return programLayout; + } + + SLANG_NO_THROW SlangInt ModuleRecorder::getSpecializationParamCount() + { + // No need to record this call as it is just a query. + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + SlangInt res = m_actualModule->getSpecializationParamCount(); + return res; + } + + SLANG_NO_THROW SlangResult ModuleRecorder::getEntryPointCode( + SlangInt entryPointIndex, + SlangInt targetIndex, + slang::IBlob** outCode, + slang::IBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IModule_getEntryPointCode, m_moduleHandle); + recorder->recordInt64(entryPointIndex); + recorder->recordInt64(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualModule->getEntryPointCode(entryPointIndex, targetIndex, outCode, outDiagnostics); + + { + recorder->recordAddress(*outCode); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult ModuleRecorder::getTargetCode( + SlangInt targetIndex, + slang::IBlob** outCode, + slang::IBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IModule_getTargetCode, m_moduleHandle); + recorder->recordInt64(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualModule->getTargetCode(targetIndex, outCode, outDiagnostics); + + { + recorder->recordAddress(*outCode); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult ModuleRecorder::getResultAsFileSystem( + SlangInt entryPointIndex, + SlangInt targetIndex, + ISlangMutableFileSystem** outFileSystem) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IModule_getResultAsFileSystem, m_moduleHandle); + recorder->recordInt64(entryPointIndex); + recorder->recordInt64(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualModule->getResultAsFileSystem(entryPointIndex, targetIndex, outFileSystem); + + { + recorder->recordAddress(*outFileSystem); + m_recordManager->endMethodRecordAppendOutput(); + } + + // TODO: We might need to wrap the file system object. + return res; + } + + SLANG_NO_THROW void ModuleRecorder::getEntryPointHash( + SlangInt entryPointIndex, + SlangInt targetIndex, + slang::IBlob** outHash) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IModule_getEntryPointHash, m_moduleHandle); + recorder->recordInt64(entryPointIndex); + recorder->recordInt64(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + m_actualModule->getEntryPointHash(entryPointIndex, targetIndex, outHash); + + { + recorder->recordAddress(*outHash); + m_recordManager->endMethodRecordAppendOutput(); + } + } + + SLANG_NO_THROW SlangResult ModuleRecorder::specialize( + slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, + slang::IComponentType** outSpecializedComponentType, + ISlangBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IModule_specialize, m_moduleHandle); + recorder->recordInt64(specializationArgCount); + recorder->recordStructArray(specializationArgs, specializationArgCount); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualModule->specialize(specializationArgs, specializationArgCount, outSpecializedComponentType, outDiagnostics); + + { + recorder->recordAddress(*outSpecializedComponentType); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult ModuleRecorder::link( + IComponentType** outLinkedComponentType, + ISlangBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IModule_link, m_moduleHandle); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualModule->link(outLinkedComponentType, outDiagnostics); + + { + recorder->recordAddress(*outLinkedComponentType); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult ModuleRecorder::getEntryPointHostCallable( + int entryPointIndex, + int targetIndex, + ISlangSharedLibrary** outSharedLibrary, + slang::IBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IModule_getEntryPointHostCallable, m_moduleHandle); + recorder->recordInt32(entryPointIndex); + recorder->recordInt32(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualModule->getEntryPointHostCallable(entryPointIndex, targetIndex, outSharedLibrary, outDiagnostics); + + { + recorder->recordAddress(*outSharedLibrary); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult ModuleRecorder::renameEntryPoint( + const char* newName, IComponentType** outEntryPoint) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IModule_renameEntryPoint, m_moduleHandle); + recorder->recordString(newName); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualModule->renameEntryPoint(newName, outEntryPoint); + + { + recorder->recordAddress(*outEntryPoint); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult ModuleRecorder::linkWithOptions( + IComponentType** outLinkedComponentType, + uint32_t compilerOptionEntryCount, + slang::CompilerOptionEntry* compilerOptionEntries, + ISlangBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::IModule_linkWithOptions, m_moduleHandle); + recorder->recordUint32(compilerOptionEntryCount); + recorder->recordStructArray(compilerOptionEntries, compilerOptionEntryCount); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualModule->linkWithOptions(outLinkedComponentType, compilerOptionEntryCount, compilerOptionEntries, outDiagnostics); + + { + recorder->recordAddress(*outLinkedComponentType); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + EntryPointRecorder* ModuleRecorder::getEntryPointRecorder(slang::IEntryPoint* entryPoint) + { + EntryPointRecorder* entryPointRecord = nullptr; + entryPointRecord = m_mapEntryPointToRecord.tryGetValue(entryPoint); + if (!entryPointRecord) + { + entryPointRecord = new EntryPointRecorder(entryPoint, m_recordManager); + Slang::ComPtr<EntryPointRecorder> result(entryPointRecord); + m_mapEntryPointToRecord.add(entryPoint, *result.detach()); + } + return entryPointRecord; + } +} diff --git a/source/slang-capture-replay/slang-module.h b/source/slang-record-replay/record/slang-module.h index 94539532c..ca0403c2d 100644 --- a/source/slang-capture-replay/slang-module.h +++ b/source/slang-record-replay/record/slang-module.h @@ -4,15 +4,15 @@ #include "slang-com-ptr.h" #include "slang.h" #include "slang-com-helper.h" -#include "../core/slang-smart-pointer.h" -#include "../slang/slang-compiler.h" +#include "../../core/slang-smart-pointer.h" +#include "../../slang/slang-compiler.h" #include "slang-entrypoint.h" -#include "capture-manager.h" +#include "record-manager.h" -namespace SlangCapture +namespace SlangRecord { using namespace Slang; - class ModuleCapture : public slang::IModule, public RefObject + class ModuleRecorder : public slang::IModule, public RefObject { public: SLANG_COM_INTERFACE(0xb1802991, 0x185a, 0x4a03, { 0xa7, 0x7e, 0x0c, 0x86, 0xe0, 0x68, 0x2a, 0xab }) @@ -20,8 +20,8 @@ namespace SlangCapture SLANG_REF_OBJECT_IUNKNOWN_ALL ISlangUnknown* getInterface(const Guid& guid); - explicit ModuleCapture(slang::IModule* module, CaptureManager* captureManager); - ~ModuleCapture(); + explicit ModuleRecorder(slang::IModule* module, RecordManager* recordManager); + ~ModuleRecorder(); // Interfaces for `IModule` virtual SLANG_NO_THROW SlangResult SLANG_MCALL findEntryPointByName( @@ -87,16 +87,16 @@ namespace SlangCapture slang::IModule* getActualModule() const { return m_actualModule; } private: - EntryPointCapture* getEntryPointCapture(slang::IEntryPoint* entryPoint); + EntryPointRecorder* getEntryPointRecorder(slang::IEntryPoint* entryPoint); Slang::ComPtr<slang::IModule> m_actualModule; uint64_t m_moduleHandle = 0; - CaptureManager* m_captureManager = nullptr; + RecordManager* m_recordManager = 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` + // `IEntryPoint` can only be created from 'IModule', so we need to record it in + // this class, and create a map such that we don't create new `EntryPointRecorder` // for the same `IEntryPoint`. - Dictionary<slang::IEntryPoint*, EntryPointCapture> m_mapEntryPointToCapture; + Dictionary<slang::IEntryPoint*, EntryPointRecorder> m_mapEntryPointToRecord; }; -} // namespace SlangCapture +} // namespace SlangRecord #endif // SLANG_MODULE_H diff --git a/source/slang-record-replay/record/slang-session.cpp b/source/slang-record-replay/record/slang-session.cpp new file mode 100644 index 000000000..82c7a7479 --- /dev/null +++ b/source/slang-record-replay/record/slang-session.cpp @@ -0,0 +1,517 @@ +#include "../util/record-utility.h" +#include "slang-session.h" +#include "slang-entrypoint.h" +#include "slang-composite-component-type.h" +#include "slang-type-conformance.h" + +namespace SlangRecord +{ + + SessionRecorder::SessionRecorder(slang::ISession* session, RecordManager* recordManager) + : m_actualSession(session), + m_recordManager(recordManager) + { + SLANG_RECORD_ASSERT(m_actualSession); + SLANG_RECORD_ASSERT(m_recordManager); + m_sessionHandle = reinterpret_cast<uint64_t>(m_actualSession.get()); + slangRecordLog(LogLevel::Verbose, "%s: %p\n", "SessionRecorder create:", session); + } + + SessionRecorder::~SessionRecorder() + { + m_actualSession->release(); + } + + ISlangUnknown* SessionRecorder::getInterface(const Guid& guid) + { + if(guid == ISlangUnknown::getTypeGuid() || guid == ISession::getTypeGuid()) + return asExternal(this); + + return nullptr; + } + + SLANG_NO_THROW slang::IGlobalSession* SessionRecorder::getGlobalSession() + { + // No need to record this function. + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + slang::IGlobalSession* pGlobalSession = m_actualSession->getGlobalSession(); + return pGlobalSession; + } + + SLANG_NO_THROW slang::IModule* SessionRecorder::loadModule( + const char* moduleName, + slang::IBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ISession_loadModule, m_sessionHandle); + recorder->recordString(moduleName); + recorder = m_recordManager->endMethodRecord(); + } + + slang::IModule* pModule = m_actualSession->loadModule(moduleName, outDiagnostics); + + { + recorder->recordAddress(*outDiagnostics); + recorder->recordAddress(pModule); + m_recordManager->endMethodRecordAppendOutput(); + } + + ModuleRecorder* pModuleRecorder = getModuleRecorder(pModule); + return static_cast<slang::IModule*>(pModuleRecorder); + } + + SLANG_NO_THROW slang::IModule* SessionRecorder::loadModuleFromIRBlob( + const char* moduleName, + const char* path, + slang::IBlob* source, + slang::IBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ISession_loadModuleFromIRBlob, m_sessionHandle); + recorder->recordString(moduleName); + recorder->recordString(path); + recorder->recordPointer(source); + recorder = m_recordManager->endMethodRecord(); + } + + slang::IModule* pModule = m_actualSession->loadModuleFromIRBlob(moduleName, path, source, outDiagnostics); + + { + recorder->recordAddress(*outDiagnostics); + recorder->recordAddress(pModule); + m_recordManager->endMethodRecordAppendOutput(); + } + + ModuleRecorder* pModuleRecorder = getModuleRecorder(pModule); + return static_cast<slang::IModule*>(pModuleRecorder); + } + + SLANG_NO_THROW slang::IModule* SessionRecorder::loadModuleFromSource( + const char* moduleName, + const char* path, + slang::IBlob* source, + slang::IBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ISession_loadModuleFromSource, m_sessionHandle); + recorder->recordString(moduleName); + recorder->recordString(path); + recorder->recordPointer(source); + recorder = m_recordManager->endMethodRecord(); + } + + slang::IModule* pModule = m_actualSession->loadModuleFromSource(moduleName, path, source, outDiagnostics); + + { + recorder->recordAddress(*outDiagnostics); + recorder->recordAddress(pModule); + m_recordManager->endMethodRecordAppendOutput(); + } + + ModuleRecorder* pModuleRecorder = getModuleRecorder(pModule); + return static_cast<slang::IModule*>(pModuleRecorder); + } + + SLANG_NO_THROW slang::IModule* SessionRecorder::loadModuleFromSourceString( + const char* moduleName, + const char* path, + const char* string, + slang::IBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ISession_loadModuleFromSourceString, m_sessionHandle); + recorder->recordString(moduleName); + recorder->recordString(path); + recorder->recordString(string); + recorder = m_recordManager->endMethodRecord(); + } + + slang::IModule* pModule = m_actualSession->loadModuleFromSourceString(moduleName, path, string, outDiagnostics); + + { + // TODO: Not sure if we need to record the diagnostics blob. + recorder->recordAddress(*outDiagnostics); + recorder->recordAddress(pModule); + m_recordManager->endMethodRecordAppendOutput(); + } + + ModuleRecorder* pModuleRecorder = getModuleRecorder(pModule); + return static_cast<slang::IModule*>(pModuleRecorder); + } + + SLANG_NO_THROW SlangResult SessionRecorder::createCompositeComponentType( + slang::IComponentType* const* componentTypes, + SlangInt componentTypeCount, + slang::IComponentType** outCompositeComponentType, + ISlangBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + Slang::List<slang::IComponentType*> componentTypeList; + + // get the actual component types from our record wrappers + if(SLANG_OK != getActualComponentTypes(componentTypes, componentTypeCount, componentTypeList)) + { + SLANG_RECORD_ASSERT(!"Failed to get actual component types"); + } + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ISession_createCompositeComponentType, m_sessionHandle); + recorder->recordAddressArray(componentTypeList.getBuffer(), componentTypeCount); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult result = m_actualSession->createCompositeComponentType( + componentTypeList.getBuffer(), componentTypeCount, outCompositeComponentType, outDiagnostics); + + { + recorder->recordAddress(*outCompositeComponentType); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + if (SLANG_OK == result) + { + CompositeComponentTypeRecorder* compositeComponentTypeRecord = + new CompositeComponentTypeRecorder(*outCompositeComponentType, m_recordManager); + Slang::ComPtr<CompositeComponentTypeRecorder> resultRecord(compositeComponentTypeRecord); + *outCompositeComponentType = resultRecord.detach(); + } + + return result; + } + + SLANG_NO_THROW slang::TypeReflection* SessionRecorder::specializeType( + slang::TypeReflection* type, + slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, + ISlangBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ISession_specializeType, m_sessionHandle); + recorder->recordAddress(type); + recorder->recordStructArray(specializationArgs, specializationArgCount); + recorder = m_recordManager->endMethodRecord(); + } + + slang::TypeReflection* pTypeReflection = m_actualSession->specializeType(type, specializationArgs, specializationArgCount, outDiagnostics); + + { + recorder->recordAddress(*outDiagnostics); + recorder->recordAddress(pTypeReflection); + m_recordManager->endMethodRecordAppendOutput(); + } + + return pTypeReflection; + } + + SLANG_NO_THROW slang::TypeLayoutReflection* SessionRecorder::getTypeLayout( + slang::TypeReflection* type, + SlangInt targetIndex, + slang::LayoutRules rules, + ISlangBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ISession_getTypeLayout, m_sessionHandle); + recorder->recordAddress(type); + recorder->recordInt64(targetIndex); + recorder->recordEnumValue(rules); + recorder = m_recordManager->endMethodRecord(); + } + + slang::TypeLayoutReflection* pTypeLayoutReflection = m_actualSession->getTypeLayout(type, targetIndex, rules, outDiagnostics); + + { + recorder->recordAddress(*outDiagnostics); + recorder->recordAddress(pTypeLayoutReflection); + m_recordManager->endMethodRecordAppendOutput(); + } + + return pTypeLayoutReflection; + } + + SLANG_NO_THROW slang::TypeReflection* SessionRecorder::getContainerType( + slang::TypeReflection* elementType, + slang::ContainerType containerType, + ISlangBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ISession_getContainerType, m_sessionHandle); + recorder->recordAddress(elementType); + recorder->recordEnumValue(containerType); + recorder = m_recordManager->endMethodRecord(); + } + + slang::TypeReflection* pTypeReflection = m_actualSession->getContainerType(elementType, containerType, outDiagnostics); + + { + recorder->recordAddress(*outDiagnostics); + recorder->recordAddress(pTypeReflection); + m_recordManager->endMethodRecordAppendOutput(); + } + + return pTypeReflection; + } + + SLANG_NO_THROW slang::TypeReflection* SessionRecorder::getDynamicType() + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ISession_getDynamicType, m_sessionHandle); + recorder = m_recordManager->endMethodRecord(); + } + + slang::TypeReflection* pTypeReflection = m_actualSession->getDynamicType(); + + { + recorder->recordAddress(pTypeReflection); + m_recordManager->endMethodRecordAppendOutput(); + } + + return pTypeReflection; + } + + SLANG_NO_THROW SlangResult SessionRecorder::getTypeRTTIMangledName( + slang::TypeReflection* type, + ISlangBlob** outNameBlob) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ISession_getTypeRTTIMangledName, m_sessionHandle); + recorder->recordAddress(type); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult result = m_actualSession->getTypeRTTIMangledName(type, outNameBlob); + + { + recorder->recordAddress(outNameBlob); + m_recordManager->endMethodRecordAppendOutput(); + } + + return result; + } + + SLANG_NO_THROW SlangResult SessionRecorder::getTypeConformanceWitnessMangledName( + slang::TypeReflection* type, + slang::TypeReflection* interfaceType, + ISlangBlob** outNameBlob) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ISession_getTypeConformanceWitnessMangledName, m_sessionHandle); + recorder->recordAddress(type); + recorder->recordAddress(interfaceType); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult result = m_actualSession->getTypeConformanceWitnessMangledName(type, interfaceType, outNameBlob); + + { + recorder->recordAddress(outNameBlob); + m_recordManager->endMethodRecordAppendOutput(); + } + + return result; + } + + SLANG_NO_THROW SlangResult SessionRecorder::getTypeConformanceWitnessSequentialID( + slang::TypeReflection* type, + slang::TypeReflection* interfaceType, + uint32_t* outId) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ISession_getTypeConformanceWitnessSequentialID, m_sessionHandle); + recorder->recordAddress(type); + recorder->recordAddress(interfaceType); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult result = m_actualSession->getTypeConformanceWitnessSequentialID(type, interfaceType, outId); + + // No need to record outId, it's not slang allocation + return result; + } + + SLANG_NO_THROW SlangResult SessionRecorder::createTypeConformanceComponentType( + slang::TypeReflection* type, + slang::TypeReflection* interfaceType, + slang::ITypeConformance** outConformance, + SlangInt conformanceIdOverride, + ISlangBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ISession_createTypeConformanceComponentType, m_sessionHandle); + recorder->recordAddress(type); + recorder->recordAddress(interfaceType); + recorder->recordInt64(conformanceIdOverride); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult result = m_actualSession->createTypeConformanceComponentType(type, interfaceType, outConformance, conformanceIdOverride, outDiagnostics); + + { + recorder->recordAddress(*outConformance); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + if (SLANG_OK != result) + { + TypeConformanceRecorder* conformanceRecord = new TypeConformanceRecorder(*outConformance, m_recordManager); + Slang::ComPtr<TypeConformanceRecorder> resultRecord(conformanceRecord); + *outConformance = resultRecord.detach(); + } + + return result; + } + + SLANG_NO_THROW SlangResult SessionRecorder::createCompileRequest( + SlangCompileRequest** outCompileRequest) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ISession_createCompileRequest, m_sessionHandle); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult result = m_actualSession->createCompileRequest(outCompileRequest); + + { + recorder->recordAddress(*outCompileRequest); + m_recordManager->endMethodRecordAppendOutput(); + } + + return result; + } + + SLANG_NO_THROW SlangInt SessionRecorder::getLoadedModuleCount() + { + // No need to record this function, it's just a query. + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + SlangInt count = m_actualSession->getLoadedModuleCount(); + return count; + } + + SLANG_NO_THROW slang::IModule* SessionRecorder::getLoadedModule(SlangInt index) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ISession_getLoadedModule, m_sessionHandle); + recorder->recordInt64(index); + recorder = m_recordManager->endMethodRecord(); + } + + slang::IModule* pModule = m_actualSession->getLoadedModule(index); + + { + recorder->recordAddress(pModule); + m_recordManager->endMethodRecordAppendOutput(); + } + + if (pModule) + { + ModuleRecorder* moduleRecord = m_mapModuleToRecord.tryGetValue(pModule); + if (!moduleRecord) + { + SLANG_RECORD_ASSERT(!"Module not found in mapModuleToRecord"); + } + return static_cast<slang::IModule*>(moduleRecord); + } + + return pModule; + } + + SLANG_NO_THROW bool SessionRecorder::isBinaryModuleUpToDate(const char* modulePath, slang::IBlob* binaryModuleBlob) + { + // No need to record this function, it's a query function and doesn't impact slang internal state. + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + bool result = m_actualSession->isBinaryModuleUpToDate(modulePath, binaryModuleBlob); + return result; + } + + ModuleRecorder* SessionRecorder::getModuleRecorder(slang::IModule* module) + { + ModuleRecorder* moduleRecord = nullptr; + moduleRecord = m_mapModuleToRecord.tryGetValue(module); + if (!moduleRecord) + { + moduleRecord = new ModuleRecorder(module, m_recordManager); + Slang::ComPtr<ModuleRecorder> result(moduleRecord); + m_mapModuleToRecord.add(module, *result.detach()); + } + return moduleRecord; + } + + SlangResult SessionRecorder::getActualComponentTypes( + slang::IComponentType* const* componentTypes, + SlangInt componentTypeCount, + List<slang::IComponentType*>& outActualComponentTypes) + { + for (SlangInt i = 0; i < componentTypeCount; i++) + { + slang::IComponentType* const& componentType = componentTypes[i]; + void* outObj = nullptr; + + if (componentType->queryInterface(ModuleRecorder::getTypeGuid(), &outObj) == SLANG_OK) + { + ModuleRecorder* moduleRecord = static_cast<ModuleRecorder*>(outObj); + outActualComponentTypes.add(moduleRecord->getActualModule()); + } + else if (componentType->queryInterface(EntryPointRecorder::getTypeGuid(), &outObj) == SLANG_OK) + { + EntryPointRecorder* entrypointRecord = static_cast<EntryPointRecorder*>(outObj); + outActualComponentTypes.add(entrypointRecord->getActualEntryPoint()); + } + // will fall back to the actual component type, it means that we didn't record this type. + else + { + outActualComponentTypes.add(componentType); + } + } + + if (componentTypeCount == outActualComponentTypes.getCount()) + { + return SLANG_OK; + } + return SLANG_FAIL; + } +} // namespace SlangRecord diff --git a/source/slang-capture-replay/slang-session.h b/source/slang-record-replay/record/slang-session.h index 23f818695..ca06e25a0 100644 --- a/source/slang-capture-replay/slang-session.h +++ b/source/slang-record-replay/record/slang-session.h @@ -4,34 +4,28 @@ #include "slang-com-ptr.h" #include "slang.h" #include "slang-com-helper.h" -#include "../core/slang-smart-pointer.h" -#include "../core/slang-dictionary.h" -#include "../slang/slang-compiler.h" +#include "../../core/slang-smart-pointer.h" +#include "../../core/slang-dictionary.h" +#include "../../slang/slang-compiler.h" #include "slang-module.h" -#include "capture-manager.h" +#include "record-manager.h" -namespace SlangCapture +namespace SlangRecord { using namespace Slang; - class SessionCapture: public RefObject, public slang::ISession + class SessionRecorder: public RefObject, public slang::ISession { public: SLANG_REF_OBJECT_IUNKNOWN_ALL ISlangUnknown* getInterface(const Guid& guid); - explicit SessionCapture(slang::ISession* session, CaptureManager* captureManager); - ~SessionCapture(); + explicit SessionRecorder(slang::ISession* session, RecordManager* recordManager); + ~SessionRecorder(); SLANG_NO_THROW slang::IGlobalSession* SLANG_MCALL getGlobalSession() override; SLANG_NO_THROW slang::IModule* SLANG_MCALL loadModule( const char* moduleName, slang::IBlob** outDiagnostics = nullptr) override; - slang::IModule* SLANG_MCALL loadModuleFromBlob( - const char* moduleName, - const char* path, - slang::IBlob* source, - ModuleBlobType blobType, - slang::IBlob** outDiagnostics = nullptr); SLANG_NO_THROW slang::IModule* SLANG_MCALL loadModuleFromIRBlob( const char* moduleName, const char* path, @@ -91,25 +85,25 @@ namespace SlangCapture SLANG_NO_THROW bool SLANG_MCALL isBinaryModuleUpToDate(const char* modulePath, slang::IBlob* binaryModuleBlob) override; private: - SLANG_FORCE_INLINE slang::ISession* asExternal(SessionCapture* session) + SLANG_FORCE_INLINE slang::ISession* asExternal(SessionRecorder* session) { return static_cast<slang::ISession*>(session); } - // The IComponentType object is the capture target, therefore `componentTypes` will not be + // The IComponentType object is the record target, therefore `componentTypes` will not be // the actual component types, we have to use the COM interface to get the actual objects. SlangResult getActualComponentTypes( slang::IComponentType* const* componentTypes, SlangInt componentTypeCount, List<slang::IComponentType*>& outActualComponentTypes); - ModuleCapture* getModuleCapture(slang::IModule* module); + ModuleRecorder* getModuleRecorder(slang::IModule* module); Slang::ComPtr<slang::ISession> m_actualSession; uint64_t m_sessionHandle = 0; - Dictionary<slang::IModule*, ModuleCapture> m_mapModuleToCapture; - CaptureManager* m_captureManager = nullptr; + Dictionary<slang::IModule*, ModuleRecorder> m_mapModuleToRecord; + RecordManager* m_recordManager = nullptr; }; } diff --git a/source/slang-record-replay/record/slang-type-conformance.cpp b/source/slang-record-replay/record/slang-type-conformance.cpp new file mode 100644 index 000000000..b9b652e9e --- /dev/null +++ b/source/slang-record-replay/record/slang-type-conformance.cpp @@ -0,0 +1,310 @@ +#include "../util/record-utility.h" +#include "slang-type-conformance.h" + +namespace SlangRecord +{ + TypeConformanceRecorder::TypeConformanceRecorder(slang::ITypeConformance* typeConformance, RecordManager* recordManager) + : m_actualTypeConformance(typeConformance), + m_recordManager(recordManager) + { + SLANG_RECORD_ASSERT(m_actualTypeConformance != nullptr); + SLANG_RECORD_ASSERT(m_recordManager != nullptr); + + m_typeConformanceHandle = reinterpret_cast<uint64_t>(m_actualTypeConformance.get()); + slangRecordLog(LogLevel::Verbose, "%s: %p\n", __PRETTY_FUNCTION__, typeConformance); + } + + TypeConformanceRecorder::~TypeConformanceRecorder() + { + m_actualTypeConformance->release(); + } + + ISlangUnknown* TypeConformanceRecorder::getInterface(const Guid& guid) + { + if (guid == TypeConformanceRecorder::getTypeGuid()) + { + return static_cast<ISlangUnknown*>(this); + } + else + { + return nullptr; + } + } + + SLANG_NO_THROW slang::ISession* TypeConformanceRecorder::getSession() + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ITypeConformance_getSession, m_typeConformanceHandle); + recorder = m_recordManager->endMethodRecord(); + } + + slang::ISession* res = m_actualTypeConformance->getSession(); + + { + recorder->recordAddress(res); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW slang::ProgramLayout* TypeConformanceRecorder::getLayout( + SlangInt targetIndex, + slang::IBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ICompositeComponentType_getLayout, m_typeConformanceHandle); + recorder->recordInt64(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + slang::ProgramLayout* programLayout = m_actualTypeConformance->getLayout(targetIndex, outDiagnostics); + + { + recorder->recordAddress(*outDiagnostics); + recorder->recordAddress(programLayout); + m_recordManager->endMethodRecordAppendOutput(); + } + + return programLayout; + } + + SLANG_NO_THROW SlangInt TypeConformanceRecorder::getSpecializationParamCount() + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + SlangInt res = m_actualTypeConformance->getSpecializationParamCount(); + return res; + } + + SLANG_NO_THROW SlangResult TypeConformanceRecorder::getEntryPointCode( + SlangInt entryPointIndex, + SlangInt targetIndex, + slang::IBlob** outCode, + slang::IBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ITypeConformance_getEntryPointCode, m_typeConformanceHandle); + recorder->recordInt64(entryPointIndex); + recorder->recordInt64(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualTypeConformance->getEntryPointCode(entryPointIndex, targetIndex, outCode, outDiagnostics); + + { + recorder->recordAddress(*outCode); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult TypeConformanceRecorder::getTargetCode( + SlangInt targetIndex, + slang::IBlob** outCode, + slang::IBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ITypeConformance_getTargetCode, m_typeConformanceHandle); + recorder->recordInt64(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualTypeConformance->getTargetCode(targetIndex, outCode, outDiagnostics); + + { + recorder->recordAddress(*outCode); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult TypeConformanceRecorder::getResultAsFileSystem( + SlangInt entryPointIndex, + SlangInt targetIndex, + ISlangMutableFileSystem** outFileSystem) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ITypeConformance_getResultAsFileSystem, m_typeConformanceHandle); + recorder->recordInt64(entryPointIndex); + recorder->recordInt64(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualTypeConformance->getResultAsFileSystem(entryPointIndex, targetIndex, outFileSystem); + + { + recorder->recordAddress(*outFileSystem); + } + + // TODO: We might need to wrap the file system object. + return res; + } + + SLANG_NO_THROW void TypeConformanceRecorder::getEntryPointHash( + SlangInt entryPointIndex, + SlangInt targetIndex, + slang::IBlob** outHash) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ITypeConformance_getEntryPointHash, m_typeConformanceHandle); + recorder->recordInt64(entryPointIndex); + recorder->recordInt64(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + m_actualTypeConformance->getEntryPointHash(entryPointIndex, targetIndex, outHash); + + { + recorder->recordAddress(*outHash); + m_recordManager->endMethodRecordAppendOutput(); + } + } + + SLANG_NO_THROW SlangResult TypeConformanceRecorder::specialize( + slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, + slang::IComponentType** outSpecializedComponentType, + ISlangBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ITypeConformance_specialize, m_typeConformanceHandle); + recorder->recordInt64(specializationArgCount); + recorder->recordStructArray(specializationArgs, specializationArgCount); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualTypeConformance->specialize(specializationArgs, specializationArgCount, outSpecializedComponentType, outDiagnostics); + + { + recorder->recordAddress(*outSpecializedComponentType); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult TypeConformanceRecorder::link( + slang::IComponentType** outLinkedComponentType, + ISlangBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ITypeConformance_link, m_typeConformanceHandle); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualTypeConformance->link(outLinkedComponentType, outDiagnostics); + + { + recorder->recordAddress(*outLinkedComponentType); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult TypeConformanceRecorder::getEntryPointHostCallable( + int entryPointIndex, + int targetIndex, + ISlangSharedLibrary** outSharedLibrary, + slang::IBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ITypeConformance_getEntryPointHostCallable, m_typeConformanceHandle); + recorder->recordInt32(entryPointIndex); + recorder->recordInt32(targetIndex); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualTypeConformance->getEntryPointHostCallable(entryPointIndex, targetIndex, outSharedLibrary, outDiagnostics); + + { + recorder->recordAddress(*outSharedLibrary); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult TypeConformanceRecorder::renameEntryPoint( + const char* newName, IComponentType** outEntryPoint) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ITypeConformance_renameEntryPoint, m_typeConformanceHandle); + recorder->recordString(newName); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualTypeConformance->renameEntryPoint(newName, outEntryPoint); + + { + recorder->recordAddress(*outEntryPoint); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } + + SLANG_NO_THROW SlangResult TypeConformanceRecorder::linkWithOptions( + IComponentType** outLinkedComponentType, + uint32_t compilerOptionEntryCount, + slang::CompilerOptionEntry* compilerOptionEntries, + ISlangBlob** outDiagnostics) + { + slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); + + ParameterRecorder* recorder {}; + { + recorder = m_recordManager->beginMethodRecord(ApiCallId::ITypeConformance_linkWithOptions, m_typeConformanceHandle); + recorder->recordUint32(compilerOptionEntryCount); + recorder->recordStructArray(compilerOptionEntries, compilerOptionEntryCount); + recorder = m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualTypeConformance->linkWithOptions(outLinkedComponentType, compilerOptionEntryCount, compilerOptionEntries, outDiagnostics); + + { + recorder->recordAddress(*outLinkedComponentType); + recorder->recordAddress(*outDiagnostics); + m_recordManager->endMethodRecordAppendOutput(); + } + + return res; + } +} diff --git a/source/slang-capture-replay/slang-type-conformance.h b/source/slang-record-replay/record/slang-type-conformance.h index 2c36abbfb..7bcae0d15 100644 --- a/source/slang-capture-replay/slang-type-conformance.h +++ b/source/slang-record-replay/record/slang-type-conformance.h @@ -4,15 +4,15 @@ #include "slang-com-ptr.h" #include "slang.h" #include "slang-com-helper.h" -#include "../core/slang-smart-pointer.h" -#include "../core/slang-dictionary.h" -#include "../slang/slang-compiler.h" -#include "capture-manager.h" +#include "../../core/slang-smart-pointer.h" +#include "../../core/slang-dictionary.h" +#include "../../slang/slang-compiler.h" +#include "record-manager.h" -namespace SlangCapture +namespace SlangRecord { using namespace Slang; - class TypeConformanceCapture: public slang::ITypeConformance, public RefObject + class TypeConformanceRecorder: public slang::ITypeConformance, public RefObject { public: SLANG_COM_INTERFACE(0x0e67d05d, 0xee0a, 0x41e1, { 0xb5, 0xa3, 0x23, 0xe3, 0xb0, 0xec, 0x33, 0xf1 }) @@ -20,8 +20,8 @@ namespace SlangCapture SLANG_REF_OBJECT_IUNKNOWN_ALL ISlangUnknown* getInterface(const Guid& guid); - explicit TypeConformanceCapture(slang::ITypeConformance* typeConformance, CaptureManager* captureManager); - ~TypeConformanceCapture(); + explicit TypeConformanceRecorder(slang::ITypeConformance* typeConformance, RecordManager* recordManager); + ~TypeConformanceRecorder(); // Interfaces for `IComponentType` virtual SLANG_NO_THROW slang::ISession* SLANG_MCALL getSession() override; @@ -71,7 +71,7 @@ namespace SlangCapture private: Slang::ComPtr<slang::ITypeConformance> m_actualTypeConformance; uint64_t m_typeConformanceHandle = 0; - CaptureManager* m_captureManager = nullptr; + RecordManager* m_recordManager = nullptr; }; } #endif // SLANG_TYPE_CONFORMANCE_H diff --git a/source/slang-record-replay/replay/decoder-consumer.cpp b/source/slang-record-replay/replay/decoder-consumer.cpp new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/source/slang-record-replay/replay/decoder-consumer.cpp diff --git a/source/slang-record-replay/replay/decoder-consumer.h b/source/slang-record-replay/replay/decoder-consumer.h new file mode 100644 index 000000000..f79d9aa5e --- /dev/null +++ b/source/slang-record-replay/replay/decoder-consumer.h @@ -0,0 +1,178 @@ +#ifndef DECODER_CONSUMER_H +#define DECODER_CONSUMER_H + +#include "slang.h" +// #include "../../slang/slang-compiler.h" +#include "../util/record-format.h" + +namespace SlangRecord +{ + class IDecoderConsumer + { + public: + virtual void CreateGlobalSession(ObjectID objectId, const uint8_t* parameterBuffer, int64_t bufferSize) = 0; + virtual void IGlobalSession_createSession(ObjectID objectId, slang::SessionDesc const& desc, ObjectID outSessionId) = 0; + virtual void IGlobalSession_findProfile(ObjectID objectId, char const* name) = 0; + virtual void IGlobalSession_setDownstreamCompilerPath(ObjectID objectId, SlangPassThrough passThrough, char const* path) = 0; + virtual void IGlobalSession_setDownstreamCompilerPrelude(ObjectID objectId, SlangPassThrough inPassThrough, char const* prelude) = 0; + virtual void IGlobalSession_getDownstreamCompilerPrelude(ObjectID objectId, SlangPassThrough inPassThrough, ObjectID outPreludeId) = 0; + + virtual void IGlobalSession_getBuildTagString(ObjectID objectId) { (void) objectId; } + + virtual void IGlobalSession_setDefaultDownstreamCompiler(ObjectID objectId, SlangSourceLanguage sourceLanguage, SlangPassThrough defaultCompiler) = 0; + virtual void IGlobalSession_getDefaultDownstreamCompiler(ObjectID objectId, SlangSourceLanguage sourceLanguage) = 0; + virtual void IGlobalSession_setLanguagePrelude(ObjectID objectId, SlangSourceLanguage inSourceLanguage, char const* prelude) = 0; + virtual void IGlobalSession_getLanguagePrelude(ObjectID objectId, SlangSourceLanguage inSourceLanguage, ObjectID outPreludeId) = 0; + virtual void IGlobalSession_createCompileRequest(ObjectID objectId, ObjectID outCompileRequest) = 0; + virtual void IGlobalSession_addBuiltins(ObjectID objectId, char const* sourcePath, char const* sourceString) = 0; + virtual void IGlobalSession_setSharedLibraryLoader(ObjectID objectId, ObjectID loaderId) = 0; + virtual void IGlobalSession_getSharedLibraryLoader(ObjectID objectId, ObjectID outLoaderId) = 0; + virtual void IGlobalSession_checkCompileTargetSupport(ObjectID objectId, SlangCompileTarget target) = 0; + virtual void IGlobalSession_checkPassThroughSupport(ObjectID objectId, SlangPassThrough passThrough) = 0; + virtual void IGlobalSession_compileStdLib(ObjectID objectId, slang::CompileStdLibFlags flags) = 0; + virtual void IGlobalSession_loadStdLib(ObjectID objectId, const void* stdLib, size_t stdLibSizeInBytes) = 0; + virtual void IGlobalSession_saveStdLib(ObjectID objectId, SlangArchiveType archiveType, ObjectID outBlobId) = 0; + virtual void IGlobalSession_findCapability(ObjectID objectId, char const* name) = 0; + virtual void IGlobalSession_setDownstreamCompilerForTransition(ObjectID objectId, SlangCompileTarget source, SlangCompileTarget target, SlangPassThrough compiler) = 0; + virtual void IGlobalSession_getDownstreamCompilerForTransition(ObjectID objectId, SlangCompileTarget source, SlangCompileTarget target) = 0; + + virtual void IGlobalSession_getCompilerElapsedTime(ObjectID objectId) { (void) objectId; } + + virtual void IGlobalSession_setSPIRVCoreGrammar(ObjectID objectId, char const* jsonPath) = 0; + virtual void IGlobalSession_parseCommandLineArguments(ObjectID objectId, int argc, const char* const* argv, ObjectID outSessionDescId, ObjectID outAllocationId) = 0; + virtual void IGlobalSession_getSessionDescDigest(ObjectID objectId, slang::SessionDesc* sessionDesc, ObjectID outBlobId) = 0; + + // ISession + virtual void ISession_getGlobalSession(ObjectID objectId, ObjectID outGlobalSessionId) = 0; + virtual void ISession_loadModule(ObjectID objectId, const char* moduleName, ObjectID outDiagnostics, ObjectID outModuleId) = 0; + + virtual void ISession_loadModuleFromIRBlob(ObjectID objectId, const char* moduleName, + const char* path, slang::IBlob* source, ObjectID outDiagnosticsId, ObjectID outModuleId) = 0; + virtual void ISession_loadModuleFromSource(ObjectID objectId, const char* moduleName, + const char* path, slang::IBlob* source, ObjectID outDiagnosticsId, ObjectID outModuleId) = 0; + virtual void ISession_loadModuleFromSourceString(ObjectID objectId, const char* moduleName, + const char* path, const char* string, ObjectID outDiagnosticsId, ObjectID outModuleId) = 0; + virtual void ISession_createCompositeComponentType(ObjectID objectId, ObjectID* componentTypeIds, + SlangInt componentTypeCount, ObjectID outCompositeComponentTypeIds, ObjectID outDiagnosticsId) = 0; + + virtual void ISession_specializeType(ObjectID objectId, ObjectID typeId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outDiagnosticsId, ObjectID outTypeReflectionId) = 0; + + virtual void ISession_getTypeLayout(ObjectID objectId, ObjectID typeId, SlangInt targetIndex, + slang::LayoutRules rules, ObjectID outDiagnosticsId, ObjectID outTypeLayoutReflection) = 0; + + virtual void ISession_getContainerType(ObjectID objectId, ObjectID elementType, + slang::ContainerType containerType, ObjectID outDiagnosticsId, ObjectID outTypeReflectionId) = 0; + + virtual void ISession_getDynamicType(ObjectID objectId, ObjectID outTypeReflectionId) = 0; + + virtual void ISession_getTypeRTTIMangledName(ObjectID objectId, ObjectID typeId, ObjectID outNameBlobId) = 0; + + virtual void ISession_getTypeConformanceWitnessMangledName(ObjectID objectId, ObjectID typeId, + ObjectID interfaceTypeId, ObjectID outNameBlobId) = 0; + + virtual void ISession_getTypeConformanceWitnessSequentialID(ObjectID objectId, ObjectID typeId, + ObjectID interfaceTypeId, uint32_t outId) = 0; + + virtual void ISession_createTypeConformanceComponentType(ObjectID objectId, ObjectID typeId, + ObjectID interfaceTypeId, ObjectID outConformanceId, + SlangInt conformanceIdOverride, ObjectID outDiagnosticsId) = 0; + + virtual void ISession_createCompileRequest(ObjectID objectId, ObjectID outCompileRequestId) = 0; + + virtual void ISession_getLoadedModuleCount(ObjectID objectId) { (void) objectId; } + + virtual void ISession_getLoadedModule(ObjectID objectId, SlangInt index, ObjectID outModuleId) = 0; + + virtual void ISession_isBinaryModuleUpToDate(ObjectID objectId) { (void) objectId; } + + // IModule + virtual void IModule_findEntryPointByName(ObjectID objectId, char const* name, ObjectID outEntryPointId) = 0; + + virtual void IModule_getDefinedEntryPointCount(ObjectID objectId) { (void) objectId; } + + virtual void IModule_getDefinedEntryPoint(ObjectID objectId, SlangInt32 index, ObjectID outEntryPointId) = 0; + virtual void IModule_serialize(ObjectID objectId, ObjectID outSerializedBlobId) = 0; + virtual void IModule_writeToFile(ObjectID objectId, char const* fileName) = 0; + + virtual void IModule_getName(ObjectID objectId) { (void) objectId; } + virtual void IModule_getFilePath(ObjectID objectId) { (void) objectId; } + virtual void IModule_getUniqueIdentity(ObjectID objectId) { (void) objectId; } + + virtual void IModule_findAndCheckEntryPoint(ObjectID objectId, char const* name, SlangStage stage, ObjectID outEntryPointId, ObjectID outDiagnostics) = 0; + + virtual void IModule_getSession(ObjectID objectId, ObjectID outSessionId) = 0; + virtual void IModule_getLayout(ObjectID objectId, SlangInt targetIndex, ObjectID outDiagnosticsId, ObjectID retProgramLayoutId) = 0; + + virtual void IModule_getSpecializationParamCount(ObjectID objectId) { (void) objectId; } + + virtual void IModule_getEntryPointCode(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void IModule_getTargetCode(ObjectID objectId, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void IModule_getResultAsFileSystem(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outFileSystem) = 0; + virtual void IModule_getEntryPointHash(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outHashId) = 0; + virtual void IModule_specialize(ObjectID objectId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outSpecializedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void IModule_link(ObjectID objectId, ObjectID outLinkedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void IModule_getEntryPointHostCallable(ObjectID objectId, int entryPointIndex, int targetIndex, ObjectID outSharedLibrary, ObjectID outDiagnostics) = 0; + virtual void IModule_renameEntryPoint(ObjectID objectId, const char* newName, ObjectID outEntryPointId) = 0; + virtual void IModule_linkWithOptions(ObjectID objectId, ObjectID outLinkedComponentTypeId, + uint32_t compilerOptionEntryCount, slang::CompilerOptionEntry* compilerOptionEntries, ObjectID outDiagnosticsId) = 0; + + // IEntryPoint + virtual void IEntryPoint_getSession(ObjectID objectId, ObjectID outSessionId) = 0; + virtual void IEntryPoint_getLayout(ObjectID objectId, SlangInt targetIndex, ObjectID outDiagnosticsId, ObjectID retProgramLayoutId) = 0; + + virtual void IEntryPoint_getSpecializationParamCount(ObjectID objectId) { (void) objectId; }; + + virtual void IEntryPoint_getEntryPointCode(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void IEntryPoint_getTargetCode(ObjectID objectId, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void IEntryPoint_getResultAsFileSystem(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outFileSystem) = 0; + virtual void IEntryPoint_getEntryPointHash(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outHashId) = 0; + virtual void IEntryPoint_specialize(ObjectID objectId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outSpecializedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void IEntryPoint_link(ObjectID objectId, ObjectID outLinkedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void IEntryPoint_getEntryPointHostCallable(ObjectID objectId, int entryPointIndex, int targetIndex, ObjectID outSharedLibrary, ObjectID outDiagnostics) = 0; + virtual void IEntryPoint_renameEntryPoint(ObjectID objectId, const char* newName, ObjectID outEntryPointId) = 0; + virtual void IEntryPoint_linkWithOptions(ObjectID objectId, ObjectID outLinkedComponentTypeId, + uint32_t compilerOptionEntryCount, slang::CompilerOptionEntry* compilerOptionEntries, ObjectID outDiagnosticsId) = 0; + + // ICompositeComponentType + virtual void ICompositeComponentType_getSession(ObjectID objectId, ObjectID outSessionId) = 0; + virtual void ICompositeComponentType_getLayout(ObjectID objectId, SlangInt targetIndex, ObjectID outDiagnosticsId, ObjectID retProgramLayoutId) = 0; + + virtual void ICompositeComponentType_getSpecializationParamCount(ObjectID objectId) { (void) objectId; }; + + virtual void ICompositeComponentType_getEntryPointCode(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void ICompositeComponentType_getTargetCode(ObjectID objectId, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void ICompositeComponentType_getResultAsFileSystem(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outFileSystem) = 0; + virtual void ICompositeComponentType_getEntryPointHash(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outHashId) = 0; + virtual void ICompositeComponentType_specialize(ObjectID objectId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outSpecializedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void ICompositeComponentType_link(ObjectID objectId, ObjectID outLinkedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void ICompositeComponentType_getEntryPointHostCallable(ObjectID objectId, int entryPointIndex, int targetIndex, ObjectID outSharedLibrary, ObjectID outDiagnostics) = 0; + virtual void ICompositeComponentType_renameEntryPoint(ObjectID objectId, const char* newName, ObjectID outEntryPointId) = 0; + virtual void ICompositeComponentType_linkWithOptions(ObjectID objectId, ObjectID outLinkedComponentTypeId, + uint32_t compilerOptionEntryCount, slang::CompilerOptionEntry* compilerOptionEntries, ObjectID outDiagnosticsId) = 0; + + // ITypeConformance + virtual void ITypeConformance_getSession(ObjectID objectId, ObjectID outSessionId) = 0; + virtual void ITypeConformance_getLayout(ObjectID objectId, SlangInt targetIndex, ObjectID outDiagnosticsId, ObjectID retProgramLayoutId) = 0; + + virtual void ITypeConformance_getSpecializationParamCount(ObjectID objectId) { (void) objectId; }; + + virtual void ITypeConformance_getEntryPointCode(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void ITypeConformance_getTargetCode(ObjectID objectId, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void ITypeConformance_getResultAsFileSystem(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outFileSystem) = 0; + virtual void ITypeConformance_getEntryPointHash(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outHashId) = 0; + virtual void ITypeConformance_specialize(ObjectID objectId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outSpecializedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void ITypeConformance_link(ObjectID objectId, ObjectID outLinkedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void ITypeConformance_getEntryPointHostCallable(ObjectID objectId, int entryPointIndex, int targetIndex, ObjectID outSharedLibrary, ObjectID outDiagnostics) = 0; + virtual void ITypeConformance_renameEntryPoint(ObjectID objectId, const char* newName, ObjectID outEntryPointId) = 0; + virtual void ITypeConformance_linkWithOptions(ObjectID objectId, ObjectID outLinkedComponentTypeId, + uint32_t compilerOptionEntryCount, slang::CompilerOptionEntry* compilerOptionEntries, ObjectID outDiagnosticsId) = 0; + }; +} + + +#endif // DECODER_CONSUMER_H diff --git a/source/slang-record-replay/replay/decoder-helper.cpp b/source/slang-record-replay/replay/decoder-helper.cpp new file mode 100644 index 000000000..c9252bbc6 --- /dev/null +++ b/source/slang-record-replay/replay/decoder-helper.cpp @@ -0,0 +1,60 @@ +#include <cstdlib> +#include <vector> +#include "decoder-helper.h" +#include "parameter-decoder.h" + +namespace SlangRecord +{ + DecoderAllocatorSingleton* DecoderAllocatorSingleton::getInstance() + { + thread_local DecoderAllocatorSingleton instance; + return &instance; + } + + void* DecoderAllocatorSingleton::allocate(size_t size) + { + void* data = calloc(1, size); + + if (!data) + { + slangRecordLog(LogLevel::Error, "Failed to allocate memory\n"); + std::abort(); + } + + m_allocations.add(data); + return data; + } + + DecoderAllocatorSingleton::~DecoderAllocatorSingleton() + { + for (auto allocation : m_allocations) + { + free(allocation); + } + } + + template <typename T, typename U> + size_t StructDecoder<T, U>::decode(const uint8_t* buffer, int64_t bufferSize) + { + return ParameterDecoder::decodeStruct(buffer, bufferSize, *this); + } + + size_t BlobDecoder::decode(const uint8_t* buffer, int64_t bufferSize) + { + size_t readByte = 0; + readByte = ParameterDecoder::decodeAddress(buffer, bufferSize, m_address); + + if (!m_address) + { + readByte += ParameterDecoder::decodePointer(buffer + readByte, bufferSize - readByte, m_blobData); + } + return readByte; + } + + template class StructDecoder<slang::SessionDesc>; + template class StructDecoder<slang::PreprocessorMacroDesc>; + template class StructDecoder<slang::CompilerOptionEntry>; + template class StructDecoder<slang::CompilerOptionValue>; + template class StructDecoder<slang::TargetDesc>; + template class StructDecoder<slang::SpecializationArg>; +} diff --git a/source/slang-record-replay/replay/decoder-helper.h b/source/slang-record-replay/replay/decoder-helper.h new file mode 100644 index 000000000..c109348e9 --- /dev/null +++ b/source/slang-record-replay/replay/decoder-helper.h @@ -0,0 +1,109 @@ +#ifndef SLANG_DECODER_HELPER_H +#define SLANG_DECODER_HELPER_H + +#include <stdint.h> +#include "slang.h" +#include "slang-com-helper.h" +#include "../util/record-format.h" +#include "../../core/slang-list.h" + +namespace SlangRecord { + + // This class is used to allocate memory for the type decoder + class DecoderAllocatorSingleton + { + public: + static DecoderAllocatorSingleton* getInstance(); + void* allocate(size_t size); + ~DecoderAllocatorSingleton(); + private: + DecoderAllocatorSingleton() = default; + Slang::List<void*> m_allocations; + }; + + class DecoderBase + { + public: + virtual ~DecoderBase() = default; + void* allocate(size_t size) { return m_allocator->allocate(size); } + protected: + DecoderAllocatorSingleton* m_allocator = DecoderAllocatorSingleton::getInstance(); + }; + + // We don't allow pointer type to be used as a template parameter + template <typename T, typename U = typename std::enable_if< !std::is_pointer<T>::value >::type> + class ValueDecoder : public DecoderBase + { + public: + T& getValue() { return m_value;} + + protected: + T m_value {}; + }; + + template <typename T, typename = typename std::enable_if< !std::is_pointer<T>::value >::type> + class StructDecoder : public ValueDecoder<T> + { + public: + using Super = ValueDecoder<T>; + size_t decode(const uint8_t* buffer, int64_t bufferSize); + }; + + // We only allow pointer type to be used as a template parameter + template <typename T, typename U = typename std::enable_if< std::is_pointer<T>::value >::type> + class PointerDecoder : public DecoderBase + { + public: + void setPointer(void* data) { m_pointer = static_cast<T>(data); } + T getPointer() const { return m_pointer; } + void setPointerAddress(uint64_t address) { m_pointerAddress = address; } + void setDataSize(size_t size) { m_dataSize = size; } + size_t getDataSize() const { return m_dataSize; } + private: + T m_pointer {nullptr}; + uint64_t m_pointerAddress = 0; + size_t m_dataSize = 0; + }; + + class BlobDecoder + { + private: + PointerDecoder<void*> m_blobData; + + class BlobImpl : public slang::IBlob + { + public: + // ISlangUnknown + virtual SlangResult SLANG_MCALL queryInterface(SlangUUID const& uuid, void** outObject) override + { + if (uuid == ISlangUnknown::getTypeGuid() || + uuid == ISlangBlob::getTypeGuid()) + { + *outObject = static_cast<ISlangBlob*>(this); + return SLANG_OK; + } + *outObject = nullptr; + return SLANG_E_NO_INTERFACE; + } + + virtual uint32_t SLANG_MCALL addRef() override { return 1; } + virtual uint32_t SLANG_MCALL release() override { return 1; } + + BlobImpl(const PointerDecoder<void*>* blobData) : m_pBlobData(blobData) {} + virtual const void* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_pBlobData->getPointer();} + virtual size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_pBlobData->getDataSize(); } + private: + const PointerDecoder<void*>* m_pBlobData; + }; + + BlobImpl m_blobImpl {&m_blobData}; + AddressFormat m_address {0}; + public: + size_t decode(const uint8_t* buffer, int64_t bufferSize); + slang::IBlob* getBlob() { return &m_blobImpl; } + }; + + using StringDecoder = PointerDecoder<char*>; +} // namespace SlangRecord + +#endif // SLANG_RECORD_DECODER_HELPER_H diff --git a/source/slang-record-replay/replay/json-consumer.cpp b/source/slang-record-replay/replay/json-consumer.cpp new file mode 100644 index 000000000..a3ea0c31f --- /dev/null +++ b/source/slang-record-replay/replay/json-consumer.cpp @@ -0,0 +1,477 @@ +#include "json-consumer.h" + +namespace SlangRecord +{ + void JsonConsumer::CreateGlobalSession(ObjectID objectId, const uint8_t* parameterBuffer, int64_t bufferSize) + { + } + + void JsonConsumer::IGlobalSession_createSession(ObjectID objectId, slang::SessionDesc const& desc, ObjectID outSessionId) + { + } + + + void JsonConsumer::IGlobalSession_findProfile(ObjectID objectId, char const* name) + { + } + + + void JsonConsumer::IGlobalSession_setDownstreamCompilerPath(ObjectID objectId, SlangPassThrough passThrough, char const* path) + { + } + + + void JsonConsumer::IGlobalSession_setDownstreamCompilerPrelude(ObjectID objectId, SlangPassThrough inPassThrough, char const* prelude) + { + } + + + void JsonConsumer::IGlobalSession_getDownstreamCompilerPrelude(ObjectID objectId, SlangPassThrough inPassThrough, ObjectID outPreludeId) + { + } + + + void JsonConsumer::IGlobalSession_setDefaultDownstreamCompiler(ObjectID objectId, SlangSourceLanguage sourceLanguage, SlangPassThrough defaultCompiler) + { + } + + + void JsonConsumer::IGlobalSession_getDefaultDownstreamCompiler(ObjectID objectId, SlangSourceLanguage sourceLanguage) + { + } + + + void JsonConsumer::IGlobalSession_setLanguagePrelude(ObjectID objectId, SlangSourceLanguage inSourceLanguage, char const* prelude) + { + } + + + void JsonConsumer::IGlobalSession_getLanguagePrelude(ObjectID objectId, SlangSourceLanguage inSourceLanguage, ObjectID outPreludeId) + { + } + + + void JsonConsumer::IGlobalSession_createCompileRequest(ObjectID objectId, ObjectID outCompileRequest) + { + } + + + void JsonConsumer::IGlobalSession_addBuiltins(ObjectID objectId, char const* sourcePath, char const* sourceString) + { + } + + + void JsonConsumer::IGlobalSession_setSharedLibraryLoader(ObjectID objectId, ObjectID loaderId) + { + } + + + void JsonConsumer::IGlobalSession_getSharedLibraryLoader(ObjectID objectId, ObjectID outLoaderId) + { + } + + + void JsonConsumer::IGlobalSession_checkCompileTargetSupport(ObjectID objectId, SlangCompileTarget target) + { + } + + + void JsonConsumer::IGlobalSession_checkPassThroughSupport(ObjectID objectId, SlangPassThrough passThrough) + { + } + + + void JsonConsumer::IGlobalSession_compileStdLib(ObjectID objectId, slang::CompileStdLibFlags flags) + { + } + + + void JsonConsumer::IGlobalSession_loadStdLib(ObjectID objectId, const void* stdLib, size_t stdLibSizeInBytes) + { + } + + + void JsonConsumer::IGlobalSession_saveStdLib(ObjectID objectId, SlangArchiveType archiveType, ObjectID outBlobId) + { + } + + + void JsonConsumer::IGlobalSession_findCapability(ObjectID objectId, char const* name) + { + } + + + void JsonConsumer::IGlobalSession_setDownstreamCompilerForTransition(ObjectID objectId, SlangCompileTarget source, SlangCompileTarget target, SlangPassThrough compiler) + { + } + + + void JsonConsumer::IGlobalSession_getDownstreamCompilerForTransition(ObjectID objectId, SlangCompileTarget source, SlangCompileTarget target) + { + } + + + void JsonConsumer::IGlobalSession_setSPIRVCoreGrammar(ObjectID objectId, char const* jsonPath) + { + } + + + void JsonConsumer::IGlobalSession_parseCommandLineArguments(ObjectID objectId, int argc, const char* const* argv, ObjectID outSessionDescId, ObjectID outAllocationId) + { + } + + + void JsonConsumer::IGlobalSession_getSessionDescDigest(ObjectID objectId, slang::SessionDesc* sessionDesc, ObjectID outBlobId) + { + } + + + + // ISession + void JsonConsumer::ISession_getGlobalSession(ObjectID objectId, ObjectID outGlobalSessionId) + { + } + + + void JsonConsumer::ISession_loadModule(ObjectID objectId, const char* moduleName, ObjectID outDiagnostics, ObjectID outModuleId) + { + } + + void JsonConsumer::ISession_loadModuleFromIRBlob(ObjectID objectId, const char* moduleName, + const char* path, slang::IBlob* source, ObjectID outDiagnosticsId, ObjectID outModuleId) + { + } + + + void JsonConsumer::ISession_loadModuleFromSource(ObjectID objectId, const char* moduleName, + const char* path, slang::IBlob* source, ObjectID outDiagnosticsId, ObjectID outModuleId) + { + } + + + void JsonConsumer::ISession_loadModuleFromSourceString(ObjectID objectId, const char* moduleName, + const char* path, const char* string, ObjectID outDiagnosticsId, ObjectID outModuleId) + { + } + + + void JsonConsumer::ISession_createCompositeComponentType(ObjectID objectId, ObjectID* componentTypeIds, + SlangInt componentTypeCount, ObjectID outCompositeComponentTypeId, ObjectID outDiagnosticsId) + { + } + + + void JsonConsumer::ISession_specializeType(ObjectID objectId, ObjectID typeId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outDiagnosticsId, ObjectID outTypeReflectionId) + { + } + + void JsonConsumer::ISession_getTypeLayout(ObjectID objectId, ObjectID typeId, SlangInt targetIndex, + slang::LayoutRules rules, ObjectID outDiagnosticsId, ObjectID outTypeLayoutReflection) + { + } + + void JsonConsumer::ISession_getContainerType(ObjectID objectId, ObjectID elementType, + slang::ContainerType containerType, ObjectID outDiagnosticsId, ObjectID outTypeReflectionId) + { + } + + void JsonConsumer::ISession_getDynamicType(ObjectID objectId, ObjectID outTypeReflectionId) + { + } + + void JsonConsumer::ISession_getTypeRTTIMangledName(ObjectID objectId, ObjectID typeId, ObjectID outNameBlobId) + { + } + + void JsonConsumer::ISession_getTypeConformanceWitnessMangledName(ObjectID objectId, ObjectID typeId, + ObjectID interfaceTypeId, ObjectID outNameBlobId) + { + } + + + void JsonConsumer::ISession_getTypeConformanceWitnessSequentialID(ObjectID objectId, ObjectID typeId, + ObjectID interfaceTypeId, uint32_t outId) + { + } + + void JsonConsumer::ISession_createTypeConformanceComponentType(ObjectID objectId, ObjectID typeId, + ObjectID interfaceTypeId, ObjectID outConformanceId, + SlangInt conformanceIdOverride, ObjectID outDiagnosticsId) + { + } + + + void JsonConsumer::ISession_createCompileRequest(ObjectID objectId, ObjectID outCompileRequestId) + { + } + + + void JsonConsumer::ISession_getLoadedModule(ObjectID objectId, SlangInt index, ObjectID outModuleId) + { + } + + + + // IModule + void JsonConsumer::IModule_findEntryPointByName(ObjectID objectId, char const* name, ObjectID outEntryPointId) + { + } + + + void JsonConsumer::IModule_getDefinedEntryPoint(ObjectID objectId, SlangInt32 index, ObjectID outEntryPointId) + { + } + + + void JsonConsumer::IModule_serialize(ObjectID objectId, ObjectID outSerializedBlobId) + { + } + + + void JsonConsumer::IModule_writeToFile(ObjectID objectId, char const* fileName) + { + } + + + void JsonConsumer::IModule_findAndCheckEntryPoint(ObjectID objectId, char const* name, SlangStage stage, ObjectID outEntryPointId, ObjectID outDiagnostics) + { + } + + + + void JsonConsumer::IModule_getSession(ObjectID objectId, ObjectID outSessionId) + { + } + + + void JsonConsumer::IModule_getLayout(ObjectID objectId, SlangInt targetIndex, ObjectID outDiagnosticsId, ObjectID retProgramLayoutId) + { + } + + + void JsonConsumer::IModule_getEntryPointCode(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) + { + } + + + void JsonConsumer::IModule_getTargetCode(ObjectID objectId, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) + { + } + + + void JsonConsumer::IModule_getResultAsFileSystem(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outFileSystem) + { + } + + + void JsonConsumer::IModule_getEntryPointHash(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outHashId) + { + } + + + void JsonConsumer::IModule_specialize(ObjectID objectId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outSpecializedComponentTypeId, ObjectID outDiagnosticsId) + { + } + + + void JsonConsumer::IModule_link(ObjectID objectId, ObjectID outLinkedComponentTypeId, ObjectID outDiagnosticsId) + { + } + + + void JsonConsumer::IModule_getEntryPointHostCallable(ObjectID objectId, int entryPointIndex, int targetIndex, ObjectID outSharedLibrary, ObjectID outDiagnostics) + { + } + + + void JsonConsumer::IModule_renameEntryPoint(ObjectID objectId, const char* newName, ObjectID outEntryPointId) + { + } + + + void JsonConsumer::IModule_linkWithOptions(ObjectID objectId, ObjectID outLinkedComponentTypeId, + uint32_t compilerOptionEntryCount, slang::CompilerOptionEntry* compilerOptionEntries, ObjectID outDiagnosticsId) + { + } + + + + // IEntryPoint + void JsonConsumer::IEntryPoint_getSession(ObjectID objectId, ObjectID outSessionId) + { + } + + + void JsonConsumer::IEntryPoint_getLayout(ObjectID objectId, SlangInt targetIndex, ObjectID outDiagnosticsId, ObjectID retProgramLayoutId) + { + } + + + void JsonConsumer::IEntryPoint_getEntryPointCode(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) + { + } + + + void JsonConsumer::IEntryPoint_getTargetCode(ObjectID objectId, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) + { + } + + + void JsonConsumer::IEntryPoint_getResultAsFileSystem(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outFileSystem) + { + } + + + void JsonConsumer::IEntryPoint_getEntryPointHash(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outHashId) + { + } + + + void JsonConsumer::IEntryPoint_specialize(ObjectID objectId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outSpecializedComponentTypeId, ObjectID outDiagnosticsId) + { + } + + + void JsonConsumer::IEntryPoint_link(ObjectID objectId, ObjectID outLinkedComponentTypeId, ObjectID outDiagnosticsId) + { + } + + + void JsonConsumer::IEntryPoint_getEntryPointHostCallable(ObjectID objectId, int entryPointIndex, int targetIndex, ObjectID outSharedLibrary, ObjectID outDiagnostics) + { + } + + + void JsonConsumer::IEntryPoint_renameEntryPoint(ObjectID objectId, const char* newName, ObjectID outEntryPointId) + { + } + + + void JsonConsumer::IEntryPoint_linkWithOptions(ObjectID objectId, ObjectID outLinkedComponentTypeId, + uint32_t compilerOptionEntryCount, slang::CompilerOptionEntry* compilerOptionEntries, ObjectID outDiagnosticsId) + { + } + + + + // ICompositeComponentType + void JsonConsumer::ICompositeComponentType_getSession(ObjectID objectId, ObjectID outSessionId) + { + } + + + void JsonConsumer::ICompositeComponentType_getLayout(ObjectID objectId, SlangInt targetIndex, ObjectID outDiagnosticsId, ObjectID retProgramLayoutId) + { + } + + + void JsonConsumer::ICompositeComponentType_getEntryPointCode(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) + { + } + + + void JsonConsumer::ICompositeComponentType_getTargetCode(ObjectID objectId, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) + { + } + + + void JsonConsumer::ICompositeComponentType_getResultAsFileSystem(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outFileSystem) + { + } + + + void JsonConsumer::ICompositeComponentType_getEntryPointHash(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outHashId) + { + } + + + void JsonConsumer::ICompositeComponentType_specialize(ObjectID objectId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outSpecializedComponentTypeId, ObjectID outDiagnosticsId) + { + } + + + void JsonConsumer::ICompositeComponentType_link(ObjectID objectId, ObjectID outLinkedComponentTypeId, ObjectID outDiagnosticsId) + { + } + + + void JsonConsumer::ICompositeComponentType_getEntryPointHostCallable(ObjectID objectId, int entryPointIndex, int targetIndex, ObjectID outSharedLibrary, ObjectID outDiagnostics) + { + } + + + void JsonConsumer::ICompositeComponentType_renameEntryPoint(ObjectID objectId, const char* newName, ObjectID outEntryPointId) + { + } + + + void JsonConsumer::ICompositeComponentType_linkWithOptions(ObjectID objectId, ObjectID outLinkedComponentTypeId, + uint32_t compilerOptionEntryCount, slang::CompilerOptionEntry* compilerOptionEntries, ObjectID outDiagnosticsId) + { + } + + + + // ITypeConformance + void JsonConsumer::ITypeConformance_getSession(ObjectID objectId, ObjectID outSessionId) + { + } + + + void JsonConsumer::ITypeConformance_getLayout(ObjectID objectId, SlangInt targetIndex, ObjectID outDiagnosticsId, ObjectID retProgramLayoutId) + { + } + + + void JsonConsumer::ITypeConformance_getEntryPointCode(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) + { + } + + + void JsonConsumer::ITypeConformance_getTargetCode(ObjectID objectId, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) + { + } + + + void JsonConsumer::ITypeConformance_getResultAsFileSystem(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outFileSystem) + { + } + + + void JsonConsumer::ITypeConformance_getEntryPointHash(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outHashId) + { + } + + + void JsonConsumer::ITypeConformance_specialize(ObjectID objectId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outSpecializedComponentTypeId, ObjectID outDiagnosticsId) + { + } + + + void JsonConsumer::ITypeConformance_link(ObjectID objectId, ObjectID outLinkedComponentTypeId, ObjectID outDiagnosticsId) + { + } + + + void JsonConsumer::ITypeConformance_getEntryPointHostCallable(ObjectID objectId, int entryPointIndex, int targetIndex, ObjectID outSharedLibrary, ObjectID outDiagnostics) + { + } + + + void JsonConsumer::ITypeConformance_renameEntryPoint(ObjectID objectId, const char* newName, ObjectID outEntryPointId) + { + } + + + void JsonConsumer::ITypeConformance_linkWithOptions(ObjectID objectId, ObjectID outLinkedComponentTypeId, + uint32_t compilerOptionEntryCount, slang::CompilerOptionEntry* compilerOptionEntries, ObjectID outDiagnosticsId) + { + } + + +}; // namespace SlangRecord diff --git a/source/slang-record-replay/replay/json-consumer.h b/source/slang-record-replay/replay/json-consumer.h new file mode 100644 index 000000000..e638a833b --- /dev/null +++ b/source/slang-record-replay/replay/json-consumer.h @@ -0,0 +1,174 @@ +#ifndef JSON_CONSUMER_H +#define JSON_CONSUMER_H + +#include "decoder-consumer.h" + +namespace SlangRecord +{ + class JsonConsumer : public IDecoderConsumer + { + public: + virtual void CreateGlobalSession(ObjectID objectId, const uint8_t* parameterBuffer, int64_t bufferSize) = 0; + virtual void IGlobalSession_createSession(ObjectID objectId, slang::SessionDesc const& desc, ObjectID outSessionId) = 0; + virtual void IGlobalSession_findProfile(ObjectID objectId, char const* name) = 0; + virtual void IGlobalSession_setDownstreamCompilerPath(ObjectID objectId, SlangPassThrough passThrough, char const* path) = 0; + virtual void IGlobalSession_setDownstreamCompilerPrelude(ObjectID objectId, SlangPassThrough inPassThrough, char const* prelude) = 0; + virtual void IGlobalSession_getDownstreamCompilerPrelude(ObjectID objectId, SlangPassThrough inPassThrough, ObjectID outPreludeId) = 0; + + virtual void IGlobalSession_getBuildTagString(ObjectID objectId) { (void) objectId; } + + virtual void IGlobalSession_setDefaultDownstreamCompiler(ObjectID objectId, SlangSourceLanguage sourceLanguage, SlangPassThrough defaultCompiler) = 0; + virtual void IGlobalSession_getDefaultDownstreamCompiler(ObjectID objectId, SlangSourceLanguage sourceLanguage) = 0; + virtual void IGlobalSession_setLanguagePrelude(ObjectID objectId, SlangSourceLanguage inSourceLanguage, char const* prelude) = 0; + virtual void IGlobalSession_getLanguagePrelude(ObjectID objectId, SlangSourceLanguage inSourceLanguage, ObjectID outPreludeId) = 0; + virtual void IGlobalSession_createCompileRequest(ObjectID objectId, ObjectID outCompileRequest) = 0; + virtual void IGlobalSession_addBuiltins(ObjectID objectId, char const* sourcePath, char const* sourceString) = 0; + virtual void IGlobalSession_setSharedLibraryLoader(ObjectID objectId, ObjectID loaderId) = 0; + virtual void IGlobalSession_getSharedLibraryLoader(ObjectID objectId, ObjectID outLoaderId) = 0; + virtual void IGlobalSession_checkCompileTargetSupport(ObjectID objectId, SlangCompileTarget target) = 0; + virtual void IGlobalSession_checkPassThroughSupport(ObjectID objectId, SlangPassThrough passThrough) = 0; + virtual void IGlobalSession_compileStdLib(ObjectID objectId, slang::CompileStdLibFlags flags) = 0; + virtual void IGlobalSession_loadStdLib(ObjectID objectId, const void* stdLib, size_t stdLibSizeInBytes) = 0; + virtual void IGlobalSession_saveStdLib(ObjectID objectId, SlangArchiveType archiveType, ObjectID outBlobId) = 0; + virtual void IGlobalSession_findCapability(ObjectID objectId, char const* name) = 0; + virtual void IGlobalSession_setDownstreamCompilerForTransition(ObjectID objectId, SlangCompileTarget source, SlangCompileTarget target, SlangPassThrough compiler) = 0; + virtual void IGlobalSession_getDownstreamCompilerForTransition(ObjectID objectId, SlangCompileTarget source, SlangCompileTarget target) = 0; + + virtual void IGlobalSession_getCompilerElapsedTime(ObjectID objectId) { (void) objectId; } + + virtual void IGlobalSession_setSPIRVCoreGrammar(ObjectID objectId, char const* jsonPath) = 0; + virtual void IGlobalSession_parseCommandLineArguments(ObjectID objectId, int argc, const char* const* argv, ObjectID outSessionDescId, ObjectID outAllocationId) = 0; + virtual void IGlobalSession_getSessionDescDigest(ObjectID objectId, slang::SessionDesc* sessionDesc, ObjectID outBlobId) = 0; + + // ISession + virtual void ISession_getGlobalSession(ObjectID objectId, ObjectID outGlobalSessionId) = 0; + virtual void ISession_loadModule(ObjectID objectId, const char* moduleName, ObjectID outDiagnostics, ObjectID outModuleId) = 0; + + virtual void ISession_loadModuleFromIRBlob(ObjectID objectId, const char* moduleName, + const char* path, slang::IBlob* source, ObjectID outDiagnosticsId, ObjectID outModuleId) = 0; + virtual void ISession_loadModuleFromSource(ObjectID objectId, const char* moduleName, + const char* path, slang::IBlob* source, ObjectID outDiagnosticsId, ObjectID outModuleId) = 0; + virtual void ISession_loadModuleFromSourceString(ObjectID objectId, const char* moduleName, + const char* path, const char* string, ObjectID outDiagnosticsId, ObjectID outModuleId) = 0; + virtual void ISession_createCompositeComponentType(ObjectID objectId, ObjectID* componentTypeIds, + SlangInt componentTypeCount, ObjectID outCompositeComponentTypeIds, ObjectID outDiagnosticsId) = 0; + + virtual void ISession_specializeType(ObjectID objectId, ObjectID typeId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outDiagnosticsId, ObjectID outTypeReflectionId) = 0; + + virtual void ISession_getTypeLayout(ObjectID objectId, ObjectID typeId, SlangInt targetIndex, + slang::LayoutRules rules, ObjectID outDiagnosticsId, ObjectID outTypeLayoutReflection) = 0; + + virtual void ISession_getContainerType(ObjectID objectId, ObjectID elementType, + slang::ContainerType containerType, ObjectID outDiagnosticsId, ObjectID outTypeReflectionId) = 0; + + virtual void ISession_getDynamicType(ObjectID objectId, ObjectID outTypeReflectionId) = 0; + + virtual void ISession_getTypeRTTIMangledName(ObjectID objectId, ObjectID typeId, ObjectID outNameBlobId) = 0; + + virtual void ISession_getTypeConformanceWitnessMangledName(ObjectID objectId, ObjectID typeId, + ObjectID interfaceTypeId, ObjectID outNameBlobId) = 0; + + virtual void ISession_getTypeConformanceWitnessSequentialID(ObjectID objectId, ObjectID typeId, + ObjectID interfaceTypeId, uint32_t outId) = 0; + + virtual void ISession_createTypeConformanceComponentType(ObjectID objectId, ObjectID typeId, + ObjectID interfaceTypeId, ObjectID outConformanceId, + SlangInt conformanceIdOverride, ObjectID outDiagnosticsId) = 0; + + virtual void ISession_createCompileRequest(ObjectID objectId, ObjectID outCompileRequestId) = 0; + + virtual void ISession_getLoadedModuleCount(ObjectID objectId) { (void) objectId; } + + virtual void ISession_getLoadedModule(ObjectID objectId, SlangInt index, ObjectID outModuleId) = 0; + + virtual void ISession_isBinaryModuleUpToDate(ObjectID objectId) { (void) objectId; } + + // IModule + virtual void IModule_findEntryPointByName(ObjectID objectId, char const* name, ObjectID outEntryPointId) = 0; + + virtual void IModule_getDefinedEntryPointCount(ObjectID objectId) { (void) objectId; } + + virtual void IModule_getDefinedEntryPoint(ObjectID objectId, SlangInt32 index, ObjectID outEntryPointId) = 0; + virtual void IModule_serialize(ObjectID objectId, ObjectID outSerializedBlobId) = 0; + virtual void IModule_writeToFile(ObjectID objectId, char const* fileName) = 0; + + virtual void IModule_getName(ObjectID objectId) { (void) objectId; } + virtual void IModule_getFilePath(ObjectID objectId) { (void) objectId; } + virtual void IModule_getUniqueIdentity(ObjectID objectId) { (void) objectId; } + + virtual void IModule_findAndCheckEntryPoint(ObjectID objectId, char const* name, SlangStage stage, ObjectID outEntryPointId, ObjectID outDiagnostics) = 0; + + virtual void IModule_getSession(ObjectID objectId, ObjectID outSessionId) = 0; + virtual void IModule_getLayout(ObjectID objectId, SlangInt targetIndex, ObjectID outDiagnosticsId, ObjectID retProgramLayoutId) = 0; + + virtual void IModule_getSpecializationParamCount(ObjectID objectId) { (void) objectId; } + + virtual void IModule_getEntryPointCode(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void IModule_getTargetCode(ObjectID objectId, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void IModule_getResultAsFileSystem(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outFileSystem) = 0; + virtual void IModule_getEntryPointHash(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outHashId) = 0; + virtual void IModule_specialize(ObjectID objectId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outSpecializedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void IModule_link(ObjectID objectId, ObjectID outLinkedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void IModule_getEntryPointHostCallable(ObjectID objectId, int entryPointIndex, int targetIndex, ObjectID outSharedLibrary, ObjectID outDiagnostics) = 0; + virtual void IModule_renameEntryPoint(ObjectID objectId, const char* newName, ObjectID outEntryPointId) = 0; + virtual void IModule_linkWithOptions(ObjectID objectId, ObjectID outLinkedComponentTypeId, + uint32_t compilerOptionEntryCount, slang::CompilerOptionEntry* compilerOptionEntries, ObjectID outDiagnosticsId) = 0; + + // IEntryPoint + virtual void IEntryPoint_getSession(ObjectID objectId, ObjectID outSessionId) = 0; + virtual void IEntryPoint_getLayout(ObjectID objectId, SlangInt targetIndex, ObjectID outDiagnosticsId, ObjectID retProgramLayoutId) = 0; + + virtual void IEntryPoint_getSpecializationParamCount(ObjectID objectId) { (void) objectId; }; + + virtual void IEntryPoint_getEntryPointCode(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void IEntryPoint_getTargetCode(ObjectID objectId, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void IEntryPoint_getResultAsFileSystem(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outFileSystem) = 0; + virtual void IEntryPoint_getEntryPointHash(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outHashId) = 0; + virtual void IEntryPoint_specialize(ObjectID objectId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outSpecializedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void IEntryPoint_link(ObjectID objectId, ObjectID outLinkedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void IEntryPoint_getEntryPointHostCallable(ObjectID objectId, int entryPointIndex, int targetIndex, ObjectID outSharedLibrary, ObjectID outDiagnostics) = 0; + virtual void IEntryPoint_renameEntryPoint(ObjectID objectId, const char* newName, ObjectID outEntryPointId) = 0; + virtual void IEntryPoint_linkWithOptions(ObjectID objectId, ObjectID outLinkedComponentTypeId, + uint32_t compilerOptionEntryCount, slang::CompilerOptionEntry* compilerOptionEntries, ObjectID outDiagnosticsId) = 0; + + // ICompositeComponentType + virtual void ICompositeComponentType_getSession(ObjectID objectId, ObjectID outSessionId) = 0; + virtual void ICompositeComponentType_getLayout(ObjectID objectId, SlangInt targetIndex, ObjectID outDiagnosticsId, ObjectID retProgramLayoutId) = 0; + + virtual void ICompositeComponentType_getSpecializationParamCount(ObjectID objectId) { (void) objectId; }; + + virtual void ICompositeComponentType_getEntryPointCode(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void ICompositeComponentType_getTargetCode(ObjectID objectId, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void ICompositeComponentType_getResultAsFileSystem(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outFileSystem) = 0; + virtual void ICompositeComponentType_getEntryPointHash(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outHashId) = 0; + virtual void ICompositeComponentType_specialize(ObjectID objectId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outSpecializedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void ICompositeComponentType_link(ObjectID objectId, ObjectID outLinkedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void ICompositeComponentType_getEntryPointHostCallable(ObjectID objectId, int entryPointIndex, int targetIndex, ObjectID outSharedLibrary, ObjectID outDiagnostics) = 0; + virtual void ICompositeComponentType_renameEntryPoint(ObjectID objectId, const char* newName, ObjectID outEntryPointId) = 0; + virtual void ICompositeComponentType_linkWithOptions(ObjectID objectId, ObjectID outLinkedComponentTypeId, + uint32_t compilerOptionEntryCount, slang::CompilerOptionEntry* compilerOptionEntries, ObjectID outDiagnosticsId) = 0; + + // ITypeConformance + virtual void ITypeConformance_getSession(ObjectID objectId, ObjectID outSessionId) = 0; + virtual void ITypeConformance_getLayout(ObjectID objectId, SlangInt targetIndex, ObjectID outDiagnosticsId, ObjectID retProgramLayoutId) = 0; + + virtual void ITypeConformance_getSpecializationParamCount(ObjectID objectId) { (void) objectId; }; + + virtual void ITypeConformance_getEntryPointCode(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void ITypeConformance_getTargetCode(ObjectID objectId, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void ITypeConformance_getResultAsFileSystem(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outFileSystem) = 0; + virtual void ITypeConformance_getEntryPointHash(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outHashId) = 0; + virtual void ITypeConformance_specialize(ObjectID objectId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outSpecializedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void ITypeConformance_link(ObjectID objectId, ObjectID outLinkedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void ITypeConformance_getEntryPointHostCallable(ObjectID objectId, int entryPointIndex, int targetIndex, ObjectID outSharedLibrary, ObjectID outDiagnostics) = 0; + virtual void ITypeConformance_renameEntryPoint(ObjectID objectId, const char* newName, ObjectID outEntryPointId) = 0; + virtual void ITypeConformance_linkWithOptions(ObjectID objectId, ObjectID outLinkedComponentTypeId, + uint32_t compilerOptionEntryCount, slang::CompilerOptionEntry* compilerOptionEntries, ObjectID outDiagnosticsId) = 0; + }; +} +#endif // JSON_CONSUMER_H diff --git a/source/slang-record-replay/replay/parameter-decoder.cpp b/source/slang-record-replay/replay/parameter-decoder.cpp new file mode 100644 index 000000000..ed1c1dfe2 --- /dev/null +++ b/source/slang-record-replay/replay/parameter-decoder.cpp @@ -0,0 +1,215 @@ +#include <string.h> +#include "parameter-decoder.h" + +namespace SlangRecord +{ + size_t ParameterDecoder::decodeString(const uint8_t* buffer, int64_t bufferSize, PointerDecoder<char*>& typeDecoder) + { + SLANG_RECORD_ASSERT((buffer != nullptr) && (bufferSize > 0)); + + if (bufferSize < (int64_t)sizeof(uint32_t)) + { + return 0; + } + + uint32_t stringLength = 0; + size_t readByte = 0; + readByte += decodeUint32(buffer, bufferSize - readByte, stringLength); + + SLANG_RECORD_ASSERT(bufferSize >= (int64_t)(readByte + stringLength)); + + if (stringLength == 0) + { + return readByte; + } + + uint8_t* data = (uint8_t*)typeDecoder.allocate(stringLength + 1); + memcpy(data, buffer + readByte, stringLength); + typeDecoder.setPointer(data); + typeDecoder.setDataSize(stringLength + 1); + return readByte + stringLength; + } + + size_t ParameterDecoder::decodePointer(const uint8_t* buffer, int64_t bufferSize, PointerDecoder<void*>& pointerDecoder) + { + SLANG_RECORD_ASSERT((buffer != nullptr) && (bufferSize > 0)); + + if (bufferSize < (int64_t)sizeof(uint32_t)) + { + return 0; + } + + uint64_t address = 0; + size_t readByte = decodeAddress(buffer, bufferSize, address); + pointerDecoder.setPointerAddress(address); + + uint64_t dataSize = 0; + readByte += decodeUint64(buffer + readByte, bufferSize - readByte, dataSize); + + // return if the data size is 0 + if (dataSize == 0) + { + return readByte; + } + + SLANG_RECORD_ASSERT(bufferSize >= (int64_t)(readByte + dataSize)); + + uint8_t* data = (uint8_t*)pointerDecoder.allocate(dataSize); + memcpy(data, buffer + readByte, dataSize); + pointerDecoder.setPointer(data); + pointerDecoder.setDataSize(dataSize); + return readByte + dataSize; + } + + size_t ParameterDecoder::decodeStruct(const uint8_t* buffer, int64_t bufferSize, ValueDecoder<slang::SessionDesc>& sessionDesc) + { + SLANG_RECORD_ASSERT((buffer != nullptr) && (bufferSize > 0)); + + if(bufferSize < (int64_t)sizeof(uint64_t)) + { + return 0; + } + + size_t readByte = 0; + slang::SessionDesc& desc = sessionDesc.getValue(); + + uint64_t structSize = 0; + readByte = decodeUint64(buffer, bufferSize, structSize); + desc.structureSize = structSize; + + readByte += decodeInt64(buffer + readByte, bufferSize - readByte, desc.targetCount); + + if (desc.targetCount > 0) + { + slang::TargetDesc* targets = (slang::TargetDesc*)sessionDesc.allocate(sizeof(slang::TargetDesc) * desc.targetCount); + readByte += decodeStructArray(buffer + readByte, bufferSize - readByte, targets, desc.targetCount); + desc.targets = targets; + } + + readByte += decodeUint32(buffer + readByte, bufferSize - readByte, desc.flags); + readByte += decodeEnumValue(buffer + readByte, bufferSize - readByte, desc.defaultMatrixLayoutMode); + readByte += decodeInt64(buffer + readByte, bufferSize - readByte, desc.searchPathCount); + + if (desc.searchPathCount > 0) + { + char** searchPaths = (char**)sessionDesc.allocate(sizeof(char*) * desc.searchPathCount); + decodeStringArray(buffer + readByte, bufferSize - readByte, searchPaths, desc.searchPathCount); + desc.searchPaths = searchPaths; + } + + readByte += decodeInt64(buffer + readByte, bufferSize - readByte, desc.preprocessorMacroCount); + if (desc.preprocessorMacroCount > 0) + { + slang::PreprocessorMacroDesc* macros = (slang::PreprocessorMacroDesc*) + sessionDesc.allocate(sizeof(slang::PreprocessorMacroDesc) * desc.preprocessorMacroCount); + readByte += decodeStructArray(buffer + readByte, bufferSize - readByte, macros, desc.preprocessorMacroCount); + desc.preprocessorMacros = macros; + } + + readByte += decodeBool(buffer + readByte, bufferSize - readByte, desc.enableEffectAnnotations); + readByte += decodeBool(buffer + readByte, bufferSize - readByte, desc.allowGLSLSyntax); + readByte += decodeUint32(buffer + readByte, bufferSize - readByte, desc.compilerOptionEntryCount); + + if (desc.compilerOptionEntryCount > 0) + { + slang::CompilerOptionEntry* entries = (slang::CompilerOptionEntry*) + sessionDesc.allocate(sizeof(slang::CompilerOptionEntry) * desc.compilerOptionEntryCount); + readByte += decodeStructArray(buffer + readByte, bufferSize - readByte, entries, desc.compilerOptionEntryCount); + desc.compilerOptionEntries = entries; + } + + return readByte; + } + + size_t ParameterDecoder::decodeStruct(const uint8_t* buffer, int64_t bufferSize, ValueDecoder<slang::PreprocessorMacroDesc>& desc) + { + SLANG_RECORD_ASSERT((buffer != nullptr) && (bufferSize > 0)); + + size_t readByte = 0; + PointerDecoder<char*> name; + PointerDecoder<char*> value; + + readByte = decodeString(buffer, bufferSize, name); + readByte += decodeString(buffer + readByte, bufferSize - readByte, value); + + desc.getValue().name = name.getPointer(); + desc.getValue().value = value.getPointer(); + + return readByte; + } + + size_t ParameterDecoder::decodeStruct(const uint8_t* buffer, int64_t bufferSize, ValueDecoder<slang::CompilerOptionEntry>& entry) + { + SLANG_RECORD_ASSERT((buffer != nullptr) && (bufferSize > 0)); + + size_t readByte = 0; + readByte = decodeEnumValue(buffer, bufferSize, entry.getValue().name); + + ValueDecoder<slang::CompilerOptionValue> value; + readByte += decodeStruct(buffer + readByte, bufferSize - readByte, value); + entry.getValue().value = value.getValue(); + + return readByte; + } + + size_t ParameterDecoder::decodeStruct(const uint8_t* buffer, int64_t bufferSize, ValueDecoder<slang::CompilerOptionValue>& value) + { + SLANG_RECORD_ASSERT((buffer != nullptr) && (bufferSize > 0)); + + size_t readByte = 0; + readByte = decodeEnumValue(buffer, bufferSize, value.getValue().kind); + readByte += decodeInt32(buffer + readByte, bufferSize - readByte, value.getValue().intValue0); + + PointerDecoder<char*> stringValue0; + readByte += decodeString(buffer + readByte, bufferSize - readByte, stringValue0); + value.getValue().stringValue0 = stringValue0.getPointer(); + + PointerDecoder<char*> stringValue1; + readByte += decodeString(buffer + readByte, bufferSize - readByte, stringValue1); + value.getValue().stringValue1 = stringValue1.getPointer(); + return 0; + } + + size_t ParameterDecoder::decodeStruct(const uint8_t* buffer, int64_t bufferSize, ValueDecoder<slang::TargetDesc>& targetDesc) + { + SLANG_RECORD_ASSERT((buffer != nullptr) && (bufferSize > 0)); + + size_t readByte = 0; + uint64_t structSize = 0; + readByte = decodeUint64(buffer, bufferSize, structSize); + targetDesc.getValue().structureSize = structSize; + + readByte += decodeEnumValue(buffer + readByte, bufferSize - readByte, targetDesc.getValue().format); + readByte += decodeEnumValue(buffer + readByte, bufferSize - readByte, targetDesc.getValue().profile); + readByte += decodeEnumValue(buffer + readByte, bufferSize - readByte, targetDesc.getValue().flags); + readByte += decodeEnumValue(buffer + readByte, bufferSize - readByte, targetDesc.getValue().floatingPointMode); + readByte += decodeEnumValue(buffer + readByte, bufferSize - readByte, targetDesc.getValue().lineDirectiveMode); + readByte += decodeBool(buffer + readByte, bufferSize - readByte, targetDesc.getValue().forceGLSLScalarBufferLayout); + readByte += decodeUint32(buffer + readByte, bufferSize - readByte, targetDesc.getValue().compilerOptionEntryCount); + + if (targetDesc.getValue().compilerOptionEntryCount > 0) + { + slang::CompilerOptionEntry* entries = (slang::CompilerOptionEntry*) + targetDesc.allocate(sizeof(slang::CompilerOptionEntry) * targetDesc.getValue().compilerOptionEntryCount); + readByte += decodeStructArray(buffer + readByte, bufferSize - readByte, entries, targetDesc.getValue().compilerOptionEntryCount); + targetDesc.getValue().compilerOptionEntries = entries; + } + + return readByte; + } + + size_t ParameterDecoder::decodeStruct(const uint8_t* buffer, int64_t bufferSize, ValueDecoder<slang::SpecializationArg>& specializationArg) + { + SLANG_RECORD_ASSERT((buffer != nullptr) && (bufferSize > 0)); + + size_t readByte = 0; + readByte = decodeEnumValue(buffer, bufferSize, specializationArg.getValue().kind); + + // TODO: Special handle to address decode is needed. + uint64_t address = 0; + readByte += decodeAddress(buffer + readByte, bufferSize - readByte, address); + (void)address; + + return readByte; + } +} diff --git a/source/slang-record-replay/replay/parameter-decoder.h b/source/slang-record-replay/replay/parameter-decoder.h new file mode 100644 index 000000000..5d6f40987 --- /dev/null +++ b/source/slang-record-replay/replay/parameter-decoder.h @@ -0,0 +1,131 @@ +#ifndef PARAMETER_DECODER_H +#define PARAMETER_DECODER_H + +#include <cinttypes> +#include <cstring> +#include <cstdlib> +#include <vector> +#include "../util/record-format.h" +#include "../util/record-utility.h" +#include "slang.h" +#include "decoder-helper.h" + +namespace SlangRecord +{ + class ParameterDecoder + { + public: + static size_t decodeInt8(const uint8_t* buffer, int64_t bufferSize, int8_t& value) { return decodeValue(buffer, bufferSize, value); } + static size_t decodeUint8(const uint8_t* buffer, int64_t bufferSize, uint8_t& value) { return decodeValue(buffer, bufferSize, value); } + static size_t decodeInt16(const uint8_t* buffer, int64_t bufferSize, int16_t& value) { return decodeValue(buffer, bufferSize, value); } + static size_t decodeUint16(const uint8_t* buffer, int64_t bufferSize, uint16_t& value) { return decodeValue(buffer, bufferSize, value); } + static size_t decodeInt32(const uint8_t* buffer, int64_t bufferSize, int32_t& value) { return decodeValue(buffer, bufferSize, value); } + static size_t decodeUint32(const uint8_t* buffer, int64_t bufferSize, uint32_t& value) { return decodeValue(buffer, bufferSize, value); } + static size_t decodeInt64(const uint8_t* buffer, int64_t bufferSize, int64_t& value) { return decodeValue(buffer, bufferSize, value); } + static size_t decodeUint64(const uint8_t* buffer, int64_t bufferSize, uint64_t& value) { return decodeValue(buffer, bufferSize, value); } + static size_t decodeFloat(const uint8_t* buffer, int64_t bufferSize, float& value) { return decodeValue(buffer, bufferSize, value); } + static size_t decodeDouble(const uint8_t* buffer, int64_t bufferSize, double& value) { return decodeValue(buffer, bufferSize, value); } + static size_t decodeBool(const uint8_t* buffer, int64_t bufferSize, bool& value) { return decodeValue(buffer, bufferSize, value); } + + template<typename T> + static size_t decodeEnumValue(const uint8_t* buffer, size_t bufferSize, T& value) + { + uint32_t decodedValue; + size_t readByte = decodeValue(buffer, bufferSize, decodedValue); + value = static_cast<T>(decodedValue); + return readByte; + } + + static size_t decodeString(const uint8_t* buffer, int64_t bufferSize, PointerDecoder<char*>& typeDecoder); + + static size_t decodePointer(const uint8_t* buffer, int64_t bufferSize, PointerDecoder<void*>& pointerDecoder); + + static size_t decodeAddress(const uint8_t* buffer, int64_t bufferSize, SlangRecord::AddressFormat& address) + { + return decodeValue(buffer, bufferSize, address); + } + static size_t decodeStruct(const uint8_t* buffer, int64_t bufferSize, ValueDecoder<slang::SessionDesc>& sessionDesc); + static size_t decodeStruct(const uint8_t* buffer, int64_t bufferSize, ValueDecoder<slang::PreprocessorMacroDesc>& desc); + static size_t decodeStruct(const uint8_t* buffer, int64_t bufferSize, ValueDecoder<slang::CompilerOptionEntry>& entry); + static size_t decodeStruct(const uint8_t* buffer, int64_t bufferSize, ValueDecoder<slang::CompilerOptionValue>& value); + static size_t decodeStruct(const uint8_t* buffer, int64_t bufferSize, ValueDecoder<slang::TargetDesc>& targetDesc); + static size_t decodeStruct(const uint8_t* buffer, int64_t bufferSize, ValueDecoder<slang::SpecializationArg>& specializationArg); + + template <typename T> + static size_t decodeValueArray(const uint8_t* buffer, int64_t bufferSize, ValueDecoder<T>* valueArray, size_t count) + { + SLANG_RECORD_ASSERT((buffer != nullptr) && (bufferSize > 0)); + + size_t readByte = 0; + for (size_t i = 0; i < count; ++i) + { + readByte += decodeValue(buffer + readByte, bufferSize - readByte, valueArray[i]); + } + return readByte; + } + + static size_t decodeStringArray(const uint8_t* buffer, int64_t bufferSize, char** outputArray, size_t count) + { + SLANG_RECORD_ASSERT((buffer != nullptr) && (bufferSize > 0)); + + size_t readByte = 0; + for (uint32_t i = 0; i < count; i++) + { + PointerDecoder<char*> item; + readByte += decodeString(buffer + readByte, bufferSize - readByte, item); + + // Copy the search path + outputArray[i] = item.getPointer(); + } + return readByte; + } + + template <typename T> + static size_t decodeStructArray(const uint8_t* buffer, int64_t bufferSize, T* outputArray, size_t count) + { + SLANG_RECORD_ASSERT((buffer != nullptr) && (bufferSize > 0)); + + size_t bufferRead = 0; + for (size_t i = 0; i < count; ++i) + { + ValueDecoder<T> item; + bufferRead += decodeStruct(buffer + bufferRead, bufferSize - bufferRead, item); + outputArray[i] = item.getValue(); + } + return bufferRead; + } + + static size_t decodeAddressArray(const uint8_t* buffer, int64_t bufferSize, uint64_t* addressArray, size_t count) + { + SLANG_RECORD_ASSERT((buffer != nullptr) && (bufferSize > 0)); + + size_t bufferRead = 0; + for (size_t i = 0; i < count; ++i) + { + bufferRead += decodeAddress(buffer + bufferRead, bufferSize - bufferRead, addressArray[i]); + } + + return bufferRead; + } + + + private: + template <typename T> + static size_t decodeValue(const uint8_t* buffer, int64_t bufferSize, T& value) + { + SLANG_RECORD_ASSERT((buffer != nullptr) && (bufferSize > 0)); + + int64_t dataSize = sizeof(T); + + SLANG_RECORD_ASSERT(bufferSize >= dataSize); + + size_t bytesRead = 0; + bytesRead = dataSize; + memcpy(&value, buffer, dataSize); + + return bytesRead; + } + }; +} // namespace SlangRecord + +#endif // PARAMETER_DECODER_H diff --git a/source/slang-record-replay/replay/recordFile-processor.cpp b/source/slang-record-replay/replay/recordFile-processor.cpp new file mode 100644 index 000000000..bf9cec435 --- /dev/null +++ b/source/slang-record-replay/replay/recordFile-processor.cpp @@ -0,0 +1,132 @@ +#include "recordFile-processor.h" +#include "../util/record-utility.h" +#include "parameter-decoder.h" + +namespace SlangRecord +{ + RecordFileProcessor::RecordFileProcessor(const std::string& filename) + { + Slang::String path(filename.c_str()); + Slang::FileMode fileMode = Slang::FileMode::Open; + Slang::FileAccess fileAccess = Slang::FileAccess::Read; + Slang::FileShare fileShare = Slang::FileShare::None; + + // Open the record file with read-only access + SlangResult res = m_inputStream.init(path, fileMode, fileAccess, fileShare); + + if (res != SLANG_OK) + { + SlangRecord::slangRecordLog(SlangRecord::LogLevel::Error, "Failed to open file %s\n", filename.c_str()); + std::abort(); + } + } + + bool RecordFileProcessor::processNextBlock() + { + FunctionHeader header {}; + if (!processHeader(header)) + { + return false; + } + + ApiClassId classId = static_cast<ApiClassId>(getClassId(header.callId)); + + // capacity comparison will be performed in the reserve call, so we can safely call reserve + m_parameterBuffer.reserve(header.dataSizeInBytes); + + size_t readBytes = 0; + SlangResult res = SLANG_OK; + + if (header.dataSizeInBytes) + { + res = m_inputStream.read(m_parameterBuffer.getBuffer(), header.dataSizeInBytes, readBytes); + } + + if (res != SLANG_OK || readBytes != header.dataSizeInBytes) + { + return false; + } + + FunctionTailer tailer {}; + if (!processTailer(tailer)) + { + return false; + } + + if (tailer.dataSizeInBytes) + { + m_outputBuffer.reserve(tailer.dataSizeInBytes); + res = m_inputStream.read(m_outputBuffer.getBuffer(), tailer.dataSizeInBytes, readBytes); + + if (res != SLANG_OK || readBytes != tailer.dataSizeInBytes) + { + return false; + } + } + + bool ret = false; + SlangDecoder::ParameterBlock paramBlock {}; + paramBlock.parameterBuffer = m_parameterBuffer.getBuffer(); + paramBlock.parameterBufferSize = header.dataSizeInBytes; + paramBlock.outputBuffer = m_outputBuffer.getBuffer(); + paramBlock.outputBufferSize = tailer.dataSizeInBytes; + + if (classId == GlobalFunction) + { + ret = m_decoder.processFunctionCall(header, paramBlock); + } + else + { + ret = m_decoder.processMethodCall(header, paramBlock); + } + + m_parameterBuffer.clear(); + return ret; + } + + bool RecordFileProcessor::processHeader(FunctionHeader& header) + { + size_t readBytes = 0; + SlangResult res = m_inputStream.read(&header, sizeof(FunctionHeader), readBytes); + + if (res != SLANG_OK || readBytes != sizeof(FunctionHeader)) + { + return false; + } + + if (header.magic != MAGIC_HEADER || header.callId == ApiCallId::InvalidCallId) + { + return false; + } + + return true; + } + + bool RecordFileProcessor::processTailer(FunctionTailer& tailer) + { + size_t readBytes = 0; + SlangResult res = m_inputStream.read(&tailer, sizeof(FunctionTailer), readBytes); + + if (res != SLANG_OK || readBytes != sizeof(FunctionTailer)) + { + return false; + } + + if (tailer.magic != MAGIC_TAILER) + { + return false; + } + + return true; + } + + bool RecordFileProcessor::processMethod(FunctionHeader const& header, const uint8_t* parameterBuffer, int64_t bufferSize) + { + return false; + } + + bool RecordFileProcessor::processFunction(FunctionHeader const& header, const uint8_t* parameterBuffer, int64_t bufferSize) + { + return false; + } +}; // namespace SlangRecord diff --git a/source/slang-record-replay/replay/recordFile-processor.h b/source/slang-record-replay/replay/recordFile-processor.h new file mode 100644 index 000000000..b9570a259 --- /dev/null +++ b/source/slang-record-replay/replay/recordFile-processor.h @@ -0,0 +1,30 @@ +#ifndef FILE_PROCESSOR_H +#define FILE_PROCESSOR_H + +#include <string> +#include "../../core/slang-stream.h" +#include "../util/record-format.h" +#include "slang-decoder.h" + +namespace SlangRecord +{ + class RecordFileProcessor + { + public: + RecordFileProcessor(const std::string& filePath); + bool processNextBlock(); + bool processHeader(FunctionHeader& header); + bool processTailer(FunctionTailer& tailer); + bool processMethod(FunctionHeader const& header, const uint8_t* buffer, int64_t bufferSize); + bool processFunction(FunctionHeader const& header, const uint8_t* buffer, int64_t bufferSize); + private: + Slang::FileStream m_inputStream; + Slang::List<uint8_t> m_parameterBuffer; + Slang::List<uint8_t> m_outputBuffer; + + SlangDecoder m_decoder; + }; + +} // namespace SlangRecord; + +#endif // FILE_PROCESSOR_H diff --git a/source/slang-record-replay/replay/replay-consumer.cpp b/source/slang-record-replay/replay/replay-consumer.cpp new file mode 100644 index 000000000..51aa2d1b1 --- /dev/null +++ b/source/slang-record-replay/replay/replay-consumer.cpp @@ -0,0 +1,481 @@ +#include "replay-consumer.h" + +namespace SlangRecord +{ + void ReplayConsumer::CreateGlobalSession(ObjectID objectId, const uint8_t* parameterBuffer, int64_t bufferSize) + { + } + + void ReplayConsumer::IGlobalSession_createSession(ObjectID objectId, slang::SessionDesc const& desc, ObjectID outSessionId) + { + } + + + void ReplayConsumer::IGlobalSession_findProfile(ObjectID objectId, char const* name) + { + } + + + void ReplayConsumer::IGlobalSession_setDownstreamCompilerPath(ObjectID objectId, SlangPassThrough passThrough, char const* path) + { + } + + + void ReplayConsumer::IGlobalSession_setDownstreamCompilerPrelude(ObjectID objectId, SlangPassThrough inPassThrough, char const* prelude) + { + } + + + void ReplayConsumer::IGlobalSession_getDownstreamCompilerPrelude(ObjectID objectId, SlangPassThrough inPassThrough, ObjectID outPreludeId) + { + } + + + void ReplayConsumer::IGlobalSession_setDefaultDownstreamCompiler(ObjectID objectId, SlangSourceLanguage sourceLanguage, SlangPassThrough defaultCompiler) + { + } + + + void ReplayConsumer::IGlobalSession_getDefaultDownstreamCompiler(ObjectID objectId, SlangSourceLanguage sourceLanguage) + { + } + + + void ReplayConsumer::IGlobalSession_setLanguagePrelude(ObjectID objectId, SlangSourceLanguage inSourceLanguage, char const* prelude) + { + } + + + void ReplayConsumer::IGlobalSession_getLanguagePrelude(ObjectID objectId, SlangSourceLanguage inSourceLanguage, ObjectID outPreludeId) + { + } + + + void ReplayConsumer::IGlobalSession_createCompileRequest(ObjectID objectId, ObjectID outCompileRequest) + { + } + + + void ReplayConsumer::IGlobalSession_addBuiltins(ObjectID objectId, char const* sourcePath, char const* sourceString) + { + } + + + void ReplayConsumer::IGlobalSession_setSharedLibraryLoader(ObjectID objectId, ObjectID loaderId) + { + } + + + void ReplayConsumer::IGlobalSession_getSharedLibraryLoader(ObjectID objectId, ObjectID outLoaderId) + { + } + + + void ReplayConsumer::IGlobalSession_checkCompileTargetSupport(ObjectID objectId, SlangCompileTarget target) + { + } + + + void ReplayConsumer::IGlobalSession_checkPassThroughSupport(ObjectID objectId, SlangPassThrough passThrough) + { + } + + + void ReplayConsumer::IGlobalSession_compileStdLib(ObjectID objectId, slang::CompileStdLibFlags flags) + { + } + + + void ReplayConsumer::IGlobalSession_loadStdLib(ObjectID objectId, const void* stdLib, size_t stdLibSizeInBytes) + { + } + + + void ReplayConsumer::IGlobalSession_saveStdLib(ObjectID objectId, SlangArchiveType archiveType, ObjectID outBlobId) + { + } + + + void ReplayConsumer::IGlobalSession_findCapability(ObjectID objectId, char const* name) + { + } + + + void ReplayConsumer::IGlobalSession_setDownstreamCompilerForTransition(ObjectID objectId, SlangCompileTarget source, SlangCompileTarget target, SlangPassThrough compiler) + { + } + + + void ReplayConsumer::IGlobalSession_getDownstreamCompilerForTransition(ObjectID objectId, SlangCompileTarget source, SlangCompileTarget target) + { + } + + + void ReplayConsumer::IGlobalSession_setSPIRVCoreGrammar(ObjectID objectId, char const* jsonPath) + { + } + + + void ReplayConsumer::IGlobalSession_parseCommandLineArguments(ObjectID objectId, int argc, const char* const* argv, ObjectID outSessionDescId, ObjectID outAllocationId) + { + } + + + void ReplayConsumer::IGlobalSession_getSessionDescDigest(ObjectID objectId, slang::SessionDesc* sessionDesc, ObjectID outBlobId) + { + } + + + + // ISession + void ReplayConsumer::ISession_getGlobalSession(ObjectID objectId, ObjectID outGlobalSessionId) + { + } + + + void ReplayConsumer::ISession_loadModule(ObjectID objectId, const char* moduleName, ObjectID outDiagnostics, ObjectID outModuleId) + { + } + + + void ReplayConsumer::ISession_loadModuleFromIRBlob(ObjectID objectId, const char* moduleName, + const char* path, slang::IBlob* source, ObjectID outDiagnosticsId, ObjectID outModuleId) + { + } + + + void ReplayConsumer::ISession_loadModuleFromSource(ObjectID objectId, const char* moduleName, + const char* path, slang::IBlob* source, ObjectID outDiagnosticsId, ObjectID outModuleId) + { + } + + + void ReplayConsumer::ISession_loadModuleFromSourceString(ObjectID objectId, const char* moduleName, + const char* path, const char* string, ObjectID outDiagnosticsId, ObjectID outModuleId) + { + } + + + void ReplayConsumer::ISession_createCompositeComponentType(ObjectID objectId, ObjectID* componentTypeIds, + SlangInt componentTypeCount, ObjectID outCompositeComponentTypeId, ObjectID outDiagnosticsId) + { + } + + + void ReplayConsumer::ISession_specializeType(ObjectID objectId, ObjectID typeId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outDiagnosticsId, ObjectID outTypeReflectionId) + { + } + + + + void ReplayConsumer::ISession_getTypeLayout(ObjectID objectId, ObjectID typeId, SlangInt targetIndex, + slang::LayoutRules rules, ObjectID outDiagnosticsId, ObjectID outTypeLayoutReflection) + { + } + + void ReplayConsumer::ISession_getContainerType(ObjectID objectId, ObjectID elementType, + slang::ContainerType containerType, ObjectID outDiagnosticsId, ObjectID outTypeReflectionId) + { + } + + void ReplayConsumer::ISession_getDynamicType(ObjectID objectId, ObjectID outTypeReflectionId) + { + } + + void ReplayConsumer::ISession_getTypeRTTIMangledName(ObjectID objectId, ObjectID typeId, ObjectID outNameBlobId) + { + } + + void ReplayConsumer::ISession_getTypeConformanceWitnessMangledName(ObjectID objectId, ObjectID typeId, + ObjectID interfaceTypeId, ObjectID outNameBlobId) + { + } + + + void ReplayConsumer::ISession_getTypeConformanceWitnessSequentialID(ObjectID objectId, ObjectID typeId, + ObjectID interfaceTypeId, uint32_t outId) + { + } + + void ReplayConsumer::ISession_createTypeConformanceComponentType(ObjectID objectId, ObjectID typeId, + ObjectID interfaceTypeId, ObjectID outConformanceId, + SlangInt conformanceIdOverride, ObjectID outDiagnosticsId) + { + } + + + + void ReplayConsumer::ISession_createCompileRequest(ObjectID objectId, ObjectID outCompileRequestId) + { + } + + + void ReplayConsumer::ISession_getLoadedModule(ObjectID objectId, SlangInt index, ObjectID outModuleId) + { + } + + + + // IModule + void ReplayConsumer::IModule_findEntryPointByName(ObjectID objectId, char const* name, ObjectID outEntryPointId) + { + } + + + void ReplayConsumer::IModule_getDefinedEntryPoint(ObjectID objectId, SlangInt32 index, ObjectID outEntryPointId) + { + } + + + void ReplayConsumer::IModule_serialize(ObjectID objectId, ObjectID outSerializedBlobId) + { + } + + + void ReplayConsumer::IModule_writeToFile(ObjectID objectId, char const* fileName) + { + } + + + void ReplayConsumer::IModule_findAndCheckEntryPoint(ObjectID objectId, char const* name, SlangStage stage, ObjectID outEntryPointId, ObjectID outDiagnostics) + { + } + + + + void ReplayConsumer::IModule_getSession(ObjectID objectId, ObjectID outSessionId) + { + } + + + void ReplayConsumer::IModule_getLayout(ObjectID objectId, SlangInt targetIndex, ObjectID outDiagnosticsId, ObjectID retProgramLayoutId) + { + } + + + void ReplayConsumer::IModule_getEntryPointCode(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) + { + } + + + void ReplayConsumer::IModule_getTargetCode(ObjectID objectId, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) + { + } + + + void ReplayConsumer::IModule_getResultAsFileSystem(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outFileSystem) + { + } + + + void ReplayConsumer::IModule_getEntryPointHash(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outHashId) + { + } + + + void ReplayConsumer::IModule_specialize(ObjectID objectId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outSpecializedComponentTypeId, ObjectID outDiagnosticsId) + { + } + + + void ReplayConsumer::IModule_link(ObjectID objectId, ObjectID outLinkedComponentTypeId, ObjectID outDiagnosticsId) + { + } + + + void ReplayConsumer::IModule_getEntryPointHostCallable(ObjectID objectId, int entryPointIndex, int targetIndex, ObjectID outSharedLibrary, ObjectID outDiagnostics) + { + } + + + void ReplayConsumer::IModule_renameEntryPoint(ObjectID objectId, const char* newName, ObjectID outEntryPointId) + { + } + + + void ReplayConsumer::IModule_linkWithOptions(ObjectID objectId, ObjectID outLinkedComponentTypeId, + uint32_t compilerOptionEntryCount, slang::CompilerOptionEntry* compilerOptionEntries, ObjectID outDiagnosticsId) + { + } + + + + // IEntryPoint + void ReplayConsumer::IEntryPoint_getSession(ObjectID objectId, ObjectID outSessionId) + { + } + + + void ReplayConsumer::IEntryPoint_getLayout(ObjectID objectId, SlangInt targetIndex, ObjectID outDiagnosticsId, ObjectID retProgramLayoutId) + { + } + + + void ReplayConsumer::IEntryPoint_getEntryPointCode(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) + { + } + + + void ReplayConsumer::IEntryPoint_getTargetCode(ObjectID objectId, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) + { + } + + + void ReplayConsumer::IEntryPoint_getResultAsFileSystem(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outFileSystem) + { + } + + + void ReplayConsumer::IEntryPoint_getEntryPointHash(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outHashId) + { + } + + + void ReplayConsumer::IEntryPoint_specialize(ObjectID objectId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outSpecializedComponentTypeId, ObjectID outDiagnosticsId) + { + } + + + void ReplayConsumer::IEntryPoint_link(ObjectID objectId, ObjectID outLinkedComponentTypeId, ObjectID outDiagnosticsId) + { + } + + + void ReplayConsumer::IEntryPoint_getEntryPointHostCallable(ObjectID objectId, int entryPointIndex, int targetIndex, ObjectID outSharedLibrary, ObjectID outDiagnostics) + { + } + + + void ReplayConsumer::IEntryPoint_renameEntryPoint(ObjectID objectId, const char* newName, ObjectID outEntryPointId) + { + } + + + void ReplayConsumer::IEntryPoint_linkWithOptions(ObjectID objectId, ObjectID outLinkedComponentTypeId, + uint32_t compilerOptionEntryCount, slang::CompilerOptionEntry* compilerOptionEntries, ObjectID outDiagnosticsId) + { + } + + + + // ICompositeComponentType + void ReplayConsumer::ICompositeComponentType_getSession(ObjectID objectId, ObjectID outSessionId) + { + } + + + void ReplayConsumer::ICompositeComponentType_getLayout(ObjectID objectId, SlangInt targetIndex, ObjectID outDiagnosticsId, ObjectID retProgramLayoutId) + { + } + + + void ReplayConsumer::ICompositeComponentType_getEntryPointCode(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) + { + } + + + void ReplayConsumer::ICompositeComponentType_getTargetCode(ObjectID objectId, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) + { + } + + + void ReplayConsumer::ICompositeComponentType_getResultAsFileSystem(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outFileSystem) + { + } + + + void ReplayConsumer::ICompositeComponentType_getEntryPointHash(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outHashId) + { + } + + + void ReplayConsumer::ICompositeComponentType_specialize(ObjectID objectId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outSpecializedComponentTypeId, ObjectID outDiagnosticsId) + { + } + + + void ReplayConsumer::ICompositeComponentType_link(ObjectID objectId, ObjectID outLinkedComponentTypeId, ObjectID outDiagnosticsId) + { + } + + + void ReplayConsumer::ICompositeComponentType_getEntryPointHostCallable(ObjectID objectId, int entryPointIndex, int targetIndex, ObjectID outSharedLibrary, ObjectID outDiagnostics) + { + } + + + void ReplayConsumer::ICompositeComponentType_renameEntryPoint(ObjectID objectId, const char* newName, ObjectID outEntryPointId) + { + } + + + void ReplayConsumer::ICompositeComponentType_linkWithOptions(ObjectID objectId, ObjectID outLinkedComponentTypeId, + uint32_t compilerOptionEntryCount, slang::CompilerOptionEntry* compilerOptionEntries, ObjectID outDiagnosticsId) + { + } + + + + // ITypeConformance + void ReplayConsumer::ITypeConformance_getSession(ObjectID objectId, ObjectID outSessionId) + { + } + + + void ReplayConsumer::ITypeConformance_getLayout(ObjectID objectId, SlangInt targetIndex, ObjectID outDiagnosticsId, ObjectID retProgramLayoutId) + { + } + + + void ReplayConsumer::ITypeConformance_getEntryPointCode(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) + { + } + + + void ReplayConsumer::ITypeConformance_getTargetCode(ObjectID objectId, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) + { + } + + + void ReplayConsumer::ITypeConformance_getResultAsFileSystem(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outFileSystem) + { + } + + + void ReplayConsumer::ITypeConformance_getEntryPointHash(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outHashId) + { + } + + + void ReplayConsumer::ITypeConformance_specialize(ObjectID objectId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outSpecializedComponentTypeId, ObjectID outDiagnosticsId) + { + } + + + void ReplayConsumer::ITypeConformance_link(ObjectID objectId, ObjectID outLinkedComponentTypeId, ObjectID outDiagnosticsId) + { + } + + + void ReplayConsumer::ITypeConformance_getEntryPointHostCallable(ObjectID objectId, int entryPointIndex, int targetIndex, ObjectID outSharedLibrary, ObjectID outDiagnostics) + { + } + + + void ReplayConsumer::ITypeConformance_renameEntryPoint(ObjectID objectId, const char* newName, ObjectID outEntryPointId) + { + } + + + void ReplayConsumer::ITypeConformance_linkWithOptions(ObjectID objectId, ObjectID outLinkedComponentTypeId, + uint32_t compilerOptionEntryCount, slang::CompilerOptionEntry* compilerOptionEntries, ObjectID outDiagnosticsId) + { + } + + +}; // namespace SlangRecord diff --git a/source/slang-record-replay/replay/replay-consumer.h b/source/slang-record-replay/replay/replay-consumer.h new file mode 100644 index 000000000..6ac733f90 --- /dev/null +++ b/source/slang-record-replay/replay/replay-consumer.h @@ -0,0 +1,196 @@ +#ifndef REPLAY_CONSUMER_H +#define REPLAY_CONSUMER_H + +#include <unordered_map> +#include "../util/record-format.h" +#include "decoder-consumer.h" + +namespace SlangRecord +{ + class ReplayConsumer : public IDecoderConsumer + { + public: + virtual void CreateGlobalSession(ObjectID objectId, const uint8_t* parameterBuffer, int64_t bufferSize) = 0; + virtual void IGlobalSession_createSession(ObjectID objectId, slang::SessionDesc const& desc, ObjectID outSessionId) = 0; + virtual void IGlobalSession_findProfile(ObjectID objectId, char const* name) = 0; + virtual void IGlobalSession_setDownstreamCompilerPath(ObjectID objectId, SlangPassThrough passThrough, char const* path) = 0; + virtual void IGlobalSession_setDownstreamCompilerPrelude(ObjectID objectId, SlangPassThrough inPassThrough, char const* prelude) = 0; + virtual void IGlobalSession_getDownstreamCompilerPrelude(ObjectID objectId, SlangPassThrough inPassThrough, ObjectID outPreludeId) = 0; + + virtual void IGlobalSession_getBuildTagString(ObjectID objectId) { (void) objectId; } + + virtual void IGlobalSession_setDefaultDownstreamCompiler(ObjectID objectId, SlangSourceLanguage sourceLanguage, SlangPassThrough defaultCompiler) = 0; + virtual void IGlobalSession_getDefaultDownstreamCompiler(ObjectID objectId, SlangSourceLanguage sourceLanguage) = 0; + virtual void IGlobalSession_setLanguagePrelude(ObjectID objectId, SlangSourceLanguage inSourceLanguage, char const* prelude) = 0; + virtual void IGlobalSession_getLanguagePrelude(ObjectID objectId, SlangSourceLanguage inSourceLanguage, ObjectID outPreludeId) = 0; + virtual void IGlobalSession_createCompileRequest(ObjectID objectId, ObjectID outCompileRequest) = 0; + virtual void IGlobalSession_addBuiltins(ObjectID objectId, char const* sourcePath, char const* sourceString) = 0; + virtual void IGlobalSession_setSharedLibraryLoader(ObjectID objectId, ObjectID loaderId) = 0; + virtual void IGlobalSession_getSharedLibraryLoader(ObjectID objectId, ObjectID outLoaderId) = 0; + virtual void IGlobalSession_checkCompileTargetSupport(ObjectID objectId, SlangCompileTarget target) = 0; + virtual void IGlobalSession_checkPassThroughSupport(ObjectID objectId, SlangPassThrough passThrough) = 0; + virtual void IGlobalSession_compileStdLib(ObjectID objectId, slang::CompileStdLibFlags flags) = 0; + virtual void IGlobalSession_loadStdLib(ObjectID objectId, const void* stdLib, size_t stdLibSizeInBytes) = 0; + virtual void IGlobalSession_saveStdLib(ObjectID objectId, SlangArchiveType archiveType, ObjectID outBlobId) = 0; + virtual void IGlobalSession_findCapability(ObjectID objectId, char const* name) = 0; + virtual void IGlobalSession_setDownstreamCompilerForTransition(ObjectID objectId, SlangCompileTarget source, SlangCompileTarget target, SlangPassThrough compiler) = 0; + virtual void IGlobalSession_getDownstreamCompilerForTransition(ObjectID objectId, SlangCompileTarget source, SlangCompileTarget target) = 0; + + virtual void IGlobalSession_getCompilerElapsedTime(ObjectID objectId) { (void) objectId; } + + virtual void IGlobalSession_setSPIRVCoreGrammar(ObjectID objectId, char const* jsonPath) = 0; + virtual void IGlobalSession_parseCommandLineArguments(ObjectID objectId, int argc, const char* const* argv, ObjectID outSessionDescId, ObjectID outAllocationId) = 0; + virtual void IGlobalSession_getSessionDescDigest(ObjectID objectId, slang::SessionDesc* sessionDesc, ObjectID outBlobId) = 0; + + // ISession + virtual void ISession_getGlobalSession(ObjectID objectId, ObjectID outGlobalSessionId) = 0; + virtual void ISession_loadModule(ObjectID objectId, const char* moduleName, ObjectID outDiagnostics, ObjectID outModuleId) = 0; + + virtual void ISession_loadModuleFromIRBlob(ObjectID objectId, const char* moduleName, + const char* path, slang::IBlob* source, ObjectID outDiagnosticsId, ObjectID outModuleId) = 0; + virtual void ISession_loadModuleFromSource(ObjectID objectId, const char* moduleName, + const char* path, slang::IBlob* source, ObjectID outDiagnosticsId, ObjectID outModuleId) = 0; + virtual void ISession_loadModuleFromSourceString(ObjectID objectId, const char* moduleName, + const char* path, const char* string, ObjectID outDiagnosticsId, ObjectID outModuleId) = 0; + virtual void ISession_createCompositeComponentType(ObjectID objectId, ObjectID* componentTypeIds, + SlangInt componentTypeCount, ObjectID outCompositeComponentTypeIds, ObjectID outDiagnosticsId) = 0; + + virtual void ISession_specializeType(ObjectID objectId, ObjectID typeId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outDiagnosticsId, ObjectID outTypeReflectionId) = 0; + + virtual void ISession_getTypeLayout(ObjectID objectId, ObjectID typeId, SlangInt targetIndex, + slang::LayoutRules rules, ObjectID outDiagnosticsId, ObjectID outTypeLayoutReflection) = 0; + + virtual void ISession_getContainerType(ObjectID objectId, ObjectID elementType, + slang::ContainerType containerType, ObjectID outDiagnosticsId, ObjectID outTypeReflectionId) = 0; + + virtual void ISession_getDynamicType(ObjectID objectId, ObjectID outTypeReflectionId) = 0; + + virtual void ISession_getTypeRTTIMangledName(ObjectID objectId, ObjectID typeId, ObjectID outNameBlobId) = 0; + + virtual void ISession_getTypeConformanceWitnessMangledName(ObjectID objectId, ObjectID typeId, + ObjectID interfaceTypeId, ObjectID outNameBlobId) = 0; + + virtual void ISession_getTypeConformanceWitnessSequentialID(ObjectID objectId, ObjectID typeId, + ObjectID interfaceTypeId, uint32_t outId) = 0; + + virtual void ISession_createTypeConformanceComponentType(ObjectID objectId, ObjectID typeId, + ObjectID interfaceTypeId, ObjectID outConformanceId, + SlangInt conformanceIdOverride, ObjectID outDiagnosticsId) = 0; + + virtual void ISession_createCompileRequest(ObjectID objectId, ObjectID outCompileRequestId) = 0; + + virtual void ISession_getLoadedModuleCount(ObjectID objectId) { (void) objectId; } + + virtual void ISession_getLoadedModule(ObjectID objectId, SlangInt index, ObjectID outModuleId) = 0; + + virtual void ISession_isBinaryModuleUpToDate(ObjectID objectId) { (void) objectId; } + + // IModule + virtual void IModule_findEntryPointByName(ObjectID objectId, char const* name, ObjectID outEntryPointId) = 0; + + virtual void IModule_getDefinedEntryPointCount(ObjectID objectId) { (void) objectId; } + + virtual void IModule_getDefinedEntryPoint(ObjectID objectId, SlangInt32 index, ObjectID outEntryPointId) = 0; + virtual void IModule_serialize(ObjectID objectId, ObjectID outSerializedBlobId) = 0; + virtual void IModule_writeToFile(ObjectID objectId, char const* fileName) = 0; + + virtual void IModule_getName(ObjectID objectId) { (void) objectId; } + virtual void IModule_getFilePath(ObjectID objectId) { (void) objectId; } + virtual void IModule_getUniqueIdentity(ObjectID objectId) { (void) objectId; } + + virtual void IModule_findAndCheckEntryPoint(ObjectID objectId, char const* name, SlangStage stage, ObjectID outEntryPointId, ObjectID outDiagnostics) = 0; + + virtual void IModule_getSession(ObjectID objectId, ObjectID outSessionId) = 0; + virtual void IModule_getLayout(ObjectID objectId, SlangInt targetIndex, ObjectID outDiagnosticsId, ObjectID retProgramLayoutId) = 0; + + virtual void IModule_getSpecializationParamCount(ObjectID objectId) { (void) objectId; } + + virtual void IModule_getEntryPointCode(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void IModule_getTargetCode(ObjectID objectId, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void IModule_getResultAsFileSystem(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outFileSystem) = 0; + virtual void IModule_getEntryPointHash(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outHashId) = 0; + virtual void IModule_specialize(ObjectID objectId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outSpecializedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void IModule_link(ObjectID objectId, ObjectID outLinkedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void IModule_getEntryPointHostCallable(ObjectID objectId, int entryPointIndex, int targetIndex, ObjectID outSharedLibrary, ObjectID outDiagnostics) = 0; + virtual void IModule_renameEntryPoint(ObjectID objectId, const char* newName, ObjectID outEntryPointId) = 0; + virtual void IModule_linkWithOptions(ObjectID objectId, ObjectID outLinkedComponentTypeId, + uint32_t compilerOptionEntryCount, slang::CompilerOptionEntry* compilerOptionEntries, ObjectID outDiagnosticsId) = 0; + + // IEntryPoint + virtual void IEntryPoint_getSession(ObjectID objectId, ObjectID outSessionId) = 0; + virtual void IEntryPoint_getLayout(ObjectID objectId, SlangInt targetIndex, ObjectID outDiagnosticsId, ObjectID retProgramLayoutId) = 0; + + virtual void IEntryPoint_getSpecializationParamCount(ObjectID objectId) { (void) objectId; }; + + virtual void IEntryPoint_getEntryPointCode(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void IEntryPoint_getTargetCode(ObjectID objectId, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void IEntryPoint_getResultAsFileSystem(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outFileSystem) = 0; + virtual void IEntryPoint_getEntryPointHash(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outHashId) = 0; + virtual void IEntryPoint_specialize(ObjectID objectId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outSpecializedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void IEntryPoint_link(ObjectID objectId, ObjectID outLinkedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void IEntryPoint_getEntryPointHostCallable(ObjectID objectId, int entryPointIndex, int targetIndex, ObjectID outSharedLibrary, ObjectID outDiagnostics) = 0; + virtual void IEntryPoint_renameEntryPoint(ObjectID objectId, const char* newName, ObjectID outEntryPointId) = 0; + virtual void IEntryPoint_linkWithOptions(ObjectID objectId, ObjectID outLinkedComponentTypeId, + uint32_t compilerOptionEntryCount, slang::CompilerOptionEntry* compilerOptionEntries, ObjectID outDiagnosticsId) = 0; + + // ICompositeComponentType + virtual void ICompositeComponentType_getSession(ObjectID objectId, ObjectID outSessionId) = 0; + virtual void ICompositeComponentType_getLayout(ObjectID objectId, SlangInt targetIndex, ObjectID outDiagnosticsId, ObjectID retProgramLayoutId) = 0; + + virtual void ICompositeComponentType_getSpecializationParamCount(ObjectID objectId) { (void) objectId; }; + + virtual void ICompositeComponentType_getEntryPointCode(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void ICompositeComponentType_getTargetCode(ObjectID objectId, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void ICompositeComponentType_getResultAsFileSystem(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outFileSystem) = 0; + virtual void ICompositeComponentType_getEntryPointHash(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outHashId) = 0; + virtual void ICompositeComponentType_specialize(ObjectID objectId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outSpecializedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void ICompositeComponentType_link(ObjectID objectId, ObjectID outLinkedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void ICompositeComponentType_getEntryPointHostCallable(ObjectID objectId, int entryPointIndex, int targetIndex, ObjectID outSharedLibrary, ObjectID outDiagnostics) = 0; + virtual void ICompositeComponentType_renameEntryPoint(ObjectID objectId, const char* newName, ObjectID outEntryPointId) = 0; + virtual void ICompositeComponentType_linkWithOptions(ObjectID objectId, ObjectID outLinkedComponentTypeId, + uint32_t compilerOptionEntryCount, slang::CompilerOptionEntry* compilerOptionEntries, ObjectID outDiagnosticsId) = 0; + + // ITypeConformance + virtual void ITypeConformance_getSession(ObjectID objectId, ObjectID outSessionId) = 0; + virtual void ITypeConformance_getLayout(ObjectID objectId, SlangInt targetIndex, ObjectID outDiagnosticsId, ObjectID retProgramLayoutId) = 0; + + virtual void ITypeConformance_getSpecializationParamCount(ObjectID objectId) { (void) objectId; }; + + virtual void ITypeConformance_getEntryPointCode(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void ITypeConformance_getTargetCode(ObjectID objectId, SlangInt targetIndex, ObjectID outCode, ObjectID outDiagnostics) = 0; + virtual void ITypeConformance_getResultAsFileSystem(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outFileSystem) = 0; + virtual void ITypeConformance_getEntryPointHash(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outHashId) = 0; + virtual void ITypeConformance_specialize(ObjectID objectId, slang::SpecializationArg const* specializationArgs, + SlangInt specializationArgCount, ObjectID outSpecializedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void ITypeConformance_link(ObjectID objectId, ObjectID outLinkedComponentTypeId, ObjectID outDiagnosticsId) = 0; + virtual void ITypeConformance_getEntryPointHostCallable(ObjectID objectId, int entryPointIndex, int targetIndex, ObjectID outSharedLibrary, ObjectID outDiagnostics) = 0; + virtual void ITypeConformance_renameEntryPoint(ObjectID objectId, const char* newName, ObjectID outEntryPointId) = 0; + virtual void ITypeConformance_linkWithOptions(ObjectID objectId, ObjectID outLinkedComponentTypeId, + uint32_t compilerOptionEntryCount, slang::CompilerOptionEntry* compilerOptionEntries, ObjectID outDiagnosticsId) = 0; + private: + // Map of the address of the object allocated by slang during record to + // the address of the object allocated by the replay. + // We need to have this map because we never save the content of the object + // allocated by slang, because those are just opaque objects or handles, we + // only need to provide them to the corresponding replay function or call the + // methods on the correct object. + std::unordered_map<ObjectID, void*> m_objectMap; + + inline void* getObjectPointer(ObjectID objectId) + { + if (m_objectMap.find(objectId) == m_objectMap.end()) + { + return nullptr; + } + else + { + return m_objectMap[objectId]; + } + } + }; +} +#endif // REPLAY_CONSUMER_H diff --git a/source/slang-record-replay/replay/slang-decoder.cpp b/source/slang-record-replay/replay/slang-decoder.cpp new file mode 100644 index 000000000..561a2c9e3 --- /dev/null +++ b/source/slang-record-replay/replay/slang-decoder.cpp @@ -0,0 +1,1974 @@ +#include "slang-decoder.h" +#include "parameter-decoder.h" +#include "decoder-helper.h" +#include "../util/record-utility.h" + +namespace SlangRecord +{ + + bool SlangDecoder::processMethodCall(FunctionHeader const& header, ParameterBlock const& parameterBlock) + { + ApiClassId classId = static_cast<ApiClassId>(getClassId(header.callId)); + ObjectID objectId = header.handleId; + switch(classId) + { + default: + slangRecordLog(LogLevel::Error, "Unhandled Slang Class Id: %d\n", classId); + return false; + case ApiClassId::Class_IGlobalSession: + return processIGlobalSessionMethods(header.callId, objectId, parameterBlock); + break; + case ApiClassId::Class_ISession: + return processISessionMethods(header.callId, objectId, parameterBlock); + break; + case ApiClassId::Class_IModule: + return processIModuleMethods(header.callId, objectId, parameterBlock); + break; + case ApiClassId::Class_IEntryPoint: + return processIEntryPointMethods(header.callId, objectId, parameterBlock); + break; + case ApiClassId::Class_ICompositeComponentType: + return processICompositeComponentTypeMethods(header.callId, objectId, parameterBlock); + break; + case ApiClassId::Class_ITypeConformance: + return processITypeConformanceMethods(header.callId, objectId, parameterBlock); + break; + } + } + + bool SlangDecoder::processIGlobalSessionMethods(ApiCallId callId, ObjectID objectId, ParameterBlock const& parameterBlock) + { + switch(callId) + { + default: + slangRecordLog(LogLevel::Error, "Unhandled Slang API call: %d\n", callId); + break; + case ApiCallId::CreateGlobalSession: + CreateGlobalSession(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_createSession: + IGlobalSession_createSession(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_findProfile: + IGlobalSession_findProfile(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_setDownstreamCompilerPath: + IGlobalSession_setDownstreamCompilerPath(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_setDownstreamCompilerPrelude: + IGlobalSession_setDownstreamCompilerPrelude(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_getDownstreamCompilerPrelude: + IGlobalSession_getDownstreamCompilerPrelude(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_getBuildTagString: + IGlobalSession_getBuildTagString(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_setDefaultDownstreamCompiler: + IGlobalSession_setDefaultDownstreamCompiler(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_getDefaultDownstreamCompiler: + IGlobalSession_getDefaultDownstreamCompiler(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_setLanguagePrelude: + IGlobalSession_setLanguagePrelude(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_getLanguagePrelude: + IGlobalSession_getLanguagePrelude(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_createCompileRequest: + IGlobalSession_createCompileRequest(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_addBuiltins: + IGlobalSession_addBuiltins(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_setSharedLibraryLoader: + IGlobalSession_setSharedLibraryLoader(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_getSharedLibraryLoader: + IGlobalSession_getSharedLibraryLoader(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_checkCompileTargetSupport: + IGlobalSession_checkCompileTargetSupport(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_checkPassThroughSupport: + IGlobalSession_checkPassThroughSupport(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_compileStdLib: + IGlobalSession_compileStdLib(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_loadStdLib: + IGlobalSession_loadStdLib(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_saveStdLib: + IGlobalSession_saveStdLib(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_findCapability: + IGlobalSession_findCapability(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_setDownstreamCompilerForTransition: + IGlobalSession_setDownstreamCompilerForTransition(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_getDownstreamCompilerForTransition: + IGlobalSession_getDownstreamCompilerForTransition(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_getCompilerElapsedTime: + IGlobalSession_getCompilerElapsedTime(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_setSPIRVCoreGrammar: + IGlobalSession_setSPIRVCoreGrammar(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_parseCommandLineArguments: + IGlobalSession_parseCommandLineArguments(objectId, parameterBlock); + break; + case ApiCallId::IGlobalSession_getSessionDescDigest: + IGlobalSession_getSessionDescDigest(objectId, parameterBlock); + break; + } + return true; + } + + + bool SlangDecoder::processISessionMethods(ApiCallId callId, ObjectID objectId, ParameterBlock const& parameterBlock) + { + switch(callId) + { + default: + slangRecordLog(LogLevel::Error, "Unhandled Slang API call: %d\n", callId); + return false; + case ApiCallId::ISession_getGlobalSession: + ISession_getGlobalSession(objectId, parameterBlock); + break; + case ApiCallId::ISession_loadModule: + ISession_loadModule(objectId, parameterBlock); + break; + case ApiCallId::ISession_loadModuleFromIRBlob: + ISession_loadModuleFromIRBlob(objectId, parameterBlock); + break; + case ApiCallId::ISession_loadModuleFromSource: + ISession_loadModuleFromSource(objectId, parameterBlock); + break; + case ApiCallId::ISession_loadModuleFromSourceString: + ISession_loadModuleFromSourceString(objectId, parameterBlock); + break; + case ApiCallId::ISession_createCompositeComponentType: + ISession_createCompositeComponentType(objectId, parameterBlock); + break; + case ApiCallId::ISession_specializeType: + ISession_specializeType(objectId, parameterBlock); + break; + case ApiCallId::ISession_getTypeLayout: + ISession_getTypeLayout(objectId, parameterBlock); + break; + case ApiCallId::ISession_getContainerType: + ISession_getContainerType(objectId, parameterBlock); + break; + case ApiCallId::ISession_getDynamicType: + ISession_getDynamicType(objectId, parameterBlock); + break; + case ApiCallId::ISession_getTypeRTTIMangledName: + ISession_getTypeRTTIMangledName(objectId, parameterBlock); + break; + case ApiCallId::ISession_getTypeConformanceWitnessMangledName: + ISession_getTypeConformanceWitnessMangledName(objectId, parameterBlock); + break; + case ApiCallId::ISession_getTypeConformanceWitnessSequentialID: + ISession_getTypeConformanceWitnessSequentialID(objectId, parameterBlock); + break; + case ApiCallId::ISession_createTypeConformanceComponentType: + ISession_createTypeConformanceComponentType(objectId, parameterBlock); + break; + case ApiCallId::ISession_createCompileRequest: + ISession_createCompileRequest(objectId, parameterBlock); + break; + case ApiCallId::ISession_getLoadedModuleCount: + ISession_getLoadedModuleCount(objectId, parameterBlock); + break; + case ApiCallId::ISession_getLoadedModule: + ISession_getLoadedModule(objectId, parameterBlock); + break; + case ApiCallId::ISession_isBinaryModuleUpToDate: + ISession_isBinaryModuleUpToDate(objectId, parameterBlock); + break; + } + return true; + } + + bool SlangDecoder::processIModuleMethods(ApiCallId callId, ObjectID objectId, ParameterBlock const& parameterBlock) + { + switch(callId) + { + default: + slangRecordLog(LogLevel::Error, "Unhandled Slang API call: %d\n", callId); + return false; + case ApiCallId::IModule_findEntryPointByName: + IModule_findEntryPointByName(objectId, parameterBlock); + break; + case ApiCallId::IModule_getDefinedEntryPointCount: + IModule_getDefinedEntryPointCount(objectId, parameterBlock); + break; + case ApiCallId::IModule_getDefinedEntryPoint: + IModule_getDefinedEntryPoint(objectId, parameterBlock); + break; + case ApiCallId::IModule_serialize: + IModule_serialize(objectId, parameterBlock); + break; + case ApiCallId::IModule_writeToFile: + IModule_writeToFile(objectId, parameterBlock); + break; + case ApiCallId::IModule_getName: + IModule_getName(objectId, parameterBlock); + break; + case ApiCallId::IModule_getFilePath: + IModule_getFilePath(objectId, parameterBlock); + break; + case ApiCallId::IModule_getUniqueIdentity: + IModule_getUniqueIdentity(objectId, parameterBlock); + break; + case ApiCallId::IModule_findAndCheckEntryPoint: + IModule_findAndCheckEntryPoint(objectId, parameterBlock); + break; + case ApiCallId::IModule_getSession: + IModule_getSession(objectId, parameterBlock); + break; + case ApiCallId::IModule_getLayout: + IModule_getLayout(objectId, parameterBlock); + break; + case ApiCallId::IModule_getSpecializationParamCount: + IModule_getSpecializationParamCount(objectId, parameterBlock); + break; + case ApiCallId::IModule_getEntryPointCode: + IModule_getEntryPointCode(objectId, parameterBlock); + break; + case ApiCallId::IModule_getTargetCode: + IModule_getTargetCode(objectId, parameterBlock); + break; + case ApiCallId::IModule_getResultAsFileSystem: + IModule_getResultAsFileSystem(objectId, parameterBlock); + break; + case ApiCallId::IModule_getEntryPointHash: + IModule_getEntryPointHash(objectId, parameterBlock); + break; + case ApiCallId::IModule_specialize: + IModule_specialize(objectId, parameterBlock); + break; + case ApiCallId::IModule_link: + IModule_link(objectId, parameterBlock); + break; + case ApiCallId::IModule_getEntryPointHostCallable: + IModule_getEntryPointHostCallable(objectId, parameterBlock); + break; + case ApiCallId::IModule_renameEntryPoint: + IModule_renameEntryPoint(objectId, parameterBlock); + break; + case ApiCallId::IModule_linkWithOptions: + IModule_linkWithOptions(objectId, parameterBlock); + break; + } + return true; + } + + bool SlangDecoder::processIEntryPointMethods(ApiCallId callId, ObjectID objectId, ParameterBlock const& parameterBlock) + { + switch(callId) + { + default: + slangRecordLog(LogLevel::Error, "Unhandled Slang API call: %d\n", callId); + return false; + case ApiCallId::IEntryPoint_getSession: + IEntryPoint_getSession(objectId, parameterBlock); + break; + case ApiCallId::IEntryPoint_getLayout: + IEntryPoint_getLayout(objectId, parameterBlock); + break; + case ApiCallId::IEntryPoint_getSpecializationParamCount: + IEntryPoint_getSpecializationParamCount(objectId, parameterBlock); + break; + case ApiCallId::IEntryPoint_getEntryPointCode: + IEntryPoint_getEntryPointCode(objectId, parameterBlock); + break; + case ApiCallId::IEntryPoint_getTargetCode: + IEntryPoint_getTargetCode(objectId, parameterBlock); + break; + case ApiCallId::IEntryPoint_getResultAsFileSystem: + IEntryPoint_getResultAsFileSystem(objectId, parameterBlock); + break; + case ApiCallId::IEntryPoint_getEntryPointHash: + IEntryPoint_getEntryPointHash(objectId, parameterBlock); + break; + case ApiCallId::IEntryPoint_specialize: + IEntryPoint_specialize(objectId, parameterBlock); + break; + case ApiCallId::IEntryPoint_link: + IEntryPoint_link(objectId, parameterBlock); + break; + case ApiCallId::IEntryPoint_getEntryPointHostCallable: + IEntryPoint_getEntryPointHostCallable(objectId, parameterBlock); + break; + case ApiCallId::IEntryPoint_renameEntryPoint: + IEntryPoint_renameEntryPoint(objectId, parameterBlock); + break; + case ApiCallId::IEntryPoint_linkWithOptions: + IEntryPoint_linkWithOptions(objectId, parameterBlock); + break; + } + return true; + } + + bool SlangDecoder::processICompositeComponentTypeMethods(ApiCallId callId, ObjectID objectId, ParameterBlock const& parameterBlock) + { + switch(callId) + { + default: + slangRecordLog(LogLevel::Error, "Unhandled Slang API call: %d\n", callId); + break; + case ApiCallId::ICompositeComponentType_getSession: + ICompositeComponentType_getSession(objectId, parameterBlock); + break; + case ApiCallId::ICompositeComponentType_getLayout: + ICompositeComponentType_getLayout(objectId, parameterBlock); + break; + case ApiCallId::ICompositeComponentType_getSpecializationParamCount: + ICompositeComponentType_getSpecializationParamCount(objectId, parameterBlock); + break; + case ApiCallId::ICompositeComponentType_getEntryPointCode: + ICompositeComponentType_getEntryPointCode(objectId, parameterBlock); + break; + case ApiCallId::ICompositeComponentType_getTargetCode: + ICompositeComponentType_getTargetCode(objectId, parameterBlock); + break; + case ApiCallId::ICompositeComponentType_getResultAsFileSystem: + ICompositeComponentType_getResultAsFileSystem(objectId, parameterBlock); + break; + case ApiCallId::ICompositeComponentType_getEntryPointHash: + ICompositeComponentType_getEntryPointHash(objectId, parameterBlock); + break; + case ApiCallId::ICompositeComponentType_specialize: + ICompositeComponentType_specialize(objectId, parameterBlock); + break; + case ApiCallId::ICompositeComponentType_link: + ICompositeComponentType_link(objectId, parameterBlock); + break; + case ApiCallId::ICompositeComponentType_getEntryPointHostCallable: + ICompositeComponentType_getEntryPointHostCallable(objectId, parameterBlock); + break; + case ApiCallId::ICompositeComponentType_renameEntryPoint: + ICompositeComponentType_renameEntryPoint(objectId, parameterBlock); + break; + case ApiCallId::ICompositeComponentType_linkWithOptions: + ICompositeComponentType_linkWithOptions(objectId, parameterBlock); + break; + } + return true; + } + + bool SlangDecoder::processITypeConformanceMethods(ApiCallId callId, ObjectID objectId, ParameterBlock const& parameterBlock) + { + switch(callId) + { + default: + slangRecordLog(LogLevel::Error, "Unhandled Slang API call: %d\n", callId); + return false; + case ApiCallId::ITypeConformance_getSession: + ITypeConformance_getSession(objectId, parameterBlock); + break; + case ApiCallId::ITypeConformance_getLayout: + ITypeConformance_getLayout(objectId, parameterBlock); + break; + case ApiCallId::ITypeConformance_getSpecializationParamCount: + ITypeConformance_getSpecializationParamCount(objectId, parameterBlock); + break; + case ApiCallId::ITypeConformance_getEntryPointCode: + ITypeConformance_getEntryPointCode(objectId, parameterBlock); + break; + case ApiCallId::ITypeConformance_getTargetCode: + ITypeConformance_getTargetCode(objectId, parameterBlock); + break; + case ApiCallId::ITypeConformance_getResultAsFileSystem: + ITypeConformance_getResultAsFileSystem(objectId, parameterBlock); + break; + case ApiCallId::ITypeConformance_getEntryPointHash: + ITypeConformance_getEntryPointHash(objectId, parameterBlock); + break; + case ApiCallId::ITypeConformance_specialize: + ITypeConformance_specialize(objectId, parameterBlock); + break; + case ApiCallId::ITypeConformance_link: + ITypeConformance_link(objectId, parameterBlock); + break; + case ApiCallId::ITypeConformance_getEntryPointHostCallable: + ITypeConformance_getEntryPointHostCallable(objectId, parameterBlock); + break; + case ApiCallId::ITypeConformance_renameEntryPoint: + ITypeConformance_renameEntryPoint(objectId, parameterBlock); + break; + case ApiCallId::ITypeConformance_linkWithOptions: + ITypeConformance_linkWithOptions(objectId, parameterBlock); + break; + } + return true; + } + + bool SlangDecoder::processFunctionCall(FunctionHeader const& header, ParameterBlock const& parameterBlock) + { + return false; + } + + + bool SlangDecoder::CreateGlobalSession(ObjectID objectId, ParameterBlock const& parameterBlock) + { + return false; + } + + bool SlangDecoder::IGlobalSession_createSession(ObjectID objectId, ParameterBlock const& parameterBlock) + { + StructDecoder<slang::SessionDesc> sessionDesc; + sessionDesc.decode(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize); + + ObjectID outSessionId = 0; + ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outSessionId); + + for (auto consumer: m_consumers) + { + consumer->IGlobalSession_createSession(objectId, sessionDesc.getValue(), outSessionId); + } + + return true; + } + + void SlangDecoder::IGlobalSession_findProfile(ObjectID objectId, ParameterBlock const& parameterBlock) + { + StringDecoder name; + ParameterDecoder::decodeString(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, name); + + for (auto consumer: m_consumers) + { + consumer->IGlobalSession_findProfile(objectId, name.getPointer()); + } + } + + void SlangDecoder::IGlobalSession_setDownstreamCompilerPath(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + SlangPassThrough passThrough {}; + readByte = ParameterDecoder::decodeEnumValue(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, passThrough); + StringDecoder path; + readByte += ParameterDecoder::decodeString(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, path); + + for (auto consumer: m_consumers) + { + consumer->IGlobalSession_setDownstreamCompilerPath(objectId, passThrough, path.getPointer()); + } + } + + void SlangDecoder::IGlobalSession_setDownstreamCompilerPrelude(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + SlangPassThrough passThrough {}; + readByte = ParameterDecoder::decodeEnumValue(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, passThrough); + StringDecoder prelude; + readByte += ParameterDecoder::decodeString(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, prelude); + + for (auto consumer: m_consumers) + { + consumer->IGlobalSession_setDownstreamCompilerPrelude(objectId, passThrough, prelude.getPointer()); + } + } + + void SlangDecoder::IGlobalSession_getDownstreamCompilerPrelude(ObjectID objectId, ParameterBlock const& parameterBlock) + { + SlangPassThrough passThrough {}; + ParameterDecoder::decodeEnumValue(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, passThrough); + + ObjectID outPreludeId = 0; + ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outPreludeId); + + for (auto consumer: m_consumers) + { + consumer->IGlobalSession_getDownstreamCompilerPrelude(objectId, passThrough, outPreludeId); + } + } + + void SlangDecoder::IGlobalSession_getBuildTagString(ObjectID objectId, ParameterBlock const& parameterBlock) + { + (void)objectId; + (void)parameterBlock; + slangRecordLog(LogLevel::Debug, "%s should not be called, it'a not recordd\n", __PRETTY_FUNCTION__); + } + + void SlangDecoder::IGlobalSession_setDefaultDownstreamCompiler(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + SlangSourceLanguage sourceLanguage {}; + SlangPassThrough defaultCompiler {}; + readByte = ParameterDecoder::decodeEnumValue(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, sourceLanguage); + readByte += ParameterDecoder::decodeEnumValue(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, defaultCompiler); + + for (auto consumer: m_consumers) + { + consumer->IGlobalSession_setDefaultDownstreamCompiler(objectId, sourceLanguage, defaultCompiler); + } + } + + void SlangDecoder::IGlobalSession_getDefaultDownstreamCompiler(ObjectID objectId, ParameterBlock const& parameterBlock) + { + SlangSourceLanguage sourceLanguage {}; + ParameterDecoder::decodeEnumValue(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, sourceLanguage); + + for (auto consumer: m_consumers) + { + consumer->IGlobalSession_getDefaultDownstreamCompiler(objectId, sourceLanguage); + } + } + + void SlangDecoder::IGlobalSession_setLanguagePrelude(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + SlangSourceLanguage sourceLanguage {}; + StringDecoder prelude; + readByte = ParameterDecoder::decodeEnumValue(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, sourceLanguage); + readByte += ParameterDecoder::decodeString(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, prelude); + + for (auto consumer: m_consumers) + { + consumer->IGlobalSession_setLanguagePrelude(objectId, sourceLanguage, prelude.getPointer()); + } + } + + void SlangDecoder::IGlobalSession_getLanguagePrelude(ObjectID objectId, ParameterBlock const& parameterBlock) + { + SlangSourceLanguage sourceLanguage {}; + ObjectID outPreludeId = 0; + ParameterDecoder::decodeEnumValue(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, sourceLanguage); + ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outPreludeId); + + for (auto consumer: m_consumers) + { + consumer->IGlobalSession_getLanguagePrelude(objectId, sourceLanguage, outPreludeId); + } + } + + void SlangDecoder::IGlobalSession_createCompileRequest(ObjectID objectId, ParameterBlock const& parameterBlock) + { + ObjectID outCompileRequestId = 0; + ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outCompileRequestId); + + for (auto consumer: m_consumers) + { + consumer->IGlobalSession_createCompileRequest(objectId, outCompileRequestId); + } + } + + void SlangDecoder::IGlobalSession_addBuiltins(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readBytes = 0; + StringDecoder sourcePath; + StringDecoder sourceString; + readBytes = ParameterDecoder::decodeString(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, sourcePath); + readBytes += ParameterDecoder::decodeString(parameterBlock.parameterBuffer + readBytes, parameterBlock.parameterBufferSize - readBytes, sourceString); + + for (auto consumer: m_consumers) + { + consumer->IGlobalSession_addBuiltins(objectId, sourcePath.getPointer(), sourceString.getPointer()); + } + } + + void SlangDecoder::IGlobalSession_setSharedLibraryLoader(ObjectID objectId, ParameterBlock const& parameterBlock) + { + // TODO: Not sure if we need to record this function. Because this functions is something like the file system + // override, it's provided by user code. So capturing it makes no sense. The only way is to wrapper this interface + // by our own implementation, and record it there. + slangRecordLog(LogLevel::Error, "%s should not be called\n", __PRETTY_FUNCTION__); + } + + void SlangDecoder::IGlobalSession_getSharedLibraryLoader(ObjectID objectId, ParameterBlock const& parameterBlock) + { + ObjectID outLoaderId = 0; + ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outLoaderId); + + for (auto consumer: m_consumers) + { + consumer->IGlobalSession_getSharedLibraryLoader(objectId, outLoaderId); + } + } + + void SlangDecoder::IGlobalSession_checkCompileTargetSupport(ObjectID objectId, ParameterBlock const& parameterBlock) + { + (void)objectId; + (void)parameterBlock; + slangRecordLog(LogLevel::Debug, "%s should not be called, it'a not recordd\n", __PRETTY_FUNCTION__); + } + + void SlangDecoder::IGlobalSession_checkPassThroughSupport(ObjectID objectId, ParameterBlock const& parameterBlock) + { + (void)objectId; + (void)parameterBlock; + slangRecordLog(LogLevel::Debug, "%s should not be called, it'a not recordd\n", __PRETTY_FUNCTION__); + } + + void SlangDecoder::IGlobalSession_compileStdLib(ObjectID objectId, ParameterBlock const& parameterBlock) + { + slang::CompileStdLibFlags flags {}; + ParameterDecoder::decodeEnumValue(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, flags); + + for (auto consumer: m_consumers) + { + consumer->IGlobalSession_compileStdLib(objectId, flags); + } + } + + void SlangDecoder::IGlobalSession_loadStdLib(ObjectID objectId, ParameterBlock const& parameterBlock) + { + PointerDecoder<void*> stdLib; + ParameterDecoder::decodePointer(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, stdLib); + + for (auto consumer: m_consumers) + { + consumer->IGlobalSession_loadStdLib(objectId, stdLib.getPointer(), stdLib.getDataSize()); + } + } + + void SlangDecoder::IGlobalSession_saveStdLib(ObjectID objectId, ParameterBlock const& parameterBlock) + { + SlangArchiveType archiveType {}; + ObjectID outBlobId = 0; + ParameterDecoder::decodeEnumValue(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, archiveType); + ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outBlobId); + + for (auto consumer: m_consumers) + { + consumer->IGlobalSession_saveStdLib(objectId, archiveType, outBlobId); + } + } + + void SlangDecoder::IGlobalSession_findCapability(ObjectID objectId, ParameterBlock const& parameterBlock) + { + (void)objectId; + (void)parameterBlock; + slangRecordLog(LogLevel::Debug, "%s should not be called, it'a not recordd\n", __PRETTY_FUNCTION__); + } + + void SlangDecoder::IGlobalSession_setDownstreamCompilerForTransition(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + SlangCompileTarget source {}; + SlangCompileTarget target {}; + SlangPassThrough compiler {}; + + readByte = ParameterDecoder::decodeEnumValue(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, source); + readByte += ParameterDecoder::decodeEnumValue(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, target); + readByte += ParameterDecoder::decodeEnumValue(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, compiler); + + for (auto consumer: m_consumers) + { + consumer->IGlobalSession_setDownstreamCompilerForTransition(objectId, source, target, compiler); + } + } + + void SlangDecoder::IGlobalSession_getDownstreamCompilerForTransition(ObjectID objectId, ParameterBlock const& parameterBlock) + { + (void)objectId; + (void)parameterBlock; + slangRecordLog(LogLevel::Debug, "%s should not be called, it'a not recordd\n", __PRETTY_FUNCTION__); + } + + void SlangDecoder::IGlobalSession_getCompilerElapsedTime(ObjectID objectId, ParameterBlock const& parameterBlock) + { + (void)objectId; + (void)parameterBlock; + slangRecordLog(LogLevel::Debug, "%s should not be called, it'a not recordd\n", __PRETTY_FUNCTION__); + } + + void SlangDecoder::IGlobalSession_setSPIRVCoreGrammar(ObjectID objectId, ParameterBlock const& parameterBlock) + { + (void)objectId; + (void)parameterBlock; + slangRecordLog(LogLevel::Debug, "%s should not be called, it'a not recordd\n", __PRETTY_FUNCTION__); + } + + void SlangDecoder::IGlobalSession_parseCommandLineArguments(ObjectID objectId, ParameterBlock const& parameterBlock) + { + int argc = 0; + size_t readByte = 0; + readByte = ParameterDecoder::decodeInt32(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, argc); + std::vector<char*> argv; + + if (argc > 0) + { + uint32_t arrayCount = 0; + readByte += ParameterDecoder::decodeUint32(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, arrayCount); + + SLANG_RECORD_ASSERT(arrayCount == (uint32_t)argc); + argv.resize(arrayCount); + + readByte += ParameterDecoder::decodeStringArray(parameterBlock.parameterBuffer + readByte, + parameterBlock.parameterBufferSize - readByte, argv.data(), arrayCount); + } + + ObjectID outSessionDescId = 0; + ObjectID outAllocationId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outSessionDescId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outAllocationId); + + for (auto consumer: m_consumers) + { + consumer->IGlobalSession_parseCommandLineArguments(objectId, argc, argv.data(), outSessionDescId, outAllocationId); + } + } + + void SlangDecoder::IGlobalSession_getSessionDescDigest(ObjectID objectId, ParameterBlock const& parameterBlock) + { + StructDecoder<slang::SessionDesc> sessionDesc; + ObjectID outBlobId = 0; + size_t readByte = 0; + sessionDesc.decode(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize); + ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outBlobId); + + for (auto consumer: m_consumers) + { + consumer->IGlobalSession_getSessionDescDigest(objectId, &sessionDesc.getValue(), outBlobId); + } + } + + + void SlangDecoder::ISession_getGlobalSession(ObjectID objectId, ParameterBlock const& parameterBlock) + { + (void)objectId; + (void)parameterBlock; + slangRecordLog(LogLevel::Debug, "%s should not be called, it'a not recordd\n", __PRETTY_FUNCTION__); + } + + void SlangDecoder::ISession_loadModule(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + StringDecoder moduleName; + readByte += ParameterDecoder::decodeString(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, moduleName); + + ObjectID outDiagnosticsId = 0; + ObjectID outModuleId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outDiagnosticsId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outModuleId); + + for (auto consumer: m_consumers) + { + consumer->ISession_loadModule(objectId, moduleName.getPointer(), outDiagnosticsId, outModuleId); + } + } + + void SlangDecoder::ISession_loadModuleFromIRBlob(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + StringDecoder moduleName; + StringDecoder path; + BlobDecoder source; + readByte = ParameterDecoder::decodeString(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, moduleName); + readByte += ParameterDecoder::decodeString(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, path); + readByte += source.decode(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte); + + ObjectID outDiagnosticsId = 0; + ObjectID outModuleId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outDiagnosticsId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outModuleId); + + for (auto consumer: m_consumers) + { + consumer->ISession_loadModuleFromIRBlob(objectId, moduleName.getPointer(), path.getPointer(), source.getBlob(), outDiagnosticsId, outModuleId); + } + } + + void SlangDecoder::ISession_loadModuleFromSource(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + StringDecoder moduleName; + StringDecoder path; + BlobDecoder source; + readByte = ParameterDecoder::decodeString(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, moduleName); + readByte += ParameterDecoder::decodeString(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, path); + readByte += source.decode(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte); + + ObjectID outDiagnosticsId = 0; + ObjectID outModuleId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outDiagnosticsId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outModuleId); + + for (auto consumer: m_consumers) + { + consumer->ISession_loadModuleFromSource(objectId, moduleName.getPointer(), path.getPointer(), source.getBlob(), outDiagnosticsId, outModuleId); + } + } + + void SlangDecoder::ISession_loadModuleFromSourceString(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + StringDecoder moduleName; + StringDecoder path; + StringDecoder source; + readByte = ParameterDecoder::decodeString(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, moduleName); + readByte += ParameterDecoder::decodeString(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, path); + readByte += ParameterDecoder::decodeString(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, source); + + ObjectID outDiagnosticsId = 0; + ObjectID outModuleId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outDiagnosticsId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outModuleId); + + for (auto consumer: m_consumers) + { + consumer->ISession_loadModuleFromSourceString(objectId, moduleName.getPointer(), path.getPointer(), source.getPointer(), outDiagnosticsId, outModuleId); + } + } + + void SlangDecoder::ISession_createCompositeComponentType(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + std::vector<ObjectID> componentTypeIdList; + uint32_t arrayCount = 0; + readByte = ParameterDecoder::decodeUint32(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, arrayCount); + + componentTypeIdList.resize(arrayCount); + readByte += ParameterDecoder::decodeAddressArray(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, componentTypeIdList.data(), arrayCount); + + ObjectID outCompositeComponentTypeId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outCompositeComponentTypeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->ISession_createCompositeComponentType(objectId, componentTypeIdList.data(), componentTypeIdList.size(), outCompositeComponentTypeId, outDiagnosticsId); + } + + } + + // TODO: See https://github.com/shader-slang/slang/issues/4624 for more details + void SlangDecoder::ISession_specializeType(ObjectID objectId, ParameterBlock const& parameterBlock) + { + slangRecordLog(LogLevel::Error, "%s: The shader reflection app is not recordd\n", __PRETTY_FUNCTION__); + + size_t readByte = 0; + ObjectID typeId = 0; + uint32_t arrayCount = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, typeId); + readByte += ParameterDecoder::decodeUint32(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, arrayCount); + + std::vector<slang::SpecializationArg> specializationArgs; + specializationArgs.resize(arrayCount); + readByte += ParameterDecoder::decodeStructArray(parameterBlock.parameterBuffer + readByte, + parameterBlock.parameterBufferSize - readByte, specializationArgs.data(), arrayCount); + + ObjectID outDiagnosticsId = 0; + ObjectID outTypeReflectionId = 0; + + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outTypeReflectionId); + + for (auto consumer: m_consumers) + { + consumer->ISession_specializeType(objectId, typeId, specializationArgs.data(), specializationArgs.size(), outDiagnosticsId, outTypeReflectionId); + } + } + + void SlangDecoder::ISession_getTypeLayout(ObjectID objectId, ParameterBlock const& parameterBlock) + { + slangRecordLog(LogLevel::Error, "%s: The shader reflection app is not recordd\n", __PRETTY_FUNCTION__); + + size_t readByte = 0; + ObjectID typeId = 0; + int64_t targetIndex = 0; + slang::LayoutRules rules {}; + readByte = ParameterDecoder::decodeAddress(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, typeId); + readByte += ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, targetIndex); + readByte += ParameterDecoder::decodeEnumValue(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, rules); + + ObjectID outDiagnosticsId = 0; + ObjectID outTypeLayoutReflectionId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outTypeLayoutReflectionId); + + for (auto consumer: m_consumers) + { + consumer->ISession_getTypeLayout(objectId, typeId, targetIndex, rules, outDiagnosticsId, outTypeLayoutReflectionId); + } + } + + void SlangDecoder::ISession_getContainerType(ObjectID objectId, ParameterBlock const& parameterBlock) + { + slangRecordLog(LogLevel::Error, "%s: The shader reflection app is not recordd\n", __PRETTY_FUNCTION__); + + size_t readByte = 0; + ObjectID elementType = 0; + slang::ContainerType containerType {}; + readByte = ParameterDecoder::decodeAddress(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, elementType); + readByte += ParameterDecoder::decodeEnumValue(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, containerType); + + ObjectID outDiagnosticsId = 0; + ObjectID outTypeReflectionId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.parameterBufferSize - readByte, outTypeReflectionId); + + for (auto consumer: m_consumers) + { + consumer->ISession_getContainerType(objectId, elementType, containerType, outDiagnosticsId, outTypeReflectionId); + } + } + + void SlangDecoder::ISession_getDynamicType(ObjectID objectId, ParameterBlock const& parameterBlock) + { + slangRecordLog(LogLevel::Error, "%s: The shader reflection app is not recordd\n", __PRETTY_FUNCTION__); + + ObjectID outTypeReflectionId = 0; + ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outTypeReflectionId); + + for (auto consumer: m_consumers) + { + consumer->ISession_getDynamicType(objectId, outTypeReflectionId); + } + } + + void SlangDecoder::ISession_getTypeRTTIMangledName(ObjectID objectId, ParameterBlock const& parameterBlock) + { + slangRecordLog(LogLevel::Error, "%s: The shader reflection app is not recordd\n", __PRETTY_FUNCTION__); + + ObjectID typeId = 0; + ObjectID outNameBlobId = 0; + ParameterDecoder::decodeAddress(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, typeId); + ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outNameBlobId); + + for (auto consumer: m_consumers) + { + consumer->ISession_getTypeRTTIMangledName(objectId, typeId, outNameBlobId); + } + } + + void SlangDecoder::ISession_getTypeConformanceWitnessMangledName(ObjectID objectId, ParameterBlock const& parameterBlock) + { + slangRecordLog(LogLevel::Error, "%s: The shader reflection app is not recordd\n", __PRETTY_FUNCTION__); + + size_t readByte = 0; + ObjectID typeId = 0; + ObjectID interfaceTypeId = 0; + ObjectID outNameBlobId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, typeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, interfaceTypeId); + + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outNameBlobId); + + for (auto consumer: m_consumers) + { + consumer->ISession_getTypeConformanceWitnessMangledName(objectId, typeId, interfaceTypeId, outNameBlobId); + } + } + + void SlangDecoder::ISession_getTypeConformanceWitnessSequentialID(ObjectID objectId, ParameterBlock const& parameterBlock) + { + slangRecordLog(LogLevel::Error, "%s: The shader reflection app is not recordd\n", __PRETTY_FUNCTION__); + + size_t readByte = 0; + + ObjectID typeId = 0; + ObjectID interfaceTypeId = 0; + + readByte = ParameterDecoder::decodeAddress(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, typeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, interfaceTypeId); + + uint32_t outSequentialId = 0; + for (auto consumer: m_consumers) + { + consumer->ISession_getTypeConformanceWitnessSequentialID(objectId, typeId, interfaceTypeId, outSequentialId); + } + } + + void SlangDecoder::ISession_createTypeConformanceComponentType(ObjectID objectId, ParameterBlock const& parameterBlock) + { + slangRecordLog(LogLevel::Error, "%s: The shader reflection app is not recordd\n", __PRETTY_FUNCTION__); + + size_t readByte = 0; + ObjectID typeId = 0; + ObjectID interfaceTypeId = 0; + int64_t conformanceIdOverride = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, typeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, interfaceTypeId); + readByte += ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, conformanceIdOverride); + + ObjectID outDiagnosticsId = 0; + ObjectID outConformanceId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outConformanceId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->ISession_createTypeConformanceComponentType(objectId, typeId, interfaceTypeId, conformanceIdOverride, outConformanceId, outDiagnosticsId); + } + } + + void SlangDecoder::ISession_createCompileRequest(ObjectID objectId, ParameterBlock const& parameterBlock) + { + ObjectID outCompileRequestId = 0; + ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outCompileRequestId); + + for (auto consumer: m_consumers) + { + consumer->ISession_createCompileRequest(objectId, outCompileRequestId); + } + } + + void SlangDecoder::ISession_getLoadedModuleCount(ObjectID objectId, ParameterBlock const& parameterBlock) + { + (void)objectId; + (void)parameterBlock; + slangRecordLog(LogLevel::Debug, "%s should not be called, it'a not recordd\n", __PRETTY_FUNCTION__); + } + + void SlangDecoder::ISession_getLoadedModule(ObjectID objectId, ParameterBlock const& parameterBlock) + { + int64_t index = 0; + ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, index); + + ObjectID outModuleId = 0; + ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outModuleId); + + for (auto consumer: m_consumers) + { + consumer->ISession_getLoadedModule(objectId, index, outModuleId); + } + } + + void SlangDecoder::ISession_isBinaryModuleUpToDate(ObjectID objectId, ParameterBlock const& parameterBlock) + { + (void)objectId; + (void)parameterBlock; + slangRecordLog(LogLevel::Debug, "%s should not be called, it'a not recordd\n", __PRETTY_FUNCTION__); + } + + + void SlangDecoder::IModule_findEntryPointByName(ObjectID objectId, ParameterBlock const& parameterBlock) + { + StringDecoder name; + ParameterDecoder::decodeString(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, name); + + ObjectID outEntryPointId = 0; + ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outEntryPointId); + + for (auto consumer: m_consumers) + { + consumer->IModule_findEntryPointByName(objectId, name.getPointer(), outEntryPointId); + } + } + + void SlangDecoder::IModule_getDefinedEntryPointCount(ObjectID objectId, ParameterBlock const& parameterBlock) + { + (void)objectId; + (void)parameterBlock; + slangRecordLog(LogLevel::Debug, "%s should not be called, it'a not recordd\n", __PRETTY_FUNCTION__); + } + + void SlangDecoder::IModule_getDefinedEntryPoint(ObjectID objectId, ParameterBlock const& parameterBlock) + { + int32_t index; + ObjectID outEntryPointId = 0; + ParameterDecoder::decodeInt32(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, index); + ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outEntryPointId); + + for (auto consumer: m_consumers) + { + consumer->IModule_getDefinedEntryPoint(objectId, index, outEntryPointId); + } + } + + void SlangDecoder::IModule_serialize(ObjectID objectId, ParameterBlock const& parameterBlock) + { + ObjectID outSerializedBlobId = 0; + ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outSerializedBlobId); + + for (auto consumer: m_consumers) + { + consumer->IModule_serialize(objectId, outSerializedBlobId); + } + } + + void SlangDecoder::IModule_writeToFile(ObjectID objectId, ParameterBlock const& parameterBlock) + { + StringDecoder fileName; + ParameterDecoder::decodeString(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, fileName); + + for (auto consumer: m_consumers) + { + consumer->IModule_writeToFile(objectId, fileName.getPointer()); + } + } + + void SlangDecoder::IModule_getName(ObjectID objectId, ParameterBlock const& parameterBlock) + { + (void)objectId; + (void)parameterBlock; + slangRecordLog(LogLevel::Debug, "%s should not be called, it'a not recordd\n", __PRETTY_FUNCTION__); + } + + void SlangDecoder::IModule_getFilePath(ObjectID objectId, ParameterBlock const& parameterBlock) + { + (void)objectId; + (void)parameterBlock; + slangRecordLog(LogLevel::Debug, "%s should not be called, it'a not recordd\n", __PRETTY_FUNCTION__); + } + + void SlangDecoder::IModule_getUniqueIdentity(ObjectID objectId, ParameterBlock const& parameterBlock) + { + (void)objectId; + (void)parameterBlock; + slangRecordLog(LogLevel::Debug, "%s should not be called, it'a not recordd\n", __PRETTY_FUNCTION__); + } + + void SlangDecoder::IModule_findAndCheckEntryPoint(ObjectID objectId, ParameterBlock const& parameterBlock) + { + StringDecoder name; + SlangStage stage {}; + size_t readByte = 0; + readByte = ParameterDecoder::decodeString(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, name); + readByte += ParameterDecoder::decodeEnumValue(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, stage); + + ObjectID outEntryPointId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outEntryPointId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->IModule_findAndCheckEntryPoint(objectId, name.getPointer(), stage, outEntryPointId, outDiagnosticsId); + } + } + + void SlangDecoder::IModule_getSession(ObjectID objectId, ParameterBlock const& parameterBlock) + { + (void)objectId; + (void)parameterBlock; + slangRecordLog(LogLevel::Debug, "%s should not be called, it'a not recordd\n", __PRETTY_FUNCTION__); + } + + void SlangDecoder::IModule_getLayout(ObjectID objectId, ParameterBlock const& parameterBlock) + { + int64_t targetIndex = 0; + ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, targetIndex); + ObjectID outDiagnosticsId = 0; + ObjectID programLayoutId = 0; + + size_t readByte = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outDiagnosticsId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, programLayoutId); + + for (auto consumer: m_consumers) + { + consumer->IModule_getLayout(objectId, targetIndex, outDiagnosticsId, programLayoutId); + } + } + + void SlangDecoder::IModule_getSpecializationParamCount(ObjectID objectId, ParameterBlock const& parameterBlock) + { + (void)objectId; + (void)parameterBlock; + slangRecordLog(LogLevel::Debug, "%s should not be called, it'a not recordd\n", __PRETTY_FUNCTION__); + } + + void SlangDecoder::IModule_getEntryPointCode(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + int64_t entryPointIndex = 0; + int64_t targetIndex = 0; + readByte = ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, entryPointIndex); + readByte += ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, targetIndex); + + ObjectID outCodeId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outCodeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->IModule_getEntryPointCode(objectId, entryPointIndex, targetIndex, outCodeId, outDiagnosticsId); + } + } + + void SlangDecoder::IModule_getTargetCode(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + int64_t targetIndex = 0; + readByte = ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, targetIndex); + + ObjectID outCodeId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outCodeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->IModule_getTargetCode(objectId, targetIndex, outCodeId, outDiagnosticsId); + } + } + + void SlangDecoder::IModule_getResultAsFileSystem(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + int64_t entryPointIndex = 0; + int64_t targetIndex = 0; + readByte = ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, entryPointIndex); + readByte += ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, targetIndex); + + ObjectID outFileSystemId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outFileSystemId); + + for (auto consumer: m_consumers) + { + consumer->IModule_getResultAsFileSystem(objectId, entryPointIndex, targetIndex, outFileSystemId); + } + } + + void SlangDecoder::IModule_getEntryPointHash(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + int64_t entryPointIndex = 0; + int64_t targetIndex = 0; + readByte = ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, entryPointIndex); + readByte += ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, targetIndex); + + ObjectID outBlobId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outBlobId); + + for (auto consumer: m_consumers) + { + consumer->IModule_getEntryPointHash(objectId, entryPointIndex, targetIndex, outBlobId); + } + } + + void SlangDecoder::IModule_specialize(ObjectID objectId, ParameterBlock const& parameterBlock) + { + slangRecordLog(LogLevel::Error, "%s: The shader reflection interfaces are not recordd\n", __PRETTY_FUNCTION__); + + size_t readByte = 0; + uint32_t specializationArgCount = 0; + readByte = ParameterDecoder::decodeUint32(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, specializationArgCount); + + std::vector<slang::SpecializationArg> specializationArgs; + + uint32_t arraySize = 0; + readByte += ParameterDecoder::decodeUint32(parameterBlock.parameterBuffer + readByte, + parameterBlock.parameterBufferSize - readByte, arraySize); + + SLANG_RECORD_ASSERT(arraySize == specializationArgCount); + + specializationArgs.resize(specializationArgCount); + readByte += ParameterDecoder::decodeStructArray(parameterBlock.parameterBuffer + readByte, + parameterBlock.parameterBufferSize - readByte, specializationArgs.data(), specializationArgCount); + + ObjectID outSpecializedComponentTypeId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outSpecializedComponentTypeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->IModule_specialize(objectId, specializationArgs.data(), specializationArgCount, outSpecializedComponentTypeId, outDiagnosticsId); + } + } + + void SlangDecoder::IModule_link(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + ObjectID outLinkedComponentTypeId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outLinkedComponentTypeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->IModule_link(objectId, outLinkedComponentTypeId, outDiagnosticsId); + } + } + + void SlangDecoder::IModule_getEntryPointHostCallable(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + int64_t entryPointIndex = 0; + int64_t targetIndex = 0; + readByte = ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, entryPointIndex); + readByte += ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, targetIndex); + + ObjectID outSharedLibraryId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outSharedLibraryId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.parameterBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->IModule_getEntryPointHostCallable(objectId, entryPointIndex, targetIndex, outSharedLibraryId, outDiagnosticsId); + } + } + + void SlangDecoder::IModule_renameEntryPoint(ObjectID objectId, ParameterBlock const& parameterBlock) + { + StringDecoder newName; + ParameterDecoder::decodeString(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, newName); + + ObjectID outEntryPointId = 0; + ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outEntryPointId); + + for (auto consumer: m_consumers) + { + consumer->IModule_renameEntryPoint(objectId, newName.getPointer(), outEntryPointId); + } + } + + void SlangDecoder::IModule_linkWithOptions(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + uint32_t compilerOptionEntryCount = 0; + readByte = ParameterDecoder::decodeUint32(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, compilerOptionEntryCount); + + std::vector<slang::CompilerOptionEntry> compilerOptionEntries; + + uint32_t arrayCount = 0; + readByte += ParameterDecoder::decodeUint32(parameterBlock.parameterBuffer + readByte, + parameterBlock.parameterBufferSize - readByte, arrayCount); + + SLANG_RECORD_ASSERT(arrayCount == compilerOptionEntryCount); + compilerOptionEntries.resize(compilerOptionEntryCount); + + readByte += ParameterDecoder::decodeStructArray(parameterBlock.parameterBuffer + readByte, + parameterBlock.parameterBufferSize - readByte, compilerOptionEntries.data(), compilerOptionEntryCount); + + ObjectID outLinkedComponentTypeId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outLinkedComponentTypeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->IModule_linkWithOptions(objectId, outLinkedComponentTypeId, compilerOptionEntryCount, compilerOptionEntries.data(), outDiagnosticsId); + } + } + + void SlangDecoder::IEntryPoint_getSession(ObjectID objectId, ParameterBlock const& parameterBlock) + { + (void)objectId; + (void)parameterBlock; + slangRecordLog(LogLevel::Debug, "%s should not be called, it'a not recordd\n", __PRETTY_FUNCTION__); + } + + void SlangDecoder::IEntryPoint_getLayout(ObjectID objectId, ParameterBlock const& parameterBlock) + { + int64_t targetIndex = 0; + ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, targetIndex); + + ObjectID outDiagnosticsId = 0; + ObjectID programLayoutId = 0; + + size_t readByte = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outDiagnosticsId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, programLayoutId); + + for (auto consumer: m_consumers) + { + consumer->IEntryPoint_getLayout(objectId, targetIndex, outDiagnosticsId, programLayoutId); + } + } + + void SlangDecoder::IEntryPoint_getSpecializationParamCount(ObjectID objectId, ParameterBlock const& parameterBlock) + { + (void)objectId; + (void)parameterBlock; + slangRecordLog(LogLevel::Debug, "%s should not be called, it'a not recordd\n", __PRETTY_FUNCTION__); + } + + void SlangDecoder::IEntryPoint_getEntryPointCode(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + int64_t entryPointIndex = 0; + int64_t targetIndex = 0; + readByte = ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, entryPointIndex); + readByte += ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, targetIndex); + + ObjectID outCodeId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outCodeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->IEntryPoint_getEntryPointCode(objectId, entryPointIndex, targetIndex, outCodeId, outDiagnosticsId); + } + } + + void SlangDecoder::IEntryPoint_getTargetCode(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + int64_t targetIndex = 0; + readByte = ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, targetIndex); + + ObjectID outCodeId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outCodeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->IEntryPoint_getTargetCode(objectId, targetIndex, outCodeId, outDiagnosticsId); + } + } + + void SlangDecoder::IEntryPoint_getResultAsFileSystem(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + int64_t entryPointIndex = 0; + int64_t targetIndex = 0; + readByte = ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, entryPointIndex); + readByte += ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, targetIndex); + + ObjectID outFileSystemId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outFileSystemId); + + for (auto consumer: m_consumers) + { + consumer->IEntryPoint_getResultAsFileSystem(objectId, entryPointIndex, targetIndex, outFileSystemId); + } + } + + void SlangDecoder::IEntryPoint_getEntryPointHash(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + int64_t entryPointIndex = 0; + int64_t targetIndex = 0; + readByte = ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, entryPointIndex); + readByte += ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, targetIndex); + + ObjectID outBlobId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outBlobId); + + for (auto consumer: m_consumers) + { + consumer->IEntryPoint_getEntryPointHash(objectId, entryPointIndex, targetIndex, outBlobId); + } + } + + void SlangDecoder::IEntryPoint_specialize(ObjectID objectId, ParameterBlock const& parameterBlock) + { + slangRecordLog(LogLevel::Error, "%s: The shader reflection interfaces are not recordd\n", __PRETTY_FUNCTION__); + + size_t readByte = 0; + uint32_t specializationArgCount = 0; + readByte = ParameterDecoder::decodeUint32(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, specializationArgCount); + + std::vector<slang::SpecializationArg> specializationArgs; + + uint32_t arraySize = 0; + readByte += ParameterDecoder::decodeUint32(parameterBlock.parameterBuffer + readByte, + parameterBlock.parameterBufferSize - readByte, arraySize); + + SLANG_RECORD_ASSERT(arraySize == specializationArgCount); + + specializationArgs.resize(specializationArgCount); + readByte += ParameterDecoder::decodeStructArray(parameterBlock.parameterBuffer + readByte, + parameterBlock.parameterBufferSize - readByte, specializationArgs.data(), specializationArgCount); + + ObjectID outSpecializedComponentTypeId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outSpecializedComponentTypeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->IEntryPoint_specialize(objectId, specializationArgs.data(), specializationArgCount, outSpecializedComponentTypeId, outDiagnosticsId); + } + } + + void SlangDecoder::IEntryPoint_link(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + ObjectID outLinkedComponentTypeId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outLinkedComponentTypeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->IEntryPoint_link(objectId, outLinkedComponentTypeId, outDiagnosticsId); + } + } + + void SlangDecoder::IEntryPoint_getEntryPointHostCallable(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + int64_t entryPointIndex = 0; + int64_t targetIndex = 0; + readByte = ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, entryPointIndex); + readByte += ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, targetIndex); + + ObjectID outSharedLibraryId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outSharedLibraryId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.parameterBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->IEntryPoint_getEntryPointHostCallable(objectId, entryPointIndex, targetIndex, outSharedLibraryId, outDiagnosticsId); + } + } + + void SlangDecoder::IEntryPoint_renameEntryPoint(ObjectID objectId, ParameterBlock const& parameterBlock) + { + StringDecoder newName; + ParameterDecoder::decodeString(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, newName); + + ObjectID outEntryPointId = 0; + ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outEntryPointId); + + for (auto consumer: m_consumers) + { + consumer->IEntryPoint_renameEntryPoint(objectId, newName.getPointer(), outEntryPointId); + } + } + + void SlangDecoder::IEntryPoint_linkWithOptions(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + uint32_t compilerOptionEntryCount = 0; + readByte = ParameterDecoder::decodeUint32(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, compilerOptionEntryCount); + + std::vector<slang::CompilerOptionEntry> compilerOptionEntries; + + uint32_t arrayCount = 0; + readByte += ParameterDecoder::decodeUint32(parameterBlock.parameterBuffer + readByte, + parameterBlock.parameterBufferSize - readByte, arrayCount); + + SLANG_RECORD_ASSERT(arrayCount == compilerOptionEntryCount); + compilerOptionEntries.resize(compilerOptionEntryCount); + + readByte += ParameterDecoder::decodeStructArray(parameterBlock.parameterBuffer + readByte, + parameterBlock.parameterBufferSize - readByte, compilerOptionEntries.data(), compilerOptionEntryCount); + + ObjectID outLinkedComponentTypeId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outLinkedComponentTypeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->IEntryPoint_linkWithOptions(objectId, outLinkedComponentTypeId, compilerOptionEntryCount, compilerOptionEntries.data(), outDiagnosticsId); + } + } + + + void SlangDecoder::ICompositeComponentType_getSession(ObjectID objectId, ParameterBlock const& parameterBlock) + { + (void)objectId; + (void)parameterBlock; + slangRecordLog(LogLevel::Debug, "%s should not be called, it'a not recordd\n", __PRETTY_FUNCTION__); + } + + void SlangDecoder::ICompositeComponentType_getLayout(ObjectID objectId, ParameterBlock const& parameterBlock) + { + int64_t targetIndex = 0; + ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, targetIndex); + ObjectID outDiagnosticsId = 0; + ObjectID programLayoutId = 0; + + size_t readByte = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outDiagnosticsId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, programLayoutId); + + for (auto consumer: m_consumers) + { + consumer->ICompositeComponentType_getLayout(objectId, targetIndex, outDiagnosticsId, programLayoutId); + } + } + + void SlangDecoder::ICompositeComponentType_getSpecializationParamCount(ObjectID objectId, ParameterBlock const& parameterBlock) + { + (void)objectId; + (void)parameterBlock; + slangRecordLog(LogLevel::Debug, "%s should not be called, it'a not recordd\n", __PRETTY_FUNCTION__); + } + + void SlangDecoder::ICompositeComponentType_getEntryPointCode(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + int64_t entryPointIndex = 0; + int64_t targetIndex = 0; + readByte = ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, entryPointIndex); + readByte += ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, targetIndex); + + ObjectID outCodeId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outCodeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->ICompositeComponentType_getEntryPointCode(objectId, entryPointIndex, targetIndex, outCodeId, outDiagnosticsId); + } + } + + void SlangDecoder::ICompositeComponentType_getTargetCode(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + int64_t targetIndex = 0; + readByte = ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, targetIndex); + + ObjectID outCodeId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outCodeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->ICompositeComponentType_getTargetCode(objectId, targetIndex, outCodeId, outDiagnosticsId); + } + } + + void SlangDecoder::ICompositeComponentType_getResultAsFileSystem(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + int64_t entryPointIndex = 0; + int64_t targetIndex = 0; + readByte = ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, entryPointIndex); + readByte += ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, targetIndex); + + ObjectID outFileSystemId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outFileSystemId); + + for (auto consumer: m_consumers) + { + consumer->ICompositeComponentType_getResultAsFileSystem(objectId, entryPointIndex, targetIndex, outFileSystemId); + } + } + + void SlangDecoder::ICompositeComponentType_getEntryPointHash(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + int64_t entryPointIndex = 0; + int64_t targetIndex = 0; + readByte = ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, entryPointIndex); + readByte += ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, targetIndex); + + ObjectID outBlobId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outBlobId); + + for (auto consumer: m_consumers) + { + consumer->ICompositeComponentType_getEntryPointHash(objectId, entryPointIndex, targetIndex, outBlobId); + } + } + + void SlangDecoder::ICompositeComponentType_specialize(ObjectID objectId, ParameterBlock const& parameterBlock) + { + slangRecordLog(LogLevel::Error, "%s: The shader reflection interfaces are not recordd\n", __PRETTY_FUNCTION__); + + size_t readByte = 0; + uint32_t specializationArgCount = 0; + readByte = ParameterDecoder::decodeUint32(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, specializationArgCount); + + std::vector<slang::SpecializationArg> specializationArgs; + + uint32_t arraySize = 0; + readByte += ParameterDecoder::decodeUint32(parameterBlock.parameterBuffer + readByte, + parameterBlock.parameterBufferSize - readByte, arraySize); + + SLANG_RECORD_ASSERT(arraySize == specializationArgCount); + + specializationArgs.resize(specializationArgCount); + readByte += ParameterDecoder::decodeStructArray(parameterBlock.parameterBuffer + readByte, + parameterBlock.parameterBufferSize - readByte, specializationArgs.data(), specializationArgCount); + + ObjectID outSpecializedComponentTypeId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outSpecializedComponentTypeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->ICompositeComponentType_specialize(objectId, specializationArgs.data(), specializationArgCount, outSpecializedComponentTypeId, outDiagnosticsId); + } + } + + void SlangDecoder::ICompositeComponentType_link(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + ObjectID outLinkedComponentTypeId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outLinkedComponentTypeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->ICompositeComponentType_link(objectId, outLinkedComponentTypeId, outDiagnosticsId); + } + } + + void SlangDecoder::ICompositeComponentType_getEntryPointHostCallable(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + int64_t entryPointIndex = 0; + int64_t targetIndex = 0; + readByte = ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, entryPointIndex); + readByte += ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, targetIndex); + + ObjectID outSharedLibraryId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outSharedLibraryId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.parameterBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->ICompositeComponentType_getEntryPointHostCallable(objectId, entryPointIndex, targetIndex, outSharedLibraryId, outDiagnosticsId); + } + } + + void SlangDecoder::ICompositeComponentType_renameEntryPoint(ObjectID objectId, ParameterBlock const& parameterBlock) + { + StringDecoder newName; + ParameterDecoder::decodeString(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, newName); + + ObjectID outEntryPointId = 0; + ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outEntryPointId); + + for (auto consumer: m_consumers) + { + consumer->ICompositeComponentType_renameEntryPoint(objectId, newName.getPointer(), outEntryPointId); + } + } + + void SlangDecoder::ICompositeComponentType_linkWithOptions(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + uint32_t compilerOptionEntryCount = 0; + readByte = ParameterDecoder::decodeUint32(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, compilerOptionEntryCount); + + std::vector<slang::CompilerOptionEntry> compilerOptionEntries; + + uint32_t arrayCount = 0; + readByte += ParameterDecoder::decodeUint32(parameterBlock.parameterBuffer + readByte, + parameterBlock.parameterBufferSize - readByte, arrayCount); + + SLANG_RECORD_ASSERT(arrayCount == compilerOptionEntryCount); + compilerOptionEntries.resize(compilerOptionEntryCount); + + readByte += ParameterDecoder::decodeStructArray(parameterBlock.parameterBuffer + readByte, + parameterBlock.parameterBufferSize - readByte, compilerOptionEntries.data(), compilerOptionEntryCount); + + ObjectID outLinkedComponentTypeId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outLinkedComponentTypeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->ICompositeComponentType_linkWithOptions(objectId, outLinkedComponentTypeId, compilerOptionEntryCount, compilerOptionEntries.data(), outDiagnosticsId); + } + } + + + void SlangDecoder::ITypeConformance_getSession(ObjectID objectId, ParameterBlock const& parameterBlock) + { + (void)objectId; + (void)parameterBlock; + slangRecordLog(LogLevel::Debug, "%s should not be called, it'a not recordd\n", __PRETTY_FUNCTION__); + } + + void SlangDecoder::ITypeConformance_getLayout(ObjectID objectId, ParameterBlock const& parameterBlock) + { + int64_t targetIndex = 0; + ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, targetIndex); + ObjectID outDiagnosticsId = 0; + ObjectID programLayoutId = 0; + + size_t readByte = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outDiagnosticsId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, programLayoutId); + + for (auto consumer: m_consumers) + { + consumer->ITypeConformance_getLayout(objectId, targetIndex, outDiagnosticsId, programLayoutId); + } + } + + void SlangDecoder::ITypeConformance_getSpecializationParamCount(ObjectID objectId, ParameterBlock const& parameterBlock) + { + (void)objectId; + (void)parameterBlock; + slangRecordLog(LogLevel::Debug, "%s should not be called, it'a not recordd\n", __PRETTY_FUNCTION__); + } + + void SlangDecoder::ITypeConformance_getEntryPointCode(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + int64_t entryPointIndex = 0; + int64_t targetIndex = 0; + readByte = ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, entryPointIndex); + readByte += ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, targetIndex); + + ObjectID outCodeId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outCodeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->ITypeConformance_getEntryPointCode(objectId, entryPointIndex, targetIndex, outCodeId, outDiagnosticsId); + } + } + + void SlangDecoder::ITypeConformance_getTargetCode(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + int64_t targetIndex = 0; + readByte = ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, targetIndex); + + ObjectID outCodeId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outCodeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.parameterBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->ITypeConformance_getTargetCode(objectId, targetIndex, outCodeId, outDiagnosticsId); + } + } + + void SlangDecoder::ITypeConformance_getResultAsFileSystem(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + int64_t entryPointIndex = 0; + int64_t targetIndex = 0; + readByte = ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, entryPointIndex); + readByte += ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, targetIndex); + + ObjectID outFileSystemId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outFileSystemId); + + for (auto consumer: m_consumers) + { + consumer->ITypeConformance_getResultAsFileSystem(objectId, entryPointIndex, targetIndex, outFileSystemId); + } + } + + void SlangDecoder::ITypeConformance_getEntryPointHash(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + int64_t entryPointIndex = 0; + int64_t targetIndex = 0; + readByte = ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, entryPointIndex); + readByte += ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, targetIndex); + + ObjectID outBlobId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outBlobId); + + for (auto consumer: m_consumers) + { + consumer->ITypeConformance_getEntryPointHash(objectId, entryPointIndex, targetIndex, outBlobId); + } + } + + void SlangDecoder::ITypeConformance_specialize(ObjectID objectId, ParameterBlock const& parameterBlock) + { + slangRecordLog(LogLevel::Error, "%s: The shader reflection interfaces are not recordd\n", __PRETTY_FUNCTION__); + + size_t readByte = 0; + uint32_t specializationArgCount = 0; + readByte = ParameterDecoder::decodeUint32(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, specializationArgCount); + + std::vector<slang::SpecializationArg> specializationArgs; + + uint32_t arraySize = 0; + readByte += ParameterDecoder::decodeUint32(parameterBlock.parameterBuffer + readByte, + parameterBlock.parameterBufferSize - readByte, arraySize); + + SLANG_RECORD_ASSERT(arraySize == specializationArgCount); + + specializationArgs.resize(specializationArgCount); + readByte += ParameterDecoder::decodeStructArray(parameterBlock.parameterBuffer + readByte, + parameterBlock.parameterBufferSize - readByte, specializationArgs.data(), specializationArgCount); + + ObjectID outSpecializedComponentTypeId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outSpecializedComponentTypeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->IModule_specialize(objectId, specializationArgs.data(), specializationArgCount, outSpecializedComponentTypeId, outDiagnosticsId); + } + } + + void SlangDecoder::ITypeConformance_link(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + ObjectID outLinkedComponentTypeId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outLinkedComponentTypeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->ITypeConformance_link(objectId, outLinkedComponentTypeId, outDiagnosticsId); + } + } + + void SlangDecoder::ITypeConformance_getEntryPointHostCallable(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + int64_t entryPointIndex = 0; + int64_t targetIndex = 0; + readByte = ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, entryPointIndex); + readByte += ParameterDecoder::decodeInt64(parameterBlock.parameterBuffer + readByte, parameterBlock.parameterBufferSize - readByte, targetIndex); + + ObjectID outSharedLibraryId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outSharedLibraryId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.parameterBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->ITypeConformance_getEntryPointHostCallable(objectId, entryPointIndex, targetIndex, outSharedLibraryId, outDiagnosticsId); + } + } + + void SlangDecoder::ITypeConformance_renameEntryPoint(ObjectID objectId, ParameterBlock const& parameterBlock) + { + StringDecoder newName; + ParameterDecoder::decodeString(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, newName); + + ObjectID outEntryPointId = 0; + ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outEntryPointId); + + for (auto consumer: m_consumers) + { + consumer->ITypeConformance_renameEntryPoint(objectId, newName.getPointer(), outEntryPointId); + } + } + + void SlangDecoder::ITypeConformance_linkWithOptions(ObjectID objectId, ParameterBlock const& parameterBlock) + { + size_t readByte = 0; + uint32_t compilerOptionEntryCount = 0; + readByte = ParameterDecoder::decodeUint32(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize, compilerOptionEntryCount); + + std::vector<slang::CompilerOptionEntry> compilerOptionEntries; + + uint32_t arrayCount = 0; + readByte += ParameterDecoder::decodeUint32(parameterBlock.parameterBuffer + readByte, + parameterBlock.parameterBufferSize - readByte, arrayCount); + + SLANG_RECORD_ASSERT(arrayCount == compilerOptionEntryCount); + compilerOptionEntries.resize(compilerOptionEntryCount); + + readByte += ParameterDecoder::decodeStructArray(parameterBlock.parameterBuffer + readByte, + parameterBlock.parameterBufferSize - readByte, compilerOptionEntries.data(), compilerOptionEntryCount); + + ObjectID outLinkedComponentTypeId = 0; + ObjectID outDiagnosticsId = 0; + readByte = ParameterDecoder::decodeAddress(parameterBlock.outputBuffer, parameterBlock.outputBufferSize, outLinkedComponentTypeId); + readByte += ParameterDecoder::decodeAddress(parameterBlock.outputBuffer + readByte, parameterBlock.outputBufferSize - readByte, outDiagnosticsId); + + for (auto consumer: m_consumers) + { + consumer->ITypeConformance_linkWithOptions(objectId, outLinkedComponentTypeId, compilerOptionEntryCount, compilerOptionEntries.data(), outDiagnosticsId); + } + } +} diff --git a/source/slang-record-replay/replay/slang-decoder.h b/source/slang-record-replay/replay/slang-decoder.h new file mode 100644 index 000000000..f127ebc85 --- /dev/null +++ b/source/slang-record-replay/replay/slang-decoder.h @@ -0,0 +1,154 @@ +#ifndef SLANG_DECODER_H +#define SLANG_DECODER_H + +#include <vector> +#include <unordered_map> +#include "../util/record-format.h" +#include "decoder-consumer.h" +#include "../../core/slang-list.h" + +namespace SlangRecord +{ + class SlangDecoder { + public: + struct ParameterBlock + { + const uint8_t* parameterBuffer = nullptr; + int64_t parameterBufferSize = 0; + + const uint8_t* outputBuffer = nullptr; + int64_t outputBufferSize = 0; + }; + + struct OutputObject + { + ObjectID recorddObjectId; + }; + + SlangDecoder() {}; + ~SlangDecoder() {}; + + bool processMethodCall(FunctionHeader const& header, ParameterBlock const& parameterBlock); + bool processFunctionCall(FunctionHeader const& header, ParameterBlock const& parameterBlock); + + bool processIGlobalSessionMethods(ApiCallId callId, ObjectID objectId, ParameterBlock const& parameterBlock); + bool processISessionMethods(ApiCallId callId, ObjectID objectId, ParameterBlock const& parameterBlock); + bool processIModuleMethods(ApiCallId callId, ObjectID objectId, ParameterBlock const& parameterBlock); + bool processIEntryPointMethods(ApiCallId callId, ObjectID objectId, ParameterBlock const& parameterBlock); + bool processICompositeComponentTypeMethods(ApiCallId callId, ObjectID objectId, ParameterBlock const& parameterBlock); + bool processITypeConformanceMethods(ApiCallId callId, ObjectID objectId, ParameterBlock const& parameterBlock); + + bool CreateGlobalSession(ObjectID objectId, ParameterBlock const& parameterBlock); + bool IGlobalSession_createSession(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_findProfile(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_setDownstreamCompilerPath(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_setDownstreamCompilerPrelude(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_getDownstreamCompilerPrelude(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_getBuildTagString(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_setDefaultDownstreamCompiler(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_getDefaultDownstreamCompiler(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_setLanguagePrelude(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_getLanguagePrelude(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_createCompileRequest(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_addBuiltins(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_setSharedLibraryLoader(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_getSharedLibraryLoader(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_checkCompileTargetSupport(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_checkPassThroughSupport(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_compileStdLib(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_loadStdLib(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_saveStdLib(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_findCapability(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_setDownstreamCompilerForTransition(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_getDownstreamCompilerForTransition(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_getCompilerElapsedTime(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_setSPIRVCoreGrammar(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_parseCommandLineArguments(ObjectID objectId, ParameterBlock const& parameterBlock); + void IGlobalSession_getSessionDescDigest(ObjectID objectId, ParameterBlock const& parameterBlock); + + void ISession_getGlobalSession(ObjectID objectId, ParameterBlock const& parameterBlock); + void ISession_loadModule(ObjectID objectId, ParameterBlock const& parameterBlock); + void ISession_loadModuleFromBlob(ObjectID objectId, ParameterBlock const& parameterBlock); + void ISession_loadModuleFromIRBlob(ObjectID objectId, ParameterBlock const& parameterBlock); + void ISession_loadModuleFromSource(ObjectID objectId, ParameterBlock const& parameterBlock); + void ISession_loadModuleFromSourceString(ObjectID objectId, ParameterBlock const& parameterBlock); + void ISession_createCompositeComponentType(ObjectID objectId, ParameterBlock const& parameterBlock); + void ISession_specializeType(ObjectID objectId, ParameterBlock const& parameterBlock); + void ISession_getTypeLayout(ObjectID objectId, ParameterBlock const& parameterBlock); + void ISession_getContainerType(ObjectID objectId, ParameterBlock const& parameterBlock); + void ISession_getDynamicType(ObjectID objectId, ParameterBlock const& parameterBlock); + void ISession_getTypeRTTIMangledName(ObjectID objectId, ParameterBlock const& parameterBlock); + void ISession_getTypeConformanceWitnessMangledName(ObjectID objectId, ParameterBlock const& parameterBlock); + void ISession_getTypeConformanceWitnessSequentialID(ObjectID objectId, ParameterBlock const& parameterBlock); + void ISession_createTypeConformanceComponentType(ObjectID objectId, ParameterBlock const& parameterBlock); + void ISession_createCompileRequest(ObjectID objectId, ParameterBlock const& parameterBlock); + void ISession_getLoadedModuleCount(ObjectID objectId, ParameterBlock const& parameterBlock); + void ISession_getLoadedModule(ObjectID objectId, ParameterBlock const& parameterBlock); + void ISession_isBinaryModuleUpToDate(ObjectID objectId, ParameterBlock const& parameterBlock); + + void IModule_findEntryPointByName(ObjectID objectId, ParameterBlock const& parameterBlock); + void IModule_getDefinedEntryPointCount(ObjectID objectId, ParameterBlock const& parameterBlock); + void IModule_getDefinedEntryPoint(ObjectID objectId, ParameterBlock const& parameterBlock); + void IModule_serialize(ObjectID objectId, ParameterBlock const& parameterBlock); + void IModule_writeToFile(ObjectID objectId, ParameterBlock const& parameterBlock); + void IModule_getName(ObjectID objectId, ParameterBlock const& parameterBlock); + void IModule_getFilePath(ObjectID objectId, ParameterBlock const& parameterBlock); + void IModule_getUniqueIdentity(ObjectID objectId, ParameterBlock const& parameterBlock); + void IModule_findAndCheckEntryPoint(ObjectID objectId, ParameterBlock const& parameterBlock); + void IModule_getSession(ObjectID objectId, ParameterBlock const& parameterBlock); + void IModule_getLayout(ObjectID objectId, ParameterBlock const& parameterBlock); + void IModule_getSpecializationParamCount(ObjectID objectId, ParameterBlock const& parameterBlock); + void IModule_getEntryPointCode(ObjectID objectId, ParameterBlock const& parameterBlock); + void IModule_getTargetCode(ObjectID objectId, ParameterBlock const& parameterBlock); + void IModule_getResultAsFileSystem(ObjectID objectId, ParameterBlock const& parameterBlock); + void IModule_getEntryPointHash(ObjectID objectId, ParameterBlock const& parameterBlock); + void IModule_specialize(ObjectID objectId, ParameterBlock const& parameterBlock); + void IModule_link(ObjectID objectId, ParameterBlock const& parameterBlock); + void IModule_getEntryPointHostCallable(ObjectID objectId, ParameterBlock const& parameterBlock); + void IModule_renameEntryPoint(ObjectID objectId, ParameterBlock const& parameterBlock); + void IModule_linkWithOptions(ObjectID objectId, ParameterBlock const& parameterBlock); + + void IEntryPoint_getSession(ObjectID objectId, ParameterBlock const& parameterBlock); + void IEntryPoint_getLayout(ObjectID objectId, ParameterBlock const& parameterBlock); + void IEntryPoint_getSpecializationParamCount(ObjectID objectId, ParameterBlock const& parameterBlock); + void IEntryPoint_getEntryPointCode(ObjectID objectId, ParameterBlock const& parameterBlock); + void IEntryPoint_getTargetCode(ObjectID objectId, ParameterBlock const& parameterBlock); + void IEntryPoint_getResultAsFileSystem(ObjectID objectId, ParameterBlock const& parameterBlock); + void IEntryPoint_getEntryPointHash(ObjectID objectId, ParameterBlock const& parameterBlock); + void IEntryPoint_specialize(ObjectID objectId, ParameterBlock const& parameterBlock); + void IEntryPoint_link(ObjectID objectId, ParameterBlock const& parameterBlock); + void IEntryPoint_getEntryPointHostCallable(ObjectID objectId, ParameterBlock const& parameterBlock); + void IEntryPoint_renameEntryPoint(ObjectID objectId, ParameterBlock const& parameterBlock); + void IEntryPoint_linkWithOptions(ObjectID objectId, ParameterBlock const& parameterBlock); + + void ICompositeComponentType_getSession(ObjectID objectId, ParameterBlock const& parameterBlock); + void ICompositeComponentType_getLayout(ObjectID objectId, ParameterBlock const& parameterBlock); + void ICompositeComponentType_getSpecializationParamCount(ObjectID objectId, ParameterBlock const& parameterBlock); + void ICompositeComponentType_getEntryPointCode(ObjectID objectId, ParameterBlock const& parameterBlock); + void ICompositeComponentType_getTargetCode(ObjectID objectId, ParameterBlock const& parameterBlock); + void ICompositeComponentType_getResultAsFileSystem(ObjectID objectId, ParameterBlock const& parameterBlock); + void ICompositeComponentType_getEntryPointHash(ObjectID objectId, ParameterBlock const& parameterBlock); + void ICompositeComponentType_specialize(ObjectID objectId, ParameterBlock const& parameterBlock); + void ICompositeComponentType_link(ObjectID objectId, ParameterBlock const& parameterBlock); + void ICompositeComponentType_getEntryPointHostCallable(ObjectID objectId, ParameterBlock const& parameterBlock); + void ICompositeComponentType_renameEntryPoint(ObjectID objectId, ParameterBlock const& parameterBlock); + void ICompositeComponentType_linkWithOptions(ObjectID objectId, ParameterBlock const& parameterBlock); + + void ITypeConformance_getSession(ObjectID objectId, ParameterBlock const& parameterBlock); + void ITypeConformance_getLayout(ObjectID objectId, ParameterBlock const& parameterBlock); + void ITypeConformance_getSpecializationParamCount(ObjectID objectId, ParameterBlock const& parameterBlock); + void ITypeConformance_getEntryPointCode(ObjectID objectId, ParameterBlock const& parameterBlock); + void ITypeConformance_getTargetCode(ObjectID objectId, ParameterBlock const& parameterBlock); + void ITypeConformance_getResultAsFileSystem(ObjectID objectId, ParameterBlock const& parameterBlock); + void ITypeConformance_getEntryPointHash(ObjectID objectId, ParameterBlock const& parameterBlock); + void ITypeConformance_specialize(ObjectID objectId, ParameterBlock const& parameterBlock); + void ITypeConformance_link(ObjectID objectId, ParameterBlock const& parameterBlock); + void ITypeConformance_getEntryPointHostCallable(ObjectID objectId, ParameterBlock const& parameterBlock); + void ITypeConformance_renameEntryPoint(ObjectID objectId, ParameterBlock const& parameterBlock); + void ITypeConformance_linkWithOptions(ObjectID objectId, ParameterBlock const& parameterBlock); + + private: + Slang::List<IDecoderConsumer*> m_consumers; + }; +} +#endif // SLANG_DECODER_H diff --git a/source/slang-capture-replay/api_callId.h b/source/slang-record-replay/util/record-format.h index a0fae73a6..d796abec6 100644 --- a/source/slang-capture-replay/api_callId.h +++ b/source/slang-record-replay/util/record-format.h @@ -3,7 +3,7 @@ #include <cstdint> -namespace SlangCapture +namespace SlangRecord { constexpr uint32_t makeApiCallId(uint16_t classId, uint16_t memberFunctionId) { @@ -31,14 +31,20 @@ namespace SlangCapture Class_ITypeConformance = 7, }; + // Store the pointer value in a 64-bit integer typedef uint64_t AddressFormat; + // Use the address directly to represent the slang object. + typedef AddressFormat ObjectID; + constexpr uint64_t g_globalFunctionHandle = 0; + constexpr uint32_t MAGIC_HEADER = 0x44414548; + constexpr uint32_t MAGIC_TAILER = 0x4C494154; enum ApiCallId : uint32_t { InvalidCallId = 0x00000000, - ICreateGlobalSession = makeApiCallId(GlobalFunction, 0x0000), + CreateGlobalSession = makeApiCallId(GlobalFunction, 0x0000), IGlobalSession_createSession = makeApiCallId(Class_IGlobalSession, 0x0001), IGlobalSession_findProfile = makeApiCallId(Class_IGlobalSession, 0x0002), IGlobalSession_setDownstreamCompilerPath = makeApiCallId(Class_IGlobalSession, 0x0003), @@ -68,7 +74,6 @@ namespace SlangCapture 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), @@ -147,5 +152,21 @@ namespace SlangCapture ITypeConformance_renameEntryPoint = makeApiCallId(Class_ITypeConformance, 0x000B), ITypeConformance_linkWithOptions = makeApiCallId(Class_ITypeConformance, 0x000C) }; + + struct FunctionHeader + { + uint32_t magic {MAGIC_HEADER}; + ApiCallId callId {InvalidCallId}; + ObjectID handleId {0}; + uint64_t dataSizeInBytes {0}; + uint64_t threadId {0}; + }; + + struct FunctionTailer + { + uint32_t magic {MAGIC_TAILER}; + uint32_t dataSizeInBytes {0}; + }; + } #endif diff --git a/source/slang-capture-replay/capture_utility.cpp b/source/slang-record-replay/util/record-utility.cpp index 550edb64f..8bf89ea67 100644 --- a/source/slang-capture-replay/capture_utility.cpp +++ b/source/slang-record-replay/util/record-utility.cpp @@ -5,12 +5,12 @@ #include <stdarg.h> #include <mutex> -#include "capture_utility.h" +#include "record-utility.h" -constexpr const char* kCaptureLayerEnvVar = "SLANG_CAPTURE_LAYER"; -constexpr const char* kCaptureLayerLogLevel = "SLANG_CAPTURE_LOG_LEVEL"; +constexpr const char* kRecordLayerEnvVar = "SLANG_RECORD_LAYER"; +constexpr const char* kRecordLayerLogLevel = "SLANG_RECORD_LOG_LEVEL"; -namespace SlangCapture +namespace SlangRecord { static thread_local unsigned int g_logLevel = LogLevel::Silent; @@ -33,10 +33,10 @@ namespace SlangCapture return out.empty() == false; } - bool isCaptureLayerEnabled() + bool isRecordLayerEnabled() { std::string envVarStr; - if(getEnvironmentVariable(kCaptureLayerEnvVar, envVarStr)) + if(getEnvironmentVariable(kRecordLayerEnvVar, envVarStr)) { if (envVarStr == "1") { @@ -55,7 +55,7 @@ namespace SlangCapture } std::string envVarStr; - if (getEnvironmentVariable(kCaptureLayerLogLevel, envVarStr)) + if (getEnvironmentVariable(kRecordLayerLogLevel, envVarStr)) { char* end = nullptr; unsigned int logLevel = std::strtol(envVarStr.c_str(), &end, 10); @@ -67,7 +67,7 @@ namespace SlangCapture } } - void slangCaptureLog(LogLevel logLevel, const char* fmt, ...) + void slangRecordLog(LogLevel logLevel, const char* fmt, ...) { if (logLevel > g_logLevel) { diff --git a/source/slang-capture-replay/capture_utility.h b/source/slang-record-replay/util/record-utility.h index 666c41947..33156a1f6 100644 --- a/source/slang-capture-replay/capture_utility.h +++ b/source/slang-record-replay/util/record-utility.h @@ -1,5 +1,5 @@ -#ifndef CAPTURE_UTILITY_H -#define CAPTURE_UTILITY_H +#ifndef RECORD_UTILITY_H +#define RECORD_UTILITY_H // in gcc and clang, __PRETTY_FUNCTION__ is the function signature, // while MSVC uses __FUNCSIG__ @@ -7,7 +7,7 @@ #define __PRETTY_FUNCTION__ __FUNCSIG__ #endif -namespace SlangCapture +namespace SlangRecord { enum LogLevel: unsigned int { @@ -17,21 +17,21 @@ namespace SlangCapture Verbose = 3, }; - bool isCaptureLayerEnabled(); - void slangCaptureLog(LogLevel logLevel, const char* fmt, ...); + bool isRecordLayerEnabled(); + void slangRecordLog(LogLevel logLevel, const char* fmt, ...); void setLogLevel(); } -#define SLANG_CAPTURE_ASSERT(VALUE) \ +#define SLANG_RECORD_ASSERT(VALUE) \ do { \ if (!(VALUE)) { \ - SlangCapture::slangCaptureLog(SlangCapture::LogLevel::Error, "Assertion failed: %s, %s, %d\n", #VALUE, __FILE__, __LINE__);\ + SlangRecord::slangRecordLog(SlangRecord::LogLevel::Error, "Assertion failed: %s, %s, %d\n", #VALUE, __FILE__, __LINE__);\ std::abort(); \ } \ } while(0) -#define SLANG_CAPTURE_CHECK(VALUE) \ +#define SLANG_RECORD_CHECK(VALUE) \ do { \ - SLANG_CAPTURE_ASSERT((VALUE) == SLANG_OK); \ + SLANG_RECORD_ASSERT((VALUE) == SLANG_OK); \ } while(0) -#endif // CAPTURE_UTILITY_H +#endif // RECORD_UTILITY_H diff --git a/source/slang/CMakeLists.txt b/source/slang/CMakeLists.txt index 27019f41a..fd20bbe22 100644 --- a/source/slang/CMakeLists.txt +++ b/source/slang/CMakeLists.txt @@ -161,6 +161,11 @@ set(SLANG_LOOKUP_GENERATOR_OUTPUT_DIR set(SLANG_LOOKUP_GENERATED_SOURCE "${SLANG_LOOKUP_GENERATOR_OUTPUT_DIR}/slang-lookup-GLSLstd450.cpp" ) +set(SLANG_RECORD_REPLAY_SYSTEM + "${slang_SOURCE_DIR}/source/slang-record-replay/record" + "${slang_SOURCE_DIR}/source/slang-record-replay/util" +) + add_custom_command( OUTPUT ${SLANG_LOOKUP_GENERATED_SOURCE} COMMAND @@ -201,10 +206,6 @@ slang_add_target( FOLDER generated ) -set(SLANG_CAPTURE_REPLAY_SYSTEM - "${slang_SOURCE_DIR}/source/slang-capture-replay" -) - # # Generate an embeddable stdlib # @@ -243,7 +244,7 @@ configure_file(${slang_SOURCE_DIR}/slang-tag-version.h.in slang-version-header/s # set(slang_common_args - EXTRA_SOURCE_DIRS ${SLANG_CAPTURE_REPLAY_SYSTEM} + EXTRA_SOURCE_DIRS ${SLANG_RECORD_REPLAY_SYSTEM} USE_EXTRA_WARNINGS LINK_WITH_PRIVATE core diff --git a/source/slang/slang-api.cpp b/source/slang/slang-api.cpp index 250b9edf3..c4f668fb2 100644 --- a/source/slang/slang-api.cpp +++ b/source/slang/slang-api.cpp @@ -5,8 +5,8 @@ #include "slang-repro.h" #include "../core/slang-shared-library.h" -#include "../slang-capture-replay/slang-global-session.h" -#include "../slang-capture-replay/capture_utility.h" +#include "../slang-record-replay/record/slang-global-session.h" +#include "../slang-record-replay/util/record-utility.h" // implementation of C interface @@ -119,11 +119,11 @@ SLANG_API SlangResult slang_createGlobalSession( } // Check if the SLANG_CAPTURE_ENABLE_ENV is enabled - if (SlangCapture::isCaptureLayerEnabled()) + if (SlangRecord::isRecordLayerEnabled()) { - SlangCapture::GlobalSessionCapture* globalSessionCapture = - new SlangCapture::GlobalSessionCapture(globalSession.detach()); - Slang::ComPtr<SlangCapture::GlobalSessionCapture> result(globalSessionCapture); + SlangRecord::GlobalSessionRecorder* globalSessionRecorder = + new SlangRecord::GlobalSessionRecorder(globalSession.detach()); + Slang::ComPtr<SlangRecord::GlobalSessionRecorder> result(globalSessionRecorder); *outGlobalSession = result.detach(); } else |
