diff --git a/vita3k/CMakeLists.txt b/vita3k/CMakeLists.txt index 52957558d..11c4e4325 100644 --- a/vita3k/CMakeLists.txt +++ b/vita3k/CMakeLists.txt @@ -85,7 +85,7 @@ add_subdirectory(touch) add_subdirectory(util) add_subdirectory(gdbstub) -add_executable(vita3k MACOSX_BUNDLE main.cpp interface.cpp interface.h performance.cpp) +add_executable(vita3k MACOSX_BUNDLE main.cpp interface.cpp interface.h performance.cpp cpu_protocol.h cpu_protocol.cpp) target_link_libraries(vita3k PRIVATE app gui modules) if(USE_DISCORD_RICH_PRESENCE) diff --git a/vita3k/host/include/host/import_var.h b/vita3k/cpu_protocol.cpp similarity index 52% rename from vita3k/host/include/host/import_var.h rename to vita3k/cpu_protocol.cpp index e8e6a45c8..2f5e71489 100644 --- a/vita3k/host/include/host/import_var.h +++ b/vita3k/cpu_protocol.cpp @@ -15,12 +15,30 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -#pragma once +#include "cpu_protocol.h" +#include +#include -#include +CPUProtocol::CPUProtocol(HostState &host) + : host(&host) { +} -#include +CPUProtocol::~CPUProtocol() { +} -struct HostState; +void CPUProtocol::call_svc(CPUState &cpu, uint32_t svc, Address pc, SceUID thread_id) { + uint32_t nid = *Ptr(pc + 4).get(host->mem); + ::call_import(*host, cpu, nid, thread_id); +} -using ImportVarFactory = std::function; +Address CPUProtocol::get_watch_memory_addr(Address addr) { + return ::get_watch_memory_addr(host->kernel, addr); +} + +std::vector &CPUProtocol::get_module_regions() { + return host->kernel.module_regions; +} + +ExclusiveMonitorPtr CPUProtocol::get_exlusive_monitor() { + return host->kernel.exclusive_monitor; +} diff --git a/vita3k/host/include/host/import_fn.h b/vita3k/cpu_protocol.h similarity index 65% rename from vita3k/host/include/host/import_fn.h rename to vita3k/cpu_protocol.h index d433742af..c0a93dccf 100644 --- a/vita3k/host/include/host/import_fn.h +++ b/vita3k/cpu_protocol.h @@ -17,11 +17,18 @@ #pragma once -#include +#include -#include - -struct CPUState; struct HostState; -using ImportFn = std::function; +struct CPUProtocol : public CPUProtocolBase { + CPUProtocol(HostState &host); + ~CPUProtocol(); + void call_svc(CPUState &cpu, uint32_t svc, Address pc, SceUID thread_id) override; + Address get_watch_memory_addr(Address addr) override; + std::vector &get_module_regions() override; + ExclusiveMonitorPtr get_exlusive_monitor() override; + +private: + HostState *host; +}; diff --git a/vita3k/host/CMakeLists.txt b/vita3k/host/CMakeLists.txt index b7fd48444..d0a7354bc 100644 --- a/vita3k/host/CMakeLists.txt +++ b/vita3k/host/CMakeLists.txt @@ -3,8 +3,6 @@ add_library( STATIC include/host/app_util.h include/host/functions.h - include/host/import_var.h - include/host/import_fn.h include/host/load_self.h include/host/pkg.h include/host/sce_types.h @@ -20,5 +18,5 @@ add_library( ) target_include_directories(host PUBLIC include ${PSVPFSPARSER_INCLUDE_DIR}) -target_link_libraries(host PUBLIC psvpfsparser app audio config ctrl dialog ime io kernel miniz net ngs nids np renderer sdl2 touch gdbstub) +target_link_libraries(host PUBLIC psvpfsparser app audio config ctrl dialog ime io kernel miniz net ngs nids np renderer sdl2 touch gdbstub codec) target_link_libraries(host PRIVATE elfio::elfio FAT16 vita-toolchain) diff --git a/vita3k/io/include/io/functions.h b/vita3k/io/include/io/functions.h index 1ec478231..a7c9ffa7a 100644 --- a/vita3k/io/include/io/functions.h +++ b/vita3k/io/include/io/functions.h @@ -49,13 +49,13 @@ int write_file(SceUID fd, const void *data, SceSize size, const IOState &io, con int truncate_file(SceUID fd, unsigned long long length, const IOState &io, const char *export_name); SceOff seek_file(SceUID fd, SceOff offset, SceIoSeekMode whence, IOState &io, const char *export_name); SceOff tell_file(IOState &io, const SceUID fd, const char *export_name); -int stat_file(IOState &io, const char *file, SceIoStat *statp, const std::wstring &pref_path, SceUInt64 base_tick, const char *export_name, SceUID fd = invalid_fd); -int stat_file_by_fd(IOState &io, const SceUID fd, SceIoStat *statp, const std::wstring &pref_path, SceUInt64 base_tick, const char *export_name); +int stat_file(IOState &io, const char *file, SceIoStat *statp, const std::wstring &pref_path, const char *export_name, SceUID fd = invalid_fd); +int stat_file_by_fd(IOState &io, const SceUID fd, SceIoStat *statp, const std::wstring &pref_path, const char *export_name); int close_file(IOState &io, SceUID fd, const char *export_name); int remove_file(IOState &io, const char *file, const std::wstring &pref_path, const char *export_name); SceUID open_dir(IOState &io, const char *path, const std::wstring &pref_path, const char *export_name); -SceUID read_dir(IOState &io, SceUID fd, SceIoDirent *dent, const std::wstring &pref_path, const SceUInt64 base_tick, const char *export_name); +SceUID read_dir(IOState &io, SceUID fd, SceIoDirent *dent, const std::wstring &pref_path, const char *export_name); int create_dir(IOState &io, const char *dir, int mode, const std::wstring &pref_path, const char *export_name, const bool recursive = false); int close_dir(IOState &io, SceUID fd, const char *export_name); int remove_dir(IOState &io, const char *dir, const std::wstring &pref_path, const char *export_name); diff --git a/vita3k/io/src/io.cpp b/vita3k/io/src/io.cpp index 7b3422cfe..236999697 100644 --- a/vita3k/io/src/io.cpp +++ b/vita3k/io/src/io.cpp @@ -448,7 +448,7 @@ SceOff tell_file(IOState &io, const SceUID fd, const char *export_name) { return std_file->second.tell(); } -int stat_file(IOState &io, const char *file, SceIoStat *statp, const std::wstring &pref_path, SceUInt64 base_tick, const char *export_name, +int stat_file(IOState &io, const char *file, SceIoStat *statp, const std::wstring &pref_path, const char *export_name, const SceUID fd) { assert(statp != nullptr); @@ -547,7 +547,7 @@ int stat_file(IOState &io, const char *file, SceIoStat *statp, const std::wstrin return 0; } -int stat_file_by_fd(IOState &io, const SceUID fd, SceIoStat *statp, const std::wstring &pref_path, SceUInt64 base_tick, const char *export_name) { +int stat_file_by_fd(IOState &io, const SceUID fd, SceIoStat *statp, const std::wstring &pref_path, const char *export_name) { assert(statp != nullptr); memset(statp, '\0', sizeof(SceIoStat)); @@ -556,7 +556,7 @@ int stat_file_by_fd(IOState &io, const SceUID fd, SceIoStat *statp, const std::w return IO_ERROR(SCE_ERROR_ERRNO_EBADFD); } - return stat_file(io, std_file->second.get_vita_loc(), statp, pref_path, base_tick, export_name, fd); + return stat_file(io, std_file->second.get_vita_loc(), statp, pref_path, export_name, fd); } int close_file(IOState &io, const SceUID fd, const char *export_name) { @@ -645,7 +645,7 @@ SceUID open_dir(IOState &io, const char *path, const std::wstring &pref_path, co return fd; } -SceUID read_dir(IOState &io, const SceUID fd, SceIoDirent *dent, const std::wstring &pref_path, const SceUInt64 base_tick, const char *export_name) { +SceUID read_dir(IOState &io, const SceUID fd, SceIoDirent *dent, const std::wstring &pref_path, const char *export_name) { assert(dent != nullptr); memset(dent->d_name, '\0', sizeof(dent->d_name)); @@ -669,12 +669,12 @@ SceUID read_dir(IOState &io, const SceUID fd, SceIoDirent *dent, const std::wstr const auto file_path = std::string(dir->second.get_vita_loc()) + '/' + d_name_utf8; LOG_TRACE_IF(log_file_op, "{}: Reading entry {} of fd: {}", export_name, file_path, log_hex(fd)); - if (stat_file(io, file_path.c_str(), &dent->d_stat, pref_path, base_tick, export_name) < 0) + if (stat_file(io, file_path.c_str(), &dent->d_stat, pref_path, export_name) < 0) return IO_ERROR(SCE_ERROR_ERRNO_EMFILE); else return 1; // move to the next file } - return read_dir(io, fd, dent, pref_path, base_tick, export_name); + return read_dir(io, fd, dent, pref_path, export_name); } return IO_ERROR(SCE_ERROR_ERRNO_EBADFD); diff --git a/vita3k/kernel/CMakeLists.txt b/vita3k/kernel/CMakeLists.txt index e42cc46be..5e16bc55a 100644 --- a/vita3k/kernel/CMakeLists.txt +++ b/vita3k/kernel/CMakeLists.txt @@ -1,20 +1,26 @@ -add_library( - kernel - STATIC +set(SOURCE_LIST include/kernel/functions.h include/kernel/state.h include/kernel/types.h - include/kernel/thread_data_queue.h + include/kernel/thread/thread_data_queue.h include/kernel/thread/thread_functions.h include/kernel/thread/thread_state.h include/kernel/thread/sync_primitives.h include/kernel/relocation.h + include/kernel/object_store.h src/kernel.cpp src/thread/thread.cpp src/thread/sync_primitives.cpp src/relocation.cpp ) +add_library( + kernel + STATIC + ${SOURCE_LIST} +) + target_include_directories(kernel PUBLIC include) -target_link_libraries(kernel PUBLIC rtc cpu mem util codec) +target_link_libraries(kernel PUBLIC rtc cpu mem util) target_link_libraries(kernel PRIVATE sdl2 miniz vita-toolchain) +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCE_LIST}) \ No newline at end of file diff --git a/vita3k/kernel/include/kernel/object_store.h b/vita3k/kernel/include/kernel/object_store.h new file mode 100644 index 000000000..0bc7b32fb --- /dev/null +++ b/vita3k/kernel/include/kernel/object_store.h @@ -0,0 +1,68 @@ +#pragma once + +#include +#include +#include + +// Brought form rpcs3 +class TypeInfo { + friend class ObjectStore; + // Global variable for each registered type + template + struct registered { + static const uint32_t index; + }; + + // Increment type counter + static uint32_t add_type(uint32_t i) { + static std::atomic g_next{ 0 }; + + return g_next.fetch_add(i); + } + +public: + template + static inline uint32_t get_index() { + return registered::index; + } + + static inline uint32_t get_count() { + return add_type(0); + } +}; + +template +const uint32_t TypeInfo::registered::index = TypeInfo::add_type(1); + +class ObjectStore { +public: + ObjectStore() {} + + ~ObjectStore() {} + + template + T *get() { + std::lock_guard lock(mutex); + auto it = objs.find(TypeInfo::registered::index); + assert(it != objs.end()); + return reinterpret_cast(it->second.get()); + } + + template + bool create(Args &&... args) { + std::lock_guard lock(mutex); + auto ptr = std::make_shared(std::forward(args)...); + objs.emplace(TypeInfo::registered::index, ptr); + return true; + } + template + void erase() { + auto it = objs.find(TypeInfo::registered::index); + assert(it != objs.end()); + objs.erase(it); + } + +private: + std::mutex mutex; + std::map> objs; +}; \ No newline at end of file diff --git a/vita3k/kernel/include/kernel/state.h b/vita3k/kernel/include/kernel/state.h index 58918148d..8ef23861e 100644 --- a/vita3k/kernel/include/kernel/state.h +++ b/vita3k/kernel/include/kernel/state.h @@ -17,16 +17,16 @@ #pragma once -#include #include +#include #include -#include #include #include #include #include #include +#include #include #include #include @@ -43,8 +43,6 @@ struct InitialFiber; struct CodecEngineBlock; -typedef std::vector InitialFibers; - typedef std::shared_ptr SceKernelMemBlockInfoPtr; typedef std::map Blocks; typedef std::map CodecEngineBlocks; @@ -61,196 +59,6 @@ typedef std::map WatchMemoryAddrs; typedef std::vector ModuleRegions; typedef Pool CPUPool; -struct MsgPipeData; - -struct WaitingThreadData { - ThreadStatePtr thread; - int32_t priority; - - // additional fields for each primitive - union { - struct { // mutex - int32_t lock_count; - }; - struct { // semaphore - int32_t signal; - }; - struct { // event flags - int32_t wait; - int32_t flags; - }; - // struct { }; // condvar - struct { //msgpipe - MsgPipeData *sending_data; - }; - }; - - bool operator>(const WaitingThreadData &rhs) const { - return priority > rhs.priority; - } - - bool operator==(const WaitingThreadData &rhs) const { - return thread == rhs.thread; - } - - bool operator==(const ThreadStatePtr &rhs) const { - return thread == rhs; - } -}; - -typedef std::unique_ptr> WaitingThreadQueuePtr; - -// NOTE: uid is copied to sync primitives here for debugging, -// not really needed since they are put in std::map's -struct SyncPrimitive { - SceUID uid; - - uint32_t attr; - - std::mutex mutex; - - char name[KERNELOBJECT_MAX_NAME_LENGTH + 1]; -}; - -struct Semaphore : SyncPrimitive { - WaitingThreadQueuePtr waiting_threads; - int max; - int val; -}; - -typedef std::shared_ptr SemaphorePtr; -typedef std::map SemaphorePtrs; - -struct Mutex : SyncPrimitive { - int init_count; - int lock_count; - ThreadStatePtr owner; - WaitingThreadQueuePtr waiting_threads; - Ptr workarea; -}; - -typedef std::shared_ptr MutexPtr; -typedef std::map MutexPtrs; - -struct EventFlag : SyncPrimitive { - WaitingThreadQueuePtr waiting_threads; - int flags; -}; - -typedef std::shared_ptr EventFlagPtr; -typedef std::map EventFlagPtrs; - -struct Condvar : SyncPrimitive { - struct SignalTarget { - enum class Type { - Any, // signal any one waiting thread - Specific, // signal a specific waiting thread (target_thread) - All, // signal all waiting threads - } type; - - SceUID thread_id; // for Type::One - - explicit SignalTarget(Type type) - : type(type) - , thread_id(0) {} - SignalTarget(Type type, SceUID thread_id) - : type(type) - , thread_id(thread_id) {} - }; - - WaitingThreadQueuePtr waiting_threads; - MutexPtr associated_mutex; -}; -typedef std::shared_ptr CondvarPtr; -typedef std::map CondvarPtrs; - -struct MsgPipeData { - std::vector data; - SceUID thread_id; - size_t read_size; - bool waiting_sender; - bool notify_at_empty; -}; - -// Unlimited buffer for now -struct MsgPipe : SyncPrimitive { - std::mutex recv_mutex; - WaitingThreadQueuePtr sender_threads; - WaitingThreadQueuePtr reciever_threads; - std::list data_buffer; -}; - -typedef std::shared_ptr MsgPipePtr; -typedef std::map MsgPipePtrs; - -struct WaitingThreadState { - std::string name; // for debugging -}; - -typedef std::map KernelWaitingThreadStates; - -typedef std::shared_ptr DecoderPtr; -typedef std::map DecoderStates; - -struct SceAvPlayerMemoryAllocator { - uint32_t user_data; - - // All of these should be cast to SceAvPlayerAllocator or SceAvPlayerDeallocator types. - Ptr general_allocator; - Ptr general_deallocator; - Ptr texture_allocator; - Ptr texture_deallocator; -}; - -struct SceAvPlayerFileManager { - uint32_t user_data; - - // Cast to SceAvPlayerOpenFile, SceAvPlayerCloseFile, SceAvPlayerReadFile and SceAvPlayerGetFileSize. - Ptr open_file; - Ptr close_file; - Ptr read_file; - Ptr file_size; -}; - -struct SceAvPlayerEventManager { - uint32_t user_data; - - // Cast to SceAvPlayerEventCallback. - Ptr event_callback; -}; - -struct PlayerInfoState { - PlayerState player; - - // Framebuffer count is defined in info. I'm being safe now and forcing it to 4 (even though its usually 2). - constexpr static uint32_t RING_BUFFER_COUNT = 4; - - uint32_t video_buffer_ring_index = 0; - uint32_t video_buffer_size = 0; - std::array, RING_BUFFER_COUNT> video_buffer; - - uint32_t audio_buffer_ring_index = 0; - uint32_t audio_buffer_size = 0; - std::array, RING_BUFFER_COUNT> audio_buffer; - - bool do_loop = false; - bool paused = false; - - uint64_t last_frame_time = 0; - SceAvPlayerMemoryAllocator memory_allocator; - SceAvPlayerFileManager file_manager; - SceAvPlayerEventManager event_manager; -}; - -typedef std::shared_ptr PlayerPtr; -typedef std::map PlayerStates; - -struct MJpegState { - bool initialized = false; - - AVCodecContext *decoder{}; -}; - struct CodecEngineBlock { uint32_t size; int32_t vaddr; @@ -289,14 +97,6 @@ typedef std::map TimerStates; using LoadedSysmodules = std::vector; -struct SceFiber; - -struct InitialFiber { - Address start; - Address end; - SceFiber *fiber; -}; - struct WatchMemory { Address start; size_t size; @@ -332,12 +132,10 @@ struct KernelState { CPUBackend cpu_backend; CPUProtocolBase *cpu_protocol; - InitialFibers initial_fibers; + ObjectStore obj_store; + SceRtcTick start_tick; SceRtcTick base_tick; - DecoderPtr mjpeg_state; - DecoderStates decoders; - PlayerStates players; TimerStates timers; Ptr process_param; diff --git a/vita3k/kernel/include/kernel/thread/sync_primitives.h b/vita3k/kernel/include/kernel/thread/sync_primitives.h index 0ad5c6b66..a9a447343 100644 --- a/vita3k/kernel/include/kernel/thread/sync_primitives.h +++ b/vita3k/kernel/include/kernel/thread/sync_primitives.h @@ -17,7 +17,138 @@ #pragma once -#include +#include +#include +#include + +struct MsgPipeData; +struct KernelState; + +struct WaitingThreadData { + ThreadStatePtr thread; + int32_t priority; + + // additional fields for each primitive + union { + struct { // mutex + int32_t lock_count; + }; + struct { // semaphore + int32_t signal; + }; + struct { // event flags + int32_t wait; + int32_t flags; + }; + // struct { }; // condvar + struct { //msgpipe + MsgPipeData *sending_data; + }; + }; + + bool operator>(const WaitingThreadData &rhs) const { + return priority > rhs.priority; + } + + bool operator==(const WaitingThreadData &rhs) const { + return thread == rhs.thread; + } + + bool operator==(const ThreadStatePtr &rhs) const { + return thread == rhs; + } +}; + +typedef std::unique_ptr> WaitingThreadQueuePtr; + +// NOTE: uid is copied to sync primitives here for debugging, +// not really needed since they are put in std::map's +struct SyncPrimitive { + SceUID uid; + + uint32_t attr; + + std::mutex mutex; + + char name[KERNELOBJECT_MAX_NAME_LENGTH + 1]; +}; + +struct Semaphore : SyncPrimitive { + WaitingThreadQueuePtr waiting_threads; + int max; + int val; +}; + +typedef std::shared_ptr SemaphorePtr; +typedef std::map SemaphorePtrs; + +struct Mutex : SyncPrimitive { + int init_count; + int lock_count; + ThreadStatePtr owner; + WaitingThreadQueuePtr waiting_threads; + Ptr workarea; +}; + +typedef std::shared_ptr MutexPtr; +typedef std::map MutexPtrs; + +struct EventFlag : SyncPrimitive { + WaitingThreadQueuePtr waiting_threads; + int flags; +}; + +typedef std::shared_ptr EventFlagPtr; +typedef std::map EventFlagPtrs; + +struct Condvar : SyncPrimitive { + struct SignalTarget { + enum class Type { + Any, // signal any one waiting thread + Specific, // signal a specific waiting thread (target_thread) + All, // signal all waiting threads + } type; + + SceUID thread_id; // for Type::One + + explicit SignalTarget(Type type) + : type(type) + , thread_id(0) {} + SignalTarget(Type type, SceUID thread_id) + : type(type) + , thread_id(thread_id) {} + }; + + WaitingThreadQueuePtr waiting_threads; + MutexPtr associated_mutex; +}; +typedef std::shared_ptr CondvarPtr; +typedef std::map CondvarPtrs; + +struct MsgPipeData { + std::vector data; + SceUID thread_id; + size_t read_size; + bool waiting_sender; + bool notify_at_empty; +}; + +// Unlimited buffer for now +struct MsgPipe : SyncPrimitive { + std::mutex recv_mutex; + WaitingThreadQueuePtr sender_threads; + WaitingThreadQueuePtr reciever_threads; + std::list data_buffer; +}; + +typedef std::shared_ptr MsgPipePtr; +typedef std::map MsgPipePtrs; + +struct WaitingThreadState { + std::string name; // for debugging +}; + +typedef std::map KernelWaitingThreadStates; enum class SyncWeight { Light, // lightweight diff --git a/vita3k/kernel/include/kernel/thread_data_queue.h b/vita3k/kernel/include/kernel/thread/thread_data_queue.h similarity index 100% rename from vita3k/kernel/include/kernel/thread_data_queue.h rename to vita3k/kernel/include/kernel/thread/thread_data_queue.h diff --git a/vita3k/main.cpp b/vita3k/main.cpp index 48fde494f..99b6e771b 100644 --- a/vita3k/main.cpp +++ b/vita3k/main.cpp @@ -17,6 +17,7 @@ #include "interface.h" +#include "cpu_protocol.h" #include #include #include @@ -134,6 +135,8 @@ int main(int argc, char *argv[]) { return HostInitFailed; } + init_libraries(host); + GuiState gui; if (!cfg.console) gui::init(gui, host); diff --git a/vita3k/module/include/module/bridge.h b/vita3k/module/include/module/bridge.h index 165ae7e91..743e46fc7 100644 --- a/vita3k/module/include/module/bridge.h +++ b/vita3k/module/include/module/bridge.h @@ -22,12 +22,13 @@ #include "vargs.h" #include "write_return_value.h" -#include -#include #include #include +using ImportFn = std::function; +using ImportVarFactory = std::function; + // Function returns a value that is written to CPU registers. template std::enable_if_t> call(Ret (*export_fn)(HostState &, SceUID, const char *, Args...), const char *export_name, const ArgsLayout &args_layout, const LayoutArgsState &state, std::index_sequence, SceUID thread_id, CPUState &cpu, HostState &host) { diff --git a/vita3k/module/include/module/module.h b/vita3k/module/include/module/module.h index 7231cc389..069f4df58 100644 --- a/vita3k/module/include/module/module.h +++ b/vita3k/module/include/module/module.h @@ -37,4 +37,4 @@ int stubbed_impl(const char *name, const char *info); #define VAR_BRIDGE_DECL(name) extern const ImportVarFactory import_##name; #define VAR_BRIDGE_IMPL(name) const ImportVarFactory import_##name = export_##name; -#define VAR_EXPORT(name) Address export_##name(HostState &host) +#define VAR_EXPORT(name) Address export_##name(HostState &host) \ No newline at end of file diff --git a/vita3k/modules/CMakeLists.txt b/vita3k/modules/CMakeLists.txt index 7dde862ec..fcca7c474 100644 --- a/vita3k/modules/CMakeLists.txt +++ b/vita3k/modules/CMakeLists.txt @@ -1,5 +1,5 @@ -add_library(modules STATIC - module_parent.cpp include/modules/module_parent.h +set(SOURCE_LIST + module_parent.cpp include/modules/module_parent.h include/modules/library_init_list.inc SceAVConfig/SceAVConfig.cpp SceAVConfig/SceAVConfig.h SceAppMgr/SceAppMgr.cpp SceAppMgr/SceAppMgr.h @@ -198,6 +198,11 @@ add_library(modules STATIC SceVshBridge/SceVshBridge.cpp SceVshBridge/SceVshBridge.h SceWlanBt/SceWlan.cpp SceWlanBt/SceWlan.h ) + +add_library(modules STATIC + ${SOURCE_LIST} +) target_include_directories(modules PUBLIC include) target_link_libraries(modules PRIVATE xxHash::xxhash) target_link_libraries(modules PUBLIC module) +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCE_LIST}) diff --git a/vita3k/modules/SceAudiodec/SceAudiodecUser.cpp b/vita3k/modules/SceAudiodec/SceAudiodecUser.cpp index 71ad95489..073e01a1a 100644 --- a/vita3k/modules/SceAudiodec/SceAudiodecUser.cpp +++ b/vita3k/modules/SceAudiodec/SceAudiodecUser.cpp @@ -17,6 +17,7 @@ #include "SceAudiodecUser.h" +#include #include enum { @@ -30,6 +31,14 @@ enum { SCE_AUDIODEC_MP3_MPEG_VERSION_1, }; +typedef std::shared_ptr DecoderPtr; +typedef std::map DecoderStates; + +struct AudiodecState { + std::mutex mutex; + DecoderStates decoders; +}; + struct SceAudiodecInfoAt9 { uint32_t config_data; uint32_t channels; @@ -86,7 +95,8 @@ EXPORT(int, sceAudiodecClearContext) { } EXPORT(int, sceAudiodecCreateDecoder, SceAudiodecCtrl *ctrl, SceAudiodecCodec codec) { - std::lock_guard lock(host.kernel.mutex); + const auto state = host.kernel.obj_store.get(); + std::lock_guard lock(state->mutex); SceUID handle = host.kernel.get_next_uid(); ctrl->handle = handle; @@ -95,7 +105,7 @@ EXPORT(int, sceAudiodecCreateDecoder, SceAudiodecCtrl *ctrl, SceAudiodecCodec co case SCE_AUDIODEC_TYPE_AT9: { SceAudiodecInfoAt9 &info = ctrl->info.get(host.mem)->at9; DecoderPtr decoder = std::make_shared(info.config_data); - host.kernel.decoders[handle] = decoder; + state->decoders[handle] = decoder; ctrl->es_size_max = decoder->get(DecoderQuery::AT9_SUPERFRAME_SIZE); ctrl->pcm_size_max = decoder->get(DecoderQuery::AT9_SAMPLE_PER_SUPERFRAME) @@ -110,7 +120,7 @@ EXPORT(int, sceAudiodecCreateDecoder, SceAudiodecCtrl *ctrl, SceAudiodecCodec co case SCE_AUDIODEC_TYPE_MP3: { SceAudiodecInfoMp3 &info = ctrl->info.get(host.mem)->mp3; DecoderPtr decoder = std::make_shared(info.channels); - host.kernel.decoders[handle] = decoder; + state->decoders[handle] = decoder; ctrl->es_size_max = 1441; @@ -142,7 +152,8 @@ EXPORT(int, sceAudiodecCreateDecoderResident) { } EXPORT(int, sceAudiodecDecode, SceAudiodecCtrl *ctrl) { - const DecoderPtr &decoder = lock_and_find(ctrl->handle, host.kernel.decoders, host.kernel.mutex); + const auto state = host.kernel.obj_store.get(); + const DecoderPtr &decoder = lock_and_find(ctrl->handle, state->decoders, state->mutex); DecoderSize size = {}; @@ -168,8 +179,9 @@ EXPORT(int, sceAudiodecDecodeNStreams) { } EXPORT(int, sceAudiodecDeleteDecoder, SceAudiodecCtrl *ctrl) { - std::lock_guard lock(host.kernel.mutex); - host.kernel.decoders.erase(ctrl->handle); + const auto state = host.kernel.obj_store.get(); + std::lock_guard lock(state->mutex); + state->decoders.erase(ctrl->handle); return 0; } @@ -192,7 +204,8 @@ EXPORT(int, sceAudiodecGetInternalError) { } EXPORT(SceInt32, sceAudiodecInitLibrary, SceUInt32 codecType, SceAudiodecInitParam *pInitParam) { - return STUBBED("EMPTY"); + host.kernel.obj_store.create(); + return 0; } EXPORT(int, sceAudiodecPartlyDecode) { @@ -200,7 +213,8 @@ EXPORT(int, sceAudiodecPartlyDecode) { } EXPORT(SceInt32, sceAudiodecTermLibrary, SceUInt32 codecType) { - return STUBBED("EMPTY"); + host.kernel.obj_store.erase(); + return 0; } BRIDGE_IMPL(sceAudiodecClearContext) diff --git a/vita3k/modules/SceAvPlayer/SceAvPlayer.cpp b/vita3k/modules/SceAvPlayer/SceAvPlayer.cpp index 67ae4f833..88b774af8 100644 --- a/vita3k/modules/SceAvPlayer/SceAvPlayer.cpp +++ b/vita3k/modules/SceAvPlayer/SceAvPlayer.cpp @@ -17,6 +17,7 @@ #include "SceAvPlayer.h" +#include #include #include #include @@ -40,6 +41,65 @@ typedef uint64_t (*SceAvPlayerGetFileSize)(void *arguments); typedef void (*SceAvPlayerEventCallback)(void *arguments, int32_t event_id, int32_t source_id, void *event_data); +struct PlayerInfoState; +typedef std::shared_ptr PlayerPtr; +typedef std::map PlayerStates; + +struct AvPlayerState { + std::mutex mutex; + PlayerStates players; +}; + +struct SceAvPlayerMemoryAllocator { + uint32_t user_data; + + // All of these should be cast to SceAvPlayerAllocator or SceAvPlayerDeallocator types. + Ptr general_allocator; + Ptr general_deallocator; + Ptr texture_allocator; + Ptr texture_deallocator; +}; + +struct SceAvPlayerFileManager { + uint32_t user_data; + + // Cast to SceAvPlayerOpenFile, SceAvPlayerCloseFile, SceAvPlayerReadFile and SceAvPlayerGetFileSize. + Ptr open_file; + Ptr close_file; + Ptr read_file; + Ptr file_size; +}; + +struct SceAvPlayerEventManager { + uint32_t user_data; + + // Cast to SceAvPlayerEventCallback. + Ptr event_callback; +}; + +struct PlayerInfoState { + PlayerState player; + + // Framebuffer count is defined in info. I'm being safe now and forcing it to 4 (even though its usually 2). + constexpr static uint32_t RING_BUFFER_COUNT = 4; + + uint32_t video_buffer_ring_index = 0; + uint32_t video_buffer_size = 0; + std::array, RING_BUFFER_COUNT> video_buffer; + + uint32_t audio_buffer_ring_index = 0; + uint32_t audio_buffer_size = 0; + std::array, RING_BUFFER_COUNT> audio_buffer; + + bool do_loop = false; + bool paused = false; + + uint64_t last_frame_time = 0; + SceAvPlayerMemoryAllocator memory_allocator; + SceAvPlayerFileManager file_manager; + SceAvPlayerEventManager event_manager; +}; + enum class DebugLevel { NONE, INFO, @@ -175,7 +235,8 @@ uint run_event_callback(HostState &host, SceUID thread_id, const PlayerPtr playe //end of callback_thread EXPORT(int32_t, sceAvPlayerAddSource, SceUID player_handle, Ptr path) { - const PlayerPtr &player_info = lock_and_find(player_handle, host.kernel.players, host.kernel.mutex); + const auto state = host.kernel.obj_store.get(); + const PlayerPtr &player_info = lock_and_find(player_handle, state->players, state->mutex); auto file_path = expand_path(host.io, path.get(host.mem), host.pref_path); if (!fs::exists(file_path) && player_info->file_manager.open_file && player_info->file_manager.close_file && player_info->file_manager.read_file && player_info->file_manager.file_size) { @@ -220,14 +281,17 @@ EXPORT(int32_t, sceAvPlayerAddSource, SceUID player_handle, Ptr path } EXPORT(int, sceAvPlayerClose, SceUID player_handle) { - const PlayerPtr &player_info = lock_and_find(player_handle, host.kernel.players, host.kernel.mutex); + const auto state = host.kernel.obj_store.get(); + const PlayerPtr &player_info = lock_and_find(player_handle, state->players, state->mutex); run_event_callback(host, thread_id, player_info, SCE_AVPLAYER_STATE_STOP, 0, Ptr(0)); - host.kernel.players.erase(player_handle); + std::lock_guard lock(state->mutex); + state->players.erase(player_handle); return 0; } EXPORT(uint64_t, sceAvPlayerCurrentTime, SceUID player_handle) { - const PlayerPtr &player_info = lock_and_find(player_handle, host.kernel.players, host.kernel.mutex); + const auto state = host.kernel.obj_store.get(); + const PlayerPtr &player_info = lock_and_find(player_handle, state->players, state->mutex); return player_info->player.last_timestamp; } @@ -252,7 +316,8 @@ EXPORT(int32_t, sceAvPlayerEnableStream, SceUID player_handle, uint32_t stream_n } EXPORT(bool, sceAvPlayerGetAudioData, SceUID player_handle, SceAvPlayerFrameInfo *frame_info) { - const PlayerPtr &player_info = lock_and_find(player_handle, host.kernel.players, host.kernel.mutex); + const auto state = host.kernel.obj_store.get(); + const PlayerPtr &player_info = lock_and_find(player_handle, state->players, state->mutex); Ptr buffer; @@ -292,7 +357,8 @@ EXPORT(uint32_t, sceAvPlayerGetStreamInfo, SceUID player_handle, uint stream_no, return SCE_AVPLAYER_ERROR_ILLEGAL_ADDR; } STUBBED("ALWAYS SUSPECTS 2 STREAMS: VIDEO AND AUDIO"); - const PlayerPtr &player_info = lock_and_find(player_handle, host.kernel.players, host.kernel.mutex); + const auto state = host.kernel.obj_store.get(); + const PlayerPtr &player_info = lock_and_find(player_handle, state->players, state->mutex); auto StreamInfo = stream_info.get(host.mem); if (stream_no == 0) { //suspect always two streams: audio and video //first is video DecoderSize size = player_info->player.get_size(); @@ -315,7 +381,8 @@ EXPORT(uint32_t, sceAvPlayerGetStreamInfo, SceUID player_handle, uint stream_no, } EXPORT(bool, sceAvPlayerGetVideoData, SceUID player_handle, SceAvPlayerFrameInfo *frame_info) { - const PlayerPtr &player_info = lock_and_find(player_handle, host.kernel.players, host.kernel.mutex); + const auto state = host.kernel.obj_store.get(); + const PlayerPtr &player_info = lock_and_find(player_handle, state->players, state->mutex); Ptr buffer; @@ -363,10 +430,12 @@ EXPORT(bool, sceAvPlayerGetVideoDataEx, SceUID player_handle, SceAvPlayerFrameIn } EXPORT(SceUID, sceAvPlayerInit, SceAvPlayerInfo *info) { + host.kernel.obj_store.create(); if (host.cfg.current_config.video_playing) { + const auto state = host.kernel.obj_store.get(); SceUID player_handle = host.kernel.get_next_uid(); PlayerPtr player = std::make_shared(); - host.kernel.players[player_handle] = player; + state->players[player_handle] = player; LOG_TRACE("SceAvPlayerInfo.memory_allocator: user_data:{}, general_allocator:{}, general_deallocator:{}, texture_allocator:{}, texture_deallocator:{}", log_hex(info->memory_allocator.user_data), log_hex(info->memory_allocator.general_allocator.address()), log_hex(info->memory_allocator.general_deallocator.address()), @@ -393,7 +462,8 @@ EXPORT(SceUID, sceAvPlayerInit, SceAvPlayerInfo *info) { } EXPORT(bool, sceAvPlayerIsActive, SceUID player_handle) { - const PlayerPtr &player_info = lock_and_find(player_handle, host.kernel.players, host.kernel.mutex); + const auto state = host.kernel.obj_store.get(); + const PlayerPtr &player_info = lock_and_find(player_handle, state->players, state->mutex); return !player_info->player.video_playing.empty(); } @@ -403,7 +473,8 @@ EXPORT(int, sceAvPlayerJumpToTime) { } EXPORT(int, sceAvPlayerPause, SceUID player_handle) { - const PlayerPtr &player_info = lock_and_find(player_handle, host.kernel.players, host.kernel.mutex); + const auto state = host.kernel.obj_store.get(); + const PlayerPtr &player_info = lock_and_find(player_handle, state->players, state->mutex); player_info->paused = true; run_event_callback(host, thread_id, player_info, SCE_AVPLAYER_STATE_PAUSE, 0, Ptr(0)); return 0; @@ -414,7 +485,8 @@ EXPORT(int, sceAvPlayerPostInit) { } EXPORT(int, sceAvPlayerResume, SceUID player_handle) { - const PlayerPtr &player_info = lock_and_find(player_handle, host.kernel.players, host.kernel.mutex); + const auto state = host.kernel.obj_store.get(); + const PlayerPtr &player_info = lock_and_find(player_handle, state->players, state->mutex); if (!player_info->paused) { run_event_callback(host, thread_id, player_info, SCE_AVPLAYER_STATE_PLAY, 0, Ptr(0)); } @@ -423,7 +495,8 @@ EXPORT(int, sceAvPlayerResume, SceUID player_handle) { } EXPORT(int, sceAvPlayerSetLooping, SceUID player_handle, bool do_loop) { - const PlayerPtr &player_info = lock_and_find(player_handle, host.kernel.players, host.kernel.mutex); + const auto state = host.kernel.obj_store.get(); + const PlayerPtr &player_info = lock_and_find(player_handle, state->players, state->mutex); player_info->do_loop = do_loop; return STUBBED("LOOPING NOT IMPLEMENTED"); @@ -434,7 +507,8 @@ EXPORT(int, sceAvPlayerSetTrickSpeed) { } EXPORT(int, sceAvPlayerStart, SceUID player_handle) { - const PlayerPtr &player_info = lock_and_find(player_handle, host.kernel.players, host.kernel.mutex); + const auto state = host.kernel.obj_store.get(); + const PlayerPtr &player_info = lock_and_find(player_handle, state->players, state->mutex); if (!player_info->player.videos_queue.empty()) { player_info->player.pop_video(); } @@ -443,7 +517,8 @@ EXPORT(int, sceAvPlayerStart, SceUID player_handle) { } EXPORT(int, sceAvPlayerStop, SceUID player_handle) { - const PlayerPtr &player_info = lock_and_find(player_handle, host.kernel.players, host.kernel.mutex); + const auto state = host.kernel.obj_store.get(); + const PlayerPtr &player_info = lock_and_find(player_handle, state->players, host.kernel.mutex); player_info->player.free_video(); run_event_callback(host, thread_id, player_info, SCE_AVPLAYER_STATE_STOP, 0, Ptr(0)); return 0; diff --git a/vita3k/modules/SceFiber/SceFiber.cpp b/vita3k/modules/SceFiber/SceFiber.cpp index dbf56c760..81bdc5f5a 100644 --- a/vita3k/modules/SceFiber/SceFiber.cpp +++ b/vita3k/modules/SceFiber/SceFiber.cpp @@ -24,10 +24,27 @@ const static int DEFAULT_FIBER_STACK_SIZE = 4096; -InitialFiber *_findIntialFiber(KernelState &kernel, Address sp) { +struct InitialFiber { + Address start; + Address end; + SceFiber *fiber; +}; + +typedef std::vector InitialFibers; + +struct FiberState { + InitialFibers initial_fibers; +}; + +LIBRARY_INIT_IMPL(SceFiber) { + host.kernel.obj_store.create(); +} +LIBRARY_INIT_REGISTER(SceFiber) + +InitialFiber *_findIntialFiber(FiberState &state, Address sp) { // TODO use interval tree // TODO destroy initial fibers - for (auto &ifiber : kernel.initial_fibers) { + for (auto &ifiber : state.initial_fibers) { // stack adress is descending if (ifiber.start <= sp && sp <= ifiber.end) { return &ifiber; @@ -36,22 +53,23 @@ InitialFiber *_findIntialFiber(KernelState &kernel, Address sp) { return nullptr; } -void _resetFiber(HostState &host, SceFiber *fiber) { - auto ifiber = _findIntialFiber(host.kernel, fiber->cpu->get_sp()); +void _resetFiber(FiberState &state, MemState &mem, SceFiber *fiber) { + auto ifiber = _findIntialFiber(state, fiber->cpu->get_sp()); assert(ifiber); const auto cpu = fiber->cpu; *fiber = *ifiber->fiber; fiber->cpu = cpu; *fiber->cpu = *ifiber->fiber->cpu; - memset(Ptr(ifiber->start).get(host.mem), 0xCC, ifiber->end - ifiber->start); + memset(Ptr(ifiber->start).get(mem), 0xCC, ifiber->end - ifiber->start); } int _fiberSwitch(HostState &host, const ThreadStatePtr thread, SceFiber *fiber, CPUContext &backup_cpu_context, SceUInt32 argOnRunTo, Ptr argOnRun, bool reset) { + const auto state = host.kernel.obj_store.get(); backup_cpu_context = save_context(*thread->cpu); bool suspended = false; if (fiber->addrContext == 0 && reset) { - _resetFiber(host, fiber); + _resetFiber(*state, host.mem, fiber); } else if (fiber->entry.address() == fiber->cpu->get_pc()) { fiber->cpu->cpu_registers[1] = argOnRunTo; } else { @@ -70,6 +88,7 @@ int _fiberSwitch(HostState &host, const ThreadStatePtr thread, SceFiber *fiber, } void _initializeFiber(HostState &host, const ThreadStatePtr thread, SceFiber *fiber, const char *name, Ptr entry, SceUInt32 argOnInitialize, Ptr addrContext, SceSize sizeContext, SceFiberOptParam *params) { + const auto state = host.kernel.obj_store.get(); fiber->entry = entry; strncpy(fiber->name, name, 32); fiber->argOnInitialize = argOnInitialize; @@ -101,7 +120,7 @@ void _initializeFiber(HostState &host, const ThreadStatePtr thread, SceFiber *fi ifiber.start = addrContext.address(); ifiber.end = addrContext.address() + sizeContext; ifiber.fiber = fiberCopy; - host.kernel.initial_fibers.push_back(ifiber); + state->initial_fibers.push_back(ifiber); } EXPORT(int, _sceFiberAttachContextAndRun, SceFiber *fiber, Address addrContext, SceSize sizeContext, SceUInt32 argOnRunTo, Ptr argOnRun) { @@ -218,6 +237,7 @@ EXPORT(int, sceFiberRenameSelf) { } EXPORT(SceInt32, sceFiberReturnToThread, SceUInt32 argOnReturn, Ptr argOnRun) { + const auto state = host.kernel.obj_store.get(); const ThreadStatePtr thread = lock_and_find(thread_id, host.kernel.threads, host.kernel.mutex); auto fiber = thread->fiber.cast().get(host.mem); (*thread->fiber.cast().get(host.mem)->cpu) = save_context(*thread->cpu); @@ -225,7 +245,7 @@ EXPORT(SceInt32, sceFiberReturnToThread, SceUInt32 argOnReturn, Ptr a Address previousArgOnRun = thread->cpu_context.cpu_registers[2]; if (fiber->addrContext == 0) { - _resetFiber(host, fiber); + _resetFiber(*state, host.mem, fiber); } else if (previousArgOnRun) { *(Ptr(previousArgOnRun).get(host.mem)) = argOnReturn; } diff --git a/vita3k/modules/SceFiber/SceFiber.h b/vita3k/modules/SceFiber/SceFiber.h index a99158b8a..ee7ea0bb6 100644 --- a/vita3k/modules/SceFiber/SceFiber.h +++ b/vita3k/modules/SceFiber/SceFiber.h @@ -18,6 +18,7 @@ #pragma once #include +#include #define SCE_FIBER_CONTEXT_MINIMUM_SIZE 512 @@ -49,6 +50,7 @@ typedef struct SceFiber { CPUContext *cpu; } SceFiber; +LIBRARY_INIT_DECL(SceFiber) BRIDGE_DECL(_sceFiberAttachContextAndRun) BRIDGE_DECL(_sceFiberAttachContextAndSwitch) BRIDGE_DECL(_sceFiberInitializeImpl) diff --git a/vita3k/modules/SceIofilemgr/SceIofilemgr.cpp b/vita3k/modules/SceIofilemgr/SceIofilemgr.cpp index 5b98ba32b..5fd2e7aec 100644 --- a/vita3k/modules/SceIofilemgr/SceIofilemgr.cpp +++ b/vita3k/modules/SceIofilemgr/SceIofilemgr.cpp @@ -51,11 +51,11 @@ EXPORT(int, _sceIoDread, const SceUID fd, SceIoDirent *dir) { if (dir == nullptr) { return RET_ERROR(SCE_KERNEL_ERROR_ILLEGAL_ADDR); } - return read_dir(host.io, fd, dir, host.pref_path, host.kernel.base_tick.tick, export_name); + return read_dir(host.io, fd, dir, host.pref_path, export_name); } EXPORT(int, _sceIoGetstat, const char *file, SceIoStat *stat) { - return stat_file(host.io, file, stat, host.pref_path, host.kernel.base_tick.tick, export_name); + return stat_file(host.io, file, stat, host.pref_path, export_name); } EXPORT(int, _sceIoGetstatAsync) { @@ -63,7 +63,7 @@ EXPORT(int, _sceIoGetstatAsync) { } EXPORT(int, _sceIoGetstatByFd, const SceUID fd, SceIoStat *stat) { - return stat_file_by_fd(host.io, fd, stat, host.pref_path, host.kernel.base_tick.tick, export_name); + return stat_file_by_fd(host.io, fd, stat, host.pref_path, export_name); } EXPORT(int, _sceIoIoctl) { diff --git a/vita3k/modules/SceJpeg/SceJpegUser.cpp b/vita3k/modules/SceJpeg/SceJpegUser.cpp index 98452ad70..450220e3c 100644 --- a/vita3k/modules/SceJpeg/SceJpegUser.cpp +++ b/vita3k/modules/SceJpeg/SceJpegUser.cpp @@ -19,6 +19,13 @@ #include +typedef std::shared_ptr DecoderPtr; + +struct MJpegState { + bool initialized = false; + DecoderPtr decoder; +}; + struct SceJpegMJpegInitInfo { uint32_t size; int32_t decoder_count; @@ -54,13 +61,12 @@ EXPORT(int, sceJpegDecodeMJpeg) { EXPORT(int, sceJpegDecodeMJpegYCbCr, const uint8_t *jpeg_data, uint32_t jpeg_size, uint8_t *output, uint32_t output_size, int mode, void *buffer, uint32_t buffer_size) { - if (!host.kernel.mjpeg_state) - return -1; + const auto state = host.kernel.obj_store.get(); DecoderSize size = {}; - host.kernel.mjpeg_state->send(jpeg_data, jpeg_size); - host.kernel.mjpeg_state->receive(output, &size); + state->decoder->send(jpeg_data, jpeg_size); + state->decoder->receive(output, &size); // Top 16 bits = width, bottom 16 bits = height. return (size.width << 16u) | size.height; @@ -71,20 +77,19 @@ EXPORT(int, sceJpegDeleteSplitDecoder) { } EXPORT(int, sceJpegFinishMJpeg) { - host.kernel.mjpeg_state.reset(); + host.kernel.obj_store.erase(); return 0; } EXPORT(int, sceJpegGetOutputInfo, const uint8_t *jpeg_data, uint32_t jpeg_size, int32_t format, int32_t mode, SceJpegOutputInfo *output) { - if (!host.kernel.mjpeg_state) - return -1; + const auto state = host.kernel.obj_store.get(); DecoderSize size = {}; - host.kernel.mjpeg_state->send(jpeg_data, jpeg_size); - host.kernel.mjpeg_state->receive(nullptr, &size); + state->decoder->send(jpeg_data, jpeg_size); + state->decoder->receive(nullptr, &size); output->width = size.width; output->height = size.height; @@ -96,13 +101,17 @@ EXPORT(int, sceJpegGetOutputInfo, const uint8_t *jpeg_data, uint32_t jpeg_size, // TODO: Decoder options are ignored for the time being. EXPORT(int, sceJpegInitMJpeg, int32_t decoder_count) { - host.kernel.mjpeg_state = std::make_shared(); + host.kernel.obj_store.create(); + const auto state = host.kernel.obj_store.get(); + state->decoder = std::make_shared(); return 0; } EXPORT(int, sceJpegInitMJpegWithParam, const SceJpegMJpegInitInfo *info) { - host.kernel.mjpeg_state = std::make_shared(); + host.kernel.obj_store.create(); + const auto state = host.kernel.obj_store.get(); + state->decoder = std::make_shared(); return 0; } diff --git a/vita3k/modules/SceJpeg/SceJpegUser.h b/vita3k/modules/SceJpeg/SceJpegUser.h index 547cd7b9f..7a86540c2 100644 --- a/vita3k/modules/SceJpeg/SceJpegUser.h +++ b/vita3k/modules/SceJpeg/SceJpegUser.h @@ -18,6 +18,7 @@ #pragma once #include +#include BRIDGE_DECL(sceJpegCreateSplitDecoder) BRIDGE_DECL(sceJpegCsc) diff --git a/vita3k/modules/SceLibKernel/SceLibKernel.cpp b/vita3k/modules/SceLibKernel/SceLibKernel.cpp index 67e1f9404..9a5242833 100644 --- a/vita3k/modules/SceLibKernel/SceLibKernel.cpp +++ b/vita3k/modules/SceLibKernel/SceLibKernel.cpp @@ -397,7 +397,7 @@ EXPORT(int, sceIoGetstatAsync) { } EXPORT(int, sceIoGetstatByFd, const SceUID fd, SceIoStat *stat) { - return stat_file_by_fd(host.io, fd, stat, host.pref_path, host.kernel.base_tick.tick, export_name); + return stat_file_by_fd(host.io, fd, stat, host.pref_path, export_name); } EXPORT(int, sceIoIoctl) { diff --git a/vita3k/modules/SceVideodec/SceVideodecUser.cpp b/vita3k/modules/SceVideodec/SceVideodecUser.cpp index bd019d58f..aaa136c85 100644 --- a/vita3k/modules/SceVideodec/SceVideodecUser.cpp +++ b/vita3k/modules/SceVideodec/SceVideodecUser.cpp @@ -16,9 +16,17 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "SceVideodecUser.h" - +#include #include +typedef std::shared_ptr DecoderPtr; +typedef std::map DecoderStates; + +struct VideodecState { + std::mutex mutex; + DecoderStates decoders; +}; + enum SceVideodecType { SCE_VIDEODEC_TYPE_HW_AVCDEC = 0x1001 }; @@ -119,11 +127,11 @@ struct SceAvcdecArrayPicture { EXPORT(int, sceAvcdecCreateDecoder, uint32_t codec_type, SceAvcdecCtrl *decoder, const SceAvcdecQueryDecoderInfo *query) { assert(codec_type == SCE_VIDEODEC_TYPE_HW_AVCDEC); - + const auto state = host.kernel.obj_store.get(); SceUID handle = host.kernel.get_next_uid(); decoder->handle = handle; - host.kernel.decoders[handle] = std::make_shared(query->horizontal, query->vertical); + state->decoders[handle] = std::make_shared(query->horizontal, query->vertical); return 0; } @@ -145,7 +153,8 @@ EXPORT(int, sceAvcdecCscInternal) { } EXPORT(int, sceAvcdecDecode, SceAvcdecCtrl *decoder, const SceAvcdecAu *au, SceAvcdecArrayPicture *picture) { - const DecoderPtr &decoder_info = lock_and_find(decoder->handle, host.kernel.decoders, host.kernel.mutex); + const auto state = host.kernel.obj_store.get(); + const DecoderPtr &decoder_info = lock_and_find(decoder->handle, state->decoders, state->mutex); H264DecoderOptions options = {}; options.pts_upper = au->pts.upper; @@ -183,14 +192,16 @@ EXPORT(int, sceAvcdecDecodeAuNongameapp) { } EXPORT(int, sceAvcdecDecodeAvailableSize, SceAvcdecCtrl *decoder) { - const DecoderPtr &decoder_info = lock_and_find(decoder->handle, host.kernel.decoders, host.kernel.mutex); + const auto state = host.kernel.obj_store.get(); + const DecoderPtr &decoder_info = lock_and_find(decoder->handle, state->decoders, state->mutex); return H264DecoderState::buffer_size( { decoder_info->get(DecoderQuery::WIDTH), decoder_info->get(DecoderQuery::HEIGHT) }); } EXPORT(int, sceAvcdecDecodeFlush, SceAvcdecCtrl *decoder) { - const DecoderPtr &decoder_info = lock_and_find(decoder->handle, host.kernel.decoders, host.kernel.mutex); + const auto state = host.kernel.obj_store.get(); + const DecoderPtr &decoder_info = lock_and_find(decoder->handle, state->decoders, state->mutex); decoder_info->flush(); @@ -226,7 +237,8 @@ EXPORT(int, sceAvcdecDecodeSetUserDataSei1FieldMemSizeNongameapp) { } EXPORT(int, sceAvcdecDecodeStop, SceAvcdecCtrl *decoder, SceAvcdecArrayPicture *picture) { - const DecoderPtr &decoder_info = lock_and_find(decoder->handle, host.kernel.decoders, host.kernel.mutex); + const auto state = host.kernel.obj_store.get(); + const DecoderPtr &decoder_info = lock_and_find(decoder->handle, state->decoders, state->mutex); uint8_t *output = picture->pPicture.get(host.mem)[0].get(host.mem)->frame.pPicture[0].cast().get(host.mem); decoder_info->receive(output); @@ -243,7 +255,9 @@ EXPORT(int, sceAvcdecDecodeWithWorkPicture) { } EXPORT(int, sceAvcdecDeleteDecoder, SceAvcdecCtrl *decoder) { - host.kernel.decoders.erase(decoder->handle); + const auto state = host.kernel.obj_store.get(); + std::lock_guard lock(state->mutex); + state->decoders.erase(decoder->handle); return 0; } @@ -366,11 +380,13 @@ EXPORT(int, sceM4vdecQueryDecoderMemSizeInternal) { } EXPORT(int, sceVideodecInitLibrary) { - return STUBBED("EMPTY"); + host.kernel.obj_store.create(); + return 0; } EXPORT(int, sceVideodecInitLibraryInternal) { - return UNIMPLEMENTED(); + host.kernel.obj_store.create(); + return 0; } EXPORT(int, sceVideodecInitLibraryNongameapp) { @@ -415,7 +431,8 @@ EXPORT(int, sceVideodecSetConfigInternal) { } EXPORT(int, sceVideodecTermLibrary) { - return UNIMPLEMENTED(); + host.kernel.obj_store.erase(); + return 0; } BRIDGE_IMPL(sceAvcdecCreateDecoder) diff --git a/vita3k/modules/include/modules/library_init_list.inc b/vita3k/modules/include/modules/library_init_list.inc new file mode 100644 index 000000000..c2e76abb7 --- /dev/null +++ b/vita3k/modules/include/modules/library_init_list.inc @@ -0,0 +1 @@ +LIBRARY(SceFiber) \ No newline at end of file diff --git a/vita3k/modules/include/modules/module_parent.h b/vita3k/modules/include/modules/module_parent.h index 876508fb9..6b7f5a49b 100644 --- a/vita3k/modules/include/modules/module_parent.h +++ b/vita3k/modules/include/modules/module_parent.h @@ -24,8 +24,8 @@ struct CPUState; struct HostState; struct KernelState; -struct CPUDepInject; +void init_libraries(HostState &host); void call_import(HostState &host, CPUState &cpu, uint32_t nid, SceUID thread_id); bool load_module(HostState &host, SceSysmoduleModuleId module_id); Address resolve_export(KernelState &kernel, uint32_t nid); @@ -41,22 +41,15 @@ struct VarExport { constexpr int var_exports_size = #define NID(name, nid) #define VAR_NID(name, nid) 1 + -#include +#include 0; #undef VAR_NID #undef NID const std::array &get_var_exports(); -// TODO move to module -struct CPUProtocol : public CPUProtocolBase { - CPUProtocol(HostState &host); - ~CPUProtocol(); - void call_svc(CPUState &cpu, uint32_t svc, Address pc, SceUID thread_id) override; - Address get_watch_memory_addr(Address addr) override; - std::vector &get_module_regions() override; - ExclusiveMonitorPtr get_exlusive_monitor() override; +using LibraryInitFn = std::function; -private: - HostState *host; -}; +#define LIBRARY_INIT_DECL(name) void export_library_init_##name(HostState &host); +#define LIBRARY_INIT_IMPL(name) void export_library_init_##name(HostState &host) +#define LIBRARY_INIT_REGISTER(name) extern const LibraryInitFn import_library_init_##name = export_library_init_##name; \ No newline at end of file diff --git a/vita3k/modules/module_parent.cpp b/vita3k/modules/module_parent.cpp index 84639b08b..ed9c34458 100644 --- a/vita3k/modules/module_parent.cpp +++ b/vita3k/modules/module_parent.cpp @@ -18,8 +18,6 @@ #include #include -#include -#include #include #include #include @@ -36,9 +34,13 @@ static constexpr bool LOG_UNK_NIDS_ALWAYS = false; +#define LIBRARY(name) extern const LibraryInitFn import_library_init_##name; +#include +#undef LIBRARY + #define VAR_NID(name, nid) extern const ImportVarFactory import_##name; #define NID(name, nid) extern const ImportFn import_##name; -#include +#include #undef NID #undef VAR_NID @@ -50,7 +52,7 @@ static ImportFn resolve_import(uint32_t nid) { #define NID(name, nid) \ case nid: \ return import_##name; -#include +#include #undef NID #undef VAR_NID } @@ -67,7 +69,7 @@ const std::array &get_var_exports() { import_##name, \ #name \ }, -#include +#include #undef VAR_NID #undef NID }; @@ -212,26 +214,8 @@ bool load_module(HostState &host, SceSysmoduleModuleId module_id) { return true; } -CPUProtocol::CPUProtocol(HostState &host) - : host(&host) { +void init_libraries(HostState &host) { +#define LIBRARY(name) import_library_init_##name(host); +#include +#undef LIBRARY } - -CPUProtocol::~CPUProtocol() { -} - -void CPUProtocol::call_svc(CPUState &cpu, uint32_t svc, Address pc, SceUID thread_id) { - uint32_t nid = *Ptr(pc + 4).get(host->mem); - ::call_import(*host, cpu, nid, thread_id); -} - -Address CPUProtocol::get_watch_memory_addr(Address addr) { - return ::get_watch_memory_addr(host->kernel, addr); -} - -std::vector &CPUProtocol::get_module_regions() { - return host->kernel.module_regions; -} - -ExclusiveMonitorPtr CPUProtocol::get_exlusive_monitor() { - return host->kernel.exclusive_monitor; -} \ No newline at end of file diff --git a/vita3k/ngs/CMakeLists.txt b/vita3k/ngs/CMakeLists.txt index 418a33324..3ef3a4f98 100644 --- a/vita3k/ngs/CMakeLists.txt +++ b/vita3k/ngs/CMakeLists.txt @@ -33,4 +33,5 @@ add_library( src/scheduler.cpp) target_include_directories(ngs PUBLIC include) -target_link_libraries(ngs PRIVATE util mem kernel codec cpu) +target_link_libraries(ngs PUBLIC codec) +target_link_libraries(ngs PRIVATE util mem kernel cpu) diff --git a/vita3k/ngs/include/ngs/modules/atrac9.h b/vita3k/ngs/include/ngs/modules/atrac9.h index 3e6a8eb83..623f4f4fc 100644 --- a/vita3k/ngs/include/ngs/modules/atrac9.h +++ b/vita3k/ngs/include/ngs/modules/atrac9.h @@ -1,8 +1,7 @@ #pragma once -#include - #include +#include namespace ngs::atrac9 { enum { diff --git a/vita3k/nids/CMakeLists.txt b/vita3k/nids/CMakeLists.txt index a7f956c15..77dc138f4 100644 --- a/vita3k/nids/CMakeLists.txt +++ b/vita3k/nids/CMakeLists.txt @@ -2,7 +2,7 @@ add_library( nids STATIC include/nids/functions.h - include/nids/nids.h + include/nids/nids.inc include/nids/types.h src/nids.cpp ) diff --git a/vita3k/nids/include/nids/nids.h b/vita3k/nids/include/nids/nids.inc similarity index 100% rename from vita3k/nids/include/nids/nids.h rename to vita3k/nids/include/nids/nids.inc diff --git a/vita3k/nids/src/nids.cpp b/vita3k/nids/src/nids.cpp index df9fd297a..5623f21b9 100644 --- a/vita3k/nids/src/nids.cpp +++ b/vita3k/nids/src/nids.cpp @@ -2,7 +2,7 @@ #define VAR_NID(name, nid) extern const char name_##name[] = #name; #define NID(name, nid) extern const char name_##name[] = #name; -#include +#include #undef NID #undef VAR_NID @@ -14,7 +14,7 @@ const char *import_name(uint32_t nid) { #define NID(name, nid) \ case nid: \ return name_##name; -#include +#include #undef NID #undef VAR_NID default: