summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/example-base/example-base.cpp120
-rw-r--r--examples/example-base/example-base.h21
-rw-r--r--examples/example-base/test-base.cpp50
-rw-r--r--examples/example-base/test-base.h21
-rw-r--r--examples/hello-world/main.cpp12
-rw-r--r--examples/triangle/main.cpp14
-rw-r--r--source/slang-record-replay/record/slang-composite-component-type.cpp19
-rw-r--r--source/slang-record-replay/record/slang-composite-component-type.h1
-rw-r--r--source/slang-record-replay/record/slang-entrypoint.cpp19
-rw-r--r--source/slang-record-replay/record/slang-entrypoint.h1
-rw-r--r--source/slang-record-replay/record/slang-filesystem.cpp5
-rw-r--r--source/slang-record-replay/record/slang-filesystem.h1
-rw-r--r--source/slang-record-replay/record/slang-global-session.cpp5
-rw-r--r--source/slang-record-replay/record/slang-global-session.h1
-rw-r--r--source/slang-record-replay/record/slang-module.cpp21
-rw-r--r--source/slang-record-replay/record/slang-module.h1
-rw-r--r--source/slang-record-replay/record/slang-session.cpp23
-rw-r--r--source/slang-record-replay/record/slang-session.h1
-rw-r--r--source/slang-record-replay/record/slang-type-conformance.cpp19
-rw-r--r--source/slang-record-replay/record/slang-type-conformance.h1
-rw-r--r--source/slang-record-replay/replay/json-consumer.cpp2
-rw-r--r--source/slang-record-replay/replay/replay-consumer.cpp8
-rwxr-xr-xtest-record-replay.sh147
-rw-r--r--tools/platform/window.h6
24 files changed, 384 insertions, 135 deletions
diff --git a/examples/example-base/example-base.cpp b/examples/example-base/example-base.cpp
index 82d474f06..fb11105f5 100644
--- a/examples/example-base/example-base.cpp
+++ b/examples/example-base/example-base.cpp
@@ -17,19 +17,6 @@ Slang::Result WindowedAppBase::initializeBase(
int height,
DeviceType deviceType)
{
- // Create a window for our application to render into.
- //
- platform::WindowDesc windowDesc;
- windowDesc.title = title;
- windowDesc.width = width;
- windowDesc.height = height;
- windowWidth = width;
- windowHeight = height;
- windowDesc.style = platform::WindowStyle::Default;
- gWindow = platform::Application::createWindow(windowDesc);
- gWindow->events.mainLoop = [this]() { mainLoop(); };
- gWindow->events.sizeChanged = Slang::Action<>(this, &WindowedAppBase::windowSizeChanged);
-
// Initialize the rendering layer.
#ifdef _DEBUG
// Enable debug layer in debug config.
@@ -41,26 +28,44 @@ Slang::Result WindowedAppBase::initializeBase(
if (SLANG_FAILED(res))
return res;
- auto deviceInfo = gDevice->getDeviceInfo();
- Slang::StringBuilder titleSb;
- titleSb << title << " (" << deviceInfo.apiName << ": " << deviceInfo.adapterName << ")";
- gWindow->setText(titleSb.getBuffer());
-
ICommandQueue::Desc queueDesc = {};
queueDesc.type = ICommandQueue::QueueType::Graphics;
gQueue = gDevice->createCommandQueue(queueDesc);
- // Create swapchain and framebuffers.
- gfx::ISwapchain::Desc swapchainDesc = {};
- swapchainDesc.format = gfx::Format::R8G8B8A8_UNORM;
- swapchainDesc.width = width;
- swapchainDesc.height = height;
- swapchainDesc.imageCount = kSwapchainImageCount;
- swapchainDesc.queue = gQueue;
- gfx::WindowHandle windowHandle = gWindow->getNativeHandle().convert<gfx::WindowHandle>();
- gSwapchain = gDevice->createSwapchain(swapchainDesc, windowHandle);
-
- IFramebufferLayout::TargetLayout renderTargetLayout = {gSwapchain->getDesc().format, 1};
+ windowWidth = width;
+ windowHeight = height;
+ // Do not create swapchain and windows in test mode, because there won't be any display.
+ if (!isTestMode())
+ {
+ // Create a window for our application to render into.
+ //
+ platform::WindowDesc windowDesc;
+ windowDesc.title = title;
+ windowDesc.width = width;
+ windowDesc.height = height;
+ windowDesc.style = platform::WindowStyle::Default;
+ gWindow = platform::Application::createWindow(windowDesc);
+ gWindow->events.mainLoop = [this]() { mainLoop(); };
+ gWindow->events.sizeChanged = Slang::Action<>(this, &WindowedAppBase::windowSizeChanged);
+
+ auto deviceInfo = gDevice->getDeviceInfo();
+ Slang::StringBuilder titleSb;
+ titleSb << title << " (" << deviceInfo.apiName << ": " << deviceInfo.adapterName << ")";
+ gWindow->setText(titleSb.getBuffer());
+
+ // Create swapchain and framebuffers.
+ gfx::ISwapchain::Desc swapchainDesc = {};
+ swapchainDesc.format = gfx::Format::R8G8B8A8_UNORM;
+ swapchainDesc.width = width;
+ swapchainDesc.height = height;
+ swapchainDesc.imageCount = kSwapchainImageCount;
+ swapchainDesc.queue = gQueue;
+ gfx::WindowHandle windowHandle = gWindow->getNativeHandle().convert<gfx::WindowHandle>();
+ gSwapchain = gDevice->createSwapchain(swapchainDesc, windowHandle);
+ createSwapchainFramebuffers();
+ }
+
+ IFramebufferLayout::TargetLayout renderTargetLayout = {gfx::Format::R8G8B8A8_UNORM, 1};
IFramebufferLayout::TargetLayout depthLayout = {gfx::Format::D32_FLOAT, 1};
IFramebufferLayout::Desc framebufferLayoutDesc;
framebufferLayoutDesc.renderTargetCount = 1;
@@ -69,7 +74,10 @@ Slang::Result WindowedAppBase::initializeBase(
SLANG_RETURN_ON_FAIL(
gDevice->createFramebufferLayout(framebufferLayoutDesc, gFramebufferLayout.writeRef()));
- createSwapchainFramebuffers();
+ if (isTestMode())
+ {
+ createOfflineFramebuffers();
+ }
for (uint32_t i = 0; i < kSwapchainImageCount; i++)
{
@@ -102,23 +110,27 @@ Slang::Result WindowedAppBase::initializeBase(
void WindowedAppBase::mainLoop()
{
int frameBufferIndex = gSwapchain->acquireNextImage();
- if (frameBufferIndex == -1)
- return;
gTransientHeaps[frameBufferIndex]->synchronizeAndReset();
renderFrame(frameBufferIndex);
gTransientHeaps[frameBufferIndex]->finish();
}
-void WindowedAppBase::createSwapchainFramebuffers()
+void WindowedAppBase::offlineRender()
{
- gFramebuffers.clear();
- for (uint32_t i = 0; i < kSwapchainImageCount; i++)
+ gTransientHeaps[0]->synchronizeAndReset();
+ renderFrame(0);
+ gTransientHeaps[0]->finish();
+}
+
+void WindowedAppBase::createFramebuffers(uint32_t width, uint32_t height, gfx::Format colorFormat, uint32_t frameBufferCount)
+{
+ for (uint32_t i = 0; i < frameBufferCount; i++)
{
gfx::ITextureResource::Desc depthBufferDesc;
depthBufferDesc.type = IResource::Type::Texture2D;
- depthBufferDesc.size.width = gSwapchain->getDesc().width;
- depthBufferDesc.size.height = gSwapchain->getDesc().height;
+ depthBufferDesc.size.width = width;
+ depthBufferDesc.size.height = height;
depthBufferDesc.size.depth = 1;
depthBufferDesc.format = gfx::Format::D32_FLOAT;
depthBufferDesc.defaultState = ResourceState::DepthWrite;
@@ -127,12 +139,28 @@ void WindowedAppBase::createSwapchainFramebuffers()
depthBufferDesc.optimalClearValue = &depthClearValue;
ComPtr<gfx::ITextureResource> depthBufferResource =
gDevice->createTextureResource(depthBufferDesc, nullptr);
+
ComPtr<gfx::ITextureResource> colorBuffer;
- gSwapchain->getImage(i, colorBuffer.writeRef());
+ if (isTestMode())
+ {
+ gfx::ITextureResource::Desc colorBufferDesc;
+ colorBufferDesc.type = IResource::Type::Texture2D;
+ colorBufferDesc.size.width = width;
+ colorBufferDesc.size.height = height;
+ colorBufferDesc.size.depth = 1;
+ colorBufferDesc.format = colorFormat;
+ colorBufferDesc.defaultState = ResourceState::RenderTarget;
+ colorBufferDesc.allowedStates = ResourceStateSet(ResourceState::RenderTarget, ResourceState::CopyDestination);
+ colorBuffer = gDevice->createTextureResource(colorBufferDesc, nullptr);
+ }
+ else
+ {
+ gSwapchain->getImage(i, colorBuffer.writeRef());
+ }
gfx::IResourceView::Desc colorBufferViewDesc;
memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc));
- colorBufferViewDesc.format = gSwapchain->getDesc().format;
+ colorBufferViewDesc.format = colorFormat;
colorBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D;
colorBufferViewDesc.type = gfx::IResourceView::Type::RenderTarget;
ComPtr<gfx::IResourceView> rtv =
@@ -152,10 +180,24 @@ void WindowedAppBase::createSwapchainFramebuffers()
framebufferDesc.renderTargetViews = rtv.readRef();
framebufferDesc.layout = gFramebufferLayout;
ComPtr<gfx::IFramebuffer> frameBuffer = gDevice->createFramebuffer(framebufferDesc);
+
gFramebuffers.add(frameBuffer);
}
}
+void WindowedAppBase::createOfflineFramebuffers()
+{
+ gFramebuffers.clear();
+ createFramebuffers(windowWidth, windowHeight, gfx::Format::R8G8B8A8_UNORM, 1);
+}
+
+void WindowedAppBase::createSwapchainFramebuffers()
+{
+ gFramebuffers.clear();
+ createFramebuffers(gSwapchain->getDesc().width, gSwapchain->getDesc().height,
+ gSwapchain->getDesc().format, kSwapchainImageCount);
+}
+
ComPtr<gfx::IResourceView> WindowedAppBase::createTextureFromFile(String fileName, int& textureWidth, int& textureHeight)
{
int channelsInFile = 0;
diff --git a/examples/example-base/example-base.h b/examples/example-base/example-base.h
index 8943323da..b97728e17 100644
--- a/examples/example-base/example-base.h
+++ b/examples/example-base/example-base.h
@@ -4,12 +4,13 @@
#include "tools/platform/window.h"
#include "source/core/slang-basic.h"
#include "source/core/slang-io.h"
+#include "test-base.h"
#ifdef _WIN32
void _Win32OutputDebugString(const char* str);
#endif
-struct WindowedAppBase
+struct WindowedAppBase : public TestBase
{
protected:
static const int kSwapchainImageCount = 2;
@@ -32,8 +33,13 @@ protected:
int width,
int height,
gfx::DeviceType deviceType = gfx::DeviceType::Default);
+
+ void createFramebuffers(uint32_t width, uint32_t height, gfx::Format colorFormat, uint32_t frameBufferCount);
void createSwapchainFramebuffers();
+ void createOfflineFramebuffers();
+
void mainLoop();
+
Slang::ComPtr<gfx::IResourceView> createTextureFromFile(Slang::String fileName, int& textureWidth, int& textureHeight);
virtual void windowSizeChanged();
@@ -42,6 +48,7 @@ protected:
public:
platform::Window* getWindow() { return gWindow.Ptr(); }
virtual void finalize() { gQueue->waitOnHost(); }
+ void offlineRender();
};
struct ExampleResources {
@@ -103,18 +110,26 @@ inline void diagnoseIfNeeded(slang::IBlob* diagnosticsBlob)
void initDebugCallback();
template<typename TApp>
-int innerMain()
+int innerMain(int argc, char** argv)
{
initDebugCallback();
TApp app;
+ app.parseOption(argc, argv);
if (SLANG_FAILED(app.initialize()))
{
return -1;
}
- platform::Application::run(app.getWindow());
+ if (!app.isTestMode())
+ {
+ platform::Application::run(app.getWindow());
+ }
+ else
+ {
+ app.offlineRender();
+ }
app.finalize();
return 0;
diff --git a/examples/example-base/test-base.cpp b/examples/example-base/test-base.cpp
new file mode 100644
index 000000000..5c727aabe
--- /dev/null
+++ b/examples/example-base/test-base.cpp
@@ -0,0 +1,50 @@
+#include "test-base.h"
+
+#ifdef _WIN32
+#include <windows.h>
+#include <shellapi.h>
+#endif
+
+int TestBase::parseOption(int argc, char** argv)
+{
+ // We only make the parse in a very loose way for only extracting the test option.
+#ifdef _WIN32
+ wchar_t** szArglist;
+ szArglist = CommandLineToArgvW(GetCommandLineW(), &argc);
+#endif
+
+ for (int i = 0; i < argc; i++)
+ {
+#ifdef _WIN32
+ if (wcscmp(szArglist[i], L"--test-mode") == 0)
+#else
+ if (strcmp(argv[i], "--test-mode") == 0)
+#endif
+ {
+ m_isTestMode = true;
+ }
+ }
+ return 0;
+}
+
+void TestBase::printEntrypointHashes(int entryPointCount, int targetCount, ComPtr<slang::IComponentType>& composedProgram)
+{
+ for (int targetIndex = 0; targetIndex < targetCount; targetIndex++)
+ {
+ for (int entryPointIndex = 0; entryPointIndex < entryPointCount; entryPointIndex++)
+ {
+ ComPtr<slang::IBlob> entryPointHashBlob;
+ composedProgram->getEntryPointHash(entryPointIndex, targetIndex, entryPointHashBlob.writeRef());
+
+ Slang::StringBuilder strBuilder;
+ strBuilder << "entrypoint: "<< entryPointIndex << ", target: " << targetIndex << ", hash: ";
+
+ uint8_t* buffer = (uint8_t*)entryPointHashBlob->getBufferPointer();
+ for (size_t i = 0; i < entryPointHashBlob->getBufferSize(); i++)
+ {
+ strBuilder<<Slang::StringUtil::makeStringWithFormat("%.2X", buffer[i]);
+ }
+ fprintf(stdout, "%s\n", strBuilder.begin());
+ }
+ }
+}
diff --git a/examples/example-base/test-base.h b/examples/example-base/test-base.h
new file mode 100644
index 000000000..22cd70d09
--- /dev/null
+++ b/examples/example-base/test-base.h
@@ -0,0 +1,21 @@
+#pragma once
+
+#include "slang.h"
+#include "slang-com-ptr.h"
+#include "source/core/slang-string-util.h"
+
+using Slang::ComPtr;
+
+class TestBase {
+
+public:
+ // Parses command line options. This example only has one option for testing purpose.
+ int parseOption(int argc, char** argv);
+
+ void printEntrypointHashes(int entryPointCount, int targetCount, ComPtr<slang::IComponentType>& composedProgram);
+
+ bool isTestMode() const { return m_isTestMode; }
+
+private:
+ bool m_isTestMode = false;
+};
diff --git a/examples/hello-world/main.cpp b/examples/hello-world/main.cpp
index 53285ae51..87d440901 100644
--- a/examples/hello-world/main.cpp
+++ b/examples/hello-world/main.cpp
@@ -12,12 +12,14 @@
#include "vulkan-api.h"
#include "examples/example-base/example-base.h"
+#include "examples/example-base/test-base.h"
+#include "source/core/slang-string-util.h"
using Slang::ComPtr;
static const ExampleResources resourceBase("hello-world");
-struct HelloWorldExample
+struct HelloWorldExample : public TestBase
{
// The Vulkan functions pointers result from loading the vulkan library.
VulkanAPI vkAPI;
@@ -66,10 +68,11 @@ struct HelloWorldExample
};
-int main()
+int main(int argc, char* argv[])
{
initDebugCallback();
HelloWorldExample example;
+ example.parseOption(argc, argv);
return example.run();
}
@@ -204,6 +207,11 @@ int HelloWorldExample::createComputePipelineFromShader()
0, 0, spirvCode.writeRef(), diagnosticsBlob.writeRef());
diagnoseIfNeeded(diagnosticsBlob);
RETURN_ON_FAIL(result);
+
+ if (isTestMode())
+ {
+ printEntrypointHashes(1, 1, composedProgram);
+ }
}
// The following steps are all Vulkan API calls to create a pipeline.
diff --git a/examples/triangle/main.cpp b/examples/triangle/main.cpp
index 93ae1bd2e..88c55c416 100644
--- a/examples/triangle/main.cpp
+++ b/examples/triangle/main.cpp
@@ -187,6 +187,11 @@ gfx::Result loadShaderProgram(
programDesc.slangGlobalScope = linkedProgram;
SLANG_RETURN_ON_FAIL(device->createProgram(programDesc, outProgram));
+ if (isTestMode())
+ {
+ printEntrypointHashes(entryPointCount, 1, linkedProgram);
+ }
+
return SLANG_OK;
}
@@ -387,9 +392,12 @@ virtual void renderFrame(int frameBufferIndex) override
commandBuffer->close();
gQueue->executeCommandBuffer(commandBuffer);
- // With that, we are done drawing for one frame, and ready for the next.
- //
- gSwapchain->present();
+ if (!isTestMode())
+ {
+ // With that, we are done drawing for one frame, and ready for the next.
+ //
+ gSwapchain->present();
+ }
}
};
diff --git a/source/slang-record-replay/record/slang-composite-component-type.cpp b/source/slang-record-replay/record/slang-composite-component-type.cpp
index e3c339adb..29ac5da8d 100644
--- a/source/slang-record-replay/record/slang-composite-component-type.cpp
+++ b/source/slang-record-replay/record/slang-composite-component-type.cpp
@@ -15,11 +15,6 @@ namespace SlangRecord
slangRecordLog(LogLevel::Verbose, "%s: %p\n", __PRETTY_FUNCTION__, componentType);
}
- CompositeComponentTypeRecorder::~CompositeComponentTypeRecorder()
- {
- m_actualCompositeComponentType->release();
- }
-
ISlangUnknown* CompositeComponentTypeRecorder::getInterface(const Guid& guid)
{
if (guid == IComponentType::getTypeGuid())
@@ -65,7 +60,7 @@ namespace SlangRecord
slang::ProgramLayout* programLayout = m_actualCompositeComponentType->getLayout(targetIndex, outDiagnostics);
{
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
recorder->recordAddress(programLayout);
m_recordManager->apendOutput();
}
@@ -101,7 +96,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outCode);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
@@ -126,7 +121,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outCode);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
@@ -201,7 +196,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outSpecializedComponentType);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
@@ -224,7 +219,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outLinkedComponentType);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
@@ -251,7 +246,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outSharedLibrary);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
@@ -300,7 +295,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outLinkedComponentType);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
diff --git a/source/slang-record-replay/record/slang-composite-component-type.h b/source/slang-record-replay/record/slang-composite-component-type.h
index 758a59434..2374bcda2 100644
--- a/source/slang-record-replay/record/slang-composite-component-type.h
+++ b/source/slang-record-replay/record/slang-composite-component-type.h
@@ -19,7 +19,6 @@ namespace SlangRecord
ISlangUnknown* getInterface(const Guid& guid);
explicit CompositeComponentTypeRecorder(slang::IComponentType* componentType, RecordManager* recordManager);
- ~CompositeComponentTypeRecorder();
// Interfaces for `IComponentType`
virtual SLANG_NO_THROW slang::ISession* SLANG_MCALL getSession() override;
diff --git a/source/slang-record-replay/record/slang-entrypoint.cpp b/source/slang-record-replay/record/slang-entrypoint.cpp
index e5c76a5af..7d43700e2 100644
--- a/source/slang-record-replay/record/slang-entrypoint.cpp
+++ b/source/slang-record-replay/record/slang-entrypoint.cpp
@@ -14,11 +14,6 @@ namespace SlangRecord
slangRecordLog(LogLevel::Verbose, "%s: %p\n", __PRETTY_FUNCTION__, entryPoint);
}
- EntryPointRecorder::~EntryPointRecorder()
- {
- m_actualEntryPoint->release();
- }
-
ISlangUnknown* EntryPointRecorder::getInterface(const Guid& guid)
{
if(guid == EntryPointRecorder::getTypeGuid())
@@ -63,7 +58,7 @@ namespace SlangRecord
slang::ProgramLayout* programLayout = m_actualEntryPoint->getLayout(targetIndex, outDiagnostics);
{
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
recorder->recordAddress(programLayout);
m_recordManager->apendOutput();
}
@@ -99,7 +94,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outCode);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
@@ -124,7 +119,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outCode);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
@@ -199,7 +194,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outSpecializedComponentType);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
@@ -222,7 +217,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outLinkedComponentType);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
@@ -249,7 +244,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outSharedLibrary);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
@@ -298,7 +293,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outLinkedComponentType);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
diff --git a/source/slang-record-replay/record/slang-entrypoint.h b/source/slang-record-replay/record/slang-entrypoint.h
index 17c6fab6f..60c1bf369 100644
--- a/source/slang-record-replay/record/slang-entrypoint.h
+++ b/source/slang-record-replay/record/slang-entrypoint.h
@@ -21,7 +21,6 @@ namespace SlangRecord
ISlangUnknown* getInterface(const Guid& guid);
explicit EntryPointRecorder(slang::IEntryPoint* entryPoint, RecordManager* recordManager);
- ~EntryPointRecorder();
// Interfaces for `IComponentType`
virtual SLANG_NO_THROW slang::ISession* SLANG_MCALL getSession() override;
diff --git a/source/slang-record-replay/record/slang-filesystem.cpp b/source/slang-record-replay/record/slang-filesystem.cpp
index 310fecd78..87a7182fc 100644
--- a/source/slang-record-replay/record/slang-filesystem.cpp
+++ b/source/slang-record-replay/record/slang-filesystem.cpp
@@ -18,11 +18,6 @@ namespace SlangRecord
slangRecordLog(LogLevel::Verbose, "%s: %p\n", __PRETTY_FUNCTION__, m_actualFileSystem.get());
}
- FileSystemRecorder::~FileSystemRecorder()
- {
- m_actualFileSystem->release();
- }
-
void* FileSystemRecorder::castAs(const Slang::Guid& guid)
{
return getInterface(guid);
diff --git a/source/slang-record-replay/record/slang-filesystem.h b/source/slang-record-replay/record/slang-filesystem.h
index ff7004fa1..6f73e479c 100644
--- a/source/slang-record-replay/record/slang-filesystem.h
+++ b/source/slang-record-replay/record/slang-filesystem.h
@@ -18,7 +18,6 @@ namespace SlangRecord
{
public:
explicit FileSystemRecorder(ISlangFileSystemExt* fileSystem, RecordManager* recordManager);
- ~FileSystemRecorder();
// ISlangUnknown
SLANG_REF_OBJECT_IUNKNOWN_ALL
diff --git a/source/slang-record-replay/record/slang-global-session.cpp b/source/slang-record-replay/record/slang-global-session.cpp
index f8fe6c65b..c5350f760 100644
--- a/source/slang-record-replay/record/slang-global-session.cpp
+++ b/source/slang-record-replay/record/slang-global-session.cpp
@@ -29,11 +29,6 @@ namespace SlangRecord
m_recordManager->apendOutput();
}
- GlobalSessionRecorder::~GlobalSessionRecorder()
- {
- m_actualGlobalSession->release();
- }
-
SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionRecorder::queryInterface(SlangUUID const& uuid, void** outObject)
{
if (uuid == Session::getTypeGuid())
diff --git a/source/slang-record-replay/record/slang-global-session.h b/source/slang-record-replay/record/slang-global-session.h
index 3fd584ef4..4242f4bff 100644
--- a/source/slang-record-replay/record/slang-global-session.h
+++ b/source/slang-record-replay/record/slang-global-session.h
@@ -15,7 +15,6 @@ namespace SlangRecord
{
public:
explicit GlobalSessionRecorder(slang::IGlobalSession* session);
- virtual ~GlobalSessionRecorder();
SLANG_REF_OBJECT_IUNKNOWN_ADD_REF
SLANG_REF_OBJECT_IUNKNOWN_RELEASE
diff --git a/source/slang-record-replay/record/slang-module.cpp b/source/slang-record-replay/record/slang-module.cpp
index 42dcd9eea..b116fa99b 100644
--- a/source/slang-record-replay/record/slang-module.cpp
+++ b/source/slang-record-replay/record/slang-module.cpp
@@ -14,11 +14,6 @@ namespace SlangRecord
slangRecordLog(LogLevel::Verbose, "%s: %p\n", __PRETTY_FUNCTION__, module);
}
- ModuleRecorder::~ModuleRecorder()
- {
- m_actualModule->release();
- }
-
ISlangUnknown* ModuleRecorder::getInterface(const Guid& guid)
{
if(guid == ModuleRecorder::getTypeGuid())
@@ -185,7 +180,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outEntryPoint);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
@@ -249,7 +244,7 @@ namespace SlangRecord
slang::ProgramLayout* programLayout = m_actualModule->getLayout(targetIndex, outDiagnostics);
{
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
recorder->recordAddress(programLayout);
m_recordManager->apendOutput();
}
@@ -285,7 +280,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outCode);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
@@ -310,7 +305,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outCode);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
@@ -386,7 +381,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outSpecializedComponentType);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
@@ -409,7 +404,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outLinkedComponentType);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
@@ -436,7 +431,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outSharedLibrary);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
@@ -485,7 +480,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outLinkedComponentType);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
diff --git a/source/slang-record-replay/record/slang-module.h b/source/slang-record-replay/record/slang-module.h
index 22339f1cd..1b1cc5de9 100644
--- a/source/slang-record-replay/record/slang-module.h
+++ b/source/slang-record-replay/record/slang-module.h
@@ -21,7 +21,6 @@ namespace SlangRecord
ISlangUnknown* getInterface(const Guid& guid);
explicit ModuleRecorder(slang::IModule* module, RecordManager* recordManager);
- ~ModuleRecorder();
// Interfaces for `IModule`
virtual SLANG_NO_THROW SlangResult SLANG_MCALL findEntryPointByName(
diff --git a/source/slang-record-replay/record/slang-session.cpp b/source/slang-record-replay/record/slang-session.cpp
index 7c0ccd2e1..3eb944082 100644
--- a/source/slang-record-replay/record/slang-session.cpp
+++ b/source/slang-record-replay/record/slang-session.cpp
@@ -17,11 +17,6 @@ namespace SlangRecord
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())
@@ -54,7 +49,7 @@ namespace SlangRecord
slang::IModule* pModule = m_actualSession->loadModule(moduleName, outDiagnostics);
{
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
recorder->recordAddress(pModule);
m_recordManager->apendOutput();
}
@@ -83,7 +78,7 @@ namespace SlangRecord
slang::IModule* pModule = m_actualSession->loadModuleFromIRBlob(moduleName, path, source, outDiagnostics);
{
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
recorder->recordAddress(pModule);
m_recordManager->apendOutput();
}
@@ -112,7 +107,7 @@ namespace SlangRecord
slang::IModule* pModule = m_actualSession->loadModuleFromSource(moduleName, path, source, outDiagnostics);
{
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
recorder->recordAddress(pModule);
m_recordManager->apendOutput();
}
@@ -142,7 +137,7 @@ namespace SlangRecord
{
// TODO: Not sure if we need to record the diagnostics blob.
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
recorder->recordAddress(pModule);
m_recordManager->apendOutput();
}
@@ -179,7 +174,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outCompositeComponentType);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
@@ -213,7 +208,7 @@ namespace SlangRecord
slang::TypeReflection* pTypeReflection = m_actualSession->specializeType(type, specializationArgs, specializationArgCount, outDiagnostics);
{
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
recorder->recordAddress(pTypeReflection);
m_recordManager->apendOutput();
}
@@ -241,7 +236,7 @@ namespace SlangRecord
slang::TypeLayoutReflection* pTypeLayoutReflection = m_actualSession->getTypeLayout(type, targetIndex, rules, outDiagnostics);
{
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
recorder->recordAddress(pTypeLayoutReflection);
m_recordManager->apendOutput();
}
@@ -267,7 +262,7 @@ namespace SlangRecord
slang::TypeReflection* pTypeReflection = m_actualSession->getContainerType(elementType, containerType, outDiagnostics);
{
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
recorder->recordAddress(pTypeReflection);
m_recordManager->apendOutput();
}
@@ -386,7 +381,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outConformance);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
diff --git a/source/slang-record-replay/record/slang-session.h b/source/slang-record-replay/record/slang-session.h
index ca06e25a0..bc56003a9 100644
--- a/source/slang-record-replay/record/slang-session.h
+++ b/source/slang-record-replay/record/slang-session.h
@@ -20,7 +20,6 @@ namespace SlangRecord
ISlangUnknown* getInterface(const Guid& guid);
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(
diff --git a/source/slang-record-replay/record/slang-type-conformance.cpp b/source/slang-record-replay/record/slang-type-conformance.cpp
index 91f108786..56433f700 100644
--- a/source/slang-record-replay/record/slang-type-conformance.cpp
+++ b/source/slang-record-replay/record/slang-type-conformance.cpp
@@ -14,11 +14,6 @@ namespace SlangRecord
slangRecordLog(LogLevel::Verbose, "%s: %p\n", __PRETTY_FUNCTION__, typeConformance);
}
- TypeConformanceRecorder::~TypeConformanceRecorder()
- {
- m_actualTypeConformance->release();
- }
-
ISlangUnknown* TypeConformanceRecorder::getInterface(const Guid& guid)
{
if (guid == TypeConformanceRecorder::getTypeGuid())
@@ -67,7 +62,7 @@ namespace SlangRecord
slang::ProgramLayout* programLayout = m_actualTypeConformance->getLayout(targetIndex, outDiagnostics);
{
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
recorder->recordAddress(programLayout);
m_recordManager->apendOutput();
}
@@ -102,7 +97,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outCode);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
@@ -127,7 +122,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outCode);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
@@ -202,7 +197,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outSpecializedComponentType);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
@@ -225,7 +220,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outLinkedComponentType);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
@@ -252,7 +247,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outSharedLibrary);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
@@ -301,7 +296,7 @@ namespace SlangRecord
{
recorder->recordAddress(*outLinkedComponentType);
- recorder->recordAddress(*outDiagnostics);
+ recorder->recordAddress(outDiagnostics ? *outDiagnostics : nullptr);
m_recordManager->apendOutput();
}
diff --git a/source/slang-record-replay/record/slang-type-conformance.h b/source/slang-record-replay/record/slang-type-conformance.h
index 7bcae0d15..7beabcca5 100644
--- a/source/slang-record-replay/record/slang-type-conformance.h
+++ b/source/slang-record-replay/record/slang-type-conformance.h
@@ -21,7 +21,6 @@ namespace SlangRecord
ISlangUnknown* getInterface(const Guid& guid);
explicit TypeConformanceRecorder(slang::ITypeConformance* typeConformance, RecordManager* recordManager);
- ~TypeConformanceRecorder();
// Interfaces for `IComponentType`
virtual SLANG_NO_THROW slang::ISession* SLANG_MCALL getSession() override;
diff --git a/source/slang-record-replay/replay/json-consumer.cpp b/source/slang-record-replay/replay/json-consumer.cpp
index 0faf5267b..456988bdb 100644
--- a/source/slang-record-replay/replay/json-consumer.cpp
+++ b/source/slang-record-replay/replay/json-consumer.cpp
@@ -448,7 +448,7 @@ namespace SlangRecord
_writePair(builder, indent, "name", Slang::StringUtil::makeStringWithFormat("\"%s\"",
desc.preprocessorMacros[i].name != nullptr ? desc.preprocessorMacros[i].name : "nullptr"));
- _writePair(builder, indent, "value", Slang::StringUtil::makeStringWithFormat("\"%s\"",
+ _writePairNoComma(builder, indent, "value", Slang::StringUtil::makeStringWithFormat("\"%s\"",
desc.preprocessorMacros[i].value != nullptr ? desc.preprocessorMacros[i].value : "nullptr"));
}
}
diff --git a/source/slang-record-replay/replay/replay-consumer.cpp b/source/slang-record-replay/replay/replay-consumer.cpp
index cb1117bc0..7710b50e9 100644
--- a/source/slang-record-replay/replay/replay-consumer.cpp
+++ b/source/slang-record-replay/replay/replay-consumer.cpp
@@ -106,7 +106,6 @@ namespace SlangRecord
SlangResult CommonInterfaceReplayer::getEntryPointHash(ObjectID objectId, SlangInt entryPointIndex, SlangInt targetIndex, ObjectID outHashId)
{
InputObjectSanityCheck(objectId);
- OutputObjectSanityCheck(outHashId);
SlangResult res = SLANG_OK;
slang::IComponentType* pObj = getObjectPointer(objectId);
@@ -115,16 +114,17 @@ namespace SlangRecord
if (outHash)
{
- m_objectMap.add(outHashId, outHash);
if (outHash->getBufferSize())
{
uint8_t* buffer = (uint8_t*)outHash->getBufferPointer();
Slang::StringBuilder strBuilder;
+ strBuilder << "entrypoint: "<< entryPointIndex << ", target: " << targetIndex << ", hash: ";
+
for (size_t i = 0; i < outHash->getBufferSize(); i++)
{
- strBuilder<<Slang::StringUtil::makeStringWithFormat("%.2X ", buffer[i]);
+ strBuilder<<Slang::StringUtil::makeStringWithFormat("%.2X", buffer[i]);
}
- slangRecordLog(LogLevel::Verbose, "getEntryPointHash: %s\n", strBuilder.begin());
+ slangRecordLog(LogLevel::Verbose, "%s\n", strBuilder.begin());
}
else
{
diff --git a/test-record-replay.sh b/test-record-replay.sh
new file mode 100755
index 000000000..2faabe954
--- /dev/null
+++ b/test-record-replay.sh
@@ -0,0 +1,147 @@
+#!/usr/bin/env bash
+
+RED='\033[0;31m'
+Green='\033[0;32m'
+NC='\033[0m'
+matchPattern="entrypoint: [0-9]+, target: [0-9]+, hash: [0-9a-fA-F]+"
+
+getHash()
+{
+ matchedLine=$1
+ local -n outputVar=$2
+
+ entrypointIdx=$(echo $matchedLine | grep -oE "entrypoint: [0-9]+" | grep -oE "[0-9]+")
+ targetIdx=$(echo $matchedLine | grep -oE "target: [0-9]+" | grep -oE "[0-9]+")
+ hashCode=$(echo $matchedLine | grep -oE "hash: .*" | grep -oE ": [0-9a-fA-F]+" | grep -oE "[0-9a-fA-F]+")
+
+ outputVar="$entrypointIdx-$targetIdx-$hashCode"
+}
+
+log()
+{
+ msg=$1
+ color=$2
+ printf "${color}$1${NC}\n"
+}
+
+parseStandardOutput()
+{
+ local -n resultArray=$1
+ lines=$2
+
+ for line in "${lines[@]}"
+ do
+ matchLine=$(echo $line | grep -oE "$matchPattern")
+
+ if [ -n "$matchLine" ]; then
+ result=""
+ getHash "$matchLine" result
+
+ if [ -n "$result" ]; then
+ resultArray+=("$result")
+ fi
+ fi
+ done
+}
+
+resultCheck()
+{
+ local -n inExpectedResults=$1
+ local -n inReplayResults=$2
+ local -n outFailedResults=$3
+
+ found=""
+ for expectedResult in ${inExpectedResults[@]}; do
+
+ for replayResult in ${inReplayResults[@]}; do
+ if [ "$replayResult" == "$expectedResult" ]; then
+ found="1"
+ fi
+ done
+
+ if [ -z "$found" ]; then
+ echo "$expectedResult is not Found in replay"
+ outFailedResults+=("$expectedResult")
+ else
+ echo "$expectedResult is Found in replay"
+ fi
+ done
+}
+
+# TODO: Add more test commands here in this array
+testCommands=("./build/Debug/bin/hello-world" "./build/Debug/bin/triangle")
+
+# Enable hash code generation for the test such that
+# we can have something to compare with replaying the test
+argsToEnableHashCode="--test-mode"
+
+declare -A testStats
+
+for ((i = 0; i < ${#testCommands[@]}; i++))
+do
+ testCommand=${testCommands[$i]}
+ echo "Start running test: $testCommand"
+
+ # Run the test executable
+ export SLANG_RECORD_LAYER=1
+ mapfile -t lines < <(${testCommand} ${argsToEnableHashCode})
+ unset SLANG_RECORD_LAYER
+
+ # parse the output from stdout
+ expectedResults=()
+ parseStandardOutput expectedResults "${lines[@]}"
+
+ echo "Expected Results: ${expectedResults[@]}"
+ if [ ${#expectedResults[@]} -eq 0 ]; then
+ log "No expected results found" $RED
+ rm -rf ./slang-record/*
+ continue
+ fi
+
+ # Replay the record file
+ export SLANG_RECORD_LOG_LEVEL=3
+ replayTestCommand="./build/Debug/bin/slang-replay ./slang-record/*.cap"
+ echo "Start replaying the test ..."
+ mapfile -t lines < <(${replayTestCommand})
+ unset SLANG_RECORD_LOG_LEVEL
+
+ # parse the output from stdout
+ replayResults=()
+ parseStandardOutput replayResults "${lines[@]}"
+
+ echo "Replay Results: ${replayResults[@]}"
+ if [ ${#replayResults[@]} -eq 0 ]; then
+ log "No replay results found" $RED
+ rm -rf ./slang-record/*
+ continue
+ fi
+
+ # Check the results
+ failedResults=()
+ resultCheck expectedResults replayResults failedResults
+
+ rm -rf ./slang-record/*
+
+ if [ ${#failedResults[@]} -eq 0 ]; then
+ testStats[$testCommand]="PASSED"
+ else
+ testStats[$testCommand]="FAILED"
+ fi
+ printf "\n"
+done
+
+for testName in "${!testStats[@]}"
+do
+ if [ "${testStats[$testName]}" == "PASSED" ]; then
+ log "$testName: PASSED" $Green
+ else
+ log "$testName: FAILED" $RED
+ fi
+done
+
+# Notify the CI if any of the tests failed
+if [ ${#testStats[@]} -eq 0 ]; then
+ exit 0
+else
+ exit 1
+fi
diff --git a/tools/platform/window.h b/tools/platform/window.h
index efbe139a7..29327def3 100644
--- a/tools/platform/window.h
+++ b/tools/platform/window.h
@@ -242,7 +242,7 @@ public:
int /*showCommand*/) \
{ \
platform::Application::init(); \
- auto result = APPLICATION_ENTRY(); \
+ auto result = APPLICATION_ENTRY(0, nullptr); \
platform::Application::dispose(); \
GFX_DUMP_LEAK \
return result; \
@@ -251,10 +251,10 @@ public:
#else
#define PLATFORM_UI_MAIN(APPLICATION_ENTRY) \
- int main() \
+ int main(int argc, char** argv) \
{ \
platform::Application::init(); \
- auto rs = APPLICATION_ENTRY(); \
+ auto rs = APPLICATION_ENTRY(argc, argv); \
platform::Application::dispose(); \
return rs; \
}