mirror of https://github.com/AxioDL/boo.git
Tons of Vulkan bug fixes
This commit is contained in:
parent
ae487b70f3
commit
74e2f47bcf
|
@ -130,7 +130,7 @@ else(NOT GEKKO)
|
||||||
if(NOT (VULKAN_LIBRARY STREQUAL VULKAN_LIBRARY-NOTFOUND))
|
if(NOT (VULKAN_LIBRARY STREQUAL VULKAN_LIBRARY-NOTFOUND))
|
||||||
message(STATUS "Vulkan loader found; enabling Vulkan support")
|
message(STATUS "Vulkan loader found; enabling Vulkan support")
|
||||||
list(APPEND _BOO_SYS_DEFINES -DBOO_HAS_VULKAN=1)
|
list(APPEND _BOO_SYS_DEFINES -DBOO_HAS_VULKAN=1)
|
||||||
list(APPEND _BOO_SYS_LIBS ${VULKAN_LIBRARY})
|
list(APPEND _BOO_SYS_LIBS ${VULKAN_LIBRARY} xcb X11-xcb)
|
||||||
list(APPEND PLAT_SRCS lib/graphicsdev/Vulkan.cpp)
|
list(APPEND PLAT_SRCS lib/graphicsdev/Vulkan.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,16 @@ namespace boo
|
||||||
|
|
||||||
struct VulkanContext
|
struct VulkanContext
|
||||||
{
|
{
|
||||||
std::vector<const char*> m_instanceLayerNames;
|
struct LayerProperties
|
||||||
|
{
|
||||||
|
VkLayerProperties properties;
|
||||||
|
std::vector<VkExtensionProperties> extensions;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<LayerProperties> m_instanceLayerProperties;
|
||||||
|
std::vector<const char*> m_layerNames;
|
||||||
std::vector<const char*> m_instanceExtensionNames;
|
std::vector<const char*> m_instanceExtensionNames;
|
||||||
VkInstance m_instance = VK_NULL_HANDLE;
|
VkInstance m_instance = VK_NULL_HANDLE;
|
||||||
std::vector<const char*> m_deviceLayerNames;
|
|
||||||
std::vector<const char*> m_deviceExtensionNames;
|
std::vector<const char*> m_deviceExtensionNames;
|
||||||
std::vector<VkPhysicalDevice> m_gpus;
|
std::vector<VkPhysicalDevice> m_gpus;
|
||||||
VkPhysicalDeviceProperties m_gpuProps;
|
VkPhysicalDeviceProperties m_gpuProps;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define VK_USE_PLATFORM_WIN32_KHR
|
#define VK_USE_PLATFORM_WIN32_KHR
|
||||||
#else
|
#else
|
||||||
#define VK_USE_PLATFORM_XLIB_KHR
|
#define VK_USE_PLATFORM_XCB_KHR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "boo/graphicsdev/Vulkan.hpp"
|
#include "boo/graphicsdev/Vulkan.hpp"
|
||||||
|
@ -135,6 +135,33 @@ static inline void ThrowIfFalse(bool res)
|
||||||
Log.report(LogVisor::FatalError, "operation failed\n", res);
|
Log.report(LogVisor::FatalError, "operation failed\n", res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VKAPI_ATTR VkBool32 VKAPI_CALL
|
||||||
|
dbgFunc(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType,
|
||||||
|
uint64_t srcObject, size_t location, int32_t msgCode,
|
||||||
|
const char *pLayerPrefix, const char *pMsg, void *pUserData)
|
||||||
|
{
|
||||||
|
if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
|
||||||
|
Log.report(LogVisor::FatalError, "[%s] Code %d : %s", pLayerPrefix, msgCode, pMsg);
|
||||||
|
} else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
|
||||||
|
Log.report(LogVisor::Warning, "[%s] Code %d : %s", pLayerPrefix, msgCode, pMsg);
|
||||||
|
} else if (msgFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
|
||||||
|
Log.report(LogVisor::Warning, "[%s] Code %d : %s", pLayerPrefix, msgCode, pMsg);
|
||||||
|
} else if (msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
|
||||||
|
Log.report(LogVisor::Info, "[%s] Code %d : %s", pLayerPrefix, msgCode, pMsg);
|
||||||
|
} else if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
|
||||||
|
Log.report(LogVisor::Info, "[%s] Code %d : %s", pLayerPrefix, msgCode, pMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* false indicates that layer should not bail-out of an
|
||||||
|
* API call that had validation failures. This may mean that the
|
||||||
|
* app dies inside the driver due to invalid parameter(s).
|
||||||
|
* That's what would happen without validation layers, so we'll
|
||||||
|
* keep that behavior here.
|
||||||
|
*/
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static bool MemoryTypeFromProperties(VulkanContext* ctx, uint32_t typeBits,
|
static bool MemoryTypeFromProperties(VulkanContext* ctx, uint32_t typeBits,
|
||||||
VkFlags requirementsMask,
|
VkFlags requirementsMask,
|
||||||
uint32_t *typeIndex)
|
uint32_t *typeIndex)
|
||||||
|
@ -209,19 +236,128 @@ static void SetImageLayout(VkCommandBuffer cmd, VkImage image,
|
||||||
1, &imageMemoryBarrier);
|
1, &imageMemoryBarrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VkResult InitGlobalExtensionProperties(VulkanContext::LayerProperties& layerProps) {
|
||||||
|
VkExtensionProperties *instance_extensions;
|
||||||
|
uint32_t instance_extension_count;
|
||||||
|
VkResult res;
|
||||||
|
char *layer_name = nullptr;
|
||||||
|
|
||||||
|
layer_name = layerProps.properties.layerName;
|
||||||
|
|
||||||
|
do {
|
||||||
|
res = vkEnumerateInstanceExtensionProperties(
|
||||||
|
layer_name, &instance_extension_count, nullptr);
|
||||||
|
if (res)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
if (instance_extension_count == 0) {
|
||||||
|
return VK_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
layerProps.extensions.resize(instance_extension_count);
|
||||||
|
instance_extensions = layerProps.extensions.data();
|
||||||
|
res = vkEnumerateInstanceExtensionProperties(
|
||||||
|
layer_name, &instance_extension_count, instance_extensions);
|
||||||
|
} while (res == VK_INCOMPLETE);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return 1 (true) if all layer names specified in check_names
|
||||||
|
* can be found in given layer properties.
|
||||||
|
*/
|
||||||
|
static void demo_check_layers(const std::vector<VulkanContext::LayerProperties>& layerProps,
|
||||||
|
const std::vector<const char*> &layerNames) {
|
||||||
|
uint32_t check_count = layerNames.size();
|
||||||
|
uint32_t layer_count = layerProps.size();
|
||||||
|
for (uint32_t i = 0; i < check_count; i++) {
|
||||||
|
VkBool32 found = 0;
|
||||||
|
for (uint32_t j = 0; j < layer_count; j++) {
|
||||||
|
if (!strcmp(layerNames[i], layerProps[j].properties.layerName)) {
|
||||||
|
found = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
Log.report(LogVisor::FatalError, "Cannot find layer: %s", layerNames[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void VulkanContext::initVulkan(const char* appName)
|
void VulkanContext::initVulkan(const char* appName)
|
||||||
{
|
{
|
||||||
|
if (!glslang::InitializeProcess())
|
||||||
|
Log.report(LogVisor::FatalError, "unable to initialize glslang");
|
||||||
|
|
||||||
|
uint32_t instanceLayerCount;
|
||||||
|
VkLayerProperties* vkProps = nullptr;
|
||||||
|
VkResult res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It's possible, though very rare, that the number of
|
||||||
|
* instance layers could change. For example, installing something
|
||||||
|
* could include new layers that the loader would pick up
|
||||||
|
* between the initial query for the count and the
|
||||||
|
* request for VkLayerProperties. The loader indicates that
|
||||||
|
* by returning a VK_INCOMPLETE status and will update the
|
||||||
|
* the count parameter.
|
||||||
|
* The count parameter will be updated with the number of
|
||||||
|
* entries loaded into the data pointer - in case the number
|
||||||
|
* of layers went down or is smaller than the size given.
|
||||||
|
*/
|
||||||
|
putenv("VK_LAYER_PATH=/usr/share/vulkan/explicit_layer.d");
|
||||||
|
do {
|
||||||
|
ThrowIfFailed(vkEnumerateInstanceLayerProperties(&instanceLayerCount, nullptr));
|
||||||
|
|
||||||
|
if (instanceLayerCount == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
vkProps = (VkLayerProperties *)realloc(vkProps, instanceLayerCount * sizeof(VkLayerProperties));
|
||||||
|
|
||||||
|
res = vkEnumerateInstanceLayerProperties(&instanceLayerCount, vkProps);
|
||||||
|
} while (res == VK_INCOMPLETE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now gather the extension list for each instance layer.
|
||||||
|
*/
|
||||||
|
for (uint32_t i=0 ; i<instanceLayerCount ; ++i)
|
||||||
|
{
|
||||||
|
LayerProperties layerProps;
|
||||||
|
layerProps.properties = vkProps[i];
|
||||||
|
ThrowIfFailed(InitGlobalExtensionProperties(layerProps));
|
||||||
|
m_instanceLayerProperties.push_back(layerProps);
|
||||||
|
}
|
||||||
|
free(vkProps);
|
||||||
|
|
||||||
/* need platform surface extensions */
|
/* need platform surface extensions */
|
||||||
m_instanceExtensionNames.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
|
m_instanceExtensionNames.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
m_instanceExtensionNames.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
|
m_instanceExtensionNames.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
|
||||||
#else
|
#else
|
||||||
m_instanceExtensionNames.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
|
m_instanceExtensionNames.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* need swapchain device extension */
|
/* need swapchain device extension */
|
||||||
m_deviceExtensionNames.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
m_deviceExtensionNames.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
m_layerNames.push_back("VK_LAYER_LUNARG_object_tracker");
|
||||||
|
m_layerNames.push_back("VK_LAYER_LUNARG_draw_state");
|
||||||
|
m_layerNames.push_back("VK_LAYER_LUNARG_mem_tracker");
|
||||||
|
m_layerNames.push_back("VK_LAYER_LUNARG_param_checker");
|
||||||
|
m_layerNames.push_back("VK_LAYER_LUNARG_image");
|
||||||
|
m_layerNames.push_back("VK_LAYER_LUNARG_threading");
|
||||||
|
m_layerNames.push_back("VK_LAYER_LUNARG_swapchain");
|
||||||
|
m_layerNames.push_back("VK_LAYER_LUNARG_device_limits");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
demo_check_layers(m_instanceLayerProperties, m_layerNames);
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
/* Enable debug callback extension */
|
||||||
|
m_instanceExtensionNames.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* create the instance */
|
/* create the instance */
|
||||||
VkApplicationInfo appInfo = {};
|
VkApplicationInfo appInfo = {};
|
||||||
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||||
|
@ -237,15 +373,32 @@ void VulkanContext::initVulkan(const char* appName)
|
||||||
instInfo.pNext = nullptr;
|
instInfo.pNext = nullptr;
|
||||||
instInfo.flags = 0;
|
instInfo.flags = 0;
|
||||||
instInfo.pApplicationInfo = &appInfo;
|
instInfo.pApplicationInfo = &appInfo;
|
||||||
instInfo.enabledLayerCount = m_instanceLayerNames.size();
|
instInfo.enabledLayerCount = m_layerNames.size();
|
||||||
instInfo.ppEnabledLayerNames = m_instanceLayerNames.size()
|
instInfo.ppEnabledLayerNames = m_layerNames.size()
|
||||||
? m_instanceLayerNames.data()
|
? m_layerNames.data()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
instInfo.enabledExtensionCount = m_instanceExtensionNames.size();
|
instInfo.enabledExtensionCount = m_instanceExtensionNames.size();
|
||||||
instInfo.ppEnabledExtensionNames = m_instanceExtensionNames.data();
|
instInfo.ppEnabledExtensionNames = m_instanceExtensionNames.data();
|
||||||
|
|
||||||
ThrowIfFailed(vkCreateInstance(&instInfo, nullptr, &m_instance));
|
ThrowIfFailed(vkCreateInstance(&instInfo, nullptr, &m_instance));
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
VkDebugReportCallbackEXT debugReportCallback;
|
||||||
|
|
||||||
|
PFN_vkCreateDebugReportCallbackEXT createDebugReportCallback =
|
||||||
|
(PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(m_instance, "vkCreateDebugReportCallbackEXT");
|
||||||
|
if (!createDebugReportCallback)
|
||||||
|
Log.report(LogVisor::FatalError, "GetInstanceProcAddr: Unable to find vkCreateDebugReportCallbackEXT function.");
|
||||||
|
|
||||||
|
VkDebugReportCallbackCreateInfoEXT debugCreateInfo = {};
|
||||||
|
debugCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
|
||||||
|
debugCreateInfo.pNext = nullptr;
|
||||||
|
debugCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
|
||||||
|
debugCreateInfo.pfnCallback = dbgFunc;
|
||||||
|
debugCreateInfo.pUserData = nullptr;
|
||||||
|
ThrowIfFailed(createDebugReportCallback(m_instance, &debugCreateInfo, nullptr, &debugReportCallback));
|
||||||
|
#endif
|
||||||
|
|
||||||
uint32_t gpuCount = 1;
|
uint32_t gpuCount = 1;
|
||||||
ThrowIfFailed(vkEnumeratePhysicalDevices(m_instance, &gpuCount, nullptr));
|
ThrowIfFailed(vkEnumeratePhysicalDevices(m_instance, &gpuCount, nullptr));
|
||||||
assert(gpuCount);
|
assert(gpuCount);
|
||||||
|
@ -286,9 +439,9 @@ void VulkanContext::initDevice()
|
||||||
deviceInfo.pNext = nullptr;
|
deviceInfo.pNext = nullptr;
|
||||||
deviceInfo.queueCreateInfoCount = 1;
|
deviceInfo.queueCreateInfoCount = 1;
|
||||||
deviceInfo.pQueueCreateInfos = &queueInfo;
|
deviceInfo.pQueueCreateInfos = &queueInfo;
|
||||||
deviceInfo.enabledLayerCount = m_deviceLayerNames.size();
|
deviceInfo.enabledLayerCount = m_layerNames.size();
|
||||||
deviceInfo.ppEnabledLayerNames =
|
deviceInfo.ppEnabledLayerNames =
|
||||||
deviceInfo.enabledLayerCount ? m_deviceLayerNames.data() : nullptr;
|
deviceInfo.enabledLayerCount ? m_layerNames.data() : nullptr;
|
||||||
deviceInfo.enabledExtensionCount = m_deviceExtensionNames.size();
|
deviceInfo.enabledExtensionCount = m_deviceExtensionNames.size();
|
||||||
deviceInfo.ppEnabledExtensionNames =
|
deviceInfo.ppEnabledExtensionNames =
|
||||||
deviceInfo.enabledExtensionCount ? m_deviceExtensionNames.data() : nullptr;
|
deviceInfo.enabledExtensionCount ? m_deviceExtensionNames.data() : nullptr;
|
||||||
|
@ -723,7 +876,7 @@ class VulkanTextureS : public ITextureS
|
||||||
|
|
||||||
size_t srcRowPitch = width * pxPitchNum / pxPitchDenom;
|
size_t srcRowPitch = width * pxPitchNum / pxPitchDenom;
|
||||||
|
|
||||||
for (size_t y=0 ; y<height ; ++i)
|
for (size_t y=0 ; y<height ; ++y)
|
||||||
{
|
{
|
||||||
memcpy(dstDataIt, srcDataIt, srcRowPitch);
|
memcpy(dstDataIt, srcDataIt, srcRowPitch);
|
||||||
srcDataIt += srcRowPitch;
|
srcDataIt += srcRowPitch;
|
||||||
|
@ -959,7 +1112,7 @@ class VulkanTextureSA : public ITextureSA
|
||||||
|
|
||||||
size_t srcRowPitch = width * pxPitchNum / pxPitchDenom;
|
size_t srcRowPitch = width * pxPitchNum / pxPitchDenom;
|
||||||
|
|
||||||
for (size_t y=0 ; y<height ; ++i)
|
for (size_t y=0 ; y<height ; ++y)
|
||||||
{
|
{
|
||||||
memcpy(dstDataIt, srcDataIt, srcRowPitch);
|
memcpy(dstDataIt, srcDataIt, srcRowPitch);
|
||||||
srcDataIt += srcRowPitch;
|
srcDataIt += srcRowPitch;
|
||||||
|
@ -1982,6 +2135,7 @@ struct VulkanCommandQueue : IGraphicsCommandQueue
|
||||||
VkCommandPoolCreateInfo poolInfo = {};
|
VkCommandPoolCreateInfo poolInfo = {};
|
||||||
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||||
poolInfo.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
|
poolInfo.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
|
||||||
|
poolInfo.queueFamilyIndex = m_ctx->m_graphicsQueueFamilyIndex;
|
||||||
ThrowIfFailed(vkCreateCommandPool(ctx->m_dev, &poolInfo, nullptr, &m_cmdPool));
|
ThrowIfFailed(vkCreateCommandPool(ctx->m_dev, &poolInfo, nullptr, &m_cmdPool));
|
||||||
ThrowIfFailed(vkCreateCommandPool(ctx->m_dev, &poolInfo, nullptr, &m_dynamicCmdPool));
|
ThrowIfFailed(vkCreateCommandPool(ctx->m_dev, &poolInfo, nullptr, &m_dynamicCmdPool));
|
||||||
|
|
||||||
|
|
|
@ -25,12 +25,15 @@ DBusConnection* RegisterDBus(const char* appName, bool& isFirst);
|
||||||
#include "XlibCommon.hpp"
|
#include "XlibCommon.hpp"
|
||||||
#include <X11/cursorfont.h>
|
#include <X11/cursorfont.h>
|
||||||
|
|
||||||
|
#if BOO_HAS_VULKAN
|
||||||
|
#include <X11/Xlib-xcb.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace boo
|
namespace boo
|
||||||
{
|
{
|
||||||
static LogVisor::LogModule Log("boo::ApplicationXlib");
|
static LogVisor::LogModule Log("boo::ApplicationXlib");
|
||||||
XlibCursors X_CURSORS;
|
XlibCursors X_CURSORS;
|
||||||
|
|
||||||
int XCB_GLX_EVENT_BASE = 0;
|
|
||||||
int XINPUT_OPCODE = 0;
|
int XINPUT_OPCODE = 0;
|
||||||
|
|
||||||
static Window GetWindowOfEvent(XEvent* event, bool& windowEvent)
|
static Window GetWindowOfEvent(XEvent* event, bool& windowEvent)
|
||||||
|
@ -110,7 +113,8 @@ static Window GetWindowOfEvent(XEvent* event, bool& windowEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
IWindow* _WindowXlibNew(const std::string& title,
|
IWindow* _WindowXlibNew(const std::string& title,
|
||||||
Display* display, int defaultScreen, XIM xIM, XIMStyle bestInputStyle, XFontSet fontset,
|
Display* display, void* xcbConn,
|
||||||
|
int defaultScreen, XIM xIM, XIMStyle bestInputStyle, XFontSet fontset,
|
||||||
GLXContext lastCtx, bool useVulkan);
|
GLXContext lastCtx, bool useVulkan);
|
||||||
|
|
||||||
static XIMStyle ChooseBetterStyle(XIMStyle style1, XIMStyle style2)
|
static XIMStyle ChooseBetterStyle(XIMStyle style1, XIMStyle style2)
|
||||||
|
@ -169,10 +173,13 @@ class ApplicationXlib final : public IApplication
|
||||||
XFontSet m_fontset;
|
XFontSet m_fontset;
|
||||||
XIMStyle m_bestStyle = 0;
|
XIMStyle m_bestStyle = 0;
|
||||||
int m_xDefaultScreen = 0;
|
int m_xDefaultScreen = 0;
|
||||||
int m_xcbFd, m_dbusFd, m_maxFd;
|
int m_x11Fd, m_dbusFd, m_maxFd;
|
||||||
|
|
||||||
|
#if BOO_HAS_VULKAN
|
||||||
/* Vulkan enable */
|
/* Vulkan enable */
|
||||||
bool m_useVulkan = true;
|
bool m_useVulkan = true;
|
||||||
|
xcb_connection_t* m_xcbConn;
|
||||||
|
#endif
|
||||||
|
|
||||||
void _deletedWindow(IWindow* window)
|
void _deletedWindow(IWindow* window)
|
||||||
{
|
{
|
||||||
|
@ -256,6 +263,16 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BOO_HAS_VULKAN
|
||||||
|
/* Cast Display to XCB connection for vulkan */
|
||||||
|
m_xcbConn = XGetXCBConnection(m_xDisp);
|
||||||
|
if (!m_xcbConn)
|
||||||
|
{
|
||||||
|
Log.report(LogVisor::FatalError, "Can't cast Display to XCB connection for Vulkan");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Configure locale */
|
/* Configure locale */
|
||||||
if (!XSupportsLocale()) {
|
if (!XSupportsLocale()) {
|
||||||
Log.report(LogVisor::FatalError, "X does not support locale %s.",
|
Log.report(LogVisor::FatalError, "X does not support locale %s.",
|
||||||
|
@ -316,9 +333,9 @@ public:
|
||||||
XkbSetDetectableAutoRepeat(m_xDisp, True, nullptr);
|
XkbSetDetectableAutoRepeat(m_xDisp, True, nullptr);
|
||||||
|
|
||||||
/* Get file descriptors of xcb and dbus interfaces */
|
/* Get file descriptors of xcb and dbus interfaces */
|
||||||
m_xcbFd = ConnectionNumber(m_xDisp);
|
m_x11Fd = ConnectionNumber(m_xDisp);
|
||||||
dbus_connection_get_unix_fd(m_dbus, &m_dbusFd);
|
dbus_connection_get_unix_fd(m_dbus, &m_dbusFd);
|
||||||
m_maxFd = MAX(m_xcbFd, m_dbusFd);
|
m_maxFd = MAX(m_x11Fd, m_dbusFd);
|
||||||
|
|
||||||
XFlush(m_xDisp);
|
XFlush(m_xDisp);
|
||||||
}
|
}
|
||||||
|
@ -375,7 +392,7 @@ public:
|
||||||
{
|
{
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
FD_SET(m_xcbFd, &fds);
|
FD_SET(m_x11Fd, &fds);
|
||||||
FD_SET(m_dbusFd, &fds);
|
FD_SET(m_dbusFd, &fds);
|
||||||
if (pselect(m_maxFd+1, &fds, NULL, NULL, NULL, &origmask) < 0)
|
if (pselect(m_maxFd+1, &fds, NULL, NULL, NULL, &origmask) < 0)
|
||||||
{
|
{
|
||||||
|
@ -384,7 +401,7 @@ public:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FD_ISSET(m_xcbFd, &fds))
|
if (FD_ISSET(m_x11Fd, &fds))
|
||||||
{
|
{
|
||||||
XLockDisplay(m_xDisp);
|
XLockDisplay(m_xDisp);
|
||||||
while (XPending(m_xDisp))
|
while (XPending(m_xDisp))
|
||||||
|
@ -458,8 +475,13 @@ public:
|
||||||
|
|
||||||
IWindow* newWindow(const std::string& title)
|
IWindow* newWindow(const std::string& title)
|
||||||
{
|
{
|
||||||
IWindow* newWindow = _WindowXlibNew(title, m_xDisp, m_xDefaultScreen, m_xIM,
|
#if BOO_HAS_VULKAN
|
||||||
|
IWindow* newWindow = _WindowXlibNew(title, m_xDisp, m_xcbConn, m_xDefaultScreen, m_xIM,
|
||||||
m_bestStyle, m_fontset, m_lastGlxCtx, m_useVulkan);
|
m_bestStyle, m_fontset, m_lastGlxCtx, m_useVulkan);
|
||||||
|
#else
|
||||||
|
IWindow* newWindow = _WindowXlibNew(title, m_xDisp, nullptr, m_xDefaultScreen, m_xIM,
|
||||||
|
m_bestStyle, m_fontset, m_lastGlxCtx, false);
|
||||||
|
#endif
|
||||||
m_windows[(Window)newWindow->getPlatformHandle()] = newWindow;
|
m_windows[(Window)newWindow->getPlatformHandle()] = newWindow;
|
||||||
return newWindow;
|
return newWindow;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,11 @@
|
||||||
#include "boo/IApplication.hpp"
|
#include "boo/IApplication.hpp"
|
||||||
#include "boo/graphicsdev/GL.hpp"
|
#include "boo/graphicsdev/GL.hpp"
|
||||||
|
|
||||||
#define VK_USE_PLATFORM_XLIB_KHR
|
#if BOO_HAS_VULKAN
|
||||||
|
#define VK_USE_PLATFORM_XCB_KHR
|
||||||
#include "boo/graphicsdev/Vulkan.hpp"
|
#include "boo/graphicsdev/Vulkan.hpp"
|
||||||
|
#include <X11/Xlib-xcb.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -60,7 +63,7 @@ static int ctxErrorHandler(Display *dpy, XErrorEvent *ev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const std::vector<std::vector<int>> ContextAttribList =
|
static const int ContextAttribList[7][7] =
|
||||||
{
|
{
|
||||||
{ GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
|
{ GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
|
||||||
GLX_CONTEXT_MINOR_VERSION_ARB, 5,
|
GLX_CONTEXT_MINOR_VERSION_ARB, 5,
|
||||||
|
@ -70,10 +73,12 @@ static const std::vector<std::vector<int>> ContextAttribList =
|
||||||
{ GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
|
{ GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
|
||||||
GLX_CONTEXT_MINOR_VERSION_ARB, 4,
|
GLX_CONTEXT_MINOR_VERSION_ARB, 4,
|
||||||
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
|
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||||
|
0
|
||||||
},
|
},
|
||||||
{ GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
|
{ GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
|
||||||
GLX_CONTEXT_MINOR_VERSION_ARB, 3,
|
GLX_CONTEXT_MINOR_VERSION_ARB, 3,
|
||||||
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
|
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||||
|
0
|
||||||
},
|
},
|
||||||
{ GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
|
{ GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
|
||||||
GLX_CONTEXT_MINOR_VERSION_ARB, 2,
|
GLX_CONTEXT_MINOR_VERSION_ARB, 2,
|
||||||
|
@ -445,9 +450,9 @@ public:
|
||||||
|
|
||||||
s_glxError = false;
|
s_glxError = false;
|
||||||
XErrorHandler oldHandler = XSetErrorHandler(&ctxErrorHandler);
|
XErrorHandler oldHandler = XSetErrorHandler(&ctxErrorHandler);
|
||||||
for (const std::vector<int>& attribs : ContextAttribList)
|
for (int i=0 ; i<std::extent<decltype(ContextAttribList)>::value ; ++i)
|
||||||
{
|
{
|
||||||
m_glxCtx = glXCreateContextAttribsARB(m_xDisp, m_fbconfig, m_lastCtx, True, attribs.data());
|
m_glxCtx = glXCreateContextAttribsARB(m_xDisp, m_fbconfig, m_lastCtx, True, ContextAttribList[i]);
|
||||||
if (m_glxCtx)
|
if (m_glxCtx)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -542,9 +547,9 @@ public:
|
||||||
{
|
{
|
||||||
s_glxError = false;
|
s_glxError = false;
|
||||||
XErrorHandler oldHandler = XSetErrorHandler(&ctxErrorHandler);
|
XErrorHandler oldHandler = XSetErrorHandler(&ctxErrorHandler);
|
||||||
for (const std::vector<int>& attribs : ContextAttribList)
|
for (int i=0 ; i<std::extent<decltype(ContextAttribList)>::value ; ++i)
|
||||||
{
|
{
|
||||||
m_mainCtx = glXCreateContextAttribsARB(m_xDisp, m_fbconfig, m_glxCtx, True, attribs.data());
|
m_mainCtx = glXCreateContextAttribsARB(m_xDisp, m_fbconfig, m_glxCtx, True, ContextAttribList[i]);
|
||||||
if (m_mainCtx)
|
if (m_mainCtx)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -565,9 +570,9 @@ public:
|
||||||
{
|
{
|
||||||
s_glxError = false;
|
s_glxError = false;
|
||||||
XErrorHandler oldHandler = XSetErrorHandler(&ctxErrorHandler);
|
XErrorHandler oldHandler = XSetErrorHandler(&ctxErrorHandler);
|
||||||
for (const std::vector<int>& attribs : ContextAttribList)
|
for (int i=0 ; i<std::extent<decltype(ContextAttribList)>::value ; ++i)
|
||||||
{
|
{
|
||||||
m_loadCtx = glXCreateContextAttribsARB(m_xDisp, m_fbconfig, m_glxCtx, True, attribs.data());
|
m_loadCtx = glXCreateContextAttribsARB(m_xDisp, m_fbconfig, m_glxCtx, True, ContextAttribList[i]);
|
||||||
if (m_loadCtx)
|
if (m_loadCtx)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -589,8 +594,9 @@ public:
|
||||||
#if BOO_HAS_VULKAN
|
#if BOO_HAS_VULKAN
|
||||||
struct GraphicsContextXlibVulkan : GraphicsContextXlib
|
struct GraphicsContextXlibVulkan : GraphicsContextXlib
|
||||||
{
|
{
|
||||||
|
xcb_connection_t* m_xcbConn;
|
||||||
VulkanContext* m_ctx;
|
VulkanContext* m_ctx;
|
||||||
VkSurfaceKHR m_surface;
|
VkSurfaceKHR m_surface = VK_NULL_HANDLE;
|
||||||
VkFormat m_format;
|
VkFormat m_format;
|
||||||
|
|
||||||
GLXFBConfig m_fbconfig = 0;
|
GLXFBConfig m_fbconfig = 0;
|
||||||
|
@ -612,84 +618,11 @@ public:
|
||||||
IWindowCallback* m_callback;
|
IWindowCallback* m_callback;
|
||||||
|
|
||||||
GraphicsContextXlibVulkan(IWindow* parentWindow,
|
GraphicsContextXlibVulkan(IWindow* parentWindow,
|
||||||
Display* display, int defaultScreen,
|
Display* display, xcb_connection_t* xcbConn, int defaultScreen,
|
||||||
VulkanContext* ctx, uint32_t& visualIdOut)
|
VulkanContext* ctx, uint32_t& visualIdOut)
|
||||||
: GraphicsContextXlib(EGraphicsAPI::Vulkan, EPixelFormat::RGBA8, parentWindow, display),
|
: GraphicsContextXlib(EGraphicsAPI::Vulkan, EPixelFormat::RGBA8, parentWindow, display),
|
||||||
m_ctx(ctx)
|
m_xcbConn(xcbConn), m_ctx(ctx)
|
||||||
{
|
{
|
||||||
if (ctx->m_instance == VK_NULL_HANDLE)
|
|
||||||
ctx->initVulkan(APP->getProcessName().c_str());
|
|
||||||
|
|
||||||
VulkanContext::Window& m_windowCtx =
|
|
||||||
*ctx->m_windows.emplace(std::make_pair(parentWindow,
|
|
||||||
std::make_unique<VulkanContext::Window>())).first->second;
|
|
||||||
m_dataFactory = new class VulkanDataFactory(this, ctx);
|
|
||||||
|
|
||||||
VkXlibSurfaceCreateInfoKHR surfaceInfo = {};
|
|
||||||
surfaceInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
|
|
||||||
surfaceInfo.dpy = display;
|
|
||||||
surfaceInfo.window = parentWindow->getPlatformHandle();
|
|
||||||
ThrowIfFailed(vkCreateXlibSurfaceKHR(ctx->m_instance, &surfaceInfo, nullptr, &m_surface));
|
|
||||||
|
|
||||||
/* Iterate over each queue to learn whether it supports presenting */
|
|
||||||
VkBool32 *supportsPresent = (VkBool32*)malloc(ctx->m_queueCount * sizeof(VkBool32));
|
|
||||||
for (uint32_t i=0 ; i<ctx->m_queueCount ; ++i)
|
|
||||||
vkGetPhysicalDeviceSurfaceSupportKHR(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<ctx->m_queueCount; ++i)
|
|
||||||
{
|
|
||||||
if ((ctx->m_queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0)
|
|
||||||
{
|
|
||||||
if (supportsPresent[i] == VK_TRUE)
|
|
||||||
{
|
|
||||||
m_ctx->m_graphicsQueueFamilyIndex = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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::FatalError,
|
|
||||||
"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::FatalError, "subsequent surface doesn't support present");
|
|
||||||
}
|
|
||||||
free(supportsPresent);
|
|
||||||
|
|
||||||
|
|
||||||
/* Get the list of VkFormats that are supported */
|
|
||||||
uint32_t formatCount;
|
|
||||||
ThrowIfFailed(vkGetPhysicalDeviceSurfaceFormatsKHR(ctx->m_gpus[0], m_surface, &formatCount, nullptr));
|
|
||||||
VkSurfaceFormatKHR* surfFormats = (VkSurfaceFormatKHR*)malloc(formatCount * sizeof(VkSurfaceFormatKHR));
|
|
||||||
ThrowIfFailed(vkGetPhysicalDeviceSurfaceFormatsKHR(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;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Log.report(LogVisor::FatalError, "no surface formats available for Vulkan swapchain");
|
|
||||||
|
|
||||||
|
|
||||||
/* Query framebuffer configurations */
|
/* Query framebuffer configurations */
|
||||||
GLXFBConfig* fbConfigs = nullptr;
|
GLXFBConfig* fbConfigs = nullptr;
|
||||||
int numFBConfigs = 0;
|
int numFBConfigs = 0;
|
||||||
|
@ -746,12 +679,6 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vkGetPhysicalDeviceXlibPresentationSupportKHR(ctx->m_gpus[0], ctx->m_graphicsQueueFamilyIndex, display, m_visualid))
|
|
||||||
{
|
|
||||||
Log.report(LogVisor::FatalError, "unable to find vulkan-compatible pixel format");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
visualIdOut = m_visualid;
|
visualIdOut = m_visualid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -805,6 +732,85 @@ public:
|
||||||
Log.report(LogVisor::FatalError, "unable to resolve glXWaitVideoSyncSGI");
|
Log.report(LogVisor::FatalError, "unable to resolve glXWaitVideoSyncSGI");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_ctx->m_instance == VK_NULL_HANDLE)
|
||||||
|
m_ctx->initVulkan(APP->getUniqueName().c_str());
|
||||||
|
|
||||||
|
VulkanContext::Window& m_windowCtx =
|
||||||
|
*m_ctx->m_windows.emplace(std::make_pair(m_parentWindow,
|
||||||
|
std::make_unique<VulkanContext::Window>())).first->second;
|
||||||
|
|
||||||
|
VkXcbSurfaceCreateInfoKHR surfaceInfo = {};
|
||||||
|
surfaceInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
|
||||||
|
surfaceInfo.connection = m_xcbConn;
|
||||||
|
surfaceInfo.window = m_parentWindow->getPlatformHandle();
|
||||||
|
ThrowIfFailed(vkCreateXcbSurfaceKHR(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)
|
||||||
|
vkGetPhysicalDeviceSurfaceSupportKHR(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;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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::FatalError,
|
||||||
|
"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::FatalError, "subsequent surface doesn't support present");
|
||||||
|
}
|
||||||
|
free(supportsPresent);
|
||||||
|
|
||||||
|
if (!vkGetPhysicalDeviceXcbPresentationSupportKHR(m_ctx->m_gpus[0], m_ctx->m_graphicsQueueFamilyIndex, m_xcbConn, m_visualid))
|
||||||
|
{
|
||||||
|
Log.report(LogVisor::FatalError, "XCB visual doesn't support vulkan present");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the list of VkFormats that are supported */
|
||||||
|
uint32_t formatCount;
|
||||||
|
ThrowIfFailed(vkGetPhysicalDeviceSurfaceFormatsKHR(m_ctx->m_gpus[0], m_surface, &formatCount, nullptr));
|
||||||
|
VkSurfaceFormatKHR* surfFormats = (VkSurfaceFormatKHR*)malloc(formatCount * sizeof(VkSurfaceFormatKHR));
|
||||||
|
ThrowIfFailed(vkGetPhysicalDeviceSurfaceFormatsKHR(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;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Log.report(LogVisor::FatalError, "no surface formats available for Vulkan swapchain");
|
||||||
|
|
||||||
|
m_ctx->initSwapChain(m_windowCtx, m_surface, m_format);
|
||||||
|
|
||||||
/* Spawn vsync thread */
|
/* Spawn vsync thread */
|
||||||
m_vsyncRunning = true;
|
m_vsyncRunning = true;
|
||||||
std::mutex initmt;
|
std::mutex initmt;
|
||||||
|
@ -850,6 +856,7 @@ public:
|
||||||
});
|
});
|
||||||
initcv.wait(outerLk);
|
initcv.wait(outerLk);
|
||||||
|
|
||||||
|
m_dataFactory = new class VulkanDataFactory(this, m_ctx);
|
||||||
m_commandQueue = _NewVulkanCommandQueue(m_ctx, m_ctx->m_windows[m_parentWindow].get(), this);
|
m_commandQueue = _NewVulkanCommandQueue(m_ctx, m_ctx->m_windows[m_parentWindow].get(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -935,7 +942,8 @@ class WindowXlib : public IWindow
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WindowXlib(const std::string& title,
|
WindowXlib(const std::string& title,
|
||||||
Display* display, int defaultScreen, XIM xIM, XIMStyle bestInputStyle, XFontSet fontset,
|
Display* display, void* xcbConn,
|
||||||
|
int defaultScreen, XIM xIM, XIMStyle bestInputStyle, XFontSet fontset,
|
||||||
GLXContext lastCtx, bool useVulkan)
|
GLXContext lastCtx, bool useVulkan)
|
||||||
: m_xDisp(display), m_callback(nullptr),
|
: m_xDisp(display), m_callback(nullptr),
|
||||||
m_bestStyle(bestInputStyle)
|
m_bestStyle(bestInputStyle)
|
||||||
|
@ -945,7 +953,7 @@ public:
|
||||||
|
|
||||||
#if BOO_HAS_VULKAN
|
#if BOO_HAS_VULKAN
|
||||||
if (useVulkan)
|
if (useVulkan)
|
||||||
m_gfxCtx.reset(new GraphicsContextXlibVulkan(this, display, defaultScreen,
|
m_gfxCtx.reset(new GraphicsContextXlibVulkan(this, display, (xcb_connection_t*)xcbConn, defaultScreen,
|
||||||
&g_VulkanContext, m_visualId));
|
&g_VulkanContext, m_visualId));
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@ -1941,11 +1949,12 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
IWindow* _WindowXlibNew(const std::string& title,
|
IWindow* _WindowXlibNew(const std::string& title,
|
||||||
Display* display, int defaultScreen, XIM xIM, XIMStyle bestInputStyle, XFontSet fontset,
|
Display* display, void* xcbConn,
|
||||||
|
int defaultScreen, XIM xIM, XIMStyle bestInputStyle, XFontSet fontset,
|
||||||
GLXContext lastCtx, bool useVulkan)
|
GLXContext lastCtx, bool useVulkan)
|
||||||
{
|
{
|
||||||
XLockDisplay(display);
|
XLockDisplay(display);
|
||||||
IWindow* ret = new WindowXlib(title, display, defaultScreen, xIM, bestInputStyle, fontset, lastCtx, useVulkan);
|
IWindow* ret = new WindowXlib(title, display, xcbConn, defaultScreen, xIM, bestInputStyle, fontset, lastCtx, useVulkan);
|
||||||
XUnlockDisplay(display);
|
XUnlockDisplay(display);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue