Add initial macOS support.

This commit is contained in:
squidbus 2024-07-09 02:18:34 -07:00 committed by TheTurtle
parent 36d528743a
commit 66fa29059c
29 changed files with 523 additions and 26 deletions

View file

@ -3,6 +3,7 @@
#include "common/assert.h"
#include "common/debug.h"
#include "common/polyfill_thread.h"
#include "common/thread.h"
#include "video_core/amdgpu/liverpool.h"
#include "video_core/amdgpu/pm4_cmds.h"
@ -31,7 +32,7 @@ void Liverpool::Process(std::stop_token stoken) {
while (!stoken.stop_requested()) {
{
std::unique_lock lk{submit_mutex};
submit_cv.wait(lk, stoken, [this] { return num_submits != 0; });
Common::CondvarWait(submit_cv, lk, stoken, [this] { return num_submits != 0; });
}
if (stoken.stop_requested()) {
break;

View file

@ -12,6 +12,7 @@
#include <queue>
#include "common/assert.h"
#include "common/bit_field.h"
#include "common/polyfill_thread.h"
#include "common/types.h"
#include "video_core/amdgpu/pixel_format.h"
#include "video_core/amdgpu/resource.h"

View file

@ -460,7 +460,7 @@ struct PM4CmdWriteData {
template <typename T>
void Address(T addr) {
addr64 = reinterpret_cast<u64>(addr);
addr64 = static_cast<u64>(addr);
}
template <typename T>

View file

@ -292,10 +292,14 @@ bool Instance::CreateDevice() {
const bool has_host_time_domain =
std::find(time_domains.cbegin(), time_domains.cend(),
vk::TimeDomainEXT::eQueryPerformanceCounter) != time_domains.cend();
#else
#elif __linux__
const bool has_host_time_domain =
std::find(time_domains.cbegin(), time_domains.cend(),
vk::TimeDomainEXT::eClockMonotonicRaw) != time_domains.cend();
#else
// Tracy limitation means only Windows and Linux can use host time domain.
// See https://github.com/shadps4-emu/tracy/blob/c6d779d78508514102fbe1b8eb28bda10d95bb2a/public/tracy/TracyVulkan.hpp#L384-L389
const bool has_host_time_domain = false;
#endif
if (has_host_time_domain) {
static constexpr std::string_view context_name{"vk_rasterizer"};

View file

@ -16,6 +16,12 @@ class WindowSDL;
VK_DEFINE_HANDLE(VmaAllocator)
#ifdef __APPLE__
#define VULKAN_LIBRARY_NAME "libMoltenVK.dylib"
#else
#define VULKAN_LIBRARY_NAME
#endif
namespace Vulkan {
class Instance {
@ -206,7 +212,7 @@ private:
void CollectToolingInfo();
private:
vk::DynamicLoader dl;
vk::DynamicLoader dl{VULKAN_LIBRARY_NAME};
vk::UniqueInstance instance;
vk::PhysicalDevice physical_device;
vk::UniqueDevice device;

View file

@ -99,6 +99,17 @@ vk::SurfaceKHR CreateSurface(vk::Instance instance, const Frontend::WindowSDL& e
UNREACHABLE();
}
}
#elif defined(VK_USE_PLATFORM_METAL_EXT)
if (window_info.type == Frontend::WindowSystemType::Metal) {
const vk::MetalSurfaceCreateInfoEXT macos_ci = {
.pLayer = static_cast<const CAMetalLayer*>(window_info.render_surface),
};
if (instance.createMetalSurfaceEXT(&macos_ci, nullptr, &surface) != vk::Result::eSuccess) {
LOG_CRITICAL(Render_Vulkan, "Failed to initialize MacOS surface");
UNREACHABLE();
}
}
#endif
if (!surface) {
@ -135,6 +146,10 @@ std::vector<const char*> GetInstanceExtensions(Frontend::WindowSystemType window
case Frontend::WindowSystemType::Wayland:
extensions.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
break;
#elif defined(VK_USE_PLATFORM_METAL_EXT)
case Frontend::WindowSystemType::Metal:
extensions.push_back(VK_EXT_METAL_SURFACE_EXTENSION_NAME);
break;
#endif
default:
LOG_ERROR(Render_Vulkan, "Presentation not supported on this platform");

View file

@ -36,7 +36,14 @@ static TextureCache* g_texture_cache = nullptr;
void GuestFaultSignalHandler(int sig, siginfo_t* info, void* raw_context) {
ucontext_t* ctx = reinterpret_cast<ucontext_t*>(raw_context);
const VAddr address = reinterpret_cast<VAddr>(info->si_addr);
if (ctx->uc_mcontext.gregs[REG_ERR] & 0x2) {
#ifdef __APPLE__
const u32 err = ctx->uc_mcontext->__es.__err;
#else
const greg_t err = ctx->uc_mcontext.gregs[REG_ERR];
#endif
if (err & 0x2) {
g_texture_cache->OnCpuWrite(address);
} else {
// Read not supported!
@ -69,9 +76,16 @@ TextureCache::TextureCache(const Vulkan::Instance& instance_, Vulkan::Scheduler&
tile_manager{instance, scheduler} {
#ifndef _WIN64
#ifdef __APPLE__
// Read-only memory write results in SIGBUS on Apple.
static constexpr int SignalType = SIGBUS;
#else
static constexpr int SignalType = SIGSEGV;
#endif
sigset_t signal_mask;
sigemptyset(&signal_mask);
sigaddset(&signal_mask, SIGSEGV);
sigaddset(&signal_mask, SignalType);
using HandlerType = decltype(sigaction::sa_sigaction);
@ -79,7 +93,7 @@ TextureCache::TextureCache(const Vulkan::Instance& instance_, Vulkan::Scheduler&
guest_access_fault.sa_flags = SA_SIGINFO | SA_ONSTACK;
guest_access_fault.sa_sigaction = &GuestFaultSignalHandler;
guest_access_fault.sa_mask = signal_mask;
sigaction(SIGSEGV, &guest_access_fault, nullptr);
sigaction(SignalType, &guest_access_fault, nullptr);
#else
veh_handle = AddVectoredExceptionHandler(0, GuestFaultSignalHandler);
ASSERT_MSG(veh_handle, "Failed to register an exception handler");