aboutsummaryrefslogtreecommitdiff
path: root/core/src/Entrypoint
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/Entrypoint')
-rw-r--r--core/src/Entrypoint/Backend.hpp23
-rw-r--r--core/src/Entrypoint/Backend_DirectX11.cpp250
-rw-r--r--core/src/Entrypoint/Backend_DirectX12.cpp470
-rw-r--r--core/src/Entrypoint/Backend_Metal.mm40
-rw-r--r--core/src/Entrypoint/Backend_OpenGL2.cpp106
-rw-r--r--core/src/Entrypoint/Backend_OpenGL3.cpp121
-rw-r--r--core/src/Entrypoint/Backend_Vulkan.cpp438
-rw-r--r--core/src/Entrypoint/main.cpp163
8 files changed, 0 insertions, 1611 deletions
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 <memory>
-
-class RenderingBackend
-{
-public:
- // Implemented in Backend_OpenGL2.cpp
- static std::unique_ptr<RenderingBackend> CreateOpenGL2Backend();
- // Implemented in Backend_OpenGL3.cpp
- static std::unique_ptr<RenderingBackend> CreateOpenGL3Backend();
- // Implemented in Backend_Vulkan.cpp
- static std::unique_ptr<RenderingBackend> CreateVulkanBackend();
- // Implemented in Backend_DirectX11.cpp
- static std::unique_ptr<RenderingBackend> CreateDx11Backend();
- // Implemented in Backend_DirectX12.cpp
- static std::unique_ptr<RenderingBackend> CreateDx12Backend();
- // Implemented in Backend_Metal.cpp
- static std::unique_ptr<RenderingBackend> 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 <backend/imgui_impl_dx11.h>
-# include <backend/imgui_impl_dx11.cpp>
-# include <stdexcept>
-# include <d3d11.h>
-# include <tchar.h>
-# include <backend/imgui_impl_win32.h>
-
-// 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<LPCREATESTRUCT>(lParam);
- self = static_cast<DirectX11Backend*>(lpcs->lpCreateParams);
- self->hWnd = hWnd;
- SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(self));
- } else {
- self = reinterpret_cast<DirectX11Backend*>(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> RenderingBackend::CreateDx11Backend()
-{
- try {
- return std::make_unique<DirectX11Backend>();
- } catch (std::exception& e) {
- return nullptr;
- }
-}
-
-#else // ^^ BUILD_CORE_WITH_DX11_BACKEND | BUILD_CORE_WITH_DX11_BACKEND vv
-
-std::unique_ptr<RenderingBackend> 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 <backend/imgui_impl_dx12.h>
-# include <backend/imgui_impl_win32.h>
-# include <d3d12.h>
-# include <dxgi1_4.h>
-# include <tchar.h>
-# include <backend/imgui_impl_dx12.cpp>
-# include <stdexcept>
-
-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<LPCREATESTRUCT>(lParam);
- self = static_cast<DirectX12Backend*>(lpcs->lpCreateParams);
- self->hWnd = hWnd;
- SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(self));
- } else {
- self = reinterpret_cast<DirectX12Backend*>(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> RenderingBackend::CreateDx12Backend()
-{
- try {
- return std::make_unique<DirectX12Backend>();
- } catch (std::exception& e) {
- return nullptr;
- }
-}
-
-#else // ^^ BUILD_CORE_WITH_DX12_BACKEND | BUILD_CORE_WITH_DX12_BACKEND vv
-
-std::unique_ptr<RenderingBackend> 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> RenderingBackend::CreateMetalBackend()
-{
- try {
- return std::make_unique<MetalBackend>();
- } catch (std::exception& e) {
- return nullptr;
- }
-}
-
-#else // ^^ BUILD_CORE_WITH_METAL_BACKEND | BUILD_CORE_WITH_METAL_BACKEND vv
-
-std::unique_ptr<RenderingBackend> 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 <glad/glad.h>
-
-# include <GLFW/glfw3.h>
-# include <backend/imgui_impl_glfw.h>
-# include <backend/imgui_impl_opengl2.h>
-# include <imgui.h>
-# include <stdexcept>
-# include <iostream>
-
-# define IMGUI_IMPL_OPENGL_LOADER_CUSTOM
-# include <backend/imgui_impl_opengl2.cpp>
-
-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> RenderingBackend::CreateOpenGL2Backend()
-{
- try {
- return std::make_unique<OpenGL2Backend>();
- } catch (std::exception& e) {
- return nullptr;
- }
-}
-
-#else // ^^ BUILD_CORE_WITH_OPENGL2_BACKEND | !BUILD_CORE_WITH_OPENGL2_BACKEND vv
-
-std::unique_ptr<RenderingBackend> 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 <glad/glad.h>
-
-# include <GLFW/glfw3.h>
-# include <iostream>
-# include <backend/imgui_impl_glfw.h>
-# include <backend/imgui_impl_opengl3.h>
-# include <imgui.h>
-# include <stdexcept>
-
-# define IMGUI_IMPL_OPENGL_LOADER_CUSTOM
-# include <backend/imgui_impl_opengl3.cpp>
-
-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> RenderingBackend::CreateOpenGL3Backend()
-{
- try {
- return std::make_unique<OpenGL3Backend>();
- } catch (std::exception& e) {
- return nullptr;
- }
-}
-
-#else // ^^ BUILD_CORE_WITH_OPENGL3_BACKEND | !BUILD_CORE_WITH_OPENGL3_BACKEND vv
-
-std::unique_ptr<RenderingBackend> 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 <iostream>
-# include <stdexcept>
-
-# define GLFW_INCLUDE_NONE
-# define GLFW_INCLUDE_VULKAN
-# include <GLFW/glfw3.h>
-
-# include <backend/imgui_impl_glfw.h>
-# include <backend/imgui_impl_vulkan.h>
-# include <backend/imgui_impl_vulkan.cpp>
-
-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<VkQueueFamilyProperties[]>(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> RenderingBackend::CreateVulkanBackend()
-{
- try {
- return std::make_unique<VulkanBackend>();
- } catch (std::exception& e) {
- return nullptr;
- }
-}
-
-#else // ^^ BUILD_CORE_WITH_VULKAN_BACKEND | ~BUILD_CORE_WITH_VULKAN_BACKEND vv
-
-std::unique_ptr<RenderingBackend> 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 <IconsFontAwesome.h>
-#include <imgui.h>
-#include <argparse/argparse.hpp>
-#include <filesystem>
-#include <iostream>
-#include <memory>
-#include <stdexcept>
-#include <string>
-#include <string_view>
-
-namespace fs = std::filesystem;
-using namespace std::literals::string_literals;
-using namespace std::literals::string_view_literals;
-
-static std::unique_ptr<RenderingBackend> 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<RenderingBackend> 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<std::string>("--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<std::string>("--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 <doctest/doctest.h>
-#endif