From f79c9668a3a271a5038bb9d55bf32e701c678a11 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 11 Aug 2019 00:20:09 +0100 Subject: [PATCH] Added shader state; WIP kernel objects --- externals/boost | 2 +- src/common/CMakeLists.txt | 2 + src/common/serialization/atomic.h | 28 ++++ src/common/serialization/boost_vector.hpp | 189 ++++++++++++++++++++++ src/core/core.cpp | 6 +- src/core/hle/kernel/client_port.cpp | 5 +- src/core/hle/kernel/client_port.h | 16 +- src/core/hle/kernel/event.h | 10 ++ src/core/hle/kernel/handle_table.h | 12 ++ src/core/hle/kernel/kernel.cpp | 23 +++ src/core/hle/kernel/kernel.h | 9 ++ src/core/hle/kernel/memory.h | 11 ++ src/core/hle/kernel/mutex.h | 12 ++ src/core/hle/kernel/object.cpp | 12 +- src/core/hle/kernel/object.h | 11 ++ src/core/hle/kernel/process.cpp | 14 +- src/core/hle/kernel/process.h | 65 +++++++- src/core/hle/kernel/resource_limit.cpp | 6 +- src/core/hle/kernel/resource_limit.h | 40 ++++- src/core/hle/kernel/semaphore.h | 11 ++ src/core/hle/kernel/server_port.cpp | 9 +- src/core/hle/kernel/server_port.h | 2 - src/core/hle/kernel/server_session.cpp | 5 +- src/core/hle/kernel/server_session.h | 2 +- src/core/hle/kernel/thread.cpp | 9 +- src/core/hle/kernel/thread.h | 2 +- src/core/hle/kernel/vm_manager.h | 28 +++- src/core/hle/kernel/wait_object.h | 14 ++ src/core/hle/service/err_f.cpp | 1 + src/core/memory.cpp | 23 +-- src/core/mmio.h | 7 + src/video_core/pica_state.h | 6 +- src/video_core/shader/shader.h | 52 ++++++ 33 files changed, 576 insertions(+), 68 deletions(-) create mode 100644 src/common/serialization/atomic.h create mode 100644 src/common/serialization/boost_vector.hpp diff --git a/externals/boost b/externals/boost index d2a5baa1a..48130d387 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit d2a5baa1ad701671a7ef547ef71cb0f0c80ce2cf +Subproject commit 48130d387975d17aed1b34ef75c21020f2d710a8 diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 5abf93dbc..b0577f9d9 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -90,6 +90,8 @@ add_library(common STATIC scm_rev.cpp scm_rev.h scope_exit.h + serialization/atomic.h + serialization/boost_vector.hpp string_util.cpp string_util.h swap.h diff --git a/src/common/serialization/atomic.h b/src/common/serialization/atomic.h new file mode 100644 index 000000000..ef33202ff --- /dev/null +++ b/src/common/serialization/atomic.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include + +namespace boost::serialization +{ + template + void serialize(Archive& ar, std::atomic& value, const unsigned int file_version) + { + boost::serialization::split_free(ar, value, file_version); + } + + template + void save(Archive& ar, const std::atomic& value, const unsigned int file_version) + { + ar << value.load(); + } + + template + void load(Archive& ar, std::atomic& value, const unsigned int file_version) + { + T tmp; + ar >> tmp; + value.store(tmp); + } + +} // namespace boost::serialization diff --git a/src/common/serialization/boost_vector.hpp b/src/common/serialization/boost_vector.hpp new file mode 100644 index 000000000..d97ebd208 --- /dev/null +++ b/src/common/serialization/boost_vector.hpp @@ -0,0 +1,189 @@ +#ifndef BOOST_SERIALIZATION_BOOST_VECTOR_HPP +#define BOOST_SERIALIZATION_BOOST_VECTOR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// boost_vector.hpp: serialization for boost vector templates + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// fast array serialization (C) Copyright 2005 Matthias Troyer +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +// default is being compatible with version 1.34.1 files, not 1.35 files +#ifndef BOOST_SERIALIZATION_VECTOR_VERSIONED +#define BOOST_SERIALIZATION_VECTOR_VERSIONED(V) (V==4 || V==5) +#endif + +namespace boost { +namespace serialization { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// vector< T > + +// the default versions + +template +inline void save( + Archive & ar, + const boost::container::vector &t, + const unsigned int /* file_version */, + mpl::false_ +){ + boost::serialization::stl::save_collection >( + ar, t + ); +} + +template +inline void load( + Archive & ar, + boost::container::vector &t, + const unsigned int /* file_version */, + mpl::false_ +){ + const boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + item_version_type item_version(0); + collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + t.reserve(count); + stl::collection_load_impl(ar, t, count, item_version); +} + +// the optimized versions + +template +inline void save( + Archive & ar, + const boost::container::vector &t, + const unsigned int /* file_version */, + mpl::true_ +){ + const collection_size_type count(t.size()); + ar << BOOST_SERIALIZATION_NVP(count); + if (!t.empty()) + // explict template arguments to pass intel C++ compiler + ar << serialization::make_array( + static_cast(&t[0]), + count + ); +} + +template +inline void load( + Archive & ar, + boost::container::vector &t, + const unsigned int /* file_version */, + mpl::true_ +){ + collection_size_type count(t.size()); + ar >> BOOST_SERIALIZATION_NVP(count); + t.resize(count); + unsigned int item_version=0; + if(BOOST_SERIALIZATION_VECTOR_VERSIONED(ar.get_library_version())) { + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + if (!t.empty()) + // explict template arguments to pass intel C++ compiler + ar >> serialization::make_array( + static_cast(&t[0]), + count + ); + } + +// dispatch to either default or optimized versions + +template +inline void save( + Archive & ar, + const boost::container::vector &t, + const unsigned int file_version +){ + typedef typename + boost::serialization::use_array_optimization::template apply< + typename remove_const::type + >::type use_optimized; + save(ar,t,file_version, use_optimized()); +} + +template +inline void load( + Archive & ar, + boost::container::vector &t, + const unsigned int file_version +){ +#ifdef BOOST_SERIALIZATION_VECTOR_135_HPP + if (ar.get_library_version()==boost::archive::library_version_type(5)) + { + load(ar,t,file_version, boost::is_arithmetic()); + return; + } +#endif + typedef typename + boost::serialization::use_array_optimization::template apply< + typename remove_const::type + >::type use_optimized; + load(ar,t,file_version, use_optimized()); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + boost::container::vector & t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + boost::container::vector & t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // serialization +} // namespace boost + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(boost::container::vector) + +#endif // BOOST_SERIALIZATION_VECTOR_HPP diff --git a/src/core/core.cpp b/src/core/core.cpp index 63730214f..902340d41 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -5,7 +5,6 @@ #include #include #include "boost/serialization/array.hpp" -#include "boost/serialization/unique_ptr.hpp" #include "audio_core/dsp_interface.h" #include "audio_core/hle/hle.h" #include "audio_core/lle/lle.h" @@ -205,6 +204,7 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo kernel = std::make_unique(*memory, *timing, [this] { PrepareReschedule(); }, system_mode); + Kernel::g_kernel = kernel.get(); if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 @@ -368,6 +368,7 @@ void System::Shutdown() { service_manager.reset(); dsp_core.reset(); cpu_core.reset(); + Kernel::g_kernel = nullptr; kernel.reset(); timing.reset(); app_loader.reset(); @@ -400,7 +401,8 @@ void System::serialize(Archive & ar, const unsigned int file_version) ar & GPU::g_regs; ar & LCD::g_regs; ar & dsp_core->GetDspMemory(); - ar & memory; + ar & *memory.get(); + ar & *kernel.get(); } void System::Save(std::ostream &stream) const diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index d217dfb7c..dc0e08d9d 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -13,9 +13,6 @@ namespace Kernel { -ClientPort::ClientPort(KernelSystem& kernel) : Object(kernel), kernel(kernel) {} -ClientPort::~ClientPort() = default; - ResultVal> ClientPort::Connect() { // Note: Threads do not wait for the server endpoint to call // AcceptSession before returning from this call. @@ -26,7 +23,7 @@ ResultVal> ClientPort::Connect() { active_sessions++; // Create a new session pair, let the created sessions inherit the parent port's HLE handler. - auto [server, client] = kernel.CreateSessionPair(server_port->GetName(), SharedFrom(this)); + auto [server, client] = g_kernel->CreateSessionPair(server_port->GetName(), SharedFrom(this)); if (server_port->hle_handler) server_port->hle_handler->ClientConnected(server); diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h index 423db0172..35544e37e 100644 --- a/src/core/hle/kernel/client_port.h +++ b/src/core/hle/kernel/client_port.h @@ -17,8 +17,6 @@ class ClientSession; class ClientPort final : public Object { public: - explicit ClientPort(KernelSystem& kernel); - ~ClientPort() override; friend class ServerPort; std::string GetTypeName() const override { @@ -52,13 +50,25 @@ public: void ConnectionClosed(); private: - KernelSystem& kernel; std::shared_ptr server_port; ///< ServerPort associated with this client port. u32 max_sessions = 0; ///< Maximum number of simultaneous sessions the port can have u32 active_sessions = 0; ///< Number of currently open sessions to this port std::string name; ///< Name of client port (optional) friend class KernelSystem; + + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & server_port; + ar & max_sessions; + ar & active_sessions; + ar & name; + } }; } // namespace Kernel diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h index efc4a0c28..9e9da267a 100644 --- a/src/core/hle/kernel/event.h +++ b/src/core/hle/kernel/event.h @@ -49,6 +49,16 @@ private: std::string name; ///< Name of event (optional) friend class KernelSystem; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & reset_type; + ar & signaled; + ar & name; + } }; } // namespace Kernel diff --git a/src/core/hle/kernel/handle_table.h b/src/core/hle/kernel/handle_table.h index bd5a5df6a..eabf06c26 100644 --- a/src/core/hle/kernel/handle_table.h +++ b/src/core/hle/kernel/handle_table.h @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/result.h" @@ -116,6 +118,16 @@ private: u16 next_free_slot; KernelSystem& kernel; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & objects; + ar & generations; + ar & next_generation; + ar & next_free_slot; + } }; } // namespace Kernel diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index ceb2f14f5..d8bd0f034 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" +#include "common/serialization/atomic.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/config_mem.h" #include "core/hle/kernel/handle_table.h" @@ -16,6 +18,8 @@ namespace Kernel { +KernelSystem* g_kernel; + /// Initialize the kernel KernelSystem::KernelSystem(Memory::MemorySystem& memory, Core::Timing& timing, std::function prepare_reschedule_callback, u32 system_mode) @@ -101,4 +105,23 @@ void KernelSystem::AddNamedPort(std::string name, std::shared_ptr po named_ports.emplace(std::move(name), std::move(port)); } +template +void KernelSystem::serialize(Archive& ar, const unsigned int file_version) +{ + ar & named_ports; + // TODO: CPU + // NB: subsystem references and prepare_reschedule_callback are constant + ar & *resource_limits.get(); + ar & next_object_id; + //ar & *timer_manager.get(); + ar & next_process_id; + ar & process_list; + ar & current_process; + // ar & *thread_manager.get(); + //ar & *config_mem_handler.get(); + //ar & *shared_page_handler.get(); +} + +SERIALIZE_IMPL(KernelSystem) + } // namespace Kernel diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 58f63938b..c662882f5 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -11,6 +11,9 @@ #include #include #include +#include +#include +#include #include "common/common_types.h" #include "core/hle/kernel/memory.h" #include "core/hle/result.h" @@ -283,6 +286,12 @@ private: std::unique_ptr shared_page_handler; std::unique_ptr ipc_recorder; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version); }; +extern KernelSystem* g_kernel; + } // namespace Kernel diff --git a/src/core/hle/kernel/memory.h b/src/core/hle/kernel/memory.h index bb4e174f7..9e9fe5eb4 100644 --- a/src/core/hle/kernel/memory.h +++ b/src/core/hle/kernel/memory.h @@ -60,6 +60,17 @@ struct MemoryRegionInfo { * @param size the size of the region to free. */ void Free(u32 offset, u32 size); + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & base; + ar & size; + ar & used; + // TODO: boost icl / free_blocks + } }; } // namespace Kernel diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 1f6358909..618685451 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -58,6 +58,18 @@ public: private: KernelSystem& kernel; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & lock_count; + ar & priority; + ar & name; + ar & holding_thread; + ar & kernel; // TODO: Check that this works! + } }; /** diff --git a/src/core/hle/kernel/object.cpp b/src/core/hle/kernel/object.cpp index f9ca68218..6ab1b1769 100644 --- a/src/core/hle/kernel/object.cpp +++ b/src/core/hle/kernel/object.cpp @@ -8,7 +8,17 @@ namespace Kernel { -Object::Object(KernelSystem& kernel) : object_id{kernel.GenerateObjectID()} {} +// TODO: Remove this +Object::Object(KernelSystem& kernel) +{ +} + +Object::Object() = default; + +void Object::Init(KernelSystem& kernel) +{ + object_id = kernel.GenerateObjectID(); +} Object::~Object() = default; diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h index 9547a83ed..8998cb88d 100644 --- a/src/core/hle/kernel/object.h +++ b/src/core/hle/kernel/object.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "common/common_types.h" #include "core/hle/kernel/kernel.h" @@ -41,8 +42,11 @@ enum { class Object : NonCopyable, public std::enable_shared_from_this { public: explicit Object(KernelSystem& kernel); + Object(); virtual ~Object(); + virtual void Init(KernelSystem& kernel); + /// Returns a unique identifier for the object. For debugging purposes only. u32 GetObjectId() const { return object_id.load(std::memory_order_relaxed); @@ -64,6 +68,13 @@ public: private: std::atomic object_id; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & object_id; + } }; template diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index c6aa2b895..63a5c3b68 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -18,7 +18,8 @@ namespace Kernel { std::shared_ptr KernelSystem::CreateCodeSet(std::string name, u64 program_id) { - auto codeset{std::make_shared(*this)}; + auto codeset{std::make_shared()}; + codeset->Init(*this); codeset->name = std::move(name); codeset->program_id = program_id; @@ -26,11 +27,9 @@ std::shared_ptr KernelSystem::CreateCodeSet(std::string name, u64 progr return codeset; } -CodeSet::CodeSet(KernelSystem& kernel) : Object(kernel) {} -CodeSet::~CodeSet() {} - std::shared_ptr KernelSystem::CreateProcess(std::shared_ptr code_set) { - auto process{std::make_shared(*this)}; + auto process{std::make_shared()}; + process->Init(*this); process->codeset = std::move(code_set); process->flags.raw = 0; @@ -401,9 +400,8 @@ ResultCode Process::Unmap(VAddr target, VAddr source, u32 size, VMAPermission pe return RESULT_SUCCESS; } -Kernel::Process::Process(KernelSystem& kernel) - : Object(kernel), handle_table(kernel), vm_manager(kernel.memory), kernel(kernel) { - +Kernel::Process::Process() : kernel(*g_kernel), handle_table(*g_kernel), vm_manager(g_kernel->memory) +{ kernel.memory.RegisterPageTable(&vm_manager.page_table); } Kernel::Process::~Process() { diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index dc2c878b8..6defd42c6 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -11,8 +11,13 @@ #include #include #include +#include +#include +#include +#include #include "common/bit_field.h" #include "common/common_types.h" +#include "common/serialization/boost_vector.hpp" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/vm_manager.h" @@ -25,6 +30,17 @@ struct AddressMapping { u32 size; bool read_only; bool unk_flag; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & address; + ar & size; + ar & read_only; + ar & unk_flag; + } }; union ProcessFlags { @@ -52,13 +68,20 @@ struct MemoryRegionInfo; class CodeSet final : public Object { public: - explicit CodeSet(KernelSystem& kernel); - ~CodeSet() override; - struct Segment { std::size_t offset = 0; VAddr addr = 0; u32 size = 0; + + private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & offset; + ar & addr; + ar & size; + } }; std::string GetTypeName() const override { @@ -106,11 +129,24 @@ public: std::string name; /// Title ID corresponding to the process u64 program_id; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + // TODO: memory reference + ar & segments; + ar & entrypoint; + ar & name; + ar & program_id; + } }; class Process final : public Object { public: - explicit Process(Kernel::KernelSystem& kernel); + explicit Process(); ~Process() override; std::string GetTypeName() const override { @@ -195,5 +231,26 @@ public: private: KernelSystem& kernel; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & handle_table; + ar & codeset; + ar & resource_limit; + ar & svc_access_mask; + ar & handle_table_size; + ar & (boost::container::vector >&)address_mappings; + ar & flags.raw; + ar & kernel_version; + ar & ideal_processor; + ar & process_id; + ar & vm_manager; + ar & memory_used; + ar & memory_region; + ar & tls_slots; + } }; } // namespace Kernel diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp index 8691c142e..fe19caff9 100644 --- a/src/core/hle/kernel/resource_limit.cpp +++ b/src/core/hle/kernel/resource_limit.cpp @@ -9,11 +9,9 @@ namespace Kernel { -ResourceLimit::ResourceLimit(KernelSystem& kernel) : Object(kernel) {} -ResourceLimit::~ResourceLimit() {} - std::shared_ptr ResourceLimit::Create(KernelSystem& kernel, std::string name) { - auto resource_limit{std::make_shared(kernel)}; + auto resource_limit{std::make_shared()}; + resource_limit->Init(kernel); resource_limit->name = std::move(name); return resource_limit; diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h index 99ae8f2cf..06fe71587 100644 --- a/src/core/hle/kernel/resource_limit.h +++ b/src/core/hle/kernel/resource_limit.h @@ -6,6 +6,8 @@ #include #include +#include +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" @@ -33,8 +35,6 @@ enum ResourceTypes { class ResourceLimit final : public Object { public: - explicit ResourceLimit(KernelSystem& kernel); - ~ResourceLimit() override; /** * Creates a resource limit object. @@ -110,6 +110,35 @@ public: /// Current CPU time that the processes in this category are utilizing s32 current_cpu_time = 0; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + // NB most of these aren't used at all currently, but we're adding them here for forwards compatibility + ar & name; + ar & max_priority; + ar & max_commit; + ar & max_threads; + ar & max_events; + ar & max_mutexes; + ar & max_semaphores; + ar & max_timers; + ar & max_shared_mems; + ar & max_address_arbiters; + ar & max_cpu_time; + ar & current_commit; + ar & current_threads; + ar & current_events; + ar & current_mutexes; + ar & current_semaphores; + ar & current_timers; + ar & current_shared_mems; + ar & current_address_arbiters; + ar & current_cpu_time; + } }; class ResourceLimitList { @@ -126,6 +155,13 @@ public: private: std::array, 4> resource_limits; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & resource_limits; + } }; } // namespace Kernel diff --git a/src/core/hle/kernel/semaphore.h b/src/core/hle/kernel/semaphore.h index 47b3eabf1..526be6812 100644 --- a/src/core/hle/kernel/semaphore.h +++ b/src/core/hle/kernel/semaphore.h @@ -43,6 +43,17 @@ public: * @return The number of free slots the semaphore had before this call */ ResultVal Release(s32 release_count); + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & max_count; + ar & available_count; + ar & name; + } }; } // namespace Kernel diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp index a69b42778..ca4cded3d 100644 --- a/src/core/hle/kernel/server_port.cpp +++ b/src/core/hle/kernel/server_port.cpp @@ -13,9 +13,6 @@ namespace Kernel { -ServerPort::ServerPort(KernelSystem& kernel) : WaitObject(kernel) {} -ServerPort::~ServerPort() {} - ResultVal> ServerPort::Accept() { if (pending_sessions.empty()) { return ERR_NO_PENDING_SESSIONS; @@ -36,8 +33,10 @@ void ServerPort::Acquire(Thread* thread) { } KernelSystem::PortPair KernelSystem::CreatePortPair(u32 max_sessions, std::string name) { - auto server_port{std::make_shared(*this)}; - auto client_port{std::make_shared(*this)}; + auto server_port{std::make_shared()}; + server_port->Init(*this); + auto client_port{std::make_shared()}; + client_port->Init(*this); server_port->name = name + "_Server"; client_port->name = name + "_Client"; diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h index 9b0f13480..c500fd1b2 100644 --- a/src/core/hle/kernel/server_port.h +++ b/src/core/hle/kernel/server_port.h @@ -20,8 +20,6 @@ class SessionRequestHandler; class ServerPort final : public WaitObject { public: - explicit ServerPort(KernelSystem& kernel); - ~ServerPort() override; std::string GetTypeName() const override { return "ServerPort"; diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 5855d83a5..c6a6261a5 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -13,7 +13,7 @@ namespace Kernel { -ServerSession::ServerSession(KernelSystem& kernel) : WaitObject(kernel), kernel(kernel) {} +ServerSession::ServerSession() : kernel(*g_kernel) {} ServerSession::~ServerSession() { // This destructor will be called automatically when the last ServerSession handle is closed by // the emulated application. @@ -30,7 +30,8 @@ ServerSession::~ServerSession() { ResultVal> ServerSession::Create(KernelSystem& kernel, std::string name) { - auto server_session{std::make_shared(kernel)}; + auto server_session{std::make_shared()}; + server_session->Init(kernel); server_session->name = std::move(name); server_session->parent = nullptr; diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index 940f38f9b..3536bcbd1 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h @@ -38,7 +38,7 @@ class Thread; class ServerSession final : public WaitObject { public: ~ServerSession() override; - explicit ServerSession(KernelSystem& kernel); + explicit ServerSession(); std::string GetName() const override { return name; diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 3b15ec35e..4c2344dcb 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -37,9 +37,9 @@ u32 ThreadManager::NewThreadId() { return next_thread_id++; } -Thread::Thread(KernelSystem& kernel) - : WaitObject(kernel), context(kernel.GetThreadManager().NewContext()), - thread_manager(kernel.GetThreadManager()) {} +Thread::Thread() + : context(g_kernel->GetThreadManager().NewContext()), + thread_manager(g_kernel->GetThreadManager()) {} Thread::~Thread() {} Thread* ThreadManager::GetCurrentThread() const { @@ -309,7 +309,8 @@ ResultVal> KernelSystem::CreateThread(std::string name, ErrorSummary::InvalidArgument, ErrorLevel::Permanent); } - auto thread{std::make_shared(*this)}; + auto thread{std::make_shared()}; + thread->Init(*this); thread_manager->thread_list.push_back(thread); thread_manager->ready_queue.prepare(priority); diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index f2ef767ef..2db5dda91 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -149,7 +149,7 @@ private: class Thread final : public WaitObject { public: - explicit Thread(KernelSystem&); + explicit Thread(); ~Thread() override; std::string GetName() const override { diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 0d3ae1e44..6711c9b4d 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -8,7 +8,8 @@ #include #include #include -#include "boost/serialization/split_member.hpp" +#include +#include #include "common/common_types.h" #include "core/hle/result.h" #include "core/memory.h" @@ -81,6 +82,21 @@ struct VirtualMemoryArea { /// Tests if this area can be merged to the right with `next`. bool CanBeMergedWith(const VirtualMemoryArea& next) const; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & base; + ar & size; + ar & type; + ar & permissions; + ar & meminfo_state; + // TODO: backing memory ref + ar & paddr; + ar & mmio_handler; + } }; /** @@ -195,9 +211,10 @@ public: private: friend class boost::serialization::access; - template - void save(Archive & ar, const unsigned int file_version) + template + void save(Archive& ar, const unsigned int file_version) const { + ar & vma_map; for (int i = 0; i < page_table.pointers.size(); i++) { ar << memory.GetFCRAMOffset(page_table.pointers[i]); } @@ -205,9 +222,10 @@ private: ar & page_table.attributes; } - template - void load(Archive & ar, const unsigned int file_version) + template + void load(Archive& ar, const unsigned int file_version) { + ar & vma_map; for (int i = 0; i < page_table.pointers.size(); i++) { u32 offset{}; ar >> offset; diff --git a/src/core/hle/kernel/wait_object.h b/src/core/hle/kernel/wait_object.h index 41e803515..e08997721 100644 --- a/src/core/hle/kernel/wait_object.h +++ b/src/core/hle/kernel/wait_object.h @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" @@ -62,6 +65,17 @@ private: /// Function to call when this object becomes available std::function hle_notifier; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & waiting_threads; + // NB: hle_notifier *not* serialized since it's a callback! + // Fortunately it's only used in one place (DSP) so we can reconstruct it there + } }; // Specialization of DynamicObjectCast for WaitObjects diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp index 13b2c7e46..b218eb793 100644 --- a/src/core/hle/service/err_f.cpp +++ b/src/core/hle/service/err_f.cpp @@ -14,6 +14,7 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/result.h" #include "core/hle/service/err_f.h" +#undef exception_info namespace Service::ERR { diff --git a/src/core/memory.cpp b/src/core/memory.cpp index fe33cf767..a07cc2e13 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -5,8 +5,7 @@ #include #include #include "boost/serialization/array.hpp" -#include "boost/serialization/nvp.hpp" -#include "boost/serialization/unique_ptr.hpp" +#include "boost/serialization/binary_object.hpp" #include "audio_core/dsp_interface.h" #include "common/archives.h" #include "common/assert.h" @@ -84,23 +83,17 @@ public: private: - template - void add_blob(Archive & ar, std::unique_ptr & var, const char *name, std::size_t size) - { - ar & boost::serialization::make_nvp( - name, - *static_cast(static_cast(var.get())) - ); - } - friend class boost::serialization::access; template void serialize(Archive & ar, const unsigned int file_version) { // TODO: Skip n3ds ram when not used? - add_blob(ar, fcram, "fcram", Memory::FCRAM_N3DS_SIZE); - add_blob(ar, vram, "vram", Memory::VRAM_SIZE); - add_blob(ar, n3ds_extra_ram, "n3ds_extra_ram", Memory::N3DS_EXTRA_RAM_SIZE); + auto s_fcram = boost::serialization::binary_object(fcram.get(), Memory::FCRAM_N3DS_SIZE); + auto s_vram = boost::serialization::binary_object(vram.get(), Memory::VRAM_SIZE); + auto s_extra = boost::serialization::binary_object(n3ds_extra_ram.get(), Memory::N3DS_EXTRA_RAM_SIZE); + ar & s_fcram; + ar & s_vram; + ar & s_extra; ar & cache_marker; // TODO: How the hell to do page tables.. // ar & page_table_list; @@ -114,7 +107,7 @@ MemorySystem::~MemorySystem() = default; template void MemorySystem::serialize(Archive & ar, const unsigned int file_version) { - ar & impl; + ar & *impl.get(); } SERIALIZE_IMPL(MemorySystem) diff --git a/src/core/mmio.h b/src/core/mmio.h index 30bafaf5f..0a8249c9a 100644 --- a/src/core/mmio.h +++ b/src/core/mmio.h @@ -32,6 +32,13 @@ public: virtual void Write64(VAddr addr, u64 data) = 0; virtual bool WriteBlock(VAddr dest_addr, const void* src_buffer, std::size_t size) = 0; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + } }; using MMIORegionPointer = std::shared_ptr; diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index 10d1e637b..376865397 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -161,8 +161,6 @@ struct State { UnionArray lut; } fog; -#undef SERIALIZE_RAW - /// Current Pica command list struct { PAddr addr; // This exists only for serialization @@ -185,7 +183,7 @@ struct State { template void serialize(Archive & ar, const unsigned int file_version) { - // ar & input_vertex; + ar & input_vertex; ar & current_attribute; ar & reset_geometry_pipeline; } @@ -220,7 +218,7 @@ private: ar & regs.reg_array; ar & vs; ar & gs; - // ar & input_default_attributes; + ar & input_default_attributes; ar & proctex; ar & lighting.luts; ar & fog.lut; diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index 3f55d3064..1a0f6ef8a 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h @@ -10,6 +10,7 @@ #include #include #include +#include #include "common/assert.h" #include "common/common_funcs.h" #include "common/common_types.h" @@ -32,6 +33,14 @@ using SwizzleData = std::array; struct AttributeBuffer { alignas(16) Common::Vec4 attr[16]; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & attr; + } }; /// Handler type for receiving vertex outputs from vertex shader or geometry shader @@ -91,6 +100,19 @@ struct GSEmitter { GSEmitter(); ~GSEmitter(); void Emit(Common::Vec4 (&output_regs)[16]); + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & buffer; + ar & vertex_id; + ar & prim_emit; + ar & winding; + ar & output_mask; + // Handlers are ignored because they're constant + } }; static_assert(std::is_standard_layout::value, "GSEmitter is not standard layout type"); @@ -108,6 +130,16 @@ struct UnitState { alignas(16) Common::Vec4 input[16]; alignas(16) Common::Vec4 temporary[16]; alignas(16) Common::Vec4 output[16]; + + private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & input; + ar & temporary; + ar & output; + } } registers; static_assert(std::is_pod::value, "Structure is not POD"); @@ -160,6 +192,17 @@ struct UnitState { void LoadInput(const ShaderRegs& config, const AttributeBuffer& input); void WriteOutput(const ShaderRegs& config, AttributeBuffer& output); + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & registers; + ar & conditional_code; + ar & address_registers; + // TODO: emitter_ptr + } }; /** @@ -173,6 +216,15 @@ struct GSUnitState : public UnitState { void ConfigOutput(const ShaderRegs& config); GSEmitter emitter; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & emitter; + } }; struct Uniforms {