diff options
Diffstat (limited to 'examples/example-base')
| -rw-r--r-- | examples/example-base/example-base.cpp | 120 | ||||
| -rw-r--r-- | examples/example-base/example-base.h | 21 | ||||
| -rw-r--r-- | examples/example-base/test-base.cpp | 50 | ||||
| -rw-r--r-- | examples/example-base/test-base.h | 21 |
4 files changed, 170 insertions, 42 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; +}; |
