Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,10 @@
if(MINGW)
target_link_libraries(ffmpeg INTERFACE bcrypt ole32 user32 ws2_32)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_link_options(ffmpeg INTERFACE LINKER:--exclude-libs,ALL)
# --exclude-libs is an ELF linker option; Mach-O has no equivalent.

Check failure on line 102 in CMakeLists.txt

View workflow job for this annotation

GitHub Actions / conventions

comment

Comments are only for technical debt, so they need a change to docs/dev/TechnicalDebt.md in the same pull request; #endif and namespace ends are always allowed
if(NOT APPLE)
target_link_options(ffmpeg INTERFACE LINKER:--exclude-libs,ALL)
endif()
endif()

set(FT_DISABLE_ZLIB ON CACHE BOOL "" FORCE)
Expand Down
1 change: 1 addition & 0 deletions core/Decoder/Jpeg/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ function(add_jpeg_decoder target runtimeTarget)
-DCMAKE_C_VISIBILITY_PRESET=hidden
-DCMAKE_VISIBILITY_INLINES_HIDDEN=ON
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}
-DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER}
Expand Down
11 changes: 9 additions & 2 deletions core/libs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@
endforeach()
endif()

# dyld has no $ORIGIN; Mach-O libraries find each other through @loader_path.

Check failure on line 50 in core/libs/CMakeLists.txt

View workflow job for this annotation

GitHub Actions / conventions

comment

Comments are only for technical debt, so they need a change to docs/dev/TechnicalDebt.md in the same pull request; #endif and namespace ends are always allowed
if(APPLE)
set(APS5_LIBRARY_RPATH "@loader_path")
else()
set(APS5_LIBRARY_RPATH "$ORIGIN")
endif()

set(LIBC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/prx/libc)
add_library(libc SHARED EXCLUDE_FROM_ALL)
set(LIBS_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
Expand All @@ -68,7 +75,7 @@
LIBRARY_OUTPUT_DIRECTORY ${UNPATCHED_DIR}
ARCHIVE_OUTPUT_DIRECTORY ${IMPLIB_DIR}
BUILD_WITH_INSTALL_RPATH ON
INSTALL_RPATH "$ORIGIN"
INSTALL_RPATH "${APS5_LIBRARY_RPATH}"
)

set(LIBC_UNPATCHED ${UNPATCHED_DIR}/libc.prx)
Expand Down Expand Up @@ -123,7 +130,7 @@
LIBRARY_OUTPUT_DIRECTORY ${UNPATCHED_DIR}
ARCHIVE_OUTPUT_DIRECTORY ${IMPLIB_DIR}
BUILD_WITH_INSTALL_RPATH ON
INSTALL_RPATH "$ORIGIN"
INSTALL_RPATH "${APS5_LIBRARY_RPATH}"
)

set(UNPATCHED_FILE ${UNPATCHED_DIR}/${LIB_NAME}.prx)
Expand Down
11 changes: 10 additions & 1 deletion core/libs/nid/src/MachONidPatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,16 @@
std::tolower(static_cast<unsigned char>(name[0])) == 's' &&
std::tolower(static_cast<unsigned char>(name[1])) == 'c' &&
std::tolower(static_cast<unsigned char>(name[2])) == 'e';
return hasNidPostfix || hasScePrefix;
// The compiler's stack-protector symbols have no NID postfix and no sce

Check failure on line 351 in core/libs/nid/src/MachONidPatcher.cpp

View workflow job for this annotation

GitHub Actions / conventions

comment

Comments are only for technical debt, so they need a change to docs/dev/TechnicalDebt.md in the same pull request; #endif and namespace ends are always allowed
// prefix, but the guest imports them by NID like anything else, so the

Check failure on line 352 in core/libs/nid/src/MachONidPatcher.cpp

View workflow job for this annotation

GitHub Actions / conventions

comment

Comments are only for technical debt, so they need a change to docs/dev/TechnicalDebt.md in the same pull request; #endif and namespace ends are always allowed
// reference has to follow the rename or the dependent library will look for

Check failure on line 353 in core/libs/nid/src/MachONidPatcher.cpp

View workflow job for this annotation

GitHub Actions / conventions

comment

Comments are only for technical debt, so they need a change to docs/dev/TechnicalDebt.md in the same pull request; #endif and namespace ends are always allowed
// a name the provider no longer exports.

Check failure on line 354 in core/libs/nid/src/MachONidPatcher.cpp

View workflow job for this annotation

GitHub Actions / conventions

comment

Comments are only for technical debt, so they need a change to docs/dev/TechnicalDebt.md in the same pull request; #endif and namespace ends are always allowed
static const char* const AbiImports[]{
"__stack_chk_guard", "__stack_chk_guard_local", "__stack_chk_fail",
"__stack_chk_fail_local", "__pthread_key_create"};
const bool isAbiImport = std::any_of(std::begin(AbiImports), std::end(AbiImports),
[&](const char* candidate) { return name == candidate; });
return hasNidPostfix || hasScePrefix || isAbiImport;
}

std::vector<bool> DylibOrdinalsArePrx(const std::vector<std::uint8_t>& binary, const Image& image) {
Expand Down
1 change: 1 addition & 0 deletions core/libs/prx/libSceAgc/Shader/src/ShaderUtils.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <string>
#include <stdexcept>
#include "prx/libSceAgc/Shader/include/ShaderUtils.hpp"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define CORE_LIBS_PRX_LIBSCEAGCDRIVER_EXECUTION_INCLUDE_DRIVER_DEVICEACCESS_HPP

#include "prx/libSceAgcDriver/Execution/include/VulkanDevice.hpp"
#include "prx/libc/include/AtomicSharedPtr.hpp"
#include <atomic>
#include <condition_variable>
#include <cstddef>
Expand All @@ -21,7 +22,7 @@ class DevicePointer {
bool operator==(std::nullptr_t) const;

private:
std::atomic<std::shared_ptr<VulkanDevice>> pointer;
AtomicSharedPtr<VulkanDevice> pointer;
};

class DeviceUseGate {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "prx/libSceAgcDriver/Execution/include/Driver/Shaders/ShaderRegistry.hpp"
#include "prx/libSceAgcDriver/Execution/include/Recipe.hpp"
#include "prx/libc/include/AtomicSharedPtr.hpp"
#include <algorithm>
#include <array>
#include <atomic>
Expand Down Expand Up @@ -31,7 +32,7 @@ struct DispatchVariant {

std::shared_ptr<const ShaderSnapshot> shader;

std::atomic<std::shared_ptr<const Recipe>> recipe;
AtomicSharedPtr<const Recipe> recipe;

static constexpr std::uint32_t NoFlatBinding = std::numeric_limits<std::uint32_t>::max();
std::vector<std::uint32_t> dataPositions;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "prx/libSceAgcDriver/Execution/include/Driver/Dispatch/DispatchCache.hpp"
#include "prx/libSceAgcDriver/Execution/include/VulkanDevice.hpp"
#include "prx/libc/include/AtomicSharedPtr.hpp"
#include <array>
#include <atomic>
#include <chrono>
Expand Down Expand Up @@ -54,7 +55,7 @@ struct DrawEntry {

std::vector<std::vector<std::shared_ptr<DispatchVariant>>> stages;

std::atomic<std::shared_ptr<const std::vector<DrawRecipeRecord>>> recipes;
AtomicSharedPtr<const std::vector<DrawRecipeRecord>> recipes;
std::uint64_t touched = 0;
std::list<std::uint64_t>::iterator order;
};
Expand Down
16 changes: 13 additions & 3 deletions core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@
}

std::uint8_t load(std::uintptr_t address) const {
return std::atomic_ref<const std::uint8_t>(pages[(address - base) / PageBytes]).load(std::memory_order_relaxed);
return std::atomic_ref<std::uint8_t>(pages[(address - base) / PageBytes]).load(std::memory_order_relaxed);
}

void store(std::uintptr_t address, std::uint8_t value) {
Expand All @@ -416,11 +416,11 @@
const auto stop = std::min<std::uintptr_t>((std::min(limit, base + size) - base + PageBytes - 1) / PageBytes, size / PageBytes);
const std::uint64_t wide = 0x0101010101010101ull * value;
while (index < stop) {
if (index % 8 == 0 && index + 8 <= stop && std::atomic_ref<const std::uint64_t>(*reinterpret_cast<const std::uint64_t*>(pages + index)).load(std::memory_order_relaxed) == wide) {
if (index % 8 == 0 && index + 8 <= stop && std::atomic_ref<std::uint64_t>(*reinterpret_cast<std::uint64_t*>(pages + index)).load(std::memory_order_relaxed) == wide) {
index += 8;
continue;
}
if (std::atomic_ref<const std::uint8_t>(pages[index]).load(std::memory_order_relaxed) != value) break;
if (std::atomic_ref<std::uint8_t>(pages[index]).load(std::memory_order_relaxed) != value) break;
++index;
}
return std::min(limit, base + index * PageBytes);
Expand Down Expand Up @@ -659,6 +659,15 @@
GetCurrentThreadStackLimits(&lowLimit, &highLimit);
low = static_cast<std::uintptr_t>(lowLimit);
high = static_cast<std::uintptr_t>(highLimit);
#else
#if defined(__APPLE__)
// Darwin has no pthread_getattr_np; the two _np accessors cover it.

Check failure on line 664 in core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp

View workflow job for this annotation

GitHub Actions / conventions

comment

Comments are only for technical debt, so they need a change to docs/dev/TechnicalDebt.md in the same pull request; #endif and namespace ends are always allowed
void* const base = const_cast<void*>(pthread_get_stackaddr_np(pthread_self()));
const std::size_t size = static_cast<std::size_t>(pthread_get_stacksize_np(pthread_self()));
if (base != nullptr && size != 0) {
low = reinterpret_cast<std::uintptr_t>(base);
high = low + size;
}
#else
pthread_attr_t attributes;
if (pthread_getattr_np(pthread_self(), &attributes) != 0) return;
Expand All @@ -669,6 +678,7 @@
high = low + size;
}
pthread_attr_destroy(&attributes);
#endif
#endif
}
};
Expand Down
32 changes: 32 additions & 0 deletions core/libs/prx/libSceAgcDriver/Execution/src/ThreadPriority.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <algorithm>
#include <cstdint>
#include <cstdio>
#include <cerrno>
#include <cstdlib>
#include <cstring>
#include <mutex>
Expand All @@ -12,6 +13,13 @@

#ifdef _WIN32
#include <windows.h>
#elif defined(__APPLE__)
#include <dlfcn.h>
#include <pthread.h>
#include <sched.h>
#include <sys/qos.h>
#include <sys/resource.h>
#include <unistd.h>
#else
#include <dlfcn.h>
#include <sched.h>
Expand Down Expand Up @@ -212,6 +220,9 @@
return ok;
}

