From 8f0dda5eab181b0f14f2652b4e984aaaae3f258c Mon Sep 17 00:00:00 2001 From: rtk0c Date: Mon, 27 Jun 2022 18:27:13 -0700 Subject: Start from a clean slate --- core/src/Entrypoint/Backend.hpp | 23 -- core/src/Entrypoint/Backend_DirectX11.cpp | 250 ---------------- core/src/Entrypoint/Backend_DirectX12.cpp | 470 ------------------------------ core/src/Entrypoint/Backend_Metal.mm | 40 --- core/src/Entrypoint/Backend_OpenGL2.cpp | 106 ------- core/src/Entrypoint/Backend_OpenGL3.cpp | 121 -------- core/src/Entrypoint/Backend_Vulkan.cpp | 438 ---------------------------- core/src/Entrypoint/main.cpp | 163 ----------- 8 files changed, 1611 deletions(-) delete mode 100644 core/src/Entrypoint/Backend.hpp delete mode 100644 core/src/Entrypoint/Backend_DirectX11.cpp delete mode 100644 core/src/Entrypoint/Backend_DirectX12.cpp delete mode 100644 core/src/Entrypoint/Backend_Metal.mm delete mode 100644 core/src/Entrypoint/Backend_OpenGL2.cpp delete mode 100644 core/src/Entrypoint/Backend_OpenGL3.cpp delete mode 100644 core/src/Entrypoint/Backend_Vulkan.cpp delete mode 100644 core/src/Entrypoint/main.cpp (limited to 'core/src/Entrypoint') diff --git a/core/src/Entrypoint/Backend.hpp b/core/src/Entrypoint/Backend.hpp deleted file mode 100644 index ca391e6..0000000 --- a/core/src/Entrypoint/Backend.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include - -class RenderingBackend -{ -public: - // Implemented in Backend_OpenGL2.cpp - static std::unique_ptr CreateOpenGL2Backend(); - // Implemented in Backend_OpenGL3.cpp - static std::unique_ptr CreateOpenGL3Backend(); - // Implemented in Backend_Vulkan.cpp - static std::unique_ptr CreateVulkanBackend(); - // Implemented in Backend_DirectX11.cpp - static std::unique_ptr CreateDx11Backend(); - // Implemented in Backend_DirectX12.cpp - static std::unique_ptr CreateDx12Backend(); - // Implemented in Backend_Metal.cpp - static std::unique_ptr CreateMetalBackend(); - - virtual ~RenderingBackend() = default; - virtual void RunUntilWindowClose(void (*windowContent)()) = 0; -}; diff --git a/core/src/Entrypoint/Backend_DirectX11.cpp b/core/src/Entrypoint/Backend_DirectX11.cpp deleted file mode 100644 index 4dc33f7..0000000 --- a/core/src/Entrypoint/Backend_DirectX11.cpp +++ /dev/null @@ -1,250 +0,0 @@ -#include "Backend.hpp" - -#if BUILD_CORE_WITH_DX11_BACKEND -# include -# include -# include -# include -# include -# include - -// Forward declare message handler from imgui_impl_win32.cpp -extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); - -class DirectX11Backend : public RenderingBackend -{ -private: - HWND hWnd; - WNDCLASSEX wc; - - ID3D11Device* mD3dDevice = nullptr; - ID3D11DeviceContext* mD3dDeviceContext = nullptr; - IDXGISwapChain* mSwapChain = nullptr; - ID3D11RenderTargetView* mMainRenderTargetView = nullptr; - -public: - DirectX11Backend() - { - ImGui_ImplWin32_EnableDpiAwareness(); - - wc.cbSize = sizeof(WNDCLASSEX); - wc.style = CS_CLASSDC; - wc.lpfnWndProc = &StaticWndProc; - wc.cbClsExtra = 0L; - wc.cbWndExtra = 0L; - wc.hInstance = GetModuleHandle(nullptr); - wc.hIcon = nullptr; - wc.hCursor = nullptr; - wc.hbrBackground = nullptr; - wc.lpszMenuName = nullptr; - wc.lpszClassName = _T("Cplt"); - wc.hIconSm = nullptr; - ::RegisterClassEx(&wc); - - hWnd = ::CreateWindow( - wc.lpszClassName, - _T("Cplt main window"), - WS_OVERLAPPEDWINDOW, - /* x */ 100, - /* y */ 100, - /* window width */ 1280, - /* window height */ 800, - nullptr, - nullptr, - wc.hInstance, - this); - - if (!CreateDeviceD3D()) { - CleanupDeviceD3D(); - ::UnregisterClass(wc.lpszClassName, wc.hInstance); - throw std::runtime_error("Failed to create d3d device."); - } - - ::ShowWindow(hWnd, SW_SHOWDEFAULT); - ::UpdateWindow(hWnd); - - IMGUI_CHECKVERSION(); - ImGui::CreateContext(); - - ImGui_ImplWin32_Init(hWnd); - ImGui_ImplDX11_Init(mD3dDevice, mD3dDeviceContext); - } - - virtual ~DirectX11Backend() - { - ImGui_ImplDX11_Shutdown(); - ImGui_ImplWin32_Shutdown(); - ImGui::DestroyContext(); - - CleanupDeviceD3D(); - ::DestroyWindow(hWnd); - ::UnregisterClass(wc.lpszClassName, wc.hInstance); - } - - virtual void RunUntilWindowClose(void (*windowContent)()) - { - while (true) { - MSG msg; - bool done = false; - while (::PeekMessage(&msg, nullptr, 0U, 0U, PM_REMOVE)) { - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); - if (msg.message == WM_QUIT) { - done = true; - } - } - if (done) break; - - ImGui_ImplDX11_NewFrame(); - ImGui_ImplWin32_NewFrame(); - ImGui::NewFrame(); - - windowContent(); - - ImGui::Render(); - const ImVec4 kClearColor = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); - const float kClearColorWithAlpha[4] = { kClearColor.x * kClearColor.w, kClearColor.y * kClearColor.w, kClearColor.z * kClearColor.w, kClearColor.w }; - mD3dDeviceContext->OMSetRenderTargets(1, &mMainRenderTargetView, nullptr); - mD3dDeviceContext->ClearRenderTargetView(mMainRenderTargetView, kClearColorWithAlpha); - ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); - - mSwapChain->Present(1, 0); // Present with vsync - } - } - -private: - bool CreateDeviceD3D() - { - // Setup swap chain - DXGI_SWAP_CHAIN_DESC sd; - ZeroMemory(&sd, sizeof(sd)); - sd.BufferCount = 2; - sd.BufferDesc.Width = 0; - sd.BufferDesc.Height = 0; - sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - sd.BufferDesc.RefreshRate.Numerator = 60; - sd.BufferDesc.RefreshRate.Denominator = 1; - sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; - sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - sd.OutputWindow = hWnd; - sd.SampleDesc.Count = 1; - sd.SampleDesc.Quality = 0; - sd.Windowed = TRUE; - sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; - - UINT createDeviceFlags = 0; - //createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; - D3D_FEATURE_LEVEL featureLevel; - const D3D_FEATURE_LEVEL featureLevelArray[2] = { - D3D_FEATURE_LEVEL_11_0, - D3D_FEATURE_LEVEL_10_0, - }; - if (D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &mSwapChain, &mD3dDevice, &featureLevel, &mD3dDeviceContext) != S_OK) { - return false; - } - - CreateRenderTarget(); - return true; - } - - void CleanupDeviceD3D() - { - CleanupRenderTarget(); - if (mSwapChain) { - mSwapChain->Release(); - mSwapChain = nullptr; - } - if (mD3dDeviceContext) { - mD3dDeviceContext->Release(); - mD3dDeviceContext = nullptr; - } - if (mD3dDevice) { - mD3dDevice->Release(); - mD3dDevice = nullptr; - } - } - - void CreateRenderTarget() - { - ID3D11Texture2D* pBackBuffer; - mSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer)); - mD3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &mMainRenderTargetView); - pBackBuffer->Release(); - } - - void CleanupRenderTarget() - { - if (mMainRenderTargetView) { - mMainRenderTargetView->Release(); - mMainRenderTargetView = nullptr; - } - } - - static LRESULT CALLBACK StaticWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) - { - DirectX11Backend* self; - if (uMsg == WM_NCCREATE) { - auto lpcs = reinterpret_cast(lParam); - self = static_cast(lpcs->lpCreateParams); - self->hWnd = hWnd; - SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(self)); - } else { - self = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); - } - - if (self) { - return self->WndProc(uMsg, wParam, lParam); - } else { - return DefWindowProc(hWnd, uMsg, wParam, lParam); - } - } - - LRESULT WndProc(UINT msg, WPARAM wParam, LPARAM lParam) - { - if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) { - return true; - } - - switch (msg) { - case WM_SIZE: { - if (mD3dDevice != nullptr && wParam != SIZE_MINIMIZED) { - CleanupRenderTarget(); - mSwapChain->ResizeBuffers(0, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam), DXGI_FORMAT_UNKNOWN, 0); - CreateRenderTarget(); - } - return 0; - } - - case WM_SYSCOMMAND: { - // Disable ALT application menu - if ((wParam & 0xfff0) == SC_KEYMENU) { - return 0; - } - } break; - - case WM_DESTROY: { - ::PostQuitMessage(0); - return 0; - } - } - return ::DefWindowProc(hWnd, msg, wParam, lParam); - } -}; - -std::unique_ptr RenderingBackend::CreateDx11Backend() -{ - try { - return std::make_unique(); - } catch (std::exception& e) { - return nullptr; - } -} - -#else // ^^ BUILD_CORE_WITH_DX11_BACKEND | BUILD_CORE_WITH_DX11_BACKEND vv - -std::unique_ptr RenderingBackend::CreateDx11Backend() -{ - return nullptr; -} - -#endif diff --git a/core/src/Entrypoint/Backend_DirectX12.cpp b/core/src/Entrypoint/Backend_DirectX12.cpp deleted file mode 100644 index fd4a531..0000000 --- a/core/src/Entrypoint/Backend_DirectX12.cpp +++ /dev/null @@ -1,470 +0,0 @@ -#include "Backend.hpp" - -#if BUILD_CORE_WITH_DX12_BACKEND -# include -# include -# include -# include -# include -# include -# include - -constexpr int kNumFramesInFlight = 3; -constexpr int kNumBackBuffers = 3; - -// Forward declare message handler from imgui_impl_win32.cpp -extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); - -class DirectX12Backend : public RenderingBackend -{ -private: - struct FrameContext - { - ID3D12CommandAllocator* CommandAllocator; - UINT64 FenceValue; - }; - - HWND hWnd; - WNDCLASSEX wc; - - FrameContext mFrameContext[kNumFramesInFlight] = {}; - UINT mFrameIndex = 0; - - ID3D12Device* mD3dDevice = nullptr; - ID3D12DescriptorHeap* mD3dRtvDescHeap = nullptr; - ID3D12DescriptorHeap* mD3dSrvDescHeap = nullptr; - ID3D12CommandQueue* mD3dCommandQueue = nullptr; - ID3D12GraphicsCommandList* mD3dCommandList = nullptr; - ID3D12Fence* mFence = nullptr; - HANDLE mFenceEvent = nullptr; - UINT64 mFenceLastSignaledValue = 0; - IDXGISwapChain3* mSwapChain = nullptr; - HANDLE mSwapChainWaitableObject = nullptr; - ID3D12Resource* mMainRenderTargetResource[kNumBackBuffers] = {}; - D3D12_CPU_DESCRIPTOR_HANDLE mMainRenderTargetDescriptor[kNumBackBuffers] = {}; - -public: - DirectX12Backend() - { - ImGui_ImplWin32_EnableDpiAwareness(); - - wc.cbSize = sizeof(WNDCLASSEX); - wc.style = CS_CLASSDC; - wc.lpfnWndProc = &StaticWndProc; - wc.cbClsExtra = 0L; - wc.cbWndExtra = 0L; - wc.hInstance = GetModuleHandle(nullptr); - wc.hIcon = nullptr; - wc.hCursor = nullptr; - wc.hbrBackground = nullptr; - wc.lpszMenuName = nullptr; - wc.lpszClassName = _T("Cplt"); - wc.hIconSm = nullptr; - ::RegisterClassEx(&wc); - - hWnd = ::CreateWindow( - wc.lpszClassName, - _T("Cplt main window"), - WS_OVERLAPPEDWINDOW, - /* x */ 100, - /* y */ 100, - /* window width */ 1280, - /* window height */ 800, - nullptr, - nullptr, - wc.hInstance, - this); - - if (!CreateDeviceD3D()) { - CleanupDeviceD3D(); - ::UnregisterClass(wc.lpszClassName, wc.hInstance); - throw std::runtime_error("Failed to create d3d device."); - } - - ::ShowWindow(hWnd, SW_SHOWDEFAULT); - ::UpdateWindow(hWnd); - - IMGUI_CHECKVERSION(); - ImGui::CreateContext(); - - ImGui_ImplWin32_Init(hWnd); - ImGui_ImplDX12_Init(mD3dDevice, kNumFramesInFlight, DXGI_FORMAT_R8G8B8A8_UNORM, mD3dSrvDescHeap, mD3dSrvDescHeap->GetCPUDescriptorHandleForHeapStart(), mD3dSrvDescHeap->GetGPUDescriptorHandleForHeapStart()); - } - - virtual ~DirectX12Backend() - { - WaitForLastSubmittedFrame(); - - // Cleanup - ImGui_ImplDX12_Shutdown(); - ImGui_ImplWin32_Shutdown(); - ImGui::DestroyContext(); - - CleanupDeviceD3D(); - ::DestroyWindow(hWnd); - ::UnregisterClass(wc.lpszClassName, wc.hInstance); - } - - virtual void RunUntilWindowClose(void (*windowContent)()) - { - while (true) { - MSG msg; - bool done = false; - while (::PeekMessage(&msg, nullptr, 0U, 0U, PM_REMOVE)) - { - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); - if (msg.message == WM_QUIT) { - done = true; - } - } - if (done) break; - - // Start the Dear ImGui frame - ImGui_ImplDX12_NewFrame(); - ImGui_ImplWin32_NewFrame(); - ImGui::NewFrame(); - - windowContent(); - - ImGui::Render(); - - FrameContext* frameCtx = WaitForNextFrameResources(); - UINT backBufferIdx = mSwapChain->GetCurrentBackBufferIndex(); - frameCtx->CommandAllocator->Reset(); - - D3D12_RESOURCE_BARRIER barrier = {}; - barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - barrier.Transition.pResource = mMainRenderTargetResource[backBufferIdx]; - barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT; - barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; - mD3dCommandList->Reset(frameCtx->CommandAllocator, nullptr); - mD3dCommandList->ResourceBarrier(1, &barrier); - - const ImVec4 kClearColor = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); - const float kClearColorWithAlpha[4] = { kClearColor.x * kClearColor.w, kClearColor.y * kClearColor.w, kClearColor.z * kClearColor.w, kClearColor.w }; - mD3dCommandList->ClearRenderTargetView(mMainRenderTargetDescriptor[backBufferIdx], kClearColorWithAlpha, 0, nullptr); - mD3dCommandList->OMSetRenderTargets(1, &mMainRenderTargetDescriptor[backBufferIdx], FALSE, nullptr); - mD3dCommandList->SetDescriptorHeaps(1, &mD3dSrvDescHeap); - ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), mD3dCommandList); - barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; - barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT; - mD3dCommandList->ResourceBarrier(1, &barrier); - mD3dCommandList->Close(); - - mD3dCommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&mD3dCommandList); - - mSwapChain->Present(1, 0); // Present with vsync - - UINT64 fenceValue = mFenceLastSignaledValue + 1; - mD3dCommandQueue->Signal(mFence, fenceValue); - mFenceLastSignaledValue = fenceValue; - frameCtx->FenceValue = fenceValue; - } - } - -private: - bool CreateDeviceD3D() - { - // Setup swap chain - DXGI_SWAP_CHAIN_DESC1 sd; - { - ZeroMemory(&sd, sizeof(sd)); - sd.BufferCount = kNumBackBuffers; - sd.Width = 0; - sd.Height = 0; - sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - sd.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT; - sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - sd.SampleDesc.Count = 1; - sd.SampleDesc.Quality = 0; - sd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - sd.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; - sd.Scaling = DXGI_SCALING_STRETCH; - sd.Stereo = FALSE; - } - - // Create device - D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0; - if (D3D12CreateDevice(nullptr, featureLevel, IID_PPV_ARGS(&mD3dDevice)) != S_OK) { - return false; - } - - { - D3D12_DESCRIPTOR_HEAP_DESC desc = {}; - desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; - desc.NumDescriptors = kNumBackBuffers; - desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; - desc.NodeMask = 1; - if (mD3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&mD3dRtvDescHeap)) != S_OK) { - return false; - } - - SIZE_T rtvDescriptorSize = mD3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); - D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = mD3dRtvDescHeap->GetCPUDescriptorHandleForHeapStart(); - for (UINT i = 0; i < kNumBackBuffers; i++) { - mMainRenderTargetDescriptor[i] = rtvHandle; - rtvHandle.ptr += rtvDescriptorSize; - } - } - - { - D3D12_DESCRIPTOR_HEAP_DESC desc = {}; - desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; - desc.NumDescriptors = 1; - desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; - if (mD3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&mD3dSrvDescHeap)) != S_OK) { - return false; - } - } - - { - D3D12_COMMAND_QUEUE_DESC desc = {}; - desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; - desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; - desc.NodeMask = 1; - if (mD3dDevice->CreateCommandQueue(&desc, IID_PPV_ARGS(&mD3dCommandQueue)) != S_OK) { - return false; - } - } - - for (UINT i = 0; i < kNumFramesInFlight; i++) { - if (mD3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&mFrameContext[i].CommandAllocator)) != S_OK) { - return false; - } - } - - if (mD3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, mFrameContext[0].CommandAllocator, nullptr, IID_PPV_ARGS(&mD3dCommandList)) != S_OK || - mD3dCommandList->Close() != S_OK) - { - return false; - } - - if (mD3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&mFence)) != S_OK) return false; - - mFenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); - if (mFenceEvent == nullptr) return false; - - { - IDXGIFactory4* dxgiFactory = nullptr; - IDXGISwapChain1* swapChain1 = nullptr; - if (CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory)) != S_OK) - return false; - if (dxgiFactory->CreateSwapChainForHwnd(mD3dCommandQueue, hWnd, &sd, nullptr, nullptr, &swapChain1) != S_OK) - return false; - if (swapChain1->QueryInterface(IID_PPV_ARGS(&mSwapChain)) != S_OK) - return false; - swapChain1->Release(); - dxgiFactory->Release(); - mSwapChain->SetMaximumFrameLatency(kNumBackBuffers); - mSwapChainWaitableObject = mSwapChain->GetFrameLatencyWaitableObject(); - } - - CreateRenderTarget(); - return true; - } - - void CleanupDeviceD3D() - { - CleanupRenderTarget(); - if (mSwapChain) { - mSwapChain->Release(); - mSwapChain = nullptr; - } - if (mSwapChainWaitableObject != nullptr) { - CloseHandle(mSwapChainWaitableObject); - } - for (UINT i = 0; i < kNumFramesInFlight; i++) - if (mFrameContext[i].CommandAllocator) { - mFrameContext[i].CommandAllocator->Release(); - mFrameContext[i].CommandAllocator = nullptr; - } - if (mD3dCommandQueue) { - mD3dCommandQueue->Release(); - mD3dCommandQueue = nullptr; - } - if (mD3dCommandList) { - mD3dCommandList->Release(); - mD3dCommandList = nullptr; - } - if (mD3dRtvDescHeap) { - mD3dRtvDescHeap->Release(); - mD3dRtvDescHeap = nullptr; - } - if (mD3dSrvDescHeap) { - mD3dSrvDescHeap->Release(); - mD3dSrvDescHeap = nullptr; - } - if (mFence) { - mFence->Release(); - mFence = nullptr; - } - if (mFenceEvent) { - CloseHandle(mFenceEvent); - mFenceEvent = nullptr; - } - if (mD3dDevice) { - mD3dDevice->Release(); - mD3dDevice = nullptr; - } - } - - void CreateRenderTarget() - { - for (UINT i = 0; i < kNumBackBuffers; i++) - { - ID3D12Resource* pBackBuffer = nullptr; - mSwapChain->GetBuffer(i, IID_PPV_ARGS(&pBackBuffer)); - mD3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, mMainRenderTargetDescriptor[i]); - mMainRenderTargetResource[i] = pBackBuffer; - } - } - - void CleanupRenderTarget() - { - WaitForLastSubmittedFrame(); - - for (UINT i = 0; i < kNumBackBuffers; i++) - if (mMainRenderTargetResource[i]) { - mMainRenderTargetResource[i]->Release(); - mMainRenderTargetResource[i] = nullptr; - } - } - - void WaitForLastSubmittedFrame() - { - FrameContext* frameCtx = &mFrameContext[mFrameIndex % kNumFramesInFlight]; - - UINT64 fenceValue = frameCtx->FenceValue; - if (fenceValue == 0) - return; // No fence was signaled - - frameCtx->FenceValue = 0; - if (mFence->GetCompletedValue() >= fenceValue) - return; - - mFence->SetEventOnCompletion(fenceValue, mFenceEvent); - WaitForSingleObject(mFenceEvent, INFINITE); - } - - FrameContext* WaitForNextFrameResources() - { - UINT nextFrameIndex = mFrameIndex + 1; - mFrameIndex = nextFrameIndex; - - HANDLE waitableObjects[] = { mSwapChainWaitableObject, nullptr }; - DWORD numWaitableObjects = 1; - - FrameContext* frameCtx = &mFrameContext[nextFrameIndex % kNumFramesInFlight]; - UINT64 fenceValue = frameCtx->FenceValue; - if (fenceValue != 0) // means no fence was signaled - { - frameCtx->FenceValue = 0; - mFence->SetEventOnCompletion(fenceValue, mFenceEvent); - waitableObjects[1] = mFenceEvent; - numWaitableObjects = 2; - } - - WaitForMultipleObjects(numWaitableObjects, waitableObjects, TRUE, INFINITE); - - return frameCtx; - } - - void ResizeSwapChain(int width, int height) - { - DXGI_SWAP_CHAIN_DESC1 sd; - mSwapChain->GetDesc1(&sd); - sd.Width = width; - sd.Height = height; - - IDXGIFactory4* dxgiFactory = nullptr; - mSwapChain->GetParent(IID_PPV_ARGS(&dxgiFactory)); - - mSwapChain->Release(); - CloseHandle(mSwapChainWaitableObject); - - IDXGISwapChain1* swapChain1 = nullptr; - dxgiFactory->CreateSwapChainForHwnd(mD3dCommandQueue, hWnd, &sd, nullptr, nullptr, &swapChain1); - swapChain1->QueryInterface(IID_PPV_ARGS(&mSwapChain)); - swapChain1->Release(); - dxgiFactory->Release(); - - mSwapChain->SetMaximumFrameLatency(kNumBackBuffers); - - mSwapChainWaitableObject = mSwapChain->GetFrameLatencyWaitableObject(); - assert(mSwapChainWaitableObject != nullptr); - } - - static LRESULT CALLBACK StaticWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) - { - DirectX12Backend* self; - if (uMsg == WM_NCCREATE) { - auto lpcs = reinterpret_cast(lParam); - self = static_cast(lpcs->lpCreateParams); - self->hWnd = hWnd; - SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(self)); - } else { - self = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); - } - - if (self) { - return self->WndProc(uMsg, wParam, lParam); - } else { - return DefWindowProc(hWnd, uMsg, wParam, lParam); - } - } - - LRESULT WndProc(UINT msg, WPARAM wParam, LPARAM lParam) - { - if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) { - return true; - } - - switch (msg) { - case WM_SIZE: { - if (mD3dDevice != nullptr && wParam != SIZE_MINIMIZED) { - WaitForLastSubmittedFrame(); - ImGui_ImplDX12_InvalidateDeviceObjects(); - CleanupRenderTarget(); - ResizeSwapChain((UINT)LOWORD(lParam), (UINT)HIWORD(lParam)); - CreateRenderTarget(); - ImGui_ImplDX12_CreateDeviceObjects(); - } - return 0; - } - - case WM_SYSCOMMAND: { - // Disable ALT application menu - if ((wParam & 0xfff0) == SC_KEYMENU) { - return 0; - } - } break; - - case WM_DESTROY: { - ::PostQuitMessage(0); - return 0; - } - } - return ::DefWindowProc(hWnd, msg, wParam, lParam); - } -}; - -std::unique_ptr RenderingBackend::CreateDx12Backend() -{ - try { - return std::make_unique(); - } catch (std::exception& e) { - return nullptr; - } -} - -#else // ^^ BUILD_CORE_WITH_DX12_BACKEND | BUILD_CORE_WITH_DX12_BACKEND vv - -std::unique_ptr RenderingBackend::CreateDx12Backend() -{ - return nullptr; -} - -#endif diff --git a/core/src/Entrypoint/Backend_Metal.mm b/core/src/Entrypoint/Backend_Metal.mm deleted file mode 100644 index 276bef2..0000000 --- a/core/src/Entrypoint/Backend_Metal.mm +++ /dev/null @@ -1,40 +0,0 @@ -#include "Backend.hpp" - -#if BUILD_CORE_WITH_METAL_BACKEND - -class MetalBackend : public RenderingBackend -{ -public: - MetalBackend() - { - // TODO - } - - virtual ~MetalBackend() - { - // TODO - } - - virtual void RunUntilWindowClose(void (*windowContent)()) - { - // TODO - } -}; - -std::unique_ptr RenderingBackend::CreateMetalBackend() -{ - try { - return std::make_unique(); - } catch (std::exception& e) { - return nullptr; - } -} - -#else // ^^ BUILD_CORE_WITH_METAL_BACKEND | BUILD_CORE_WITH_METAL_BACKEND vv - -std::unique_ptr RenderingBackend::CreateMetalBackend() -{ - return nullptr; -} - -#endif diff --git a/core/src/Entrypoint/Backend_OpenGL2.cpp b/core/src/Entrypoint/Backend_OpenGL2.cpp deleted file mode 100644 index 8f80094..0000000 --- a/core/src/Entrypoint/Backend_OpenGL2.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include "Entrypoint/Backend.hpp" - -#if BUILD_CORE_WITH_OPENGL2_BACKEND -# include - -# include -# include -# include -# include -# include -# include - -# define IMGUI_IMPL_OPENGL_LOADER_CUSTOM -# include - -class OpenGL2Backend : public RenderingBackend -{ -private: - GLFWwindow* mWindow; - -public: - OpenGL2Backend() - { - glfwSetErrorCallback(&GlfwErrorCallback); - if (!glfwInit()) { - throw std::runtime_error("Failed to initialize GLFW."); - } - - mWindow = glfwCreateWindow(1280, 720, "Cplt", nullptr, nullptr); - if (mWindow == nullptr) { - throw std::runtime_error("Failed to create GLFW window."); - } - glfwMakeContextCurrent(mWindow); - glfwSwapInterval(1); // Enable vsync - - if (gladLoadGLLoader((GLADloadproc)glfwGetProcAddress) == 0) { - throw std::runtime_error("Failed to initialize OpenGL."); - } - - IMGUI_CHECKVERSION(); - ImGui::CreateContext(); - - ImGui_ImplGlfw_InitForOpenGL(mWindow, true); - ImGui_ImplOpenGL2_Init(); - } - - virtual ~OpenGL2Backend() - { - ImGui_ImplOpenGL2_Shutdown(); - ImGui_ImplGlfw_Shutdown(); - ImGui::DestroyContext(); - - glfwDestroyWindow(mWindow); - glfwTerminate(); - } - - virtual void RunUntilWindowClose(void (*windowContent)()) - { - while (!glfwWindowShouldClose(mWindow)) { - glfwPollEvents(); - - ImGui_ImplOpenGL2_NewFrame(); - ImGui_ImplGlfw_NewFrame(); - ImGui::NewFrame(); - - windowContent(); - - int displayWidth, displayHeight; - glfwGetFramebufferSize(mWindow, &displayWidth, &displayHeight); - glViewport(0, 0, displayWidth, displayHeight); - - const ImVec4 kClearColor = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); - glClearColor(kClearColor.x * kClearColor.w, kClearColor.y * kClearColor.w, kClearColor.z * kClearColor.w, kClearColor.w); - glClear(GL_COLOR_BUFFER_BIT); - - ImGui::Render(); - ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData()); - - glfwMakeContextCurrent(mWindow); - glfwSwapBuffers(mWindow); - } - } - - static void GlfwErrorCallback(int errorCode, const char* message) - { - std::cerr << "GLFW Error " << errorCode << ": " << message << "\n"; - } -}; - -std::unique_ptr RenderingBackend::CreateOpenGL2Backend() -{ - try { - return std::make_unique(); - } catch (std::exception& e) { - return nullptr; - } -} - -#else // ^^ BUILD_CORE_WITH_OPENGL2_BACKEND | !BUILD_CORE_WITH_OPENGL2_BACKEND vv - -std::unique_ptr RenderingBackend::CreateOpenGL2Backend() -{ - return nullptr; -} - -#endif diff --git a/core/src/Entrypoint/Backend_OpenGL3.cpp b/core/src/Entrypoint/Backend_OpenGL3.cpp deleted file mode 100644 index 96a260a..0000000 --- a/core/src/Entrypoint/Backend_OpenGL3.cpp +++ /dev/null @@ -1,121 +0,0 @@ -#include "Entrypoint/Backend.hpp" - -#if BUILD_CORE_WITH_OPENGL3_BACKEND -# include - -# include -# include -# include -# include -# include -# include - -# define IMGUI_IMPL_OPENGL_LOADER_CUSTOM -# include - -class OpenGL3Backend : public RenderingBackend -{ -private: - GLFWwindow* mWindow; - -public: - OpenGL3Backend() - { - glfwSetErrorCallback(&GlfwErrorCallback); - if (!glfwInit()) { - throw std::runtime_error("Failed to initialize GLFW."); - } - -# if defined(__APPLE__) - // GL 3.2 + GLSL 150 - const char* glslVersion = "#version 150"; - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac -# else - // GL 3.0 + GLSL 130 - const char* glslVersion = "#version 130"; - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); - // glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only - // glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 3.0+ only -# endif - - mWindow = glfwCreateWindow(1280, 720, "Cplt", nullptr, nullptr); - if (mWindow == nullptr) { - throw std::runtime_error("Failed to create GLFW window."); - } - glfwMakeContextCurrent(mWindow); - glfwSwapInterval(1); // Enable vsync - - if (gladLoadGLLoader((GLADloadproc)glfwGetProcAddress) == 0) { - throw std::runtime_error("Failed to initialize OpenGL."); - } - - IMGUI_CHECKVERSION(); - ImGui::CreateContext(); - - ImGui_ImplGlfw_InitForOpenGL(mWindow, true); - ImGui_ImplOpenGL3_Init(glslVersion); - } - - virtual ~OpenGL3Backend() - { - ImGui_ImplOpenGL3_Shutdown(); - ImGui_ImplGlfw_Shutdown(); - ImGui::DestroyContext(); - - glfwDestroyWindow(mWindow); - glfwTerminate(); - } - - virtual void RunUntilWindowClose(void (*windowContent)()) - { - while (!glfwWindowShouldClose(mWindow)) { - glfwPollEvents(); - - ImGui_ImplOpenGL3_NewFrame(); - ImGui_ImplGlfw_NewFrame(); - ImGui::NewFrame(); - - windowContent(); - - int displayWidth, displayHeight; - glfwGetFramebufferSize(mWindow, &displayWidth, &displayHeight); - glViewport(0, 0, displayWidth, displayHeight); - - const ImVec4 kClearColor = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); - glClearColor(kClearColor.x * kClearColor.w, kClearColor.y * kClearColor.w, kClearColor.z * kClearColor.w, kClearColor.w); - glClear(GL_COLOR_BUFFER_BIT); - - ImGui::Render(); - ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); - - glfwSwapBuffers(mWindow); - } - } - - static void GlfwErrorCallback(int errorCode, const char* message) - { - std::cerr << "GLFW Error " << errorCode << ": " << message << "\n"; - } -}; - -std::unique_ptr RenderingBackend::CreateOpenGL3Backend() -{ - try { - return std::make_unique(); - } catch (std::exception& e) { - return nullptr; - } -} - -#else // ^^ BUILD_CORE_WITH_OPENGL3_BACKEND | !BUILD_CORE_WITH_OPENGL3_BACKEND vv - -std::unique_ptr RenderingBackend::CreateOpenGL3Backend() -{ - return nullptr; -} - -#endif diff --git a/core/src/Entrypoint/Backend_Vulkan.cpp b/core/src/Entrypoint/Backend_Vulkan.cpp deleted file mode 100644 index de3b5ca..0000000 --- a/core/src/Entrypoint/Backend_Vulkan.cpp +++ /dev/null @@ -1,438 +0,0 @@ -#include "Entrypoint/Backend.hpp" - -#if BUILD_CORE_WITH_VULKAN_BACKEND -# include -# include - -# define GLFW_INCLUDE_NONE -# define GLFW_INCLUDE_VULKAN -# include - -# include -# include -# include - -class VulkanBackend : public RenderingBackend -{ -private: - GLFWwindow* mWindow; - - VkAllocationCallbacks* mAllocator = NULL; - VkInstance mInstance = VK_NULL_HANDLE; - VkPhysicalDevice mPhysicalDevice = VK_NULL_HANDLE; - VkDevice mDevice = VK_NULL_HANDLE; - uint32_t mQueueFamily = (uint32_t)-1; - VkQueue mQueue = VK_NULL_HANDLE; - VkDebugReportCallbackEXT mDebugReport = VK_NULL_HANDLE; - VkPipelineCache mPipelineCache = VK_NULL_HANDLE; - VkDescriptorPool mDescriptorPool = VK_NULL_HANDLE; - - ImGui_ImplVulkanH_Window mMainWindowData; - int mMinImageCount = 2; - bool mSwapChainRebuild = false; - -public: - VulkanBackend() - { - glfwSetErrorCallback(&GlfwErrorCallback); - if (!glfwInit()) { - throw std::runtime_error("Failed to initialize GLFW."); - } - - glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - mWindow = glfwCreateWindow(1280, 720, "Cplt", nullptr, nullptr); - if (mWindow == nullptr) { - throw std::runtime_error("Failed to create GLFW window."); - } - - if (!glfwVulkanSupported()) { - throw std::runtime_error("GLFW reports vulkan not supported."); - } - - uint32_t extensionsCount = 0; - const char** extensions = glfwGetRequiredInstanceExtensions(&extensionsCount); - SetupVulkan(extensions, extensionsCount); - - // Create window surface - VkSurfaceKHR surface; - VkResult err = glfwCreateWindowSurface(mInstance, mWindow, mAllocator, &surface); - CheckVkResults(err); - - // Create framebuffers - int w, h; - glfwGetFramebufferSize(mWindow, &w, &h); - SetupVulkanWindow(&mMainWindowData, surface, w, h); - - IMGUI_CHECKVERSION(); - ImGui::CreateContext(); - - ImGui_ImplGlfw_InitForVulkan(mWindow, true); - ImGui_ImplVulkan_InitInfo init_info = {}; - init_info.Instance = mInstance; - init_info.PhysicalDevice = mPhysicalDevice; - init_info.Device = mDevice; - init_info.QueueFamily = mQueueFamily; - init_info.Queue = mQueue; - init_info.PipelineCache = mPipelineCache; - init_info.DescriptorPool = mDescriptorPool; - init_info.Allocator = mAllocator; - init_info.MinImageCount = mMinImageCount; - init_info.ImageCount = mMainWindowData.ImageCount; - init_info.CheckVkResultFn = CheckVkResults; - ImGui_ImplVulkan_Init(&init_info, mMainWindowData.RenderPass); - } - - virtual ~VulkanBackend() - { - auto err = vkDeviceWaitIdle(mDevice); - CheckVkResults(err); - ImGui_ImplVulkan_Shutdown(); - ImGui_ImplGlfw_Shutdown(); - ImGui::DestroyContext(); - - CleanupVulkanWindow(); - CleanupVulkan(); - - glfwDestroyWindow(mWindow); - glfwTerminate(); - } - - virtual void RunUntilWindowClose(void (*windowContent)()) override - { - // Upload Fonts - { - // Use any command queue - VkCommandPool commandPool = mMainWindowData.Frames[mMainWindowData.FrameIndex].CommandPool; - VkCommandBuffer commandBuffer = mMainWindowData.Frames[mMainWindowData.FrameIndex].CommandBuffer; - - CheckVkResults(vkResetCommandPool(mDevice, commandPool, 0)); - VkCommandBufferBeginInfo beginInfo = {}; - beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - beginInfo.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - CheckVkResults(vkBeginCommandBuffer(commandBuffer, &beginInfo)); - - ImGui_ImplVulkan_CreateFontsTexture(commandBuffer); - - VkSubmitInfo endInfo = {}; - endInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - endInfo.commandBufferCount = 1; - endInfo.pCommandBuffers = &commandBuffer; - CheckVkResults(vkEndCommandBuffer(commandBuffer)); - CheckVkResults(vkQueueSubmit(mQueue, 1, &endInfo, VK_NULL_HANDLE)); - - CheckVkResults(vkDeviceWaitIdle(mDevice)); - ImGui_ImplVulkan_DestroyFontUploadObjects(); - } - - while (!glfwWindowShouldClose(mWindow)) { - glfwPollEvents(); - - // Resize swap chain? - if (mSwapChainRebuild) { - int width, height; - glfwGetFramebufferSize(mWindow, &width, &height); - if (width > 0 && height > 0) { - ImGui_ImplVulkan_SetMinImageCount(mMinImageCount); - ImGui_ImplVulkanH_CreateOrResizeWindow(mInstance, mPhysicalDevice, mDevice, &mMainWindowData, mQueueFamily, mAllocator, width, height, mMinImageCount); - mMainWindowData.FrameIndex = 0; - mSwapChainRebuild = false; - } - } - - // Start the Dear ImGui frame - ImGui_ImplVulkan_NewFrame(); - ImGui_ImplGlfw_NewFrame(); - ImGui::NewFrame(); - - windowContent(); - - ImGui::Render(); - ImDrawData* drawData = ImGui::GetDrawData(); - const bool isMinimized = (drawData->DisplaySize.x <= 0.0f || drawData->DisplaySize.y <= 0.0f); - if (!isMinimized) { - const ImVec4 kClearColor = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); - mMainWindowData.ClearValue.color.float32[0] = kClearColor.x * kClearColor.w; - mMainWindowData.ClearValue.color.float32[1] = kClearColor.y * kClearColor.w; - mMainWindowData.ClearValue.color.float32[2] = kClearColor.z * kClearColor.w; - mMainWindowData.ClearValue.color.float32[3] = kClearColor.w; - FrameRender(&mMainWindowData, drawData); - FramePresent(&mMainWindowData); - } - } - } - -private: - void SetupVulkan(const char** extensions, uint32_t extensions_count) - { - VkResult err; - - // Create Vulkan Instance - { - VkInstanceCreateInfo createInfo = {}; - createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - createInfo.enabledExtensionCount = extensions_count; - createInfo.ppEnabledExtensionNames = extensions; - // Create Vulkan Instance without any debug feature - err = vkCreateInstance(&createInfo, mAllocator, &mInstance); - CheckVkResults(err); - } - - // Select GPU - { - uint32_t gpuCount; - err = vkEnumeratePhysicalDevices(mInstance, &gpuCount, NULL); - CheckVkResults(err); - IM_ASSERT(gpuCount > 0); - - VkPhysicalDevice* gpus = (VkPhysicalDevice*)malloc(sizeof(VkPhysicalDevice) * gpuCount); - err = vkEnumeratePhysicalDevices(mInstance, &gpuCount, gpus); - CheckVkResults(err); - - // If a number >1 of GPUs got reported, find discrete GPU if present, or use first one available. This covers - // most common cases (multi-gpu/integrated+dedicated graphics). Handling more complicated setups (multiple - // dedicated GPUs) is out of scope of this sample. - int useGpu = 0; - for (int i = 0; i < (int)gpuCount; i++) - { - VkPhysicalDeviceProperties properties; - vkGetPhysicalDeviceProperties(gpus[i], &properties); - if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) - { - useGpu = i; - break; - } - } - - mPhysicalDevice = gpus[useGpu]; - free(gpus); - } - - // Select graphics queue family - { - uint32_t count; - vkGetPhysicalDeviceQueueFamilyProperties(mPhysicalDevice, &count, NULL); - - auto queues = std::make_unique(count); - vkGetPhysicalDeviceQueueFamilyProperties(mPhysicalDevice, &count, queues.get()); - for (uint32_t i = 0; i < count; i++) { - if (queues[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) - { - mQueueFamily = i; - break; - } - } - - IM_ASSERT(mQueueFamily != (uint32_t)-1); - } - - // Create Logical Device (with 1 queue) - { - int deviceExtensionCount = 1; - const char* deviceExtensions[] = { "VK_KHR_swapchain" }; - const float queuePriority[] = { 1.0f }; - VkDeviceQueueCreateInfo queue_info[1] = {}; - queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - queue_info[0].queueFamilyIndex = mQueueFamily; - queue_info[0].queueCount = 1; - queue_info[0].pQueuePriorities = queuePriority; - VkDeviceCreateInfo createInfo = {}; - createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - createInfo.queueCreateInfoCount = sizeof(queue_info) / sizeof(queue_info[0]); - createInfo.pQueueCreateInfos = queue_info; - createInfo.enabledExtensionCount = deviceExtensionCount; - createInfo.ppEnabledExtensionNames = deviceExtensions; - err = vkCreateDevice(mPhysicalDevice, &createInfo, mAllocator, &mDevice); - CheckVkResults(err); - vkGetDeviceQueue(mDevice, mQueueFamily, 0, &mQueue); - } - - // Create Descriptor Pool - { - VkDescriptorPoolSize poolSizes[] = { - { VK_DESCRIPTOR_TYPE_SAMPLER, 1000 }, - { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 }, - { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000 }, - { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 }, - { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000 }, - { VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000 }, - { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000 }, - { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 }, - { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 }, - { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 }, - { VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 } - }; - VkDescriptorPoolCreateInfo poolInfo = {}; - poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - poolInfo.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; - poolInfo.maxSets = 1000 * IM_ARRAYSIZE(poolSizes); - poolInfo.poolSizeCount = (uint32_t)IM_ARRAYSIZE(poolSizes); - poolInfo.pPoolSizes = poolSizes; - err = vkCreateDescriptorPool(mDevice, &poolInfo, mAllocator, &mDescriptorPool); - CheckVkResults(err); - } - } - - void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface, int width, int height) - { - wd->Surface = surface; - - // Check for WSI support - VkBool32 res; - vkGetPhysicalDeviceSurfaceSupportKHR(mPhysicalDevice, mQueueFamily, wd->Surface, &res); - if (res != VK_TRUE) { - throw "Error no WSI support on physical device 0."; - } - - // Select Surface Format - const VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM }; - const VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; - wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(mPhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace); - - // Select Present Mode - VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_FIFO_KHR }; - wd->PresentMode = ImGui_ImplVulkanH_SelectPresentMode(mPhysicalDevice, wd->Surface, &present_modes[0], IM_ARRAYSIZE(present_modes)); - - // Create SwapChain, RenderPass, Framebuffer, etc. - IM_ASSERT(mMinImageCount >= 2); - ImGui_ImplVulkanH_CreateOrResizeWindow(mInstance, mPhysicalDevice, mDevice, wd, mQueueFamily, mAllocator, width, height, mMinImageCount); - } - - void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* drawData) - { - VkResult err; - - VkSemaphore imageAcquiredSemaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore; - VkSemaphore renderCompleteSemaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore; - err = vkAcquireNextImageKHR(mDevice, wd->Swapchain, UINT64_MAX, imageAcquiredSemaphore, VK_NULL_HANDLE, &wd->FrameIndex); - if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR) { - mSwapChainRebuild = true; - return; - } - CheckVkResults(err); - - ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex]; - { - err = vkWaitForFences(mDevice, 1, &fd->Fence, VK_TRUE, UINT64_MAX); // wait indefinitely instead of periodically checking - CheckVkResults(err); - - err = vkResetFences(mDevice, 1, &fd->Fence); - CheckVkResults(err); - } - { - err = vkResetCommandPool(mDevice, fd->CommandPool, 0); - CheckVkResults(err); - VkCommandBufferBeginInfo info = {}; - info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - err = vkBeginCommandBuffer(fd->CommandBuffer, &info); - CheckVkResults(err); - } - { - VkRenderPassBeginInfo info = {}; - info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - info.renderPass = wd->RenderPass; - info.framebuffer = fd->Framebuffer; - info.renderArea.extent.width = wd->Width; - info.renderArea.extent.height = wd->Height; - info.clearValueCount = 1; - info.pClearValues = &wd->ClearValue; - vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); - } - - // Record dear imgui primitives into command buffer - ImGui_ImplVulkan_RenderDrawData(drawData, fd->CommandBuffer); - - // Submit command buffer - vkCmdEndRenderPass(fd->CommandBuffer); - { - VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - VkSubmitInfo info = {}; - info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - info.waitSemaphoreCount = 1; - info.pWaitSemaphores = &imageAcquiredSemaphore; - info.pWaitDstStageMask = &wait_stage; - info.commandBufferCount = 1; - info.pCommandBuffers = &fd->CommandBuffer; - info.signalSemaphoreCount = 1; - info.pSignalSemaphores = &renderCompleteSemaphore; - - err = vkEndCommandBuffer(fd->CommandBuffer); - CheckVkResults(err); - err = vkQueueSubmit(mQueue, 1, &info, fd->Fence); - CheckVkResults(err); - } - } - - void FramePresent(ImGui_ImplVulkanH_Window* wd) - { - if (mSwapChainRebuild) { - return; - } - - VkSemaphore renderCompleteSemaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore; - VkPresentInfoKHR info = {}; - info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; - info.waitSemaphoreCount = 1; - info.pWaitSemaphores = &renderCompleteSemaphore; - info.swapchainCount = 1; - info.pSwapchains = &wd->Swapchain; - info.pImageIndices = &wd->FrameIndex; - VkResult err = vkQueuePresentKHR(mQueue, &info); - if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR) { - mSwapChainRebuild = true; - return; - } - CheckVkResults(err); - wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->ImageCount; // Now we can use the next set of semaphores - } - - void CleanupVulkan() - { - vkDestroyDescriptorPool(mDevice, mDescriptorPool, mAllocator); - - vkDestroyDevice(mDevice, mAllocator); - vkDestroyInstance(mInstance, mAllocator); - } - - void CleanupVulkanWindow() - { - ImGui_ImplVulkanH_DestroyWindow(mInstance, mDevice, &mMainWindowData, mAllocator); - } - - static void CheckVkResults(VkResult err) - { - if (err == 0) return; - - std::string message; - message += "Vulkan error: VkResult = "; - message += err; - - if (err < 0) { - throw std::runtime_error(message); - } else { - std::cerr << message << '\n'; - } - } - static void GlfwErrorCallback(int errorCode, const char* message) - { - std::cerr << "GLFW Error " << errorCode << ": " << message << "\n"; - } -}; - -std::unique_ptr RenderingBackend::CreateVulkanBackend() -{ - try { - return std::make_unique(); - } catch (std::exception& e) { - return nullptr; - } -} - -#else // ^^ BUILD_CORE_WITH_VULKAN_BACKEND | ~BUILD_CORE_WITH_VULKAN_BACKEND vv - -std::unique_ptr RenderingBackend::CreateVulkanBackend() -{ - return nullptr; -} - -#endif diff --git a/core/src/Entrypoint/main.cpp b/core/src/Entrypoint/main.cpp deleted file mode 100644 index abfb26c..0000000 --- a/core/src/Entrypoint/main.cpp +++ /dev/null @@ -1,163 +0,0 @@ -#include "Entrypoint/Backend.hpp" -#include "Model/GlobalStates.hpp" -#include "UI/UI.hpp" -#include "Utils/I18n.hpp" -#include "Utils/ScopeGuard.hpp" -#include "Utils/Sigslot.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace fs = std::filesystem; -using namespace std::literals::string_literals; -using namespace std::literals::string_view_literals; - -static std::unique_ptr CreateDefaultBackend() -{ -#if defined(_WIN32) -# if BUILD_CORE_WITH_DX12_BACKEND - if (auto backend = RenderingBackend::CreateDx12Backend()) { - return backend; - } -# endif -# if BUILD_CORE_WITH_DX11_BACKEND - if (auto backend = RenderingBackend::CreateDx11Backend()) { - return backend; - } -# endif -# if BUILD_CORE_WITH_VULKAN_BACKEND - if (auto backend = RenderingBackend::CreateVulkanBackend()) { - return backend; - } -# endif -# if BUILD_CORE_WITH_OPENGL3_BACKEND - if (auto backend = RenderingBackend::CreateOpenGL3Backend()) { - return backend; - } -# endif -# if BUILD_CORE_WITH_OPENGL2_BACKEND - if (auto backend = RenderingBackend::CreateOpenGL2Backend()) { - return backend; - } -# endif -#elif defined(__APPLE__) - // We currently only support using metal on macos - return RenderingBackend::CreateMetalBackend(); -#elif defined(__linux__) -# if BUILD_CORE_WITH_VULKAN_BACKEND - if (auto backend = RenderingBackend::CreateVulkanBackend()) { - return backend; - } -# endif -# if BUILD_CORE_WITH_OPENGL3_BACKEND - if (auto backend = RenderingBackend::CreateOpenGL3Backend()) { - return backend; - } -# endif -# if BUILD_CORE_WITH_OPENGL2_BACKEND - if (auto backend = RenderingBackend::CreateOpenGL2Backend()) { - return backend; - } -# endif -#endif - - return nullptr; -} - -static std::unique_ptr CreateBackend(std::string_view option) -{ - if (option == "default") { - return CreateDefaultBackend(); - } else if (option == "opengl2") { - return RenderingBackend::CreateOpenGL2Backend(); - } else if (option == "opengl3") { - return RenderingBackend::CreateOpenGL3Backend(); - } else if (option == "vulkan") { - return RenderingBackend::CreateVulkanBackend(); - } else if (option == "dx11") { - return RenderingBackend::CreateDx11Backend(); - } else if (option == "dx12") { - return RenderingBackend::CreateDx12Backend(); - } else if (option == "metal") { - return RenderingBackend::CreateMetalBackend(); - } else { - std::string message; - message += "Unknown backend '"; - message += option; - message += "'.\n"; - throw std::runtime_error(message); - } -} - -#ifdef DOCTEST_CONFIG_DISABLE -int main(int argc, char* argv[]) -{ - argparse::ArgumentParser parser; - parser.add_argument("--global-data-directory") - .help("Directory in which global data (such as recently used projects) are saved to. Use 'default' to use the default directory on each platform.") - .default_value("default"s); - parser.add_argument("--rendering-backend") - .help("Which rendering backend to use. If equals 'default', the preferred API for each platform will be used") - .default_value("default"s); - - try { - parser.parse_args(argc, argv); - } catch (const std::runtime_error& error) { - std::cout << error.what() << '\n'; - std::cout << parser; - return -1; - } - - auto backendOption = parser.get("--rendering-backend"); - auto backend = CreateBackend(backendOption); - - auto& io = ImGui::GetIO(); - - // Disable saving window positions - io.IniFilename = nullptr; - // Disable log (dump widget tree) file, we don't trigger it but just to be safe - io.LogFilename = nullptr; - - // Light mode because all major OS's default theme is white - // TODO follow system theme - ImGui::StyleColorsLight(); - - // Configure default fonts - { - // Includes latin alphabet, although for some reason smaller than if rendered using 18 point NotoSans regular - io.Fonts->AddFontFromFileTTF("fonts/NotoSansSC-Regular.otf", 18, nullptr, io.Fonts->GetGlyphRangesChineseFull()); - - ImWchar iconRanges[] = { ICON_MIN_FA, ICON_MAX_FA }; - ImFontConfig config; - config.MergeMode = true; - io.Fonts->AddFontFromFileTTF("fonts/FontAwesome5-Solid.otf", 14, &config, iconRanges); - } - - auto dataDirOption = parser.get("--global-data-directory"); - if (dataDirOption == "default") { - GlobalStates::Init(); - } else { - fs::path path(dataDirOption); - GlobalStates::Init(std::move(path)); - } - DEFER - { - GlobalStates::Shutdown(); - }; - - // Main loop - backend->RunUntilWindowClose(&UI::MainWindow); - - return 0; -} -#else -# define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN -# include -#endif -- cgit v1.2.3-70-g09d2