Windows and Vulkan fixes

This commit is contained in:
Jack Andersen
2017-11-24 16:49:20 -10:00
parent 3c90192351
commit b23da43f05
5 changed files with 171 additions and 121 deletions

View File

@@ -22,7 +22,7 @@ PFN_GetScaleFactorForMonitor MyGetScaleFactorForMonitor = nullptr;
#include "logvisor/logvisor.hpp"
#if BOO_HAS_VULKAN
#include <vulkan/vulkan.h>
#include "boo/graphicsdev/Vulkan.hpp"
#endif
DWORD g_mainThreadId = 0;
@@ -68,7 +68,7 @@ static logvisor::Module Log("boo::ApplicationWin32");
Win32Cursors WIN32_CURSORS;
std::shared_ptr<IWindow> _WindowWin32New(SystemStringView title, Boo3DAppContextWin32& d3dCtx,
void* vulkanHandle, uint32_t sampleCount);
uint32_t sampleCount);
class ApplicationWin32 final : public IApplication
{
@@ -114,32 +114,75 @@ public:
if (!MyCreateDXGIFactory1)
Log.report(logvisor::Fatal, "unable to find CreateDXGIFactory1 in DXGI.dll\n");
bool no12 = false;
bool yes12 = false;
bool noD3d = false;
#if BOO_HAS_VULKAN
bool useVulkan = true;
#endif
for (const SystemString& arg : args)
{
if (!arg.compare(L"--d3d11"))
no12 = true;
#if BOO_HAS_VULKAN
if (!arg.compare(L"--vulkan"))
noD3d = true;
if (!arg.compare(L"--d3d12"))
{
useVulkan = false;
yes12 = true;
}
if (!arg.compare(L"--d3d11"))
{
useVulkan = false;
}
if (!arg.compare(L"--gl"))
{
noD3d = true;
useVulkan = false;
}
#else
if (!arg.compare(L"--d3d12"))
yes12 = true;
if (!arg.compare(L"--gl"))
noD3d = true;
#endif
}
#if BOO_HAS_VULKAN
if (useVulkan)
{
HMODULE vulkanLib = LoadLibraryW(L"vulkan-1.dll");
if (vulkanLib)
{
m_getVkProc = (PFN_vkGetInstanceProcAddr)GetProcAddress(vulkanLib, "vkGetInstanceProcAddr");
if (m_getVkProc)
{
/* Check device support for vulkan */
vk::init_dispatch_table_top(PFN_vkGetInstanceProcAddr(m_getVkProc));
if (g_VulkanContext.m_instance == VK_NULL_HANDLE)
{
auto appName = getUniqueName();
if (g_VulkanContext.initVulkan(WCSTMBS(appName.data()).c_str()))
{
vk::init_dispatch_table_middle(g_VulkanContext.m_instance, false);
if (g_VulkanContext.enumerateDevices())
{
/* Obtain DXGI Factory */
HRESULT hr = MyCreateDXGIFactory1(__uuidof(IDXGIFactory1), &m_3dCtx.m_vulkanDxFactory);
if (FAILED(hr))
Log.report(logvisor::Fatal, "unable to create DXGI factory");
Log.report(logvisor::Info, "initialized Vulkan renderer");
return;
}
}
}
}
}
}
#endif
#if _WIN32_WINNT_WIN10
HMODULE d3d12lib = LoadLibraryW(L"D3D12.dll");
if (!no12 && !noD3d && d3d12lib)
HMODULE d3d12lib = nullptr;
if (yes12 && !noD3d)
d3d12lib = LoadLibraryW(L"D3D12.dll");
if (d3d12lib)
{
#if _DEBUG
{
@@ -223,8 +266,10 @@ public:
}
}
#endif
HMODULE d3d11lib = LoadLibraryW(L"D3D11.dll");
if (d3d11lib && !noD3d)
HMODULE d3d11lib = nullptr;
if (!noD3d)
d3d11lib = LoadLibraryW(L"D3D11.dll");
if (d3d11lib)
{
if (!FindBestD3DCompile())
Log.report(logvisor::Fatal, "unable to find D3DCompile_[43-47].dll");
@@ -279,27 +324,6 @@ public:
return;
}
#if BOO_HAS_VULKAN
if (useVulkan)
{
HMODULE vulkanLib = LoadLibraryW(L"vulkan-1.dll");
if (vulkanLib)
{
m_getVkProc = (PFN_vkGetInstanceProcAddr)GetProcAddress(vulkanLib, "vkGetInstanceProcAddr");
if (m_getVkProc)
{
/* Obtain DXGI Factory */
HRESULT hr = MyCreateDXGIFactory1(__uuidof(IDXGIFactory1), &m_3dCtx.m_vulkanDxFactory);
if (FAILED(hr))
Log.report(logvisor::Fatal, "unable to create DXGI factory");
Log.report(logvisor::Info, "initialized Vulkan renderer");
return;
}
}
}
#endif
/* Finally try OpenGL */
{
/* Obtain DXGI Factory */
@@ -311,7 +335,7 @@ public:
return;
}
Log.report(logvisor::Fatal, "system doesn't support OGL, D3D11 or D3D12");
Log.report(logvisor::Fatal, "system doesn't support Vulkan, D3D11, or OpenGL");
}
EPlatformType getPlatformType() const
@@ -470,12 +494,7 @@ public:
return ret;
}
#if BOO_HAS_VULKAN
std::shared_ptr<IWindow> window = _WindowWin32New(title, m_3dCtx, m_getVkProc, sampleCount);
#else
std::shared_ptr<IWindow> window = _WindowWin32New(title, m_3dCtx, nullptr, sampleCount);
#endif
std::shared_ptr<IWindow> window = _WindowWin32New(title, m_3dCtx, sampleCount);
HWND hwnd = HWND(window->getPlatformHandle());
m_allWindows[hwnd] = window;
return window;

