diff options
| author | lizzie <lizzie@eden-emu.dev> | 2025-10-22 04:53:40 +0200 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2025-10-22 04:53:40 +0200 |
| commit | 87cacbeed49facf18355c55cc93d0a2a0142be09 (patch) | |
| tree | 320ab5933dd97b5f54f5fcc2cb4ed775587c9cbf /src | |
| parent | 992bae4e2a14ca2547c09637b7dc6fc5f73b353a (diff) | |
[compat] HaikuOS port (#2805)
Still had the issues with libusb, but that should get solved with the other PRs anyways
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2805
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/host_memory.cpp | 31 | ||||
| -rw-r--r-- | src/common/settings.cpp | 2 | ||||
| -rw-r--r-- | src/common/settings.h | 2 | ||||
| -rw-r--r-- | src/common/thread.cpp | 62 | ||||
| -rw-r--r-- | src/common/virtual_buffer.cpp | 16 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_32.cpp | 2 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_64.cpp | 2 | ||||
| -rw-r--r-- | src/core/frontend/emu_window.h | 6 | ||||
| -rw-r--r-- | src/core/internal_network/network.cpp | 6 | ||||
| -rw-r--r-- | src/core/internal_network/network.h | 5 | ||||
| -rw-r--r-- | src/core/internal_network/sockets.h | 14 | ||||
| -rw-r--r-- | src/core/tools/renderdoc.cpp | 2 | ||||
| -rw-r--r-- | src/dynarmic/src/dynarmic/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | src/qt_common/qt_common.cpp | 5 | ||||
| -rw-r--r-- | src/qt_common/util/game.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/host_shaders/CMakeLists.txt | 10 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_device.cpp | 33 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan.h | 5 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_instance.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_surface.cpp | 20 |
20 files changed, 126 insertions, 106 deletions
diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp index 3838c12903..6e47fa286d 100644 --- a/src/common/host_memory.cpp +++ b/src/common/host_memory.cpp @@ -12,7 +12,7 @@ #include <windows.h> #include "common/dynamic_library.h" -#elif defined(__linux__) || defined(__FreeBSD__) || defined(__sun__) || defined(__APPLE__) // ^^^ Windows ^^^ vvv POSIX vvv +#else // ^^^ Windows ^^^ vvv POSIX vvv #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -394,7 +394,7 @@ private: std::unordered_map<size_t, size_t> placeholder_host_pointers; ///< Placeholder backing offset }; -#elif defined(__linux__) || defined(__FreeBSD__) || defined(__sun__) || defined(__APPLE__) // ^^^ Windows ^^^ vvv POSIX vvv +#else // ^^^ Windows ^^^ vvv POSIX vvv #ifdef ARCHITECTURE_arm64 @@ -679,32 +679,7 @@ private: FreeRegionManager free_manager{}; }; -#else // ^^^ POSIX ^^^ vvv Generic vvv - -class HostMemory::Impl { -public: - explicit Impl([[maybe_unused]] size_t backing_size, [[maybe_unused]] size_t virtual_size) { - // This is just a place holder. - ASSERT_MSG(false, "Please implement fastmem in a proper way on your platform."); - } - - void Map(size_t virtual_offset, size_t host_offset, size_t length, MemoryPermission perm) {} - - void Unmap(size_t virtual_offset, size_t length) {} - - void Protect(size_t virtual_offset, size_t length, bool read, bool write, bool execute) {} - - bool ClearBackingRegion(size_t physical_offset, size_t length) { - return false; - } - - void EnableDirectMappedAddress() {} - - u8* backing_base{nullptr}; - u8* virtual_base{nullptr}; -}; - -#endif // ^^^ Generic ^^^ +#endif // ^^^ POSIX ^^^ HostMemory::HostMemory(size_t backing_size_, size_t virtual_size_) : backing_size(backing_size_), virtual_size(virtual_size_) { diff --git a/src/common/settings.cpp b/src/common/settings.cpp index e817acc36e..0022d242c3 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -169,7 +169,7 @@ bool IsFastmemEnabled() { if (values.cpu_accuracy.GetValue() == CpuAccuracy::Unsafe) { return bool(values.cpuopt_unsafe_host_mmu); } -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) || defined(__HAIKU__) return false; #else return true; diff --git a/src/common/settings.h b/src/common/settings.h index 4eea9cf265..1dc3bdca20 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -296,7 +296,7 @@ struct Values { Category::CpuDebug}; SwitchableSetting<bool> cpuopt_unsafe_host_mmu{linkage, -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) || defined(__HAIKU__) false, #else true, diff --git a/src/common/thread.cpp b/src/common/thread.cpp index 2de7465a22..3f0fb48c25 100644 --- a/src/common/thread.cpp +++ b/src/common/thread.cpp @@ -11,6 +11,8 @@ #include "common/thread.h" #ifdef __APPLE__ #include <mach/mach.h> +#elif defined(__HAIKU__) +#include <kernel/OS.h> #elif defined(_WIN32) #include <windows.h> #include "common/string_util.h" @@ -31,43 +33,38 @@ namespace Common { -#ifdef _WIN32 - void SetCurrentThreadPriority(ThreadPriority new_priority) { - auto handle = GetCurrentThread(); - int windows_priority = 0; - switch (new_priority) { - case ThreadPriority::Low: - windows_priority = THREAD_PRIORITY_BELOW_NORMAL; - break; - case ThreadPriority::Normal: - windows_priority = THREAD_PRIORITY_NORMAL; - break; - case ThreadPriority::High: - windows_priority = THREAD_PRIORITY_ABOVE_NORMAL; - break; - case ThreadPriority::VeryHigh: - windows_priority = THREAD_PRIORITY_HIGHEST; - break; - case ThreadPriority::Critical: - windows_priority = THREAD_PRIORITY_TIME_CRITICAL; - break; - default: - windows_priority = THREAD_PRIORITY_NORMAL; - break; - } - SetThreadPriority(handle, windows_priority); -} - +#ifdef _WIN32 + int windows_priority = [&]() { + switch (new_priority) { + case ThreadPriority::Low: return THREAD_PRIORITY_BELOW_NORMAL; + case ThreadPriority::Normal: return THREAD_PRIORITY_NORMAL; + case ThreadPriority::High: return THREAD_PRIORITY_ABOVE_NORMAL; + case ThreadPriority::VeryHigh: return THREAD_PRIORITY_HIGHEST; + case ThreadPriority::Critical: return THREAD_PRIORITY_TIME_CRITICAL; + default: return THREAD_PRIORITY_NORMAL; + } + }(); + SetThreadPriority(GetCurrentThread(), windows_priority); +#elif defined(__HAIKU__) + // TODO: We have priorities for 3D rendering applications - may help lavapipe? + int priority = [&]() { + switch (new_priority) { + case ThreadPriority::Low: return B_LOW_PRIORITY; + case ThreadPriority::Normal: return B_NORMAL_PRIORITY; + case ThreadPriority::High: return B_DISPLAY_PRIORITY; + case ThreadPriority::VeryHigh: return B_URGENT_DISPLAY_PRIORITY; + case ThreadPriority::Critical: return B_URGENT_PRIORITY; + default: return B_NORMAL_PRIORITY; + } + }(); + set_thread_priority(find_thread(NULL), priority); #else - -void SetCurrentThreadPriority(ThreadPriority new_priority) { pthread_t this_thread = pthread_self(); - const auto scheduling_type = SCHED_OTHER; s32 max_prio = sched_get_priority_max(scheduling_type); s32 min_prio = sched_get_priority_min(scheduling_type); - u32 level = (std::max)(static_cast<u32>(new_priority) + 1, 4U); + u32 level = (std::max)(u32(new_priority) + 1, 4U); struct sched_param params; if (max_prio > min_prio) { @@ -77,9 +74,8 @@ void SetCurrentThreadPriority(ThreadPriority new_priority) { } pthread_setschedparam(this_thread, scheduling_type, ¶ms); -} - #endif +} #ifdef _MSC_VER diff --git a/src/common/virtual_buffer.cpp b/src/common/virtual_buffer.cpp index dea6de99f0..55ddfc243a 100644 --- a/src/common/virtual_buffer.cpp +++ b/src/common/virtual_buffer.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -14,24 +17,19 @@ namespace Common { void* AllocateMemoryPages(std::size_t size) noexcept { #ifdef _WIN32 - void* base{VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_READWRITE)}; + void* base = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_READWRITE); #else - void* base{mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0)}; - - if (base == MAP_FAILED) { + void* base = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); + if (base == MAP_FAILED) base = nullptr; - } #endif - ASSERT(base); - return base; } void FreeMemoryPages(void* base, [[maybe_unused]] std::size_t size) noexcept { - if (!base) { + if (!base) return; - } #ifdef _WIN32 ASSERT(VirtualFree(base, 0, MEM_RELEASE)); #else diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 3c72ab2396..1618f2131b 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -295,7 +295,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ArmDynarmic32::MakeJit(Common::PageTable* pa // Curated optimizations case Settings::CpuAccuracy::Auto: config.unsafe_optimizations = true; -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) || defined(__HAIKU__) config.fastmem_pointer = std::nullopt; config.fastmem_exclusive_access = false; #endif diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 707d51d2a2..62f7de1414 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -354,7 +354,7 @@ std::shared_ptr<Dynarmic::A64::Jit> ArmDynarmic64::MakeJit(Common::PageTable* pa // Safe optimisations case Settings::CpuAccuracy::Auto: config.unsafe_optimizations = true; -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) || defined(__HAIKU__) config.fastmem_pointer = std::nullopt; config.fastmem_exclusive_access = false; #endif diff --git a/src/core/frontend/emu_window.h b/src/core/frontend/emu_window.h index c7b48a58d7..ee7a7693b2 100644 --- a/src/core/frontend/emu_window.h +++ b/src/core/frontend/emu_window.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2014 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -13,7 +16,7 @@ namespace Core::Frontend { class GraphicsContext; -/// Information for the Graphics Backends signifying what type of screen pointer is in +/// @brief Information for the Graphics Backends signifying what type of screen pointer is in /// WindowInformation enum class WindowSystemType { Headless, @@ -22,6 +25,7 @@ enum class WindowSystemType { Wayland, Cocoa, Android, + Xcb, }; /** diff --git a/src/core/internal_network/network.cpp b/src/core/internal_network/network.cpp index b21d8a7a16..35f2157761 100644 --- a/src/core/internal_network/network.cpp +++ b/src/core/internal_network/network.cpp @@ -15,7 +15,7 @@ #ifdef _WIN32 #include <winsock2.h> #include <ws2tcpip.h> -#elif defined(__unix__) || defined(__APPLE__) +#else #include <arpa/inet.h> #include <errno.h> #include <fcntl.h> @@ -24,8 +24,6 @@ #include <poll.h> #include <sys/socket.h> #include <unistd.h> -#else -#error "Unimplemented platform" #endif #include "common/assert.h" @@ -165,7 +163,7 @@ Errno TranslateNativeError(int e, CallType call_type = CallType::Other) { } } -#elif defined(__unix__) || defined(__APPLE__) // ^ _WIN32 v __unix__ +#else // ^^^ Windows vvv POSIX using SOCKET = int; using WSAPOLLFD = pollfd; diff --git a/src/core/internal_network/network.h b/src/core/internal_network/network.h index 5a3343efd9..5df28911f8 100644 --- a/src/core/internal_network/network.h +++ b/src/core/internal_network/network.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -104,7 +107,7 @@ constexpr IPv4Address TranslateIPv4(in_addr addr) { auto& bytes = addr.S_un.S_un_b; return IPv4Address{bytes.s_b1, bytes.s_b2, bytes.s_b3, bytes.s_b4}; } -#elif defined(__unix__) || defined(__APPLE__) +#else constexpr IPv4Address TranslateIPv4(in_addr addr) { const u32 bytes = addr.s_addr; return IPv4Address{static_cast<u8>(bytes), static_cast<u8>(bytes >> 8), diff --git a/src/core/internal_network/sockets.h b/src/core/internal_network/sockets.h index 27468709fd..0b751b6622 100644 --- a/src/core/internal_network/sockets.h +++ b/src/core/internal_network/sockets.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -8,15 +11,6 @@ #include <span> #include <utility> -#if defined(_WIN32) -// windows -#elif defined(__unix__) || defined(__APPLE__) -// unix -#else -// haiku -#error "Platform not implemented" -#endif - #include "common/common_types.h" #include "core/internal_network/network.h" @@ -28,7 +22,7 @@ struct ProxyPacket; class SocketBase { public: -#if defined(__unix__) || defined(__APPLE__) +#ifndef _WIN32 using SOCKET = int; static constexpr SOCKET INVALID_SOCKET = -1; static constexpr SOCKET SOCKET_ERROR = -1; diff --git a/src/core/tools/renderdoc.cpp b/src/core/tools/renderdoc.cpp index d3a47e1d96..5fab291fe5 100644 --- a/src/core/tools/renderdoc.cpp +++ b/src/core/tools/renderdoc.cpp @@ -28,6 +28,8 @@ RenderdocAPI::RenderdocAPI() { ASSERT(ret == 1); } } +#elif defined(__HAIKU__) + // no rtld on haiku #else #ifdef ANDROID static constexpr const char RENDERDOC_LIB[] = "libVkLayer_GLES_RenderDoc.so"; diff --git a/src/dynarmic/src/dynarmic/CMakeLists.txt b/src/dynarmic/src/dynarmic/CMakeLists.txt index 763ff4b34b..f21000044e 100644 --- a/src/dynarmic/src/dynarmic/CMakeLists.txt +++ b/src/dynarmic/src/dynarmic/CMakeLists.txt @@ -345,7 +345,8 @@ elseif (APPLE) backend/exception_handler_macos_mig.c ) endif() -elseif (UNIX) +elseif (UNIX AND NOT PLATFORM_HAIKU) + # Haiku lacks <ucontext.h> if (CMAKE_SYSTEM_NAME STREQUAL "Linux") target_link_libraries(dynarmic PRIVATE rt) endif() diff --git a/src/qt_common/qt_common.cpp b/src/qt_common/qt_common.cpp index 6be241c740..1fa3df98cf 100644 --- a/src/qt_common/qt_common.cpp +++ b/src/qt_common/qt_common.cpp @@ -33,8 +33,7 @@ std::unique_ptr<Core::System> system = nullptr; std::shared_ptr<FileSys::RealVfsFilesystem> vfs = nullptr; std::unique_ptr<FileSys::ManualContentProvider> provider = nullptr; -Core::Frontend::WindowSystemType GetWindowSystemType() -{ +Core::Frontend::WindowSystemType GetWindowSystemType() { // Determine WSI type based on Qt platform. QString platform_name = QGuiApplication::platformName(); if (platform_name == QStringLiteral("windows")) @@ -49,6 +48,8 @@ Core::Frontend::WindowSystemType GetWindowSystemType() return Core::Frontend::WindowSystemType::Cocoa; else if (platform_name == QStringLiteral("android")) return Core::Frontend::WindowSystemType::Android; + else if (platform_name == QStringLiteral("haiku")) + return Core::Frontend::WindowSystemType::Xcb; LOG_CRITICAL(Frontend, "Unknown Qt platform {}!", platform_name.toStdString()); return Core::Frontend::WindowSystemType::Windows; diff --git a/src/qt_common/util/game.cpp b/src/qt_common/util/game.cpp index 04434c714f..e5018d24cb 100644 --- a/src/qt_common/util/game.cpp +++ b/src/qt_common/util/game.cpp @@ -149,7 +149,7 @@ bool MakeShortcutIcoPath(const u64 program_id, #if defined(_WIN32) out_icon_path = Common::FS::GetEdenPath(Common::FS::EdenPath::IconsDir); ico_extension = "ico"; -#elif defined(__linux__) || defined(__FreeBSD__) +#elif !defined(__ANDROID__) // Any *nix but android out_icon_path = Common::FS::GetDataDirectory("XDG_DATA_HOME") / "icons/hicolor/256x256"; #endif // Create icons directory if it doesn't exist diff --git a/src/video_core/host_shaders/CMakeLists.txt b/src/video_core/host_shaders/CMakeLists.txt index 9f7b9edd5a..fef9a5b16e 100644 --- a/src/video_core/host_shaders/CMakeLists.txt +++ b/src/video_core/host_shaders/CMakeLists.txt @@ -86,7 +86,15 @@ set(SHADER_FILES dynamic_resolution_scale.comp ) -find_program(GLSLANGVALIDATOR "glslangValidator") +if (PLATFORM_HAIKU) + # glslangValidator WILL crash, glslang will not - why? Who the fuck knows + #/boot/home/glslang/build/StandAlone/glslangValidator + set(GLSLANGVALIDATOR "glslang") +else() + # Normal sane platform who doesn't have a CRASHING glslangValidator + find_program(GLSLANGVALIDATOR "glslangValidator") +endif() + if ("${GLSLANGVALIDATOR}" STREQUAL "GLSLANGVALIDATOR-NOTFOUND") message(FATAL_ERROR "Required program `glslangValidator` not found.") endif() diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp index f3d884f0eb..8b10747b9a 100644 --- a/src/video_core/renderer_opengl/gl_device.cpp +++ b/src/video_core/renderer_opengl/gl_device.cpp @@ -50,20 +50,24 @@ bool TestProgram(const GLchar* glsl) { return link_status == GL_TRUE; } -std::vector<std::string_view> GetExtensions() { +/// @brief Query OpenGL extensions +/// DO NOT use string_view, the driver can immediately free up the extension name and such +/// do NOT under ANY circumstances use string_view, make a copy, it's required +std::vector<std::string> GetExtensions() { GLint num_extensions; glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions); - std::vector<std::string_view> extensions; - extensions.reserve(num_extensions); + std::vector<std::string> extensions; for (GLint index = 0; index < num_extensions; ++index) { - extensions.push_back( - reinterpret_cast<const char*>(glGetStringi(GL_EXTENSIONS, static_cast<GLuint>(index)))); + auto const* p = reinterpret_cast<const char*>(glGetStringi(GL_EXTENSIONS, GLuint(index))); + if (p != nullptr) // Fuck you? - sincerely, buggy mesa drivers + extensions.push_back(std::string{p}); } return extensions; } -bool HasExtension(std::span<const std::string_view> extensions, std::string_view extension) { - return std::ranges::find(extensions, extension) != extensions.end(); +/// @brief Find extension in set of extensions (string) +bool HasExtension(std::span<const std::string> extensions, std::string_view extension) { + return std::ranges::find(extensions, std::string{extension}) != extensions.end(); } std::array<u32, Shader::MaxStageTypes> BuildMaxUniformBuffers() noexcept { @@ -148,7 +152,7 @@ static bool HasSlowSoftwareAstc(std::string_view vendor_name, std::string_view r return false; } -[[nodiscard]] bool IsDebugToolAttached(std::span<const std::string_view> extensions) { +[[nodiscard]] bool IsDebugToolAttached(std::span<const std::string> extensions) { const bool nsight = std::getenv("NVTX_INJECTION64_PATH") || std::getenv("NSIGHT_LAUNCHED"); return nsight || HasExtension(extensions, "GL_EXT_debug_tool") || Settings::values.renderer_debug.GetValue(); @@ -160,10 +164,17 @@ Device::Device(Core::Frontend::EmuWindow& emu_window) { LOG_ERROR(Render_OpenGL, "OpenGL 4.6 is not available"); throw std::runtime_error{"Insufficient version"}; } +#ifdef __HAIKU__ + if (glad_glCreateProgramPipelines == nullptr) { + LOG_ERROR(Render_OpenGL, "You must compile Mesa +22 manually or use a different libGL.so (GLES is not supported)"); + throw std::runtime_error{"Outdated mesa"}; + } +#endif + vendor_name = reinterpret_cast<const char*>(glGetString(GL_VENDOR)); - const std::string_view version = reinterpret_cast<const char*>(glGetString(GL_VERSION)); - const std::string_view renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER)); - const std::vector extensions = GetExtensions(); + const std::string version = reinterpret_cast<const char*>(glGetString(GL_VERSION)); + const std::string renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER)); + const std::vector<std::string> extensions = GetExtensions(); const bool is_nvidia = vendor_name == "NVIDIA Corporation"; const bool is_amd = vendor_name == "ATI Technologies Inc."; diff --git a/src/video_core/vulkan_common/vulkan.h b/src/video_core/vulkan_common/vulkan.h index 62aa132915..13f679ff54 100644 --- a/src/video_core/vulkan_common/vulkan.h +++ b/src/video_core/vulkan_common/vulkan.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -10,6 +13,8 @@ #define VK_USE_PLATFORM_METAL_EXT #elif defined(__ANDROID__) #define VK_USE_PLATFORM_ANDROID_KHR +#elif defined(__HAIKU__) +#define VK_USE_PLATFORM_XCB_KHR #else #define VK_USE_PLATFORM_XLIB_KHR #define VK_USE_PLATFORM_WAYLAND_KHR diff --git a/src/video_core/vulkan_common/vulkan_instance.cpp b/src/video_core/vulkan_common/vulkan_instance.cpp index 1948e0030a..d9404933cd 100644 --- a/src/video_core/vulkan_common/vulkan_instance.cpp +++ b/src/video_core/vulkan_common/vulkan_instance.cpp @@ -59,6 +59,10 @@ namespace { case Core::Frontend::WindowSystemType::Android: extensions.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); break; +#elif defined(__HAIKU__) + case Core::Frontend::WindowSystemType::Xcb: + extensions.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); + break; #else case Core::Frontend::WindowSystemType::X11: extensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); diff --git a/src/video_core/vulkan_common/vulkan_surface.cpp b/src/video_core/vulkan_common/vulkan_surface.cpp index e45f8e43fb..f1b56cc0a8 100644 --- a/src/video_core/vulkan_common/vulkan_surface.cpp +++ b/src/video_core/vulkan_common/vulkan_surface.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -54,6 +57,23 @@ vk::SurfaceKHR CreateSurface( throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED); } } +#elif defined(__HAIKU__) + if (window_info.type == Core::Frontend::WindowSystemType::Xcb) { + const VkXcbSurfaceCreateInfoKHR xcb_ci{ + .sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR, + .pNext = nullptr, + .flags = 0, + .connection = static_cast<xcb_connection_t*>(window_info.display_connection), + .window = xcb_window_t(uintptr_t(window_info.render_surface)) + }; + const auto vkCreateXcbSurfaceKHR = reinterpret_cast<PFN_vkCreateXcbSurfaceKHR>( + dld.vkGetInstanceProcAddr(*instance, "vkCreateXcbSurfaceKHR")); + if (!vkCreateXcbSurfaceKHR || + vkCreateXcbSurfaceKHR(*instance, &xcb_ci, nullptr, &unsafe_surface) != VK_SUCCESS) { + LOG_ERROR(Render_Vulkan, "Failed to initialize Xcb surface"); + throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED); + } + } #else if (window_info.type == Core::Frontend::WindowSystemType::X11) { const VkXlibSurfaceCreateInfoKHR xlib_ci{ |
