summaryrefslogtreecommitdiffstats
path: root/tools/render-test
diff options
context:
space:
mode:
Diffstat (limited to 'tools/render-test')
-rw-r--r--tools/render-test/cpu-memory-binding.cpp2
-rw-r--r--tools/render-test/render-test-main.cpp377
-rw-r--r--tools/render-test/render-test-tool.vcxproj3
-rw-r--r--tools/render-test/render-test-tool.vcxproj.filters9
-rw-r--r--tools/render-test/window.cpp21
-rw-r--r--tools/render-test/window.h45
-rw-r--r--tools/render-test/windows/win-window.cpp185
7 files changed, 381 insertions, 261 deletions
diff --git a/tools/render-test/cpu-memory-binding.cpp b/tools/render-test/cpu-memory-binding.cpp
index c2d853aa8..3bf1f1bbd 100644
--- a/tools/render-test/cpu-memory-binding.cpp
+++ b/tools/render-test/cpu-memory-binding.cpp
@@ -91,7 +91,7 @@ SlangResult CPUMemoryBinding::init(slang::ShaderReflection* reflection, int entr
}
{
- auto entryPointCount = reflection->getEntryPointCount();
+ auto entryPointCount = int(reflection->getEntryPointCount());
if (entryPointIndex < 0 || entryPointIndex >= entryPointCount)
{
SLANG_ASSERT(!"Entry point index out of range");
diff --git a/tools/render-test/render-test-main.cpp b/tools/render-test/render-test-main.cpp
index 5b9621142..d2ef2a746 100644
--- a/tools/render-test/render-test-main.cpp
+++ b/tools/render-test/render-test-main.cpp
@@ -1,11 +1,9 @@
// render-test-main.cpp
+#define _CRT_SECURE_NO_WARNINGS 1
+
#include "options.h"
#include "render.h"
-#include "render-d3d11.h"
-#include "render-d3d12.h"
-#include "render-gl.h"
-#include "render-vk.h"
#include "slang-support.h"
#include "surface.h"
@@ -21,20 +19,12 @@
#include <stdio.h>
#include <stdlib.h>
+#include "window.h"
+
#include "../../source/core/slang-test-tool-util.h"
#include "cpu-compute-util.h"
-#define WIN32_LEAN_AND_MEAN
-#define NOMINMAX
-#include <Windows.h>
-#undef WIN32_LEAN_AND_MEAN
-#undef NOMINMAX
-
-#ifdef _MSC_VER
-#pragma warning(disable: 4996)
-#endif
-
namespace renderer_test {
using Slang::Result;
@@ -42,141 +32,6 @@ using Slang::Result;
int gWindowWidth = 1024;
int gWindowHeight = 768;
-class Window: public RefObject
-{
-public:
- SlangResult initialize(int width, int height);
-
- void show();
-
- void* getHandle() const { return m_hwnd; }
-
- Window() {}
- ~Window();
-
- static LRESULT CALLBACK windowProc(HWND windowHandle,
- UINT message,
- WPARAM wParam,
- LPARAM lParam);
-
-protected:
-
- HINSTANCE m_hinst = nullptr;
- HWND m_hwnd = nullptr;
-};
-
-//
-// We use a bare-minimum window procedure to get things up and running.
-//
-
-/* static */LRESULT CALLBACK Window::windowProc(
- HWND windowHandle,
- UINT message,
- WPARAM wParam,
- LPARAM lParam)
-{
- switch (message)
- {
- case WM_CLOSE:
- PostQuitMessage(0);
- return 0;
- }
-
- return DefWindowProcW(windowHandle, message, wParam, lParam);
-}
-
-static ATOM _getWindowClassAtom(HINSTANCE hinst)
-{
- static ATOM s_windowClassAtom;
-
- if (s_windowClassAtom)
- {
- return s_windowClassAtom;
- }
- WNDCLASSEXW windowClassDesc;
- windowClassDesc.cbSize = sizeof(windowClassDesc);
- windowClassDesc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
- windowClassDesc.lpfnWndProc = &Window::windowProc;
- windowClassDesc.cbClsExtra = 0;
- windowClassDesc.cbWndExtra = 0;
- windowClassDesc.hInstance = hinst;
- windowClassDesc.hIcon = 0;
- windowClassDesc.hCursor = 0;
- windowClassDesc.hbrBackground = 0;
- windowClassDesc.lpszMenuName = 0;
- windowClassDesc.lpszClassName = L"SlangRenderTest";
- windowClassDesc.hIconSm = 0;
- s_windowClassAtom = RegisterClassExW(&windowClassDesc);
-
- return s_windowClassAtom;
-}
-
-SlangResult Window::initialize(int widthIn, int heightIn)
-{
- // Do initial window-creation stuff here, rather than in the renderer-specific files
-
- m_hinst = GetModuleHandleA(0);
-
- // First we register a window class.
- ATOM windowClassAtom = _getWindowClassAtom(m_hinst);
- if (!windowClassAtom)
- {
- fprintf(stderr, "error: failed to register window class\n");
- return SLANG_FAIL;
- }
-
- // Next, we create a window using that window class.
-
- // We will create a borderless window since our screen-capture logic in GL
- // seems to get thrown off by having to deal with a window frame.
- DWORD windowStyle = WS_POPUP;
- DWORD windowExtendedStyle = 0;
-
- RECT windowRect = { 0, 0, widthIn, heightIn };
- AdjustWindowRectEx(&windowRect, windowStyle, /*hasMenu=*/false, windowExtendedStyle);
-
- {
- auto width = windowRect.right - windowRect.left;
- auto height = windowRect.bottom - windowRect.top;
-
- LPWSTR windowName = L"Slang Render Test";
- m_hwnd = CreateWindowExW(
- windowExtendedStyle,
- (LPWSTR)windowClassAtom,
- windowName,
- windowStyle,
- 0, 0, // x, y
- width, height,
- NULL, // parent
- NULL, // menu
- m_hinst,
- NULL);
- }
- if (!m_hwnd)
- {
- fprintf(stderr, "error: failed to create window\n");
- return SLANG_FAIL;
- }
-
- return SLANG_OK;
-}
-
-
-void Window::show()
-{
- // Once initialization is all complete, we show the window...
- int showCommand = SW_SHOW;
- ShowWindow(m_hwnd, showCommand);
-}
-
-Window::~Window()
-{
- if (m_hwnd)
- {
- DestroyWindow(m_hwnd);
- }
-}
-
//
// For the purposes of a small example, we will define the vertex data for a
// single triangle directly in the source file. It should be easy to extend
@@ -200,16 +55,19 @@ static const int kVertexCount = SLANG_COUNT_OF(kVertexData);
using namespace Slang;
-class RenderTestApp
+class RenderTestApp : public WindowListener
{
public:
- // At initialization time, we are going to load and compile our Slang shader
- // code, and then create the API objects we need for rendering.
- Result initialize(SlangSession* session, Renderer* renderer, Options::ShaderProgramType shaderType, const ShaderCompilerUtil::Input& input);
- void runCompute();
- void renderFrame();
- void finalize();
+ // WindowListener
+ virtual Result update(Window* window) SLANG_OVERRIDE;
+
+ // At initialization time, we are going to load and compile our Slang shader
+ // code, and then create the API objects we need for rendering.
+ Result initialize(SlangSession* session, Renderer* renderer, const Options& options, const ShaderCompilerUtil::Input& input);
+ void runCompute();
+ void renderFrame();
+ void finalize();
BindingStateImpl* getBindingState() const { return m_bindingState; }
@@ -235,11 +93,15 @@ class RenderTestApp
ShaderInputLayout m_shaderInputLayout; ///< The binding layout
int m_numAddedConstantBuffers; ///< Constant buffers can be added to the binding directly. Will be added at the end.
+
+ Options m_options;
};
-SlangResult RenderTestApp::initialize(SlangSession* session, Renderer* renderer, Options::ShaderProgramType shaderType, const ShaderCompilerUtil::Input& input)
+SlangResult RenderTestApp::initialize(SlangSession* session, Renderer* renderer, const Options& options, const ShaderCompilerUtil::Input& input)
{
- SLANG_RETURN_ON_FAIL(_initializeShaders(session, renderer, shaderType, input));
+ m_options = options;
+
+ SLANG_RETURN_ON_FAIL(_initializeShaders(session, renderer, options.shaderType, input));
m_numAddedConstantBuffers = 0;
m_renderer = renderer;
@@ -260,7 +122,7 @@ SlangResult RenderTestApp::initialize(SlangSession* session, Renderer* renderer,
// TODO: Should probably be more sophisticated than this - with 'dynamic' constant buffer/s binding always being specified
// in the test file
RefPtr<BufferResource> addedConstantBuffer;
- switch(shaderType)
+ switch(m_options.shaderType)
{
default:
break;
@@ -298,7 +160,7 @@ SlangResult RenderTestApp::initialize(SlangSession* session, Renderer* renderer,
return SLANG_FAIL;
{
- switch(shaderType)
+ switch(m_options.shaderType)
{
default:
assert(!"unexpected test shader type");
@@ -435,6 +297,52 @@ Result RenderTestApp::writeScreen(const char* filename)
return PngSerializeUtil::write(filename, surface);
}
+Result RenderTestApp::update(Window* window)
+{
+ // Whenever we don't have Windows events to process, we render a frame.
+ if (m_options.shaderType == Options::ShaderProgramType::Compute)
+ {
+ runCompute();
+ }
+ else
+ {
+ static const float kClearColor[] = { 0.25, 0.25, 0.25, 1.0 };
+ m_renderer->setClearColor(kClearColor);
+ m_renderer->clearFrame();
+
+ renderFrame();
+ }
+
+ // If we are in a mode where output is requested, we need to snapshot the back buffer here
+ if (m_options.outputPath)
+ {
+ // Submit the work
+ m_renderer->submitGpuWork();
+ // Wait until everything is complete
+ m_renderer->waitForGpu();
+
+ if (gOptions.shaderType == Options::ShaderProgramType::Compute || gOptions.shaderType == Options::ShaderProgramType::GraphicsCompute)
+ {
+ SLANG_RETURN_ON_FAIL(writeBindingOutput(gOptions.outputPath));
+ }
+ else
+ {
+ SlangResult res = writeScreen(gOptions.outputPath);
+ if (SLANG_FAILED(res))
+ {
+ fprintf(stderr, "ERROR: failed to write screen capture to file\n");
+ return res;
+ }
+ }
+ // We are done
+ window->postQuit();
+ return SLANG_OK;
+ }
+
+ m_renderer->presentFrame();
+ return SLANG_OK;
+}
+
} // namespace renderer_test
SLANG_TEST_TOOL_API SlangResult innerMain(Slang::StdWriters* stdWriters, SlangSession* session, int argcIn, const char*const* argvIn)
@@ -449,8 +357,6 @@ SLANG_TEST_TOOL_API SlangResult innerMain(Slang::StdWriters* stdWriters, SlangSe
// Declare window pointer before renderer, such that window is released after renderer
RefPtr<renderer_test::Window> window;
- // Renderer is constructed (later) using the window
- Slang::RefPtr<Renderer> renderer;
ShaderCompilerUtil::Input input;
@@ -465,7 +371,6 @@ SLANG_TEST_TOOL_API SlangResult innerMain(Slang::StdWriters* stdWriters, SlangSe
switch (gOptions.rendererType)
{
case RendererType::DirectX11:
- renderer = createD3D11Renderer();
input.target = SLANG_DXBC;
input.profile = "sm_5_0";
nativeLanguage = SLANG_SOURCE_LANGUAGE_HLSL;
@@ -474,7 +379,6 @@ SLANG_TEST_TOOL_API SlangResult innerMain(Slang::StdWriters* stdWriters, SlangSe
break;
case RendererType::DirectX12:
- renderer = createD3D12Renderer();
input.target = SLANG_DXBC;
input.profile = "sm_5_0";
nativeLanguage = SLANG_SOURCE_LANGUAGE_HLSL;
@@ -489,7 +393,6 @@ SLANG_TEST_TOOL_API SlangResult innerMain(Slang::StdWriters* stdWriters, SlangSe
break;
case RendererType::OpenGl:
- renderer = createGLRenderer();
input.target = SLANG_GLSL;
input.profile = "glsl_430";
nativeLanguage = SLANG_SOURCE_LANGUAGE_GLSL;
@@ -497,7 +400,6 @@ SLANG_TEST_TOOL_API SlangResult innerMain(Slang::StdWriters* stdWriters, SlangSe
break;
case RendererType::Vulkan:
- renderer = createVKRenderer();
input.target = SLANG_SPIRV;
input.profile = "glsl_430";
nativeLanguage = SLANG_SOURCE_LANGUAGE_GLSL;
@@ -540,18 +442,59 @@ SLANG_TEST_TOOL_API SlangResult innerMain(Slang::StdWriters* stdWriters, SlangSe
rendererName << "'" << gOptions.adapter << "'";
}
-
- if (renderer)
+ // If it's CPU testing we don't need a window or a renderer
+ if (gOptions.rendererType == RendererType::CPU)
{
+ if (gOptions.onlyStartup)
+ {
+ // Need generic C/C++
+ if (SLANG_FAILED(spSessionCheckPassThroughSupport(session, SLANG_PASS_THROUGH_GENERIC_C_CPP)))
+ {
+ return SLANG_FAIL;
+ }
+ // Should work ...
+ return SLANG_OK;
+ }
+
+ ShaderCompilerUtil::OutputAndLayout compilationAndLayout;
+ SLANG_RETURN_ON_FAIL(ShaderCompilerUtil::compileWithLayout(session, gOptions.sourcePath, gOptions.shaderType, input, compilationAndLayout));
+
+ CPUComputeUtil::Context context;
+ SLANG_RETURN_ON_FAIL(CPUComputeUtil::calcBindings(compilationAndLayout, context));
+ SLANG_RETURN_ON_FAIL(CPUComputeUtil::execute(compilationAndLayout, context));
+
+ // Dump everything out that was written
+ return CPUComputeUtil::writeBindings(compilationAndLayout.layout, context.buffers, gOptions.outputPath);
+ }
+
+ // Renderer is constructed (later) using the window
+ Slang::RefPtr<Renderer> renderer;
+
+ {
+ RendererUtil::CreateFunc createFunc = RendererUtil::getCreateFunc(gOptions.rendererType);
+ if (createFunc)
+ {
+ renderer = createFunc();
+ }
+
+ if (!renderer)
+ {
+ if (!gOptions.onlyStartup)
+ {
+ fprintf(stderr, "Unable to create renderer %s\n", rendererName.getBuffer());
+ }
+ return SLANG_FAIL;
+ }
+
Renderer::Desc desc;
desc.width = gWindowWidth;
desc.height = gWindowHeight;
desc.adapter = gOptions.adapter;
- window = new renderer_test::Window;
+ window = renderer_test::Window::create();
SLANG_RETURN_ON_FAIL(window->initialize(gWindowWidth, gWindowHeight));
- SlangResult res = renderer->initialize(desc, (HWND)window->getHandle());
+ SlangResult res = renderer->initialize(desc, window->getHandle());
if (SLANG_FAILED(res))
{
if (!gOptions.onlyStartup)
@@ -570,105 +513,19 @@ SLANG_TEST_TOOL_API SlangResult innerMain(Slang::StdWriters* stdWriters, SlangSe
}
}
}
- else
- {
- if (gOptions.rendererType != RendererType::CPU)
- {
- if (!gOptions.onlyStartup)
- {
- fprintf(stderr, "Unable to create renderer %s\n", rendererName.getBuffer());
- }
- return SLANG_FAIL;
- }
- }
-
+
// If the only test is we can startup, then we are done
if (gOptions.onlyStartup)
{
return SLANG_OK;
}
- if (!renderer)
- {
- ShaderCompilerUtil::OutputAndLayout compilationAndLayout;
- SLANG_RETURN_ON_FAIL(ShaderCompilerUtil::compileWithLayout(session, gOptions.sourcePath, gOptions.shaderType, input, compilationAndLayout));
-
- CPUComputeUtil::Context context;
- SLANG_RETURN_ON_FAIL(CPUComputeUtil::calcBindings(compilationAndLayout, context));
- SLANG_RETURN_ON_FAIL(CPUComputeUtil::execute(compilationAndLayout, context));
-
- // Dump everything out that was written
- return CPUComputeUtil::writeBindings(compilationAndLayout.layout, context.buffers, gOptions.outputPath);
- }
-
{
- RenderTestApp app;
- SLANG_RETURN_ON_FAIL(app.initialize(session, renderer, gOptions.shaderType, input));
-
+ RefPtr<RenderTestApp> app(new RenderTestApp);
+ SLANG_RETURN_ON_FAIL(app->initialize(session, renderer, gOptions, input));
window->show();
-
- // ... and enter the event loop:
- for (;;)
- {
- MSG message;
-
- int result = PeekMessageW(&message, NULL, 0, 0, PM_REMOVE);
- if (result != 0)
- {
- if (message.message == WM_QUIT)
- {
- return (int)message.wParam;
- }
-
- TranslateMessage(&message);
- DispatchMessageW(&message);
- }
- else
- {
- // Whenever we don't have Windows events to process, we render a frame.
- if (gOptions.shaderType == Options::ShaderProgramType::Compute)
- {
- app.runCompute();
- }
- else
- {
- static const float kClearColor[] = { 0.25, 0.25, 0.25, 1.0 };
- renderer->setClearColor(kClearColor);
- renderer->clearFrame();
-
- app.renderFrame();
- }
- // If we are in a mode where output is requested, we need to snapshot the back buffer here
- if (gOptions.outputPath)
- {
- // Submit the work
- renderer->submitGpuWork();
- // Wait until everything is complete
- renderer->waitForGpu();
-
- if (gOptions.shaderType == Options::ShaderProgramType::Compute || gOptions.shaderType == Options::ShaderProgramType::GraphicsCompute)
- {
- SLANG_RETURN_ON_FAIL(app.writeBindingOutput(gOptions.outputPath));
- }
- else
- {
- SlangResult res = app.writeScreen(gOptions.outputPath);
-
- if (SLANG_FAILED(res))
- {
- fprintf(stderr, "ERROR: failed to write screen capture to file\n");
- return res;
- }
- }
- return SLANG_OK;
- }
-
- renderer->presentFrame();
- }
- }
+ return window->runLoop(app);
}
-
- return SLANG_OK;
}
int main(int argc, char** argv)
diff --git a/tools/render-test/render-test-tool.vcxproj b/tools/render-test/render-test-tool.vcxproj
index 3e0c0ae56..3cc813300 100644
--- a/tools/render-test/render-test-tool.vcxproj
+++ b/tools/render-test/render-test-tool.vcxproj
@@ -186,6 +186,7 @@
<ClInclude Include="shader-input-layout.h" />
<ClInclude Include="shader-renderer-util.h" />
<ClInclude Include="slang-support.h" />
+ <ClInclude Include="window.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="cpu-compute-util.cpp" />
@@ -196,6 +197,8 @@
<ClCompile Include="shader-input-layout.cpp" />
<ClCompile Include="shader-renderer-util.cpp" />
<ClCompile Include="slang-support.cpp" />
+ <ClCompile Include="window.cpp" />
+ <ClCompile Include="windows\win-window.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\source\core\core.vcxproj">
diff --git a/tools/render-test/render-test-tool.vcxproj.filters b/tools/render-test/render-test-tool.vcxproj.filters
index 769d53aed..7091fce6b 100644
--- a/tools/render-test/render-test-tool.vcxproj.filters
+++ b/tools/render-test/render-test-tool.vcxproj.filters
@@ -30,6 +30,9 @@
<ClInclude Include="slang-support.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="window.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="cpu-compute-util.cpp">
@@ -56,5 +59,11 @@
<ClCompile Include="slang-support.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="window.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="windows\win-window.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
</Project> \ No newline at end of file
diff --git a/tools/render-test/window.cpp b/tools/render-test/window.cpp
new file mode 100644
index 000000000..0ab4ff412
--- /dev/null
+++ b/tools/render-test/window.cpp
@@ -0,0 +1,21 @@
+// window.cpp
+
+#include "window.h"
+
+namespace renderer_test {
+using namespace Slang;
+
+#if SLANG_WINDOWS_FAMILY
+extern Window* createWinWindow();
+#endif
+
+/* static */Window* Window::create()
+{
+#if SLANG_WINDOWS_FAMILY
+ return createWinWindow();
+#else
+ return nullptr;
+#endif
+}
+
+} // renderer_test
diff --git a/tools/render-test/window.h b/tools/render-test/window.h
new file mode 100644
index 000000000..e647a602c
--- /dev/null
+++ b/tools/render-test/window.h
@@ -0,0 +1,45 @@
+// window.h
+#pragma once
+
+#include <slang.h>
+#include "../../source/core/slang-smart-pointer.h"
+
+namespace renderer_test {
+
+class Window;
+
+class WindowListener : public Slang::RefObject
+{
+public:
+ virtual SlangResult update(Window* window) = 0;
+};
+
+class Window : public Slang::RefObject
+{
+public:
+ virtual SlangResult initialize(int width, int height) = 0;
+
+ virtual void show() = 0;
+ virtual void* getHandle() const = 0;
+ virtual void postQuit() { m_isQuitting = true; }
+
+ /// Run the event loop. Events will be sent to the WindowListener
+ virtual SlangResult runLoop(WindowListener* listener) = 0;
+
+ bool isQuitting() const { return m_isQuitting; }
+ int getQuitValue() const { return m_quitValue; }
+
+ static Window* create();
+
+ virtual ~Window() {}
+
+protected:
+ Window() {}
+
+ bool m_isQuitting = false;
+ int m_quitValue = 0;
+};
+
+Window* createWindow();
+
+} // renderer_test
diff --git a/tools/render-test/windows/win-window.cpp b/tools/render-test/windows/win-window.cpp
new file mode 100644
index 000000000..7f45f9789
--- /dev/null
+++ b/tools/render-test/windows/win-window.cpp
@@ -0,0 +1,185 @@
+// win-window.cpp
+
+#define _CRT_SECURE_NO_WARNINGS 1
+
+#include <slang.h>
+#include <slang-com-helper.h>
+
+#include "../window.h"
+
+#define WIN32_LEAN_AND_MEAN
+#define NOMINMAX
+#include <Windows.h>
+#undef WIN32_LEAN_AND_MEAN
+#undef NOMINMAX
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4996)
+#endif
+
+#include <stdio.h>
+
+namespace renderer_test {
+
+class WinWindow : public Window
+{
+public:
+ virtual SlangResult initialize(int width, int height) SLANG_OVERRIDE;
+
+ virtual void show() SLANG_OVERRIDE;
+ virtual void* getHandle() const SLANG_OVERRIDE { return m_hwnd; }
+ virtual SlangResult runLoop(WindowListener* listener) SLANG_OVERRIDE;
+
+ virtual ~WinWindow();
+
+ static LRESULT CALLBACK windowProc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam);
+
+protected:
+
+ HINSTANCE m_hinst = nullptr;
+ HWND m_hwnd = nullptr;
+};
+
+//
+// We use a bare-minimum window procedure to get things up and running.
+//
+
+/* static */LRESULT CALLBACK WinWindow::windowProc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_CLOSE:
+ PostQuitMessage(0);
+ return 0;
+ }
+ return DefWindowProcW(windowHandle, message, wParam, lParam);
+}
+
+static ATOM _getWindowClassAtom(HINSTANCE hinst)
+{
+ static ATOM s_windowClassAtom;
+
+ if (s_windowClassAtom)
+ {
+ return s_windowClassAtom;
+ }
+ WNDCLASSEXW windowClassDesc;
+ windowClassDesc.cbSize = sizeof(windowClassDesc);
+ windowClassDesc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
+ windowClassDesc.lpfnWndProc = &WinWindow::windowProc;
+ windowClassDesc.cbClsExtra = 0;
+ windowClassDesc.cbWndExtra = 0;
+ windowClassDesc.hInstance = hinst;
+ windowClassDesc.hIcon = 0;
+ windowClassDesc.hCursor = 0;
+ windowClassDesc.hbrBackground = 0;
+ windowClassDesc.lpszMenuName = 0;
+ windowClassDesc.lpszClassName = L"SlangRenderTest";
+ windowClassDesc.hIconSm = 0;
+ s_windowClassAtom = RegisterClassExW(&windowClassDesc);
+
+ return s_windowClassAtom;
+}
+
+SlangResult WinWindow::initialize(int widthIn, int heightIn)
+{
+ // Do initial window-creation stuff here, rather than in the renderer-specific files
+
+ m_hinst = GetModuleHandleA(0);
+
+ // First we register a window class.
+ ATOM windowClassAtom = _getWindowClassAtom(m_hinst);
+ if (!windowClassAtom)
+ {
+ fprintf(stderr, "error: failed to register window class\n");
+ return SLANG_FAIL;
+ }
+
+ // Next, we create a window using that window class.
+
+ // We will create a borderless window since our screen-capture logic in GL
+ // seems to get thrown off by having to deal with a window frame.
+ DWORD windowStyle = WS_POPUP;
+ DWORD windowExtendedStyle = 0;
+
+ RECT windowRect = { 0, 0, widthIn, heightIn };
+ AdjustWindowRectEx(&windowRect, windowStyle, /*hasMenu=*/false, windowExtendedStyle);
+
+ {
+ auto width = windowRect.right - windowRect.left;
+ auto height = windowRect.bottom - windowRect.top;
+
+ LPWSTR windowName = L"Slang Render Test";
+ m_hwnd = CreateWindowExW(
+ windowExtendedStyle,
+ (LPWSTR)windowClassAtom,
+ windowName,
+ windowStyle,
+ 0, 0, // x, y
+ width, height,
+ NULL, // parent
+ NULL, // menu
+ m_hinst,
+ NULL);
+ }
+ if (!m_hwnd)
+ {
+ fprintf(stderr, "error: failed to create window\n");
+ return SLANG_FAIL;
+ }
+
+ return SLANG_OK;
+}
+
+
+void WinWindow::show()
+{
+ // Once initialization is all complete, we show the window...
+ int showCommand = SW_SHOW;
+ ShowWindow(m_hwnd, showCommand);
+}
+
+SlangResult WinWindow::runLoop(WindowListener* listener)
+{
+ // ... and enter the event loop:
+ while (!m_isQuitting)
+ {
+ MSG message;
+ int result = PeekMessageW(&message, NULL, 0, 0, PM_REMOVE);
+ if (result != 0)
+ {
+ if (message.message == WM_QUIT)
+ {
+ m_quitValue = (int)message.wParam;
+ return SLANG_OK;
+ }
+
+ TranslateMessage(&message);
+ DispatchMessageW(&message);
+ }
+ else
+ {
+ if (listener)
+ {
+ SLANG_RETURN_ON_FAIL(listener->update(this));
+ }
+ }
+ }
+
+ return SLANG_OK;
+}
+
+WinWindow::~WinWindow()
+{
+ if (m_hwnd)
+ {
+ DestroyWindow(m_hwnd);
+ }
+}
+
+Window* createWinWindow()
+{
+ return new WinWindow;
+}
+
+} // namespace renderer_test