View File

@@ -10,6 +10,10 @@
#include "WinCommon.hpp"
#include <windows.h>
#if BOO_HAS_VULKAN
#include "boo/graphicsdev/Vulkan.hpp"
#endif
extern DWORD g_mainThreadId;
#if _WIN32_WINNT_WINBLUE
@@ -41,6 +45,45 @@ struct OGLContext
std::unordered_map<const boo::IWindow*, Window> m_windows;
};
template <class W>
static inline void SetFullscreen(W& win, bool fs)
{
if (fs)
{
win.m_fsStyle = GetWindowLong(win.m_hwnd, GWL_STYLE);
win.m_fsExStyle = GetWindowLong(win.m_hwnd, GWL_EXSTYLE);
GetWindowRect(win.m_hwnd, &win.m_fsRect);
SetWindowLong(win.m_hwnd, GWL_STYLE,
win.m_fsStyle & ~(WS_CAPTION | WS_THICKFRAME));
SetWindowLong(win.m_hwnd, GWL_EXSTYLE,
win.m_fsExStyle & ~(WS_EX_DLGMODALFRAME |
WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));
MONITORINFO monitor_info;
monitor_info.cbSize = sizeof(monitor_info);
GetMonitorInfo(MonitorFromWindow(win.m_hwnd, MONITOR_DEFAULTTONEAREST),
&monitor_info);
SetWindowPos(win.m_hwnd, NULL, monitor_info.rcMonitor.left, monitor_info.rcMonitor.top,
monitor_info.rcMonitor.right - monitor_info.rcMonitor.left,
monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top,
SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS);
win.m_fs = true;
}
else
{
SetWindowLong(win.m_hwnd, GWL_STYLE, win.m_fsStyle);
SetWindowLong(win.m_hwnd, GWL_EXSTYLE, win.m_fsExStyle);
SetWindowPos(win.m_hwnd, NULL, win.m_fsRect.left, win.m_fsRect.top,
win.m_fsRect.right - win.m_fsRect.left, win.m_fsRect.bottom - win.m_fsRect.top,
SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS);
win.m_fs = false;
}
}
struct Boo3DAppContextWin32 : Boo3DAppContext
{
OGLContext m_ctxOgl;
@@ -48,6 +91,14 @@ struct Boo3DAppContextWin32 : Boo3DAppContext
bool isFullscreen(const boo::IWindow* window)
{
#if BOO_HAS_VULKAN
if (m_vulkanDxFactory)
{
boo::VulkanContext::Window& win = *boo::g_VulkanContext.m_windows[window];
return win.m_fs;
}
#endif
#if _WIN32_WINNT_WIN10
if (m_ctx12.m_dev)
{
@@ -70,6 +121,19 @@ struct Boo3DAppContextWin32 : Boo3DAppContext
bool setFullscreen(boo::IWindow* window, bool fs)
{
#if BOO_HAS_VULKAN
if (m_vulkanDxFactory)
{
boo::VulkanContext::Window& win = *boo::g_VulkanContext.m_windows[window];
if (fs && win.m_fs)
return false;
else if (!fs && !win.m_fs)
return false;
SetFullscreen(win, fs);
return true;
}
#endif
#if _WIN32_WINNT_WIN10
if (m_ctx12.m_dev)
{
@@ -128,42 +192,7 @@ struct Boo3DAppContextWin32 : Boo3DAppContext
return false;
else if (!fs && !win.m_fs)
return false;
if (fs)
{
win.m_fsStyle = GetWindowLong(win.m_hwnd, GWL_STYLE);
win.m_fsExStyle = GetWindowLong(win.m_hwnd, GWL_EXSTYLE);
GetWindowRect(win.m_hwnd, &win.m_fsRect);
SetWindowLong(win.m_hwnd, GWL_STYLE,
win.m_fsStyle & ~(WS_CAPTION | WS_THICKFRAME));
SetWindowLong(win.m_hwnd, GWL_EXSTYLE,
win.m_fsExStyle & ~(WS_EX_DLGMODALFRAME |
WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));
MONITORINFO monitor_info;
monitor_info.cbSize = sizeof(monitor_info);
GetMonitorInfo(MonitorFromWindow(win.m_hwnd, MONITOR_DEFAULTTONEAREST),
&monitor_info);
SetWindowPos(win.m_hwnd, NULL, monitor_info.rcMonitor.left, monitor_info.rcMonitor.top,
monitor_info.rcMonitor.right - monitor_info.rcMonitor.left,
monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top,
SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS);
win.m_fs = true;
}
else
{
SetWindowLong(win.m_hwnd, GWL_STYLE, win.m_fsStyle);
SetWindowLong(win.m_hwnd, GWL_EXSTYLE, win.m_fsExStyle);
SetWindowPos(win.m_hwnd, NULL, win.m_fsRect.left, win.m_fsRect.top,
win.m_fsRect.right - win.m_fsRect.left, win.m_fsRect.bottom - win.m_fsRect.top,
SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS);
win.m_fs = false;
}
SetFullscreen(win, fs);
return true;
}
};

View File

@@ -497,22 +497,12 @@ public:
m_pf = pf;
}
bool initializeContext(void* getVkProc)
bool initializeContext(void*)
{
vk::init_dispatch_table_top(PFN_vkGetInstanceProcAddr(getVkProc));
if (m_ctx->m_instance == VK_NULL_HANDLE)
{
auto appName = APP->getUniqueName();
m_ctx->initVulkan(WCSTMBS(appName.data()).c_str());
}
vk::init_dispatch_table_middle(m_ctx->m_instance, false);
if (!m_ctx->enumerateDevices())
return false;
m_windowCtx =
m_ctx->m_windows.emplace(std::make_pair(m_parentWindow,
std::make_unique<VulkanContext::Window>())).first->second.get();
m_windowCtx->m_hwnd = m_hwnd;
VkWin32SurfaceCreateInfoKHR surfaceInfo = {};
surfaceInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
@@ -970,13 +960,23 @@ class WindowWin32 : public IWindow
public:
WindowWin32(SystemStringView title, Boo3DAppContextWin32& b3dCtx, void* vulkanHandle, uint32_t sampleCount)
WindowWin32(SystemStringView title, Boo3DAppContextWin32& b3dCtx, uint32_t sampleCount)
{
m_hwnd = CreateWindowW(L"BooWindow", title.data(), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, NULL, NULL);
HINSTANCE wndInstance = HINSTANCE(GetWindowLongPtr(m_hwnd, GWLP_HINSTANCE));
m_imc = ImmGetContext(m_hwnd);
#if BOO_HAS_VULKAN
if (b3dCtx.m_vulkanDxFactory)
{
m_gfxCtx.reset(new GraphicsContextWin32Vulkan(this, wndInstance, m_hwnd, &g_VulkanContext,
b3dCtx, sampleCount));
if (m_gfxCtx->initializeContext(nullptr))
return;
}
#endif
IGraphicsContext::EGraphicsAPI api = IGraphicsContext::EGraphicsAPI::D3D11;
#if _WIN32_WINNT_WIN10
if (b3dCtx.m_ctx12.m_dev)
@@ -989,15 +989,6 @@ public:
m_openGL = true;
return;
}
#if BOO_HAS_VULKAN
else if (b3dCtx.m_vulkanDxFactory)
{
m_gfxCtx.reset(new GraphicsContextWin32Vulkan(this, wndInstance, m_hwnd, &g_VulkanContext,
b3dCtx, sampleCount));
if (m_gfxCtx->initializeContext(vulkanHandle))
return;
}
#endif
m_gfxCtx.reset(new GraphicsContextWin32D3D(api, this, m_hwnd, b3dCtx, sampleCount));
}
@@ -1583,9 +1574,9 @@ public:
};
std::shared_ptr<IWindow> _WindowWin32New(SystemStringView title, Boo3DAppContextWin32& d3dCtx,
void* vulkanHandle, uint32_t sampleCount)
uint32_t sampleCount)
{
return std::make_shared<WindowWin32>(title, d3dCtx, vulkanHandle, sampleCount);
return std::make_shared<WindowWin32>(title, d3dCtx, sampleCount);
}
}