mirror of https://github.com/AxioDL/boo.git
Add preliminary Win32 Vulkan support
This commit is contained in:
parent
02c1004d67
commit
3076c0525d
|
@ -33,6 +33,19 @@ list(APPEND PLAT_HDRS
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
|
||||||
|
unset(VULKAN_SDK_DIRS CACHE)
|
||||||
|
get_filename_component(VULKAN_SDK_DIRS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\LunarG\\VulkanSDK;VK_SDK_PATHs]" ABSOLUTE CACHE)
|
||||||
|
if (NOT ${VULKAN_SDK_DIRS} STREQUAL "/registry")
|
||||||
|
message(STATUS "Enabling Vulkan support")
|
||||||
|
list(GET VULKAN_SDK_DIRS 0 VULKAN_SDK_DIR)
|
||||||
|
include_directories("${VULKAN_SDK_DIR}/Include")
|
||||||
|
list(APPEND _BOO_SYS_DEFINES -DBOO_HAS_VULKAN=1)
|
||||||
|
list(APPEND _BOO_SYS_INCLUDES "${VULKAN_SDK_DIR}/Include")
|
||||||
|
list(APPEND PLAT_SRCS lib/graphicsdev/Vulkan.cpp
|
||||||
|
lib/graphicsdev/VulkanDispatchTable.cpp)
|
||||||
|
endif()
|
||||||
|
|
||||||
list(APPEND PLAT_SRCS
|
list(APPEND PLAT_SRCS
|
||||||
lib/win/ApplicationWin32.cpp
|
lib/win/ApplicationWin32.cpp
|
||||||
lib/win/WindowWin32.cpp
|
lib/win/WindowWin32.cpp
|
||||||
|
@ -182,6 +195,7 @@ list(APPEND _BOO_SYS_LIBS glslang HLSL soxr OSDependent OGLCompiler SPIRV glslan
|
||||||
|
|
||||||
set(BOO_SYS_LIBS ${_BOO_SYS_LIBS} CACHE PATH "boo system libraries" FORCE)
|
set(BOO_SYS_LIBS ${_BOO_SYS_LIBS} CACHE PATH "boo system libraries" FORCE)
|
||||||
set(BOO_SYS_DEFINES ${_BOO_SYS_DEFINES} CACHE PATH "boo system defines" FORCE)
|
set(BOO_SYS_DEFINES ${_BOO_SYS_DEFINES} CACHE PATH "boo system defines" FORCE)
|
||||||
|
set(BOO_SYS_INCLUDES ${_BOO_SYS_INCLUDES} CACHE PATH "boo system includes" FORCE)
|
||||||
|
|
||||||
add_definitions(${_BOO_SYS_DEFINES})
|
add_definitions(${_BOO_SYS_DEFINES})
|
||||||
include_directories(include glslang soxr/src)
|
include_directories(include glslang soxr/src)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "boo/graphicsdev/Vulkan.hpp"
|
#include "boo/graphicsdev/Vulkan.hpp"
|
||||||
#include "boo/IGraphicsContext.hpp"
|
#include "boo/IGraphicsContext.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <array>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <glslang/Public/ShaderLang.h>
|
#include <glslang/Public/ShaderLang.h>
|
||||||
#include <StandAlone/ResourceLimits.h>
|
#include <StandAlone/ResourceLimits.h>
|
||||||
|
@ -230,7 +231,11 @@ void VulkanContext::initVulkan(const char* appName)
|
||||||
* entries loaded into the data pointer - in case the number
|
* entries loaded into the data pointer - in case the number
|
||||||
* of layers went down or is smaller than the size given.
|
* of layers went down or is smaller than the size given.
|
||||||
*/
|
*/
|
||||||
|
#ifdef _WIN32
|
||||||
|
_putenv("VK_LAYER_PATH=\\VulkanSDK\\1.0.17.0\\Bin");
|
||||||
|
#else
|
||||||
setenv("VK_LAYER_PATH", "/usr/share/vulkan/explicit_layer.d", 1);
|
setenv("VK_LAYER_PATH", "/usr/share/vulkan/explicit_layer.d", 1);
|
||||||
|
#endif
|
||||||
do {
|
do {
|
||||||
ThrowIfFailed(vk::EnumerateInstanceLayerProperties(&instanceLayerCount, nullptr));
|
ThrowIfFailed(vk::EnumerateInstanceLayerProperties(&instanceLayerCount, nullptr));
|
||||||
|
|
||||||
|
@ -304,7 +309,15 @@ void VulkanContext::initVulkan(const char* appName)
|
||||||
instInfo.enabledExtensionCount = m_instanceExtensionNames.size();
|
instInfo.enabledExtensionCount = m_instanceExtensionNames.size();
|
||||||
instInfo.ppEnabledExtensionNames = m_instanceExtensionNames.data();
|
instInfo.ppEnabledExtensionNames = m_instanceExtensionNames.data();
|
||||||
|
|
||||||
ThrowIfFailed(vk::CreateInstance(&instInfo, nullptr, &m_instance));
|
VkResult instRes = vk::CreateInstance(&instInfo, nullptr, &m_instance);
|
||||||
|
if (instRes != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
MessageBoxW(nullptr, L"Error creating Vulkan instance\n\n"
|
||||||
|
L"The Vulkan runtime is installed, but there are no supported "
|
||||||
|
L"hardware vendor interfaces present",
|
||||||
|
L"Vulkan Error", MB_OK | MB_ICONERROR);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
VkDebugReportCallbackEXT debugReportCallback;
|
VkDebugReportCallbackEXT debugReportCallback;
|
||||||
|
@ -877,7 +890,7 @@ class VulkanTextureS : public ITextureS
|
||||||
texCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
texCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||||
texCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
texCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
texCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
texCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
texCreateInfo.extent = { m_width, m_height, 1 };
|
texCreateInfo.extent = { uint32_t(m_width), uint32_t(m_height), 1 };
|
||||||
texCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
texCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||||
ThrowIfFailed(vk::CreateImage(ctx->m_dev, &texCreateInfo, nullptr, &m_gpuTex));
|
ThrowIfFailed(vk::CreateImage(ctx->m_dev, &texCreateInfo, nullptr, &m_gpuTex));
|
||||||
|
|
||||||
|
@ -1070,7 +1083,7 @@ class VulkanTextureSA : public ITextureSA
|
||||||
texCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
texCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||||
texCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
texCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
texCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
texCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
texCreateInfo.extent = { m_width, m_height, 1 };
|
texCreateInfo.extent = { uint32_t(m_width), uint32_t(m_height), 1 };
|
||||||
texCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
texCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||||
ThrowIfFailed(vk::CreateImage(ctx->m_dev, &texCreateInfo, nullptr, &m_gpuTex));
|
ThrowIfFailed(vk::CreateImage(ctx->m_dev, &texCreateInfo, nullptr, &m_gpuTex));
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,10 @@
|
||||||
#include "boo/graphicsdev/D3D.hpp"
|
#include "boo/graphicsdev/D3D.hpp"
|
||||||
#include "logvisor/logvisor.hpp"
|
#include "logvisor/logvisor.hpp"
|
||||||
|
|
||||||
|
#if BOO_HAS_VULKAN
|
||||||
|
#include <vulkan/vulkan.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
DWORD g_mainThreadId = 0;
|
DWORD g_mainThreadId = 0;
|
||||||
|
|
||||||
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||||
|
@ -60,7 +64,8 @@ namespace boo
|
||||||
static logvisor::Module Log("boo::ApplicationWin32");
|
static logvisor::Module Log("boo::ApplicationWin32");
|
||||||
Win32Cursors WIN32_CURSORS;
|
Win32Cursors WIN32_CURSORS;
|
||||||
|
|
||||||
IWindow* _WindowWin32New(const SystemString& title, Boo3DAppContext& d3dCtx, uint32_t sampleCount);
|
IWindow* _WindowWin32New(const SystemString& title, Boo3DAppContext& d3dCtx,
|
||||||
|
void* vulkanHandle, uint32_t sampleCount);
|
||||||
|
|
||||||
class ApplicationWin32 final : public IApplication
|
class ApplicationWin32 final : public IApplication
|
||||||
{
|
{
|
||||||
|
@ -73,6 +78,7 @@ class ApplicationWin32 final : public IApplication
|
||||||
bool m_singleInstance;
|
bool m_singleInstance;
|
||||||
|
|
||||||
Boo3DAppContext m_3dCtx;
|
Boo3DAppContext m_3dCtx;
|
||||||
|
PFN_vkGetInstanceProcAddr m_getVkProc = nullptr;
|
||||||
|
|
||||||
void _deletedWindow(IWindow* window)
|
void _deletedWindow(IWindow* window)
|
||||||
{
|
{
|
||||||
|
@ -105,12 +111,25 @@ public:
|
||||||
|
|
||||||
bool no12 = false;
|
bool no12 = false;
|
||||||
bool noD3d = false;
|
bool noD3d = false;
|
||||||
|
#if BOO_HAS_VULKAN
|
||||||
|
bool useVulkan = true;
|
||||||
|
#endif
|
||||||
for (const SystemString& arg : args)
|
for (const SystemString& arg : args)
|
||||||
{
|
{
|
||||||
if (!arg.compare(L"--d3d11"))
|
if (!arg.compare(L"--d3d11"))
|
||||||
no12 = true;
|
no12 = true;
|
||||||
|
#if BOO_HAS_VULKAN
|
||||||
|
if (!arg.compare(L"--vulkan"))
|
||||||
|
noD3d = true;
|
||||||
|
if (!arg.compare(L"--gl"))
|
||||||
|
{
|
||||||
|
noD3d = true;
|
||||||
|
useVulkan = false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (!arg.compare(L"--gl"))
|
if (!arg.compare(L"--gl"))
|
||||||
noD3d = true;
|
noD3d = true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if _WIN32_WINNT_WIN10
|
#if _WIN32_WINNT_WIN10
|
||||||
|
@ -227,6 +246,27 @@ public:
|
||||||
return;
|
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 */
|
/* Finally try OpenGL */
|
||||||
{
|
{
|
||||||
/* Obtain DXGI Factory */
|
/* Obtain DXGI Factory */
|
||||||
|
@ -383,7 +423,7 @@ public:
|
||||||
return m_mwret;
|
return m_mwret;
|
||||||
}
|
}
|
||||||
|
|
||||||
IWindow* window = _WindowWin32New(title, m_3dCtx, sampleCount);
|
IWindow* window = _WindowWin32New(title, m_3dCtx, m_getVkProc, sampleCount);
|
||||||
HWND hwnd = HWND(window->getPlatformHandle());
|
HWND hwnd = HWND(window->getPlatformHandle());
|
||||||
m_allWindows[hwnd] = window;
|
m_allWindows[hwnd] = window;
|
||||||
return window;
|
return window;
|
||||||
|
|
|
@ -103,6 +103,7 @@ struct Boo3DAppContext
|
||||||
D3D12Context m_ctx12;
|
D3D12Context m_ctx12;
|
||||||
#endif
|
#endif
|
||||||
OGLContext m_ctxOgl;
|
OGLContext m_ctxOgl;
|
||||||
|
ComPtr<IDXGIFactory1> m_vulkanDxFactory;
|
||||||
|
|
||||||
void resize(boo::IWindow* window, size_t width, size_t height)
|
void resize(boo::IWindow* window, size_t width, size_t height)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "Win32Common.hpp"
|
#include "Win32Common.hpp"
|
||||||
#include <Windowsx.h>
|
#include <Windowsx.h>
|
||||||
|
#include "boo/IApplication.hpp"
|
||||||
#include "boo/IWindow.hpp"
|
#include "boo/IWindow.hpp"
|
||||||
#include "boo/IGraphicsContext.hpp"
|
#include "boo/IGraphicsContext.hpp"
|
||||||
#include "logvisor/logvisor.hpp"
|
#include "logvisor/logvisor.hpp"
|
||||||
|
@ -9,6 +10,10 @@
|
||||||
#include "boo/graphicsdev/glew.h"
|
#include "boo/graphicsdev/glew.h"
|
||||||
#include "boo/graphicsdev/wglew.h"
|
#include "boo/graphicsdev/wglew.h"
|
||||||
|
|
||||||
|
#if BOO_HAS_VULKAN
|
||||||
|
#include "boo/graphicsdev/Vulkan.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
static const int ContextAttribs[] =
|
static const int ContextAttribs[] =
|
||||||
{
|
{
|
||||||
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
|
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||||
|
@ -30,6 +35,11 @@ IGraphicsDataFactory* _NewD3D12DataFactory(D3D12Context* ctx, IGraphicsContext*
|
||||||
IGraphicsCommandQueue* _NewD3D11CommandQueue(D3D11Context* ctx, D3D11Context::Window* windowCtx, IGraphicsContext* parent);
|
IGraphicsCommandQueue* _NewD3D11CommandQueue(D3D11Context* ctx, D3D11Context::Window* windowCtx, IGraphicsContext* parent);
|
||||||
IGraphicsDataFactory* _NewD3D11DataFactory(D3D11Context* ctx, IGraphicsContext* parent, uint32_t sampleCount);
|
IGraphicsDataFactory* _NewD3D11DataFactory(D3D11Context* ctx, IGraphicsContext* parent, uint32_t sampleCount);
|
||||||
IGraphicsCommandQueue* _NewGLCommandQueue(IGraphicsContext* parent);
|
IGraphicsCommandQueue* _NewGLCommandQueue(IGraphicsContext* parent);
|
||||||
|
#if BOO_HAS_VULKAN
|
||||||
|
IGraphicsCommandQueue* _NewVulkanCommandQueue(VulkanContext* ctx,
|
||||||
|
VulkanContext::Window* windowCtx,
|
||||||
|
IGraphicsContext* parent);
|
||||||
|
#endif
|
||||||
|
|
||||||
struct GraphicsContextWin32 : IGraphicsContext
|
struct GraphicsContextWin32 : IGraphicsContext
|
||||||
{
|
{
|
||||||
|
@ -370,6 +380,239 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if BOO_HAS_VULKAN
|
||||||
|
struct GraphicsContextWin32Vulkan : GraphicsContextWin32
|
||||||
|
{
|
||||||
|
HINSTANCE m_appInstance;
|
||||||
|
HWND m_hwnd;
|
||||||
|
VulkanContext* m_ctx;
|
||||||
|
VkSurfaceKHR m_surface = VK_NULL_HANDLE;
|
||||||
|
VkFormat m_format;
|
||||||
|
VkColorSpaceKHR m_colorspace;
|
||||||
|
uint32_t m_sampleCount;
|
||||||
|
|
||||||
|
IGraphicsCommandQueue* m_commandQueue = nullptr;
|
||||||
|
IGraphicsDataFactory* m_dataFactory = nullptr;
|
||||||
|
|
||||||
|
std::thread m_vsyncThread;
|
||||||
|
bool m_vsyncRunning;
|
||||||
|
|
||||||
|
static void ThrowIfFailed(VkResult res)
|
||||||
|
{
|
||||||
|
if (res != VK_SUCCESS)
|
||||||
|
Log.report(logvisor::Fatal, "%d\n", res);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
IWindowCallback* m_callback;
|
||||||
|
|
||||||
|
GraphicsContextWin32Vulkan(IWindow* parentWindow, HINSTANCE appInstance, HWND hwnd,
|
||||||
|
VulkanContext* ctx, Boo3DAppContext& b3dCtx, uint32_t drawSamples)
|
||||||
|
: GraphicsContextWin32(EGraphicsAPI::Vulkan, parentWindow, b3dCtx),
|
||||||
|
m_appInstance(appInstance), m_hwnd(hwnd), m_ctx(ctx), m_sampleCount(drawSamples)
|
||||||
|
{
|
||||||
|
HMONITOR testMon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY);
|
||||||
|
ComPtr<IDXGIAdapter1> adapter;
|
||||||
|
ComPtr<IDXGIOutput> foundOut;
|
||||||
|
int i=0;
|
||||||
|
while (b3dCtx.m_vulkanDxFactory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND)
|
||||||
|
{
|
||||||
|
int j=0;
|
||||||
|
ComPtr<IDXGIOutput> out;
|
||||||
|
while (adapter->EnumOutputs(j, &out) != DXGI_ERROR_NOT_FOUND)
|
||||||
|
{
|
||||||
|
DXGI_OUTPUT_DESC desc;
|
||||||
|
out->GetDesc(&desc);
|
||||||
|
if (desc.Monitor == testMon)
|
||||||
|
{
|
||||||
|
out.As<IDXGIOutput>(&m_output);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
if (m_output)
|
||||||
|
break;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_output)
|
||||||
|
Log.report(logvisor::Fatal, "unable to find window's IDXGIOutput");
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy()
|
||||||
|
{
|
||||||
|
VulkanContext::Window& m_windowCtx = *m_ctx->m_windows[m_parentWindow];
|
||||||
|
m_windowCtx.m_swapChains[0].destroy(m_ctx->m_dev);
|
||||||
|
m_windowCtx.m_swapChains[1].destroy(m_ctx->m_dev);
|
||||||
|
//vk::DestroySurfaceKHR(m_ctx->m_instance, m_surface, nullptr);
|
||||||
|
|
||||||
|
if (m_vsyncRunning)
|
||||||
|
{
|
||||||
|
m_vsyncRunning = false;
|
||||||
|
m_vsyncThread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ctx->m_windows.erase(m_parentWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
~GraphicsContextWin32Vulkan() {destroy();}
|
||||||
|
|
||||||
|
VulkanContext::Window* m_windowCtx = nullptr;
|
||||||
|
|
||||||
|
void resized(SWindowRect& rect)
|
||||||
|
{
|
||||||
|
if (m_windowCtx)
|
||||||
|
m_ctx->resizeSwapChain(*m_windowCtx, m_surface, m_format, m_colorspace);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setCallback(IWindowCallback* cb)
|
||||||
|
{
|
||||||
|
m_callback = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
EGraphicsAPI getAPI() const
|
||||||
|
{
|
||||||
|
return m_api;
|
||||||
|
}
|
||||||
|
|
||||||
|
EPixelFormat getPixelFormat() const
|
||||||
|
{
|
||||||
|
return m_pf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPixelFormat(EPixelFormat pf)
|
||||||
|
{
|
||||||
|
if (pf > EPixelFormat::RGBAF32_Z24)
|
||||||
|
return;
|
||||||
|
m_pf = pf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void initializeContext(void* getVkProc)
|
||||||
|
{
|
||||||
|
vk::init_dispatch_table_top(PFN_vkGetInstanceProcAddr(getVkProc));
|
||||||
|
if (m_ctx->m_instance == VK_NULL_HANDLE)
|
||||||
|
{
|
||||||
|
const SystemString& appName = APP->getUniqueName();
|
||||||
|
int len = WideCharToMultiByte(CP_UTF8, 0, appName.c_str(), appName.size(), nullptr, 0, nullptr, nullptr);
|
||||||
|
std::string utf8(len, '\0');
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, appName.c_str(), appName.size(), &utf8[0], len, nullptr, nullptr);
|
||||||
|
m_ctx->initVulkan(utf8.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::init_dispatch_table_middle(m_ctx->m_instance, false);
|
||||||
|
m_ctx->enumerateDevices();
|
||||||
|
|
||||||
|
m_windowCtx =
|
||||||
|
m_ctx->m_windows.emplace(std::make_pair(m_parentWindow,
|
||||||
|
std::make_unique<VulkanContext::Window>())).first->second.get();
|
||||||
|
|
||||||
|
VkWin32SurfaceCreateInfoKHR surfaceInfo = {};
|
||||||
|
surfaceInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
|
||||||
|
surfaceInfo.hinstance = m_appInstance;
|
||||||
|
surfaceInfo.hwnd = m_hwnd;
|
||||||
|
ThrowIfFailed(vk::CreateWin32SurfaceKHR(m_ctx->m_instance, &surfaceInfo, nullptr, &m_surface));
|
||||||
|
|
||||||
|
/* Iterate over each queue to learn whether it supports presenting */
|
||||||
|
VkBool32 *supportsPresent = (VkBool32*)malloc(m_ctx->m_queueCount * sizeof(VkBool32));
|
||||||
|
for (uint32_t i=0 ; i<m_ctx->m_queueCount ; ++i)
|
||||||
|
vk::GetPhysicalDeviceSurfaceSupportKHR(m_ctx->m_gpus[0], i, m_surface, &supportsPresent[i]);
|
||||||
|
|
||||||
|
/* Search for a graphics queue and a present queue in the array of queue
|
||||||
|
* families, try to find one that supports both */
|
||||||
|
if (m_ctx->m_graphicsQueueFamilyIndex == UINT32_MAX)
|
||||||
|
{
|
||||||
|
/* First window, init device */
|
||||||
|
for (uint32_t i=0 ; i<m_ctx->m_queueCount; ++i)
|
||||||
|
{
|
||||||
|
if ((m_ctx->m_queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0)
|
||||||
|
{
|
||||||
|
if (supportsPresent[i] == VK_TRUE)
|
||||||
|
{
|
||||||
|
m_ctx->m_graphicsQueueFamilyIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate error if could not find a queue that supports both a graphics
|
||||||
|
* and present */
|
||||||
|
if (m_ctx->m_graphicsQueueFamilyIndex == UINT32_MAX)
|
||||||
|
Log.report(logvisor::Fatal,
|
||||||
|
"Could not find a queue that supports both graphics and present");
|
||||||
|
|
||||||
|
m_ctx->initDevice();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Subsequent window, verify present */
|
||||||
|
if (supportsPresent[m_ctx->m_graphicsQueueFamilyIndex] == VK_FALSE)
|
||||||
|
Log.report(logvisor::Fatal, "subsequent surface doesn't support present");
|
||||||
|
}
|
||||||
|
free(supportsPresent);
|
||||||
|
|
||||||
|
vk::init_dispatch_table_bottom(m_ctx->m_instance, m_ctx->m_dev);
|
||||||
|
|
||||||
|
if (!vk::GetPhysicalDeviceWin32PresentationSupportKHR(m_ctx->m_gpus[0], m_ctx->m_graphicsQueueFamilyIndex))
|
||||||
|
{
|
||||||
|
Log.report(logvisor::Fatal, "Win32 doesn't support vulkan present");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the list of VkFormats that are supported */
|
||||||
|
uint32_t formatCount;
|
||||||
|
ThrowIfFailed(vk::GetPhysicalDeviceSurfaceFormatsKHR(m_ctx->m_gpus[0], m_surface, &formatCount, nullptr));
|
||||||
|
VkSurfaceFormatKHR* surfFormats = (VkSurfaceFormatKHR*)malloc(formatCount * sizeof(VkSurfaceFormatKHR));
|
||||||
|
ThrowIfFailed(vk::GetPhysicalDeviceSurfaceFormatsKHR(m_ctx->m_gpus[0], m_surface, &formatCount, surfFormats));
|
||||||
|
|
||||||
|
|
||||||
|
/* If the format list includes just one entry of VK_FORMAT_UNDEFINED,
|
||||||
|
* the surface has no preferred format. Otherwise, at least one
|
||||||
|
* supported format will be returned. */
|
||||||
|
if (formatCount >= 1)
|
||||||
|
{
|
||||||
|
if (surfFormats[0].format == VK_FORMAT_UNDEFINED)
|
||||||
|
m_format = VK_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
else
|
||||||
|
m_format = surfFormats[0].format;
|
||||||
|
m_colorspace = surfFormats[0].colorSpace;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Log.report(logvisor::Fatal, "no surface formats available for Vulkan swapchain");
|
||||||
|
|
||||||
|
m_ctx->initSwapChain(*m_windowCtx, m_surface, m_format, m_colorspace);
|
||||||
|
|
||||||
|
m_dataFactory = new class VulkanDataFactory(this, m_ctx, m_sampleCount);
|
||||||
|
m_commandQueue = _NewVulkanCommandQueue(m_ctx, m_ctx->m_windows[m_parentWindow].get(), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void makeCurrent() {}
|
||||||
|
|
||||||
|
void postInit() {}
|
||||||
|
|
||||||
|
IGraphicsCommandQueue* getCommandQueue()
|
||||||
|
{
|
||||||
|
return m_commandQueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
IGraphicsDataFactory* getDataFactory()
|
||||||
|
{
|
||||||
|
return m_dataFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
IGraphicsDataFactory* getMainContextDataFactory()
|
||||||
|
{
|
||||||
|
return getDataFactory();
|
||||||
|
}
|
||||||
|
|
||||||
|
IGraphicsDataFactory* getLoadContextDataFactory()
|
||||||
|
{
|
||||||
|
return getDataFactory();
|
||||||
|
}
|
||||||
|
|
||||||
|
void present() {}
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
static void genFrameDefault(MONITORINFO* screen, int& xOut, int& yOut, int& wOut, int& hOut)
|
static void genFrameDefault(MONITORINFO* screen, int& xOut, int& yOut, int& wOut, int& hOut)
|
||||||
{
|
{
|
||||||
float width = screen->rcMonitor.right * 2.0 / 3.0;
|
float width = screen->rcMonitor.right * 2.0 / 3.0;
|
||||||
|
@ -709,11 +952,12 @@ class WindowWin32 : public IWindow
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
WindowWin32(const SystemString& title, Boo3DAppContext& b3dCtx, uint32_t sampleCount)
|
WindowWin32(const SystemString& title, Boo3DAppContext& b3dCtx, void* vulkanHandle, uint32_t sampleCount)
|
||||||
{
|
{
|
||||||
m_hwnd = CreateWindowW(L"BooWindow", title.c_str(), WS_OVERLAPPEDWINDOW,
|
m_hwnd = CreateWindowW(L"BooWindow", title.c_str(), WS_OVERLAPPEDWINDOW,
|
||||||
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||||
NULL, NULL, NULL, NULL);
|
NULL, NULL, NULL, NULL);
|
||||||
|
HINSTANCE wndInstance = HINSTANCE(GetWindowLongPtr(m_hwnd, GWLP_HINSTANCE));
|
||||||
m_imc = ImmGetContext(m_hwnd);
|
m_imc = ImmGetContext(m_hwnd);
|
||||||
IGraphicsContext::EGraphicsAPI api = IGraphicsContext::EGraphicsAPI::D3D11;
|
IGraphicsContext::EGraphicsAPI api = IGraphicsContext::EGraphicsAPI::D3D11;
|
||||||
#if _WIN32_WINNT_WIN10
|
#if _WIN32_WINNT_WIN10
|
||||||
|
@ -726,6 +970,13 @@ public:
|
||||||
this, m_hwnd, b3dCtx, sampleCount));
|
this, m_hwnd, b3dCtx, sampleCount));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (b3dCtx.m_vulkanDxFactory)
|
||||||
|
{
|
||||||
|
m_gfxCtx.reset(new GraphicsContextWin32Vulkan(this, wndInstance, m_hwnd, &g_VulkanContext,
|
||||||
|
b3dCtx, sampleCount));
|
||||||
|
m_gfxCtx->initializeContext(vulkanHandle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
m_gfxCtx.reset(new GraphicsContextWin32D3D(api, this, m_hwnd, b3dCtx, sampleCount));
|
m_gfxCtx.reset(new GraphicsContextWin32D3D(api, this, m_hwnd, b3dCtx, sampleCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1291,9 +1542,10 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
IWindow* _WindowWin32New(const SystemString& title, Boo3DAppContext& d3dCtx, uint32_t sampleCount)
|
IWindow* _WindowWin32New(const SystemString& title, Boo3DAppContext& d3dCtx,
|
||||||
|
void* vulkanHandle, uint32_t sampleCount)
|
||||||
{
|
{
|
||||||
return new WindowWin32(title, d3dCtx, sampleCount);
|
return new WindowWin32(title, d3dCtx, vulkanHandle, sampleCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue