mirror of
https://github.com/AxioDL/boo.git
synced 2025-12-09 13:37:48 +00:00
Initial D3D window appearing
This commit is contained in:
@@ -4,8 +4,10 @@
|
||||
#include <Usbiodef.h>
|
||||
|
||||
#if _DEBUG
|
||||
#define DXGI_CREATE_FLAGS DXGI_CREATE_FACTORY_DEBUG
|
||||
#define D3D11_CREATE_DEVICE_FLAGS D3D11_CREATE_DEVICE_DEBUG
|
||||
#else
|
||||
#define DXGI_CREATE_FLAGS 0
|
||||
#define D3D11_CREATE_DEVICE_FLAGS 0
|
||||
#endif
|
||||
|
||||
@@ -16,6 +18,9 @@
|
||||
#include "boo/inputdev/DeviceFinder.hpp"
|
||||
#include <LogVisor/LogVisor.hpp>
|
||||
|
||||
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignaturePROC = nullptr;
|
||||
|
||||
namespace boo
|
||||
{
|
||||
static LogVisor::LogModule Log("ApplicationWin32");
|
||||
@@ -68,22 +73,59 @@ public:
|
||||
HMODULE d3d12lib = LoadLibraryW(L"D3D12.dll");
|
||||
if (d3d12lib)
|
||||
{
|
||||
#if _DEBUG
|
||||
{
|
||||
PFN_D3D12_GET_DEBUG_INTERFACE MyD3D12GetDebugInterface =
|
||||
(PFN_D3D12_GET_DEBUG_INTERFACE)GetProcAddress(d3d12lib, "D3D12GetDebugInterface");
|
||||
ComPtr<ID3D12Debug> debugController;
|
||||
if (SUCCEEDED(MyD3D12GetDebugInterface(IID_PPV_ARGS(&debugController))))
|
||||
{
|
||||
debugController->EnableDebugLayer();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
D3D12SerializeRootSignaturePROC =
|
||||
(PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)GetProcAddress(d3d12lib, "D3D12SerializeRootSignature");
|
||||
|
||||
/* Create device */
|
||||
PFN_D3D12_CREATE_DEVICE MyD3D12CreateDevice = (PFN_D3D12_CREATE_DEVICE)GetProcAddress(d3d12lib, "D3D12CreateDevice");
|
||||
if (!MyD3D12CreateDevice)
|
||||
Log.report(LogVisor::FatalError, "unable to find D3D12CreateDevice in D3D12.dll");
|
||||
|
||||
/* Create device */
|
||||
if (FAILED(MyD3D12CreateDevice(nullptr, D3D_FEATURE_LEVEL_12_0, __uuidof(ID3D12Device), &m_d3dCtx.m_ctx12.m_dev)))
|
||||
HRESULT hr = MyD3D12CreateDevice(nullptr, D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), &m_d3dCtx.m_ctx12.m_dev);
|
||||
if (FAILED(hr))
|
||||
Log.report(LogVisor::FatalError, "unable to create D3D12 device");
|
||||
|
||||
/* Obtain DXGI Factory */
|
||||
ComPtr<IDXGIDevice2> device;
|
||||
ComPtr<IDXGIAdapter> adapter;
|
||||
m_d3dCtx.m_ctx12.m_dev.As<IDXGIDevice2>(&device);
|
||||
device->GetParent(__uuidof(IDXGIAdapter), &adapter);
|
||||
adapter->GetParent(__uuidof(IDXGIFactory2), &m_d3dCtx.m_dxFactory);
|
||||
|
||||
hr = MyCreateDXGIFactory2(DXGI_CREATE_FLAGS, __uuidof(IDXGIFactory4), &m_d3dCtx.m_ctx12.m_dxFactory);
|
||||
if (FAILED(hr))
|
||||
Log.report(LogVisor::FatalError, "unable to create DXGI factory");
|
||||
|
||||
/* Establish loader objects */
|
||||
if (FAILED(m_d3dCtx.m_ctx12.m_dev->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||
__uuidof(ID3D12CommandAllocator), &m_d3dCtx.m_ctx12.m_loadqalloc)))
|
||||
Log.report(LogVisor::FatalError, "unable to create loader allocator");
|
||||
|
||||
D3D12_COMMAND_QUEUE_DESC desc =
|
||||
{
|
||||
D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||
D3D12_COMMAND_QUEUE_PRIORITY_NORMAL,
|
||||
D3D12_COMMAND_QUEUE_FLAG_NONE
|
||||
};
|
||||
if (FAILED(m_d3dCtx.m_ctx12.m_dev->CreateCommandQueue(&desc, __uuidof(ID3D12CommandQueue), &m_d3dCtx.m_ctx12.m_loadq)))
|
||||
Log.report(LogVisor::FatalError, "unable to create loader queue");
|
||||
|
||||
if (FAILED(m_d3dCtx.m_ctx12.m_dev->CreateFence(0, D3D12_FENCE_FLAG_NONE, __uuidof(ID3D12Fence), &m_d3dCtx.m_ctx12.m_loadfence)))
|
||||
Log.report(LogVisor::FatalError, "unable to create loader fence");
|
||||
|
||||
m_d3dCtx.m_ctx12.m_loadfencehandle = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
||||
|
||||
if (FAILED(m_d3dCtx.m_ctx12.m_dev->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_d3dCtx.m_ctx12.m_loadqalloc.Get(),
|
||||
nullptr, __uuidof(ID3D12GraphicsCommandList), &m_d3dCtx.m_ctx12.m_loadlist)))
|
||||
Log.report(LogVisor::FatalError, "unable to create loader list");
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -110,7 +152,7 @@ public:
|
||||
ComPtr<IDXGIAdapter> adapter;
|
||||
m_d3dCtx.m_ctx11.m_dev.As<IDXGIDevice2>(&device);
|
||||
device->GetParent(__uuidof(IDXGIAdapter), &adapter);
|
||||
adapter->GetParent(__uuidof(IDXGIFactory2), &m_d3dCtx.m_dxFactory);
|
||||
adapter->GetParent(__uuidof(IDXGIFactory2), &m_d3dCtx.m_ctx11.m_dxFactory);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -154,8 +196,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
DWORD m_mainThreadId = 0;
|
||||
int run()
|
||||
{
|
||||
m_mainThreadId = GetCurrentThreadId();
|
||||
|
||||
/* Spawn client thread */
|
||||
int clientReturn = 0;
|
||||
std::thread clientThread([&]()
|
||||
@@ -165,6 +210,16 @@ public:
|
||||
MSG msg = {0};
|
||||
while (GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
if (msg.message == WM_USER)
|
||||
{
|
||||
/* New-window message (coalesced onto main thread) */
|
||||
std::unique_lock<std::mutex> lk(m_nwmt);
|
||||
const SystemString* title = reinterpret_cast<const SystemString*>(msg.wParam);
|
||||
m_mwret = newWindow(*title);
|
||||
lk.unlock();
|
||||
m_nwcv.notify_one();
|
||||
continue;
|
||||
}
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
@@ -194,8 +249,20 @@ public:
|
||||
return m_args;
|
||||
}
|
||||
|
||||
std::mutex m_nwmt;
|
||||
std::condition_variable m_nwcv;
|
||||
IWindow* m_mwret = nullptr;
|
||||
IWindow* newWindow(const SystemString& title)
|
||||
{
|
||||
if (GetCurrentThreadId() != m_mainThreadId)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_nwmt);
|
||||
if (!PostThreadMessage(m_mainThreadId, WM_USER, WPARAM(&title), 0))
|
||||
Log.report(LogVisor::FatalError, "PostThreadMessage error");
|
||||
m_nwcv.wait(lk);
|
||||
return m_mwret;
|
||||
}
|
||||
|
||||
IWindow* window = _WindowWin32New(title, m_d3dCtx);
|
||||
HWND hwnd = HWND(window->getPlatformHandle());
|
||||
m_allWindows[hwnd] = window;
|
||||
@@ -217,6 +284,24 @@ int ApplicationRun(IApplication::EPlatformType platform,
|
||||
if (platform != IApplication::PLAT_WIN32 &&
|
||||
platform != IApplication::PLAT_AUTO)
|
||||
return 1;
|
||||
|
||||
/* One class for *all* boo windows */
|
||||
WNDCLASS wndClass =
|
||||
{
|
||||
0,
|
||||
WindowProc,
|
||||
0,
|
||||
0,
|
||||
GetModuleHandle(nullptr),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
L"BooWindow"
|
||||
};
|
||||
|
||||
RegisterClassW(&wndClass);
|
||||
|
||||
APP = new ApplicationWin32(cb, uniqueName, friendlyName, pname, args, singleInstance);
|
||||
return APP->run();
|
||||
}
|
||||
@@ -242,36 +327,3 @@ static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
|
||||
return static_cast<boo::ApplicationWin32*>(boo::APP)->winHwndHandler(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
int wmain(int argc, wchar_t** argv);
|
||||
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int)
|
||||
{
|
||||
#if _DEBUG
|
||||
/* Debug console */
|
||||
AllocConsole();
|
||||
freopen("CONOUT$", "w", stdout);
|
||||
#endif
|
||||
|
||||
/* One class for *all* boo windows */
|
||||
WNDCLASS wndClass =
|
||||
{
|
||||
0,
|
||||
WindowProc,
|
||||
0,
|
||||
0,
|
||||
hInstance,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
L"BooWindow"
|
||||
};
|
||||
|
||||
RegisterClassW(&wndClass);
|
||||
|
||||
int argc = 0;
|
||||
LPWSTR* argv = CommandLineToArgvW(lpCmdLine, &argc);
|
||||
|
||||
/* Call into the 'proper' entry point */
|
||||
return wmain(argc, argv);
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <windows.h>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "boo/System.hpp"
|
||||
|
||||
namespace boo {class IWindow;}
|
||||
|
||||
#if _WIN32_WINNT_WIN10
|
||||
@@ -19,12 +21,16 @@ namespace boo {class IWindow;}
|
||||
|
||||
struct D3D12Context
|
||||
{
|
||||
ComPtr<IDXGIFactory4> m_dxFactory;
|
||||
ComPtr<ID3D12Device> m_dev;
|
||||
ComPtr<ID3D12CommandAllocator> m_qalloc[2];
|
||||
ComPtr<ID3D12CommandQueue> m_q;
|
||||
ComPtr<ID3D12CommandAllocator> m_loadqalloc;
|
||||
ComPtr<ID3D12CommandQueue> m_loadq;
|
||||
ComPtr<ID3D12Fence> m_frameFence;
|
||||
ComPtr<ID3D12Fence> m_loadfence;
|
||||
UINT64 m_loadfenceval = 0;
|
||||
HANDLE m_loadfencehandle;
|
||||
ComPtr<ID3D12GraphicsCommandList> m_loadlist;
|
||||
ComPtr<ID3D12RootSignature> m_rs;
|
||||
struct Window
|
||||
{
|
||||
@@ -45,6 +51,7 @@ struct D3D12Context
|
||||
|
||||
struct D3D11Context
|
||||
{
|
||||
ComPtr<IDXGIFactory2> m_dxFactory;
|
||||
ComPtr<ID3D11Device1> m_dev;
|
||||
ComPtr<ID3D11DeviceContext1> m_devCtx;
|
||||
struct Window
|
||||
@@ -55,15 +62,12 @@ struct D3D11Context
|
||||
std::unordered_map<boo::IWindow*, Window> m_windows;
|
||||
};
|
||||
|
||||
#include "boo/System.hpp"
|
||||
|
||||
struct D3DAppContext
|
||||
{
|
||||
D3D11Context m_ctx11;
|
||||
#if _WIN32_WINNT_WIN10
|
||||
D3D12Context m_ctx12;
|
||||
#endif
|
||||
ComPtr<IDXGIFactory2> m_dxFactory;
|
||||
};
|
||||
|
||||
struct HWNDEvent
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
namespace boo
|
||||
{
|
||||
static LogVisor::LogModule Log("WindowWin32");
|
||||
class WindowWin32;
|
||||
IGraphicsCommandQueue* _NewD3D12CommandQueue(D3D12Context* ctx, D3D12Context::Window* windowCtx, IGraphicsContext* parent);
|
||||
IGraphicsCommandQueue* _NewD3D12CommandQueue(D3D12Context* ctx, D3D12Context::Window* windowCtx, IGraphicsContext* parent,
|
||||
ID3D12CommandQueue** cmdQueueOut);
|
||||
IGraphicsCommandQueue* _NewD3D11CommandQueue(D3D11Context* ctx, D3D11Context::Window* windowCtx, IGraphicsContext* parent);
|
||||
|
||||
struct GraphicsContextWin32 : IGraphicsContext
|
||||
@@ -19,7 +19,7 @@ struct GraphicsContextWin32 : IGraphicsContext
|
||||
|
||||
EGraphicsAPI m_api;
|
||||
EPixelFormat m_pf;
|
||||
WindowWin32* m_parentWindow;
|
||||
IWindow* m_parentWindow;
|
||||
D3DAppContext& m_d3dCtx;
|
||||
|
||||
ComPtr<IDXGISwapChain1> m_swapChain;
|
||||
@@ -31,7 +31,7 @@ struct GraphicsContextWin32 : IGraphicsContext
|
||||
public:
|
||||
IWindowCallback* m_callback;
|
||||
|
||||
GraphicsContextWin32(EGraphicsAPI api, WindowWin32* parentWindow, D3DAppContext& d3dCtx)
|
||||
GraphicsContextWin32(EGraphicsAPI api, IWindow* parentWindow, HWND hwnd, D3DAppContext& d3dCtx)
|
||||
: m_api(api),
|
||||
m_pf(PF_RGBA8),
|
||||
m_parentWindow(parentWindow),
|
||||
@@ -46,30 +46,22 @@ public:
|
||||
scDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
scDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
||||
|
||||
#if _WIN32_WINNT_WIN10
|
||||
IUnknown* dev;
|
||||
if (d3dCtx.m_ctx12.m_dev)
|
||||
{
|
||||
scDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
|
||||
dev = static_cast<IUnknown*>(d3dCtx.m_ctx12.m_dev.Get());
|
||||
}
|
||||
else
|
||||
dev = static_cast<IUnknown*>(d3dCtx.m_ctx11.m_dev.Get());
|
||||
#else
|
||||
IUnknown* dev = static_cast<IUnknown*>(d3dCtx.m_ctx11.m_dev.Get());
|
||||
#endif
|
||||
if (FAILED(d3dCtx.m_dxFactory->CreateSwapChainForHwnd(dev,
|
||||
parentWindow->m_hwnd, &scDesc, nullptr, nullptr, &m_swapChain)))
|
||||
Log.report(LogVisor::FatalError, "unable to create swap chain");
|
||||
|
||||
if (FAILED(m_swapChain->GetContainingOutput(&m_output)))
|
||||
Log.report(LogVisor::FatalError, "unable to get DXGI output");
|
||||
|
||||
#if _WIN32_WINNT_WIN10
|
||||
if (d3dCtx.m_ctx12.m_dev)
|
||||
{
|
||||
auto insIt = d3dCtx.m_ctx12.m_windows.emplace(std::make_pair(parentWindow, D3D12Context::Window()));
|
||||
D3D12Context::Window& w = insIt.first->second;
|
||||
|
||||
ID3D12CommandQueue* cmdQueue;
|
||||
m_dataFactory = new D3D12DataFactory(this, &d3dCtx.m_ctx12);
|
||||
m_commandQueue = _NewD3D12CommandQueue(&d3dCtx.m_ctx12, &w, this, &cmdQueue);
|
||||
|
||||
scDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
|
||||
HRESULT hr = d3dCtx.m_ctx12.m_dxFactory->CreateSwapChainForHwnd(cmdQueue,
|
||||
hwnd, &scDesc, nullptr, nullptr, &m_swapChain);
|
||||
if (FAILED(hr))
|
||||
Log.report(LogVisor::FatalError, "unable to create swap chain");
|
||||
|
||||
m_swapChain.As<IDXGISwapChain3>(&w.m_swapChain);
|
||||
m_swapChain->GetBuffer(0, __uuidof(ID3D12Resource), &w.m_fb[0]);
|
||||
m_swapChain->GetBuffer(1, __uuidof(ID3D12Resource), &w.m_fb[1]);
|
||||
@@ -77,12 +69,15 @@ public:
|
||||
D3D12_RESOURCE_DESC resDesc = w.m_fb[0]->GetDesc();
|
||||
w.width = resDesc.Width;
|
||||
w.height = resDesc.Height;
|
||||
m_dataFactory = new D3D12DataFactory(this, &d3dCtx.m_ctx12);
|
||||
m_commandQueue = _NewD3D12CommandQueue(&d3dCtx.m_ctx12, &w, this);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#if 0
|
||||
if (FAILED(d3dCtx.m_ctx11.m_dxFactory->CreateSwapChainForHwnd(d3dCtx.m_ctx11.m_dev.Get(),
|
||||
hwnd, &scDesc, nullptr, nullptr, &m_swapChain)))
|
||||
Log.report(LogVisor::FatalError, "unable to create swap chain");
|
||||
|
||||
auto insIt = d3dCtx.m_ctx11.m_windows.emplace(std::make_pair(parentWindow, D3D11Context::Window()));
|
||||
D3D11Context::Window& w = insIt.first->second;
|
||||
ComPtr<ID3D11Texture2D> fbRes;
|
||||
@@ -93,7 +88,11 @@ public:
|
||||
w.height = resDesc.Height;
|
||||
m_dataFactory = new D3D11DataFactory(this, &d3dCtx.m_ctx11);
|
||||
m_commandQueue = _NewD3D11CommandQueue(&d3dCtx.m_ctx11, &insIt.first->second, this);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (FAILED(m_swapChain->GetContainingOutput(&m_output)))
|
||||
Log.report(LogVisor::FatalError, "unable to get DXGI output");
|
||||
}
|
||||
|
||||
~GraphicsContextWin32()
|
||||
@@ -141,18 +140,18 @@ public:
|
||||
|
||||
IGraphicsCommandQueue* getCommandQueue()
|
||||
{
|
||||
|
||||
return m_commandQueue;
|
||||
}
|
||||
|
||||
IGraphicsDataFactory* getDataFactory()
|
||||
{
|
||||
|
||||
return m_dataFactory;
|
||||
}
|
||||
|
||||
/* Creates a new context on current thread!! Call from client loading thread */
|
||||
IGraphicsDataFactory* getLoadContextDataFactory()
|
||||
{
|
||||
|
||||
return m_dataFactory;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -235,7 +234,7 @@ public:
|
||||
m_hwnd = CreateWindowW(L"BooWindow", title.c_str(), WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
NULL, NULL, NULL, NULL);
|
||||
m_gfxCtx.reset(new GraphicsContextWin32(IGraphicsContext::API_D3D11, this, d3dCtx));
|
||||
m_gfxCtx.reset(new GraphicsContextWin32(IGraphicsContext::API_D3D11, this, m_hwnd, d3dCtx));
|
||||
}
|
||||
|
||||
~WindowWin32()
|
||||
|
||||
Reference in New Issue
Block a user