From 2c447f686dc575d3264b8b7a26eb2e829a9fc2bb Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 13 Mar 2014 20:11:16 +0400 Subject: [PATCH] sys_spinlock implemented --- rpcs3/Emu/SysCalls/Modules/cellAdec.cpp | 20 ++++---- rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp | 44 ++++++++--------- rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp | 5 ++ rpcs3/Emu/SysCalls/SysCalls.h | 7 +++ rpcs3/Emu/SysCalls/lv2/SC_Spinlock.cpp | 51 ++++++++++++++++++++ rpcs3/Emu/SysCalls/lv2/SC_Spinlock.h | 6 +++ rpcs3/rpcs3.vcxproj | 1 + rpcs3/rpcs3.vcxproj.filters | 3 ++ 8 files changed, 105 insertions(+), 32 deletions(-) create mode 100644 rpcs3/Emu/SysCalls/lv2/SC_Spinlock.cpp create mode 100644 rpcs3/Emu/SysCalls/lv2/SC_Spinlock.h diff --git a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp index 4147d21aaa..a2805567c4 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp @@ -23,13 +23,13 @@ int adecRead(void* opaque, u8* buf, int buf_size) int res = 0; next: - if (adec.reader.size < (u32)buf_size /*&& !vdec.just_started*/) + if (adec.reader.size < (u32)buf_size /*&& !adec.just_started*/) { while (adec.job.IsEmpty()) { if (Emu.IsStopped()) { - ConLog.Warning("vdecRead() aborted"); + ConLog.Warning("adecRead() aborted"); return 0; } Sleep(1); @@ -212,7 +212,7 @@ u32 adecOpen(AudioDecoder* data) if (Memory.CopyToReal(buf, task.au.addr, task.au.size)) dump.Write(buf, task.au.size); free(buf); dump.Close(); - }*/ + } if (adec.just_started) // deferred initialization { @@ -259,7 +259,7 @@ u32 adecOpen(AudioDecoder* data) break; } adec.just_started = false; - } + }*/ bool last_frame = false; @@ -271,7 +271,7 @@ u32 adecOpen(AudioDecoder* data) return; } - /*if (!adec.ctx) // fake + if (!adec.ctx) // fake { AdecFrame frame; frame.pts = task.au.pts; @@ -285,7 +285,7 @@ u32 adecOpen(AudioDecoder* data) adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg); break; - }*/ + } last_frame = av_read_frame(adec.fmt, &au) < 0; if (last_frame) @@ -296,14 +296,14 @@ u32 adecOpen(AudioDecoder* data) au.size = 0; } - struct VdecFrameHolder : AdecFrame + struct AdecFrameHolder : AdecFrame { - VdecFrameHolder() + AdecFrameHolder() { data = av_frame_alloc(); } - ~VdecFrameHolder() + ~AdecFrameHolder() { if (data) { @@ -336,7 +336,7 @@ u32 adecOpen(AudioDecoder* data) if (got_frame) { - ConLog.Write("got_frame (%d, vdec: pts=0x%llx, dts=0x%llx)", got_frame, au.pts, au.dts); + ConLog.Write("got_frame (%d, pts=0x%llx, dts=0x%llx)", got_frame, au.pts, au.dts); frame.pts = task.au.pts; // ??? frame.auAddr = task.au.addr; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp index aca92144af..c211fa07d3 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp @@ -9,7 +9,7 @@ Module cellSpurs(0x000a, cellSpurs_init); int _cellSpursAttributeInitialize(mem_ptr_t attr, int nSpus, int spuPriority, int ppuPriority, bool exitIfNoWork) { - cellSpurs.Warning("cellSpursAttributeInitialize(attr_addr=0x%x, nSpus=%u, spuPriority=%u, ppuPriority=%u, exitIfNoWork=%u)", + cellSpurs.Error("_cellSpursAttributeInitialize(attr_addr=0x%x, nSpus=%u, spuPriority=%u, ppuPriority=%u, exitIfNoWork=%u)", attr.GetAddr(), nSpus, spuPriority, ppuPriority, exitIfNoWork); if(!attr.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; @@ -18,7 +18,7 @@ int _cellSpursAttributeInitialize(mem_ptr_t attr, int nSpus, int cellSpursAttributeSetMemoryContainerForSpuThread(mem_ptr_t attr, u32 container) { - cellSpurs.Warning("cellSpursAttributeSetMemoryContainerForSpuThread(attr_addr=0x%x, container=0x%x)", + cellSpurs.Error("cellSpursAttributeSetMemoryContainerForSpuThread(attr_addr=0x%x, container=0x%x)", attr.GetAddr(), container); if(!attr.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; @@ -27,7 +27,7 @@ int cellSpursAttributeSetMemoryContainerForSpuThread(mem_ptr_t attr, const mem8_t prefix, u32 size) { - cellSpurs.Warning("cellSpursAttributeSetNamePrefix(attr_addr=0x%x, prefix_addr=0x%x, size=0x%x)", + cellSpurs.Error("cellSpursAttributeSetNamePrefix(attr_addr=0x%x, prefix_addr=0x%x, size=0x%x)", attr.GetAddr(), prefix.GetAddr(), size); if(!attr.IsGood() || !prefix.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; if(size > 15) return CELL_SPURS_CORE_ERROR_INVAL; @@ -37,7 +37,7 @@ int cellSpursAttributeSetNamePrefix(mem_ptr_t attr, const me int cellSpursAttributeEnableSpuPrintfIfAvailable(mem_ptr_t attr) { - cellSpurs.Warning("cellSpursAttributeEnableSpuPrintfIfAvailable(attr_addr=0x%x)", attr.GetAddr()); + cellSpurs.Error("cellSpursAttributeEnableSpuPrintfIfAvailable(attr_addr=0x%x)", attr.GetAddr()); if(!attr.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; return CELL_OK; @@ -45,7 +45,7 @@ int cellSpursAttributeEnableSpuPrintfIfAvailable(mem_ptr_t a int cellSpursAttributeSetSpuThreadGroupType(mem_ptr_t attr, int type) { - cellSpurs.Warning("cellSpursAttributeSetSpuThreadGroupType(attr_addr=0x%x, type=%u)", attr.GetAddr(), type); + cellSpurs.Error("cellSpursAttributeSetSpuThreadGroupType(attr_addr=0x%x, type=%u)", attr.GetAddr(), type); if(!attr.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; return CELL_OK; @@ -54,7 +54,7 @@ int cellSpursAttributeSetSpuThreadGroupType(mem_ptr_t attr, int cellSpursAttributeEnableSystemWorkload(mem_ptr_t attr, const u8 priority[8], uint maxSpu, const bool isPreemptible[8]) { - cellSpurs.Warning("cellSpursAttributeEnableSystemWorkload(attr_addr=0x%x, priority[%u], maxSpu=%u, isPreemptible[%u])", + cellSpurs.Error("cellSpursAttributeEnableSystemWorkload(attr_addr=0x%x, priority[%u], maxSpu=%u, isPreemptible[%u])", attr.GetAddr(), priority, maxSpu, isPreemptible); if(!attr.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; for (int i=0; i<8; i++) @@ -65,7 +65,7 @@ int cellSpursAttributeEnableSystemWorkload(mem_ptr_t attr, c int cellSpursInitializeWithAttribute2(mem_ptr_t spurs, const mem_ptr_t attr) { - cellSpurs.Warning("cellSpursInitializeWithAttribute2(spurs_addr=0x%x, spurs_addr=0x%x)", + cellSpurs.Error("cellSpursInitializeWithAttribute2(spurs_addr=0x%x, spurs_addr=0x%x)", spurs.GetAddr(), attr.GetAddr()); if(!attr.IsGood() || !spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; @@ -74,7 +74,7 @@ int cellSpursInitializeWithAttribute2(mem_ptr_t spurs, const mem_ptr int cellSpursFinalize(mem_ptr_t spurs) { - cellSpurs.Warning("cellSpursFinalize(spurs_addr=0x%x)", spurs.GetAddr()); + cellSpurs.Error("cellSpursFinalize(spurs_addr=0x%x)", spurs.GetAddr()); if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; return CELL_OK; @@ -82,7 +82,7 @@ int cellSpursFinalize(mem_ptr_t spurs) int cellSpursGetSpuThreadGroupId(mem_ptr_t spurs, mem32_t group) { - cellSpurs.Warning("cellSpursGetSpuThreadGroupId(spurs_addr=0x%x, group_addr=0x%x)", + cellSpurs.Error("cellSpursGetSpuThreadGroupId(spurs_addr=0x%x, group_addr=0x%x)", spurs.GetAddr(), group.GetAddr()); if(!spurs.IsGood() || group.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; @@ -91,7 +91,7 @@ int cellSpursGetSpuThreadGroupId(mem_ptr_t spurs, mem32_t group) int cellSpursGetNumSpuThread(mem_ptr_t spurs, mem32_t nThreads) { - cellSpurs.Warning("cellSpursGetNumSpuThread(spurs_addr=0x%x, nThreads_addr=0x%x)", + cellSpurs.Error("cellSpursGetNumSpuThread(spurs_addr=0x%x, nThreads_addr=0x%x)", spurs.GetAddr(), nThreads.GetAddr()); if(!spurs.IsGood() || nThreads.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; @@ -100,7 +100,7 @@ int cellSpursGetNumSpuThread(mem_ptr_t spurs, mem32_t nThreads) int cellSpursGetSpuThreadId(mem_ptr_t spurs, mem32_t thread, mem32_t nThreads) { - cellSpurs.Warning("cellSpursGetSpuThreadId(spurs_addr=0x%x, thread_addr=0x%x, nThreads_addr=0x%x)", + cellSpurs.Error("cellSpursGetSpuThreadId(spurs_addr=0x%x, thread_addr=0x%x, nThreads_addr=0x%x)", spurs.GetAddr(), thread.GetAddr(), nThreads.GetAddr()); if(!spurs.IsGood() || !thread.IsGood() || nThreads.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; @@ -109,7 +109,7 @@ int cellSpursGetSpuThreadId(mem_ptr_t spurs, mem32_t thread, mem32_t int cellSpursSetMaxContention(mem_ptr_t spurs, uint workloadId, uint maxContention) { - cellSpurs.Warning("cellSpursSetMaxContention(spurs_addr=0x%x, workloadId=%u, maxContention=%u)", + cellSpurs.Error("cellSpursSetMaxContention(spurs_addr=0x%x, workloadId=%u, maxContention=%u)", spurs.GetAddr(), workloadId, maxContention); if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; @@ -118,7 +118,7 @@ int cellSpursSetMaxContention(mem_ptr_t spurs, uint workloadId, uint int cellSpursSetPriorities(mem_ptr_t spurs, uint workloadId, const u8 priorities[CELL_SPURS_MAX_SPU]) { - cellSpurs.Warning("cellSpursSetPriorities(spurs_addr=0x%x, workloadId=%u, priorities[%u])", + cellSpurs.Error("cellSpursSetPriorities(spurs_addr=0x%x, workloadId=%u, priorities[%u])", spurs.GetAddr(), workloadId, priorities); if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; @@ -127,7 +127,7 @@ int cellSpursSetPriorities(mem_ptr_t spurs, uint workloadId, const u8 int cellSpursSetPriority(mem_ptr_t spurs, uint workloadId, uint spuId, uint priority) { - cellSpurs.Warning("cellSpursSetPriority(spurs_addr=0x%x, workloadId=%u, spuId=%u, priority=%u)", + cellSpurs.Error("cellSpursSetPriority(spurs_addr=0x%x, workloadId=%u, spuId=%u, priority=%u)", spurs.GetAddr(), workloadId, spuId, priority); if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; @@ -136,7 +136,7 @@ int cellSpursSetPriority(mem_ptr_t spurs, uint workloadId, uint spuId int cellSpursSetPreemptionVictimHints(mem_ptr_t spurs, const bool isPreemptible[8]) { - cellSpurs.Warning("cellSpursSetPreemptionVictimHints(spurs_addr=0x%x, isPreemptible[%u])", + cellSpurs.Error("cellSpursSetPreemptionVictimHints(spurs_addr=0x%x, isPreemptible[%u])", spurs.GetAddr(), isPreemptible); if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; @@ -145,7 +145,7 @@ int cellSpursSetPreemptionVictimHints(mem_ptr_t spurs, const bool isP int cellSpursAttachLv2EventQueue(mem_ptr_t spurs, u32 queue, mem8_t port, int isDynamic) { - cellSpurs.Warning("cellSpursAttachLv2EventQueue(spurs_addr=0x%x, queue=0x%x, port_addr=0x%x, isDynamic=%u)", + cellSpurs.Error("cellSpursAttachLv2EventQueue(spurs_addr=0x%x, queue=0x%x, port_addr=0x%x, isDynamic=%u)", spurs.GetAddr(), queue, port.GetAddr(), isDynamic); if(!spurs.IsGood() || !port.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; @@ -154,7 +154,7 @@ int cellSpursAttachLv2EventQueue(mem_ptr_t spurs, u32 queue, mem8_t p int cellSpursDetachLv2EventQueue(mem_ptr_t spurs, u8 port) { - cellSpurs.Warning("cellSpursDetachLv2EventQueue(spurs_addr=0x%x, port=0x%x)", spurs.GetAddr(), port); + cellSpurs.Error("cellSpursDetachLv2EventQueue(spurs_addr=0x%x, port=0x%x)", spurs.GetAddr(), port); if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; return CELL_OK; @@ -162,7 +162,7 @@ int cellSpursDetachLv2EventQueue(mem_ptr_t spurs, u8 port) int cellSpursEnableExceptionEventHandler(mem_ptr_t spurs, bool flag) { - cellSpurs.Warning("cellSpursEnableExceptionEventHandler(spurs_addr=0x%x, flag=%u)", spurs.GetAddr(), flag); + cellSpurs.Error("cellSpursEnableExceptionEventHandler(spurs_addr=0x%x, flag=%u)", spurs.GetAddr(), flag); if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; return CELL_OK; @@ -171,7 +171,7 @@ int cellSpursEnableExceptionEventHandler(mem_ptr_t spurs, bool flag) int cellSpursSetGlobalExceptionEventHandler(mem_ptr_t spurs, mem_func_ptr_t eaHandler, mem_ptr_t arg) { - cellSpurs.Warning("cellSpursEnableExceptionEventHandler(spurs_addr=0x%x, eaHandler_addr=0x%x, arg_addr=0x%x,)", + cellSpurs.Error("cellSpursEnableExceptionEventHandler(spurs_addr=0x%x, eaHandler_addr=0x%x, arg_addr=0x%x,)", spurs.GetAddr(), eaHandler.GetAddr(), arg.GetAddr()); if(!spurs.IsGood() || eaHandler.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; @@ -180,7 +180,7 @@ int cellSpursSetGlobalExceptionEventHandler(mem_ptr_t spurs, int cellSpursUnsetGlobalExceptionEventHandler(mem_ptr_t spurs) { - cellSpurs.Warning("cellSpursUnsetGlobalExceptionEventHandler(spurs_addr=0x%x)", spurs.GetAddr()); + cellSpurs.Error("cellSpursUnsetGlobalExceptionEventHandler(spurs_addr=0x%x)", spurs.GetAddr()); if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; return CELL_OK; @@ -188,7 +188,7 @@ int cellSpursUnsetGlobalExceptionEventHandler(mem_ptr_t spurs) int cellSpursGetInfo(mem_ptr_t spurs, mem_ptr_t info) { - cellSpurs.Warning("cellSpursGetInfo(spurs_addr=0x%x, info_addr=0x%x)", spurs.GetAddr(), info.GetAddr()); + cellSpurs.Error("cellSpursGetInfo(spurs_addr=0x%x, info_addr=0x%x)", spurs.GetAddr(), info.GetAddr()); if(!spurs.IsGood() || !info.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; return CELL_OK; @@ -197,7 +197,7 @@ int cellSpursGetInfo(mem_ptr_t spurs, mem_ptr_t info) // Task functions int cellSpursGetTasksetId(mem_ptr_t taskset, mem32_t workloadId) { - cellSpurs.Warning("cellSpursGetTasksetId(taskset_addr=0x%x, workloadId_addr=0x%x)", taskset.GetAddr(), workloadId.GetAddr()); + cellSpurs.Error("cellSpursGetTasksetId(taskset_addr=0x%x, workloadId_addr=0x%x)", taskset.GetAddr(), workloadId.GetAddr()); if(!taskset.IsGood() || !taskset.IsGood()) return CELL_SPURS_TASK_ERROR_NULL_POINTER; return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index 175ea47fb5..945e925063 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -185,6 +185,11 @@ void sysPrxForUser_init() sysPrxForUser.AddFunc(0x52aadadf, sys_lwcond_signal_to); sysPrxForUser.AddFunc(0x2a6d9d51, sys_lwcond_wait); + sysPrxForUser.AddFunc(0x8c2bb498, sys_spinlock_initialize); + sysPrxForUser.AddFunc(0xa285139d, sys_spinlock_lock); + sysPrxForUser.AddFunc(0x722a0254, sys_spinlock_trylock); + sysPrxForUser.AddFunc(0x5267cb35, sys_spinlock_unlock); + sysPrxForUser.AddFunc(0x67f9fedb, sys_game_process_exitspawn2); sysPrxForUser.AddFunc(0xfc52a7a9, sys_game_process_exitspawn); diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index 9d75580371..0b06490c51 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -9,6 +9,7 @@ #include "lv2/SC_Lwcond.h" #include "lv2/SC_Event_flag.h" #include "lv2/SC_Condition.h" +#include "lv2/SC_Spinlock.h" #include "Emu/event.h" //#define SYSCALLS_DEBUG @@ -200,6 +201,12 @@ extern int sys_rwlock_wlock(u32 rw_lock_id, u64 timeout); extern int sys_rwlock_trywlock(u32 rw_lock_id); extern int sys_rwlock_wunlock(u32 rw_lock_id); +//sys_spinlock +extern void sys_spinlock_initialize(mem_ptr_t lock); +extern void sys_spinlock_lock(mem_ptr_t lock); +extern int sys_spinlock_trylock(mem_ptr_t lock); +extern void sys_spinlock_unlock(mem_ptr_t lock); + //ppu_thread extern void sys_ppu_thread_exit(u64 errorcode); extern int sys_ppu_thread_yield(); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Spinlock.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Spinlock.cpp new file mode 100644 index 0000000000..90d9a35a3a --- /dev/null +++ b/rpcs3/Emu/SysCalls/lv2/SC_Spinlock.cpp @@ -0,0 +1,51 @@ +#include "stdafx.h" +#include "Emu/SysCalls/SysCalls.h" +#include "Emu/SysCalls/lv2/SC_Spinlock.h" + +SysCallBase sys_spinlock("sys_spinlock"); + +void sys_spinlock_initialize(mem_ptr_t lock) +{ + sys_spinlock.Log("sys_spinlock_initialize(lock_addr=0x%x)", lock.GetAddr()); + + lock->mutex.initialize(); +} + +void sys_spinlock_lock(mem_ptr_t lock) +{ + sys_spinlock.Log("sys_spinlock_lock(lock_addr=0x%x)", lock.GetAddr()); + + be_t tid = GetCurrentPPUThread().GetId(); + switch (lock->mutex.lock(tid)) + { + case SMR_ABORT: ConLog.Warning("sys_spinlock_lock(0x%x) aborted", lock.GetAddr()); break; + case SMR_DEADLOCK: ConLog.Error("sys_spinlock_lock(0x%x) reached deadlock", lock.GetAddr()); break; // ??? + default: break; + } +} + +int sys_spinlock_trylock(mem_ptr_t lock) +{ + sys_spinlock.Log("sys_spinlock_trylock(lock_addr=0x%x)", lock.GetAddr()); + + be_t tid = GetCurrentPPUThread().GetId(); + switch (lock->mutex.trylock(tid)) + { + case SMR_FAILED: return CELL_EBUSY; + case SMR_ABORT: ConLog.Warning("sys_spinlock_trylock(0x%x) aborted", lock.GetAddr()); break; + case SMR_DEADLOCK: ConLog.Error("sys_spinlock_trylock(0x%x) reached deadlock", lock.GetAddr()); break; + default: break; + } + + return CELL_OK; +} + +void sys_spinlock_unlock(mem_ptr_t lock) +{ + sys_spinlock.Log("sys_spinlock_unlock(lock_addr=0x%x)", lock.GetAddr()); + + switch (lock->mutex.unlock(lock->mutex.GetOwner())) + { + default: break; + } +} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Spinlock.h b/rpcs3/Emu/SysCalls/lv2/SC_Spinlock.h new file mode 100644 index 0000000000..0ff4af4029 --- /dev/null +++ b/rpcs3/Emu/SysCalls/lv2/SC_Spinlock.h @@ -0,0 +1,6 @@ +#pragma once + +struct spinlock +{ + SMutexBE mutex; +}; \ No newline at end of file diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 1dfb346159..a02f6bf916 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -277,6 +277,7 @@ + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index b10d1cb470..7e4015ba55 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -466,6 +466,9 @@ Emu\SysCalls\Modules + + Emu\SysCalls\lv2 +