Create XCB Connection mechanism for WSISurface implementation for Linux (#2400)
- Add new Linux Trait to determine which display driver client API to use (only xcb supported for now) - Add support for xcb connections (initial) for Linux/Vulkan - Fix minor assertion caused by wrong use of sizeof - Fix casing issue in a couple of material files (Linux is case sensitive)
This commit is contained in:
@@ -9,8 +9,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
|
||||
#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
#include <xcb/xcb.h>
|
||||
#endif // LY_COMPILE_DEFINITIONS
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
class LinuxLifecycleEvents
|
||||
@@ -25,4 +30,31 @@ namespace AzFramework
|
||||
|
||||
using Bus = AZ::EBus<LinuxLifecycleEvents>;
|
||||
};
|
||||
|
||||
#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
class LinuxXcbConnectionManager
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(LinuxXcbConnectionManager, "{649951316-3626-4C9D-9DCA-2E7ABF84C0A9}");
|
||||
|
||||
virtual ~LinuxXcbConnectionManager() = default;
|
||||
|
||||
virtual xcb_connection_t* GetXcbConnection() const = 0;
|
||||
};
|
||||
|
||||
class LinuxXcbConnectionManagerBusTraits
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// EBusTraits overrides
|
||||
static constexpr AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
|
||||
static constexpr AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
};
|
||||
|
||||
using LinuxXcbConnectionManagerBus = AZ::EBus<LinuxXcbConnectionManager, LinuxXcbConnectionManagerBusTraits>;
|
||||
using LinuxXcbConnectionManagerInterface = AZ::Interface<LinuxXcbConnectionManager>;
|
||||
|
||||
#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
} // namespace AzFramework
|
||||
|
||||
+47
@@ -12,6 +12,32 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
namespace AzFramework
|
||||
{
|
||||
#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
class LinuxXcbConnectionManagerImpl
|
||||
: public LinuxXcbConnectionManagerBus::Handler
|
||||
{
|
||||
public:
|
||||
LinuxXcbConnectionManagerImpl()
|
||||
{
|
||||
m_xcbConnection = xcb_connect(nullptr, nullptr);
|
||||
AZ_Error("ApplicationLinux", m_xcbConnection != nullptr, "Unable to connect to X11 Server.");
|
||||
LinuxXcbConnectionManagerBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
~LinuxXcbConnectionManagerImpl()
|
||||
{
|
||||
LinuxXcbConnectionManagerBus::Handler::BusDisconnect();
|
||||
xcb_disconnect(m_xcbConnection);
|
||||
}
|
||||
xcb_connection_t* GetXcbConnection() const override
|
||||
{
|
||||
return m_xcbConnection;
|
||||
}
|
||||
private:
|
||||
xcb_connection_t* m_xcbConnection = nullptr;
|
||||
};
|
||||
#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
class ApplicationLinux
|
||||
: public Application::Implementation
|
||||
@@ -27,6 +53,12 @@ namespace AzFramework
|
||||
// Application::Implementation
|
||||
void PumpSystemEventLoopOnce() override;
|
||||
void PumpSystemEventLoopUntilEmpty() override;
|
||||
private:
|
||||
|
||||
#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
AZStd::unique_ptr<LinuxXcbConnectionManager> m_xcbConnectionManager;
|
||||
#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -39,11 +71,26 @@ namespace AzFramework
|
||||
ApplicationLinux::ApplicationLinux()
|
||||
{
|
||||
LinuxLifecycleEvents::Bus::Handler::BusConnect();
|
||||
|
||||
#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
m_xcbConnectionManager = AZStd::make_unique<LinuxXcbConnectionManagerImpl>();
|
||||
if (LinuxXcbConnectionManagerInterface::Get() == nullptr)
|
||||
{
|
||||
LinuxXcbConnectionManagerInterface::Register(m_xcbConnectionManager.get());
|
||||
}
|
||||
#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
ApplicationLinux::~ApplicationLinux()
|
||||
{
|
||||
#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
if (LinuxXcbConnectionManagerInterface::Get() == m_xcbConnectionManager.get())
|
||||
{
|
||||
LinuxXcbConnectionManagerInterface::Unregister(m_xcbConnectionManager.get());
|
||||
}
|
||||
m_xcbConnectionManager.reset();
|
||||
#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
LinuxLifecycleEvents::Bus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
|
||||
@@ -5,3 +5,30 @@
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#
|
||||
#
|
||||
|
||||
# Based on the linux window manager trait, perform the appropriate additional build configurations
|
||||
# Only 'xcb', 'wayland', and 'xlib' are recognized
|
||||
if (${PAL_TRAIT_LINUX_WINDOW_MANAGER} STREQUAL "xcb")
|
||||
|
||||
find_library(XCB_LIBRARY xcb)
|
||||
|
||||
set(LY_BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
${XCB_LIBRARY}
|
||||
)
|
||||
|
||||
set(LY_COMPILE_DEFINITIONS PUBLIC PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB)
|
||||
|
||||
elseif(PAL_TRAIT_LINUX_WINDOW_MANAGER STREQUAL "wayland")
|
||||
|
||||
set(LY_COMPILE_DEFINITIONS PUBLIC PAL_TRAIT_LINUX_WINDOW_MANAGER_WAYLAND)
|
||||
|
||||
elseif(PAL_TRAIT_LINUX_WINDOW_MANAGER STREQUAL "xlib")
|
||||
|
||||
set(LY_COMPILE_DEFINITIONS PUBLIC PAL_TRAIT_LINUX_WINDOW_MANAGER_XLIB)
|
||||
|
||||
else()
|
||||
|
||||
message(FATAL_ERROR, "Linux Window Manager ${PAL_TRAIT_LINUX_WINDOW_MANAGER} is not recognized")
|
||||
|
||||
endif()
|
||||
|
||||
@@ -6,6 +6,18 @@
|
||||
#
|
||||
#
|
||||
|
||||
set(GLAD_VULKAN_COMPILE_DEFINITIONS
|
||||
VK_USE_PLATFORM_XCB_KHR
|
||||
)
|
||||
if (${PAL_TRAIT_LINUX_WINDOW_MANAGER} STREQUAL "xcb")
|
||||
set(GLAD_VULKAN_COMPILE_DEFINITIONS
|
||||
VK_USE_PLATFORM_XCB_KHR
|
||||
)
|
||||
elseif(PAL_TRAIT_LINUX_WINDOW_MANAGER STREQUAL "wayland")
|
||||
set(GLAD_VULKAN_COMPILE_DEFINITIONS
|
||||
VK_USE_PLATFORM_WAYLAND_KHR
|
||||
)
|
||||
elseif(PAL_TRAIT_LINUX_WINDOW_MANAGER STREQUAL "xlib")
|
||||
set(GLAD_VULKAN_COMPILE_DEFINITIONS
|
||||
VK_USE_PLATFORM_XLIB_KHR
|
||||
)
|
||||
else()
|
||||
message(FATAL_ERROR, "Linux Window Manager ${PAL_TRAIT_LINUX_WINDOW_MANAGER} is not recognized")
|
||||
endif()
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#include <AzFramework/API/ApplicationAPI_Platform.h>
|
||||
#include <RHI/Conversion.h>
|
||||
#include <RHI/Instance.h>
|
||||
#include <RHI/WSISurface.h>
|
||||
@@ -17,15 +18,36 @@ namespace AZ
|
||||
{
|
||||
Instance& instance = Instance::GetInstance();
|
||||
|
||||
#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
|
||||
xcb_connection_t* xcb_connection = nullptr;
|
||||
if (auto xcbConnectionManager = AzFramework::LinuxXcbConnectionManagerInterface::Get();
|
||||
xcbConnectionManager != nullptr)
|
||||
{
|
||||
xcb_connection = xcbConnectionManager->GetXcbConnection();
|
||||
}
|
||||
AZ_Error("AtomVulkan_RHI", xcb_connection!=nullptr, "Unable to get XCB Connection");
|
||||
|
||||
VkXcbSurfaceCreateInfoKHR createInfo{};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
|
||||
createInfo.pNext = nullptr;
|
||||
createInfo.flags = 0;
|
||||
createInfo.connection = xcb_connection;
|
||||
createInfo.window = static_cast<xcb_window_t>(m_descriptor.m_windowHandle.GetIndex());
|
||||
const VkResult result = vkCreateXcbSurfaceKHR(instance.GetNativeInstance(), &createInfo, nullptr, &m_nativeSurface);
|
||||
AssertSuccess(result);
|
||||
|
||||
return ConvertResult(result);
|
||||
#elif PAL_TRAIT_LINUX_WINDOW_MANAGER_WAYLAND
|
||||
#error "Linux Window Manager Wayland not supported."
|
||||
return RHI::ResultCode::Unimplemented;
|
||||
#elif PAL_TRAIT_LINUX_WINDOW_MANAGER_XLIB
|
||||
#error "Linux Window Manager XLIB not supported."
|
||||
return RHI::ResultCode::Unimplemented;
|
||||
#else
|
||||
#error "Linux Window Manager not recognized."
|
||||
return RHI::ResultCode::Unimplemented;
|
||||
#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@
|
||||
},
|
||||
"normal": {
|
||||
"flipY": true,
|
||||
"textureMap": "Objects/Lucy/Lucy_normal.png"
|
||||
"textureMap": "Objects/Lucy/Lucy_Normal.png"
|
||||
},
|
||||
"subsurfaceScattering": {
|
||||
"enableSubsurfaceScattering": true,
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@
|
||||
},
|
||||
"normal": {
|
||||
"flipY": true,
|
||||
"textureMap": "Objects/Lucy/Lucy_normal.png"
|
||||
"textureMap": "Objects/Lucy/Lucy_Normal.png"
|
||||
},
|
||||
"subsurfaceScattering": {
|
||||
"enableSubsurfaceScattering": true,
|
||||
|
||||
@@ -37,3 +37,7 @@ set(LY_ASSET_DEPLOY_ASSET_TYPE "pc" CACHE STRING "Set the asset type for deploym
|
||||
|
||||
# Set the python cmd tool
|
||||
ly_set(LY_PYTHON_CMD ${CMAKE_CURRENT_SOURCE_DIR}/python/python.sh)
|
||||
|
||||
# Set the default window manager that applications should be using on Linux
|
||||
# Note: Only ("xcb", "wayland", or "xlib" should be considered)
|
||||
set(PAL_TRAIT_LINUX_WINDOW_MANAGER "xcb" CACHE STRING "Sets the Window Manager type to use when configuring Linux (xcb, wayland, or xlib)")
|
||||
|
||||
Reference in New Issue
Block a user