mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-03 21:41:26 +12:00
Basic support for Vulkan Portability on OSX
This commit is contained in:
parent
eaf20295ac
commit
c452b43ebc
8 changed files with 90 additions and 29 deletions
|
@ -73,7 +73,11 @@ using ulong = unsigned long;
|
||||||
using ullong = unsigned long long;
|
using ullong = unsigned long long;
|
||||||
using llong = long long;
|
using llong = long long;
|
||||||
|
|
||||||
|
#if __APPLE__
|
||||||
|
using uptr = std::uint64_t;
|
||||||
|
#else
|
||||||
using uptr = std::uintptr_t;
|
using uptr = std::uintptr_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
using u8 = std::uint8_t;
|
using u8 = std::uint8_t;
|
||||||
using u16 = std::uint16_t;
|
using u16 = std::uint16_t;
|
||||||
|
|
|
@ -256,10 +256,11 @@ if(USE_LIBEVDEV)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
option(USE_VULKAN "Vulkan render backend" ON)
|
option(USE_VULKAN "Vulkan render backend" ON)
|
||||||
if(NOT APPLE AND USE_VULKAN)
|
if(USE_VULKAN)
|
||||||
find_package(Vulkan)
|
find_package(Vulkan)
|
||||||
if(VULKAN_FOUND)
|
if(VULKAN_FOUND)
|
||||||
add_definitions(-DHAVE_VULKAN)
|
add_definitions(-DHAVE_VULKAN)
|
||||||
|
include_directories("${Vulkan_INCLUDE_DIRS}")
|
||||||
else()
|
else()
|
||||||
message("WARNING! USE_VULKAN was enabled, but libvulkan was not found. RPCS3 will be compiled without Vulkan support.")
|
message("WARNING! USE_VULKAN was enabled, but libvulkan was not found. RPCS3 will be compiled without Vulkan support.")
|
||||||
endif()
|
endif()
|
||||||
|
@ -388,7 +389,7 @@ if(NOT MSVC)
|
||||||
target_link_libraries(rpcs3 Threads::Threads)
|
target_link_libraries(rpcs3 Threads::Threads)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(UNIX)
|
if(NOT APPLE AND UNIX)
|
||||||
find_package(X11 REQUIRED)
|
find_package(X11 REQUIRED)
|
||||||
target_include_directories(rpcs3 PUBLIC ${X11_INCLUDE_DIR})
|
target_include_directories(rpcs3 PUBLIC ${X11_INCLUDE_DIR})
|
||||||
target_link_libraries(rpcs3 ${X11_LIBRARIES})
|
target_link_libraries(rpcs3 ${X11_LIBRARIES})
|
||||||
|
@ -438,7 +439,7 @@ else()
|
||||||
if(CMAKE_SYSTEM MATCHES "Linux")
|
if(CMAKE_SYSTEM MATCHES "Linux")
|
||||||
target_link_libraries(rpcs3 "${RPCS3_SRC_DIR}/../3rdparty/discord-rpc/lib/libdiscord-rpc-linux.a")
|
target_link_libraries(rpcs3 "${RPCS3_SRC_DIR}/../3rdparty/discord-rpc/lib/libdiscord-rpc-linux.a")
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
target_link_libraries(rpcs3 "${RPCS3_SRC_DIR}/../3rdparty/discord-rpc/lib/libdiscord-rpc-mac.a")
|
target_link_libraries(rpcs3 "${RPCS3_SRC_DIR}/../3rdparty/discord-rpc/lib/libdiscord-rpc-mac.a" objc "-framework Foundation" "-framework CoreServices")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
// nothing
|
||||||
#else
|
#else
|
||||||
// Cannot include Xlib.h before Qt5
|
// Cannot include Xlib.h before Qt5
|
||||||
// and we don't need all of Xlib anyway
|
// and we don't need all of Xlib anyway
|
||||||
|
@ -49,6 +51,8 @@ using draw_context_t = void*;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
using display_handle_t = HWND;
|
using display_handle_t = HWND;
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
using display_handle_t = void*; // NSView
|
||||||
#else
|
#else
|
||||||
using display_handle_t = std::variant<
|
using display_handle_t = std::variant<
|
||||||
std::pair<Display*, Window>
|
std::pair<Display*, Window>
|
||||||
|
|
|
@ -516,7 +516,7 @@ VKGSRender::VKGSRender() : GSRender()
|
||||||
|
|
||||||
display_handle_t display = m_frame->handle();
|
display_handle_t display = m_frame->handle();
|
||||||
|
|
||||||
#ifndef _WIN32
|
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||||
display.match([this](std::pair<Display*, Window> p) { m_display_handle = p.first; XFlush(m_display_handle); }, [](auto _) {});
|
display.match([this](std::pair<Display*, Window> p) { m_display_handle = p.first; XFlush(m_display_handle); }, [](auto _) {});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -776,7 +776,7 @@ VKGSRender::~VKGSRender()
|
||||||
m_swapchain->destroy();
|
m_swapchain->destroy();
|
||||||
m_thread_context.close();
|
m_thread_context.close();
|
||||||
|
|
||||||
#if !defined(_WIN32) && defined(HAVE_VULKAN)
|
#if !defined(_WIN32) && !defined(__APPLE__) && defined(HAVE_VULKAN)
|
||||||
if (m_display_handle)
|
if (m_display_handle)
|
||||||
XCloseDisplay(m_display_handle);
|
XCloseDisplay(m_display_handle);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -375,7 +375,7 @@ private:
|
||||||
//Vertex layout
|
//Vertex layout
|
||||||
rsx::vertex_input_layout m_vertex_layout;
|
rsx::vertex_input_layout m_vertex_layout;
|
||||||
|
|
||||||
#if !defined(_WIN32) && defined(HAVE_VULKAN)
|
#if !defined(_WIN32) && !defined(__APPLE__) && defined(HAVE_VULKAN)
|
||||||
Display *m_display_handle = nullptr;
|
Display *m_display_handle = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,10 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "Utilities/variant.hpp"
|
#include "Utilities/variant.hpp"
|
||||||
#include "Emu/RSX/GSRender.h"
|
#include "Emu/RSX/GSRender.h"
|
||||||
#include "Emu/System.h"
|
#include "Emu/System.h"
|
||||||
|
@ -21,10 +25,6 @@
|
||||||
|
|
||||||
#include "3rdparty/GPUOpen/include/vk_mem_alloc.h"
|
#include "3rdparty/GPUOpen/include/vk_mem_alloc.h"
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
#include <X11/Xutil.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#define VK_DISABLE_COMPONENT_SWIZZLE 1
|
#define VK_DISABLE_COMPONENT_SWIZZLE 1
|
||||||
#else
|
#else
|
||||||
|
@ -1502,6 +1502,52 @@ public:
|
||||||
src.first = false;
|
src.first = false;
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
|
||||||
|
class swapchain_MacOS : public native_swapchain_base
|
||||||
|
{
|
||||||
|
void* nsView = NULL;
|
||||||
|
|
||||||
|
public:
|
||||||
|
swapchain_MacOS(physical_device &gpu, uint32_t _present_queue, uint32_t _graphics_queue, VkFormat format = VK_FORMAT_B8G8R8A8_UNORM)
|
||||||
|
: native_swapchain_base(gpu, _present_queue, _graphics_queue, format)
|
||||||
|
{}
|
||||||
|
|
||||||
|
~swapchain_MacOS(){}
|
||||||
|
|
||||||
|
bool init() override
|
||||||
|
{
|
||||||
|
//TODO: get from `nsView`
|
||||||
|
m_width = 0;
|
||||||
|
m_height = 0;
|
||||||
|
|
||||||
|
if (m_width == 0 || m_height == 0)
|
||||||
|
{
|
||||||
|
LOG_ERROR(RSX, "Invalid window dimensions %d x %d", m_width, m_height);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
init_swapchain_images(dev, 3);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void create(display_handle_t& window_handle) override
|
||||||
|
{
|
||||||
|
nsView = window_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy(bool full=true) override
|
||||||
|
{
|
||||||
|
swapchain_images.clear();
|
||||||
|
|
||||||
|
if (full)
|
||||||
|
dev.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
VkResult present(u32 index) override
|
||||||
|
{
|
||||||
|
fmt::throw_exception("Native macOS swapchain is not implemented yet!");
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
class swapchain_X11 : public native_swapchain_base
|
class swapchain_X11 : public native_swapchain_base
|
||||||
|
@ -1991,15 +2037,20 @@ public:
|
||||||
std::vector<const char *> extensions;
|
std::vector<const char *> extensions;
|
||||||
std::vector<const char *> layers;
|
std::vector<const char *> layers;
|
||||||
|
|
||||||
#ifndef __APPLE__
|
|
||||||
if (!fast)
|
if (!fast)
|
||||||
{
|
{
|
||||||
|
supported_extensions support;
|
||||||
|
|
||||||
extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
|
extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
|
||||||
|
if (support.is_supported(VK_EXT_DEBUG_REPORT_EXTENSION_NAME))
|
||||||
|
{
|
||||||
extensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
|
extensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
|
||||||
|
}
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
|
extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
extensions.push_back(VK_MVK_MACOS_SURFACE_EXTENSION_NAME);
|
||||||
#else
|
#else
|
||||||
supported_extensions support;
|
|
||||||
bool found_surface_ext = false;
|
bool found_surface_ext = false;
|
||||||
if (support.is_supported(VK_KHR_XLIB_SURFACE_EXTENSION_NAME))
|
if (support.is_supported(VK_KHR_XLIB_SURFACE_EXTENSION_NAME))
|
||||||
{
|
{
|
||||||
|
@ -2018,11 +2069,10 @@ public:
|
||||||
LOG_ERROR(RSX, "Could not find a supported Vulkan surface extension");
|
LOG_ERROR(RSX, "Could not find a supported Vulkan surface extension");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif //(WIN32)
|
#endif //(WIN32, __APPLE__)
|
||||||
if (g_cfg.video.debug_output)
|
if (g_cfg.video.debug_output)
|
||||||
layers.push_back("VK_LAYER_LUNARG_standard_validation");
|
layers.push_back("VK_LAYER_LUNARG_standard_validation");
|
||||||
}
|
}
|
||||||
#endif //(!APPLE)
|
|
||||||
|
|
||||||
VkInstanceCreateInfo instance_info = {};
|
VkInstanceCreateInfo instance_info = {};
|
||||||
instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||||
|
@ -2095,6 +2145,7 @@ public:
|
||||||
|
|
||||||
swapchain_base* createSwapChain(display_handle_t window_handle, vk::physical_device &dev)
|
swapchain_base* createSwapChain(display_handle_t window_handle, vk::physical_device &dev)
|
||||||
{
|
{
|
||||||
|
VkSurfaceKHR surface;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
using swapchain_NATIVE = swapchain_WIN32;
|
using swapchain_NATIVE = swapchain_WIN32;
|
||||||
HINSTANCE hInstance = NULL;
|
HINSTANCE hInstance = NULL;
|
||||||
|
@ -2104,16 +2155,17 @@ public:
|
||||||
createInfo.hinstance = hInstance;
|
createInfo.hinstance = hInstance;
|
||||||
createInfo.hwnd = window_handle;
|
createInfo.hwnd = window_handle;
|
||||||
|
|
||||||
VkSurfaceKHR surface;
|
|
||||||
CHECK_RESULT(vkCreateWin32SurfaceKHR(m_instance, &createInfo, NULL, &surface));
|
CHECK_RESULT(vkCreateWin32SurfaceKHR(m_instance, &createInfo, NULL, &surface));
|
||||||
|
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
using swapchain_NATIVE = swapchain_X11;
|
using swapchain_NATIVE = swapchain_MacOS;
|
||||||
VkSurfaceKHR surface;
|
VkMacOSSurfaceCreateInfoMVK createInfo = {};
|
||||||
|
createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
|
||||||
|
createInfo.pView = window_handle;
|
||||||
|
|
||||||
|
CHECK_RESULT(vkCreateMacOSSurfaceMVK(m_instance, &createInfo, NULL, &surface));
|
||||||
#else
|
#else
|
||||||
using swapchain_NATIVE = swapchain_X11;
|
using swapchain_NATIVE = swapchain_X11;
|
||||||
VkSurfaceKHR surface;
|
|
||||||
|
|
||||||
window_handle.match(
|
window_handle.match(
|
||||||
[&](std::pair<Display*, Window> p)
|
[&](std::pair<Display*, Window> p)
|
||||||
|
@ -2141,7 +2193,6 @@ public:
|
||||||
std::vector<VkBool32> supportsPresent(device_queues, VK_FALSE);
|
std::vector<VkBool32> supportsPresent(device_queues, VK_FALSE);
|
||||||
bool present_possible = false;
|
bool present_possible = false;
|
||||||
|
|
||||||
#ifndef __APPLE__
|
|
||||||
for (u32 index = 0; index < device_queues; index++)
|
for (u32 index = 0; index < device_queues; index++)
|
||||||
{
|
{
|
||||||
vkGetPhysicalDeviceSurfaceSupportKHR(dev, index, surface, &supportsPresent[index]);
|
vkGetPhysicalDeviceSurfaceSupportKHR(dev, index, surface, &supportsPresent[index]);
|
||||||
|
@ -2160,7 +2211,6 @@ public:
|
||||||
{
|
{
|
||||||
LOG_ERROR(RSX, "It is not possible for the currently selected GPU to present to the window (Likely caused by NVIDIA driver running the current display)");
|
LOG_ERROR(RSX, "It is not possible for the currently selected GPU to present to the window (Likely caused by NVIDIA driver running the current display)");
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Search for a graphics and a present queue in the array of queue
|
// Search for a graphics and a present queue in the array of queue
|
||||||
// families, try to find one that supports both
|
// families, try to find one that supports both
|
||||||
|
@ -2219,10 +2269,6 @@ public:
|
||||||
return swapchain;
|
return swapchain;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
fmt::throw_exception("Unreachable" HERE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Get the list of VkFormat's that are supported:
|
// Get the list of VkFormat's that are supported:
|
||||||
uint32_t formatCount;
|
uint32_t formatCount;
|
||||||
CHECK_RESULT(vkGetPhysicalDeviceSurfaceFormatsKHR(dev, surface, &formatCount, nullptr));
|
CHECK_RESULT(vkGetPhysicalDeviceSurfaceFormatsKHR(dev, surface, &formatCount, nullptr));
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define VK_USE_PLATFORM_WIN32_KHR
|
#define VK_USE_PLATFORM_WIN32_KHR
|
||||||
#elif !defined __APPLE__
|
#elif defined(__APPLE__)
|
||||||
|
#define VK_USE_PLATFORM_MACOS_MVK
|
||||||
|
#else
|
||||||
#define VK_USE_PLATFORM_XLIB_KHR
|
#define VK_USE_PLATFORM_XLIB_KHR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
//nothing
|
||||||
#else
|
#else
|
||||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
|
@ -200,6 +202,8 @@ display_handle_t gs_frame::handle() const
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
return (HWND) this->winId();
|
return (HWND) this->winId();
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
return (void*) this->winId(); //NSView
|
||||||
#else
|
#else
|
||||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||||
QPlatformNativeInterface *native = QGuiApplication::platformNativeInterface();
|
QPlatformNativeInterface *native = QGuiApplication::platformNativeInterface();
|
||||||
|
@ -238,7 +242,7 @@ void gs_frame::delete_context(draw_context_t ctx)
|
||||||
|
|
||||||
int gs_frame::client_width()
|
int gs_frame::client_width()
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) || defined(__APPLE__)
|
||||||
return size().width();
|
return size().width();
|
||||||
#else
|
#else
|
||||||
return size().width() * devicePixelRatio();
|
return size().width() * devicePixelRatio();
|
||||||
|
@ -247,7 +251,7 @@ int gs_frame::client_width()
|
||||||
|
|
||||||
int gs_frame::client_height()
|
int gs_frame::client_height()
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) || defined(__APPLE__)
|
||||||
return size().height();
|
return size().height();
|
||||||
#else
|
#else
|
||||||
return size().height() * devicePixelRatio();
|
return size().height() * devicePixelRatio();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue