mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-13 06:03:16 +00:00
''
This commit is contained in:
commit
96d13fa210
72 changed files with 2824 additions and 1147 deletions
|
@ -63,7 +63,7 @@ struct OrbisVirtualQueryInfo {
|
|||
|
||||
struct OrbisKernelBatchMapEntry {
|
||||
void* start;
|
||||
off_t offset;
|
||||
size_t offset;
|
||||
size_t length;
|
||||
char protection;
|
||||
char type;
|
||||
|
|
|
@ -465,7 +465,7 @@ int PS4_SYSV_ABI scePthreadMutexDestroy(ScePthreadMutex* mutex) {
|
|||
|
||||
int result = pthread_mutex_destroy(&(*mutex)->pth_mutex);
|
||||
|
||||
LOG_INFO(Kernel_Pthread, "name={}, result={}", (*mutex)->name, result);
|
||||
LOG_DEBUG(Kernel_Pthread, "name={}, result={}", (*mutex)->name, result);
|
||||
|
||||
delete *mutex;
|
||||
*mutex = nullptr;
|
||||
|
@ -725,7 +725,10 @@ int PS4_SYSV_ABI scePthreadCondDestroy(ScePthreadCond* cond) {
|
|||
}
|
||||
int result = pthread_cond_destroy(&(*cond)->cond);
|
||||
|
||||
LOG_INFO(Kernel_Pthread, "scePthreadCondDestroy, result={}", result);
|
||||
LOG_DEBUG(Kernel_Pthread, "scePthreadCondDestroy, result={}", result);
|
||||
|
||||
delete *cond;
|
||||
*cond = nullptr;
|
||||
|
||||
switch (result) {
|
||||
case 0:
|
||||
|
@ -808,8 +811,6 @@ int PS4_SYSV_ABI posix_pthread_cond_timedwait(ScePthreadCond* cond, ScePthreadMu
|
|||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_cond_broadcast(ScePthreadCond* cond) {
|
||||
LOG_INFO(Kernel_Pthread,
|
||||
"posix posix_pthread_cond_broadcast redirect to scePthreadCondBroadcast");
|
||||
int result = scePthreadCondBroadcast(cond);
|
||||
if (result != 0) {
|
||||
int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP
|
||||
|
@ -821,7 +822,6 @@ int PS4_SYSV_ABI posix_pthread_cond_broadcast(ScePthreadCond* cond) {
|
|||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_mutexattr_init(ScePthreadMutexattr* attr) {
|
||||
// LOG_INFO(Kernel_Pthread, "posix pthread_mutexattr_init redirect to scePthreadMutexattrInit");
|
||||
int result = scePthreadMutexattrInit(attr);
|
||||
if (result < 0) {
|
||||
int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP
|
||||
|
@ -833,7 +833,6 @@ int PS4_SYSV_ABI posix_pthread_mutexattr_init(ScePthreadMutexattr* attr) {
|
|||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_mutexattr_settype(ScePthreadMutexattr* attr, int type) {
|
||||
// LOG_INFO(Kernel_Pthread, "posix pthread_mutex_init redirect to scePthreadMutexInit");
|
||||
int result = scePthreadMutexattrSettype(attr, type);
|
||||
if (result < 0) {
|
||||
int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP
|
||||
|
@ -858,7 +857,6 @@ int PS4_SYSV_ABI posix_pthread_once(pthread_once_t* once_control, void (*init_ro
|
|||
|
||||
int PS4_SYSV_ABI posix_pthread_mutexattr_setprotocol(ScePthreadMutexattr* attr, int protocol) {
|
||||
int result = scePthreadMutexattrSetprotocol(attr, protocol);
|
||||
LOG_INFO(Kernel_Pthread, "redirect to scePthreadMutexattrSetprotocol: result = {}", result);
|
||||
if (result < 0) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -1142,7 +1140,7 @@ int PS4_SYSV_ABI scePthreadCondWait(ScePthreadCond* cond, ScePthreadMutex* mutex
|
|||
}
|
||||
int result = pthread_cond_wait(&(*cond)->cond, &(*mutex)->pth_mutex);
|
||||
|
||||
LOG_INFO(Kernel_Pthread, "scePthreadCondWait, result={}", result);
|
||||
LOG_DEBUG(Kernel_Pthread, "scePthreadCondWait, result={}", result);
|
||||
|
||||
switch (result) {
|
||||
case 0:
|
||||
|
@ -1162,7 +1160,7 @@ int PS4_SYSV_ABI scePthreadCondattrDestroy(ScePthreadCondattr* attr) {
|
|||
}
|
||||
int result = pthread_condattr_destroy(&(*attr)->cond_attr);
|
||||
|
||||
LOG_INFO(Kernel_Pthread, "scePthreadCondattrDestroy: result = {} ", result);
|
||||
LOG_DEBUG(Kernel_Pthread, "scePthreadCondattrDestroy: result = {} ", result);
|
||||
|
||||
switch (result) {
|
||||
case 0:
|
||||
|
@ -1292,8 +1290,6 @@ int PS4_SYSV_ABI posix_pthread_attr_setdetachstate(ScePthreadAttr* attr, int det
|
|||
int PS4_SYSV_ABI posix_pthread_create_name_np(ScePthread* thread, const ScePthreadAttr* attr,
|
||||
PthreadEntryFunc start_routine, void* arg,
|
||||
const char* name) {
|
||||
LOG_INFO(Kernel_Pthread, "posix pthread_create redirect to scePthreadCreate: name = {}", name);
|
||||
|
||||
int result = scePthreadCreate(thread, attr, start_routine, arg, name);
|
||||
if (result != 0) {
|
||||
int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP
|
||||
|
@ -1340,17 +1336,11 @@ int PS4_SYSV_ABI posix_pthread_cond_init(ScePthreadCond* cond, const ScePthreadC
|
|||
|
||||
int PS4_SYSV_ABI posix_pthread_cond_signal(ScePthreadCond* cond) {
|
||||
int result = scePthreadCondSignal(cond);
|
||||
LOG_INFO(Kernel_Pthread,
|
||||
"posix posix_pthread_cond_signal redirect to scePthreadCondSignal, result = {}",
|
||||
result);
|
||||
return result;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_cond_destroy(ScePthreadCond* cond) {
|
||||
int result = scePthreadCondDestroy(cond);
|
||||
LOG_INFO(Kernel_Pthread,
|
||||
"posix posix_pthread_cond_destroy redirect to scePthreadCondDestroy, result = {}",
|
||||
result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1370,6 +1360,10 @@ int PS4_SYSV_ABI posix_sem_wait(sem_t* sem) {
|
|||
return sem_wait(sem);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_sem_trywait(sem_t* sem) {
|
||||
return sem_trywait(sem);
|
||||
}
|
||||
|
||||
#ifndef HAVE_SEM_TIMEDWAIT
|
||||
int sem_timedwait(sem_t* sem, const struct timespec* abstime) {
|
||||
int rc;
|
||||
|
@ -1509,6 +1503,7 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
|||
LIB_FUNCTION("WrOLvHU0yQM", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setspecific);
|
||||
LIB_FUNCTION("4+h9EzwKF4I", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetschedpolicy);
|
||||
LIB_FUNCTION("-Wreprtu0Qs", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetdetachstate);
|
||||
LIB_FUNCTION("JaRMy+QcpeU", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrGetdetachstate);
|
||||
LIB_FUNCTION("eXbUSpEaTsA", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetinheritsched);
|
||||
LIB_FUNCTION("DzES9hQF4f4", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetschedparam);
|
||||
LIB_FUNCTION("nsYoNRywwNg", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrInit);
|
||||
|
@ -1621,6 +1616,7 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
|||
LIB_FUNCTION("Xs9hdiD7sAA", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setschedparam);
|
||||
LIB_FUNCTION("pDuPEf3m4fI", "libScePosix", 1, "libkernel", 1, 1, posix_sem_init);
|
||||
LIB_FUNCTION("YCV5dGGBcCo", "libScePosix", 1, "libkernel", 1, 1, posix_sem_wait);
|
||||
LIB_FUNCTION("WBWzsRifCEA", "libScePosix", 1, "libkernel", 1, 1, posix_sem_trywait);
|
||||
LIB_FUNCTION("w5IHyvahg-o", "libScePosix", 1, "libkernel", 1, 1, posix_sem_timedwait);
|
||||
LIB_FUNCTION("IKP8typ0QUk", "libScePosix", 1, "libkernel", 1, 1, posix_sem_post);
|
||||
LIB_FUNCTION("cDW233RAwWo", "libScePosix", 1, "libkernel", 1, 1, posix_sem_destroy);
|
||||
|
|
|
@ -470,7 +470,7 @@ int PS4_SYSV_ABI scePadSetUserColor() {
|
|||
}
|
||||
|
||||
int PS4_SYSV_ABI scePadSetVibration(s32 handle, const OrbisPadVibrationParam* pParam) {
|
||||
LOG_ERROR(Lib_Pad, "(STUBBED) called");
|
||||
LOG_DEBUG(Lib_Pad, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
|
@ -665,4 +665,4 @@ void RegisterlibScePad(Core::Loader::SymbolsResolver* sym) {
|
|||
LIB_FUNCTION("7xA+hFtvBCA", "libScePad", 1, "libScePad", 1, 1, Func_EF103E845B6F0420);
|
||||
};
|
||||
|
||||
} // namespace Libraries::Pad
|
||||
} // namespace Libraries::Pad
|
||||
|
|
|
@ -8,11 +8,6 @@
|
|||
#include "core/libraries/kernel/memory_management.h"
|
||||
#include "core/memory.h"
|
||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
namespace Core {
|
||||
|
||||
|
@ -177,7 +172,7 @@ int MemoryManager::MapMemory(void** out_addr, VAddr virtual_addr, size_t size, M
|
|||
|
||||
if (type == VMAType::Direct) {
|
||||
new_vma.phys_base = phys_addr;
|
||||
MapVulkanMemory(mapped_addr, size);
|
||||
rasterizer->MapMemory(mapped_addr, size);
|
||||
}
|
||||
if (type == VMAType::Flexible) {
|
||||
flexible_usage += size;
|
||||
|
@ -227,7 +222,7 @@ void MemoryManager::UnmapMemory(VAddr virtual_addr, size_t size) {
|
|||
const auto type = it->second.type;
|
||||
const bool has_backing = type == VMAType::Direct || type == VMAType::File;
|
||||
if (type == VMAType::Direct) {
|
||||
UnmapVulkanMemory(virtual_addr, size);
|
||||
rasterizer->UnmapMemory(virtual_addr, size);
|
||||
}
|
||||
if (type == VMAType::Flexible) {
|
||||
flexible_usage -= size;
|
||||
|
@ -377,7 +372,7 @@ int MemoryManager::MTypeProtect(VAddr addr, size_t size, VMAType mtype, int prot
|
|||
|
||||
|
||||
int MemoryManager::VirtualQuery(VAddr addr, int flags,
|
||||
Libraries::Kernel::OrbisVirtualQueryInfo* info) {
|
||||
::Libraries::Kernel::OrbisVirtualQueryInfo* info) {
|
||||
std::scoped_lock lk{mutex};
|
||||
|
||||
auto it = FindVMA(addr);
|
||||
|
@ -407,7 +402,7 @@ int MemoryManager::VirtualQuery(VAddr addr, int flags,
|
|||
}
|
||||
|
||||
int MemoryManager::DirectMemoryQuery(PAddr addr, bool find_next,
|
||||
Libraries::Kernel::OrbisQueryInfo* out_info) {
|
||||
::Libraries::Kernel::OrbisQueryInfo* out_info) {
|
||||
std::scoped_lock lk{mutex};
|
||||
|
||||
auto dmem_area = FindDmemArea(addr);
|
||||
|
@ -447,13 +442,6 @@ int MemoryManager::DirectQueryAvailable(PAddr search_start, PAddr search_end, si
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
std::pair<vk::Buffer, size_t> MemoryManager::GetVulkanBuffer(VAddr addr) {
|
||||
auto it = mapped_memories.upper_bound(addr);
|
||||
it = std::prev(it);
|
||||
ASSERT(it != mapped_memories.end() && it->first <= addr);
|
||||
return std::make_pair(*it->second.buffer, addr - it->first);
|
||||
}
|
||||
|
||||
void MemoryManager::NameVirtualRange(VAddr virtual_addr, size_t size, std::string_view name) {
|
||||
auto it = FindVMA(virtual_addr);
|
||||
|
||||
|
@ -569,85 +557,6 @@ MemoryManager::DMemHandle MemoryManager::Split(DMemHandle dmem_handle, size_t of
|
|||
return dmem_map.emplace_hint(std::next(dmem_handle), new_area.base, new_area);
|
||||
};
|
||||
|
||||
void MemoryManager::MapVulkanMemory(VAddr addr, size_t size) {
|
||||
return;
|
||||
const vk::Device device = instance->GetDevice();
|
||||
const auto memory_props = instance->GetPhysicalDevice().getMemoryProperties();
|
||||
void* host_pointer = reinterpret_cast<void*>(addr);
|
||||
const auto host_mem_props = device.getMemoryHostPointerPropertiesEXT(
|
||||
vk::ExternalMemoryHandleTypeFlagBits::eHostAllocationEXT, host_pointer);
|
||||
ASSERT(host_mem_props.memoryTypeBits != 0);
|
||||
|
||||
int mapped_memory_type = -1;
|
||||
auto find_mem_type_with_flag = [&](const vk::MemoryPropertyFlags flags) {
|
||||
u32 host_mem_types = host_mem_props.memoryTypeBits;
|
||||
while (host_mem_types != 0) {
|
||||
// Try to find a cached memory type
|
||||
mapped_memory_type = std::countr_zero(host_mem_types);
|
||||
host_mem_types -= (1 << mapped_memory_type);
|
||||
|
||||
if ((memory_props.memoryTypes[mapped_memory_type].propertyFlags & flags) == flags) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mapped_memory_type = -1;
|
||||
};
|
||||
|
||||
// First try to find a memory that is both coherent and cached
|
||||
find_mem_type_with_flag(vk::MemoryPropertyFlagBits::eHostCoherent |
|
||||
vk::MemoryPropertyFlagBits::eHostCached);
|
||||
if (mapped_memory_type == -1)
|
||||
// Then only coherent (lower performance)
|
||||
find_mem_type_with_flag(vk::MemoryPropertyFlagBits::eHostCoherent);
|
||||
|
||||
if (mapped_memory_type == -1) {
|
||||
LOG_CRITICAL(Render_Vulkan, "No coherent memory available for memory mapping");
|
||||
mapped_memory_type = std::countr_zero(host_mem_props.memoryTypeBits);
|
||||
}
|
||||
|
||||
const vk::StructureChain alloc_info = {
|
||||
vk::MemoryAllocateInfo{
|
||||
.allocationSize = size,
|
||||
.memoryTypeIndex = static_cast<uint32_t>(mapped_memory_type),
|
||||
},
|
||||
vk::ImportMemoryHostPointerInfoEXT{
|
||||
.handleType = vk::ExternalMemoryHandleTypeFlagBits::eHostAllocationEXT,
|
||||
.pHostPointer = host_pointer,
|
||||
},
|
||||
};
|
||||
|
||||
const auto [it, new_memory] = mapped_memories.try_emplace(addr);
|
||||
ASSERT_MSG(new_memory, "Attempting to remap already mapped vulkan memory");
|
||||
|
||||
auto& memory = it->second;
|
||||
memory.backing = device.allocateMemoryUnique(alloc_info.get());
|
||||
|
||||
constexpr vk::BufferUsageFlags MapFlags =
|
||||
vk::BufferUsageFlagBits::eIndexBuffer | vk::BufferUsageFlagBits::eVertexBuffer |
|
||||
vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eTransferDst |
|
||||
vk::BufferUsageFlagBits::eUniformBuffer | vk::BufferUsageFlagBits::eStorageBuffer;
|
||||
|
||||
const vk::StructureChain buffer_info = {
|
||||
vk::BufferCreateInfo{
|
||||
.size = size,
|
||||
.usage = MapFlags,
|
||||
.sharingMode = vk::SharingMode::eExclusive,
|
||||
},
|
||||
vk::ExternalMemoryBufferCreateInfoKHR{
|
||||
.handleTypes = vk::ExternalMemoryHandleTypeFlagBits::eHostAllocationEXT,
|
||||
}};
|
||||
memory.buffer = device.createBufferUnique(buffer_info.get());
|
||||
device.bindBufferMemory(*memory.buffer, *memory.backing, 0);
|
||||
}
|
||||
|
||||
void MemoryManager::UnmapVulkanMemory(VAddr addr, size_t size) {
|
||||
return;
|
||||
const auto it = mapped_memories.find(addr);
|
||||
ASSERT(it != mapped_memories.end() && it->second.buffer_size == size);
|
||||
mapped_memories.erase(it);
|
||||
}
|
||||
|
||||
int MemoryManager::GetDirectMemoryType(PAddr addr, int* directMemoryTypeOut,
|
||||
void** directMemoryStartOut, void** directMemoryEndOut) {
|
||||
std::scoped_lock lk{mutex};
|
||||
|
|
|
@ -3,20 +3,17 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <boost/icl/split_interval_map.hpp>
|
||||
#include "common/enum.h"
|
||||
#include "common/singleton.h"
|
||||
#include "common/types.h"
|
||||
#include "core/address_space.h"
|
||||
#include "core/libraries/kernel/memory_management.h"
|
||||
#include "video_core/renderer_vulkan/vk_common.h"
|
||||
|
||||
namespace Vulkan {
|
||||
class Instance;
|
||||
class Rasterizer;
|
||||
}
|
||||
|
||||
namespace Libraries::Kernel {
|
||||
|
@ -128,8 +125,8 @@ public:
|
|||
explicit MemoryManager();
|
||||
~MemoryManager();
|
||||
|
||||
void SetInstance(const Vulkan::Instance* instance_) {
|
||||
instance = instance_;
|
||||
void SetRasterizer(Vulkan::Rasterizer* rasterizer_) {
|
||||
rasterizer = rasterizer_;
|
||||
}
|
||||
|
||||
void SetTotalFlexibleSize(u64 size) {
|
||||
|
@ -140,9 +137,7 @@ public:
|
|||
return total_flexible_size - flexible_usage;
|
||||
}
|
||||
|
||||
/// Returns the offset of the mapped virtual system managed memory base from where it usually
|
||||
/// would be mapped.
|
||||
[[nodiscard]] VAddr SystemReservedVirtualBase() noexcept {
|
||||
VAddr SystemReservedVirtualBase() noexcept {
|
||||
return impl.SystemReservedVirtualBase();
|
||||
}
|
||||
|
||||
|
@ -176,8 +171,6 @@ public:
|
|||
int DirectQueryAvailable(PAddr search_start, PAddr search_end, size_t alignment,
|
||||
PAddr* phys_addr_out, size_t* size_out);
|
||||
|
||||
std::pair<vk::Buffer, size_t> GetVulkanBuffer(VAddr addr);
|
||||
|
||||
int GetDirectMemoryType(PAddr addr, int* directMemoryTypeOut, void** directMemoryStartOut,
|
||||
void** directMemoryEndOut);
|
||||
|
||||
|
@ -222,10 +215,6 @@ private:
|
|||
|
||||
DMemHandle Split(DMemHandle dmem_handle, size_t offset_in_area);
|
||||
|
||||
void MapVulkanMemory(VAddr addr, size_t size);
|
||||
|
||||
void UnmapVulkanMemory(VAddr addr, size_t size);
|
||||
|
||||
private:
|
||||
AddressSpace impl;
|
||||
DMemMap dmem_map;
|
||||
|
@ -233,14 +222,7 @@ private:
|
|||
std::recursive_mutex mutex;
|
||||
size_t total_flexible_size = 448_MB;
|
||||
size_t flexible_usage{};
|
||||
|
||||
struct MappedMemory {
|
||||
vk::UniqueBuffer buffer;
|
||||
vk::UniqueDeviceMemory backing;
|
||||
size_t buffer_size;
|
||||
};
|
||||
std::map<VAddr, MappedMemory> mapped_memories;
|
||||
const Vulkan::Instance* instance{};
|
||||
Vulkan::Rasterizer* rasterizer{};
|
||||
};
|
||||
|
||||
using Memory = Common::Singleton<MemoryManager>;
|
||||
|
|
|
@ -88,6 +88,7 @@ void Module::LoadModuleToMemory(u32& max_tls_index) {
|
|||
aligned_base_size + TrampolineSize, MemoryProt::CpuReadWrite,
|
||||
MemoryMapFlags::Fixed, VMAType::Code, name, true);
|
||||
LoadOffset += CODE_BASE_INCR * (1 + aligned_base_size / CODE_BASE_INCR);
|
||||
LOG_INFO(Core_Linker, "Loading module {} to {}", name, fmt::ptr(*out_addr));
|
||||
|
||||
// Initialize trampoline generator.
|
||||
void* trampoline_addr = std::bit_cast<void*>(base_virtual_addr + aligned_base_size);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue