diff --git a/Samples/D3D1211On12/src/D3D1211On12.cpp b/Samples/D3D1211On12/src/D3D1211On12.cpp index 3c4ab5e5b..0409a01cb 100644 --- a/Samples/D3D1211On12/src/D3D1211On12.cpp +++ b/Samples/D3D1211On12/src/D3D1211On12.cpp @@ -40,7 +40,7 @@ void D3D1211on12::LoadPipeline() { UINT d3d11DeviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; D2D1_FACTORY_OPTIONS d2dFactoryOptions = {}; -#ifdef _DEBUG +#if defined(_DEBUG) // Enable the D2D debug layer. d2dFactoryOptions.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION; @@ -98,7 +98,7 @@ void D3D1211on12::LoadPipeline() swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - swapChainDesc.OutputWindow = m_hwnd; + swapChainDesc.OutputWindow = Win32Application::GetHwnd(); swapChainDesc.SampleDesc.Count = 1; swapChainDesc.Windowed = TRUE; @@ -112,7 +112,7 @@ void D3D1211on12::LoadPipeline() ThrowIfFailed(swapChain.As(&m_swapChain)); // This sample does not support fullscreen transitions. - ThrowIfFailed(factory->MakeWindowAssociation(m_hwnd, DXGI_MWA_NO_ALT_ENTER)); + ThrowIfFailed(factory->MakeWindowAssociation(Win32Application::GetHwnd(), DXGI_MWA_NO_ALT_ENTER)); m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); @@ -230,7 +230,7 @@ void D3D1211on12::LoadAssets() ComPtr vertexShader; ComPtr pixelShader; -#ifdef _DEBUG +#if defined(_DEBUG) // Enable better shader debugging with the graphics debugging tools. UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else @@ -374,7 +374,7 @@ void D3D1211on12::OnRender() RenderUI(); // Present the frame. - ThrowIfFailed(m_swapChain->Present(0, 0)); + ThrowIfFailed(m_swapChain->Present(1, 0)); MoveToNextFrame(); } @@ -419,11 +419,6 @@ void D3D1211on12::OnDestroy() CloseHandle(m_fenceEvent); } -bool D3D1211on12::OnEvent(MSG) -{ - return false; -} - void D3D1211on12::PopulateCommandList() { // Command list allocators can only be reset when the associated diff --git a/Samples/D3D1211On12/src/D3D1211On12.h b/Samples/D3D1211On12/src/D3D1211On12.h index 497bc06b2..6b93b372d 100644 --- a/Samples/D3D1211On12/src/D3D1211On12.h +++ b/Samples/D3D1211On12/src/D3D1211On12.h @@ -21,12 +21,10 @@ class D3D1211on12 : public DXSample public: D3D1211on12(UINT width, UINT height, std::wstring name); -protected: virtual void OnInit(); virtual void OnUpdate(); virtual void OnRender(); virtual void OnDestroy(); - virtual bool OnEvent(MSG msg); private: static const UINT FrameCount = 3; diff --git a/Samples/D3D1211On12/src/D3D1211On12.vcxproj b/Samples/D3D1211On12/src/D3D1211On12.vcxproj index 1dfc41b01..e693bcbf3 100644 --- a/Samples/D3D1211On12/src/D3D1211On12.vcxproj +++ b/Samples/D3D1211On12/src/D3D1211On12.vcxproj @@ -96,6 +96,7 @@ + @@ -103,6 +104,7 @@ + diff --git a/Samples/D3D1211On12/src/D3D1211On12.vcxproj.filters b/Samples/D3D1211On12/src/D3D1211On12.vcxproj.filters index 502454ea8..4f384ce3b 100644 --- a/Samples/D3D1211On12/src/D3D1211On12.vcxproj.filters +++ b/Samples/D3D1211On12/src/D3D1211On12.vcxproj.filters @@ -44,6 +44,9 @@ Header Files + + Header Files\Util + @@ -58,5 +61,8 @@ Source Files + + Source Files\Util + \ No newline at end of file diff --git a/Samples/D3D1211On12/src/DXSample.cpp b/Samples/D3D1211On12/src/DXSample.cpp index 651f40eb7..663ef590a 100644 --- a/Samples/D3D1211On12/src/DXSample.cpp +++ b/Samples/D3D1211On12/src/DXSample.cpp @@ -11,17 +11,13 @@ #include "stdafx.h" #include "DXSample.h" -#include DXSample::DXSample(UINT width, UINT height, std::wstring name) : m_width(width), m_height(height), + m_title(name), m_useWarpDevice(false) { - ParseCommandLineArgs(); - - m_title = name + (m_useWarpDevice ? L" (WARP)" : L""); - WCHAR assetsPath[512]; GetAssetsPath(assetsPath, _countof(assetsPath)); m_assetsPath = assetsPath; @@ -33,67 +29,6 @@ DXSample::~DXSample() { } -int DXSample::Run(HINSTANCE hInstance, int nCmdShow) -{ - // Initialize the window class. - WNDCLASSEX windowClass = { 0 }; - windowClass.cbSize = sizeof(WNDCLASSEX); - windowClass.style = CS_HREDRAW | CS_VREDRAW; - windowClass.lpfnWndProc = WindowProc; - windowClass.hInstance = hInstance; - windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); - windowClass.lpszClassName = L"WindowClass1"; - RegisterClassEx(&windowClass); - - RECT windowRect = { 0, 0, static_cast(m_width), static_cast(m_height) }; - AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); - - // Create the window and store a handle to it. - m_hwnd = CreateWindowEx(NULL, - L"WindowClass1", - m_title.c_str(), - WS_OVERLAPPEDWINDOW, - 300, - 300, - windowRect.right - windowRect.left, - windowRect.bottom - windowRect.top, - NULL, // We have no parent window, NULL. - NULL, // We aren't using menus, NULL. - hInstance, - NULL); // We aren't using multiple windows, NULL. - - ShowWindow(m_hwnd, nCmdShow); - - // Initialize the sample. OnInit is defined in each child-implementation of DXSample. - OnInit(); - - // Main sample loop. - MSG msg = { 0 }; - while (true) - { - // Process any messages in the queue. - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (msg.message == WM_QUIT) - break; - - // Pass events into our sample. - OnEvent(msg); - } - - OnUpdate(); - OnRender(); - } - - OnDestroy(); - - // Return this part of the WM_QUIT message to Windows. - return static_cast(msg.wParam); -} - // Helper function for resolving the full path of assets. std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) { @@ -102,7 +37,8 @@ std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) // Helper function for acquiring the first available hardware adapter that supports Direct3D 12. // If no such adapter can be found, *ppAdapter will be set to nullptr. -void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter) +_Use_decl_annotations_ +void DXSample::GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter) { IDXGIAdapter1* pAdapter = nullptr; *ppAdapter = nullptr; @@ -134,36 +70,20 @@ void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_m void DXSample::SetCustomWindowText(LPCWSTR text) { std::wstring windowText = m_title + L": " + text; - SetWindowText(m_hwnd, windowText.c_str()); + SetWindowText(Win32Application::GetHwnd(), windowText.c_str()); } // Helper function for parsing any supplied command line args. -void DXSample::ParseCommandLineArgs() +_Use_decl_annotations_ +void DXSample::ParseCommandLineArgs(WCHAR* argv[], int argc) { - int argc; - LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc); for (int i = 1; i < argc; ++i) { if (_wcsnicmp(argv[i], L"-warp", wcslen(argv[i])) == 0 || _wcsnicmp(argv[i], L"/warp", wcslen(argv[i])) == 0) { m_useWarpDevice = true; + m_title = m_title + L" (WARP)"; } } - LocalFree(argv); -} - -// Main message handler for the sample. -LRESULT CALLBACK DXSample::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - // Handle destroy/shutdown messages. - switch (message) - { - case WM_DESTROY: - PostQuitMessage(0); - return 0; - } - - // Handle any messages the switch statement didn't. - return DefWindowProc(hWnd, message, wParam, lParam); } diff --git a/Samples/D3D1211On12/src/DXSample.h b/Samples/D3D1211On12/src/DXSample.h index 39915ee91..5b417c3b2 100644 --- a/Samples/D3D1211On12/src/DXSample.h +++ b/Samples/D3D1211On12/src/DXSample.h @@ -12,6 +12,7 @@ #pragma once #include "DXSampleHelper.h" +#include "Win32Application.h" class DXSample { @@ -19,35 +20,36 @@ class DXSample DXSample(UINT width, UINT height, std::wstring name); virtual ~DXSample(); - int Run(HINSTANCE hInstance, int nCmdShow); - void SetCustomWindowText(LPCWSTR text); - -protected: virtual void OnInit() = 0; virtual void OnUpdate() = 0; virtual void OnRender() = 0; virtual void OnDestroy() = 0; - virtual bool OnEvent(MSG msg) = 0; - std::wstring GetAssetFullPath(LPCWSTR assetName); - void GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + // Samples override the event handlers to handle specific messages. + virtual void OnKeyDown(UINT8 /*key*/) {} + virtual void OnKeyUp(UINT8 /*key*/) {} + + // Accessors. + UINT GetWidth() const { return m_width; } + UINT GetHeight() const { return m_height; } + const WCHAR* GetTitle() const { return m_title.c_str(); } - static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + void ParseCommandLineArgs(_In_reads_(argc) WCHAR* argv[], int argc); + +protected: + std::wstring GetAssetFullPath(LPCWSTR assetName); + void GetHardwareAdapter(_In_ IDXGIFactory2* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + void SetCustomWindowText(LPCWSTR text); // Viewport dimensions. UINT m_width; UINT m_height; float m_aspectRatio; - // Window handle. - HWND m_hwnd; - // Adapter info. bool m_useWarpDevice; private: - void ParseCommandLineArgs(); - // Root assets path. std::wstring m_assetsPath; diff --git a/Samples/D3D1211On12/src/Main.cpp b/Samples/D3D1211On12/src/Main.cpp index 2d28440e7..9266b3af6 100644 --- a/Samples/D3D1211On12/src/Main.cpp +++ b/Samples/D3D1211On12/src/Main.cpp @@ -16,5 +16,5 @@ _Use_decl_annotations_ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) { D3D1211on12 sample(1280, 720, L"D3D12 11 on 12 Sample"); - return sample.Run(hInstance, nCmdShow); + return Win32Application::Run(&sample, hInstance, nCmdShow); } diff --git a/Samples/D3D1211On12/src/Win32Application.cpp b/Samples/D3D1211On12/src/Win32Application.cpp new file mode 100644 index 000000000..9b4a24d55 --- /dev/null +++ b/Samples/D3D1211On12/src/Win32Application.cpp @@ -0,0 +1,119 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#include "stdafx.h" +#include "Win32Application.h" + +HWND Win32Application::m_hwnd = nullptr; + +int Win32Application::Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow) +{ + // Parse the command line parameters + int argc; + LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc); + pSample->ParseCommandLineArgs(argv, argc); + LocalFree(argv); + + // Initialize the window class. + WNDCLASSEX windowClass = { 0 }; + windowClass.cbSize = sizeof(WNDCLASSEX); + windowClass.style = CS_HREDRAW | CS_VREDRAW; + windowClass.lpfnWndProc = WindowProc; + windowClass.hInstance = hInstance; + windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); + windowClass.lpszClassName = L"DXSampleClass"; + RegisterClassEx(&windowClass); + + RECT windowRect = { 0, 0, static_cast(pSample->GetWidth()), static_cast(pSample->GetHeight()) }; + AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); + + // Create the window and store a handle to it. + m_hwnd = CreateWindow( + windowClass.lpszClassName, + pSample->GetTitle(), + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + windowRect.right - windowRect.left, + windowRect.bottom - windowRect.top, + nullptr, // We have no parent window. + nullptr, // We aren't using menus. + hInstance, + pSample); + + // Initialize the sample. OnInit is defined in each child-implementation of DXSample. + pSample->OnInit(); + + ShowWindow(m_hwnd, nCmdShow); + + // Main sample loop. + MSG msg = {}; + while (msg.message != WM_QUIT) + { + // Process any messages in the queue. + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + pSample->OnDestroy(); + + // Return this part of the WM_QUIT message to Windows. + return static_cast(msg.wParam); +} + +// Main message handler for the sample. +LRESULT CALLBACK Win32Application::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + DXSample* pSample = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); + + switch (message) + { + case WM_CREATE: + { + // Save the DXSample* passed in to CreateWindow. + LPCREATESTRUCT pCreateStruct = reinterpret_cast(lParam); + SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(pCreateStruct->lpCreateParams)); + } + return 0; + + case WM_KEYDOWN: + if (pSample) + { + pSample->OnKeyDown(static_cast(wParam)); + } + return 0; + + case WM_KEYUP: + if (pSample) + { + pSample->OnKeyUp(static_cast(wParam)); + } + return 0; + + case WM_PAINT: + if (pSample) + { + pSample->OnUpdate(); + pSample->OnRender(); + } + return 0; + + case WM_DESTROY: + PostQuitMessage(0); + return 0; + } + + // Handle any messages the switch statement didn't. + return DefWindowProc(hWnd, message, wParam, lParam); +} diff --git a/Samples/D3D1211On12/src/Win32Application.h b/Samples/D3D1211On12/src/Win32Application.h new file mode 100644 index 000000000..8d2299164 --- /dev/null +++ b/Samples/D3D1211On12/src/Win32Application.h @@ -0,0 +1,29 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#pragma once + +#include "DXSample.h" + +class DXSample; + +class Win32Application +{ +public: + static int Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow); + static HWND GetHwnd() { return m_hwnd; } + +protected: + static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + +private: + static HWND m_hwnd; +}; diff --git a/Samples/D3D1211On12/src/stdafx.h b/Samples/D3D1211On12/src/stdafx.h index 2f055eb84..5f3165d74 100644 --- a/Samples/D3D1211On12/src/stdafx.h +++ b/Samples/D3D1211On12/src/stdafx.h @@ -32,3 +32,4 @@ #include #include +#include diff --git a/Samples/D3D12Bundles/src/D3D12Bundles.cpp b/Samples/D3D12Bundles/src/D3D12Bundles.cpp index 39b20e723..8ff7d4771 100644 --- a/Samples/D3D12Bundles/src/D3D12Bundles.cpp +++ b/Samples/D3D12Bundles/src/D3D12Bundles.cpp @@ -43,7 +43,7 @@ void D3D12Bundles::OnInit() // Load the rendering pipeline dependencies. void D3D12Bundles::LoadPipeline() { -#ifdef _DEBUG +#if defined(_DEBUG) // Enable the D3D12 debug layer. { ComPtr debugController; @@ -95,7 +95,7 @@ void D3D12Bundles::LoadPipeline() swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - swapChainDesc.OutputWindow = m_hwnd; + swapChainDesc.OutputWindow = Win32Application::GetHwnd(); swapChainDesc.SampleDesc.Count = 1; swapChainDesc.Windowed = TRUE; @@ -109,7 +109,7 @@ void D3D12Bundles::LoadPipeline() ThrowIfFailed(swapChain.As(&m_swapChain)); // This sample does not support fullscreen transitions. - ThrowIfFailed(factory->MakeWindowAssociation(m_hwnd, DXGI_MWA_NO_ALT_ENTER)); + ThrowIfFailed(factory->MakeWindowAssociation(Win32Application::GetHwnd(), DXGI_MWA_NO_ALT_ENTER)); m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); @@ -485,7 +485,7 @@ void D3D12Bundles::OnRender() m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); // Present and update the frame index for the next frame. - ThrowIfFailed(m_swapChain->Present(0, 0)); + ThrowIfFailed(m_swapChain->Present(1, 0)); m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); // Signal and increment the fence value. @@ -519,20 +519,14 @@ void D3D12Bundles::OnDestroy() } } -bool D3D12Bundles::OnEvent(MSG msg) +void D3D12Bundles::OnKeyDown(UINT8 key) { - switch (msg.message) - { - case WM_KEYDOWN: - m_camera.OnKeyDown(msg.wParam); - break; - - case WM_KEYUP: - m_camera.OnKeyUp(msg.wParam); - break; - } + m_camera.OnKeyDown(key); +} - return false; +void D3D12Bundles::OnKeyUp(UINT8 key) +{ + m_camera.OnKeyUp(key); } // Create the resources that will be used every frame. diff --git a/Samples/D3D12Bundles/src/D3D12Bundles.h b/Samples/D3D12Bundles/src/D3D12Bundles.h index c4c263dea..abe6efc90 100644 --- a/Samples/D3D12Bundles/src/D3D12Bundles.h +++ b/Samples/D3D12Bundles/src/D3D12Bundles.h @@ -25,12 +25,12 @@ class D3D12Bundles : public DXSample public: D3D12Bundles(UINT width, UINT height, std::wstring name); -protected: virtual void OnInit(); virtual void OnUpdate(); virtual void OnRender(); virtual void OnDestroy(); - virtual bool OnEvent(MSG msg); + virtual void OnKeyDown(UINT8 key); + virtual void OnKeyUp(UINT8 key); private: static const UINT FrameCount = 3; diff --git a/Samples/D3D12Bundles/src/D3D12Bundles.vcxproj b/Samples/D3D12Bundles/src/D3D12Bundles.vcxproj index f87297a2a..40d62dbd9 100644 --- a/Samples/D3D12Bundles/src/D3D12Bundles.vcxproj +++ b/Samples/D3D12Bundles/src/D3D12Bundles.vcxproj @@ -103,6 +103,7 @@ + @@ -114,6 +115,7 @@ + diff --git a/Samples/D3D12Bundles/src/D3D12Bundles.vcxproj.filters b/Samples/D3D12Bundles/src/D3D12Bundles.vcxproj.filters index 4d00d0ed0..e84d6b8e9 100644 --- a/Samples/D3D12Bundles/src/D3D12Bundles.vcxproj.filters +++ b/Samples/D3D12Bundles/src/D3D12Bundles.vcxproj.filters @@ -51,6 +51,9 @@ Header Files + + Header Files\Util + @@ -71,6 +74,9 @@ Source Files\Util + + Source Files\Util + diff --git a/Samples/D3D12Bundles/src/DXSample.cpp b/Samples/D3D12Bundles/src/DXSample.cpp index 651f40eb7..663ef590a 100644 --- a/Samples/D3D12Bundles/src/DXSample.cpp +++ b/Samples/D3D12Bundles/src/DXSample.cpp @@ -11,17 +11,13 @@ #include "stdafx.h" #include "DXSample.h" -#include DXSample::DXSample(UINT width, UINT height, std::wstring name) : m_width(width), m_height(height), + m_title(name), m_useWarpDevice(false) { - ParseCommandLineArgs(); - - m_title = name + (m_useWarpDevice ? L" (WARP)" : L""); - WCHAR assetsPath[512]; GetAssetsPath(assetsPath, _countof(assetsPath)); m_assetsPath = assetsPath; @@ -33,67 +29,6 @@ DXSample::~DXSample() { } -int DXSample::Run(HINSTANCE hInstance, int nCmdShow) -{ - // Initialize the window class. - WNDCLASSEX windowClass = { 0 }; - windowClass.cbSize = sizeof(WNDCLASSEX); - windowClass.style = CS_HREDRAW | CS_VREDRAW; - windowClass.lpfnWndProc = WindowProc; - windowClass.hInstance = hInstance; - windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); - windowClass.lpszClassName = L"WindowClass1"; - RegisterClassEx(&windowClass); - - RECT windowRect = { 0, 0, static_cast(m_width), static_cast(m_height) }; - AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); - - // Create the window and store a handle to it. - m_hwnd = CreateWindowEx(NULL, - L"WindowClass1", - m_title.c_str(), - WS_OVERLAPPEDWINDOW, - 300, - 300, - windowRect.right - windowRect.left, - windowRect.bottom - windowRect.top, - NULL, // We have no parent window, NULL. - NULL, // We aren't using menus, NULL. - hInstance, - NULL); // We aren't using multiple windows, NULL. - - ShowWindow(m_hwnd, nCmdShow); - - // Initialize the sample. OnInit is defined in each child-implementation of DXSample. - OnInit(); - - // Main sample loop. - MSG msg = { 0 }; - while (true) - { - // Process any messages in the queue. - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (msg.message == WM_QUIT) - break; - - // Pass events into our sample. - OnEvent(msg); - } - - OnUpdate(); - OnRender(); - } - - OnDestroy(); - - // Return this part of the WM_QUIT message to Windows. - return static_cast(msg.wParam); -} - // Helper function for resolving the full path of assets. std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) { @@ -102,7 +37,8 @@ std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) // Helper function for acquiring the first available hardware adapter that supports Direct3D 12. // If no such adapter can be found, *ppAdapter will be set to nullptr. -void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter) +_Use_decl_annotations_ +void DXSample::GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter) { IDXGIAdapter1* pAdapter = nullptr; *ppAdapter = nullptr; @@ -134,36 +70,20 @@ void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_m void DXSample::SetCustomWindowText(LPCWSTR text) { std::wstring windowText = m_title + L": " + text; - SetWindowText(m_hwnd, windowText.c_str()); + SetWindowText(Win32Application::GetHwnd(), windowText.c_str()); } // Helper function for parsing any supplied command line args. -void DXSample::ParseCommandLineArgs() +_Use_decl_annotations_ +void DXSample::ParseCommandLineArgs(WCHAR* argv[], int argc) { - int argc; - LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc); for (int i = 1; i < argc; ++i) { if (_wcsnicmp(argv[i], L"-warp", wcslen(argv[i])) == 0 || _wcsnicmp(argv[i], L"/warp", wcslen(argv[i])) == 0) { m_useWarpDevice = true; + m_title = m_title + L" (WARP)"; } } - LocalFree(argv); -} - -// Main message handler for the sample. -LRESULT CALLBACK DXSample::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - // Handle destroy/shutdown messages. - switch (message) - { - case WM_DESTROY: - PostQuitMessage(0); - return 0; - } - - // Handle any messages the switch statement didn't. - return DefWindowProc(hWnd, message, wParam, lParam); } diff --git a/Samples/D3D12Bundles/src/DXSample.h b/Samples/D3D12Bundles/src/DXSample.h index 39915ee91..5b417c3b2 100644 --- a/Samples/D3D12Bundles/src/DXSample.h +++ b/Samples/D3D12Bundles/src/DXSample.h @@ -12,6 +12,7 @@ #pragma once #include "DXSampleHelper.h" +#include "Win32Application.h" class DXSample { @@ -19,35 +20,36 @@ class DXSample DXSample(UINT width, UINT height, std::wstring name); virtual ~DXSample(); - int Run(HINSTANCE hInstance, int nCmdShow); - void SetCustomWindowText(LPCWSTR text); - -protected: virtual void OnInit() = 0; virtual void OnUpdate() = 0; virtual void OnRender() = 0; virtual void OnDestroy() = 0; - virtual bool OnEvent(MSG msg) = 0; - std::wstring GetAssetFullPath(LPCWSTR assetName); - void GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + // Samples override the event handlers to handle specific messages. + virtual void OnKeyDown(UINT8 /*key*/) {} + virtual void OnKeyUp(UINT8 /*key*/) {} + + // Accessors. + UINT GetWidth() const { return m_width; } + UINT GetHeight() const { return m_height; } + const WCHAR* GetTitle() const { return m_title.c_str(); } - static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + void ParseCommandLineArgs(_In_reads_(argc) WCHAR* argv[], int argc); + +protected: + std::wstring GetAssetFullPath(LPCWSTR assetName); + void GetHardwareAdapter(_In_ IDXGIFactory2* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + void SetCustomWindowText(LPCWSTR text); // Viewport dimensions. UINT m_width; UINT m_height; float m_aspectRatio; - // Window handle. - HWND m_hwnd; - // Adapter info. bool m_useWarpDevice; private: - void ParseCommandLineArgs(); - // Root assets path. std::wstring m_assetsPath; diff --git a/Samples/D3D12Bundles/src/Main.cpp b/Samples/D3D12Bundles/src/Main.cpp index 86b72def0..cb0b88f00 100644 --- a/Samples/D3D12Bundles/src/Main.cpp +++ b/Samples/D3D12Bundles/src/Main.cpp @@ -15,6 +15,6 @@ _Use_decl_annotations_ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) { - D3D12Bundles sample(1280, 720, L"D3D12 Bundles"); - return sample.Run(hInstance, nCmdShow); + D3D12Bundles sample(1280, 720, L"D3D12 Bundles Sample"); + return Win32Application::Run(&sample, hInstance, nCmdShow); } diff --git a/Samples/D3D12Bundles/src/Win32Application.cpp b/Samples/D3D12Bundles/src/Win32Application.cpp new file mode 100644 index 000000000..9b4a24d55 --- /dev/null +++ b/Samples/D3D12Bundles/src/Win32Application.cpp @@ -0,0 +1,119 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#include "stdafx.h" +#include "Win32Application.h" + +HWND Win32Application::m_hwnd = nullptr; + +int Win32Application::Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow) +{ + // Parse the command line parameters + int argc; + LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc); + pSample->ParseCommandLineArgs(argv, argc); + LocalFree(argv); + + // Initialize the window class. + WNDCLASSEX windowClass = { 0 }; + windowClass.cbSize = sizeof(WNDCLASSEX); + windowClass.style = CS_HREDRAW | CS_VREDRAW; + windowClass.lpfnWndProc = WindowProc; + windowClass.hInstance = hInstance; + windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); + windowClass.lpszClassName = L"DXSampleClass"; + RegisterClassEx(&windowClass); + + RECT windowRect = { 0, 0, static_cast(pSample->GetWidth()), static_cast(pSample->GetHeight()) }; + AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); + + // Create the window and store a handle to it. + m_hwnd = CreateWindow( + windowClass.lpszClassName, + pSample->GetTitle(), + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + windowRect.right - windowRect.left, + windowRect.bottom - windowRect.top, + nullptr, // We have no parent window. + nullptr, // We aren't using menus. + hInstance, + pSample); + + // Initialize the sample. OnInit is defined in each child-implementation of DXSample. + pSample->OnInit(); + + ShowWindow(m_hwnd, nCmdShow); + + // Main sample loop. + MSG msg = {}; + while (msg.message != WM_QUIT) + { + // Process any messages in the queue. + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + pSample->OnDestroy(); + + // Return this part of the WM_QUIT message to Windows. + return static_cast(msg.wParam); +} + +// Main message handler for the sample. +LRESULT CALLBACK Win32Application::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + DXSample* pSample = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); + + switch (message) + { + case WM_CREATE: + { + // Save the DXSample* passed in to CreateWindow. + LPCREATESTRUCT pCreateStruct = reinterpret_cast(lParam); + SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(pCreateStruct->lpCreateParams)); + } + return 0; + + case WM_KEYDOWN: + if (pSample) + { + pSample->OnKeyDown(static_cast(wParam)); + } + return 0; + + case WM_KEYUP: + if (pSample) + { + pSample->OnKeyUp(static_cast(wParam)); + } + return 0; + + case WM_PAINT: + if (pSample) + { + pSample->OnUpdate(); + pSample->OnRender(); + } + return 0; + + case WM_DESTROY: + PostQuitMessage(0); + return 0; + } + + // Handle any messages the switch statement didn't. + return DefWindowProc(hWnd, message, wParam, lParam); +} diff --git a/Samples/D3D12Bundles/src/Win32Application.h b/Samples/D3D12Bundles/src/Win32Application.h new file mode 100644 index 000000000..8d2299164 --- /dev/null +++ b/Samples/D3D12Bundles/src/Win32Application.h @@ -0,0 +1,29 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#pragma once + +#include "DXSample.h" + +class DXSample; + +class Win32Application +{ +public: + static int Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow); + static HWND GetHwnd() { return m_hwnd; } + +protected: + static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + +private: + static HWND m_hwnd; +}; diff --git a/Samples/D3D12Bundles/src/stdafx.h b/Samples/D3D12Bundles/src/stdafx.h index 51c95848c..dacde4bfc 100644 --- a/Samples/D3D12Bundles/src/stdafx.h +++ b/Samples/D3D12Bundles/src/stdafx.h @@ -31,3 +31,4 @@ #include #include #include +#include diff --git a/Samples/D3D12DynamicIndexing/src/D3D12DynamicIndexing.cpp b/Samples/D3D12DynamicIndexing/src/D3D12DynamicIndexing.cpp index 7466f0b28..83b55ae0b 100644 --- a/Samples/D3D12DynamicIndexing/src/D3D12DynamicIndexing.cpp +++ b/Samples/D3D12DynamicIndexing/src/D3D12DynamicIndexing.cpp @@ -47,7 +47,7 @@ void D3D12DynamicIndexing::OnInit() // Load the rendering pipeline dependencies. void D3D12DynamicIndexing::LoadPipeline() { -#ifdef _DEBUG +#if defined(_DEBUG) // Enable the D3D12 debug layer. { ComPtr debugController; @@ -99,7 +99,7 @@ void D3D12DynamicIndexing::LoadPipeline() swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - swapChainDesc.OutputWindow = m_hwnd; + swapChainDesc.OutputWindow = Win32Application::GetHwnd(); swapChainDesc.SampleDesc.Count = 1; swapChainDesc.Windowed = TRUE; @@ -113,7 +113,7 @@ void D3D12DynamicIndexing::LoadPipeline() ThrowIfFailed(swapChain.As(&m_swapChain)); // This sample does not support fullscreen transitions. - ThrowIfFailed(factory->MakeWindowAssociation(m_hwnd, DXGI_MWA_NO_ALT_ENTER)); + ThrowIfFailed(factory->MakeWindowAssociation(Win32Application::GetHwnd(), DXGI_MWA_NO_ALT_ENTER)); m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); @@ -583,7 +583,7 @@ void D3D12DynamicIndexing::OnRender() m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); // Present and update the frame index for the next frame. - ThrowIfFailed(m_swapChain->Present(0, 0)); + ThrowIfFailed(m_swapChain->Present(1, 0)); m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); // Signal and increment the fence value. @@ -617,20 +617,14 @@ void D3D12DynamicIndexing::OnDestroy() } } -bool D3D12DynamicIndexing::OnEvent(MSG msg) +void D3D12DynamicIndexing::OnKeyDown(UINT8 key) { - switch (msg.message) - { - case WM_KEYDOWN: - m_camera.OnKeyDown(msg.wParam); - break; - - case WM_KEYUP: - m_camera.OnKeyUp(msg.wParam); - break; - } + m_camera.OnKeyDown(key); +} - return false; +void D3D12DynamicIndexing::OnKeyUp(UINT8 key) +{ + m_camera.OnKeyUp(key); } // Create the resources that will be used every frame. diff --git a/Samples/D3D12DynamicIndexing/src/D3D12DynamicIndexing.h b/Samples/D3D12DynamicIndexing/src/D3D12DynamicIndexing.h index 2cd620950..58304cc62 100644 --- a/Samples/D3D12DynamicIndexing/src/D3D12DynamicIndexing.h +++ b/Samples/D3D12DynamicIndexing/src/D3D12DynamicIndexing.h @@ -25,12 +25,12 @@ class D3D12DynamicIndexing : public DXSample public: D3D12DynamicIndexing(UINT width, UINT height, std::wstring name); -protected: virtual void OnInit(); virtual void OnUpdate(); virtual void OnRender(); virtual void OnDestroy(); - virtual bool OnEvent(MSG msg); + virtual void OnKeyDown(UINT8 key); + virtual void OnKeyUp(UINT8 key); private: static const UINT FrameCount = 3; diff --git a/Samples/D3D12DynamicIndexing/src/D3D12DynamicIndexing.vcxproj b/Samples/D3D12DynamicIndexing/src/D3D12DynamicIndexing.vcxproj index 108012ed7..76fc77ea9 100644 --- a/Samples/D3D12DynamicIndexing/src/D3D12DynamicIndexing.vcxproj +++ b/Samples/D3D12DynamicIndexing/src/D3D12DynamicIndexing.vcxproj @@ -103,6 +103,7 @@ + @@ -114,6 +115,7 @@ + diff --git a/Samples/D3D12DynamicIndexing/src/D3D12DynamicIndexing.vcxproj.filters b/Samples/D3D12DynamicIndexing/src/D3D12DynamicIndexing.vcxproj.filters index 7caa9f0bf..1ed2a2b9f 100644 --- a/Samples/D3D12DynamicIndexing/src/D3D12DynamicIndexing.vcxproj.filters +++ b/Samples/D3D12DynamicIndexing/src/D3D12DynamicIndexing.vcxproj.filters @@ -51,6 +51,9 @@ Header Files + + Header Files\Util + @@ -71,6 +74,9 @@ Source Files\Util + + Source Files\Util + diff --git a/Samples/D3D12DynamicIndexing/src/DXSample.cpp b/Samples/D3D12DynamicIndexing/src/DXSample.cpp index 651f40eb7..663ef590a 100644 --- a/Samples/D3D12DynamicIndexing/src/DXSample.cpp +++ b/Samples/D3D12DynamicIndexing/src/DXSample.cpp @@ -11,17 +11,13 @@ #include "stdafx.h" #include "DXSample.h" -#include DXSample::DXSample(UINT width, UINT height, std::wstring name) : m_width(width), m_height(height), + m_title(name), m_useWarpDevice(false) { - ParseCommandLineArgs(); - - m_title = name + (m_useWarpDevice ? L" (WARP)" : L""); - WCHAR assetsPath[512]; GetAssetsPath(assetsPath, _countof(assetsPath)); m_assetsPath = assetsPath; @@ -33,67 +29,6 @@ DXSample::~DXSample() { } -int DXSample::Run(HINSTANCE hInstance, int nCmdShow) -{ - // Initialize the window class. - WNDCLASSEX windowClass = { 0 }; - windowClass.cbSize = sizeof(WNDCLASSEX); - windowClass.style = CS_HREDRAW | CS_VREDRAW; - windowClass.lpfnWndProc = WindowProc; - windowClass.hInstance = hInstance; - windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); - windowClass.lpszClassName = L"WindowClass1"; - RegisterClassEx(&windowClass); - - RECT windowRect = { 0, 0, static_cast(m_width), static_cast(m_height) }; - AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); - - // Create the window and store a handle to it. - m_hwnd = CreateWindowEx(NULL, - L"WindowClass1", - m_title.c_str(), - WS_OVERLAPPEDWINDOW, - 300, - 300, - windowRect.right - windowRect.left, - windowRect.bottom - windowRect.top, - NULL, // We have no parent window, NULL. - NULL, // We aren't using menus, NULL. - hInstance, - NULL); // We aren't using multiple windows, NULL. - - ShowWindow(m_hwnd, nCmdShow); - - // Initialize the sample. OnInit is defined in each child-implementation of DXSample. - OnInit(); - - // Main sample loop. - MSG msg = { 0 }; - while (true) - { - // Process any messages in the queue. - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (msg.message == WM_QUIT) - break; - - // Pass events into our sample. - OnEvent(msg); - } - - OnUpdate(); - OnRender(); - } - - OnDestroy(); - - // Return this part of the WM_QUIT message to Windows. - return static_cast(msg.wParam); -} - // Helper function for resolving the full path of assets. std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) { @@ -102,7 +37,8 @@ std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) // Helper function for acquiring the first available hardware adapter that supports Direct3D 12. // If no such adapter can be found, *ppAdapter will be set to nullptr. -void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter) +_Use_decl_annotations_ +void DXSample::GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter) { IDXGIAdapter1* pAdapter = nullptr; *ppAdapter = nullptr; @@ -134,36 +70,20 @@ void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_m void DXSample::SetCustomWindowText(LPCWSTR text) { std::wstring windowText = m_title + L": " + text; - SetWindowText(m_hwnd, windowText.c_str()); + SetWindowText(Win32Application::GetHwnd(), windowText.c_str()); } // Helper function for parsing any supplied command line args. -void DXSample::ParseCommandLineArgs() +_Use_decl_annotations_ +void DXSample::ParseCommandLineArgs(WCHAR* argv[], int argc) { - int argc; - LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc); for (int i = 1; i < argc; ++i) { if (_wcsnicmp(argv[i], L"-warp", wcslen(argv[i])) == 0 || _wcsnicmp(argv[i], L"/warp", wcslen(argv[i])) == 0) { m_useWarpDevice = true; + m_title = m_title + L" (WARP)"; } } - LocalFree(argv); -} - -// Main message handler for the sample. -LRESULT CALLBACK DXSample::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - // Handle destroy/shutdown messages. - switch (message) - { - case WM_DESTROY: - PostQuitMessage(0); - return 0; - } - - // Handle any messages the switch statement didn't. - return DefWindowProc(hWnd, message, wParam, lParam); } diff --git a/Samples/D3D12DynamicIndexing/src/DXSample.h b/Samples/D3D12DynamicIndexing/src/DXSample.h index 39915ee91..5b417c3b2 100644 --- a/Samples/D3D12DynamicIndexing/src/DXSample.h +++ b/Samples/D3D12DynamicIndexing/src/DXSample.h @@ -12,6 +12,7 @@ #pragma once #include "DXSampleHelper.h" +#include "Win32Application.h" class DXSample { @@ -19,35 +20,36 @@ class DXSample DXSample(UINT width, UINT height, std::wstring name); virtual ~DXSample(); - int Run(HINSTANCE hInstance, int nCmdShow); - void SetCustomWindowText(LPCWSTR text); - -protected: virtual void OnInit() = 0; virtual void OnUpdate() = 0; virtual void OnRender() = 0; virtual void OnDestroy() = 0; - virtual bool OnEvent(MSG msg) = 0; - std::wstring GetAssetFullPath(LPCWSTR assetName); - void GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + // Samples override the event handlers to handle specific messages. + virtual void OnKeyDown(UINT8 /*key*/) {} + virtual void OnKeyUp(UINT8 /*key*/) {} + + // Accessors. + UINT GetWidth() const { return m_width; } + UINT GetHeight() const { return m_height; } + const WCHAR* GetTitle() const { return m_title.c_str(); } - static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + void ParseCommandLineArgs(_In_reads_(argc) WCHAR* argv[], int argc); + +protected: + std::wstring GetAssetFullPath(LPCWSTR assetName); + void GetHardwareAdapter(_In_ IDXGIFactory2* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + void SetCustomWindowText(LPCWSTR text); // Viewport dimensions. UINT m_width; UINT m_height; float m_aspectRatio; - // Window handle. - HWND m_hwnd; - // Adapter info. bool m_useWarpDevice; private: - void ParseCommandLineArgs(); - // Root assets path. std::wstring m_assetsPath; diff --git a/Samples/D3D12DynamicIndexing/src/Main.cpp b/Samples/D3D12DynamicIndexing/src/Main.cpp index 17e6440da..19d9ac989 100644 --- a/Samples/D3D12DynamicIndexing/src/Main.cpp +++ b/Samples/D3D12DynamicIndexing/src/Main.cpp @@ -16,5 +16,5 @@ _Use_decl_annotations_ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) { D3D12DynamicIndexing sample(1280, 720, L"D3D12 Dynamic Indexing Sample"); - return sample.Run(hInstance, nCmdShow); + return Win32Application::Run(&sample, hInstance, nCmdShow); } diff --git a/Samples/D3D12DynamicIndexing/src/Win32Application.cpp b/Samples/D3D12DynamicIndexing/src/Win32Application.cpp new file mode 100644 index 000000000..9b4a24d55 --- /dev/null +++ b/Samples/D3D12DynamicIndexing/src/Win32Application.cpp @@ -0,0 +1,119 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#include "stdafx.h" +#include "Win32Application.h" + +HWND Win32Application::m_hwnd = nullptr; + +int Win32Application::Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow) +{ + // Parse the command line parameters + int argc; + LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc); + pSample->ParseCommandLineArgs(argv, argc); + LocalFree(argv); + + // Initialize the window class. + WNDCLASSEX windowClass = { 0 }; + windowClass.cbSize = sizeof(WNDCLASSEX); + windowClass.style = CS_HREDRAW | CS_VREDRAW; + windowClass.lpfnWndProc = WindowProc; + windowClass.hInstance = hInstance; + windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); + windowClass.lpszClassName = L"DXSampleClass"; + RegisterClassEx(&windowClass); + + RECT windowRect = { 0, 0, static_cast(pSample->GetWidth()), static_cast(pSample->GetHeight()) }; + AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); + + // Create the window and store a handle to it. + m_hwnd = CreateWindow( + windowClass.lpszClassName, + pSample->GetTitle(), + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + windowRect.right - windowRect.left, + windowRect.bottom - windowRect.top, + nullptr, // We have no parent window. + nullptr, // We aren't using menus. + hInstance, + pSample); + + // Initialize the sample. OnInit is defined in each child-implementation of DXSample. + pSample->OnInit(); + + ShowWindow(m_hwnd, nCmdShow); + + // Main sample loop. + MSG msg = {}; + while (msg.message != WM_QUIT) + { + // Process any messages in the queue. + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + pSample->OnDestroy(); + + // Return this part of the WM_QUIT message to Windows. + return static_cast(msg.wParam); +} + +// Main message handler for the sample. +LRESULT CALLBACK Win32Application::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + DXSample* pSample = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); + + switch (message) + { + case WM_CREATE: + { + // Save the DXSample* passed in to CreateWindow. + LPCREATESTRUCT pCreateStruct = reinterpret_cast(lParam); + SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(pCreateStruct->lpCreateParams)); + } + return 0; + + case WM_KEYDOWN: + if (pSample) + { + pSample->OnKeyDown(static_cast(wParam)); + } + return 0; + + case WM_KEYUP: + if (pSample) + { + pSample->OnKeyUp(static_cast(wParam)); + } + return 0; + + case WM_PAINT: + if (pSample) + { + pSample->OnUpdate(); + pSample->OnRender(); + } + return 0; + + case WM_DESTROY: + PostQuitMessage(0); + return 0; + } + + // Handle any messages the switch statement didn't. + return DefWindowProc(hWnd, message, wParam, lParam); +} diff --git a/Samples/D3D12DynamicIndexing/src/Win32Application.h b/Samples/D3D12DynamicIndexing/src/Win32Application.h new file mode 100644 index 000000000..8d2299164 --- /dev/null +++ b/Samples/D3D12DynamicIndexing/src/Win32Application.h @@ -0,0 +1,29 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#pragma once + +#include "DXSample.h" + +class DXSample; + +class Win32Application +{ +public: + static int Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow); + static HWND GetHwnd() { return m_hwnd; } + +protected: + static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + +private: + static HWND m_hwnd; +}; diff --git a/Samples/D3D12DynamicIndexing/src/stdafx.h b/Samples/D3D12DynamicIndexing/src/stdafx.h index ff33f3a01..1e2654e44 100644 --- a/Samples/D3D12DynamicIndexing/src/stdafx.h +++ b/Samples/D3D12DynamicIndexing/src/stdafx.h @@ -30,3 +30,4 @@ #include #include #include +#include diff --git a/Samples/D3D12ExecuteIndirect/src/D3D12ExecuteIndirect.cpp b/Samples/D3D12ExecuteIndirect/src/D3D12ExecuteIndirect.cpp index 85ed52a51..905ab3cde 100644 --- a/Samples/D3D12ExecuteIndirect/src/D3D12ExecuteIndirect.cpp +++ b/Samples/D3D12ExecuteIndirect/src/D3D12ExecuteIndirect.cpp @@ -58,7 +58,7 @@ void D3D12ExecuteIndirect::OnInit() // Load the rendering pipeline dependencies. void D3D12ExecuteIndirect::LoadPipeline() { -#ifdef _DEBUG +#if defined(_DEBUG) // Enable the D3D12 debug layer. { ComPtr debugController; @@ -116,7 +116,7 @@ void D3D12ExecuteIndirect::LoadPipeline() swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - swapChainDesc.OutputWindow = m_hwnd; + swapChainDesc.OutputWindow = Win32Application::GetHwnd(); swapChainDesc.SampleDesc.Count = 1; swapChainDesc.Windowed = TRUE; @@ -130,7 +130,7 @@ void D3D12ExecuteIndirect::LoadPipeline() ThrowIfFailed(swapChain.As(&m_swapChain)); // This sample does not support fullscreen transitions. - ThrowIfFailed(factory->MakeWindowAssociation(m_hwnd, DXGI_MWA_NO_ALT_ENTER)); + ThrowIfFailed(factory->MakeWindowAssociation(Win32Application::GetHwnd(), DXGI_MWA_NO_ALT_ENTER)); m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); @@ -218,7 +218,7 @@ void D3D12ExecuteIndirect::LoadAssets() ComPtr computeShader; ComPtr error; -#ifdef _DEBUG +#if defined(_DEBUG) // Enable better shader debugging with the graphics debugging tools. UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else @@ -419,10 +419,11 @@ void D3D12ExecuteIndirect::LoadAssets() commands.resize(TriangleResourceCount); const UINT commandBufferSize = CommandBufferSizePerFrame * FrameCount; + D3D12_RESOURCE_DESC commandBufferDesc = CD3DX12_RESOURCE_DESC::Buffer(commandBufferSize); ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, - &CD3DX12_RESOURCE_DESC::Buffer(commandBufferSize), + &commandBufferDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_commandBuffer))); @@ -486,10 +487,11 @@ void D3D12ExecuteIndirect::LoadAssets() { // Allocate a buffer large enough to hold all of the indirect commands // for a single frame as well as a UAV counter. + commandBufferDesc = CD3DX12_RESOURCE_DESC::Buffer(CommandBufferSizePerFrame + sizeof(UINT), D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS); ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, - &CD3DX12_RESOURCE_DESC::Buffer(CommandBufferSizePerFrame + sizeof(UINT), D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS), + &commandBufferDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_processedCommandBuffers[frame]))); @@ -617,17 +619,12 @@ void D3D12ExecuteIndirect::OnDestroy() CloseHandle(m_fenceEvent); } -bool D3D12ExecuteIndirect::OnEvent(MSG msg) +void D3D12ExecuteIndirect::OnKeyDown(UINT8 key) { - switch (msg.message) + if (key == VK_SPACE) { - case WM_KEYDOWN: - if (msg.wParam == VK_SPACE) - { - m_enableCulling = !m_enableCulling; - } + m_enableCulling = !m_enableCulling; } - return false; } // Fill the command list with all the render commands and dependent state. diff --git a/Samples/D3D12ExecuteIndirect/src/D3D12ExecuteIndirect.h b/Samples/D3D12ExecuteIndirect/src/D3D12ExecuteIndirect.h index 2680d8e4e..9869509b5 100644 --- a/Samples/D3D12ExecuteIndirect/src/D3D12ExecuteIndirect.h +++ b/Samples/D3D12ExecuteIndirect/src/D3D12ExecuteIndirect.h @@ -21,12 +21,11 @@ class D3D12ExecuteIndirect : public DXSample public: D3D12ExecuteIndirect(UINT width, UINT height, std::wstring name); -protected: virtual void OnInit(); virtual void OnUpdate(); virtual void OnRender(); virtual void OnDestroy(); - virtual bool OnEvent(MSG msg); + virtual void OnKeyDown(UINT8 key); private: static const UINT FrameCount = 3; diff --git a/Samples/D3D12ExecuteIndirect/src/D3D12ExecuteIndirect.vcxproj b/Samples/D3D12ExecuteIndirect/src/D3D12ExecuteIndirect.vcxproj index 7bcdc689e..af9a0d2ee 100644 --- a/Samples/D3D12ExecuteIndirect/src/D3D12ExecuteIndirect.vcxproj +++ b/Samples/D3D12ExecuteIndirect/src/D3D12ExecuteIndirect.vcxproj @@ -98,6 +98,7 @@ + @@ -105,6 +106,7 @@ + diff --git a/Samples/D3D12ExecuteIndirect/src/D3D12ExecuteIndirect.vcxproj.filters b/Samples/D3D12ExecuteIndirect/src/D3D12ExecuteIndirect.vcxproj.filters index 7b8c8ddf1..28bf1f917 100644 --- a/Samples/D3D12ExecuteIndirect/src/D3D12ExecuteIndirect.vcxproj.filters +++ b/Samples/D3D12ExecuteIndirect/src/D3D12ExecuteIndirect.vcxproj.filters @@ -39,6 +39,9 @@ Header Files + + Header Files\Util + @@ -53,6 +56,9 @@ Source Files + + Source Files\Util + diff --git a/Samples/D3D12ExecuteIndirect/src/DXSample.cpp b/Samples/D3D12ExecuteIndirect/src/DXSample.cpp index 651f40eb7..663ef590a 100644 --- a/Samples/D3D12ExecuteIndirect/src/DXSample.cpp +++ b/Samples/D3D12ExecuteIndirect/src/DXSample.cpp @@ -11,17 +11,13 @@ #include "stdafx.h" #include "DXSample.h" -#include DXSample::DXSample(UINT width, UINT height, std::wstring name) : m_width(width), m_height(height), + m_title(name), m_useWarpDevice(false) { - ParseCommandLineArgs(); - - m_title = name + (m_useWarpDevice ? L" (WARP)" : L""); - WCHAR assetsPath[512]; GetAssetsPath(assetsPath, _countof(assetsPath)); m_assetsPath = assetsPath; @@ -33,67 +29,6 @@ DXSample::~DXSample() { } -int DXSample::Run(HINSTANCE hInstance, int nCmdShow) -{ - // Initialize the window class. - WNDCLASSEX windowClass = { 0 }; - windowClass.cbSize = sizeof(WNDCLASSEX); - windowClass.style = CS_HREDRAW | CS_VREDRAW; - windowClass.lpfnWndProc = WindowProc; - windowClass.hInstance = hInstance; - windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); - windowClass.lpszClassName = L"WindowClass1"; - RegisterClassEx(&windowClass); - - RECT windowRect = { 0, 0, static_cast(m_width), static_cast(m_height) }; - AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); - - // Create the window and store a handle to it. - m_hwnd = CreateWindowEx(NULL, - L"WindowClass1", - m_title.c_str(), - WS_OVERLAPPEDWINDOW, - 300, - 300, - windowRect.right - windowRect.left, - windowRect.bottom - windowRect.top, - NULL, // We have no parent window, NULL. - NULL, // We aren't using menus, NULL. - hInstance, - NULL); // We aren't using multiple windows, NULL. - - ShowWindow(m_hwnd, nCmdShow); - - // Initialize the sample. OnInit is defined in each child-implementation of DXSample. - OnInit(); - - // Main sample loop. - MSG msg = { 0 }; - while (true) - { - // Process any messages in the queue. - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (msg.message == WM_QUIT) - break; - - // Pass events into our sample. - OnEvent(msg); - } - - OnUpdate(); - OnRender(); - } - - OnDestroy(); - - // Return this part of the WM_QUIT message to Windows. - return static_cast(msg.wParam); -} - // Helper function for resolving the full path of assets. std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) { @@ -102,7 +37,8 @@ std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) // Helper function for acquiring the first available hardware adapter that supports Direct3D 12. // If no such adapter can be found, *ppAdapter will be set to nullptr. -void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter) +_Use_decl_annotations_ +void DXSample::GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter) { IDXGIAdapter1* pAdapter = nullptr; *ppAdapter = nullptr; @@ -134,36 +70,20 @@ void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_m void DXSample::SetCustomWindowText(LPCWSTR text) { std::wstring windowText = m_title + L": " + text; - SetWindowText(m_hwnd, windowText.c_str()); + SetWindowText(Win32Application::GetHwnd(), windowText.c_str()); } // Helper function for parsing any supplied command line args. -void DXSample::ParseCommandLineArgs() +_Use_decl_annotations_ +void DXSample::ParseCommandLineArgs(WCHAR* argv[], int argc) { - int argc; - LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc); for (int i = 1; i < argc; ++i) { if (_wcsnicmp(argv[i], L"-warp", wcslen(argv[i])) == 0 || _wcsnicmp(argv[i], L"/warp", wcslen(argv[i])) == 0) { m_useWarpDevice = true; + m_title = m_title + L" (WARP)"; } } - LocalFree(argv); -} - -// Main message handler for the sample. -LRESULT CALLBACK DXSample::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - // Handle destroy/shutdown messages. - switch (message) - { - case WM_DESTROY: - PostQuitMessage(0); - return 0; - } - - // Handle any messages the switch statement didn't. - return DefWindowProc(hWnd, message, wParam, lParam); } diff --git a/Samples/D3D12ExecuteIndirect/src/DXSample.h b/Samples/D3D12ExecuteIndirect/src/DXSample.h index 39915ee91..5b417c3b2 100644 --- a/Samples/D3D12ExecuteIndirect/src/DXSample.h +++ b/Samples/D3D12ExecuteIndirect/src/DXSample.h @@ -12,6 +12,7 @@ #pragma once #include "DXSampleHelper.h" +#include "Win32Application.h" class DXSample { @@ -19,35 +20,36 @@ class DXSample DXSample(UINT width, UINT height, std::wstring name); virtual ~DXSample(); - int Run(HINSTANCE hInstance, int nCmdShow); - void SetCustomWindowText(LPCWSTR text); - -protected: virtual void OnInit() = 0; virtual void OnUpdate() = 0; virtual void OnRender() = 0; virtual void OnDestroy() = 0; - virtual bool OnEvent(MSG msg) = 0; - std::wstring GetAssetFullPath(LPCWSTR assetName); - void GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + // Samples override the event handlers to handle specific messages. + virtual void OnKeyDown(UINT8 /*key*/) {} + virtual void OnKeyUp(UINT8 /*key*/) {} + + // Accessors. + UINT GetWidth() const { return m_width; } + UINT GetHeight() const { return m_height; } + const WCHAR* GetTitle() const { return m_title.c_str(); } - static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + void ParseCommandLineArgs(_In_reads_(argc) WCHAR* argv[], int argc); + +protected: + std::wstring GetAssetFullPath(LPCWSTR assetName); + void GetHardwareAdapter(_In_ IDXGIFactory2* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + void SetCustomWindowText(LPCWSTR text); // Viewport dimensions. UINT m_width; UINT m_height; float m_aspectRatio; - // Window handle. - HWND m_hwnd; - // Adapter info. bool m_useWarpDevice; private: - void ParseCommandLineArgs(); - // Root assets path. std::wstring m_assetsPath; diff --git a/Samples/D3D12ExecuteIndirect/src/Main.cpp b/Samples/D3D12ExecuteIndirect/src/Main.cpp index a3c39182f..8f1eeb7b1 100644 --- a/Samples/D3D12ExecuteIndirect/src/Main.cpp +++ b/Samples/D3D12ExecuteIndirect/src/Main.cpp @@ -16,5 +16,5 @@ _Use_decl_annotations_ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) { D3D12ExecuteIndirect sample(1280, 720, L"D3D12 Execute Indirect sample - Press the SPACE bar to toggle GPU primitive culling"); - return sample.Run(hInstance, nCmdShow); + return Win32Application::Run(&sample, hInstance, nCmdShow); } diff --git a/Samples/D3D12ExecuteIndirect/src/Win32Application.cpp b/Samples/D3D12ExecuteIndirect/src/Win32Application.cpp new file mode 100644 index 000000000..9b4a24d55 --- /dev/null +++ b/Samples/D3D12ExecuteIndirect/src/Win32Application.cpp @@ -0,0 +1,119 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#include "stdafx.h" +#include "Win32Application.h" + +HWND Win32Application::m_hwnd = nullptr; + +int Win32Application::Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow) +{ + // Parse the command line parameters + int argc; + LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc); + pSample->ParseCommandLineArgs(argv, argc); + LocalFree(argv); + + // Initialize the window class. + WNDCLASSEX windowClass = { 0 }; + windowClass.cbSize = sizeof(WNDCLASSEX); + windowClass.style = CS_HREDRAW | CS_VREDRAW; + windowClass.lpfnWndProc = WindowProc; + windowClass.hInstance = hInstance; + windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); + windowClass.lpszClassName = L"DXSampleClass"; + RegisterClassEx(&windowClass); + + RECT windowRect = { 0, 0, static_cast(pSample->GetWidth()), static_cast(pSample->GetHeight()) }; + AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); + + // Create the window and store a handle to it. + m_hwnd = CreateWindow( + windowClass.lpszClassName, + pSample->GetTitle(), + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + windowRect.right - windowRect.left, + windowRect.bottom - windowRect.top, + nullptr, // We have no parent window. + nullptr, // We aren't using menus. + hInstance, + pSample); + + // Initialize the sample. OnInit is defined in each child-implementation of DXSample. + pSample->OnInit(); + + ShowWindow(m_hwnd, nCmdShow); + + // Main sample loop. + MSG msg = {}; + while (msg.message != WM_QUIT) + { + // Process any messages in the queue. + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + pSample->OnDestroy(); + + // Return this part of the WM_QUIT message to Windows. + return static_cast(msg.wParam); +} + +// Main message handler for the sample. +LRESULT CALLBACK Win32Application::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + DXSample* pSample = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); + + switch (message) + { + case WM_CREATE: + { + // Save the DXSample* passed in to CreateWindow. + LPCREATESTRUCT pCreateStruct = reinterpret_cast(lParam); + SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(pCreateStruct->lpCreateParams)); + } + return 0; + + case WM_KEYDOWN: + if (pSample) + { + pSample->OnKeyDown(static_cast(wParam)); + } + return 0; + + case WM_KEYUP: + if (pSample) + { + pSample->OnKeyUp(static_cast(wParam)); + } + return 0; + + case WM_PAINT: + if (pSample) + { + pSample->OnUpdate(); + pSample->OnRender(); + } + return 0; + + case WM_DESTROY: + PostQuitMessage(0); + return 0; + } + + // Handle any messages the switch statement didn't. + return DefWindowProc(hWnd, message, wParam, lParam); +} diff --git a/Samples/D3D12ExecuteIndirect/src/Win32Application.h b/Samples/D3D12ExecuteIndirect/src/Win32Application.h new file mode 100644 index 000000000..8d2299164 --- /dev/null +++ b/Samples/D3D12ExecuteIndirect/src/Win32Application.h @@ -0,0 +1,29 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#pragma once + +#include "DXSample.h" + +class DXSample; + +class Win32Application +{ +public: + static int Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow); + static HWND GetHwnd() { return m_hwnd; } + +protected: + static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + +private: + static HWND m_hwnd; +}; diff --git a/Samples/D3D12ExecuteIndirect/src/stdafx.h b/Samples/D3D12ExecuteIndirect/src/stdafx.h index 6c0c4cfbb..e8f990c5f 100644 --- a/Samples/D3D12ExecuteIndirect/src/stdafx.h +++ b/Samples/D3D12ExecuteIndirect/src/stdafx.h @@ -29,3 +29,4 @@ #include #include +#include diff --git a/Samples/D3D12Fullscreen/src/D3D12Fullscreen.cpp b/Samples/D3D12Fullscreen/src/D3D12Fullscreen.cpp index 6160aba2a..d2436ff82 100644 --- a/Samples/D3D12Fullscreen/src/D3D12Fullscreen.cpp +++ b/Samples/D3D12Fullscreen/src/D3D12Fullscreen.cpp @@ -33,7 +33,7 @@ void D3D12Fullscreen::OnInit() // Load the rendering pipeline dependencies. void D3D12Fullscreen::LoadPipeline() { -#ifdef _DEBUG +#if defined(_DEBUG) // Enable the D3D12 debug layer. { ComPtr debugController; @@ -85,7 +85,7 @@ void D3D12Fullscreen::LoadPipeline() swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - swapChainDesc.OutputWindow = m_hwnd; + swapChainDesc.OutputWindow = Win32Application::GetHwnd(); swapChainDesc.SampleDesc.Count = 1; swapChainDesc.Windowed = TRUE; @@ -137,16 +137,17 @@ void D3D12Fullscreen::LoadAssets() { ComPtr vertexShader; ComPtr pixelShader; + ComPtr error; -#ifdef _DEBUG +#if defined(_DEBUG) // Enable better shader debugging with the graphics debugging tools. UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else UINT compileFlags = 0; #endif - ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "VSMain", "vs_5_0", compileFlags, 0, &vertexShader, nullptr)); - ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "PSMain", "ps_5_0", compileFlags, 0, &pixelShader, nullptr)); + ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "VSMain", "vs_5_0", compileFlags, 0, &vertexShader, &error)); + ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "PSMain", "ps_5_0", compileFlags, 0, &pixelShader, &error)); // Define the vertex input layout. D3D12_INPUT_ELEMENT_DESC inputElementDescs[] = @@ -354,11 +355,11 @@ void D3D12Fullscreen::OnDestroy() CloseHandle(m_fenceEvent); } -bool D3D12Fullscreen::OnEvent(MSG msg) +void D3D12Fullscreen::OnKeyDown(UINT8 key) { - switch (msg.message) + switch (key) { - case WM_KEYDOWN: + case VK_SPACE: // Instrument the Space Bar to toggle between fullscreen states. // The window message loop callback will receive a WM_SIZE message once the // window is in the fullscreen state. At that point, the IDXGISwapChain should @@ -366,7 +367,6 @@ bool D3D12Fullscreen::OnEvent(MSG msg) // // NOTE: ALT+Enter will perform a similar operation; the code below is not // required to enable that key combination. - if (msg.wParam == VK_SPACE) { BOOL fullscreenState; ThrowIfFailed(m_swapChain->GetFullscreenState(&fullscreenState, nullptr)); @@ -381,7 +381,6 @@ bool D3D12Fullscreen::OnEvent(MSG msg) } break; } - return false; } // Fill the command list with all the render commands and dependent state. diff --git a/Samples/D3D12Fullscreen/src/D3D12Fullscreen.h b/Samples/D3D12Fullscreen/src/D3D12Fullscreen.h index bc274c686..4832d0018 100644 --- a/Samples/D3D12Fullscreen/src/D3D12Fullscreen.h +++ b/Samples/D3D12Fullscreen/src/D3D12Fullscreen.h @@ -28,7 +28,7 @@ class D3D12Fullscreen : public DXSample virtual void OnRender(); virtual void OnSizeChanged(UINT width, UINT height, bool minimized); virtual void OnDestroy(); - virtual bool OnEvent(MSG msg); + virtual void OnKeyDown(UINT8 key); private: static const UINT FrameCount = 2; diff --git a/Samples/D3D12Fullscreen/src/D3D12Fullscreen.vcxproj b/Samples/D3D12Fullscreen/src/D3D12Fullscreen.vcxproj index f493a557e..c99efe1dd 100644 --- a/Samples/D3D12Fullscreen/src/D3D12Fullscreen.vcxproj +++ b/Samples/D3D12Fullscreen/src/D3D12Fullscreen.vcxproj @@ -103,6 +103,7 @@ + @@ -112,11 +113,13 @@ Create Create + true Document + true diff --git a/Samples/D3D12Fullscreen/src/D3D12Fullscreen.vcxproj.filters b/Samples/D3D12Fullscreen/src/D3D12Fullscreen.vcxproj.filters index 778eb6de1..16b26446d 100644 --- a/Samples/D3D12Fullscreen/src/D3D12Fullscreen.vcxproj.filters +++ b/Samples/D3D12Fullscreen/src/D3D12Fullscreen.vcxproj.filters @@ -39,6 +39,9 @@ Header Files\Util + + Header Files\Util + @@ -53,6 +56,9 @@ Source Files\Util + + Source Files\Util + diff --git a/Samples/D3D12Fullscreen/src/DXSample.cpp b/Samples/D3D12Fullscreen/src/DXSample.cpp index 4489f588c..7cae57f40 100644 --- a/Samples/D3D12Fullscreen/src/DXSample.cpp +++ b/Samples/D3D12Fullscreen/src/DXSample.cpp @@ -11,18 +11,14 @@ #include "stdafx.h" #include "DXSample.h" -#include - -using namespace Microsoft::WRL; DXSample::DXSample(UINT width, UINT height, std::wstring name) : + m_width(width), + m_height(height), + m_title(name), m_aspectRatio(0.0f), m_useWarpDevice(false) { - ParseCommandLineArgs(); - - m_title = name + (m_useWarpDevice ? L" (WARP)" : L""); - WCHAR assetsPath[512]; GetAssetsPath(assetsPath, _countof(assetsPath)); m_assetsPath = assetsPath; @@ -34,61 +30,6 @@ DXSample::~DXSample() { } -int DXSample::Run(HINSTANCE hInstance, int nCmdShow) -{ - // Initialize the window class. - WNDCLASSEX windowClass = { 0 }; - windowClass.cbSize = sizeof(WNDCLASSEX); - windowClass.style = CS_HREDRAW | CS_VREDRAW; - windowClass.lpfnWndProc = WindowProc; - windowClass.hInstance = hInstance; - windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); - windowClass.lpszClassName = L"WindowClass1"; - RegisterClassEx(&windowClass); - - RECT windowRect = { 0, 0, static_cast(m_width), static_cast(m_height) }; - AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); - - // Create the window and store a handle to it. - m_hwnd = CreateWindow( - L"WindowClass1", - m_title.c_str(), - WS_OVERLAPPEDWINDOW, - 300, - 300, - windowRect.right - windowRect.left, - windowRect.bottom - windowRect.top, - NULL, // We have no parent window, NULL. - NULL, // We aren't using menus, NULL. - hInstance, - this); - - // Initialize the sample. OnInit is defined in each child-implementation of DXSample. - OnInit(); - - ShowWindow(m_hwnd, nCmdShow); - - // Main sample loop. - MSG msg = {}; - while (msg.message != WM_QUIT) - { - // Process any messages in the queue. - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - - // Pass events into our sample. - OnEvent(msg); - } - } - - OnDestroy(); - - // Return this part of the WM_QUIT message to Windows. - return static_cast(msg.wParam); -} - void DXSample::UpdateForSizeChange(UINT clientWidth, UINT clientHeight) { m_width = clientWidth; @@ -105,7 +46,7 @@ std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) // Helper function for acquiring the first available hardware adapter that supports Direct3D 12. // If no such adapter can be found, *ppAdapter will be set to nullptr. _Use_decl_annotations_ -void DXSample::GetHardwareAdapter(IDXGIFactory4* pFactory, IDXGIAdapter1** ppAdapter) +void DXSample::GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter) { IDXGIAdapter1* pAdapter = nullptr; *ppAdapter = nullptr; @@ -137,62 +78,20 @@ void DXSample::GetHardwareAdapter(IDXGIFactory4* pFactory, IDXGIAdapter1** ppAda void DXSample::SetCustomWindowText(LPCWSTR text) { std::wstring windowText = m_title + L": " + text; - SetWindowText(m_hwnd, windowText.c_str()); + SetWindowText(Win32Application::GetHwnd(), windowText.c_str()); } // Helper function for parsing any supplied command line args. -void DXSample::ParseCommandLineArgs() +_Use_decl_annotations_ +void DXSample::ParseCommandLineArgs(WCHAR* argv[], int argc) { - int argc; - LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc); for (int i = 1; i < argc; ++i) { if (_wcsnicmp(argv[i], L"-warp", wcslen(argv[i])) == 0 || _wcsnicmp(argv[i], L"/warp", wcslen(argv[i])) == 0) { m_useWarpDevice = true; + m_title = m_title + L" (WARP)"; } } - LocalFree(argv); -} - -// Main message handler for the sample. -LRESULT CALLBACK DXSample::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - DXSample* pSample = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); - - switch (message) - { - case WM_CREATE: - { - // Save a pointer to the DXSample passed in to CreateWindow. - LPCREATESTRUCT pCreateStruct = reinterpret_cast(lParam); - SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(pCreateStruct->lpCreateParams)); - } - return 0; - - case WM_PAINT: - if (pSample) - { - pSample->OnUpdate(); - pSample->OnRender(); - } - return 0; - - case WM_SIZE: - if (pSample) - { - RECT clientRect = {}; - GetClientRect(hWnd, &clientRect); - pSample->OnSizeChanged(clientRect.right - clientRect.left, clientRect.bottom - clientRect.top, wParam == SIZE_MINIMIZED); - } - return 0; - - case WM_DESTROY: - PostQuitMessage(0); - return 0; - } - - // Handle any messages the switch statement didn't. - return DefWindowProc(hWnd, message, wParam, lParam); } diff --git a/Samples/D3D12Fullscreen/src/DXSample.h b/Samples/D3D12Fullscreen/src/DXSample.h index 44cad4a3c..a5a453e14 100644 --- a/Samples/D3D12Fullscreen/src/DXSample.h +++ b/Samples/D3D12Fullscreen/src/DXSample.h @@ -12,6 +12,7 @@ #pragma once #include "DXSampleHelper.h" +#include "Win32Application.h" class DXSample { @@ -19,38 +20,38 @@ class DXSample DXSample(UINT width, UINT height, std::wstring name); virtual ~DXSample(); - int Run(HINSTANCE hInstance, int nCmdShow); - void SetCustomWindowText(LPCWSTR text); - -protected: virtual void OnInit() = 0; virtual void OnUpdate() = 0; virtual void OnRender() = 0; virtual void OnSizeChanged(UINT width, UINT height, bool minimized) = 0; virtual void OnDestroy() = 0; - virtual bool OnEvent(MSG msg) = 0; + // Samples override the event handlers to handle specific messages. + virtual void OnKeyDown(UINT8 /*key*/) {} + virtual void OnKeyUp(UINT8 /*key*/) {} + + // Accessors. + UINT GetWidth() const { return m_width; } + UINT GetHeight() const { return m_height; } + const WCHAR* GetTitle() const { return m_title.c_str(); } + + void ParseCommandLineArgs(_In_reads_(argc) WCHAR* argv[], int argc); void UpdateForSizeChange(UINT clientWidth, UINT clientHeight); +protected: std::wstring GetAssetFullPath(LPCWSTR assetName); - void GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); - - static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + void GetHardwareAdapter(_In_ IDXGIFactory2* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + void SetCustomWindowText(LPCWSTR text); // Viewport dimensions. UINT m_width; UINT m_height; float m_aspectRatio; - // Window handle. - HWND m_hwnd; - // Adapter info. bool m_useWarpDevice; private: - void ParseCommandLineArgs(); - // Root assets path. std::wstring m_assetsPath; diff --git a/Samples/D3D12Fullscreen/src/Main.cpp b/Samples/D3D12Fullscreen/src/Main.cpp index fc0bbfcf6..aab950e6b 100644 --- a/Samples/D3D12Fullscreen/src/Main.cpp +++ b/Samples/D3D12Fullscreen/src/Main.cpp @@ -16,5 +16,5 @@ _Use_decl_annotations_ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) { D3D12Fullscreen sample(1280, 720, L"D3D12 Fullscreen sample - Press the SPACE bar or ALT+Enter to toggle fullscreen mode"); - return sample.Run(hInstance, nCmdShow); + return Win32Application::Run(&sample, hInstance, nCmdShow); } diff --git a/Samples/D3D12Fullscreen/src/Win32Application.cpp b/Samples/D3D12Fullscreen/src/Win32Application.cpp new file mode 100644 index 000000000..231dcf908 --- /dev/null +++ b/Samples/D3D12Fullscreen/src/Win32Application.cpp @@ -0,0 +1,128 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#include "stdafx.h" +#include "Win32Application.h" + +HWND Win32Application::m_hwnd = nullptr; + +int Win32Application::Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow) +{ + // Parse the command line parameters + int argc; + LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc); + pSample->ParseCommandLineArgs(argv, argc); + LocalFree(argv); + + // Initialize the window class. + WNDCLASSEX windowClass = { 0 }; + windowClass.cbSize = sizeof(WNDCLASSEX); + windowClass.style = CS_HREDRAW | CS_VREDRAW; + windowClass.lpfnWndProc = WindowProc; + windowClass.hInstance = hInstance; + windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); + windowClass.lpszClassName = L"DXSampleClass"; + RegisterClassEx(&windowClass); + + RECT windowRect = { 0, 0, static_cast(pSample->GetWidth()), static_cast(pSample->GetHeight()) }; + AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); + + // Create the window and store a handle to it. + m_hwnd = CreateWindow( + windowClass.lpszClassName, + pSample->GetTitle(), + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + windowRect.right - windowRect.left, + windowRect.bottom - windowRect.top, + nullptr, // We have no parent window. + nullptr, // We aren't using menus. + hInstance, + pSample); + + // Initialize the sample. OnInit is defined in each child-implementation of DXSample. + pSample->OnInit(); + + ShowWindow(m_hwnd, nCmdShow); + + // Main sample loop. + MSG msg = {}; + while (msg.message != WM_QUIT) + { + // Process any messages in the queue. + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + pSample->OnDestroy(); + + // Return this part of the WM_QUIT message to Windows. + return static_cast(msg.wParam); +} + +// Main message handler for the sample. +LRESULT CALLBACK Win32Application::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + DXSample* pSample = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); + + switch (message) + { + case WM_CREATE: + { + // Save the DXSample* passed in to CreateWindow. + LPCREATESTRUCT pCreateStruct = reinterpret_cast(lParam); + SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(pCreateStruct->lpCreateParams)); + } + return 0; + + case WM_KEYDOWN: + if (pSample) + { + pSample->OnKeyDown(static_cast(wParam)); + } + return 0; + + case WM_KEYUP: + if (pSample) + { + pSample->OnKeyUp(static_cast(wParam)); + } + return 0; + + case WM_PAINT: + if (pSample) + { + pSample->OnUpdate(); + pSample->OnRender(); + } + return 0; + + case WM_SIZE: + if (pSample) + { + RECT clientRect = {}; + GetClientRect(hWnd, &clientRect); + pSample->OnSizeChanged(clientRect.right - clientRect.left, clientRect.bottom - clientRect.top, wParam == SIZE_MINIMIZED); + } + return 0; + + case WM_DESTROY: + PostQuitMessage(0); + return 0; + } + + // Handle any messages the switch statement didn't. + return DefWindowProc(hWnd, message, wParam, lParam); +} diff --git a/Samples/D3D12Fullscreen/src/Win32Application.h b/Samples/D3D12Fullscreen/src/Win32Application.h new file mode 100644 index 000000000..8d2299164 --- /dev/null +++ b/Samples/D3D12Fullscreen/src/Win32Application.h @@ -0,0 +1,29 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#pragma once + +#include "DXSample.h" + +class DXSample; + +class Win32Application +{ +public: + static int Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow); + static HWND GetHwnd() { return m_hwnd; } + +protected: + static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + +private: + static HWND m_hwnd; +}; diff --git a/Samples/D3D12Fullscreen/src/stdafx.h b/Samples/D3D12Fullscreen/src/stdafx.h index 24fa15dac..766ec83d9 100644 --- a/Samples/D3D12Fullscreen/src/stdafx.h +++ b/Samples/D3D12Fullscreen/src/stdafx.h @@ -29,3 +29,4 @@ #include #include +#include diff --git a/Samples/D3D12HelloWorld/src/HelloBundles/D3D12HelloBundles.cpp b/Samples/D3D12HelloWorld/src/HelloBundles/D3D12HelloBundles.cpp index 4db3dd0c0..dd5399c89 100644 --- a/Samples/D3D12HelloWorld/src/HelloBundles/D3D12HelloBundles.cpp +++ b/Samples/D3D12HelloWorld/src/HelloBundles/D3D12HelloBundles.cpp @@ -36,7 +36,7 @@ void D3D12HelloBundles::OnInit() // Load the rendering pipeline dependencies. void D3D12HelloBundles::LoadPipeline() { -#ifdef _DEBUG +#if defined(_DEBUG) // Enable the D3D12 debug layer. { ComPtr debugController; @@ -88,7 +88,7 @@ void D3D12HelloBundles::LoadPipeline() swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - swapChainDesc.OutputWindow = m_hwnd; + swapChainDesc.OutputWindow = Win32Application::GetHwnd(); swapChainDesc.SampleDesc.Count = 1; swapChainDesc.Windowed = TRUE; @@ -102,7 +102,7 @@ void D3D12HelloBundles::LoadPipeline() ThrowIfFailed(swapChain.As(&m_swapChain)); // This sample does not support fullscreen transitions. - ThrowIfFailed(factory->MakeWindowAssociation(m_hwnd, DXGI_MWA_NO_ALT_ENTER)); + ThrowIfFailed(factory->MakeWindowAssociation(Win32Application::GetHwnd(), DXGI_MWA_NO_ALT_ENTER)); m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); @@ -154,7 +154,7 @@ void D3D12HelloBundles::LoadAssets() ComPtr vertexShader; ComPtr pixelShader; -#ifdef _DEBUG +#if defined(_DEBUG) // Enable better shader debugging with the graphics debugging tools. UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else @@ -290,11 +290,6 @@ void D3D12HelloBundles::OnDestroy() CloseHandle(m_fenceEvent); } -bool D3D12HelloBundles::OnEvent(MSG) -{ - return false; -} - void D3D12HelloBundles::PopulateCommandList() { // Command list allocators can only be reset when the associated diff --git a/Samples/D3D12HelloWorld/src/HelloBundles/D3D12HelloBundles.h b/Samples/D3D12HelloWorld/src/HelloBundles/D3D12HelloBundles.h index 8d3cd34b5..b54e7ebf3 100644 --- a/Samples/D3D12HelloWorld/src/HelloBundles/D3D12HelloBundles.h +++ b/Samples/D3D12HelloWorld/src/HelloBundles/D3D12HelloBundles.h @@ -21,12 +21,10 @@ class D3D12HelloBundles : public DXSample public: D3D12HelloBundles(UINT width, UINT height, std::wstring name); -protected: virtual void OnInit(); virtual void OnUpdate(); virtual void OnRender(); virtual void OnDestroy(); - virtual bool OnEvent(MSG msg); private: static const UINT FrameCount = 2; diff --git a/Samples/D3D12HelloWorld/src/HelloBundles/D3D12HelloBundles.vcxproj b/Samples/D3D12HelloWorld/src/HelloBundles/D3D12HelloBundles.vcxproj index be9ce36bd..5accfdf48 100644 --- a/Samples/D3D12HelloWorld/src/HelloBundles/D3D12HelloBundles.vcxproj +++ b/Samples/D3D12HelloWorld/src/HelloBundles/D3D12HelloBundles.vcxproj @@ -109,6 +109,7 @@ + @@ -116,6 +117,7 @@ + diff --git a/Samples/D3D12HelloWorld/src/HelloBundles/D3D12HelloBundles.vcxproj.filters b/Samples/D3D12HelloWorld/src/HelloBundles/D3D12HelloBundles.vcxproj.filters index 4dfbc43e9..3e2199555 100644 --- a/Samples/D3D12HelloWorld/src/HelloBundles/D3D12HelloBundles.vcxproj.filters +++ b/Samples/D3D12HelloWorld/src/HelloBundles/D3D12HelloBundles.vcxproj.filters @@ -30,6 +30,9 @@ Header Files + + Header Files + @@ -44,6 +47,9 @@ Source Files + + Source Files + diff --git a/Samples/D3D12HelloWorld/src/HelloBundles/DXSample.cpp b/Samples/D3D12HelloWorld/src/HelloBundles/DXSample.cpp index 651f40eb7..663ef590a 100644 --- a/Samples/D3D12HelloWorld/src/HelloBundles/DXSample.cpp +++ b/Samples/D3D12HelloWorld/src/HelloBundles/DXSample.cpp @@ -11,17 +11,13 @@ #include "stdafx.h" #include "DXSample.h" -#include DXSample::DXSample(UINT width, UINT height, std::wstring name) : m_width(width), m_height(height), + m_title(name), m_useWarpDevice(false) { - ParseCommandLineArgs(); - - m_title = name + (m_useWarpDevice ? L" (WARP)" : L""); - WCHAR assetsPath[512]; GetAssetsPath(assetsPath, _countof(assetsPath)); m_assetsPath = assetsPath; @@ -33,67 +29,6 @@ DXSample::~DXSample() { } -int DXSample::Run(HINSTANCE hInstance, int nCmdShow) -{ - // Initialize the window class. - WNDCLASSEX windowClass = { 0 }; - windowClass.cbSize = sizeof(WNDCLASSEX); - windowClass.style = CS_HREDRAW | CS_VREDRAW; - windowClass.lpfnWndProc = WindowProc; - windowClass.hInstance = hInstance; - windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); - windowClass.lpszClassName = L"WindowClass1"; - RegisterClassEx(&windowClass); - - RECT windowRect = { 0, 0, static_cast(m_width), static_cast(m_height) }; - AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); - - // Create the window and store a handle to it. - m_hwnd = CreateWindowEx(NULL, - L"WindowClass1", - m_title.c_str(), - WS_OVERLAPPEDWINDOW, - 300, - 300, - windowRect.right - windowRect.left, - windowRect.bottom - windowRect.top, - NULL, // We have no parent window, NULL. - NULL, // We aren't using menus, NULL. - hInstance, - NULL); // We aren't using multiple windows, NULL. - - ShowWindow(m_hwnd, nCmdShow); - - // Initialize the sample. OnInit is defined in each child-implementation of DXSample. - OnInit(); - - // Main sample loop. - MSG msg = { 0 }; - while (true) - { - // Process any messages in the queue. - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (msg.message == WM_QUIT) - break; - - // Pass events into our sample. - OnEvent(msg); - } - - OnUpdate(); - OnRender(); - } - - OnDestroy(); - - // Return this part of the WM_QUIT message to Windows. - return static_cast(msg.wParam); -} - // Helper function for resolving the full path of assets. std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) { @@ -102,7 +37,8 @@ std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) // Helper function for acquiring the first available hardware adapter that supports Direct3D 12. // If no such adapter can be found, *ppAdapter will be set to nullptr. -void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter) +_Use_decl_annotations_ +void DXSample::GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter) { IDXGIAdapter1* pAdapter = nullptr; *ppAdapter = nullptr; @@ -134,36 +70,20 @@ void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_m void DXSample::SetCustomWindowText(LPCWSTR text) { std::wstring windowText = m_title + L": " + text; - SetWindowText(m_hwnd, windowText.c_str()); + SetWindowText(Win32Application::GetHwnd(), windowText.c_str()); } // Helper function for parsing any supplied command line args. -void DXSample::ParseCommandLineArgs() +_Use_decl_annotations_ +void DXSample::ParseCommandLineArgs(WCHAR* argv[], int argc) { - int argc; - LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc); for (int i = 1; i < argc; ++i) { if (_wcsnicmp(argv[i], L"-warp", wcslen(argv[i])) == 0 || _wcsnicmp(argv[i], L"/warp", wcslen(argv[i])) == 0) { m_useWarpDevice = true; + m_title = m_title + L" (WARP)"; } } - LocalFree(argv); -} - -// Main message handler for the sample. -LRESULT CALLBACK DXSample::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - // Handle destroy/shutdown messages. - switch (message) - { - case WM_DESTROY: - PostQuitMessage(0); - return 0; - } - - // Handle any messages the switch statement didn't. - return DefWindowProc(hWnd, message, wParam, lParam); } diff --git a/Samples/D3D12HelloWorld/src/HelloBundles/DXSample.h b/Samples/D3D12HelloWorld/src/HelloBundles/DXSample.h index 39915ee91..5b417c3b2 100644 --- a/Samples/D3D12HelloWorld/src/HelloBundles/DXSample.h +++ b/Samples/D3D12HelloWorld/src/HelloBundles/DXSample.h @@ -12,6 +12,7 @@ #pragma once #include "DXSampleHelper.h" +#include "Win32Application.h" class DXSample { @@ -19,35 +20,36 @@ class DXSample DXSample(UINT width, UINT height, std::wstring name); virtual ~DXSample(); - int Run(HINSTANCE hInstance, int nCmdShow); - void SetCustomWindowText(LPCWSTR text); - -protected: virtual void OnInit() = 0; virtual void OnUpdate() = 0; virtual void OnRender() = 0; virtual void OnDestroy() = 0; - virtual bool OnEvent(MSG msg) = 0; - std::wstring GetAssetFullPath(LPCWSTR assetName); - void GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + // Samples override the event handlers to handle specific messages. + virtual void OnKeyDown(UINT8 /*key*/) {} + virtual void OnKeyUp(UINT8 /*key*/) {} + + // Accessors. + UINT GetWidth() const { return m_width; } + UINT GetHeight() const { return m_height; } + const WCHAR* GetTitle() const { return m_title.c_str(); } - static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + void ParseCommandLineArgs(_In_reads_(argc) WCHAR* argv[], int argc); + +protected: + std::wstring GetAssetFullPath(LPCWSTR assetName); + void GetHardwareAdapter(_In_ IDXGIFactory2* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + void SetCustomWindowText(LPCWSTR text); // Viewport dimensions. UINT m_width; UINT m_height; float m_aspectRatio; - // Window handle. - HWND m_hwnd; - // Adapter info. bool m_useWarpDevice; private: - void ParseCommandLineArgs(); - // Root assets path. std::wstring m_assetsPath; diff --git a/Samples/D3D12HelloWorld/src/HelloBundles/Main.cpp b/Samples/D3D12HelloWorld/src/HelloBundles/Main.cpp index 61d8fd610..e29e229ca 100644 --- a/Samples/D3D12HelloWorld/src/HelloBundles/Main.cpp +++ b/Samples/D3D12HelloWorld/src/HelloBundles/Main.cpp @@ -16,5 +16,5 @@ _Use_decl_annotations_ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) { D3D12HelloBundles sample(1280, 720, L"D3D12 Hello Bundles"); - return sample.Run(hInstance, nCmdShow); + return Win32Application::Run(&sample, hInstance, nCmdShow); } diff --git a/Samples/D3D12HelloWorld/src/HelloBundles/Win32Application.cpp b/Samples/D3D12HelloWorld/src/HelloBundles/Win32Application.cpp new file mode 100644 index 000000000..9b4a24d55 --- /dev/null +++ b/Samples/D3D12HelloWorld/src/HelloBundles/Win32Application.cpp @@ -0,0 +1,119 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#include "stdafx.h" +#include "Win32Application.h" + +HWND Win32Application::m_hwnd = nullptr; + +int Win32Application::Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow) +{ + // Parse the command line parameters + int argc; + LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc); + pSample->ParseCommandLineArgs(argv, argc); + LocalFree(argv); + + // Initialize the window class. + WNDCLASSEX windowClass = { 0 }; + windowClass.cbSize = sizeof(WNDCLASSEX); + windowClass.style = CS_HREDRAW | CS_VREDRAW; + windowClass.lpfnWndProc = WindowProc; + windowClass.hInstance = hInstance; + windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); + windowClass.lpszClassName = L"DXSampleClass"; + RegisterClassEx(&windowClass); + + RECT windowRect = { 0, 0, static_cast(pSample->GetWidth()), static_cast(pSample->GetHeight()) }; + AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); + + // Create the window and store a handle to it. + m_hwnd = CreateWindow( + windowClass.lpszClassName, + pSample->GetTitle(), + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + windowRect.right - windowRect.left, + windowRect.bottom - windowRect.top, + nullptr, // We have no parent window. + nullptr, // We aren't using menus. + hInstance, + pSample); + + // Initialize the sample. OnInit is defined in each child-implementation of DXSample. + pSample->OnInit(); + + ShowWindow(m_hwnd, nCmdShow); + + // Main sample loop. + MSG msg = {}; + while (msg.message != WM_QUIT) + { + // Process any messages in the queue. + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + pSample->OnDestroy(); + + // Return this part of the WM_QUIT message to Windows. + return static_cast(msg.wParam); +} + +// Main message handler for the sample. +LRESULT CALLBACK Win32Application::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + DXSample* pSample = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); + + switch (message) + { + case WM_CREATE: + { + // Save the DXSample* passed in to CreateWindow. + LPCREATESTRUCT pCreateStruct = reinterpret_cast(lParam); + SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(pCreateStruct->lpCreateParams)); + } + return 0; + + case WM_KEYDOWN: + if (pSample) + { + pSample->OnKeyDown(static_cast(wParam)); + } + return 0; + + case WM_KEYUP: + if (pSample) + { + pSample->OnKeyUp(static_cast(wParam)); + } + return 0; + + case WM_PAINT: + if (pSample) + { + pSample->OnUpdate(); + pSample->OnRender(); + } + return 0; + + case WM_DESTROY: + PostQuitMessage(0); + return 0; + } + + // Handle any messages the switch statement didn't. + return DefWindowProc(hWnd, message, wParam, lParam); +} diff --git a/Samples/D3D12HelloWorld/src/HelloBundles/Win32Application.h b/Samples/D3D12HelloWorld/src/HelloBundles/Win32Application.h new file mode 100644 index 000000000..8d2299164 --- /dev/null +++ b/Samples/D3D12HelloWorld/src/HelloBundles/Win32Application.h @@ -0,0 +1,29 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#pragma once + +#include "DXSample.h" + +class DXSample; + +class Win32Application +{ +public: + static int Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow); + static HWND GetHwnd() { return m_hwnd; } + +protected: + static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + +private: + static HWND m_hwnd; +}; diff --git a/Samples/D3D12HelloWorld/src/HelloBundles/stdafx.h b/Samples/D3D12HelloWorld/src/HelloBundles/stdafx.h index 0fa3ed18f..10d9eff15 100644 --- a/Samples/D3D12HelloWorld/src/HelloBundles/stdafx.h +++ b/Samples/D3D12HelloWorld/src/HelloBundles/stdafx.h @@ -29,3 +29,4 @@ #include #include +#include diff --git a/Samples/D3D12HelloWorld/src/HelloConstBuffers/D3D12HelloConstBuffers.cpp b/Samples/D3D12HelloWorld/src/HelloConstBuffers/D3D12HelloConstBuffers.cpp index 23ccb4eb5..326f592a5 100644 --- a/Samples/D3D12HelloWorld/src/HelloConstBuffers/D3D12HelloConstBuffers.cpp +++ b/Samples/D3D12HelloWorld/src/HelloConstBuffers/D3D12HelloConstBuffers.cpp @@ -37,7 +37,7 @@ void D3D12HelloConstBuffers::OnInit() // Load the rendering pipeline dependencies. void D3D12HelloConstBuffers::LoadPipeline() { -#ifdef _DEBUG +#if defined(_DEBUG) // Enable the D3D12 debug layer. { ComPtr debugController; @@ -89,7 +89,7 @@ void D3D12HelloConstBuffers::LoadPipeline() swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - swapChainDesc.OutputWindow = m_hwnd; + swapChainDesc.OutputWindow = Win32Application::GetHwnd(); swapChainDesc.SampleDesc.Count = 1; swapChainDesc.Windowed = TRUE; @@ -103,7 +103,7 @@ void D3D12HelloConstBuffers::LoadPipeline() ThrowIfFailed(swapChain.As(&m_swapChain)); // This sample does not support fullscreen transitions. - ThrowIfFailed(factory->MakeWindowAssociation(m_hwnd, DXGI_MWA_NO_ALT_ENTER)); + ThrowIfFailed(factory->MakeWindowAssociation(Win32Application::GetHwnd(), DXGI_MWA_NO_ALT_ENTER)); m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); @@ -177,7 +177,7 @@ void D3D12HelloConstBuffers::LoadAssets() ComPtr vertexShader; ComPtr pixelShader; -#ifdef _DEBUG +#if defined(_DEBUG) // Enable better shader debugging with the graphics debugging tools. UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else @@ -336,11 +336,6 @@ void D3D12HelloConstBuffers::OnDestroy() CloseHandle(m_fenceEvent); } -bool D3D12HelloConstBuffers::OnEvent(MSG) -{ - return false; -} - // Fill the command list with all the render commands and dependent state. void D3D12HelloConstBuffers::PopulateCommandList() { diff --git a/Samples/D3D12HelloWorld/src/HelloConstBuffers/D3D12HelloConstBuffers.h b/Samples/D3D12HelloWorld/src/HelloConstBuffers/D3D12HelloConstBuffers.h index ff0feff80..a105039cd 100644 --- a/Samples/D3D12HelloWorld/src/HelloConstBuffers/D3D12HelloConstBuffers.h +++ b/Samples/D3D12HelloWorld/src/HelloConstBuffers/D3D12HelloConstBuffers.h @@ -21,12 +21,10 @@ class D3D12HelloConstBuffers : public DXSample public: D3D12HelloConstBuffers(UINT width, UINT height, std::wstring name); -protected: virtual void OnInit(); virtual void OnUpdate(); virtual void OnRender(); virtual void OnDestroy(); - virtual bool OnEvent(MSG msg); private: static const UINT FrameCount = 2; diff --git a/Samples/D3D12HelloWorld/src/HelloConstBuffers/D3D12HelloConstBuffers.vcxproj b/Samples/D3D12HelloWorld/src/HelloConstBuffers/D3D12HelloConstBuffers.vcxproj index a11de9817..09a16d595 100644 --- a/Samples/D3D12HelloWorld/src/HelloConstBuffers/D3D12HelloConstBuffers.vcxproj +++ b/Samples/D3D12HelloWorld/src/HelloConstBuffers/D3D12HelloConstBuffers.vcxproj @@ -109,6 +109,7 @@ + @@ -116,6 +117,7 @@ + diff --git a/Samples/D3D12HelloWorld/src/HelloConstBuffers/D3D12HelloConstBuffers.vcxproj.filters b/Samples/D3D12HelloWorld/src/HelloConstBuffers/D3D12HelloConstBuffers.vcxproj.filters index 41a3f3eb3..edbb3147d 100644 --- a/Samples/D3D12HelloWorld/src/HelloConstBuffers/D3D12HelloConstBuffers.vcxproj.filters +++ b/Samples/D3D12HelloWorld/src/HelloConstBuffers/D3D12HelloConstBuffers.vcxproj.filters @@ -30,6 +30,9 @@ Header Files + + Header Files + @@ -44,6 +47,9 @@ Source Files + + Source Files + diff --git a/Samples/D3D12HelloWorld/src/HelloConstBuffers/DXSample.cpp b/Samples/D3D12HelloWorld/src/HelloConstBuffers/DXSample.cpp index 651f40eb7..663ef590a 100644 --- a/Samples/D3D12HelloWorld/src/HelloConstBuffers/DXSample.cpp +++ b/Samples/D3D12HelloWorld/src/HelloConstBuffers/DXSample.cpp @@ -11,17 +11,13 @@ #include "stdafx.h" #include "DXSample.h" -#include DXSample::DXSample(UINT width, UINT height, std::wstring name) : m_width(width), m_height(height), + m_title(name), m_useWarpDevice(false) { - ParseCommandLineArgs(); - - m_title = name + (m_useWarpDevice ? L" (WARP)" : L""); - WCHAR assetsPath[512]; GetAssetsPath(assetsPath, _countof(assetsPath)); m_assetsPath = assetsPath; @@ -33,67 +29,6 @@ DXSample::~DXSample() { } -int DXSample::Run(HINSTANCE hInstance, int nCmdShow) -{ - // Initialize the window class. - WNDCLASSEX windowClass = { 0 }; - windowClass.cbSize = sizeof(WNDCLASSEX); - windowClass.style = CS_HREDRAW | CS_VREDRAW; - windowClass.lpfnWndProc = WindowProc; - windowClass.hInstance = hInstance; - windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); - windowClass.lpszClassName = L"WindowClass1"; - RegisterClassEx(&windowClass); - - RECT windowRect = { 0, 0, static_cast(m_width), static_cast(m_height) }; - AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); - - // Create the window and store a handle to it. - m_hwnd = CreateWindowEx(NULL, - L"WindowClass1", - m_title.c_str(), - WS_OVERLAPPEDWINDOW, - 300, - 300, - windowRect.right - windowRect.left, - windowRect.bottom - windowRect.top, - NULL, // We have no parent window, NULL. - NULL, // We aren't using menus, NULL. - hInstance, - NULL); // We aren't using multiple windows, NULL. - - ShowWindow(m_hwnd, nCmdShow); - - // Initialize the sample. OnInit is defined in each child-implementation of DXSample. - OnInit(); - - // Main sample loop. - MSG msg = { 0 }; - while (true) - { - // Process any messages in the queue. - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (msg.message == WM_QUIT) - break; - - // Pass events into our sample. - OnEvent(msg); - } - - OnUpdate(); - OnRender(); - } - - OnDestroy(); - - // Return this part of the WM_QUIT message to Windows. - return static_cast(msg.wParam); -} - // Helper function for resolving the full path of assets. std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) { @@ -102,7 +37,8 @@ std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) // Helper function for acquiring the first available hardware adapter that supports Direct3D 12. // If no such adapter can be found, *ppAdapter will be set to nullptr. -void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter) +_Use_decl_annotations_ +void DXSample::GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter) { IDXGIAdapter1* pAdapter = nullptr; *ppAdapter = nullptr; @@ -134,36 +70,20 @@ void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_m void DXSample::SetCustomWindowText(LPCWSTR text) { std::wstring windowText = m_title + L": " + text; - SetWindowText(m_hwnd, windowText.c_str()); + SetWindowText(Win32Application::GetHwnd(), windowText.c_str()); } // Helper function for parsing any supplied command line args. -void DXSample::ParseCommandLineArgs() +_Use_decl_annotations_ +void DXSample::ParseCommandLineArgs(WCHAR* argv[], int argc) { - int argc; - LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc); for (int i = 1; i < argc; ++i) { if (_wcsnicmp(argv[i], L"-warp", wcslen(argv[i])) == 0 || _wcsnicmp(argv[i], L"/warp", wcslen(argv[i])) == 0) { m_useWarpDevice = true; + m_title = m_title + L" (WARP)"; } } - LocalFree(argv); -} - -// Main message handler for the sample. -LRESULT CALLBACK DXSample::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - // Handle destroy/shutdown messages. - switch (message) - { - case WM_DESTROY: - PostQuitMessage(0); - return 0; - } - - // Handle any messages the switch statement didn't. - return DefWindowProc(hWnd, message, wParam, lParam); } diff --git a/Samples/D3D12HelloWorld/src/HelloConstBuffers/DXSample.h b/Samples/D3D12HelloWorld/src/HelloConstBuffers/DXSample.h index 39915ee91..5b417c3b2 100644 --- a/Samples/D3D12HelloWorld/src/HelloConstBuffers/DXSample.h +++ b/Samples/D3D12HelloWorld/src/HelloConstBuffers/DXSample.h @@ -12,6 +12,7 @@ #pragma once #include "DXSampleHelper.h" +#include "Win32Application.h" class DXSample { @@ -19,35 +20,36 @@ class DXSample DXSample(UINT width, UINT height, std::wstring name); virtual ~DXSample(); - int Run(HINSTANCE hInstance, int nCmdShow); - void SetCustomWindowText(LPCWSTR text); - -protected: virtual void OnInit() = 0; virtual void OnUpdate() = 0; virtual void OnRender() = 0; virtual void OnDestroy() = 0; - virtual bool OnEvent(MSG msg) = 0; - std::wstring GetAssetFullPath(LPCWSTR assetName); - void GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + // Samples override the event handlers to handle specific messages. + virtual void OnKeyDown(UINT8 /*key*/) {} + virtual void OnKeyUp(UINT8 /*key*/) {} + + // Accessors. + UINT GetWidth() const { return m_width; } + UINT GetHeight() const { return m_height; } + const WCHAR* GetTitle() const { return m_title.c_str(); } - static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + void ParseCommandLineArgs(_In_reads_(argc) WCHAR* argv[], int argc); + +protected: + std::wstring GetAssetFullPath(LPCWSTR assetName); + void GetHardwareAdapter(_In_ IDXGIFactory2* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + void SetCustomWindowText(LPCWSTR text); // Viewport dimensions. UINT m_width; UINT m_height; float m_aspectRatio; - // Window handle. - HWND m_hwnd; - // Adapter info. bool m_useWarpDevice; private: - void ParseCommandLineArgs(); - // Root assets path. std::wstring m_assetsPath; diff --git a/Samples/D3D12HelloWorld/src/HelloConstBuffers/Main.cpp b/Samples/D3D12HelloWorld/src/HelloConstBuffers/Main.cpp index be0bb2ca3..9b9b32410 100644 --- a/Samples/D3D12HelloWorld/src/HelloConstBuffers/Main.cpp +++ b/Samples/D3D12HelloWorld/src/HelloConstBuffers/Main.cpp @@ -16,5 +16,5 @@ _Use_decl_annotations_ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) { D3D12HelloConstBuffers sample(1280, 720, L"D3D12 Hello Constant Buffers"); - return sample.Run(hInstance, nCmdShow); + return Win32Application::Run(&sample, hInstance, nCmdShow); } diff --git a/Samples/D3D12HelloWorld/src/HelloConstBuffers/Win32Application.cpp b/Samples/D3D12HelloWorld/src/HelloConstBuffers/Win32Application.cpp new file mode 100644 index 000000000..9b4a24d55 --- /dev/null +++ b/Samples/D3D12HelloWorld/src/HelloConstBuffers/Win32Application.cpp @@ -0,0 +1,119 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#include "stdafx.h" +#include "Win32Application.h" + +HWND Win32Application::m_hwnd = nullptr; + +int Win32Application::Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow) +{ + // Parse the command line parameters + int argc; + LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc); + pSample->ParseCommandLineArgs(argv, argc); + LocalFree(argv); + + // Initialize the window class. + WNDCLASSEX windowClass = { 0 }; + windowClass.cbSize = sizeof(WNDCLASSEX); + windowClass.style = CS_HREDRAW | CS_VREDRAW; + windowClass.lpfnWndProc = WindowProc; + windowClass.hInstance = hInstance; + windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); + windowClass.lpszClassName = L"DXSampleClass"; + RegisterClassEx(&windowClass); + + RECT windowRect = { 0, 0, static_cast(pSample->GetWidth()), static_cast(pSample->GetHeight()) }; + AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); + + // Create the window and store a handle to it. + m_hwnd = CreateWindow( + windowClass.lpszClassName, + pSample->GetTitle(), + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + windowRect.right - windowRect.left, + windowRect.bottom - windowRect.top, + nullptr, // We have no parent window. + nullptr, // We aren't using menus. + hInstance, + pSample); + + // Initialize the sample. OnInit is defined in each child-implementation of DXSample. + pSample->OnInit(); + + ShowWindow(m_hwnd, nCmdShow); + + // Main sample loop. + MSG msg = {}; + while (msg.message != WM_QUIT) + { + // Process any messages in the queue. + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + pSample->OnDestroy(); + + // Return this part of the WM_QUIT message to Windows. + return static_cast(msg.wParam); +} + +// Main message handler for the sample. +LRESULT CALLBACK Win32Application::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + DXSample* pSample = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); + + switch (message) + { + case WM_CREATE: + { + // Save the DXSample* passed in to CreateWindow. + LPCREATESTRUCT pCreateStruct = reinterpret_cast(lParam); + SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(pCreateStruct->lpCreateParams)); + } + return 0; + + case WM_KEYDOWN: + if (pSample) + { + pSample->OnKeyDown(static_cast(wParam)); + } + return 0; + + case WM_KEYUP: + if (pSample) + { + pSample->OnKeyUp(static_cast(wParam)); + } + return 0; + + case WM_PAINT: + if (pSample) + { + pSample->OnUpdate(); + pSample->OnRender(); + } + return 0; + + case WM_DESTROY: + PostQuitMessage(0); + return 0; + } + + // Handle any messages the switch statement didn't. + return DefWindowProc(hWnd, message, wParam, lParam); +} diff --git a/Samples/D3D12HelloWorld/src/HelloConstBuffers/Win32Application.h b/Samples/D3D12HelloWorld/src/HelloConstBuffers/Win32Application.h new file mode 100644 index 000000000..8d2299164 --- /dev/null +++ b/Samples/D3D12HelloWorld/src/HelloConstBuffers/Win32Application.h @@ -0,0 +1,29 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#pragma once + +#include "DXSample.h" + +class DXSample; + +class Win32Application +{ +public: + static int Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow); + static HWND GetHwnd() { return m_hwnd; } + +protected: + static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + +private: + static HWND m_hwnd; +}; diff --git a/Samples/D3D12HelloWorld/src/HelloConstBuffers/stdafx.h b/Samples/D3D12HelloWorld/src/HelloConstBuffers/stdafx.h index 0fa3ed18f..10d9eff15 100644 --- a/Samples/D3D12HelloWorld/src/HelloConstBuffers/stdafx.h +++ b/Samples/D3D12HelloWorld/src/HelloConstBuffers/stdafx.h @@ -29,3 +29,4 @@ #include #include +#include diff --git a/Samples/D3D12HelloWorld/src/HelloTexture/D3D12HelloTexture.cpp b/Samples/D3D12HelloWorld/src/HelloTexture/D3D12HelloTexture.cpp index 930b6ef44..c0a8dfd32 100644 --- a/Samples/D3D12HelloWorld/src/HelloTexture/D3D12HelloTexture.cpp +++ b/Samples/D3D12HelloWorld/src/HelloTexture/D3D12HelloTexture.cpp @@ -36,7 +36,7 @@ void D3D12HelloTexture::OnInit() // Load the rendering pipeline dependencies. void D3D12HelloTexture::LoadPipeline() { -#ifdef _DEBUG +#if defined(_DEBUG) // Enable the D3D12 debug layer. { ComPtr debugController; @@ -88,7 +88,7 @@ void D3D12HelloTexture::LoadPipeline() swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - swapChainDesc.OutputWindow = m_hwnd; + swapChainDesc.OutputWindow = Win32Application::GetHwnd(); swapChainDesc.SampleDesc.Count = 1; swapChainDesc.Windowed = TRUE; @@ -102,7 +102,7 @@ void D3D12HelloTexture::LoadPipeline() ThrowIfFailed(swapChain.As(&m_swapChain)); // This sample does not support fullscreen transitions. - ThrowIfFailed(factory->MakeWindowAssociation(m_hwnd, DXGI_MWA_NO_ALT_ENTER)); + ThrowIfFailed(factory->MakeWindowAssociation(Win32Application::GetHwnd(), DXGI_MWA_NO_ALT_ENTER)); m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); @@ -181,7 +181,7 @@ void D3D12HelloTexture::LoadAssets() ComPtr vertexShader; ComPtr pixelShader; -#ifdef _DEBUG +#if defined(_DEBUG) // Enable better shader debugging with the graphics debugging tools. UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else @@ -402,11 +402,6 @@ void D3D12HelloTexture::OnDestroy() CloseHandle(m_fenceEvent); } -bool D3D12HelloTexture::OnEvent(MSG) -{ - return false; -} - void D3D12HelloTexture::PopulateCommandList() { // Command list allocators can only be reset when the associated diff --git a/Samples/D3D12HelloWorld/src/HelloTexture/D3D12HelloTexture.h b/Samples/D3D12HelloWorld/src/HelloTexture/D3D12HelloTexture.h index d4fae3e28..701b605ec 100644 --- a/Samples/D3D12HelloWorld/src/HelloTexture/D3D12HelloTexture.h +++ b/Samples/D3D12HelloWorld/src/HelloTexture/D3D12HelloTexture.h @@ -21,12 +21,10 @@ class D3D12HelloTexture : public DXSample public: D3D12HelloTexture(UINT width, UINT height, std::wstring name); -protected: virtual void OnInit(); virtual void OnUpdate(); virtual void OnRender(); virtual void OnDestroy(); - virtual bool OnEvent(MSG msg); private: static const UINT FrameCount = 2; diff --git a/Samples/D3D12HelloWorld/src/HelloTexture/D3D12HelloTexture.vcxproj b/Samples/D3D12HelloWorld/src/HelloTexture/D3D12HelloTexture.vcxproj index 9e310df74..9907caf7a 100644 --- a/Samples/D3D12HelloWorld/src/HelloTexture/D3D12HelloTexture.vcxproj +++ b/Samples/D3D12HelloWorld/src/HelloTexture/D3D12HelloTexture.vcxproj @@ -109,6 +109,7 @@ + @@ -116,6 +117,7 @@ + diff --git a/Samples/D3D12HelloWorld/src/HelloTexture/D3D12HelloTexture.vcxproj.filters b/Samples/D3D12HelloWorld/src/HelloTexture/D3D12HelloTexture.vcxproj.filters index b90b72556..19b7a15dc 100644 --- a/Samples/D3D12HelloWorld/src/HelloTexture/D3D12HelloTexture.vcxproj.filters +++ b/Samples/D3D12HelloWorld/src/HelloTexture/D3D12HelloTexture.vcxproj.filters @@ -30,6 +30,9 @@ Header Files + + Header Files + @@ -44,6 +47,9 @@ Source Files + + Source Files + diff --git a/Samples/D3D12HelloWorld/src/HelloTexture/DXSample.cpp b/Samples/D3D12HelloWorld/src/HelloTexture/DXSample.cpp index 651f40eb7..663ef590a 100644 --- a/Samples/D3D12HelloWorld/src/HelloTexture/DXSample.cpp +++ b/Samples/D3D12HelloWorld/src/HelloTexture/DXSample.cpp @@ -11,17 +11,13 @@ #include "stdafx.h" #include "DXSample.h" -#include DXSample::DXSample(UINT width, UINT height, std::wstring name) : m_width(width), m_height(height), + m_title(name), m_useWarpDevice(false) { - ParseCommandLineArgs(); - - m_title = name + (m_useWarpDevice ? L" (WARP)" : L""); - WCHAR assetsPath[512]; GetAssetsPath(assetsPath, _countof(assetsPath)); m_assetsPath = assetsPath; @@ -33,67 +29,6 @@ DXSample::~DXSample() { } -int DXSample::Run(HINSTANCE hInstance, int nCmdShow) -{ - // Initialize the window class. - WNDCLASSEX windowClass = { 0 }; - windowClass.cbSize = sizeof(WNDCLASSEX); - windowClass.style = CS_HREDRAW | CS_VREDRAW; - windowClass.lpfnWndProc = WindowProc; - windowClass.hInstance = hInstance; - windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); - windowClass.lpszClassName = L"WindowClass1"; - RegisterClassEx(&windowClass); - - RECT windowRect = { 0, 0, static_cast(m_width), static_cast(m_height) }; - AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); - - // Create the window and store a handle to it. - m_hwnd = CreateWindowEx(NULL, - L"WindowClass1", - m_title.c_str(), - WS_OVERLAPPEDWINDOW, - 300, - 300, - windowRect.right - windowRect.left, - windowRect.bottom - windowRect.top, - NULL, // We have no parent window, NULL. - NULL, // We aren't using menus, NULL. - hInstance, - NULL); // We aren't using multiple windows, NULL. - - ShowWindow(m_hwnd, nCmdShow); - - // Initialize the sample. OnInit is defined in each child-implementation of DXSample. - OnInit(); - - // Main sample loop. - MSG msg = { 0 }; - while (true) - { - // Process any messages in the queue. - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (msg.message == WM_QUIT) - break; - - // Pass events into our sample. - OnEvent(msg); - } - - OnUpdate(); - OnRender(); - } - - OnDestroy(); - - // Return this part of the WM_QUIT message to Windows. - return static_cast(msg.wParam); -} - // Helper function for resolving the full path of assets. std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) { @@ -102,7 +37,8 @@ std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) // Helper function for acquiring the first available hardware adapter that supports Direct3D 12. // If no such adapter can be found, *ppAdapter will be set to nullptr. -void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter) +_Use_decl_annotations_ +void DXSample::GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter) { IDXGIAdapter1* pAdapter = nullptr; *ppAdapter = nullptr; @@ -134,36 +70,20 @@ void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_m void DXSample::SetCustomWindowText(LPCWSTR text) { std::wstring windowText = m_title + L": " + text; - SetWindowText(m_hwnd, windowText.c_str()); + SetWindowText(Win32Application::GetHwnd(), windowText.c_str()); } // Helper function for parsing any supplied command line args. -void DXSample::ParseCommandLineArgs() +_Use_decl_annotations_ +void DXSample::ParseCommandLineArgs(WCHAR* argv[], int argc) { - int argc; - LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc); for (int i = 1; i < argc; ++i) { if (_wcsnicmp(argv[i], L"-warp", wcslen(argv[i])) == 0 || _wcsnicmp(argv[i], L"/warp", wcslen(argv[i])) == 0) { m_useWarpDevice = true; + m_title = m_title + L" (WARP)"; } } - LocalFree(argv); -} - -// Main message handler for the sample. -LRESULT CALLBACK DXSample::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - // Handle destroy/shutdown messages. - switch (message) - { - case WM_DESTROY: - PostQuitMessage(0); - return 0; - } - - // Handle any messages the switch statement didn't. - return DefWindowProc(hWnd, message, wParam, lParam); } diff --git a/Samples/D3D12HelloWorld/src/HelloTexture/DXSample.h b/Samples/D3D12HelloWorld/src/HelloTexture/DXSample.h index 39915ee91..5b417c3b2 100644 --- a/Samples/D3D12HelloWorld/src/HelloTexture/DXSample.h +++ b/Samples/D3D12HelloWorld/src/HelloTexture/DXSample.h @@ -12,6 +12,7 @@ #pragma once #include "DXSampleHelper.h" +#include "Win32Application.h" class DXSample { @@ -19,35 +20,36 @@ class DXSample DXSample(UINT width, UINT height, std::wstring name); virtual ~DXSample(); - int Run(HINSTANCE hInstance, int nCmdShow); - void SetCustomWindowText(LPCWSTR text); - -protected: virtual void OnInit() = 0; virtual void OnUpdate() = 0; virtual void OnRender() = 0; virtual void OnDestroy() = 0; - virtual bool OnEvent(MSG msg) = 0; - std::wstring GetAssetFullPath(LPCWSTR assetName); - void GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + // Samples override the event handlers to handle specific messages. + virtual void OnKeyDown(UINT8 /*key*/) {} + virtual void OnKeyUp(UINT8 /*key*/) {} + + // Accessors. + UINT GetWidth() const { return m_width; } + UINT GetHeight() const { return m_height; } + const WCHAR* GetTitle() const { return m_title.c_str(); } - static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + void ParseCommandLineArgs(_In_reads_(argc) WCHAR* argv[], int argc); + +protected: + std::wstring GetAssetFullPath(LPCWSTR assetName); + void GetHardwareAdapter(_In_ IDXGIFactory2* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + void SetCustomWindowText(LPCWSTR text); // Viewport dimensions. UINT m_width; UINT m_height; float m_aspectRatio; - // Window handle. - HWND m_hwnd; - // Adapter info. bool m_useWarpDevice; private: - void ParseCommandLineArgs(); - // Root assets path. std::wstring m_assetsPath; diff --git a/Samples/D3D12HelloWorld/src/HelloTexture/Main.cpp b/Samples/D3D12HelloWorld/src/HelloTexture/Main.cpp index 79096c5c5..9866c3c60 100644 --- a/Samples/D3D12HelloWorld/src/HelloTexture/Main.cpp +++ b/Samples/D3D12HelloWorld/src/HelloTexture/Main.cpp @@ -16,5 +16,5 @@ _Use_decl_annotations_ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) { D3D12HelloTexture sample(1280, 720, L"D3D12 Hello Texture"); - return sample.Run(hInstance, nCmdShow); + return Win32Application::Run(&sample, hInstance, nCmdShow); } diff --git a/Samples/D3D12HelloWorld/src/HelloTexture/Win32Application.cpp b/Samples/D3D12HelloWorld/src/HelloTexture/Win32Application.cpp new file mode 100644 index 000000000..9b4a24d55 --- /dev/null +++ b/Samples/D3D12HelloWorld/src/HelloTexture/Win32Application.cpp @@ -0,0 +1,119 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#include "stdafx.h" +#include "Win32Application.h" + +HWND Win32Application::m_hwnd = nullptr; + +int Win32Application::Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow) +{ + // Parse the command line parameters + int argc; + LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc); + pSample->ParseCommandLineArgs(argv, argc); + LocalFree(argv); + + // Initialize the window class. + WNDCLASSEX windowClass = { 0 }; + windowClass.cbSize = sizeof(WNDCLASSEX); + windowClass.style = CS_HREDRAW | CS_VREDRAW; + windowClass.lpfnWndProc = WindowProc; + windowClass.hInstance = hInstance; + windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); + windowClass.lpszClassName = L"DXSampleClass"; + RegisterClassEx(&windowClass); + + RECT windowRect = { 0, 0, static_cast(pSample->GetWidth()), static_cast(pSample->GetHeight()) }; + AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); + + // Create the window and store a handle to it. + m_hwnd = CreateWindow( + windowClass.lpszClassName, + pSample->GetTitle(), + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + windowRect.right - windowRect.left, + windowRect.bottom - windowRect.top, + nullptr, // We have no parent window. + nullptr, // We aren't using menus. + hInstance, + pSample); + + // Initialize the sample. OnInit is defined in each child-implementation of DXSample. + pSample->OnInit(); + + ShowWindow(m_hwnd, nCmdShow); + + // Main sample loop. + MSG msg = {}; + while (msg.message != WM_QUIT) + { + // Process any messages in the queue. + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + pSample->OnDestroy(); + + // Return this part of the WM_QUIT message to Windows. + return static_cast(msg.wParam); +} + +// Main message handler for the sample. +LRESULT CALLBACK Win32Application::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + DXSample* pSample = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); + + switch (message) + { + case WM_CREATE: + { + // Save the DXSample* passed in to CreateWindow. + LPCREATESTRUCT pCreateStruct = reinterpret_cast(lParam); + SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(pCreateStruct->lpCreateParams)); + } + return 0; + + case WM_KEYDOWN: + if (pSample) + { + pSample->OnKeyDown(static_cast(wParam)); + } + return 0; + + case WM_KEYUP: + if (pSample) + { + pSample->OnKeyUp(static_cast(wParam)); + } + return 0; + + case WM_PAINT: + if (pSample) + { + pSample->OnUpdate(); + pSample->OnRender(); + } + return 0; + + case WM_DESTROY: + PostQuitMessage(0); + return 0; + } + + // Handle any messages the switch statement didn't. + return DefWindowProc(hWnd, message, wParam, lParam); +} diff --git a/Samples/D3D12HelloWorld/src/HelloTexture/Win32Application.h b/Samples/D3D12HelloWorld/src/HelloTexture/Win32Application.h new file mode 100644 index 000000000..8d2299164 --- /dev/null +++ b/Samples/D3D12HelloWorld/src/HelloTexture/Win32Application.h @@ -0,0 +1,29 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#pragma once + +#include "DXSample.h" + +class DXSample; + +class Win32Application +{ +public: + static int Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow); + static HWND GetHwnd() { return m_hwnd; } + +protected: + static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + +private: + static HWND m_hwnd; +}; diff --git a/Samples/D3D12HelloWorld/src/HelloTexture/stdafx.h b/Samples/D3D12HelloWorld/src/HelloTexture/stdafx.h index ff33f3a01..1e2654e44 100644 --- a/Samples/D3D12HelloWorld/src/HelloTexture/stdafx.h +++ b/Samples/D3D12HelloWorld/src/HelloTexture/stdafx.h @@ -30,3 +30,4 @@ #include #include #include +#include diff --git a/Samples/D3D12HelloWorld/src/HelloTriangle/D3D12HelloTriangle.cpp b/Samples/D3D12HelloWorld/src/HelloTriangle/D3D12HelloTriangle.cpp index 7810c2e72..4e8a934ee 100644 --- a/Samples/D3D12HelloWorld/src/HelloTriangle/D3D12HelloTriangle.cpp +++ b/Samples/D3D12HelloWorld/src/HelloTriangle/D3D12HelloTriangle.cpp @@ -36,7 +36,7 @@ void D3D12HelloTriangle::OnInit() // Load the rendering pipeline dependencies. void D3D12HelloTriangle::LoadPipeline() { -#ifdef _DEBUG +#if defined(_DEBUG) // Enable the D3D12 debug layer. { ComPtr debugController; @@ -88,7 +88,7 @@ void D3D12HelloTriangle::LoadPipeline() swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - swapChainDesc.OutputWindow = m_hwnd; + swapChainDesc.OutputWindow = Win32Application::GetHwnd(); swapChainDesc.SampleDesc.Count = 1; swapChainDesc.Windowed = TRUE; @@ -102,7 +102,7 @@ void D3D12HelloTriangle::LoadPipeline() ThrowIfFailed(swapChain.As(&m_swapChain)); // This sample does not support fullscreen transitions. - ThrowIfFailed(factory->MakeWindowAssociation(m_hwnd, DXGI_MWA_NO_ALT_ENTER)); + ThrowIfFailed(factory->MakeWindowAssociation(Win32Application::GetHwnd(), DXGI_MWA_NO_ALT_ENTER)); m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); @@ -153,7 +153,7 @@ void D3D12HelloTriangle::LoadAssets() ComPtr vertexShader; ComPtr pixelShader; -#ifdef _DEBUG +#if defined(_DEBUG) // Enable better shader debugging with the graphics debugging tools. UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else @@ -279,11 +279,6 @@ void D3D12HelloTriangle::OnDestroy() CloseHandle(m_fenceEvent); } -bool D3D12HelloTriangle::OnEvent(MSG) -{ - return false; -} - void D3D12HelloTriangle::PopulateCommandList() { // Command list allocators can only be reset when the associated diff --git a/Samples/D3D12HelloWorld/src/HelloTriangle/D3D12HelloTriangle.h b/Samples/D3D12HelloWorld/src/HelloTriangle/D3D12HelloTriangle.h index dff2f6337..2d541e5ca 100644 --- a/Samples/D3D12HelloWorld/src/HelloTriangle/D3D12HelloTriangle.h +++ b/Samples/D3D12HelloWorld/src/HelloTriangle/D3D12HelloTriangle.h @@ -21,12 +21,10 @@ class D3D12HelloTriangle : public DXSample public: D3D12HelloTriangle(UINT width, UINT height, std::wstring name); -protected: virtual void OnInit(); virtual void OnUpdate(); virtual void OnRender(); virtual void OnDestroy(); - virtual bool OnEvent(MSG msg); private: static const UINT FrameCount = 2; diff --git a/Samples/D3D12HelloWorld/src/HelloTriangle/D3D12HelloTriangle.vcxproj b/Samples/D3D12HelloWorld/src/HelloTriangle/D3D12HelloTriangle.vcxproj index 3008256f0..677e30b64 100644 --- a/Samples/D3D12HelloWorld/src/HelloTriangle/D3D12HelloTriangle.vcxproj +++ b/Samples/D3D12HelloWorld/src/HelloTriangle/D3D12HelloTriangle.vcxproj @@ -109,6 +109,7 @@ + @@ -116,6 +117,7 @@ + diff --git a/Samples/D3D12HelloWorld/src/HelloTriangle/D3D12HelloTriangle.vcxproj.filters b/Samples/D3D12HelloWorld/src/HelloTriangle/D3D12HelloTriangle.vcxproj.filters index dafefc6df..5096e998a 100644 --- a/Samples/D3D12HelloWorld/src/HelloTriangle/D3D12HelloTriangle.vcxproj.filters +++ b/Samples/D3D12HelloWorld/src/HelloTriangle/D3D12HelloTriangle.vcxproj.filters @@ -30,6 +30,9 @@ Header Files + + Header Files + @@ -44,6 +47,9 @@ Source Files + + Source Files + diff --git a/Samples/D3D12HelloWorld/src/HelloTriangle/DXSample.cpp b/Samples/D3D12HelloWorld/src/HelloTriangle/DXSample.cpp index 651f40eb7..663ef590a 100644 --- a/Samples/D3D12HelloWorld/src/HelloTriangle/DXSample.cpp +++ b/Samples/D3D12HelloWorld/src/HelloTriangle/DXSample.cpp @@ -11,17 +11,13 @@ #include "stdafx.h" #include "DXSample.h" -#include DXSample::DXSample(UINT width, UINT height, std::wstring name) : m_width(width), m_height(height), + m_title(name), m_useWarpDevice(false) { - ParseCommandLineArgs(); - - m_title = name + (m_useWarpDevice ? L" (WARP)" : L""); - WCHAR assetsPath[512]; GetAssetsPath(assetsPath, _countof(assetsPath)); m_assetsPath = assetsPath; @@ -33,67 +29,6 @@ DXSample::~DXSample() { } -int DXSample::Run(HINSTANCE hInstance, int nCmdShow) -{ - // Initialize the window class. - WNDCLASSEX windowClass = { 0 }; - windowClass.cbSize = sizeof(WNDCLASSEX); - windowClass.style = CS_HREDRAW | CS_VREDRAW; - windowClass.lpfnWndProc = WindowProc; - windowClass.hInstance = hInstance; - windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); - windowClass.lpszClassName = L"WindowClass1"; - RegisterClassEx(&windowClass); - - RECT windowRect = { 0, 0, static_cast(m_width), static_cast(m_height) }; - AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); - - // Create the window and store a handle to it. - m_hwnd = CreateWindowEx(NULL, - L"WindowClass1", - m_title.c_str(), - WS_OVERLAPPEDWINDOW, - 300, - 300, - windowRect.right - windowRect.left, - windowRect.bottom - windowRect.top, - NULL, // We have no parent window, NULL. - NULL, // We aren't using menus, NULL. - hInstance, - NULL); // We aren't using multiple windows, NULL. - - ShowWindow(m_hwnd, nCmdShow); - - // Initialize the sample. OnInit is defined in each child-implementation of DXSample. - OnInit(); - - // Main sample loop. - MSG msg = { 0 }; - while (true) - { - // Process any messages in the queue. - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (msg.message == WM_QUIT) - break; - - // Pass events into our sample. - OnEvent(msg); - } - - OnUpdate(); - OnRender(); - } - - OnDestroy(); - - // Return this part of the WM_QUIT message to Windows. - return static_cast(msg.wParam); -} - // Helper function for resolving the full path of assets. std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) { @@ -102,7 +37,8 @@ std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) // Helper function for acquiring the first available hardware adapter that supports Direct3D 12. // If no such adapter can be found, *ppAdapter will be set to nullptr. -void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter) +_Use_decl_annotations_ +void DXSample::GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter) { IDXGIAdapter1* pAdapter = nullptr; *ppAdapter = nullptr; @@ -134,36 +70,20 @@ void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_m void DXSample::SetCustomWindowText(LPCWSTR text) { std::wstring windowText = m_title + L": " + text; - SetWindowText(m_hwnd, windowText.c_str()); + SetWindowText(Win32Application::GetHwnd(), windowText.c_str()); } // Helper function for parsing any supplied command line args. -void DXSample::ParseCommandLineArgs() +_Use_decl_annotations_ +void DXSample::ParseCommandLineArgs(WCHAR* argv[], int argc) { - int argc; - LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc); for (int i = 1; i < argc; ++i) { if (_wcsnicmp(argv[i], L"-warp", wcslen(argv[i])) == 0 || _wcsnicmp(argv[i], L"/warp", wcslen(argv[i])) == 0) { m_useWarpDevice = true; + m_title = m_title + L" (WARP)"; } } - LocalFree(argv); -} - -// Main message handler for the sample. -LRESULT CALLBACK DXSample::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - // Handle destroy/shutdown messages. - switch (message) - { - case WM_DESTROY: - PostQuitMessage(0); - return 0; - } - - // Handle any messages the switch statement didn't. - return DefWindowProc(hWnd, message, wParam, lParam); } diff --git a/Samples/D3D12HelloWorld/src/HelloTriangle/DXSample.h b/Samples/D3D12HelloWorld/src/HelloTriangle/DXSample.h index 39915ee91..5b417c3b2 100644 --- a/Samples/D3D12HelloWorld/src/HelloTriangle/DXSample.h +++ b/Samples/D3D12HelloWorld/src/HelloTriangle/DXSample.h @@ -12,6 +12,7 @@ #pragma once #include "DXSampleHelper.h" +#include "Win32Application.h" class DXSample { @@ -19,35 +20,36 @@ class DXSample DXSample(UINT width, UINT height, std::wstring name); virtual ~DXSample(); - int Run(HINSTANCE hInstance, int nCmdShow); - void SetCustomWindowText(LPCWSTR text); - -protected: virtual void OnInit() = 0; virtual void OnUpdate() = 0; virtual void OnRender() = 0; virtual void OnDestroy() = 0; - virtual bool OnEvent(MSG msg) = 0; - std::wstring GetAssetFullPath(LPCWSTR assetName); - void GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + // Samples override the event handlers to handle specific messages. + virtual void OnKeyDown(UINT8 /*key*/) {} + virtual void OnKeyUp(UINT8 /*key*/) {} + + // Accessors. + UINT GetWidth() const { return m_width; } + UINT GetHeight() const { return m_height; } + const WCHAR* GetTitle() const { return m_title.c_str(); } - static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + void ParseCommandLineArgs(_In_reads_(argc) WCHAR* argv[], int argc); + +protected: + std::wstring GetAssetFullPath(LPCWSTR assetName); + void GetHardwareAdapter(_In_ IDXGIFactory2* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + void SetCustomWindowText(LPCWSTR text); // Viewport dimensions. UINT m_width; UINT m_height; float m_aspectRatio; - // Window handle. - HWND m_hwnd; - // Adapter info. bool m_useWarpDevice; private: - void ParseCommandLineArgs(); - // Root assets path. std::wstring m_assetsPath; diff --git a/Samples/D3D12HelloWorld/src/HelloTriangle/Main.cpp b/Samples/D3D12HelloWorld/src/HelloTriangle/Main.cpp index 390a13a5b..9a0ed5f26 100644 --- a/Samples/D3D12HelloWorld/src/HelloTriangle/Main.cpp +++ b/Samples/D3D12HelloWorld/src/HelloTriangle/Main.cpp @@ -16,5 +16,5 @@ _Use_decl_annotations_ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) { D3D12HelloTriangle sample(1280, 720, L"D3D12 Hello Triangle"); - return sample.Run(hInstance, nCmdShow); + return Win32Application::Run(&sample, hInstance, nCmdShow); } diff --git a/Samples/D3D12HelloWorld/src/HelloTriangle/Win32Application.cpp b/Samples/D3D12HelloWorld/src/HelloTriangle/Win32Application.cpp new file mode 100644 index 000000000..9b4a24d55 --- /dev/null +++ b/Samples/D3D12HelloWorld/src/HelloTriangle/Win32Application.cpp @@ -0,0 +1,119 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#include "stdafx.h" +#include "Win32Application.h" + +HWND Win32Application::m_hwnd = nullptr; + +int Win32Application::Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow) +{ + // Parse the command line parameters + int argc; + LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc); + pSample->ParseCommandLineArgs(argv, argc); + LocalFree(argv); + + // Initialize the window class. + WNDCLASSEX windowClass = { 0 }; + windowClass.cbSize = sizeof(WNDCLASSEX); + windowClass.style = CS_HREDRAW | CS_VREDRAW; + windowClass.lpfnWndProc = WindowProc; + windowClass.hInstance = hInstance; + windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); + windowClass.lpszClassName = L"DXSampleClass"; + RegisterClassEx(&windowClass); + + RECT windowRect = { 0, 0, static_cast(pSample->GetWidth()), static_cast(pSample->GetHeight()) }; + AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); + + // Create the window and store a handle to it. + m_hwnd = CreateWindow( + windowClass.lpszClassName, + pSample->GetTitle(), + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + windowRect.right - windowRect.left, + windowRect.bottom - windowRect.top, + nullptr, // We have no parent window. + nullptr, // We aren't using menus. + hInstance, + pSample); + + // Initialize the sample. OnInit is defined in each child-implementation of DXSample. + pSample->OnInit(); + + ShowWindow(m_hwnd, nCmdShow); + + // Main sample loop. + MSG msg = {}; + while (msg.message != WM_QUIT) + { + // Process any messages in the queue. + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + pSample->OnDestroy(); + + // Return this part of the WM_QUIT message to Windows. + return static_cast(msg.wParam); +} + +// Main message handler for the sample. +LRESULT CALLBACK Win32Application::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + DXSample* pSample = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); + + switch (message) + { + case WM_CREATE: + { + // Save the DXSample* passed in to CreateWindow. + LPCREATESTRUCT pCreateStruct = reinterpret_cast(lParam); + SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(pCreateStruct->lpCreateParams)); + } + return 0; + + case WM_KEYDOWN: + if (pSample) + { + pSample->OnKeyDown(static_cast(wParam)); + } + return 0; + + case WM_KEYUP: + if (pSample) + { + pSample->OnKeyUp(static_cast(wParam)); + } + return 0; + + case WM_PAINT: + if (pSample) + { + pSample->OnUpdate(); + pSample->OnRender(); + } + return 0; + + case WM_DESTROY: + PostQuitMessage(0); + return 0; + } + + // Handle any messages the switch statement didn't. + return DefWindowProc(hWnd, message, wParam, lParam); +} diff --git a/Samples/D3D12HelloWorld/src/HelloTriangle/Win32Application.h b/Samples/D3D12HelloWorld/src/HelloTriangle/Win32Application.h new file mode 100644 index 000000000..8d2299164 --- /dev/null +++ b/Samples/D3D12HelloWorld/src/HelloTriangle/Win32Application.h @@ -0,0 +1,29 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#pragma once + +#include "DXSample.h" + +class DXSample; + +class Win32Application +{ +public: + static int Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow); + static HWND GetHwnd() { return m_hwnd; } + +protected: + static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + +private: + static HWND m_hwnd; +}; diff --git a/Samples/D3D12HelloWorld/src/HelloTriangle/stdafx.h b/Samples/D3D12HelloWorld/src/HelloTriangle/stdafx.h index 0fa3ed18f..10d9eff15 100644 --- a/Samples/D3D12HelloWorld/src/HelloTriangle/stdafx.h +++ b/Samples/D3D12HelloWorld/src/HelloTriangle/stdafx.h @@ -29,3 +29,4 @@ #include #include +#include diff --git a/Samples/D3D12HelloWorld/src/HelloWindow/D3D12HelloWindow.cpp b/Samples/D3D12HelloWorld/src/HelloWindow/D3D12HelloWindow.cpp index a464b95f9..208a5b39c 100644 --- a/Samples/D3D12HelloWorld/src/HelloWindow/D3D12HelloWindow.cpp +++ b/Samples/D3D12HelloWorld/src/HelloWindow/D3D12HelloWindow.cpp @@ -28,7 +28,7 @@ void D3D12HelloWindow::OnInit() // Load the rendering pipeline dependencies. void D3D12HelloWindow::LoadPipeline() { -#ifdef _DEBUG +#if defined(_DEBUG) // Enable the D3D12 debug layer. { ComPtr debugController; @@ -80,7 +80,7 @@ void D3D12HelloWindow::LoadPipeline() swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - swapChainDesc.OutputWindow = m_hwnd; + swapChainDesc.OutputWindow = Win32Application::GetHwnd(); swapChainDesc.SampleDesc.Count = 1; swapChainDesc.Windowed = TRUE; @@ -94,7 +94,7 @@ void D3D12HelloWindow::LoadPipeline() ThrowIfFailed(swapChain.As(&m_swapChain)); // This sample does not support fullscreen transitions. - ThrowIfFailed(factory->MakeWindowAssociation(m_hwnd, DXGI_MWA_NO_ALT_ENTER)); + ThrowIfFailed(factory->MakeWindowAssociation(Win32Application::GetHwnd(), DXGI_MWA_NO_ALT_ENTER)); m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); @@ -179,11 +179,6 @@ void D3D12HelloWindow::OnDestroy() CloseHandle(m_fenceEvent); } -bool D3D12HelloWindow::OnEvent(MSG) -{ - return false; -} - void D3D12HelloWindow::PopulateCommandList() { // Command list allocators can only be reset when the associated diff --git a/Samples/D3D12HelloWorld/src/HelloWindow/D3D12HelloWindow.h b/Samples/D3D12HelloWorld/src/HelloWindow/D3D12HelloWindow.h index a0b1ce63b..a94cabf68 100644 --- a/Samples/D3D12HelloWorld/src/HelloWindow/D3D12HelloWindow.h +++ b/Samples/D3D12HelloWorld/src/HelloWindow/D3D12HelloWindow.h @@ -20,12 +20,10 @@ class D3D12HelloWindow : public DXSample public: D3D12HelloWindow(UINT width, UINT height, std::wstring name); -protected: virtual void OnInit(); virtual void OnUpdate(); virtual void OnRender(); virtual void OnDestroy(); - virtual bool OnEvent(MSG msg); private: static const UINT FrameCount = 2; diff --git a/Samples/D3D12HelloWorld/src/HelloWindow/D3D12HelloWindow.vcxproj b/Samples/D3D12HelloWorld/src/HelloWindow/D3D12HelloWindow.vcxproj index 4fbfd1c96..3cf034bda 100644 --- a/Samples/D3D12HelloWorld/src/HelloWindow/D3D12HelloWindow.vcxproj +++ b/Samples/D3D12HelloWorld/src/HelloWindow/D3D12HelloWindow.vcxproj @@ -109,6 +109,7 @@ + @@ -116,6 +117,7 @@ + diff --git a/Samples/D3D12HelloWorld/src/HelloWindow/D3D12HelloWindow.vcxproj.filters b/Samples/D3D12HelloWorld/src/HelloWindow/D3D12HelloWindow.vcxproj.filters index 7680c5c5d..0ec1bc1d2 100644 --- a/Samples/D3D12HelloWorld/src/HelloWindow/D3D12HelloWindow.vcxproj.filters +++ b/Samples/D3D12HelloWorld/src/HelloWindow/D3D12HelloWindow.vcxproj.filters @@ -24,19 +24,25 @@ Header Files + + Header Files + Source Files - + Source Files - + Source Files Source Files + + Source Files + \ No newline at end of file diff --git a/Samples/D3D12HelloWorld/src/HelloWindow/DXSample.cpp b/Samples/D3D12HelloWorld/src/HelloWindow/DXSample.cpp index 651f40eb7..663ef590a 100644 --- a/Samples/D3D12HelloWorld/src/HelloWindow/DXSample.cpp +++ b/Samples/D3D12HelloWorld/src/HelloWindow/DXSample.cpp @@ -11,17 +11,13 @@ #include "stdafx.h" #include "DXSample.h" -#include DXSample::DXSample(UINT width, UINT height, std::wstring name) : m_width(width), m_height(height), + m_title(name), m_useWarpDevice(false) { - ParseCommandLineArgs(); - - m_title = name + (m_useWarpDevice ? L" (WARP)" : L""); - WCHAR assetsPath[512]; GetAssetsPath(assetsPath, _countof(assetsPath)); m_assetsPath = assetsPath; @@ -33,67 +29,6 @@ DXSample::~DXSample() { } -int DXSample::Run(HINSTANCE hInstance, int nCmdShow) -{ - // Initialize the window class. - WNDCLASSEX windowClass = { 0 }; - windowClass.cbSize = sizeof(WNDCLASSEX); - windowClass.style = CS_HREDRAW | CS_VREDRAW; - windowClass.lpfnWndProc = WindowProc; - windowClass.hInstance = hInstance; - windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); - windowClass.lpszClassName = L"WindowClass1"; - RegisterClassEx(&windowClass); - - RECT windowRect = { 0, 0, static_cast(m_width), static_cast(m_height) }; - AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); - - // Create the window and store a handle to it. - m_hwnd = CreateWindowEx(NULL, - L"WindowClass1", - m_title.c_str(), - WS_OVERLAPPEDWINDOW, - 300, - 300, - windowRect.right - windowRect.left, - windowRect.bottom - windowRect.top, - NULL, // We have no parent window, NULL. - NULL, // We aren't using menus, NULL. - hInstance, - NULL); // We aren't using multiple windows, NULL. - - ShowWindow(m_hwnd, nCmdShow); - - // Initialize the sample. OnInit is defined in each child-implementation of DXSample. - OnInit(); - - // Main sample loop. - MSG msg = { 0 }; - while (true) - { - // Process any messages in the queue. - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (msg.message == WM_QUIT) - break; - - // Pass events into our sample. - OnEvent(msg); - } - - OnUpdate(); - OnRender(); - } - - OnDestroy(); - - // Return this part of the WM_QUIT message to Windows. - return static_cast(msg.wParam); -} - // Helper function for resolving the full path of assets. std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) { @@ -102,7 +37,8 @@ std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) // Helper function for acquiring the first available hardware adapter that supports Direct3D 12. // If no such adapter can be found, *ppAdapter will be set to nullptr. -void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter) +_Use_decl_annotations_ +void DXSample::GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter) { IDXGIAdapter1* pAdapter = nullptr; *ppAdapter = nullptr; @@ -134,36 +70,20 @@ void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_m void DXSample::SetCustomWindowText(LPCWSTR text) { std::wstring windowText = m_title + L": " + text; - SetWindowText(m_hwnd, windowText.c_str()); + SetWindowText(Win32Application::GetHwnd(), windowText.c_str()); } // Helper function for parsing any supplied command line args. -void DXSample::ParseCommandLineArgs() +_Use_decl_annotations_ +void DXSample::ParseCommandLineArgs(WCHAR* argv[], int argc) { - int argc; - LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc); for (int i = 1; i < argc; ++i) { if (_wcsnicmp(argv[i], L"-warp", wcslen(argv[i])) == 0 || _wcsnicmp(argv[i], L"/warp", wcslen(argv[i])) == 0) { m_useWarpDevice = true; + m_title = m_title + L" (WARP)"; } } - LocalFree(argv); -} - -// Main message handler for the sample. -LRESULT CALLBACK DXSample::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - // Handle destroy/shutdown messages. - switch (message) - { - case WM_DESTROY: - PostQuitMessage(0); - return 0; - } - - // Handle any messages the switch statement didn't. - return DefWindowProc(hWnd, message, wParam, lParam); } diff --git a/Samples/D3D12HelloWorld/src/HelloWindow/DXSample.h b/Samples/D3D12HelloWorld/src/HelloWindow/DXSample.h index 39915ee91..5b417c3b2 100644 --- a/Samples/D3D12HelloWorld/src/HelloWindow/DXSample.h +++ b/Samples/D3D12HelloWorld/src/HelloWindow/DXSample.h @@ -12,6 +12,7 @@ #pragma once #include "DXSampleHelper.h" +#include "Win32Application.h" class DXSample { @@ -19,35 +20,36 @@ class DXSample DXSample(UINT width, UINT height, std::wstring name); virtual ~DXSample(); - int Run(HINSTANCE hInstance, int nCmdShow); - void SetCustomWindowText(LPCWSTR text); - -protected: virtual void OnInit() = 0; virtual void OnUpdate() = 0; virtual void OnRender() = 0; virtual void OnDestroy() = 0; - virtual bool OnEvent(MSG msg) = 0; - std::wstring GetAssetFullPath(LPCWSTR assetName); - void GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + // Samples override the event handlers to handle specific messages. + virtual void OnKeyDown(UINT8 /*key*/) {} + virtual void OnKeyUp(UINT8 /*key*/) {} + + // Accessors. + UINT GetWidth() const { return m_width; } + UINT GetHeight() const { return m_height; } + const WCHAR* GetTitle() const { return m_title.c_str(); } - static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + void ParseCommandLineArgs(_In_reads_(argc) WCHAR* argv[], int argc); + +protected: + std::wstring GetAssetFullPath(LPCWSTR assetName); + void GetHardwareAdapter(_In_ IDXGIFactory2* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + void SetCustomWindowText(LPCWSTR text); // Viewport dimensions. UINT m_width; UINT m_height; float m_aspectRatio; - // Window handle. - HWND m_hwnd; - // Adapter info. bool m_useWarpDevice; private: - void ParseCommandLineArgs(); - // Root assets path. std::wstring m_assetsPath; diff --git a/Samples/D3D12HelloWorld/src/HelloWindow/Main.cpp b/Samples/D3D12HelloWorld/src/HelloWindow/Main.cpp index d91581050..2eba245c2 100644 --- a/Samples/D3D12HelloWorld/src/HelloWindow/Main.cpp +++ b/Samples/D3D12HelloWorld/src/HelloWindow/Main.cpp @@ -16,5 +16,5 @@ _Use_decl_annotations_ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) { D3D12HelloWindow sample(1280, 720, L"D3D12 Hello Window"); - return sample.Run(hInstance, nCmdShow); + return Win32Application::Run(&sample, hInstance, nCmdShow); } diff --git a/Samples/D3D12HelloWorld/src/HelloWindow/Win32Application.cpp b/Samples/D3D12HelloWorld/src/HelloWindow/Win32Application.cpp new file mode 100644 index 000000000..9b4a24d55 --- /dev/null +++ b/Samples/D3D12HelloWorld/src/HelloWindow/Win32Application.cpp @@ -0,0 +1,119 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#include "stdafx.h" +#include "Win32Application.h" + +HWND Win32Application::m_hwnd = nullptr; + +int Win32Application::Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow) +{ + // Parse the command line parameters + int argc; + LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc); + pSample->ParseCommandLineArgs(argv, argc); + LocalFree(argv); + + // Initialize the window class. + WNDCLASSEX windowClass = { 0 }; + windowClass.cbSize = sizeof(WNDCLASSEX); + windowClass.style = CS_HREDRAW | CS_VREDRAW; + windowClass.lpfnWndProc = WindowProc; + windowClass.hInstance = hInstance; + windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); + windowClass.lpszClassName = L"DXSampleClass"; + RegisterClassEx(&windowClass); + + RECT windowRect = { 0, 0, static_cast(pSample->GetWidth()), static_cast(pSample->GetHeight()) }; + AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); + + // Create the window and store a handle to it. + m_hwnd = CreateWindow( + windowClass.lpszClassName, + pSample->GetTitle(), + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + windowRect.right - windowRect.left, + windowRect.bottom - windowRect.top, + nullptr, // We have no parent window. + nullptr, // We aren't using menus. + hInstance, + pSample); + + // Initialize the sample. OnInit is defined in each child-implementation of DXSample. + pSample->OnInit(); + + ShowWindow(m_hwnd, nCmdShow); + + // Main sample loop. + MSG msg = {}; + while (msg.message != WM_QUIT) + { + // Process any messages in the queue. + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + pSample->OnDestroy(); + + // Return this part of the WM_QUIT message to Windows. + return static_cast(msg.wParam); +} + +// Main message handler for the sample. +LRESULT CALLBACK Win32Application::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + DXSample* pSample = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); + + switch (message) + { + case WM_CREATE: + { + // Save the DXSample* passed in to CreateWindow. + LPCREATESTRUCT pCreateStruct = reinterpret_cast(lParam); + SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(pCreateStruct->lpCreateParams)); + } + return 0; + + case WM_KEYDOWN: + if (pSample) + { + pSample->OnKeyDown(static_cast(wParam)); + } + return 0; + + case WM_KEYUP: + if (pSample) + { + pSample->OnKeyUp(static_cast(wParam)); + } + return 0; + + case WM_PAINT: + if (pSample) + { + pSample->OnUpdate(); + pSample->OnRender(); + } + return 0; + + case WM_DESTROY: + PostQuitMessage(0); + return 0; + } + + // Handle any messages the switch statement didn't. + return DefWindowProc(hWnd, message, wParam, lParam); +} diff --git a/Samples/D3D12HelloWorld/src/HelloWindow/Win32Application.h b/Samples/D3D12HelloWorld/src/HelloWindow/Win32Application.h new file mode 100644 index 000000000..8d2299164 --- /dev/null +++ b/Samples/D3D12HelloWorld/src/HelloWindow/Win32Application.h @@ -0,0 +1,29 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#pragma once + +#include "DXSample.h" + +class DXSample; + +class Win32Application +{ +public: + static int Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow); + static HWND GetHwnd() { return m_hwnd; } + +protected: + static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + +private: + static HWND m_hwnd; +}; diff --git a/Samples/D3D12HelloWorld/src/HelloWindow/stdafx.h b/Samples/D3D12HelloWorld/src/HelloWindow/stdafx.h index 0fa3ed18f..10d9eff15 100644 --- a/Samples/D3D12HelloWorld/src/HelloWindow/stdafx.h +++ b/Samples/D3D12HelloWorld/src/HelloWindow/stdafx.h @@ -29,3 +29,4 @@ #include #include +#include diff --git a/Samples/D3D12Multithreading/src/D3D12Multithreading.cpp b/Samples/D3D12Multithreading/src/D3D12Multithreading.cpp index 53cbc1e57..c79a6b50b 100644 --- a/Samples/D3D12Multithreading/src/D3D12Multithreading.cpp +++ b/Samples/D3D12Multithreading/src/D3D12Multithreading.cpp @@ -55,7 +55,7 @@ void D3D12Multithreading::OnInit() // Load the rendering pipeline dependencies. void D3D12Multithreading::LoadPipeline() { -#ifdef _DEBUG +#if defined(_DEBUG) // Enable the D3D12 debug layer. { ComPtr debugController; @@ -107,7 +107,7 @@ void D3D12Multithreading::LoadPipeline() swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - swapChainDesc.OutputWindow = m_hwnd; + swapChainDesc.OutputWindow = Win32Application::GetHwnd(); swapChainDesc.SampleDesc.Count = 1; swapChainDesc.Windowed = TRUE; @@ -121,7 +121,7 @@ void D3D12Multithreading::LoadPipeline() ThrowIfFailed(swapChain.As(&m_swapChain)); // This sample does not support fullscreen transitions. - ThrowIfFailed(factory->MakeWindowAssociation(m_hwnd, DXGI_MWA_NO_ALT_ENTER)); + ThrowIfFailed(factory->MakeWindowAssociation(Win32Application::GetHwnd(), DXGI_MWA_NO_ALT_ENTER)); m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); @@ -201,7 +201,7 @@ void D3D12Multithreading::LoadAssets() ComPtr vertexShader; ComPtr pixelShader; -#ifdef _DEBUG +#if defined(_DEBUG) // Enable better shader debugging with the graphics debugging tools. UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else @@ -741,7 +741,7 @@ void D3D12Multithreading::OnRender() // Present and update the frame index for the next frame. PIXBeginEvent(m_commandQueue.Get(), 0, L"Presenting to screen"); - ThrowIfFailed(m_swapChain->Present(0, 0)); + ThrowIfFailed(m_swapChain->Present(1, 0)); PIXEndEvent(m_commandQueue.Get()); m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); @@ -786,24 +786,9 @@ void D3D12Multithreading::OnDestroy() } } -bool D3D12Multithreading::OnEvent(MSG msg) +void D3D12Multithreading::OnKeyDown(UINT8 key) { - switch (msg.message) - { - case WM_KEYDOWN: - OnKeyDown(msg.wParam); - break; - case WM_KEYUP: - OnKeyUp(msg.wParam); - break; - } - - return false; -} - -void D3D12Multithreading::OnKeyDown(WPARAM wParam) -{ - switch (wParam) + switch (key) { case VK_LEFT: m_keyboardInput.leftArrowPressed = true; @@ -823,9 +808,9 @@ void D3D12Multithreading::OnKeyDown(WPARAM wParam) } } -void D3D12Multithreading::OnKeyUp(WPARAM wParam) +void D3D12Multithreading::OnKeyUp(UINT8 key) { - switch (wParam) + switch (key) { case VK_LEFT: m_keyboardInput.leftArrowPressed = false; @@ -839,7 +824,6 @@ void D3D12Multithreading::OnKeyUp(WPARAM wParam) case VK_DOWN: m_keyboardInput.downArrowPressed = false; break; - } } diff --git a/Samples/D3D12Multithreading/src/D3D12Multithreading.h b/Samples/D3D12Multithreading/src/D3D12Multithreading.h index b90077661..6ec0b1e8f 100644 --- a/Samples/D3D12Multithreading/src/D3D12Multithreading.h +++ b/Samples/D3D12Multithreading/src/D3D12Multithreading.h @@ -51,12 +51,12 @@ class D3D12Multithreading : public DXSample static D3D12Multithreading* Get() { return s_app; } -protected: virtual void OnInit(); virtual void OnUpdate(); virtual void OnRender(); virtual void OnDestroy(); - virtual bool OnEvent(MSG msg); + virtual void OnKeyDown(UINT8 key); + virtual void OnKeyUp(UINT8 key); private: struct InputState @@ -134,8 +134,6 @@ class D3D12Multithreading : public DXSample void LoadPipeline(); void LoadAssets(); void LoadContexts(); - void OnKeyUp(WPARAM wParam); - void OnKeyDown(WPARAM wParam); void BeginFrame(); void MidFrame(); void EndFrame(); diff --git a/Samples/D3D12Multithreading/src/D3D12Multithreading.vcxproj b/Samples/D3D12Multithreading/src/D3D12Multithreading.vcxproj index 98b02aeee..df44470d7 100644 --- a/Samples/D3D12Multithreading/src/D3D12Multithreading.vcxproj +++ b/Samples/D3D12Multithreading/src/D3D12Multithreading.vcxproj @@ -102,6 +102,7 @@ + @@ -113,6 +114,7 @@ + diff --git a/Samples/D3D12Multithreading/src/D3D12Multithreading.vcxproj.filters b/Samples/D3D12Multithreading/src/D3D12Multithreading.vcxproj.filters index 2bd45abe1..4313ab0cd 100644 --- a/Samples/D3D12Multithreading/src/D3D12Multithreading.vcxproj.filters +++ b/Samples/D3D12Multithreading/src/D3D12Multithreading.vcxproj.filters @@ -51,6 +51,9 @@ Header Files\Util + + Header Files\Util + @@ -71,6 +74,9 @@ Source Files\Util + + Source Files\Util + diff --git a/Samples/D3D12Multithreading/src/DXSample.cpp b/Samples/D3D12Multithreading/src/DXSample.cpp index 651f40eb7..663ef590a 100644 --- a/Samples/D3D12Multithreading/src/DXSample.cpp +++ b/Samples/D3D12Multithreading/src/DXSample.cpp @@ -11,17 +11,13 @@ #include "stdafx.h" #include "DXSample.h" -#include DXSample::DXSample(UINT width, UINT height, std::wstring name) : m_width(width), m_height(height), + m_title(name), m_useWarpDevice(false) { - ParseCommandLineArgs(); - - m_title = name + (m_useWarpDevice ? L" (WARP)" : L""); - WCHAR assetsPath[512]; GetAssetsPath(assetsPath, _countof(assetsPath)); m_assetsPath = assetsPath; @@ -33,67 +29,6 @@ DXSample::~DXSample() { } -int DXSample::Run(HINSTANCE hInstance, int nCmdShow) -{ - // Initialize the window class. - WNDCLASSEX windowClass = { 0 }; - windowClass.cbSize = sizeof(WNDCLASSEX); - windowClass.style = CS_HREDRAW | CS_VREDRAW; - windowClass.lpfnWndProc = WindowProc; - windowClass.hInstance = hInstance; - windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); - windowClass.lpszClassName = L"WindowClass1"; - RegisterClassEx(&windowClass); - - RECT windowRect = { 0, 0, static_cast(m_width), static_cast(m_height) }; - AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); - - // Create the window and store a handle to it. - m_hwnd = CreateWindowEx(NULL, - L"WindowClass1", - m_title.c_str(), - WS_OVERLAPPEDWINDOW, - 300, - 300, - windowRect.right - windowRect.left, - windowRect.bottom - windowRect.top, - NULL, // We have no parent window, NULL. - NULL, // We aren't using menus, NULL. - hInstance, - NULL); // We aren't using multiple windows, NULL. - - ShowWindow(m_hwnd, nCmdShow); - - // Initialize the sample. OnInit is defined in each child-implementation of DXSample. - OnInit(); - - // Main sample loop. - MSG msg = { 0 }; - while (true) - { - // Process any messages in the queue. - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (msg.message == WM_QUIT) - break; - - // Pass events into our sample. - OnEvent(msg); - } - - OnUpdate(); - OnRender(); - } - - OnDestroy(); - - // Return this part of the WM_QUIT message to Windows. - return static_cast(msg.wParam); -} - // Helper function for resolving the full path of assets. std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) { @@ -102,7 +37,8 @@ std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) // Helper function for acquiring the first available hardware adapter that supports Direct3D 12. // If no such adapter can be found, *ppAdapter will be set to nullptr. -void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter) +_Use_decl_annotations_ +void DXSample::GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter) { IDXGIAdapter1* pAdapter = nullptr; *ppAdapter = nullptr; @@ -134,36 +70,20 @@ void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_m void DXSample::SetCustomWindowText(LPCWSTR text) { std::wstring windowText = m_title + L": " + text; - SetWindowText(m_hwnd, windowText.c_str()); + SetWindowText(Win32Application::GetHwnd(), windowText.c_str()); } // Helper function for parsing any supplied command line args. -void DXSample::ParseCommandLineArgs() +_Use_decl_annotations_ +void DXSample::ParseCommandLineArgs(WCHAR* argv[], int argc) { - int argc; - LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc); for (int i = 1; i < argc; ++i) { if (_wcsnicmp(argv[i], L"-warp", wcslen(argv[i])) == 0 || _wcsnicmp(argv[i], L"/warp", wcslen(argv[i])) == 0) { m_useWarpDevice = true; + m_title = m_title + L" (WARP)"; } } - LocalFree(argv); -} - -// Main message handler for the sample. -LRESULT CALLBACK DXSample::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - // Handle destroy/shutdown messages. - switch (message) - { - case WM_DESTROY: - PostQuitMessage(0); - return 0; - } - - // Handle any messages the switch statement didn't. - return DefWindowProc(hWnd, message, wParam, lParam); } diff --git a/Samples/D3D12Multithreading/src/DXSample.h b/Samples/D3D12Multithreading/src/DXSample.h index 39915ee91..5b417c3b2 100644 --- a/Samples/D3D12Multithreading/src/DXSample.h +++ b/Samples/D3D12Multithreading/src/DXSample.h @@ -12,6 +12,7 @@ #pragma once #include "DXSampleHelper.h" +#include "Win32Application.h" class DXSample { @@ -19,35 +20,36 @@ class DXSample DXSample(UINT width, UINT height, std::wstring name); virtual ~DXSample(); - int Run(HINSTANCE hInstance, int nCmdShow); - void SetCustomWindowText(LPCWSTR text); - -protected: virtual void OnInit() = 0; virtual void OnUpdate() = 0; virtual void OnRender() = 0; virtual void OnDestroy() = 0; - virtual bool OnEvent(MSG msg) = 0; - std::wstring GetAssetFullPath(LPCWSTR assetName); - void GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + // Samples override the event handlers to handle specific messages. + virtual void OnKeyDown(UINT8 /*key*/) {} + virtual void OnKeyUp(UINT8 /*key*/) {} + + // Accessors. + UINT GetWidth() const { return m_width; } + UINT GetHeight() const { return m_height; } + const WCHAR* GetTitle() const { return m_title.c_str(); } - static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + void ParseCommandLineArgs(_In_reads_(argc) WCHAR* argv[], int argc); + +protected: + std::wstring GetAssetFullPath(LPCWSTR assetName); + void GetHardwareAdapter(_In_ IDXGIFactory2* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + void SetCustomWindowText(LPCWSTR text); // Viewport dimensions. UINT m_width; UINT m_height; float m_aspectRatio; - // Window handle. - HWND m_hwnd; - // Adapter info. bool m_useWarpDevice; private: - void ParseCommandLineArgs(); - // Root assets path. std::wstring m_assetsPath; diff --git a/Samples/D3D12Multithreading/src/Main.cpp b/Samples/D3D12Multithreading/src/Main.cpp index 146de66f2..526bc392f 100644 --- a/Samples/D3D12Multithreading/src/Main.cpp +++ b/Samples/D3D12Multithreading/src/Main.cpp @@ -16,5 +16,5 @@ _Use_decl_annotations_ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) { D3D12Multithreading sample(1280, 720, L"D3D12 Multithreading Sample"); - return sample.Run(hInstance, nCmdShow); + return Win32Application::Run(&sample, hInstance, nCmdShow); } diff --git a/Samples/D3D12Multithreading/src/Win32Application.cpp b/Samples/D3D12Multithreading/src/Win32Application.cpp new file mode 100644 index 000000000..9b4a24d55 --- /dev/null +++ b/Samples/D3D12Multithreading/src/Win32Application.cpp @@ -0,0 +1,119 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#include "stdafx.h" +#include "Win32Application.h" + +HWND Win32Application::m_hwnd = nullptr; + +int Win32Application::Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow) +{ + // Parse the command line parameters + int argc; + LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc); + pSample->ParseCommandLineArgs(argv, argc); + LocalFree(argv); + + // Initialize the window class. + WNDCLASSEX windowClass = { 0 }; + windowClass.cbSize = sizeof(WNDCLASSEX); + windowClass.style = CS_HREDRAW | CS_VREDRAW; + windowClass.lpfnWndProc = WindowProc; + windowClass.hInstance = hInstance; + windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); + windowClass.lpszClassName = L"DXSampleClass"; + RegisterClassEx(&windowClass); + + RECT windowRect = { 0, 0, static_cast(pSample->GetWidth()), static_cast(pSample->GetHeight()) }; + AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); + + // Create the window and store a handle to it. + m_hwnd = CreateWindow( + windowClass.lpszClassName, + pSample->GetTitle(), + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + windowRect.right - windowRect.left, + windowRect.bottom - windowRect.top, + nullptr, // We have no parent window. + nullptr, // We aren't using menus. + hInstance, + pSample); + + // Initialize the sample. OnInit is defined in each child-implementation of DXSample. + pSample->OnInit(); + + ShowWindow(m_hwnd, nCmdShow); + + // Main sample loop. + MSG msg = {}; + while (msg.message != WM_QUIT) + { + // Process any messages in the queue. + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + pSample->OnDestroy(); + + // Return this part of the WM_QUIT message to Windows. + return static_cast(msg.wParam); +} + +// Main message handler for the sample. +LRESULT CALLBACK Win32Application::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + DXSample* pSample = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); + + switch (message) + { + case WM_CREATE: + { + // Save the DXSample* passed in to CreateWindow. + LPCREATESTRUCT pCreateStruct = reinterpret_cast(lParam); + SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(pCreateStruct->lpCreateParams)); + } + return 0; + + case WM_KEYDOWN: + if (pSample) + { + pSample->OnKeyDown(static_cast(wParam)); + } + return 0; + + case WM_KEYUP: + if (pSample) + { + pSample->OnKeyUp(static_cast(wParam)); + } + return 0; + + case WM_PAINT: + if (pSample) + { + pSample->OnUpdate(); + pSample->OnRender(); + } + return 0; + + case WM_DESTROY: + PostQuitMessage(0); + return 0; + } + + // Handle any messages the switch statement didn't. + return DefWindowProc(hWnd, message, wParam, lParam); +} diff --git a/Samples/D3D12Multithreading/src/Win32Application.h b/Samples/D3D12Multithreading/src/Win32Application.h new file mode 100644 index 000000000..8d2299164 --- /dev/null +++ b/Samples/D3D12Multithreading/src/Win32Application.h @@ -0,0 +1,29 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#pragma once + +#include "DXSample.h" + +class DXSample; + +class Win32Application +{ +public: + static int Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow); + static HWND GetHwnd() { return m_hwnd; } + +protected: + static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + +private: + static HWND m_hwnd; +}; diff --git a/Samples/D3D12Multithreading/src/stdafx.h b/Samples/D3D12Multithreading/src/stdafx.h index f5bb6fbb2..aa41222b9 100644 --- a/Samples/D3D12Multithreading/src/stdafx.h +++ b/Samples/D3D12Multithreading/src/stdafx.h @@ -33,6 +33,7 @@ #include #include #include +#include #define SINGLETHREADED FALSE diff --git a/Samples/D3D12PipelineStateCache/src/D3D12PipelineStateCache.cpp b/Samples/D3D12PipelineStateCache/src/D3D12PipelineStateCache.cpp index 4c7216c5d..734f7f9e9 100644 --- a/Samples/D3D12PipelineStateCache/src/D3D12PipelineStateCache.cpp +++ b/Samples/D3D12PipelineStateCache/src/D3D12PipelineStateCache.cpp @@ -53,7 +53,7 @@ void D3D12PipelineStateCache::OnInit() // Load the rendering pipeline dependencies. void D3D12PipelineStateCache::LoadPipeline() { -#ifdef _DEBUG +#if defined(_DEBUG) // Enable the D3D12 debug layer. { ComPtr debugController; @@ -105,7 +105,7 @@ void D3D12PipelineStateCache::LoadPipeline() swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - swapChainDesc.OutputWindow = m_hwnd; + swapChainDesc.OutputWindow = Win32Application::GetHwnd(); swapChainDesc.SampleDesc.Count = 1; swapChainDesc.Windowed = TRUE; swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT; @@ -120,7 +120,7 @@ void D3D12PipelineStateCache::LoadPipeline() ThrowIfFailed(swapChain.As(&m_swapChain)); // This sample does not support fullscreen transitions. - ThrowIfFailed(factory->MakeWindowAssociation(m_hwnd, DXGI_MWA_NO_ALT_ENTER)); + ThrowIfFailed(factory->MakeWindowAssociation(Win32Application::GetHwnd(), DXGI_MWA_NO_ALT_ENTER)); m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); m_swapChainEvent = m_swapChain->GetFrameLatencyWaitableObject(); @@ -373,7 +373,7 @@ void D3D12PipelineStateCache::OnRender() m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); // Present the frame. - ThrowIfFailed(m_swapChain->Present(0, 0)); + ThrowIfFailed(m_swapChain->Present(1, 0)); m_drawIndex = 0; m_psoLibrary.EndFrame(); @@ -389,21 +389,71 @@ void D3D12PipelineStateCache::OnDestroy() CloseHandle(m_fenceEvent); } -bool D3D12PipelineStateCache::OnEvent(MSG msg) +void D3D12PipelineStateCache::OnKeyDown(UINT8 key) { - switch (msg.message) + m_camera.OnKeyDown(key); +} + +void D3D12PipelineStateCache::OnKeyUp(UINT8 key) +{ + m_camera.OnKeyUp(key); + + switch (key) { - case WM_KEYDOWN: - m_camera.OnKeyDown(msg.wParam); + case 'C': + WaitForGpu(); + m_psoLibrary.ClearPSOCache(); + break; + + case 'U': + m_psoLibrary.ToggleUberShader(); + break; + + case 'L': + m_psoLibrary.ToggleDiskLibrary(); + break; + + case '1': + ToggleEffect(PostBlit); + break; + + case '2': + ToggleEffect(PostInvert); + break; + + case '3': + ToggleEffect(PostGrayScale); + break; + + case '4': + ToggleEffect(PostEdgeDetect); + break; + + case '5': + ToggleEffect(PostBlur); + break; + + case '6': + ToggleEffect(PostWarp); + break; + + case '7': + ToggleEffect(PostPixelate); + break; + + case '8': + ToggleEffect(PostDistort); + break; + + case '9': + ToggleEffect(PostWave); break; - case WM_KEYUP: - m_camera.OnKeyUp(msg.wParam); - OnKeyUp(msg.wParam); + default: break; } - return false; + UpdateWindowTextPso(); } // Fill the command list with all the render commands and dependent state. @@ -527,66 +577,6 @@ void D3D12PipelineStateCache::ToggleEffect(EffectPipelineType type) m_enabledEffects[type] = !m_enabledEffects[type]; } -void D3D12PipelineStateCache::OnKeyUp(WPARAM key) -{ - switch (key) - { - case 'C': - WaitForGpu(); - m_psoLibrary.ClearPSOCache(); - break; - - case 'U': - m_psoLibrary.ToggleUberShader(); - break; - - case 'L': - m_psoLibrary.ToggleDiskLibrary(); - break; - - case '1': - ToggleEffect(PostBlit); - break; - - case '2': - ToggleEffect(PostInvert); - break; - - case '3': - ToggleEffect(PostGrayScale); - break; - - case '4': - ToggleEffect(PostEdgeDetect); - break; - - case '5': - ToggleEffect(PostBlur); - break; - - case '6': - ToggleEffect(PostWarp); - break; - - case '7': - ToggleEffect(PostPixelate); - break; - - case '8': - ToggleEffect(PostDistort); - break; - - case '9': - ToggleEffect(PostWave); - break; - - default: - break; - } - - UpdateWindowTextPso(); -} - void D3D12PipelineStateCache::UpdateWindowTextPso() { std::wstringstream stringStream; diff --git a/Samples/D3D12PipelineStateCache/src/D3D12PipelineStateCache.h b/Samples/D3D12PipelineStateCache/src/D3D12PipelineStateCache.h index 9b6382342..41b164937 100644 --- a/Samples/D3D12PipelineStateCache/src/D3D12PipelineStateCache.h +++ b/Samples/D3D12PipelineStateCache/src/D3D12PipelineStateCache.h @@ -24,12 +24,12 @@ class D3D12PipelineStateCache : public DXSample public: D3D12PipelineStateCache(UINT width, UINT height, std::wstring name); -protected: virtual void OnInit(); virtual void OnUpdate(); virtual void OnRender(); virtual void OnDestroy(); - virtual bool OnEvent(MSG msg); + virtual void OnKeyDown(UINT8 key); + virtual void OnKeyUp(UINT8 key); private: static const UINT FrameCount = 2; @@ -106,7 +106,6 @@ class D3D12PipelineStateCache : public DXSample void LoadAssets(); void PopulateCommandList(); void ToggleEffect(EffectPipelineType type); - void OnKeyUp(WPARAM key); void UpdateWindowTextPso(); void WaitForGpu(); void MoveToNextFrame(); diff --git a/Samples/D3D12PipelineStateCache/src/D3D12PipelineStateCache.vcxproj b/Samples/D3D12PipelineStateCache/src/D3D12PipelineStateCache.vcxproj index 90090245f..5a160413e 100644 --- a/Samples/D3D12PipelineStateCache/src/D3D12PipelineStateCache.vcxproj +++ b/Samples/D3D12PipelineStateCache/src/D3D12PipelineStateCache.vcxproj @@ -101,6 +101,7 @@ + @@ -123,6 +124,7 @@ + diff --git a/Samples/D3D12PipelineStateCache/src/D3D12PipelineStateCache.vcxproj.filters b/Samples/D3D12PipelineStateCache/src/D3D12PipelineStateCache.vcxproj.filters index 0b49cf8e3..00cef804e 100644 --- a/Samples/D3D12PipelineStateCache/src/D3D12PipelineStateCache.vcxproj.filters +++ b/Samples/D3D12PipelineStateCache/src/D3D12PipelineStateCache.vcxproj.filters @@ -96,6 +96,9 @@ Assets\PrecompiledShaders + + Header Files\Util + @@ -122,6 +125,9 @@ Source Files\Util + + Source Files\Util + diff --git a/Samples/D3D12PipelineStateCache/src/DXSample.cpp b/Samples/D3D12PipelineStateCache/src/DXSample.cpp index 651f40eb7..663ef590a 100644 --- a/Samples/D3D12PipelineStateCache/src/DXSample.cpp +++ b/Samples/D3D12PipelineStateCache/src/DXSample.cpp @@ -11,17 +11,13 @@ #include "stdafx.h" #include "DXSample.h" -#include DXSample::DXSample(UINT width, UINT height, std::wstring name) : m_width(width), m_height(height), + m_title(name), m_useWarpDevice(false) { - ParseCommandLineArgs(); - - m_title = name + (m_useWarpDevice ? L" (WARP)" : L""); - WCHAR assetsPath[512]; GetAssetsPath(assetsPath, _countof(assetsPath)); m_assetsPath = assetsPath; @@ -33,67 +29,6 @@ DXSample::~DXSample() { } -int DXSample::Run(HINSTANCE hInstance, int nCmdShow) -{ - // Initialize the window class. - WNDCLASSEX windowClass = { 0 }; - windowClass.cbSize = sizeof(WNDCLASSEX); - windowClass.style = CS_HREDRAW | CS_VREDRAW; - windowClass.lpfnWndProc = WindowProc; - windowClass.hInstance = hInstance; - windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); - windowClass.lpszClassName = L"WindowClass1"; - RegisterClassEx(&windowClass); - - RECT windowRect = { 0, 0, static_cast(m_width), static_cast(m_height) }; - AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); - - // Create the window and store a handle to it. - m_hwnd = CreateWindowEx(NULL, - L"WindowClass1", - m_title.c_str(), - WS_OVERLAPPEDWINDOW, - 300, - 300, - windowRect.right - windowRect.left, - windowRect.bottom - windowRect.top, - NULL, // We have no parent window, NULL. - NULL, // We aren't using menus, NULL. - hInstance, - NULL); // We aren't using multiple windows, NULL. - - ShowWindow(m_hwnd, nCmdShow); - - // Initialize the sample. OnInit is defined in each child-implementation of DXSample. - OnInit(); - - // Main sample loop. - MSG msg = { 0 }; - while (true) - { - // Process any messages in the queue. - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (msg.message == WM_QUIT) - break; - - // Pass events into our sample. - OnEvent(msg); - } - - OnUpdate(); - OnRender(); - } - - OnDestroy(); - - // Return this part of the WM_QUIT message to Windows. - return static_cast(msg.wParam); -} - // Helper function for resolving the full path of assets. std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) { @@ -102,7 +37,8 @@ std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) // Helper function for acquiring the first available hardware adapter that supports Direct3D 12. // If no such adapter can be found, *ppAdapter will be set to nullptr. -void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter) +_Use_decl_annotations_ +void DXSample::GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter) { IDXGIAdapter1* pAdapter = nullptr; *ppAdapter = nullptr; @@ -134,36 +70,20 @@ void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_m void DXSample::SetCustomWindowText(LPCWSTR text) { std::wstring windowText = m_title + L": " + text; - SetWindowText(m_hwnd, windowText.c_str()); + SetWindowText(Win32Application::GetHwnd(), windowText.c_str()); } // Helper function for parsing any supplied command line args. -void DXSample::ParseCommandLineArgs() +_Use_decl_annotations_ +void DXSample::ParseCommandLineArgs(WCHAR* argv[], int argc) { - int argc; - LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc); for (int i = 1; i < argc; ++i) { if (_wcsnicmp(argv[i], L"-warp", wcslen(argv[i])) == 0 || _wcsnicmp(argv[i], L"/warp", wcslen(argv[i])) == 0) { m_useWarpDevice = true; + m_title = m_title + L" (WARP)"; } } - LocalFree(argv); -} - -// Main message handler for the sample. -LRESULT CALLBACK DXSample::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - // Handle destroy/shutdown messages. - switch (message) - { - case WM_DESTROY: - PostQuitMessage(0); - return 0; - } - - // Handle any messages the switch statement didn't. - return DefWindowProc(hWnd, message, wParam, lParam); } diff --git a/Samples/D3D12PipelineStateCache/src/DXSample.h b/Samples/D3D12PipelineStateCache/src/DXSample.h index 39915ee91..5b417c3b2 100644 --- a/Samples/D3D12PipelineStateCache/src/DXSample.h +++ b/Samples/D3D12PipelineStateCache/src/DXSample.h @@ -12,6 +12,7 @@ #pragma once #include "DXSampleHelper.h" +#include "Win32Application.h" class DXSample { @@ -19,35 +20,36 @@ class DXSample DXSample(UINT width, UINT height, std::wstring name); virtual ~DXSample(); - int Run(HINSTANCE hInstance, int nCmdShow); - void SetCustomWindowText(LPCWSTR text); - -protected: virtual void OnInit() = 0; virtual void OnUpdate() = 0; virtual void OnRender() = 0; virtual void OnDestroy() = 0; - virtual bool OnEvent(MSG msg) = 0; - std::wstring GetAssetFullPath(LPCWSTR assetName); - void GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + // Samples override the event handlers to handle specific messages. + virtual void OnKeyDown(UINT8 /*key*/) {} + virtual void OnKeyUp(UINT8 /*key*/) {} + + // Accessors. + UINT GetWidth() const { return m_width; } + UINT GetHeight() const { return m_height; } + const WCHAR* GetTitle() const { return m_title.c_str(); } - static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + void ParseCommandLineArgs(_In_reads_(argc) WCHAR* argv[], int argc); + +protected: + std::wstring GetAssetFullPath(LPCWSTR assetName); + void GetHardwareAdapter(_In_ IDXGIFactory2* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + void SetCustomWindowText(LPCWSTR text); // Viewport dimensions. UINT m_width; UINT m_height; float m_aspectRatio; - // Window handle. - HWND m_hwnd; - // Adapter info. bool m_useWarpDevice; private: - void ParseCommandLineArgs(); - // Root assets path. std::wstring m_assetsPath; diff --git a/Samples/D3D12PipelineStateCache/src/Main.cpp b/Samples/D3D12PipelineStateCache/src/Main.cpp index d657081ce..12b684594 100644 --- a/Samples/D3D12PipelineStateCache/src/Main.cpp +++ b/Samples/D3D12PipelineStateCache/src/Main.cpp @@ -48,7 +48,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) D3D12PipelineStateCache sample(1280, 720, L"D3D12 Pipeline State Object Cache Sample"); FILE* pStreamOut = CreateConsoleAndPrintDemoInformation(); - int result = sample.Run(hInstance, nCmdShow); + int result = Win32Application::Run(&sample, hInstance, nCmdShow); DestroyConsole(pStreamOut); return result; diff --git a/Samples/D3D12PipelineStateCache/src/Win32Application.cpp b/Samples/D3D12PipelineStateCache/src/Win32Application.cpp new file mode 100644 index 000000000..9b4a24d55 --- /dev/null +++ b/Samples/D3D12PipelineStateCache/src/Win32Application.cpp @@ -0,0 +1,119 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#include "stdafx.h" +#include "Win32Application.h" + +HWND Win32Application::m_hwnd = nullptr; + +int Win32Application::Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow) +{ + // Parse the command line parameters + int argc; + LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc); + pSample->ParseCommandLineArgs(argv, argc); + LocalFree(argv); + + // Initialize the window class. + WNDCLASSEX windowClass = { 0 }; + windowClass.cbSize = sizeof(WNDCLASSEX); + windowClass.style = CS_HREDRAW | CS_VREDRAW; + windowClass.lpfnWndProc = WindowProc; + windowClass.hInstance = hInstance; + windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); + windowClass.lpszClassName = L"DXSampleClass"; + RegisterClassEx(&windowClass); + + RECT windowRect = { 0, 0, static_cast(pSample->GetWidth()), static_cast(pSample->GetHeight()) }; + AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); + + // Create the window and store a handle to it. + m_hwnd = CreateWindow( + windowClass.lpszClassName, + pSample->GetTitle(), + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + windowRect.right - windowRect.left, + windowRect.bottom - windowRect.top, + nullptr, // We have no parent window. + nullptr, // We aren't using menus. + hInstance, + pSample); + + // Initialize the sample. OnInit is defined in each child-implementation of DXSample. + pSample->OnInit(); + + ShowWindow(m_hwnd, nCmdShow); + + // Main sample loop. + MSG msg = {}; + while (msg.message != WM_QUIT) + { + // Process any messages in the queue. + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + pSample->OnDestroy(); + + // Return this part of the WM_QUIT message to Windows. + return static_cast(msg.wParam); +} + +// Main message handler for the sample. +LRESULT CALLBACK Win32Application::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + DXSample* pSample = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); + + switch (message) + { + case WM_CREATE: + { + // Save the DXSample* passed in to CreateWindow. + LPCREATESTRUCT pCreateStruct = reinterpret_cast(lParam); + SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(pCreateStruct->lpCreateParams)); + } + return 0; + + case WM_KEYDOWN: + if (pSample) + { + pSample->OnKeyDown(static_cast(wParam)); + } + return 0; + + case WM_KEYUP: + if (pSample) + { + pSample->OnKeyUp(static_cast(wParam)); + } + return 0; + + case WM_PAINT: + if (pSample) + { + pSample->OnUpdate(); + pSample->OnRender(); + } + return 0; + + case WM_DESTROY: + PostQuitMessage(0); + return 0; + } + + // Handle any messages the switch statement didn't. + return DefWindowProc(hWnd, message, wParam, lParam); +} diff --git a/Samples/D3D12PipelineStateCache/src/Win32Application.h b/Samples/D3D12PipelineStateCache/src/Win32Application.h new file mode 100644 index 000000000..8d2299164 --- /dev/null +++ b/Samples/D3D12PipelineStateCache/src/Win32Application.h @@ -0,0 +1,29 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#pragma once + +#include "DXSample.h" + +class DXSample; + +class Win32Application +{ +public: + static int Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow); + static HWND GetHwnd() { return m_hwnd; } + +protected: + static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + +private: + static HWND m_hwnd; +}; diff --git a/Samples/D3D12PipelineStateCache/src/stdafx.h b/Samples/D3D12PipelineStateCache/src/stdafx.h index 6c2254652..c12628a7a 100644 --- a/Samples/D3D12PipelineStateCache/src/stdafx.h +++ b/Samples/D3D12PipelineStateCache/src/stdafx.h @@ -34,3 +34,4 @@ #include #include #include +#include diff --git a/Samples/D3D12PredicationQueries/src/D3D12PredicationQueries.cpp b/Samples/D3D12PredicationQueries/src/D3D12PredicationQueries.cpp index c3d9d056f..6b051f6f9 100644 --- a/Samples/D3D12PredicationQueries/src/D3D12PredicationQueries.cpp +++ b/Samples/D3D12PredicationQueries/src/D3D12PredicationQueries.cpp @@ -39,7 +39,7 @@ void D3D12PredicationQueries::OnInit() // Load the rendering pipeline dependencies. void D3D12PredicationQueries::LoadPipeline() { -#ifdef _DEBUG +#if defined(_DEBUG) // Enable the D3D12 debug layer. { ComPtr debugController; @@ -91,7 +91,7 @@ void D3D12PredicationQueries::LoadPipeline() swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - swapChainDesc.OutputWindow = m_hwnd; + swapChainDesc.OutputWindow = Win32Application::GetHwnd(); swapChainDesc.SampleDesc.Count = 1; swapChainDesc.Windowed = TRUE; @@ -105,7 +105,7 @@ void D3D12PredicationQueries::LoadPipeline() ThrowIfFailed(swapChain.As(&m_swapChain)); // This sample does not support fullscreen transitions. - ThrowIfFailed(factory->MakeWindowAssociation(m_hwnd, DXGI_MWA_NO_ALT_ENTER)); + ThrowIfFailed(factory->MakeWindowAssociation(Win32Application::GetHwnd(), DXGI_MWA_NO_ALT_ENTER)); m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); @@ -191,7 +191,7 @@ void D3D12PredicationQueries::LoadAssets() ComPtr vertexShader; ComPtr pixelShader; -#ifdef _DEBUG +#if defined(_DEBUG) // Enable better shader debugging with the graphics debugging tools. UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else @@ -374,10 +374,11 @@ void D3D12PredicationQueries::LoadAssets() // Create the query result buffer. { + D3D12_RESOURCE_DESC queryResultDesc = CD3DX12_RESOURCE_DESC::Buffer(8); ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, - &CD3DX12_RESOURCE_DESC::Buffer(8), + &queryResultDesc, D3D12_RESOURCE_STATE_PREDICATION, nullptr, IID_PPV_ARGS(&m_queryResult) @@ -438,7 +439,7 @@ void D3D12PredicationQueries::OnRender() m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); // Present the frame. - ThrowIfFailed(m_swapChain->Present(0, 0)); + ThrowIfFailed(m_swapChain->Present(1, 0)); MoveToNextFrame(); } @@ -451,11 +452,6 @@ void D3D12PredicationQueries::OnDestroy() CloseHandle(m_fenceEvent); } -bool D3D12PredicationQueries::OnEvent(MSG) -{ - return false; -} - // Fill the command list with all the render commands and dependent state. void D3D12PredicationQueries::PopulateCommandList() { diff --git a/Samples/D3D12PredicationQueries/src/D3D12PredicationQueries.h b/Samples/D3D12PredicationQueries/src/D3D12PredicationQueries.h index 1c7d87da1..ba1231722 100644 --- a/Samples/D3D12PredicationQueries/src/D3D12PredicationQueries.h +++ b/Samples/D3D12PredicationQueries/src/D3D12PredicationQueries.h @@ -22,12 +22,10 @@ class D3D12PredicationQueries : public DXSample public: D3D12PredicationQueries(UINT width, UINT height, std::wstring name); -protected: virtual void OnInit(); virtual void OnUpdate(); virtual void OnRender(); virtual void OnDestroy(); - virtual bool OnEvent(MSG msg); private: static const UINT FrameCount = 2; diff --git a/Samples/D3D12PredicationQueries/src/D3D12PredicationQueries.vcxproj b/Samples/D3D12PredicationQueries/src/D3D12PredicationQueries.vcxproj index 7e8fd6fb9..a5db5b0c1 100644 --- a/Samples/D3D12PredicationQueries/src/D3D12PredicationQueries.vcxproj +++ b/Samples/D3D12PredicationQueries/src/D3D12PredicationQueries.vcxproj @@ -98,6 +98,7 @@ + @@ -105,6 +106,7 @@ + diff --git a/Samples/D3D12PredicationQueries/src/D3D12PredicationQueries.vcxproj.filters b/Samples/D3D12PredicationQueries/src/D3D12PredicationQueries.vcxproj.filters index deafa2156..cbe17ec71 100644 --- a/Samples/D3D12PredicationQueries/src/D3D12PredicationQueries.vcxproj.filters +++ b/Samples/D3D12PredicationQueries/src/D3D12PredicationQueries.vcxproj.filters @@ -39,6 +39,9 @@ Header Files + + Header Files\Util + @@ -53,6 +56,9 @@ Source Files + + Source Files\Util + diff --git a/Samples/D3D12PredicationQueries/src/DXSample.cpp b/Samples/D3D12PredicationQueries/src/DXSample.cpp index 651f40eb7..663ef590a 100644 --- a/Samples/D3D12PredicationQueries/src/DXSample.cpp +++ b/Samples/D3D12PredicationQueries/src/DXSample.cpp @@ -11,17 +11,13 @@ #include "stdafx.h" #include "DXSample.h" -#include DXSample::DXSample(UINT width, UINT height, std::wstring name) : m_width(width), m_height(height), + m_title(name), m_useWarpDevice(false) { - ParseCommandLineArgs(); - - m_title = name + (m_useWarpDevice ? L" (WARP)" : L""); - WCHAR assetsPath[512]; GetAssetsPath(assetsPath, _countof(assetsPath)); m_assetsPath = assetsPath; @@ -33,67 +29,6 @@ DXSample::~DXSample() { } -int DXSample::Run(HINSTANCE hInstance, int nCmdShow) -{ - // Initialize the window class. - WNDCLASSEX windowClass = { 0 }; - windowClass.cbSize = sizeof(WNDCLASSEX); - windowClass.style = CS_HREDRAW | CS_VREDRAW; - windowClass.lpfnWndProc = WindowProc; - windowClass.hInstance = hInstance; - windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); - windowClass.lpszClassName = L"WindowClass1"; - RegisterClassEx(&windowClass); - - RECT windowRect = { 0, 0, static_cast(m_width), static_cast(m_height) }; - AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); - - // Create the window and store a handle to it. - m_hwnd = CreateWindowEx(NULL, - L"WindowClass1", - m_title.c_str(), - WS_OVERLAPPEDWINDOW, - 300, - 300, - windowRect.right - windowRect.left, - windowRect.bottom - windowRect.top, - NULL, // We have no parent window, NULL. - NULL, // We aren't using menus, NULL. - hInstance, - NULL); // We aren't using multiple windows, NULL. - - ShowWindow(m_hwnd, nCmdShow); - - // Initialize the sample. OnInit is defined in each child-implementation of DXSample. - OnInit(); - - // Main sample loop. - MSG msg = { 0 }; - while (true) - { - // Process any messages in the queue. - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (msg.message == WM_QUIT) - break; - - // Pass events into our sample. - OnEvent(msg); - } - - OnUpdate(); - OnRender(); - } - - OnDestroy(); - - // Return this part of the WM_QUIT message to Windows. - return static_cast(msg.wParam); -} - // Helper function for resolving the full path of assets. std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) { @@ -102,7 +37,8 @@ std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) // Helper function for acquiring the first available hardware adapter that supports Direct3D 12. // If no such adapter can be found, *ppAdapter will be set to nullptr. -void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter) +_Use_decl_annotations_ +void DXSample::GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter) { IDXGIAdapter1* pAdapter = nullptr; *ppAdapter = nullptr; @@ -134,36 +70,20 @@ void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_m void DXSample::SetCustomWindowText(LPCWSTR text) { std::wstring windowText = m_title + L": " + text; - SetWindowText(m_hwnd, windowText.c_str()); + SetWindowText(Win32Application::GetHwnd(), windowText.c_str()); } // Helper function for parsing any supplied command line args. -void DXSample::ParseCommandLineArgs() +_Use_decl_annotations_ +void DXSample::ParseCommandLineArgs(WCHAR* argv[], int argc) { - int argc; - LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc); for (int i = 1; i < argc; ++i) { if (_wcsnicmp(argv[i], L"-warp", wcslen(argv[i])) == 0 || _wcsnicmp(argv[i], L"/warp", wcslen(argv[i])) == 0) { m_useWarpDevice = true; + m_title = m_title + L" (WARP)"; } } - LocalFree(argv); -} - -// Main message handler for the sample. -LRESULT CALLBACK DXSample::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - // Handle destroy/shutdown messages. - switch (message) - { - case WM_DESTROY: - PostQuitMessage(0); - return 0; - } - - // Handle any messages the switch statement didn't. - return DefWindowProc(hWnd, message, wParam, lParam); } diff --git a/Samples/D3D12PredicationQueries/src/DXSample.h b/Samples/D3D12PredicationQueries/src/DXSample.h index 39915ee91..5b417c3b2 100644 --- a/Samples/D3D12PredicationQueries/src/DXSample.h +++ b/Samples/D3D12PredicationQueries/src/DXSample.h @@ -12,6 +12,7 @@ #pragma once #include "DXSampleHelper.h" +#include "Win32Application.h" class DXSample { @@ -19,35 +20,36 @@ class DXSample DXSample(UINT width, UINT height, std::wstring name); virtual ~DXSample(); - int Run(HINSTANCE hInstance, int nCmdShow); - void SetCustomWindowText(LPCWSTR text); - -protected: virtual void OnInit() = 0; virtual void OnUpdate() = 0; virtual void OnRender() = 0; virtual void OnDestroy() = 0; - virtual bool OnEvent(MSG msg) = 0; - std::wstring GetAssetFullPath(LPCWSTR assetName); - void GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + // Samples override the event handlers to handle specific messages. + virtual void OnKeyDown(UINT8 /*key*/) {} + virtual void OnKeyUp(UINT8 /*key*/) {} + + // Accessors. + UINT GetWidth() const { return m_width; } + UINT GetHeight() const { return m_height; } + const WCHAR* GetTitle() const { return m_title.c_str(); } - static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + void ParseCommandLineArgs(_In_reads_(argc) WCHAR* argv[], int argc); + +protected: + std::wstring GetAssetFullPath(LPCWSTR assetName); + void GetHardwareAdapter(_In_ IDXGIFactory2* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + void SetCustomWindowText(LPCWSTR text); // Viewport dimensions. UINT m_width; UINT m_height; float m_aspectRatio; - // Window handle. - HWND m_hwnd; - // Adapter info. bool m_useWarpDevice; private: - void ParseCommandLineArgs(); - // Root assets path. std::wstring m_assetsPath; diff --git a/Samples/D3D12PredicationQueries/src/Main.cpp b/Samples/D3D12PredicationQueries/src/Main.cpp index 268cdea30..df1d1da3e 100644 --- a/Samples/D3D12PredicationQueries/src/Main.cpp +++ b/Samples/D3D12PredicationQueries/src/Main.cpp @@ -16,5 +16,5 @@ _Use_decl_annotations_ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) { D3D12PredicationQueries sample(1280, 720, L"D3D12 Predication and Queries sample"); - return sample.Run(hInstance, nCmdShow); + return Win32Application::Run(&sample, hInstance, nCmdShow); } diff --git a/Samples/D3D12PredicationQueries/src/Win32Application.cpp b/Samples/D3D12PredicationQueries/src/Win32Application.cpp new file mode 100644 index 000000000..9b4a24d55 --- /dev/null +++ b/Samples/D3D12PredicationQueries/src/Win32Application.cpp @@ -0,0 +1,119 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#include "stdafx.h" +#include "Win32Application.h" + +HWND Win32Application::m_hwnd = nullptr; + +int Win32Application::Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow) +{ + // Parse the command line parameters + int argc; + LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc); + pSample->ParseCommandLineArgs(argv, argc); + LocalFree(argv); + + // Initialize the window class. + WNDCLASSEX windowClass = { 0 }; + windowClass.cbSize = sizeof(WNDCLASSEX); + windowClass.style = CS_HREDRAW | CS_VREDRAW; + windowClass.lpfnWndProc = WindowProc; + windowClass.hInstance = hInstance; + windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); + windowClass.lpszClassName = L"DXSampleClass"; + RegisterClassEx(&windowClass); + + RECT windowRect = { 0, 0, static_cast(pSample->GetWidth()), static_cast(pSample->GetHeight()) }; + AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); + + // Create the window and store a handle to it. + m_hwnd = CreateWindow( + windowClass.lpszClassName, + pSample->GetTitle(), + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + windowRect.right - windowRect.left, + windowRect.bottom - windowRect.top, + nullptr, // We have no parent window. + nullptr, // We aren't using menus. + hInstance, + pSample); + + // Initialize the sample. OnInit is defined in each child-implementation of DXSample. + pSample->OnInit(); + + ShowWindow(m_hwnd, nCmdShow); + + // Main sample loop. + MSG msg = {}; + while (msg.message != WM_QUIT) + { + // Process any messages in the queue. + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + pSample->OnDestroy(); + + // Return this part of the WM_QUIT message to Windows. + return static_cast(msg.wParam); +} + +// Main message handler for the sample. +LRESULT CALLBACK Win32Application::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + DXSample* pSample = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); + + switch (message) + { + case WM_CREATE: + { + // Save the DXSample* passed in to CreateWindow. + LPCREATESTRUCT pCreateStruct = reinterpret_cast(lParam); + SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(pCreateStruct->lpCreateParams)); + } + return 0; + + case WM_KEYDOWN: + if (pSample) + { + pSample->OnKeyDown(static_cast(wParam)); + } + return 0; + + case WM_KEYUP: + if (pSample) + { + pSample->OnKeyUp(static_cast(wParam)); + } + return 0; + + case WM_PAINT: + if (pSample) + { + pSample->OnUpdate(); + pSample->OnRender(); + } + return 0; + + case WM_DESTROY: + PostQuitMessage(0); + return 0; + } + + // Handle any messages the switch statement didn't. + return DefWindowProc(hWnd, message, wParam, lParam); +} diff --git a/Samples/D3D12PredicationQueries/src/Win32Application.h b/Samples/D3D12PredicationQueries/src/Win32Application.h new file mode 100644 index 000000000..8d2299164 --- /dev/null +++ b/Samples/D3D12PredicationQueries/src/Win32Application.h @@ -0,0 +1,29 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#pragma once + +#include "DXSample.h" + +class DXSample; + +class Win32Application +{ +public: + static int Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow); + static HWND GetHwnd() { return m_hwnd; } + +protected: + static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + +private: + static HWND m_hwnd; +}; diff --git a/Samples/D3D12PredicationQueries/src/stdafx.h b/Samples/D3D12PredicationQueries/src/stdafx.h index 6c0c4cfbb..e8f990c5f 100644 --- a/Samples/D3D12PredicationQueries/src/stdafx.h +++ b/Samples/D3D12PredicationQueries/src/stdafx.h @@ -29,3 +29,4 @@ #include #include +#include diff --git a/Samples/D3D12nBodyGravity/src/D3D12nBodyGravity.cpp b/Samples/D3D12nBodyGravity/src/D3D12nBodyGravity.cpp index 4b2e2b94a..d843cdf41 100644 --- a/Samples/D3D12nBodyGravity/src/D3D12nBodyGravity.cpp +++ b/Samples/D3D12nBodyGravity/src/D3D12nBodyGravity.cpp @@ -69,7 +69,7 @@ void D3D12nBodyGravity::OnInit() // Load the rendering pipeline dependencies. void D3D12nBodyGravity::LoadPipeline() { -#ifdef _DEBUG +#if defined(_DEBUG) // Enable the D3D12 debug layer. { ComPtr debugController; @@ -121,7 +121,7 @@ void D3D12nBodyGravity::LoadPipeline() swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - swapChainDesc.OutputWindow = m_hwnd; + swapChainDesc.OutputWindow = Win32Application::GetHwnd(); swapChainDesc.SampleDesc.Count = 1; swapChainDesc.Windowed = TRUE; swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT; @@ -136,7 +136,7 @@ void D3D12nBodyGravity::LoadPipeline() ThrowIfFailed(swapChain.As(&m_swapChain)); // This sample does not support fullscreen transitions. - ThrowIfFailed(factory->MakeWindowAssociation(m_hwnd, DXGI_MWA_NO_ALT_ENTER)); + ThrowIfFailed(factory->MakeWindowAssociation(Win32Application::GetHwnd(), DXGI_MWA_NO_ALT_ENTER)); m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); @@ -218,7 +218,7 @@ void D3D12nBodyGravity::LoadAssets() ComPtr pixelShader; ComPtr computeShader; -#ifdef _DEBUG +#if defined(_DEBUG) // Enable better shader debugging with the graphics debugging tools. UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else @@ -441,6 +441,7 @@ void D3D12nBodyGravity::CreateParticleBuffers() D3D12_HEAP_PROPERTIES defaultHeapProperties = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT); D3D12_HEAP_PROPERTIES uploadHeapProperties = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD); D3D12_RESOURCE_DESC bufferDesc = CD3DX12_RESOURCE_DESC::Buffer(dataSize, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS); + D3D12_RESOURCE_DESC uploadBufferDesc = CD3DX12_RESOURCE_DESC::Buffer(dataSize); for (UINT index = 0; index < ThreadCount; index++) { @@ -468,7 +469,7 @@ void D3D12nBodyGravity::CreateParticleBuffers() ThrowIfFailed(m_device->CreateCommittedResource( &uploadHeapProperties, D3D12_HEAP_FLAG_NONE, - &bufferDesc, + &uploadBufferDesc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_particleBuffer0Upload[index]))); @@ -476,7 +477,7 @@ void D3D12nBodyGravity::CreateParticleBuffers() ThrowIfFailed(m_device->CreateCommittedResource( &uploadHeapProperties, D3D12_HEAP_FLAG_NONE, - &bufferDesc, + &uploadBufferDesc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_particleBuffer1Upload[index]))); @@ -600,7 +601,7 @@ void D3D12nBodyGravity::OnRender() m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); // Present the frame. - ThrowIfFailed(m_swapChain->Present(0, 0)); + ThrowIfFailed(m_swapChain->Present(1, 0)); MoveToNextFrame(); } @@ -774,20 +775,14 @@ void D3D12nBodyGravity::OnDestroy() } } -bool D3D12nBodyGravity::OnEvent(MSG msg) +void D3D12nBodyGravity::OnKeyDown(UINT8 key) { - switch (msg.message) - { - case WM_KEYDOWN: - m_camera.OnKeyDown(msg.wParam); - break; - - case WM_KEYUP: - m_camera.OnKeyUp(msg.wParam); - break; - } + m_camera.OnKeyDown(key); +} - return false; +void D3D12nBodyGravity::OnKeyUp(UINT8 key) +{ + m_camera.OnKeyUp(key); } void D3D12nBodyGravity::WaitForRenderContext() diff --git a/Samples/D3D12nBodyGravity/src/D3D12nBodyGravity.h b/Samples/D3D12nBodyGravity/src/D3D12nBodyGravity.h index 5495a4c4e..3f334762d 100644 --- a/Samples/D3D12nBodyGravity/src/D3D12nBodyGravity.h +++ b/Samples/D3D12nBodyGravity/src/D3D12nBodyGravity.h @@ -23,12 +23,12 @@ class D3D12nBodyGravity : public DXSample public: D3D12nBodyGravity(UINT width, UINT height, std::wstring name); -protected: virtual void OnInit(); virtual void OnUpdate(); virtual void OnRender(); virtual void OnDestroy(); - virtual bool OnEvent(MSG msg); + virtual void OnKeyDown(UINT8 key); + virtual void OnKeyUp(UINT8 key); private: static const UINT FrameCount = 2; diff --git a/Samples/D3D12nBodyGravity/src/D3D12nBodyGravity.vcxproj b/Samples/D3D12nBodyGravity/src/D3D12nBodyGravity.vcxproj index e49b509dc..8f041837b 100644 --- a/Samples/D3D12nBodyGravity/src/D3D12nBodyGravity.vcxproj +++ b/Samples/D3D12nBodyGravity/src/D3D12nBodyGravity.vcxproj @@ -98,6 +98,7 @@ + @@ -107,6 +108,7 @@ + diff --git a/Samples/D3D12nBodyGravity/src/D3D12nBodyGravity.vcxproj.filters b/Samples/D3D12nBodyGravity/src/D3D12nBodyGravity.vcxproj.filters index a5c191f8e..7655d2eb9 100644 --- a/Samples/D3D12nBodyGravity/src/D3D12nBodyGravity.vcxproj.filters +++ b/Samples/D3D12nBodyGravity/src/D3D12nBodyGravity.vcxproj.filters @@ -45,6 +45,9 @@ Header Files\Util + + Header Files\Util + @@ -62,6 +65,9 @@ Source Files\Util + + Source Files\Util + diff --git a/Samples/D3D12nBodyGravity/src/DXSample.cpp b/Samples/D3D12nBodyGravity/src/DXSample.cpp index 651f40eb7..663ef590a 100644 --- a/Samples/D3D12nBodyGravity/src/DXSample.cpp +++ b/Samples/D3D12nBodyGravity/src/DXSample.cpp @@ -11,17 +11,13 @@ #include "stdafx.h" #include "DXSample.h" -#include DXSample::DXSample(UINT width, UINT height, std::wstring name) : m_width(width), m_height(height), + m_title(name), m_useWarpDevice(false) { - ParseCommandLineArgs(); - - m_title = name + (m_useWarpDevice ? L" (WARP)" : L""); - WCHAR assetsPath[512]; GetAssetsPath(assetsPath, _countof(assetsPath)); m_assetsPath = assetsPath; @@ -33,67 +29,6 @@ DXSample::~DXSample() { } -int DXSample::Run(HINSTANCE hInstance, int nCmdShow) -{ - // Initialize the window class. - WNDCLASSEX windowClass = { 0 }; - windowClass.cbSize = sizeof(WNDCLASSEX); - windowClass.style = CS_HREDRAW | CS_VREDRAW; - windowClass.lpfnWndProc = WindowProc; - windowClass.hInstance = hInstance; - windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); - windowClass.lpszClassName = L"WindowClass1"; - RegisterClassEx(&windowClass); - - RECT windowRect = { 0, 0, static_cast(m_width), static_cast(m_height) }; - AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); - - // Create the window and store a handle to it. - m_hwnd = CreateWindowEx(NULL, - L"WindowClass1", - m_title.c_str(), - WS_OVERLAPPEDWINDOW, - 300, - 300, - windowRect.right - windowRect.left, - windowRect.bottom - windowRect.top, - NULL, // We have no parent window, NULL. - NULL, // We aren't using menus, NULL. - hInstance, - NULL); // We aren't using multiple windows, NULL. - - ShowWindow(m_hwnd, nCmdShow); - - // Initialize the sample. OnInit is defined in each child-implementation of DXSample. - OnInit(); - - // Main sample loop. - MSG msg = { 0 }; - while (true) - { - // Process any messages in the queue. - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (msg.message == WM_QUIT) - break; - - // Pass events into our sample. - OnEvent(msg); - } - - OnUpdate(); - OnRender(); - } - - OnDestroy(); - - // Return this part of the WM_QUIT message to Windows. - return static_cast(msg.wParam); -} - // Helper function for resolving the full path of assets. std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) { @@ -102,7 +37,8 @@ std::wstring DXSample::GetAssetFullPath(LPCWSTR assetName) // Helper function for acquiring the first available hardware adapter that supports Direct3D 12. // If no such adapter can be found, *ppAdapter will be set to nullptr. -void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter) +_Use_decl_annotations_ +void DXSample::GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter) { IDXGIAdapter1* pAdapter = nullptr; *ppAdapter = nullptr; @@ -134,36 +70,20 @@ void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_m void DXSample::SetCustomWindowText(LPCWSTR text) { std::wstring windowText = m_title + L": " + text; - SetWindowText(m_hwnd, windowText.c_str()); + SetWindowText(Win32Application::GetHwnd(), windowText.c_str()); } // Helper function for parsing any supplied command line args. -void DXSample::ParseCommandLineArgs() +_Use_decl_annotations_ +void DXSample::ParseCommandLineArgs(WCHAR* argv[], int argc) { - int argc; - LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc); for (int i = 1; i < argc; ++i) { if (_wcsnicmp(argv[i], L"-warp", wcslen(argv[i])) == 0 || _wcsnicmp(argv[i], L"/warp", wcslen(argv[i])) == 0) { m_useWarpDevice = true; + m_title = m_title + L" (WARP)"; } } - LocalFree(argv); -} - -// Main message handler for the sample. -LRESULT CALLBACK DXSample::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - // Handle destroy/shutdown messages. - switch (message) - { - case WM_DESTROY: - PostQuitMessage(0); - return 0; - } - - // Handle any messages the switch statement didn't. - return DefWindowProc(hWnd, message, wParam, lParam); } diff --git a/Samples/D3D12nBodyGravity/src/DXSample.h b/Samples/D3D12nBodyGravity/src/DXSample.h index 39915ee91..5b417c3b2 100644 --- a/Samples/D3D12nBodyGravity/src/DXSample.h +++ b/Samples/D3D12nBodyGravity/src/DXSample.h @@ -12,6 +12,7 @@ #pragma once #include "DXSampleHelper.h" +#include "Win32Application.h" class DXSample { @@ -19,35 +20,36 @@ class DXSample DXSample(UINT width, UINT height, std::wstring name); virtual ~DXSample(); - int Run(HINSTANCE hInstance, int nCmdShow); - void SetCustomWindowText(LPCWSTR text); - -protected: virtual void OnInit() = 0; virtual void OnUpdate() = 0; virtual void OnRender() = 0; virtual void OnDestroy() = 0; - virtual bool OnEvent(MSG msg) = 0; - std::wstring GetAssetFullPath(LPCWSTR assetName); - void GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + // Samples override the event handlers to handle specific messages. + virtual void OnKeyDown(UINT8 /*key*/) {} + virtual void OnKeyUp(UINT8 /*key*/) {} + + // Accessors. + UINT GetWidth() const { return m_width; } + UINT GetHeight() const { return m_height; } + const WCHAR* GetTitle() const { return m_title.c_str(); } - static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + void ParseCommandLineArgs(_In_reads_(argc) WCHAR* argv[], int argc); + +protected: + std::wstring GetAssetFullPath(LPCWSTR assetName); + void GetHardwareAdapter(_In_ IDXGIFactory2* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); + void SetCustomWindowText(LPCWSTR text); // Viewport dimensions. UINT m_width; UINT m_height; float m_aspectRatio; - // Window handle. - HWND m_hwnd; - // Adapter info. bool m_useWarpDevice; private: - void ParseCommandLineArgs(); - // Root assets path. std::wstring m_assetsPath; diff --git a/Samples/D3D12nBodyGravity/src/Main.cpp b/Samples/D3D12nBodyGravity/src/Main.cpp index 66c2470f5..8425cc300 100644 --- a/Samples/D3D12nBodyGravity/src/Main.cpp +++ b/Samples/D3D12nBodyGravity/src/Main.cpp @@ -16,5 +16,5 @@ _Use_decl_annotations_ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) { D3D12nBodyGravity sample(1280, 720, L"D3D12 n-Body Gravity Simulation"); - return sample.Run(hInstance, nCmdShow); + return Win32Application::Run(&sample, hInstance, nCmdShow); } diff --git a/Samples/D3D12nBodyGravity/src/Win32Application.cpp b/Samples/D3D12nBodyGravity/src/Win32Application.cpp new file mode 100644 index 000000000..9b4a24d55 --- /dev/null +++ b/Samples/D3D12nBodyGravity/src/Win32Application.cpp @@ -0,0 +1,119 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#include "stdafx.h" +#include "Win32Application.h" + +HWND Win32Application::m_hwnd = nullptr; + +int Win32Application::Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow) +{ + // Parse the command line parameters + int argc; + LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc); + pSample->ParseCommandLineArgs(argv, argc); + LocalFree(argv); + + // Initialize the window class. + WNDCLASSEX windowClass = { 0 }; + windowClass.cbSize = sizeof(WNDCLASSEX); + windowClass.style = CS_HREDRAW | CS_VREDRAW; + windowClass.lpfnWndProc = WindowProc; + windowClass.hInstance = hInstance; + windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); + windowClass.lpszClassName = L"DXSampleClass"; + RegisterClassEx(&windowClass); + + RECT windowRect = { 0, 0, static_cast(pSample->GetWidth()), static_cast(pSample->GetHeight()) }; + AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); + + // Create the window and store a handle to it. + m_hwnd = CreateWindow( + windowClass.lpszClassName, + pSample->GetTitle(), + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + windowRect.right - windowRect.left, + windowRect.bottom - windowRect.top, + nullptr, // We have no parent window. + nullptr, // We aren't using menus. + hInstance, + pSample); + + // Initialize the sample. OnInit is defined in each child-implementation of DXSample. + pSample->OnInit(); + + ShowWindow(m_hwnd, nCmdShow); + + // Main sample loop. + MSG msg = {}; + while (msg.message != WM_QUIT) + { + // Process any messages in the queue. + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + pSample->OnDestroy(); + + // Return this part of the WM_QUIT message to Windows. + return static_cast(msg.wParam); +} + +// Main message handler for the sample. +LRESULT CALLBACK Win32Application::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + DXSample* pSample = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); + + switch (message) + { + case WM_CREATE: + { + // Save the DXSample* passed in to CreateWindow. + LPCREATESTRUCT pCreateStruct = reinterpret_cast(lParam); + SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(pCreateStruct->lpCreateParams)); + } + return 0; + + case WM_KEYDOWN: + if (pSample) + { + pSample->OnKeyDown(static_cast(wParam)); + } + return 0; + + case WM_KEYUP: + if (pSample) + { + pSample->OnKeyUp(static_cast(wParam)); + } + return 0; + + case WM_PAINT: + if (pSample) + { + pSample->OnUpdate(); + pSample->OnRender(); + } + return 0; + + case WM_DESTROY: + PostQuitMessage(0); + return 0; + } + + // Handle any messages the switch statement didn't. + return DefWindowProc(hWnd, message, wParam, lParam); +} diff --git a/Samples/D3D12nBodyGravity/src/Win32Application.h b/Samples/D3D12nBodyGravity/src/Win32Application.h new file mode 100644 index 000000000..8d2299164 --- /dev/null +++ b/Samples/D3D12nBodyGravity/src/Win32Application.h @@ -0,0 +1,29 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#pragma once + +#include "DXSample.h" + +class DXSample; + +class Win32Application +{ +public: + static int Run(DXSample* pSample, HINSTANCE hInstance, int nCmdShow); + static HWND GetHwnd() { return m_hwnd; } + +protected: + static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + +private: + static HWND m_hwnd; +}; diff --git a/Samples/D3D12nBodyGravity/src/stdafx.h b/Samples/D3D12nBodyGravity/src/stdafx.h index 6c0c4cfbb..e8f990c5f 100644 --- a/Samples/D3D12nBodyGravity/src/stdafx.h +++ b/Samples/D3D12nBodyGravity/src/stdafx.h @@ -29,3 +29,4 @@ #include #include +#include