#if !defined(__APPLE__)
// Darwin has no rtkit, no RLIMIT_RTTIME and no SCHED_RESET_ON_FORK; Raise below

Check failure on line 224 in core/libs/prx/libSceAgcDriver/Execution/src/ThreadPriority.cpp

View workflow job for this annotation

GitHub Actions / conventions

comment

Comments are only for technical debt, so they need a change to docs/dev/TechnicalDebt.md in the same pull request; #endif and namespace ends are always allowed
// uses the QoS and nice interfaces instead.

Check failure on line 225 in core/libs/prx/libSceAgcDriver/Execution/src/ThreadPriority.cpp

View workflow job for this annotation

GitHub Actions / conventions

comment

Comments are only for technical debt, so they need a change to docs/dev/TechnicalDebt.md in the same pull request; #endif and namespace ends are always allowed
bool PrepareRealtime(std::uint32_t priority, const char* role, std::string& failure) {
std::int64_t maxPriority = 0;
std::int64_t maxRttime = 0;
Expand Down Expand Up @@ -249,7 +260,27 @@
return true;
}

#endif

void Raise(const char* role) {
#if defined(__APPLE__)
// Darwin offers no rtkit. QoS classes cover the raised-priority case, and

Check failure on line 267 in core/libs/prx/libSceAgcDriver/Execution/src/ThreadPriority.cpp

View workflow job for this annotation

GitHub Actions / conventions

comment

Comments are only for technical debt, so they need a change to docs/dev/TechnicalDebt.md in the same pull request; #endif and namespace ends are always allowed
// a negative nice value is the closest match for "high".
const bool realtime = RequestedMode() == ThreadPriorityMode::Realtime;
if (realtime) {
pthread_set_qos_class_self_np(QOS_CLASS_USER_INTERACTIVE, 0);
} else {
const std::int32_t nice = static_cast<std::int32_t>(
std::max(-20, std::min(19, EnvInt("APS5_THREAD_NICE", -10))));
if (setpriority(PRIO_PROCESS, 0, nice) != 0 && errno != EPERM) {
throw std::runtime_error(
std::string("APS5_THREAD_PRIORITY: ") + role + " setpriority failed (error "
+ std::to_string(errno) + ")");
}
}
LogOnce(role, realtime ? "user-interactive QoS" : "nice");
return;
#else
const auto tid = static_cast<std::uint64_t>(syscall(SYS_gettid));
std::string failure;
if (RequestedMode() == ThreadPriorityMode::Realtime) {
Expand All @@ -266,6 +297,7 @@
throw std::runtime_error(std::string("APS5_THREAD_PRIORITY=high: ") + role + " nice " + std::to_string(nice) + " refused: " + failure);
}
LogOnce(role, "nice " + std::to_string(nice) + " via rtkit");
#endif
}

