diff --git a/CMakeLists.txt b/CMakeLists.txt index 986477c2..16ad1c41 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -282,7 +282,7 @@ set(SOURCE_FILES src/emulator.cpp src/io_file.cpp src/config.cpp src/core/memory.cpp src/renderer.cpp src/core/renderer_null/renderer_null.cpp src/http_server.cpp src/stb_image_write.c src/core/cheats.cpp src/core/action_replay.cpp src/discord_rpc.cpp src/lua.cpp src/memory_mapped_file.cpp src/miniaudio.cpp src/renderdoc.cpp - src/frontend_settings.cpp + src/frontend_settings.cpp src/dynamic_library.cpp ) set(CRYPTO_SOURCE_FILES src/core/crypto/aes_engine.cpp) set(KERNEL_SOURCE_FILES src/core/kernel/kernel.cpp src/core/kernel/resource_limits.cpp @@ -365,6 +365,7 @@ set(HEADER_FILES include/emulator.hpp include/helpers.hpp include/termcolor.hpp include/align.hpp include/audio/aac_decoder.hpp include/PICA/pica_simd.hpp include/services/fonts.hpp include/audio/audio_interpolation.hpp include/audio/hle_mixer.hpp include/audio/dsp_simd.hpp include/enum_flag_ops.hpp include/services/dsp_firmware_db.hpp include/frontend_settings.hpp + include/dynamic_library.hpp ) cmrc_add_resource_library( @@ -385,7 +386,6 @@ set(THIRD_PARTY_SOURCE_FILES third_party/imgui/imgui.cpp third_party/host_memory/host_memory.cpp third_party/host_memory/virtual_buffer.cpp - third_party/host_memory/dynamic_library.cpp ) if(ENABLE_LUAJIT AND NOT ANDROID) diff --git a/third_party/host_memory/include/host_memory/dynamic_library.h b/include/dynamic_library.hpp similarity index 83% rename from third_party/host_memory/include/host_memory/dynamic_library.h rename to include/dynamic_library.hpp index ca12eb5d..95f86920 100644 --- a/third_party/host_memory/include/host_memory/dynamic_library.h +++ b/include/dynamic_library.hpp @@ -6,7 +6,6 @@ #include namespace Common { - /** * Provides a platform-independent interface for loading a dynamic library and retrieving symbols. * The interface maintains an internal reference count to allow one handle to be shared between @@ -35,7 +34,7 @@ namespace Common { ~DynamicLibrary(); /// Returns the specified library name with the platform-specific suffix added. - [[nodiscard]] static std::string GetUnprefixedFilename(const char* filename); + [[nodiscard]] static std::string getUnprefixedFilename(const char* filename); /// Returns the specified library name in platform-specific format. /// Major/minor versions will not be included if set to -1. @@ -43,27 +42,27 @@ namespace Common { /// Windows: LIBNAME-MAJOR-MINOR.dll /// Linux: libLIBNAME.so.MAJOR.MINOR /// Mac: libLIBNAME.MAJOR.MINOR.dylib - [[nodiscard]] static std::string GetVersionedFilename(const char* libname, int major = -1, int minor = -1); + [[nodiscard]] static std::string getVersionedFilename(const char* libname, int major = -1, int minor = -1); /// Returns true if a module is loaded, otherwise false. - [[nodiscard]] bool IsOpen() const { return handle != nullptr; } + [[nodiscard]] bool isOpen() const { return handle != nullptr; } /// Loads (or replaces) the handle with the specified library file name. /// Returns true if the library was loaded and can be used. - [[nodiscard]] bool Open(const char* filename); + [[nodiscard]] bool open(const char* filename); /// Unloads the library, any function pointers from this library are no longer valid. - void Close(); + void close(); /// Returns the address of the specified symbol (function or variable) as an untyped pointer. /// If the specified symbol does not exist in this library, nullptr is returned. - [[nodiscard]] void* GetSymbolAddress(const char* name) const; + [[nodiscard]] void* getSymbolAddress(const char* name) const; /// Obtains the address of the specified symbol, automatically casting to the correct type. /// Returns true if the symbol was found and assigned, otherwise false. template - [[nodiscard]] bool GetSymbol(const char* name, T* ptr) const { - *ptr = reinterpret_cast(GetSymbolAddress(name)); + [[nodiscard]] bool getSymbol(const char* name, T* ptr) const { + *ptr = reinterpret_cast(getSymbolAddress(name)); return *ptr != nullptr; } @@ -71,5 +70,4 @@ namespace Common { /// Platform-dependent data type representing a dynamic library handle. void* handle = nullptr; }; - } // namespace Common \ No newline at end of file diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 7f9e825c..15f92e37 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -15,7 +15,7 @@ CMRC_DECLARE(ConsoleFonts); using namespace KernelMemoryTypes; Memory::Memory(const EmulatorConfig& config) : config(config) { - arena = new Common::HostMemory(FASTMEM_BACKING_SIZE, FASTMEM_VIRTUAL_SIZE); + arena = new Common::HostMemory(FASTMEM_BACKING_SIZE, FASTMEM_VIRTUAL_SIZE, false); readTable.resize(totalPageCount, 0); writeTable.resize(totalPageCount, 0); diff --git a/third_party/host_memory/dynamic_library.cpp b/src/dynamic_library.cpp similarity index 82% rename from third_party/host_memory/dynamic_library.cpp rename to src/dynamic_library.cpp index 4855dbe4..833baef7 100644 --- a/third_party/host_memory/dynamic_library.cpp +++ b/src/dynamic_library.cpp @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: 2019 Dolphin Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "host_memory/dynamic_library.h" +#include "dynamic_library.hpp" #include @@ -15,21 +15,20 @@ #endif namespace Common { - DynamicLibrary::DynamicLibrary() = default; - DynamicLibrary::DynamicLibrary(const char* filename) { void(Open(filename)); } + DynamicLibrary::DynamicLibrary(const char* filename) { void(open(filename)); } DynamicLibrary::DynamicLibrary(void* handle_) : handle{handle_} {} DynamicLibrary::DynamicLibrary(DynamicLibrary&& rhs) noexcept : handle{std::exchange(rhs.handle, nullptr)} {} DynamicLibrary& DynamicLibrary::operator=(DynamicLibrary&& rhs) noexcept { - Close(); + close(); handle = std::exchange(rhs.handle, nullptr); return *this; } - DynamicLibrary::~DynamicLibrary() { Close(); } + DynamicLibrary::~DynamicLibrary() { close(); } - std::string DynamicLibrary::GetUnprefixedFilename(const char* filename) { + std::string DynamicLibrary::getUnprefixedFilename(const char* filename) { #if defined(_WIN32) return std::string(filename) + ".dll"; #elif defined(__APPLE__) @@ -39,7 +38,7 @@ namespace Common { #endif } - std::string DynamicLibrary::GetVersionedFilename(const char* libname, int major, int minor) { + std::string DynamicLibrary::getVersionedFilename(const char* libname, int major, int minor) { #if defined(_WIN32) if (major >= 0 && minor >= 0) return fmt::format("{}-{}-{}.dll", libname, major, minor); @@ -66,7 +65,7 @@ namespace Common { #endif } - bool DynamicLibrary::Open(const char* filename) { + bool DynamicLibrary::open(const char* filename) { #ifdef _WIN32 handle = reinterpret_cast(LoadLibraryA(filename)); #else @@ -75,8 +74,8 @@ namespace Common { return handle != nullptr; } - void DynamicLibrary::Close() { - if (!IsOpen()) return; + void DynamicLibrary::close() { + if (!isOpen()) return; #ifdef _WIN32 FreeLibrary(reinterpret_cast(handle)); @@ -86,7 +85,7 @@ namespace Common { handle = nullptr; } - void* DynamicLibrary::GetSymbolAddress(const char* name) const { + void* DynamicLibrary::getSymbolAddress(const char* name) const { #ifdef _WIN32 return reinterpret_cast(GetProcAddress(reinterpret_cast(handle), name)); #else diff --git a/third_party/host_memory/host_memory.cpp b/third_party/host_memory/host_memory.cpp index 4c12fd3b..bbd15ebe 100644 --- a/third_party/host_memory/host_memory.cpp +++ b/third_party/host_memory/host_memory.cpp @@ -16,7 +16,7 @@ #include #include -#include "host_memory/dynamic_library.h" +#include "dynamic_library.hpp" #elif defined(__linux__) || defined(__FreeBSD__) // ^^^ Windows ^^^ vvv Linux vvv @@ -99,7 +99,7 @@ namespace Common { template static void GetFuncAddress(Common::DynamicLibrary& dll, const char* name, T& pfn) { - if (!dll.GetSymbol(name, &pfn)) { + if (!dll.getSymbol(name, &pfn)) { Helpers::warn("Failed to load %s", name); throw std::bad_alloc{}; } @@ -109,7 +109,7 @@ namespace Common { public: explicit Impl(size_t backing_size_, size_t virtual_size_) : backing_size{backing_size_}, virtual_size{virtual_size_}, process{GetCurrentProcess()}, kernelbase_dll("Kernelbase") { - if (!kernelbase_dll.IsOpen()) { + if (!kernelbase_dll.isOpen()) { Helpers::warn("Failed to load Kernelbase.dll"); throw std::bad_alloc{}; } @@ -666,8 +666,13 @@ namespace Common { #endif // ^^^ Generic ^^^ - HostMemory::HostMemory(size_t backing_size_, size_t virtual_size_) : backing_size(backing_size_), virtual_size(virtual_size_) { + HostMemory::HostMemory(size_t backing_size_, size_t virtual_size_, bool enableFastmem) : backing_size(backing_size_), virtual_size(virtual_size_) { try { + // Fastmem is disabled, just throw bad alloc and use the VirtualBuffer fallback. + if (!enableFastmem) { + throw std::bad_alloc{}; + } + // Try to allocate a fastmem arena. // The implementation will fail with std::bad_alloc on errors. impl = std::make_unique( @@ -683,7 +688,10 @@ namespace Common { } } catch (const std::bad_alloc&) { - Helpers::warn("Fastmem unavailable, falling back to VirtualBuffer for memory allocation"); + if (enableFastmem) { + Helpers::warn("Fastmem unavailable, falling back to VirtualBuffer for memory allocation"); + } + fallback_buffer = std::make_unique>(backing_size); backing_base = fallback_buffer->data(); virtual_base = nullptr; diff --git a/third_party/host_memory/include/host_memory/host_memory.h b/third_party/host_memory/include/host_memory/host_memory.h index 420ec49c..79e664fa 100644 --- a/third_party/host_memory/include/host_memory/host_memory.h +++ b/third_party/host_memory/include/host_memory/host_memory.h @@ -25,7 +25,7 @@ namespace Common { */ class HostMemory { public: - explicit HostMemory(size_t backing_size_, size_t virtual_size_); + explicit HostMemory(size_t backing_size_, size_t virtual_size_, bool useFastmem); ~HostMemory(); /**