summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaizhangNV <149626564+kaizhangNV@users.noreply.github.com>2024-06-17 08:41:34 -0700
committerGitHub <noreply@github.com>2024-06-17 08:41:34 -0700
commit93fcb83c34c932c82deeb8a8cd626f0dc990716c (patch)
tree20952609883337228174b1e0301aed5dbdc750cb
parentf6b3ba88d2ccef03278902cdc86afc8d540c0122 (diff)
Feature/capture (#4397)
* Add the function tailer for appending the output - The basic format for the capture encode is as follow: Header: 4 bytes: magic number ('H' 'E' 'A' 'D' ) 4 bytes: call id - specify the method name 8 bytes: handle id - specify 'this' pointer 8 bytes: payload size in bytes - specify the data size of parameters 8 bytes: thread id Payload: Encode for all the parameters. Tailer (optional): Tailer is an optional, it only used when the output of the method is also stored in the method. Usually it just the opaque handle allocated by slang. 4 bytes: magic number ('T' 'A' 'I' 'L') 4 bytes: payload size in bytes. - Fix some issues in checking the result of write of output stream. * Encoding methods of IGlobalSession Add encoding logic for all the member functions of IGlobalSession, except those query functions that do not impact the internal state of slang. Because some get functions will invoke allocations by slang, these functions are account for the "query functions". Therefore those functions are still captured. All the allocations are stored by using their address, because those allocations are opaque and will finally be used as inputs for other APIs, there is no need to store the data. We just need to track those address and know which APIs will consume them. * Add SLANG_CAPTURE_CHECK macro Add SLANG_CAPTURE_CHECK macro to check SLANG_OK is returned. * Fix build error
-rw-r--r--source/core/slang-stream.h2
-rw-r--r--source/slang-capture-replay/capture-manager.cpp35
-rw-r--r--source/slang-capture-replay/capture-manager.h16
-rw-r--r--source/slang-capture-replay/capture_utility.h4
-rw-r--r--source/slang-capture-replay/output-stream.cpp6
-rw-r--r--source/slang-capture-replay/parameter-encoder.cpp70
-rw-r--r--source/slang-capture-replay/parameter-encoder.h2
-rw-r--r--source/slang-capture-replay/slang-global-session.cpp209
-rw-r--r--source/slang-capture-replay/slang-global-session.h2
9 files changed, 327 insertions, 19 deletions
diff --git a/source/core/slang-stream.h b/source/core/slang-stream.h
index a62c18838..8459d53d1 100644
--- a/source/core/slang-stream.h
+++ b/source/core/slang-stream.h
@@ -138,7 +138,7 @@ public:
void setContent(const void* contents, size_t contentsSize)
{
m_ownedContents.setCount(contentsSize);
- if (contentsSize > 0)
+ if (contents != nullptr)
{
::memcpy(m_ownedContents.getBuffer(), contents, contentsSize);
}
diff --git a/source/slang-capture-replay/capture-manager.cpp b/source/slang-capture-replay/capture-manager.cpp
index be5615e00..2d04b077a 100644
--- a/source/slang-capture-replay/capture-manager.cpp
+++ b/source/slang-capture-replay/capture-manager.cpp
@@ -10,14 +10,14 @@ namespace SlangCapture
: m_encoder(&m_memoryStream)
{
std::stringstream ss;
- ss << "gs-"<< globalSessionHandle <<"t-"<<std::this_thread::get_id() << ".cap";
+ ss << "gs-"<< globalSessionHandle <<"-t-"<<std::this_thread::get_id() << ".cap";
m_fileStream = std::make_unique<FileOutputStream>(ss.str());
}
void CaptureManager::clearWithHeader(const ApiCallId& callId, uint64_t handleId)
{
m_memoryStream.flush();
- FunctionHeader header {};
+ FunctionHeader header;
header.callId = callId;
header.handleId = handleId;
@@ -25,13 +25,22 @@ namespace SlangCapture
m_memoryStream.write(&header, sizeof(FunctionHeader));
}
+ void CaptureManager::clearWithTailer()
+ {
+ m_memoryStream.flush();
+ FunctionTailer tailer;
+
+ // write header to memory stream
+ m_memoryStream.write(&tailer, sizeof(FunctionTailer));
+ }
+
ParameterEncoder* CaptureManager::beginMethodCapture(const ApiCallId& callId, uint64_t handleId)
{
clearWithHeader(callId, handleId);
return &m_encoder;
}
- void CaptureManager::endMethodCapture()
+ ParameterEncoder* CaptureManager::endMethodCapture()
{
FunctionHeader* pHeader = const_cast<FunctionHeader*>(
reinterpret_cast<const FunctionHeader*>(m_memoryStream.getData()));
@@ -49,5 +58,25 @@ namespace SlangCapture
// clear the memory stream
m_memoryStream.flush();
+
+ clearWithTailer();
+ return &m_encoder;
+ }
+
+ void CaptureManager::endMethodCaptureAppendOutput()
+ {
+ 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
+ m_fileStream->write(m_memoryStream.getData(), m_memoryStream.getSizeInBytes());
+
+ // take effect of the write
+ m_fileStream->flush();
+
+ // clear the memory stream
+ m_memoryStream.flush();
}
}
diff --git a/source/slang-capture-replay/capture-manager.h b/source/slang-capture-replay/capture-manager.h
index 55d42c458..721986066 100644
--- a/source/slang-capture-replay/capture-manager.h
+++ b/source/slang-capture-replay/capture-manager.h
@@ -9,19 +9,33 @@ namespace SlangCapture
{
public:
CaptureManager(uint64_t globalSessionHandle);
+
+ // Each method capture has to start with a FunctionHeader
ParameterEncoder* beginMethodCapture(const ApiCallId& callId, uint64_t handleId);
- void endMethodCapture();
+ 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();
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;
ParameterEncoder m_encoder;
diff --git a/source/slang-capture-replay/capture_utility.h b/source/slang-capture-replay/capture_utility.h
index 6edd2af9c..666c41947 100644
--- a/source/slang-capture-replay/capture_utility.h
+++ b/source/slang-capture-replay/capture_utility.h
@@ -30,4 +30,8 @@ namespace SlangCapture
} \
} while(0)
+#define SLANG_CAPTURE_CHECK(VALUE) \
+ do { \
+ SLANG_CAPTURE_ASSERT((VALUE) == SLANG_OK); \
+ } while(0)
#endif // CAPTURE_UTILITY_H
diff --git a/source/slang-capture-replay/output-stream.cpp b/source/slang-capture-replay/output-stream.cpp
index acde6fbf1..97c4b098b 100644
--- a/source/slang-capture-replay/output-stream.cpp
+++ b/source/slang-capture-replay/output-stream.cpp
@@ -26,7 +26,7 @@ namespace SlangCapture
void FileOutputStream::write(const void* data, size_t len)
{
- SLANG_CAPTURE_ASSERT(m_fileStream.write(data, len));
+ SLANG_CAPTURE_CHECK(m_fileStream.write(data, len));
}
MemoryStream::MemoryStream()
@@ -35,12 +35,12 @@ namespace SlangCapture
void FileOutputStream::flush()
{
- SLANG_CAPTURE_ASSERT(m_fileStream.flush());
+ SLANG_CAPTURE_CHECK(m_fileStream.flush());
}
void MemoryStream::write(const void* data, size_t len)
{
- SLANG_CAPTURE_ASSERT(m_memoryStream.write(data, len));
+ SLANG_CAPTURE_CHECK(m_memoryStream.write(data, len));
}
void MemoryStream::flush()
diff --git a/source/slang-capture-replay/parameter-encoder.cpp b/source/slang-capture-replay/parameter-encoder.cpp
index 5167cc2ab..8c77884a9 100644
--- a/source/slang-capture-replay/parameter-encoder.cpp
+++ b/source/slang-capture-replay/parameter-encoder.cpp
@@ -1,4 +1,5 @@
#include "parameter-encoder.h"
+#include "api_callId.h"
namespace SlangCapture
{
@@ -13,7 +14,7 @@ namespace SlangCapture
}
encodeUint32(desc.flags);
- encodeUint32(desc.defaultMatrixLayoutMode);
+ encodeEnumValue(desc.defaultMatrixLayoutMode);
encodeInt64(desc.searchPathCount);
for (SlangInt i = 0; i < desc.searchPathCount; i++)
{
@@ -44,29 +45,82 @@ namespace SlangCapture
void ParameterEncoder::encodeStruct(slang::CompilerOptionEntry const& entry)
{
- encodeInt32((int32_t)(entry.name));
+ encodeEnumValue(entry.name);
encodeStruct(entry.value);
}
void ParameterEncoder::encodeStruct(slang::CompilerOptionValue const& value)
{
- (void)value;
+ encodeEnumValue(value.kind);
+ encodeInt32(value.intValue0);
+ encodeString(value.stringValue0);
+ encodeString(value.stringValue1);
}
void ParameterEncoder::encodeStruct(slang::TargetDesc const& targetDesc)
{
- (void)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::encodePointer(const void* value, bool omitData, size_t size)
{
- (void)value;
- (void)omitData;
- (void)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)
{
- (void)value;
+ if (value == nullptr)
+ {
+ encodeUint32(0);
+ }
+ else
+ {
+ uint32_t size = (uint32_t)strlen(value);
+ encodeUint32(size);
+ m_stream->write(value, size);
+ }
+ }
+
+ void ParameterEncoder::encodeStringArray(const char* const* strArray, size_t count)
+ {
+ encodeUint64(count);
+ for (size_t i = 0; i < count; i++)
+ {
+ encodeString(strArray[i]);
+ }
}
}
diff --git a/source/slang-capture-replay/parameter-encoder.h b/source/slang-capture-replay/parameter-encoder.h
index c7c2d959a..2b7abab45 100644
--- a/source/slang-capture-replay/parameter-encoder.h
+++ b/source/slang-capture-replay/parameter-encoder.h
@@ -29,7 +29,9 @@ namespace SlangCapture
void encodeEnumValue(T value) { encodeValue(static_cast<uint32_t>(value)); }
void encodeString(const char* value);
+ void encodeStringArray(const char* const* strArray, size_t count);
void encodePointer(const void* value, bool omitData = false, size_t size = 0);
+ void encodePointer(ISlangBlob* blob);
void encodeAddress(const void* value) { encodeValue(reinterpret_cast<uint64_t>(value)); }
void encodeStruct(slang::SessionDesc const& desc);
diff --git a/source/slang-capture-replay/slang-global-session.cpp b/source/slang-capture-replay/slang-global-session.cpp
index 45ea0b58d..b90d7611d 100644
--- a/source/slang-capture-replay/slang-global-session.cpp
+++ b/source/slang-capture-replay/slang-global-session.cpp
@@ -12,8 +12,8 @@ namespace SlangCapture
{
SLANG_CAPTURE_ASSERT(m_actualGlobalSession != nullptr);
- m_thisHandle = reinterpret_cast<SlangCapture::AddressFormat>(this);
- m_captureManager = std::make_unique<CaptureManager>(m_thisHandle);
+ 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.
@@ -41,8 +41,22 @@ namespace SlangCapture
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->encodeAddress(nullptr);
+ 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,
@@ -65,6 +79,14 @@ namespace SlangCapture
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;
}
@@ -72,24 +94,58 @@ namespace SlangCapture
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->encodeAddress(nullptr);
+ 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;
}
@@ -97,6 +153,15 @@ namespace SlangCapture
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;
}
@@ -104,6 +169,14 @@ namespace SlangCapture
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;
}
@@ -111,43 +184,103 @@ namespace SlangCapture
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->encodeAddress(nullptr);
+ 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->encodeAddress(nullptr);
+ 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->encodeAddress(nullptr);
+ }
+
ISlangSharedLibraryLoader* loader = m_actualGlobalSession->getSharedLibraryLoader();
+
+ {
+ encoder->encodeAddress(loader);
+ }
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;
@@ -155,6 +288,7 @@ namespace SlangCapture
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;
@@ -163,6 +297,13 @@ namespace SlangCapture
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);
+ }
+
SlangResult res = m_actualGlobalSession->compileStdLib(flags);
return res;
}
@@ -170,6 +311,14 @@ namespace SlangCapture
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;
}
@@ -177,12 +326,22 @@ namespace SlangCapture
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->encodeAddress(outBlob);
+ m_captureManager->endMethodCapture();
+ }
+
SlangResult res = m_actualGlobalSession->saveStdLib(archiveType, outBlob);
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;
@@ -191,11 +350,22 @@ namespace SlangCapture
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;
@@ -203,6 +373,7 @@ namespace SlangCapture
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);
}
@@ -210,6 +381,14 @@ namespace SlangCapture
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;
}
@@ -218,14 +397,40 @@ namespace SlangCapture
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);
+ }
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-global-session.h b/source/slang-capture-replay/slang-global-session.h
index 6923ddf11..ef7036baf 100644
--- a/source/slang-capture-replay/slang-global-session.h
+++ b/source/slang-capture-replay/slang-global-session.h
@@ -77,7 +77,7 @@ namespace SlangCapture
// session at the same time. So even if there is one session used by multiple threads, those threads will execute the compile jobs
// sequentially.
std::unique_ptr<CaptureManager> m_captureManager;
- uint64_t m_thisHandle = 0;
+ uint64_t m_globalSessionHandle = 0;
};
} // namespace Slang