#else
Expand Down
17 changes: 12 additions & 5 deletions core/libs/prx/libSceAgcDriver/Graphics/src/GuestBufferMemory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@
#include "prx/libc/include/CpuTopology.hpp"
#include "prx/libc/include/GuestArena.hpp"
#include "prx/libc/include/GuestWriteWatch.hpp"
#include "prx/libc/include/AtomicSharedPtr.hpp"
#ifdef _WIN32
#include <windows.h>
#else
#include <fcntl.h>
#if defined(__linux__)
#include <linux/udmabuf.h>
#include <sys/ioctl.h>
#endif
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
Expand Down Expand Up @@ -114,7 +117,7 @@ struct GuestBufferMemory::AddressSpace {
namespace {

struct AddressSpaceCache {
std::atomic<std::shared_ptr<const GuestBufferMemory::AddressSpace>> current;
AtomicSharedPtr<const GuestBufferMemory::AddressSpace> current;
std::atomic<std::uint64_t> serials{0};
// Set by the waiter's drop, cleared by the next publish: the rebuild's reason.
std::atomic<bool> droppedByWaiter{false};
Expand Down Expand Up @@ -262,7 +265,7 @@ const char* createHostPointerImport(const Context& context, HostImport& entry, V
return bindImport(context, entry, VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT, &import, pointer.memoryTypeBits, allocated, failure);
}

#ifndef _WIN32
#if defined(__linux__) && !defined(_WIN32)
int udmabufDevice() {
static const int device = [] {
const int result = open("/dev/udmabuf", O_RDWR | O_CLOEXEC);
Expand Down Expand Up @@ -304,7 +307,10 @@ const char* createDmaBufImport(const Context& context, HostImport& entry, int fi
}
#endif

#ifndef _WIN32
// dma-buf import is a Linux facility: Darwin has no /dev/udmabuf and no
// VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, so titles fall back to the
// host-pointer copy path that createImport already tries first.
#if defined(__linux__)
constexpr std::uint64_t ImportChunkBytes = std::uint64_t{64} << 20u;

struct ImportChunk {
Expand Down Expand Up @@ -451,7 +457,7 @@ const char* createChunkedDmaBufImport(const Context& context, HostImport& entry,

const char* createImport(const Context& context, HostImport& entry, VkResult& failure) {
const char* step = createHostPointerImport(context, entry, failure);
#ifndef _WIN32
#if defined(__linux__)
int file = -1;
std::uint64_t offset = 0;
if (step != nullptr && context.dmaBufImport && GuestArena::GuestArenaSharedBacking_nid_postfix(static_cast<std::uintptr_t>(entry.base), static_cast<std::size_t>(entry.bytes), &file, &offset)) {
Expand Down Expand Up @@ -1865,7 +1871,8 @@ ImportProbe ProbeImportWriteProtection(const Context& context) {

ImportProbe ProbeDmaBufImportWriteProtection(const Context& context) {
ImportProbe probe;
#ifdef _WIN32
#if defined(_WIN32) || defined(__APPLE__)
// The write watch backs dma-buf imports, which Darwin does not have.
static_cast<void>(context);
probe.failure = "the Linux write watch";
return probe;
Expand Down
3 changes: 2 additions & 1 deletion core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "prx/libSceAgcDriver/Execution/include/Pm4Opcodes.hpp"
#include "prx/libc/include/CpuTopology.hpp"
#include "prx/libc/include/GuestAllocations.hpp"
#include "prx/libc/include/AtomicSharedPtr.hpp"
#include <algorithm>
#include <array>
#include <atomic>
Expand Down Expand Up @@ -633,7 +634,7 @@ using WriteRanges = Recorder::WriteRanges;
// work. A range leaves the snapshot only after its batch's completions (CPU write-backs) ran, so a
// reader that sees no overlap either precedes the note (the queues are unordered then, as on the
// GPU) or follows the write-back.
std::atomic<std::shared_ptr<const WriteRanges>> pendingWrites;
AtomicSharedPtr<const WriteRanges> pendingWrites;

bool HookSnapshotEnabled() {
// Debug aid: APS5_NO_HOOK_SNAPSHOT=1 takes the GpuMutex on every access as before.
Expand Down
5 changes: 4 additions & 1 deletion core/libs/prx/libSceAudioIn/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
add_library(libSceAudioIn SHARED EXCLUDE_FROM_ALL Export.cpp)
target_include_directories(libSceAudioIn PRIVATE ${LIBS_INCLUDE_DIR} ${ANYPS5_SDL2_INCLUDE_DIR})
target_link_libraries(libSceAudioIn PRIVATE SDL2-static)
target_link_options(libSceAudioIn PRIVATE LINKER:--exclude-libs,ALL)
# --exclude-libs is an ELF linker option; Mach-O has no equivalent.
if(NOT APPLE)
target_link_options(libSceAudioIn PRIVATE LINKER:--exclude-libs,ALL)
endif()
configure_windows_unwind(libSceAudioIn)

if(BUILD_TESTING)
Expand Down
Loading
Loading