mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-05 00:42:48 +00:00
Merge branch 'main' into qt-style
This commit is contained in:
commit
e385636f38
@ -120,7 +120,7 @@ find_package(SDL3 3.1.2 CONFIG)
|
|||||||
find_package(stb MODULE)
|
find_package(stb MODULE)
|
||||||
find_package(toml11 4.2.0 CONFIG)
|
find_package(toml11 4.2.0 CONFIG)
|
||||||
find_package(tsl-robin-map 1.3.0 CONFIG)
|
find_package(tsl-robin-map 1.3.0 CONFIG)
|
||||||
find_package(VulkanHeaders 1.4.303 CONFIG)
|
find_package(VulkanHeaders 1.4.305 CONFIG)
|
||||||
find_package(VulkanMemoryAllocator 3.1.0 CONFIG)
|
find_package(VulkanMemoryAllocator 3.1.0 CONFIG)
|
||||||
find_package(xbyak 7.07 CONFIG)
|
find_package(xbyak 7.07 CONFIG)
|
||||||
find_package(xxHash 0.8.2 MODULE)
|
find_package(xxHash 0.8.2 MODULE)
|
||||||
@ -557,6 +557,16 @@ set(CORE src/core/aerolib/stubs.cpp
|
|||||||
src/core/devices/logger.cpp
|
src/core/devices/logger.cpp
|
||||||
src/core/devices/logger.h
|
src/core/devices/logger.h
|
||||||
src/core/devices/nop_device.h
|
src/core/devices/nop_device.h
|
||||||
|
src/core/devices/console_device.cpp
|
||||||
|
src/core/devices/console_device.h
|
||||||
|
src/core/devices/deci_tty6_device.cpp
|
||||||
|
src/core/devices/deci_tty6_device.h
|
||||||
|
src/core/devices/random_device.cpp
|
||||||
|
src/core/devices/random_device.h
|
||||||
|
src/core/devices/urandom_device.cpp
|
||||||
|
src/core/devices/urandom_device.h
|
||||||
|
src/core/devices/srandom_device.cpp
|
||||||
|
src/core/devices/srandom_device.h
|
||||||
src/core/file_format/pfs.h
|
src/core/file_format/pfs.h
|
||||||
src/core/file_format/pkg.cpp
|
src/core/file_format/pkg.cpp
|
||||||
src/core/file_format/pkg.h
|
src/core/file_format/pkg.h
|
||||||
|
2
externals/vulkan-headers
vendored
2
externals/vulkan-headers
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 6a74a7d65cafa19e38ec116651436cce6efd5b2e
|
Subproject commit a03d2f6d5753b365d704d58161825890baad0755
|
@ -79,6 +79,7 @@ static std::string trophyKey;
|
|||||||
static bool load_game_size = true;
|
static bool load_game_size = true;
|
||||||
std::vector<std::filesystem::path> settings_install_dirs = {};
|
std::vector<std::filesystem::path> settings_install_dirs = {};
|
||||||
std::filesystem::path settings_addon_install_dir = {};
|
std::filesystem::path settings_addon_install_dir = {};
|
||||||
|
std::filesystem::path save_data_path = {};
|
||||||
u32 main_window_geometry_x = 400;
|
u32 main_window_geometry_x = 400;
|
||||||
u32 main_window_geometry_y = 400;
|
u32 main_window_geometry_y = 400;
|
||||||
u32 main_window_geometry_w = 1280;
|
u32 main_window_geometry_w = 1280;
|
||||||
@ -111,6 +112,13 @@ bool GetLoadGameSizeEnabled() {
|
|||||||
return load_game_size;
|
return load_game_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::filesystem::path GetSaveDataPath() {
|
||||||
|
if (save_data_path.empty()) {
|
||||||
|
return Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir);
|
||||||
|
}
|
||||||
|
return save_data_path;
|
||||||
|
}
|
||||||
|
|
||||||
void setLoadGameSizeEnabled(bool enable) {
|
void setLoadGameSizeEnabled(bool enable) {
|
||||||
load_game_size = enable;
|
load_game_size = enable;
|
||||||
}
|
}
|
||||||
@ -511,6 +519,10 @@ void setGameInstallDirs(const std::vector<std::filesystem::path>& settings_insta
|
|||||||
settings_install_dirs = settings_install_dirs_config;
|
settings_install_dirs = settings_install_dirs_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setSaveDataPath(const std::filesystem::path& path) {
|
||||||
|
save_data_path = path;
|
||||||
|
}
|
||||||
|
|
||||||
u32 getMainWindowGeometryX() {
|
u32 getMainWindowGeometryX() {
|
||||||
return main_window_geometry_x;
|
return main_window_geometry_x;
|
||||||
}
|
}
|
||||||
@ -699,6 +711,8 @@ void load(const std::filesystem::path& path) {
|
|||||||
addGameInstallDir(std::filesystem::path{dir});
|
addGameInstallDir(std::filesystem::path{dir});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
save_data_path = toml::find_fs_path_or(gui, "saveDataPath", {});
|
||||||
|
|
||||||
settings_addon_install_dir = toml::find_fs_path_or(gui, "addonInstallDir", {});
|
settings_addon_install_dir = toml::find_fs_path_or(gui, "addonInstallDir", {});
|
||||||
main_window_geometry_x = toml::find_or<int>(gui, "geometry_x", 0);
|
main_window_geometry_x = toml::find_or<int>(gui, "geometry_x", 0);
|
||||||
main_window_geometry_y = toml::find_or<int>(gui, "geometry_y", 0);
|
main_window_geometry_y = toml::find_or<int>(gui, "geometry_y", 0);
|
||||||
@ -794,6 +808,7 @@ void save(const std::filesystem::path& path) {
|
|||||||
install_dirs.emplace_back(std::string{fmt::UTF(dirString.u8string()).data});
|
install_dirs.emplace_back(std::string{fmt::UTF(dirString.u8string()).data});
|
||||||
}
|
}
|
||||||
data["GUI"]["installDirs"] = install_dirs;
|
data["GUI"]["installDirs"] = install_dirs;
|
||||||
|
data["GUI"]["saveDataPath"] = std::string{fmt::UTF(save_data_path.u8string()).data};
|
||||||
data["GUI"]["loadGameSizeEnabled"] = load_game_size;
|
data["GUI"]["loadGameSizeEnabled"] = load_game_size;
|
||||||
|
|
||||||
data["GUI"]["addonInstallDir"] =
|
data["GUI"]["addonInstallDir"] =
|
||||||
|
@ -18,6 +18,7 @@ void saveMainWindow(const std::filesystem::path& path);
|
|||||||
std::string getTrophyKey();
|
std::string getTrophyKey();
|
||||||
void setTrophyKey(std::string key);
|
void setTrophyKey(std::string key);
|
||||||
bool GetLoadGameSizeEnabled();
|
bool GetLoadGameSizeEnabled();
|
||||||
|
std::filesystem::path GetSaveDataPath();
|
||||||
void setLoadGameSizeEnabled(bool enable);
|
void setLoadGameSizeEnabled(bool enable);
|
||||||
bool getIsFullscreen();
|
bool getIsFullscreen();
|
||||||
std::string getFullscreenMode();
|
std::string getFullscreenMode();
|
||||||
@ -83,6 +84,7 @@ void setUserName(const std::string& type);
|
|||||||
void setUpdateChannel(const std::string& type);
|
void setUpdateChannel(const std::string& type);
|
||||||
void setSeparateUpdateEnabled(bool use);
|
void setSeparateUpdateEnabled(bool use);
|
||||||
void setGameInstallDirs(const std::vector<std::filesystem::path>& settings_install_dirs_config);
|
void setGameInstallDirs(const std::vector<std::filesystem::path>& settings_install_dirs_config);
|
||||||
|
void setSaveDataPath(const std::filesystem::path& path);
|
||||||
void setCompatibilityEnabled(bool use);
|
void setCompatibilityEnabled(bool use);
|
||||||
void setCheckCompatibilityOnStartup(bool use);
|
void setCheckCompatibilityOnStartup(bool use);
|
||||||
|
|
||||||
|
@ -67,28 +67,25 @@ struct AddressSpace::Impl {
|
|||||||
static constexpr size_t ReductionOnFail = 1_GB;
|
static constexpr size_t ReductionOnFail = 1_GB;
|
||||||
static constexpr size_t MaxReductions = 10;
|
static constexpr size_t MaxReductions = 10;
|
||||||
|
|
||||||
size_t reduction = 0;
|
|
||||||
size_t virtual_size = SystemManagedSize + SystemReservedSize + UserSize;
|
size_t virtual_size = SystemManagedSize + SystemReservedSize + UserSize;
|
||||||
for (u32 i = 0; i < MaxReductions; i++) {
|
for (u32 i = 0; i < MaxReductions; i++) {
|
||||||
virtual_base = static_cast<u8*>(VirtualAlloc2(process, NULL, virtual_size - reduction,
|
virtual_base = static_cast<u8*>(VirtualAlloc2(process, NULL, virtual_size,
|
||||||
MEM_RESERVE | MEM_RESERVE_PLACEHOLDER,
|
MEM_RESERVE | MEM_RESERVE_PLACEHOLDER,
|
||||||
PAGE_NOACCESS, ¶m, 1));
|
PAGE_NOACCESS, ¶m, 1));
|
||||||
if (virtual_base) {
|
if (virtual_base) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
reduction += ReductionOnFail;
|
virtual_size -= ReductionOnFail;
|
||||||
}
|
}
|
||||||
ASSERT_MSG(virtual_base, "Unable to reserve virtual address space: {}",
|
ASSERT_MSG(virtual_base, "Unable to reserve virtual address space: {}",
|
||||||
Common::GetLastErrorMsg());
|
Common::GetLastErrorMsg());
|
||||||
|
|
||||||
// Take the reduction off of the system managed area, and leave the others unchanged.
|
|
||||||
reduction = size_t(virtual_base - SYSTEM_MANAGED_MIN);
|
|
||||||
system_managed_base = virtual_base;
|
|
||||||
system_managed_size = SystemManagedSize - reduction;
|
|
||||||
system_reserved_base = reinterpret_cast<u8*>(SYSTEM_RESERVED_MIN);
|
system_reserved_base = reinterpret_cast<u8*>(SYSTEM_RESERVED_MIN);
|
||||||
system_reserved_size = SystemReservedSize;
|
system_reserved_size = SystemReservedSize;
|
||||||
|
system_managed_base = virtual_base;
|
||||||
|
system_managed_size = system_reserved_base - virtual_base;
|
||||||
user_base = reinterpret_cast<u8*>(USER_MIN);
|
user_base = reinterpret_cast<u8*>(USER_MIN);
|
||||||
user_size = UserSize;
|
user_size = virtual_base + virtual_size - user_base;
|
||||||
|
|
||||||
LOG_INFO(Kernel_Vmm, "System managed virtual memory region: {} - {}",
|
LOG_INFO(Kernel_Vmm, "System managed virtual memory region: {} - {}",
|
||||||
fmt::ptr(system_managed_base),
|
fmt::ptr(system_managed_base),
|
||||||
@ -101,10 +98,8 @@ struct AddressSpace::Impl {
|
|||||||
|
|
||||||
// Initializer placeholder tracker
|
// Initializer placeholder tracker
|
||||||
const uintptr_t system_managed_addr = reinterpret_cast<uintptr_t>(system_managed_base);
|
const uintptr_t system_managed_addr = reinterpret_cast<uintptr_t>(system_managed_base);
|
||||||
const uintptr_t system_reserved_addr = reinterpret_cast<uintptr_t>(system_reserved_base);
|
|
||||||
const uintptr_t user_addr = reinterpret_cast<uintptr_t>(user_base);
|
|
||||||
regions.emplace(system_managed_addr,
|
regions.emplace(system_managed_addr,
|
||||||
MemoryRegion{system_managed_addr, virtual_size - reduction, false});
|
MemoryRegion{system_managed_addr, virtual_size, false});
|
||||||
|
|
||||||
// Allocate backing file that represents the total physical memory.
|
// Allocate backing file that represents the total physical memory.
|
||||||
backing_handle =
|
backing_handle =
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "base_device.h"
|
#include "base_device.h"
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
74
src/core/devices/console_device.cpp
Normal file
74
src/core/devices/console_device.cpp
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "common/logging/log.h"
|
||||||
|
#include "console_device.h"
|
||||||
|
|
||||||
|
namespace Core::Devices {
|
||||||
|
|
||||||
|
std::shared_ptr<BaseDevice> ConsoleDevice::Create(u32 handle, const char*, int, u16) {
|
||||||
|
return std::shared_ptr<BaseDevice>(
|
||||||
|
reinterpret_cast<Devices::BaseDevice*>(new ConsoleDevice(handle)));
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConsoleDevice::ioctl(u64 cmd, Common::VaCtx* args) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 ConsoleDevice::write(const void* buf, size_t nbytes) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ConsoleDevice::writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ConsoleDevice::readv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 ConsoleDevice::preadv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 ConsoleDevice::lseek(s64 offset, int whence) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 ConsoleDevice::read(void* buf, size_t nbytes) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConsoleDevice::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 ConsoleDevice::fsync() {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConsoleDevice::ftruncate(s64 length) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConsoleDevice::getdents(void* buf, u32 nbytes, s64* basep) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 ConsoleDevice::pwrite(const void* buf, size_t nbytes, u64 offset) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Core::Devices
|
33
src/core/devices/console_device.h
Normal file
33
src/core/devices/console_device.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <memory>
|
||||||
|
#include "base_device.h"
|
||||||
|
|
||||||
|
namespace Core::Devices {
|
||||||
|
|
||||||
|
class ConsoleDevice final : BaseDevice {
|
||||||
|
u32 handle;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, int, u16);
|
||||||
|
explicit ConsoleDevice(u32 handle) : handle(handle) {}
|
||||||
|
|
||||||
|
~ConsoleDevice() override = default;
|
||||||
|
|
||||||
|
int ioctl(u64 cmd, Common::VaCtx* args) override;
|
||||||
|
s64 write(const void* buf, size_t nbytes) override;
|
||||||
|
size_t readv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override;
|
||||||
|
size_t writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override;
|
||||||
|
s64 preadv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) override;
|
||||||
|
s64 lseek(s64 offset, int whence) override;
|
||||||
|
s64 read(void* buf, size_t nbytes) override;
|
||||||
|
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
|
||||||
|
s32 fsync() override;
|
||||||
|
int ftruncate(s64 length) override;
|
||||||
|
int getdents(void* buf, u32 nbytes, s64* basep) override;
|
||||||
|
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Core::Devices
|
74
src/core/devices/deci_tty6_device.cpp
Normal file
74
src/core/devices/deci_tty6_device.cpp
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "common/logging/log.h"
|
||||||
|
#include "deci_tty6_device.h"
|
||||||
|
|
||||||
|
namespace Core::Devices {
|
||||||
|
|
||||||
|
std::shared_ptr<BaseDevice> DeciTty6Device::Create(u32 handle, const char*, int, u16) {
|
||||||
|
return std::shared_ptr<BaseDevice>(
|
||||||
|
reinterpret_cast<Devices::BaseDevice*>(new DeciTty6Device(handle)));
|
||||||
|
}
|
||||||
|
|
||||||
|
int DeciTty6Device::ioctl(u64 cmd, Common::VaCtx* args) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 DeciTty6Device::write(const void* buf, size_t nbytes) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t DeciTty6Device::writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t DeciTty6Device::readv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 DeciTty6Device::preadv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 DeciTty6Device::lseek(s64 offset, int whence) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 DeciTty6Device::read(void* buf, size_t nbytes) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DeciTty6Device::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 DeciTty6Device::fsync() {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DeciTty6Device::ftruncate(s64 length) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DeciTty6Device::getdents(void* buf, u32 nbytes, s64* basep) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 DeciTty6Device::pwrite(const void* buf, size_t nbytes, u64 offset) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Core::Devices
|
33
src/core/devices/deci_tty6_device.h
Normal file
33
src/core/devices/deci_tty6_device.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <memory>
|
||||||
|
#include "base_device.h"
|
||||||
|
|
||||||
|
namespace Core::Devices {
|
||||||
|
|
||||||
|
class DeciTty6Device final : BaseDevice {
|
||||||
|
u32 handle;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, int, u16);
|
||||||
|
explicit DeciTty6Device(u32 handle) : handle(handle) {}
|
||||||
|
|
||||||
|
~DeciTty6Device() override = default;
|
||||||
|
|
||||||
|
int ioctl(u64 cmd, Common::VaCtx* args) override;
|
||||||
|
s64 write(const void* buf, size_t nbytes) override;
|
||||||
|
size_t readv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override;
|
||||||
|
size_t writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override;
|
||||||
|
s64 preadv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) override;
|
||||||
|
s64 lseek(s64 offset, int whence) override;
|
||||||
|
s64 read(void* buf, size_t nbytes) override;
|
||||||
|
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
|
||||||
|
s32 fsync() override;
|
||||||
|
int ftruncate(s64 length) override;
|
||||||
|
int getdents(void* buf, u32 nbytes, s64* basep) override;
|
||||||
|
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Core::Devices
|
@ -1,5 +1,5 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/libraries/kernel/file_system.h"
|
#include "core/libraries/kernel/file_system.h"
|
||||||
@ -17,10 +17,12 @@ s64 Logger::write(const void* buf, size_t nbytes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t Logger::writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) {
|
size_t Logger::writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) {
|
||||||
|
size_t total_written = 0;
|
||||||
for (int i = 0; i < iovcnt; i++) {
|
for (int i = 0; i < iovcnt; i++) {
|
||||||
log(static_cast<const char*>(iov[i].iov_base), iov[i].iov_len);
|
log(static_cast<const char*>(iov[i].iov_base), iov[i].iov_len);
|
||||||
|
total_written += iov[i].iov_len;
|
||||||
}
|
}
|
||||||
return iovcnt;
|
return total_written;
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 Logger::pwrite(const void* buf, size_t nbytes, u64 offset) {
|
s64 Logger::pwrite(const void* buf, size_t nbytes, u64 offset) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "base_device.h"
|
#include "base_device.h"
|
||||||
@ -17,36 +17,47 @@ public:
|
|||||||
int ioctl(u64 cmd, Common::VaCtx* args) override {
|
int ioctl(u64 cmd, Common::VaCtx* args) override {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 write(const void* buf, size_t nbytes) override {
|
s64 write(const void* buf, size_t nbytes) override {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t readv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override {
|
size_t readv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override {
|
size_t writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 preadv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) override {
|
s64 preadv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) override {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 lseek(s64 offset, int whence) override {
|
s64 lseek(s64 offset, int whence) override {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 read(void* buf, size_t nbytes) override {
|
s64 read(void* buf, size_t nbytes) override {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override {
|
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 fsync() override {
|
s32 fsync() override {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ftruncate(s64 length) override {
|
int ftruncate(s64 length) override {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getdents(void* buf, u32 nbytes, s64* basep) override {
|
int getdents(void* buf, u32 nbytes, s64* basep) override {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override {
|
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
78
src/core/devices/random_device.cpp
Normal file
78
src/core/devices/random_device.cpp
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include "common/logging/log.h"
|
||||||
|
#include "random_device.h"
|
||||||
|
|
||||||
|
namespace Core::Devices {
|
||||||
|
|
||||||
|
std::shared_ptr<BaseDevice> RandomDevice::Create(u32 handle, const char*, int, u16) {
|
||||||
|
std::srand(std::time(nullptr));
|
||||||
|
return std::shared_ptr<BaseDevice>(
|
||||||
|
reinterpret_cast<Devices::BaseDevice*>(new RandomDevice(handle)));
|
||||||
|
}
|
||||||
|
|
||||||
|
int RandomDevice::ioctl(u64 cmd, Common::VaCtx* args) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 RandomDevice::write(const void* buf, size_t nbytes) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t RandomDevice::writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t RandomDevice::readv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 RandomDevice::preadv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 RandomDevice::lseek(s64 offset, int whence) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 RandomDevice::read(void* buf, size_t nbytes) {
|
||||||
|
auto rbuf = static_cast<char*>(buf);
|
||||||
|
for (size_t i = 0; i < nbytes; i++) {
|
||||||
|
rbuf[i] = std::rand() & 0xFF;
|
||||||
|
}
|
||||||
|
return nbytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RandomDevice::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 RandomDevice::fsync() {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RandomDevice::ftruncate(s64 length) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RandomDevice::getdents(void* buf, u32 nbytes, s64* basep) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 RandomDevice::pwrite(const void* buf, size_t nbytes, u64 offset) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Core::Devices
|
33
src/core/devices/random_device.h
Normal file
33
src/core/devices/random_device.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <memory>
|
||||||
|
#include "base_device.h"
|
||||||
|
|
||||||
|
namespace Core::Devices {
|
||||||
|
|
||||||
|
class RandomDevice final : BaseDevice {
|
||||||
|
u32 handle;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, int, u16);
|
||||||
|
explicit RandomDevice(u32 handle) : handle(handle) {}
|
||||||
|
|
||||||
|
~RandomDevice() override = default;
|
||||||
|
|
||||||
|
int ioctl(u64 cmd, Common::VaCtx* args) override;
|
||||||
|
s64 write(const void* buf, size_t nbytes) override;
|
||||||
|
size_t readv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override;
|
||||||
|
size_t writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override;
|
||||||
|
s64 preadv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) override;
|
||||||
|
s64 lseek(s64 offset, int whence) override;
|
||||||
|
s64 read(void* buf, size_t nbytes) override;
|
||||||
|
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
|
||||||
|
s32 fsync() override;
|
||||||
|
int ftruncate(s64 length) override;
|
||||||
|
int getdents(void* buf, u32 nbytes, s64* basep) override;
|
||||||
|
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Core::Devices
|
79
src/core/devices/srandom_device.cpp
Normal file
79
src/core/devices/srandom_device.cpp
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include "common/logging/log.h"
|
||||||
|
#include "srandom_device.h"
|
||||||
|
|
||||||
|
namespace Core::Devices {
|
||||||
|
|
||||||
|
std::shared_ptr<BaseDevice> SRandomDevice::Create(u32 handle, const char*, int, u16) {
|
||||||
|
std::srand(std::time(nullptr));
|
||||||
|
return std::shared_ptr<BaseDevice>(
|
||||||
|
reinterpret_cast<Devices::BaseDevice*>(new SRandomDevice(handle)));
|
||||||
|
}
|
||||||
|
|
||||||
|
int SRandomDevice::ioctl(u64 cmd, Common::VaCtx* args) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 SRandomDevice::write(const void* buf, size_t nbytes) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t SRandomDevice::writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t SRandomDevice::readv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 SRandomDevice::preadv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 SRandomDevice::lseek(s64 offset, int whence) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 SRandomDevice::read(void* buf, size_t nbytes) {
|
||||||
|
auto rbuf = static_cast<char*>(buf);
|
||||||
|
for (size_t i = 0; i < nbytes; i++) {
|
||||||
|
rbuf[i] = std::rand();
|
||||||
|
}
|
||||||
|
return nbytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SRandomDevice::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 SRandomDevice::fsync() {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return s32();
|
||||||
|
}
|
||||||
|
|
||||||
|
int SRandomDevice::ftruncate(s64 length) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SRandomDevice::getdents(void* buf, u32 nbytes, s64* basep) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 SRandomDevice::pwrite(const void* buf, size_t nbytes, u64 offset) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Core::Devices
|
33
src/core/devices/srandom_device.h
Normal file
33
src/core/devices/srandom_device.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <memory>
|
||||||
|
#include "base_device.h"
|
||||||
|
|
||||||
|
namespace Core::Devices {
|
||||||
|
|
||||||
|
class SRandomDevice final : BaseDevice {
|
||||||
|
u32 handle;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, int, u16);
|
||||||
|
explicit SRandomDevice(u32 handle) : handle(handle) {}
|
||||||
|
|
||||||
|
~SRandomDevice() override = default;
|
||||||
|
|
||||||
|
int ioctl(u64 cmd, Common::VaCtx* args) override;
|
||||||
|
s64 write(const void* buf, size_t nbytes) override;
|
||||||
|
size_t readv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override;
|
||||||
|
size_t writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override;
|
||||||
|
s64 preadv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) override;
|
||||||
|
s64 lseek(s64 offset, int whence) override;
|
||||||
|
s64 read(void* buf, size_t nbytes) override;
|
||||||
|
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
|
||||||
|
s32 fsync() override;
|
||||||
|
int ftruncate(s64 length) override;
|
||||||
|
int getdents(void* buf, u32 nbytes, s64* basep) override;
|
||||||
|
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Core::Devices
|
79
src/core/devices/urandom_device.cpp
Normal file
79
src/core/devices/urandom_device.cpp
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include "common/logging/log.h"
|
||||||
|
#include "urandom_device.h"
|
||||||
|
|
||||||
|
namespace Core::Devices {
|
||||||
|
|
||||||
|
std::shared_ptr<BaseDevice> URandomDevice::Create(u32 handle, const char*, int, u16) {
|
||||||
|
std::srand(std::time(nullptr));
|
||||||
|
return std::shared_ptr<BaseDevice>(
|
||||||
|
reinterpret_cast<Devices::BaseDevice*>(new URandomDevice(handle)));
|
||||||
|
}
|
||||||
|
|
||||||
|
int URandomDevice::ioctl(u64 cmd, Common::VaCtx* args) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 URandomDevice::write(const void* buf, size_t nbytes) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t URandomDevice::writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t URandomDevice::readv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 URandomDevice::preadv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 URandomDevice::lseek(s64 offset, int whence) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 URandomDevice::read(void* buf, size_t nbytes) {
|
||||||
|
auto rbuf = static_cast<char*>(buf);
|
||||||
|
for (size_t i = 0; i < nbytes; i++) {
|
||||||
|
rbuf[i] = std::rand() & 0xFF;
|
||||||
|
}
|
||||||
|
return nbytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
int URandomDevice::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 URandomDevice::fsync() {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int URandomDevice::ftruncate(s64 length) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int URandomDevice::getdents(void* buf, u32 nbytes, s64* basep) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 URandomDevice::pwrite(const void* buf, size_t nbytes, u64 offset) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Core::Devices
|
33
src/core/devices/urandom_device.h
Normal file
33
src/core/devices/urandom_device.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <memory>
|
||||||
|
#include "base_device.h"
|
||||||
|
|
||||||
|
namespace Core::Devices {
|
||||||
|
|
||||||
|
class URandomDevice final : BaseDevice {
|
||||||
|
u32 handle;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, int, u16);
|
||||||
|
explicit URandomDevice(u32 handle) : handle(handle) {}
|
||||||
|
|
||||||
|
~URandomDevice() override = default;
|
||||||
|
|
||||||
|
int ioctl(u64 cmd, Common::VaCtx* args) override;
|
||||||
|
s64 write(const void* buf, size_t nbytes) override;
|
||||||
|
size_t readv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override;
|
||||||
|
size_t writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override;
|
||||||
|
s64 preadv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) override;
|
||||||
|
s64 lseek(s64 offset, int whence) override;
|
||||||
|
s64 read(void* buf, size_t nbytes) override;
|
||||||
|
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
|
||||||
|
s32 fsync() override;
|
||||||
|
int ftruncate(s64 length) override;
|
||||||
|
int getdents(void* buf, u32 nbytes, s64* basep) override;
|
||||||
|
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Core::Devices
|
@ -93,6 +93,12 @@ void L::DrawMenuBar() {
|
|||||||
}
|
}
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SameLine(ImGui::GetWindowWidth() - 30.0f);
|
||||||
|
if (Button("X", ImVec2(25, 25))) {
|
||||||
|
DebugState.IsShowingDebugMenuBar() = false;
|
||||||
|
}
|
||||||
|
|
||||||
EndMainMenuBar();
|
EndMainMenuBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@ void HandleTable::CreateStdHandles() {
|
|||||||
std::shared_ptr<Devices::BaseDevice>{reinterpret_cast<Devices::BaseDevice*>(device)};
|
std::shared_ptr<Devices::BaseDevice>{reinterpret_cast<Devices::BaseDevice*>(device)};
|
||||||
};
|
};
|
||||||
// order matters
|
// order matters
|
||||||
setup("/dev/stdin", new Devices::NopDevice(0)); // stdin
|
setup("/dev/stdin", new Devices::Logger("stdin", false)); // stdin
|
||||||
setup("/dev/stdout", new Devices::Logger("stdout", false)); // stdout
|
setup("/dev/stdout", new Devices::Logger("stdout", false)); // stdout
|
||||||
setup("/dev/stderr", new Devices::Logger("stderr", true)); // stderr
|
setup("/dev/stderr", new Devices::Logger("stderr", true)); // stderr
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,13 @@
|
|||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/scope_exit.h"
|
#include "common/scope_exit.h"
|
||||||
#include "common/singleton.h"
|
#include "common/singleton.h"
|
||||||
|
#include "core/devices/console_device.h"
|
||||||
|
#include "core/devices/deci_tty6_device.h"
|
||||||
#include "core/devices/logger.h"
|
#include "core/devices/logger.h"
|
||||||
#include "core/devices/nop_device.h"
|
#include "core/devices/nop_device.h"
|
||||||
|
#include "core/devices/random_device.h"
|
||||||
|
#include "core/devices/srandom_device.h"
|
||||||
|
#include "core/devices/urandom_device.h"
|
||||||
#include "core/file_sys/fs.h"
|
#include "core/file_sys/fs.h"
|
||||||
#include "core/libraries/kernel/file_system.h"
|
#include "core/libraries/kernel/file_system.h"
|
||||||
#include "core/libraries/kernel/orbis_error.h"
|
#include "core/libraries/kernel/orbis_error.h"
|
||||||
@ -41,6 +46,12 @@ static std::map<std::string, FactoryDevice> available_device = {
|
|||||||
{"/dev/deci_stderr", GET_DEVICE_FD(2)},
|
{"/dev/deci_stderr", GET_DEVICE_FD(2)},
|
||||||
|
|
||||||
{"/dev/null", GET_DEVICE_FD(0)}, // fd0 (stdin) is a nop device
|
{"/dev/null", GET_DEVICE_FD(0)}, // fd0 (stdin) is a nop device
|
||||||
|
|
||||||
|
{"/dev/urandom", &D::URandomDevice::Create },
|
||||||
|
{"/dev/random", &D::RandomDevice::Create },
|
||||||
|
{"/dev/srandom", &D::SRandomDevice::Create },
|
||||||
|
{"/dev/console", &D::ConsoleDevice::Create },
|
||||||
|
{"/dev/deci_tty6",&D::DeciTty6Device::Create }
|
||||||
// clang-format on
|
// clang-format on
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -67,17 +78,6 @@ int PS4_SYSV_ABI sceKernelOpen(const char* raw_path, int flags, u16 mode) {
|
|||||||
bool directory = (flags & ORBIS_KERNEL_O_DIRECTORY) != 0;
|
bool directory = (flags & ORBIS_KERNEL_O_DIRECTORY) != 0;
|
||||||
|
|
||||||
std::string_view path{raw_path};
|
std::string_view path{raw_path};
|
||||||
|
|
||||||
if (path == "/dev/console") {
|
|
||||||
return 2000;
|
|
||||||
}
|
|
||||||
if (path == "/dev/deci_tty6") {
|
|
||||||
return 2001;
|
|
||||||
}
|
|
||||||
if (path == "/dev/urandom") {
|
|
||||||
return 2003;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 handle = h->CreateHandle();
|
u32 handle = h->CreateHandle();
|
||||||
auto* file = h->GetFile(handle);
|
auto* file = h->GetFile(handle);
|
||||||
|
|
||||||
@ -167,9 +167,6 @@ int PS4_SYSV_ABI sceKernelClose(int d) {
|
|||||||
if (d < 3) { // d probably hold an error code
|
if (d < 3) { // d probably hold an error code
|
||||||
return ORBIS_KERNEL_ERROR_EPERM;
|
return ORBIS_KERNEL_ERROR_EPERM;
|
||||||
}
|
}
|
||||||
if (d == 2003) { // dev/urandom case
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
auto* file = h->GetFile(d);
|
auto* file = h->GetFile(d);
|
||||||
if (file == nullptr) {
|
if (file == nullptr) {
|
||||||
@ -273,13 +270,6 @@ size_t PS4_SYSV_ABI _readv(int d, const SceKernelIovec* iov, int iovcnt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t PS4_SYSV_ABI _writev(int fd, const SceKernelIovec* iov, int iovcn) {
|
size_t PS4_SYSV_ABI _writev(int fd, const SceKernelIovec* iov, int iovcn) {
|
||||||
if (fd == 1) {
|
|
||||||
size_t total_written = 0;
|
|
||||||
for (int i = 0; i < iovcn; i++) {
|
|
||||||
total_written += ::fwrite(iov[i].iov_base, 1, iov[i].iov_len, stdout);
|
|
||||||
}
|
|
||||||
return total_written;
|
|
||||||
}
|
|
||||||
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
auto* file = h->GetFile(fd);
|
auto* file = h->GetFile(fd);
|
||||||
if (file == nullptr) {
|
if (file == nullptr) {
|
||||||
@ -337,13 +327,6 @@ s64 PS4_SYSV_ABI posix_lseek(int d, s64 offset, int whence) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s64 PS4_SYSV_ABI sceKernelRead(int d, void* buf, size_t nbytes) {
|
s64 PS4_SYSV_ABI sceKernelRead(int d, void* buf, size_t nbytes) {
|
||||||
if (d == 2003) // dev urandom case
|
|
||||||
{
|
|
||||||
auto rbuf = static_cast<char*>(buf);
|
|
||||||
for (size_t i = 0; i < nbytes; i++)
|
|
||||||
rbuf[i] = std::rand() & 0xFF;
|
|
||||||
return nbytes;
|
|
||||||
}
|
|
||||||
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
auto* file = h->GetFile(d);
|
auto* file = h->GetFile(d);
|
||||||
if (file == nullptr) {
|
if (file == nullptr) {
|
||||||
@ -757,7 +740,6 @@ s32 PS4_SYSV_ABI sceKernelRename(const char* from, const char* to) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RegisterFileSystem(Core::Loader::SymbolsResolver* sym) {
|
void RegisterFileSystem(Core::Loader::SymbolsResolver* sym) {
|
||||||
std::srand(std::time(nullptr));
|
|
||||||
LIB_FUNCTION("1G3lF1Gg1k8", "libkernel", 1, "libkernel", 1, 1, sceKernelOpen);
|
LIB_FUNCTION("1G3lF1Gg1k8", "libkernel", 1, "libkernel", 1, 1, sceKernelOpen);
|
||||||
LIB_FUNCTION("wuCroIGjt2g", "libScePosix", 1, "libkernel", 1, 1, posix_open);
|
LIB_FUNCTION("wuCroIGjt2g", "libScePosix", 1, "libkernel", 1, 1, posix_open);
|
||||||
LIB_FUNCTION("wuCroIGjt2g", "libkernel", 1, "libkernel", 1, 1, open);
|
LIB_FUNCTION("wuCroIGjt2g", "libkernel", 1, "libkernel", 1, 1, open);
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
#include "core/libraries/np_manager/np_manager.h"
|
#include "core/libraries/np_manager/np_manager.h"
|
||||||
|
#include "core/libraries/np_manager/np_manager_error.h"
|
||||||
#include "core/tls.h"
|
#include "core/tls.h"
|
||||||
|
|
||||||
namespace Libraries::NpManager {
|
namespace Libraries::NpManager {
|
||||||
@ -935,14 +936,22 @@ int PS4_SYSV_ABI sceNpGetAccountDateOfBirthA() {
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNpGetAccountId() {
|
int PS4_SYSV_ABI sceNpGetAccountId(OrbisNpOnlineId* online_id, u64* account_id) {
|
||||||
LOG_ERROR(Lib_NpManager, "(STUBBED) called");
|
LOG_DEBUG(Lib_NpManager, "called");
|
||||||
return ORBIS_OK;
|
if (online_id == nullptr || account_id == nullptr) {
|
||||||
|
return ORBIS_NP_ERROR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
*account_id = 0;
|
||||||
|
return ORBIS_NP_ERROR_SIGNED_OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNpGetAccountIdA() {
|
int PS4_SYSV_ABI sceNpGetAccountIdA(OrbisUserServiceUserId user_id, u64* account_id) {
|
||||||
LOG_ERROR(Lib_NpManager, "(STUBBED) called");
|
LOG_DEBUG(Lib_NpManager, "user_id {}", user_id);
|
||||||
return ORBIS_OK;
|
if (account_id == nullptr) {
|
||||||
|
return ORBIS_NP_ERROR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
*account_id = 0;
|
||||||
|
return ORBIS_NP_ERROR_SIGNED_OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNpGetAccountLanguage() {
|
int PS4_SYSV_ABI sceNpGetAccountLanguage() {
|
||||||
@ -972,6 +981,9 @@ int PS4_SYSV_ABI sceNpGetGamePresenceStatusA() {
|
|||||||
|
|
||||||
int PS4_SYSV_ABI sceNpGetNpId(OrbisUserServiceUserId user_id, OrbisNpId* np_id) {
|
int PS4_SYSV_ABI sceNpGetNpId(OrbisUserServiceUserId user_id, OrbisNpId* np_id) {
|
||||||
LOG_DEBUG(Lib_NpManager, "user_id {}", user_id);
|
LOG_DEBUG(Lib_NpManager, "user_id {}", user_id);
|
||||||
|
if (np_id == nullptr) {
|
||||||
|
return ORBIS_NP_ERROR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
return ORBIS_NP_ERROR_SIGNED_OUT;
|
return ORBIS_NP_ERROR_SIGNED_OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -980,8 +992,11 @@ int PS4_SYSV_ABI sceNpGetNpReachabilityState() {
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNpGetOnlineId(s32 user_id, OrbisNpOnlineId* online_id) {
|
int PS4_SYSV_ABI sceNpGetOnlineId(OrbisUserServiceUserId user_id, OrbisNpOnlineId* online_id) {
|
||||||
LOG_DEBUG(Lib_NpManager, "user_id {}", user_id);
|
LOG_DEBUG(Lib_NpManager, "user_id {}", user_id);
|
||||||
|
if (online_id == nullptr) {
|
||||||
|
return ORBIS_NP_ERROR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
return ORBIS_NP_ERROR_SIGNED_OUT;
|
return ORBIS_NP_ERROR_SIGNED_OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -995,7 +1010,10 @@ int PS4_SYSV_ABI sceNpGetParentalControlInfoA() {
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNpGetState(s32 userId, OrbisNpState* state) {
|
int PS4_SYSV_ABI sceNpGetState(OrbisUserServiceUserId user_id, OrbisNpState* state) {
|
||||||
|
if (state == nullptr) {
|
||||||
|
return ORBIS_NP_ERROR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
*state = OrbisNpState::SignedOut;
|
*state = OrbisNpState::SignedOut;
|
||||||
LOG_DEBUG(Lib_NpManager, "Signed out");
|
LOG_DEBUG(Lib_NpManager, "Signed out");
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
@ -1011,8 +1029,12 @@ int PS4_SYSV_ABI sceNpGetUserIdByOnlineId() {
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNpHasSignedUp() {
|
int PS4_SYSV_ABI sceNpHasSignedUp(OrbisUserServiceUserId user_id, bool* has_signed_up) {
|
||||||
LOG_ERROR(Lib_NpManager, "(STUBBED) called");
|
LOG_DEBUG(Lib_NpManager, "called");
|
||||||
|
if (has_signed_up == nullptr) {
|
||||||
|
return ORBIS_NP_ERROR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
*has_signed_up = false;
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,8 +11,6 @@ class SymbolsResolver;
|
|||||||
|
|
||||||
namespace Libraries::NpManager {
|
namespace Libraries::NpManager {
|
||||||
|
|
||||||
constexpr int ORBIS_NP_ERROR_SIGNED_OUT = 0x80550006;
|
|
||||||
|
|
||||||
enum class OrbisNpState : u32 { Unknown = 0, SignedOut, SignedIn };
|
enum class OrbisNpState : u32 { Unknown = 0, SignedOut, SignedIn };
|
||||||
|
|
||||||
using OrbisNpStateCallbackForNpToolkit = PS4_SYSV_ABI void (*)(s32 userId, OrbisNpState state,
|
using OrbisNpStateCallbackForNpToolkit = PS4_SYSV_ABI void (*)(s32 userId, OrbisNpState state,
|
||||||
@ -220,22 +218,22 @@ int PS4_SYSV_ABI sceNpGetAccountCountry();
|
|||||||
int PS4_SYSV_ABI sceNpGetAccountCountryA();
|
int PS4_SYSV_ABI sceNpGetAccountCountryA();
|
||||||
int PS4_SYSV_ABI sceNpGetAccountDateOfBirth();
|
int PS4_SYSV_ABI sceNpGetAccountDateOfBirth();
|
||||||
int PS4_SYSV_ABI sceNpGetAccountDateOfBirthA();
|
int PS4_SYSV_ABI sceNpGetAccountDateOfBirthA();
|
||||||
int PS4_SYSV_ABI sceNpGetAccountId();
|
int PS4_SYSV_ABI sceNpGetAccountId(OrbisNpOnlineId* online_id, u64* account_id);
|
||||||
int PS4_SYSV_ABI sceNpGetAccountIdA();
|
int PS4_SYSV_ABI sceNpGetAccountIdA(OrbisUserServiceUserId user_id, u64* account_id);
|
||||||
int PS4_SYSV_ABI sceNpGetAccountLanguage();
|
int PS4_SYSV_ABI sceNpGetAccountLanguage();
|
||||||
int PS4_SYSV_ABI sceNpGetAccountLanguage2();
|
int PS4_SYSV_ABI sceNpGetAccountLanguage2();
|
||||||
int PS4_SYSV_ABI sceNpGetAccountLanguageA();
|
int PS4_SYSV_ABI sceNpGetAccountLanguageA();
|
||||||
int PS4_SYSV_ABI sceNpGetGamePresenceStatus();
|
int PS4_SYSV_ABI sceNpGetGamePresenceStatus();
|
||||||
int PS4_SYSV_ABI sceNpGetGamePresenceStatusA();
|
int PS4_SYSV_ABI sceNpGetGamePresenceStatusA();
|
||||||
int PS4_SYSV_ABI sceNpGetNpId(OrbisUserServiceUserId userId, OrbisNpId* npId);
|
int PS4_SYSV_ABI sceNpGetNpId(OrbisUserServiceUserId user_id, OrbisNpId* np_id);
|
||||||
int PS4_SYSV_ABI sceNpGetNpReachabilityState();
|
int PS4_SYSV_ABI sceNpGetNpReachabilityState();
|
||||||
int PS4_SYSV_ABI sceNpGetOnlineId(s32 userId, OrbisNpOnlineId* onlineId);
|
int PS4_SYSV_ABI sceNpGetOnlineId(OrbisUserServiceUserId user_id, OrbisNpOnlineId* online_id);
|
||||||
int PS4_SYSV_ABI sceNpGetParentalControlInfo();
|
int PS4_SYSV_ABI sceNpGetParentalControlInfo();
|
||||||
int PS4_SYSV_ABI sceNpGetParentalControlInfoA();
|
int PS4_SYSV_ABI sceNpGetParentalControlInfoA();
|
||||||
int PS4_SYSV_ABI sceNpGetState(s32 userId, OrbisNpState* state);
|
int PS4_SYSV_ABI sceNpGetState(OrbisUserServiceUserId user_id, OrbisNpState* state);
|
||||||
int PS4_SYSV_ABI sceNpGetUserIdByAccountId();
|
int PS4_SYSV_ABI sceNpGetUserIdByAccountId();
|
||||||
int PS4_SYSV_ABI sceNpGetUserIdByOnlineId();
|
int PS4_SYSV_ABI sceNpGetUserIdByOnlineId();
|
||||||
int PS4_SYSV_ABI sceNpHasSignedUp();
|
int PS4_SYSV_ABI sceNpHasSignedUp(OrbisUserServiceUserId user_id, bool* has_signed_up);
|
||||||
int PS4_SYSV_ABI sceNpIdMapperAbortRequest();
|
int PS4_SYSV_ABI sceNpIdMapperAbortRequest();
|
||||||
int PS4_SYSV_ABI sceNpIdMapperAccountIdToNpId();
|
int PS4_SYSV_ABI sceNpIdMapperAccountIdToNpId();
|
||||||
int PS4_SYSV_ABI sceNpIdMapperAccountIdToOnlineId();
|
int PS4_SYSV_ABI sceNpIdMapperAccountIdToOnlineId();
|
||||||
|
9
src/core/libraries/np_manager/np_manager_error.h
Normal file
9
src/core/libraries/np_manager/np_manager_error.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/libraries/error_codes.h"
|
||||||
|
|
||||||
|
constexpr int ORBIS_NP_ERROR_INVALID_ARGUMENT = 0x80550003;
|
||||||
|
constexpr int ORBIS_NP_ERROR_SIGNED_OUT = 0x80550006;
|
@ -47,15 +47,13 @@ namespace Libraries::SaveData {
|
|||||||
|
|
||||||
std::filesystem::path SaveInstance::MakeTitleSavePath(OrbisUserServiceUserId user_id,
|
std::filesystem::path SaveInstance::MakeTitleSavePath(OrbisUserServiceUserId user_id,
|
||||||
std::string_view game_serial) {
|
std::string_view game_serial) {
|
||||||
return Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) / std::to_string(user_id) /
|
return Config::GetSaveDataPath() / std::to_string(user_id) / game_serial;
|
||||||
game_serial;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::filesystem::path SaveInstance::MakeDirSavePath(OrbisUserServiceUserId user_id,
|
std::filesystem::path SaveInstance::MakeDirSavePath(OrbisUserServiceUserId user_id,
|
||||||
std::string_view game_serial,
|
std::string_view game_serial,
|
||||||
std::string_view dir_name) {
|
std::string_view dir_name) {
|
||||||
return Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) / std::to_string(user_id) /
|
return Config::GetSaveDataPath() / std::to_string(user_id) / game_serial / dir_name;
|
||||||
game_serial / dir_name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t SaveInstance::GetMaxBlockFromSFO(const PSF& psf) {
|
uint64_t SaveInstance::GetMaxBlockFromSFO(const PSF& psf) {
|
||||||
|
@ -205,6 +205,21 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices,
|
|||||||
delete selected_item;
|
delete selected_item;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
connect(ui->browseButton, &QPushButton::clicked, this, [this]() {
|
||||||
|
const auto save_data_path = Config::GetSaveDataPath();
|
||||||
|
QString initial_path;
|
||||||
|
Common::FS::PathToQString(initial_path, save_data_path);
|
||||||
|
|
||||||
|
QString save_data_path_string =
|
||||||
|
QFileDialog::getExistingDirectory(this, tr("Directory to save data"), initial_path);
|
||||||
|
|
||||||
|
auto file_path = Common::FS::PathFromQString(save_data_path_string);
|
||||||
|
if (!file_path.empty()) {
|
||||||
|
Config::setSaveDataPath(file_path);
|
||||||
|
ui->currentSaveDataPath->setText(save_data_path_string);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// DEBUG TAB
|
// DEBUG TAB
|
||||||
@ -260,6 +275,10 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices,
|
|||||||
ui->addFolderButton->installEventFilter(this);
|
ui->addFolderButton->installEventFilter(this);
|
||||||
ui->removeFolderButton->installEventFilter(this);
|
ui->removeFolderButton->installEventFilter(this);
|
||||||
|
|
||||||
|
ui->saveDataGroupBox->installEventFilter(this);
|
||||||
|
ui->currentSaveDataPath->installEventFilter(this);
|
||||||
|
ui->browseButton->installEventFilter(this);
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
ui->debugDump->installEventFilter(this);
|
ui->debugDump->installEventFilter(this);
|
||||||
ui->vkValidationCheckBox->installEventFilter(this);
|
ui->vkValidationCheckBox->installEventFilter(this);
|
||||||
@ -290,6 +309,11 @@ void SettingsDialog::LoadValuesFromConfig() {
|
|||||||
const QVector<int> languageIndexes = {21, 23, 14, 6, 18, 1, 12, 22, 2, 4, 25, 24, 29, 5, 0, 9,
|
const QVector<int> languageIndexes = {21, 23, 14, 6, 18, 1, 12, 22, 2, 4, 25, 24, 29, 5, 0, 9,
|
||||||
15, 16, 17, 7, 26, 8, 11, 20, 3, 13, 27, 10, 19, 30, 28};
|
15, 16, 17, 7, 26, 8, 11, 20, 3, 13, 27, 10, 19, 30, 28};
|
||||||
|
|
||||||
|
const auto save_data_path = Config::GetSaveDataPath();
|
||||||
|
QString save_data_path_string;
|
||||||
|
Common::FS::PathToQString(save_data_path_string, save_data_path);
|
||||||
|
ui->currentSaveDataPath->setText(save_data_path_string);
|
||||||
|
|
||||||
ui->consoleLanguageComboBox->setCurrentIndex(
|
ui->consoleLanguageComboBox->setCurrentIndex(
|
||||||
std::distance(languageIndexes.begin(),
|
std::distance(languageIndexes.begin(),
|
||||||
std::find(languageIndexes.begin(), languageIndexes.end(),
|
std::find(languageIndexes.begin(), languageIndexes.end(),
|
||||||
@ -507,6 +531,13 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) {
|
|||||||
text = tr("removeFolderButton");
|
text = tr("removeFolderButton");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save Data
|
||||||
|
if (elementName == "saveDataGroupBox" || elementName == "currentSaveDataPath") {
|
||||||
|
text = tr("saveDataBox");
|
||||||
|
} else if (elementName == "browseButton") {
|
||||||
|
text = tr("browseButton");
|
||||||
|
}
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
if (elementName == "debugDump") {
|
if (elementName == "debugDump") {
|
||||||
text = tr("debugDump");
|
text = tr("debugDump");
|
||||||
@ -624,4 +655,4 @@ void SettingsDialog::ResetInstallFolders() {
|
|||||||
}
|
}
|
||||||
Config::setGameInstallDirs(settings_install_dirs_config);
|
Config::setGameInstallDirs(settings_install_dirs_config);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -53,7 +53,7 @@
|
|||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>3</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QScrollArea" name="generalTab">
|
<widget class="QScrollArea" name="generalTab">
|
||||||
<property name="widgetResizable">
|
<property name="widgetResizable">
|
||||||
@ -1256,41 +1256,74 @@
|
|||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="pathsTabLayout" stretch="0">
|
<layout class="QVBoxLayout" name="pathsTabLayout" stretch="0">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="pathsTabVLayout">
|
<widget class="QGroupBox" name="gameFoldersGroupBox">
|
||||||
<item>
|
<property name="title">
|
||||||
<widget class="QGroupBox" name="gameFoldersGroupBox">
|
<string>Game Folders</string>
|
||||||
<property name="title">
|
</property>
|
||||||
<string>Game Folders</string>
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
</property>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="addFolderButton">
|
<widget class="QPushButton" name="addFolderButton">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Add...</string>
|
<string>Add...</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="removeFolderButton">
|
<widget class="QPushButton" name="removeFolderButton">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Remove</string>
|
<string>Remove</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
<item>
|
||||||
</item>
|
<spacer name="horizontalSpacer">
|
||||||
<item>
|
<property name="orientation">
|
||||||
<widget class="QListWidget" name="gameFoldersListWidget"/>
|
<enum>Qt::Horizontal</enum>
|
||||||
</item>
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</item>
|
||||||
</item>
|
<item>
|
||||||
</layout>
|
<widget class="QListWidget" name="gameFoldersListWidget"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="saveDataGroupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Save Data Path</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="saveDataLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="currentSaveDataPath">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="browseButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Browse</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -912,6 +912,14 @@
|
|||||||
<source>rdocCheckBox</source>
|
<source>rdocCheckBox</source>
|
||||||
<translation>Enable RenderDoc Debugging:\nIf enabled, the emulator will provide compatibility with Renderdoc to allow capture and analysis of the currently rendered frame.</translation>
|
<translation>Enable RenderDoc Debugging:\nIf enabled, the emulator will provide compatibility with Renderdoc to allow capture and analysis of the currently rendered frame.</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>saveDataBox</source>
|
||||||
|
<translation>Save Data Path:\nThe folder where game save data will be saved.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>browseButton</source>
|
||||||
|
<translation>Browse:\nBrowse for a folder to set as the save data path.</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheatsPatches</name>
|
<name>CheatsPatches</name>
|
||||||
|
@ -3420,8 +3420,8 @@ constexpr std::array<InstFormat, 112> InstructionFormatMIMG = {{
|
|||||||
{InstClass::VectorMemImgUt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
{InstClass::VectorMemImgUt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||||
ScalarType::Uint32},
|
ScalarType::Uint32},
|
||||||
// 15 = IMAGE_ATOMIC_SWAP
|
// 15 = IMAGE_ATOMIC_SWAP
|
||||||
{InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined,
|
{InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||||
ScalarType::Undefined},
|
ScalarType::Uint32},
|
||||||
// 16 = IMAGE_ATOMIC_CMPSWAP
|
// 16 = IMAGE_ATOMIC_CMPSWAP
|
||||||
{InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined,
|
{InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined,
|
||||||
ScalarType::Undefined},
|
ScalarType::Undefined},
|
||||||
|
@ -107,6 +107,8 @@ void Translator::EmitVectorMemory(const GcnInst& inst) {
|
|||||||
return IMAGE_GET_RESINFO(inst);
|
return IMAGE_GET_RESINFO(inst);
|
||||||
|
|
||||||
// Image atomic operations
|
// Image atomic operations
|
||||||
|
case Opcode::IMAGE_ATOMIC_SWAP:
|
||||||
|
return IMAGE_ATOMIC(AtomicOp::Swap, inst);
|
||||||
case Opcode::IMAGE_ATOMIC_ADD:
|
case Opcode::IMAGE_ATOMIC_ADD:
|
||||||
return IMAGE_ATOMIC(AtomicOp::Add, inst);
|
return IMAGE_ATOMIC(AtomicOp::Add, inst);
|
||||||
case Opcode::IMAGE_ATOMIC_SMIN:
|
case Opcode::IMAGE_ATOMIC_SMIN:
|
||||||
|
@ -283,8 +283,7 @@ inline CompMapping RemapSwizzle(const DataFormat format, const CompMapping swizz
|
|||||||
result.a = swizzle.a;
|
result.a = swizzle.a;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
case DataFormat::Format10_10_10_2:
|
case DataFormat::Format10_10_10_2: {
|
||||||
case DataFormat::Format5_5_5_1: {
|
|
||||||
CompMapping result;
|
CompMapping result;
|
||||||
result.r = swizzle.a;
|
result.r = swizzle.a;
|
||||||
result.g = swizzle.b;
|
result.g = swizzle.b;
|
||||||
@ -292,6 +291,14 @@ inline CompMapping RemapSwizzle(const DataFormat format, const CompMapping swizz
|
|||||||
result.a = swizzle.r;
|
result.a = swizzle.r;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
case DataFormat::Format1_5_5_5: {
|
||||||
|
CompMapping result;
|
||||||
|
result.r = swizzle.b;
|
||||||
|
result.g = swizzle.g;
|
||||||
|
result.b = swizzle.r;
|
||||||
|
result.a = swizzle.a;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return swizzle;
|
return swizzle;
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,6 @@ void BufferCache::InlineData(VAddr address, const void* value, u32 num_bytes, bo
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
scheduler.EndRendering();
|
scheduler.EndRendering();
|
||||||
const auto cmdbuf = scheduler.CommandBuffer();
|
|
||||||
const Buffer* buffer = [&] {
|
const Buffer* buffer = [&] {
|
||||||
if (is_gds) {
|
if (is_gds) {
|
||||||
return &gds_buffer;
|
return &gds_buffer;
|
||||||
@ -218,6 +217,7 @@ void BufferCache::InlineData(VAddr address, const void* value, u32 num_bytes, bo
|
|||||||
const BufferId buffer_id = FindBuffer(address, num_bytes);
|
const BufferId buffer_id = FindBuffer(address, num_bytes);
|
||||||
return &slot_buffers[buffer_id];
|
return &slot_buffers[buffer_id];
|
||||||
}();
|
}();
|
||||||
|
const auto cmdbuf = scheduler.CommandBuffer();
|
||||||
const vk::BufferMemoryBarrier2 pre_barrier = {
|
const vk::BufferMemoryBarrier2 pre_barrier = {
|
||||||
.srcStageMask = vk::PipelineStageFlagBits2::eAllCommands,
|
.srcStageMask = vk::PipelineStageFlagBits2::eAllCommands,
|
||||||
.srcAccessMask = vk::AccessFlagBits2::eMemoryRead,
|
.srcAccessMask = vk::AccessFlagBits2::eMemoryRead,
|
||||||
|
@ -612,11 +612,13 @@ std::span<const SurfaceFormatInfo> SurfaceFormats() {
|
|||||||
vk::Format::eB5G6R5UnormPack16),
|
vk::Format::eB5G6R5UnormPack16),
|
||||||
// 1_5_5_5
|
// 1_5_5_5
|
||||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format1_5_5_5, AmdGpu::NumberFormat::Unorm,
|
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format1_5_5_5, AmdGpu::NumberFormat::Unorm,
|
||||||
|
vk::Format::eA1R5G5B5UnormPack16),
|
||||||
|
// 5_5_5_1
|
||||||
|
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format5_5_5_1, AmdGpu::NumberFormat::Unorm,
|
||||||
vk::Format::eR5G5B5A1UnormPack16),
|
vk::Format::eR5G5B5A1UnormPack16),
|
||||||
// 5_5_5_1 - Remapped to 1_5_5_5.
|
|
||||||
// 4_4_4_4
|
// 4_4_4_4
|
||||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format4_4_4_4, AmdGpu::NumberFormat::Unorm,
|
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format4_4_4_4, AmdGpu::NumberFormat::Unorm,
|
||||||
vk::Format::eR4G4B4A4UnormPack16),
|
vk::Format::eA4B4G4R4UnormPack16),
|
||||||
// 8_24
|
// 8_24
|
||||||
// 24_8
|
// 24_8
|
||||||
// X24_8_32
|
// X24_8_32
|
||||||
|
@ -283,6 +283,7 @@ bool Instance::CreateDevice() {
|
|||||||
add_extension(VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME);
|
add_extension(VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME);
|
||||||
add_extension(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
|
add_extension(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
|
||||||
add_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
|
add_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
|
||||||
|
add_extension(VK_EXT_4444_FORMATS_EXTENSION_NAME);
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
// Required by Vulkan spec if supported.
|
// Required by Vulkan spec if supported.
|
||||||
|
@ -28,19 +28,19 @@ static const char* const VALIDATION_LAYER_NAME = "VK_LAYER_KHRONOS_validation";
|
|||||||
static const char* const CRASH_DIAGNOSTIC_LAYER_NAME = "VK_LAYER_LUNARG_crash_diagnostic";
|
static const char* const CRASH_DIAGNOSTIC_LAYER_NAME = "VK_LAYER_LUNARG_crash_diagnostic";
|
||||||
|
|
||||||
static VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsCallback(
|
static VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsCallback(
|
||||||
VkDebugUtilsMessageSeverityFlagBitsEXT severity, VkDebugUtilsMessageTypeFlagsEXT type,
|
vk::DebugUtilsMessageSeverityFlagBitsEXT severity, vk::DebugUtilsMessageTypeFlagsEXT type,
|
||||||
const VkDebugUtilsMessengerCallbackDataEXT* callback_data, void* user_data) {
|
const vk::DebugUtilsMessengerCallbackDataEXT* callback_data, void* user_data) {
|
||||||
|
|
||||||
Common::Log::Level level{};
|
Common::Log::Level level{};
|
||||||
switch (severity) {
|
switch (severity) {
|
||||||
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
|
case vk::DebugUtilsMessageSeverityFlagBitsEXT::eError:
|
||||||
level = Common::Log::Level::Error;
|
level = Common::Log::Level::Error;
|
||||||
break;
|
break;
|
||||||
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
|
case vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning:
|
||||||
level = Common::Log::Level::Info;
|
level = Common::Log::Level::Info;
|
||||||
break;
|
break;
|
||||||
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT:
|
case vk::DebugUtilsMessageSeverityFlagBitsEXT::eInfo:
|
||||||
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT:
|
case vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose:
|
||||||
level = Common::Log::Level::Debug;
|
level = Common::Log::Level::Debug;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -825,6 +825,9 @@ void Presenter::Present(Frame* frame, bool is_reusing_frame) {
|
|||||||
|
|
||||||
{ // Draw the game
|
{ // Draw the game
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{0.0f});
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{0.0f});
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||||
ImGui::SetNextWindowDockID(dockId, ImGuiCond_Once);
|
ImGui::SetNextWindowDockID(dockId, ImGuiCond_Once);
|
||||||
ImGui::Begin("Display##game_display", nullptr, ImGuiWindowFlags_NoNav);
|
ImGui::Begin("Display##game_display", nullptr, ImGuiWindowFlags_NoNav);
|
||||||
|
|
||||||
@ -840,7 +843,8 @@ void Presenter::Present(Frame* frame, bool is_reusing_frame) {
|
|||||||
static_cast<float>(imgRect.extent.height),
|
static_cast<float>(imgRect.extent.height),
|
||||||
});
|
});
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar(3);
|
||||||
|
ImGui::PopStyleColor();
|
||||||
}
|
}
|
||||||
ImGui::Core::Render(cmdbuf, swapchain_image_view, swapchain.GetExtent());
|
ImGui::Core::Render(cmdbuf, swapchain_image_view, swapchain.GetExtent());
|
||||||
|
|
||||||
|
@ -166,6 +166,7 @@ void ImageInfo::UpdateSize() {
|
|||||||
mip_w = std::max(mip_w, 1u);
|
mip_w = std::max(mip_w, 1u);
|
||||||
mip_h = std::max(mip_h, 1u);
|
mip_h = std::max(mip_h, 1u);
|
||||||
auto mip_d = std::max(size.depth >> mip, 1u);
|
auto mip_d = std::max(size.depth >> mip, 1u);
|
||||||
|
auto thickness = 1;
|
||||||
|
|
||||||
if (props.is_pow2) {
|
if (props.is_pow2) {
|
||||||
mip_w = std::bit_ceil(mip_w);
|
mip_w = std::bit_ceil(mip_w);
|
||||||
@ -177,35 +178,35 @@ void ImageInfo::UpdateSize() {
|
|||||||
case AmdGpu::TilingMode::Display_Linear: {
|
case AmdGpu::TilingMode::Display_Linear: {
|
||||||
std::tie(mip_info.pitch, mip_info.size) =
|
std::tie(mip_info.pitch, mip_info.size) =
|
||||||
ImageSizeLinearAligned(mip_w, mip_h, bpp, num_samples);
|
ImageSizeLinearAligned(mip_w, mip_h, bpp, num_samples);
|
||||||
mip_info.height = mip_h;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AmdGpu::TilingMode::Texture_Volume:
|
case AmdGpu::TilingMode::Texture_Volume:
|
||||||
mip_d += (-mip_d) & 3u;
|
thickness = 4;
|
||||||
|
mip_d += (-mip_d) & (thickness - 1);
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case AmdGpu::TilingMode::Display_MicroTiled:
|
case AmdGpu::TilingMode::Display_MicroTiled:
|
||||||
case AmdGpu::TilingMode::Texture_MicroTiled: {
|
case AmdGpu::TilingMode::Texture_MicroTiled: {
|
||||||
std::tie(mip_info.pitch, mip_info.size) =
|
std::tie(mip_info.pitch, mip_info.size) =
|
||||||
ImageSizeMicroTiled(mip_w, mip_h, bpp, num_samples);
|
ImageSizeMicroTiled(mip_w, mip_h, thickness, bpp, num_samples);
|
||||||
mip_info.height = std::max(mip_h, 8u);
|
|
||||||
if (props.is_block) {
|
|
||||||
mip_info.pitch = std::max(mip_info.pitch * 4, 32u);
|
|
||||||
mip_info.height = std::max(mip_info.height * 4, 32u);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AmdGpu::TilingMode::Display_MacroTiled:
|
case AmdGpu::TilingMode::Display_MacroTiled:
|
||||||
case AmdGpu::TilingMode::Texture_MacroTiled:
|
case AmdGpu::TilingMode::Texture_MacroTiled:
|
||||||
case AmdGpu::TilingMode::Depth_MacroTiled: {
|
case AmdGpu::TilingMode::Depth_MacroTiled: {
|
||||||
ASSERT(!props.is_block);
|
ASSERT(!props.is_block);
|
||||||
std::tie(mip_info.pitch, mip_info.size) =
|
std::tie(mip_info.pitch, mip_info.size) = ImageSizeMacroTiled(
|
||||||
ImageSizeMacroTiled(mip_w, mip_h, bpp, num_samples, tiling_idx, mip, alt_tile);
|
mip_w, mip_h, thickness, bpp, num_samples, tiling_idx, mip, alt_tile);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mip_info.height = mip_h;
|
||||||
|
if (props.is_block) {
|
||||||
|
mip_info.pitch = std::max(mip_info.pitch * 4, 32u);
|
||||||
|
mip_info.height = std::max(mip_info.height * 4, 32u);
|
||||||
|
}
|
||||||
mip_info.size *= mip_d;
|
mip_info.size *= mip_d;
|
||||||
mip_info.offset = guest_size;
|
mip_info.offset = guest_size;
|
||||||
mips_layout.emplace_back(mip_info);
|
mips_layout.emplace_back(mip_info);
|
||||||
|
@ -60,15 +60,13 @@ void TextureCache::MarkAsMaybeDirty(ImageId image_id, Image& image) {
|
|||||||
|
|
||||||
void TextureCache::InvalidateMemory(VAddr addr, size_t size) {
|
void TextureCache::InvalidateMemory(VAddr addr, size_t size) {
|
||||||
std::scoped_lock lock{mutex};
|
std::scoped_lock lock{mutex};
|
||||||
const auto end = addr + size;
|
|
||||||
const auto pages_start = PageManager::GetPageAddr(addr);
|
const auto pages_start = PageManager::GetPageAddr(addr);
|
||||||
const auto pages_end = PageManager::GetNextPageAddr(addr + size - 1);
|
const auto pages_end = PageManager::GetNextPageAddr(addr + size - 1);
|
||||||
ForEachImageInRegion(pages_start, pages_end - pages_start, [&](ImageId image_id, Image& image) {
|
ForEachImageInRegion(pages_start, pages_end - pages_start, [&](ImageId image_id, Image& image) {
|
||||||
const auto image_begin = image.info.guest_address;
|
const auto image_begin = image.info.guest_address;
|
||||||
const auto image_end = image.info.guest_address + image.info.guest_size;
|
const auto image_end = image.info.guest_address + image.info.guest_size;
|
||||||
if (image_begin < end && addr < image_end) {
|
if (image.Overlaps(addr, size)) {
|
||||||
// Start or end of the modified region is in the image, or the image is entirely within
|
// Modified region overlaps image, so the image was definitely accessed by this fault.
|
||||||
// the modified region, so the image was definitely accessed by this page fault.
|
|
||||||
// Untrack the image, so that the range is unprotected and the guest can write freely.
|
// Untrack the image, so that the range is unprotected and the guest can write freely.
|
||||||
image.flags |= ImageFlagBits::CpuDirty;
|
image.flags |= ImageFlagBits::CpuDirty;
|
||||||
UntrackImage(image_id);
|
UntrackImage(image_id);
|
||||||
@ -545,12 +543,12 @@ void TextureCache::RefreshImage(Image& image, Vulkan::Scheduler* custom_schedule
|
|||||||
auto* sched_ptr = custom_scheduler ? custom_scheduler : &scheduler;
|
auto* sched_ptr = custom_scheduler ? custom_scheduler : &scheduler;
|
||||||
sched_ptr->EndRendering();
|
sched_ptr->EndRendering();
|
||||||
|
|
||||||
const auto cmdbuf = sched_ptr->CommandBuffer();
|
|
||||||
const VAddr image_addr = image.info.guest_address;
|
const VAddr image_addr = image.info.guest_address;
|
||||||
const size_t image_size = image.info.guest_size;
|
const size_t image_size = image.info.guest_size;
|
||||||
const auto [vk_buffer, buf_offset] =
|
const auto [vk_buffer, buf_offset] =
|
||||||
buffer_cache.ObtainViewBuffer(image_addr, image_size, is_gpu_dirty);
|
buffer_cache.ObtainViewBuffer(image_addr, image_size, is_gpu_dirty);
|
||||||
|
|
||||||
|
const auto cmdbuf = sched_ptr->CommandBuffer();
|
||||||
// The obtained buffer may be written by a shader so we need to emit a barrier to prevent RAW
|
// The obtained buffer may be written by a shader so we need to emit a barrier to prevent RAW
|
||||||
// hazard
|
// hazard
|
||||||
if (auto barrier = vk_buffer->GetBarrier(vk::AccessFlagBits2::eTransferRead,
|
if (auto barrier = vk_buffer->GetBarrier(vk::AccessFlagBits2::eTransferRead,
|
||||||
@ -643,6 +641,9 @@ void TextureCache::UnregisterImage(ImageId image_id) {
|
|||||||
|
|
||||||
void TextureCache::TrackImage(ImageId image_id) {
|
void TextureCache::TrackImage(ImageId image_id) {
|
||||||
auto& image = slot_images[image_id];
|
auto& image = slot_images[image_id];
|
||||||
|
if (!(image.flags & ImageFlagBits::Registered)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const auto image_begin = image.info.guest_address;
|
const auto image_begin = image.info.guest_address;
|
||||||
const auto image_end = image.info.guest_address + image.info.guest_size;
|
const auto image_end = image.info.guest_address + image.info.guest_size;
|
||||||
if (image_begin == image.track_addr && image_end == image.track_addr_end) {
|
if (image_begin == image.track_addr && image_end == image.track_addr_end) {
|
||||||
@ -666,6 +667,9 @@ void TextureCache::TrackImage(ImageId image_id) {
|
|||||||
|
|
||||||
void TextureCache::TrackImageHead(ImageId image_id) {
|
void TextureCache::TrackImageHead(ImageId image_id) {
|
||||||
auto& image = slot_images[image_id];
|
auto& image = slot_images[image_id];
|
||||||
|
if (!(image.flags & ImageFlagBits::Registered)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const auto image_begin = image.info.guest_address;
|
const auto image_begin = image.info.guest_address;
|
||||||
if (image_begin == image.track_addr) {
|
if (image_begin == image.track_addr) {
|
||||||
return;
|
return;
|
||||||
@ -678,6 +682,9 @@ void TextureCache::TrackImageHead(ImageId image_id) {
|
|||||||
|
|
||||||
void TextureCache::TrackImageTail(ImageId image_id) {
|
void TextureCache::TrackImageTail(ImageId image_id) {
|
||||||
auto& image = slot_images[image_id];
|
auto& image = slot_images[image_id];
|
||||||
|
if (!(image.flags & ImageFlagBits::Registered)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const auto image_end = image.info.guest_address + image.info.guest_size;
|
const auto image_end = image.info.guest_address + image.info.guest_size;
|
||||||
if (image_end == image.track_addr_end) {
|
if (image_end == image.track_addr_end) {
|
||||||
return;
|
return;
|
||||||
|
@ -118,6 +118,7 @@ public:
|
|||||||
|
|
||||||
/// Updates image contents if it was modified by CPU.
|
/// Updates image contents if it was modified by CPU.
|
||||||
void UpdateImage(ImageId image_id, Vulkan::Scheduler* custom_scheduler = nullptr) {
|
void UpdateImage(ImageId image_id, Vulkan::Scheduler* custom_scheduler = nullptr) {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
Image& image = slot_images[image_id];
|
Image& image = slot_images[image_id];
|
||||||
TrackImage(image_id);
|
TrackImage(image_id);
|
||||||
RefreshImage(image, custom_scheduler);
|
RefreshImage(image, custom_scheduler);
|
||||||
|
@ -308,20 +308,20 @@ constexpr std::pair<u32, size_t> ImageSizeLinearAligned(u32 pitch, u32 height, u
|
|||||||
return {pitch_aligned, (log_sz * bpp + 7) / 8};
|
return {pitch_aligned, (log_sz * bpp + 7) / 8};
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr std::pair<u32, size_t> ImageSizeMicroTiled(u32 pitch, u32 height, u32 bpp,
|
constexpr std::pair<u32, size_t> ImageSizeMicroTiled(u32 pitch, u32 height, u32 thickness, u32 bpp,
|
||||||
u32 num_samples) {
|
u32 num_samples) {
|
||||||
const auto& [pitch_align, height_align] = micro_tile_extent;
|
const auto& [pitch_align, height_align] = micro_tile_extent;
|
||||||
auto pitch_aligned = (pitch + pitch_align - 1) & ~(pitch_align - 1);
|
auto pitch_aligned = (pitch + pitch_align - 1) & ~(pitch_align - 1);
|
||||||
const auto height_aligned = (height + height_align - 1) & ~(height_align - 1);
|
const auto height_aligned = (height + height_align - 1) & ~(height_align - 1);
|
||||||
size_t log_sz = (pitch_aligned * height_aligned * bpp * num_samples + 7) / 8;
|
size_t log_sz = (pitch_aligned * height_aligned * bpp * num_samples + 7) / 8;
|
||||||
while (log_sz % 256) {
|
while ((log_sz * thickness) % 256) {
|
||||||
pitch_aligned += 8;
|
pitch_aligned += pitch_align;
|
||||||
log_sz = (pitch_aligned * height_aligned * bpp * num_samples + 7) / 8;
|
log_sz = (pitch_aligned * height_aligned * bpp * num_samples + 7) / 8;
|
||||||
}
|
}
|
||||||
return {pitch_aligned, log_sz};
|
return {pitch_aligned, log_sz};
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr std::pair<u32, size_t> ImageSizeMacroTiled(u32 pitch, u32 height, u32 bpp,
|
constexpr std::pair<u32, size_t> ImageSizeMacroTiled(u32 pitch, u32 height, u32 thickness, u32 bpp,
|
||||||
u32 num_samples, u32 tiling_idx, u32 mip_n,
|
u32 num_samples, u32 tiling_idx, u32 mip_n,
|
||||||
bool alt) {
|
bool alt) {
|
||||||
const auto& [pitch_align, height_align] =
|
const auto& [pitch_align, height_align] =
|
||||||
@ -335,7 +335,7 @@ constexpr std::pair<u32, size_t> ImageSizeMacroTiled(u32 pitch, u32 height, u32
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (downgrade_to_micro) {
|
if (downgrade_to_micro) {
|
||||||
return ImageSizeMicroTiled(pitch, height, bpp, num_samples);
|
return ImageSizeMicroTiled(pitch, height, thickness, bpp, num_samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto pitch_aligned = (pitch + pitch_align - 1) & ~(pitch_align - 1);
|
const auto pitch_aligned = (pitch + pitch_align - 1) & ~(pitch_align - 1);
|
||||||
|
Loading…
Reference in New Issue
Block a user