get render threading working in melon
Squashed commit of the following: commit 6c54b59f5f8f8bbf8698eebbc2a7e39079b0e726 Author: CasualPokePlayer <50538166+CasualPokePlayer@users.noreply.github.com> Date: Wed Mar 16 19:19:12 2022 -0700 update submodule commit 2c65d4375b64d8e729ebc0d35fd34865627bc494 Author: CasualPokePlayer <50538166+CasualPokePlayer@users.noreply.github.com> Date: Wed Mar 16 19:14:36 2022 -0700 frontend stuff commit 4566edcc623061beb6e3a7b2ead5571b42abdf3e Author: CasualPokePlayer <50538166+CasualPokePlayer@users.noreply.github.com> Date: Wed Mar 16 18:10:45 2022 -0700 probably hacky bullshit commit 1fb9427c56a8d1af60378163cc2cafe6b36149c9 Author: CasualPokePlayer <50538166+CasualPokePlayer@users.noreply.github.com> Date: Wed Mar 16 00:59:58 2022 -0700 more mt testing
This commit is contained in:
parent
57c453ea68
commit
7150a97e07
Binary file not shown.
|
@ -132,10 +132,10 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
||||||
public abstract IntPtr GetFrameThreadProc();
|
public abstract IntPtr GetFrameThreadProc();
|
||||||
|
|
||||||
[UnmanagedFunctionPointer(CC)]
|
[UnmanagedFunctionPointer(CC)]
|
||||||
public delegate void ThreadWaitCallback();
|
public delegate void ThreadStartCallback();
|
||||||
|
|
||||||
[BizImport(CC)]
|
[BizImport(CC)]
|
||||||
public abstract void SetThreadWaitCallback(ThreadWaitCallback callback);
|
public abstract void SetThreadStartCallback(ThreadStartCallback callback);
|
||||||
|
|
||||||
[BizImport(CC)]
|
[BizImport(CC)]
|
||||||
public abstract int GetNANDSize();
|
public abstract int GetNANDSize();
|
||||||
|
|
|
@ -32,7 +32,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
||||||
|
|
||||||
public class NDSSettings
|
public class NDSSettings
|
||||||
{
|
{
|
||||||
#if false
|
#if true
|
||||||
[DisplayName("Threaded Rendering")]
|
[DisplayName("Threaded Rendering")]
|
||||||
[Description("")]
|
[Description("")]
|
||||||
[DefaultValue(true)]
|
[DefaultValue(true)]
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
||||||
|
|
||||||
InitMemoryCallbacks();
|
InitMemoryCallbacks();
|
||||||
_tracecb = MakeTrace;
|
_tracecb = MakeTrace;
|
||||||
_threadwaitcb = ThreadWaitCallback;
|
_threadstartcb = ThreadStartCallback;
|
||||||
|
|
||||||
_core = PreInit<LibMelonDS>(new WaterboxOptions
|
_core = PreInit<LibMelonDS>(new WaterboxOptions
|
||||||
{
|
{
|
||||||
|
@ -66,7 +66,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
||||||
MmapHeapSizeKB = 1024 * 1024,
|
MmapHeapSizeKB = 1024 * 1024,
|
||||||
SkipCoreConsistencyCheck = CoreComm.CorePreferences.HasFlag(CoreComm.CorePreferencesFlags.WaterboxCoreConsistencyCheck),
|
SkipCoreConsistencyCheck = CoreComm.CorePreferences.HasFlag(CoreComm.CorePreferencesFlags.WaterboxCoreConsistencyCheck),
|
||||||
SkipMemoryConsistencyCheck = CoreComm.CorePreferences.HasFlag(CoreComm.CorePreferencesFlags.WaterboxMemoryConsistencyCheck),
|
SkipMemoryConsistencyCheck = CoreComm.CorePreferences.HasFlag(CoreComm.CorePreferencesFlags.WaterboxMemoryConsistencyCheck),
|
||||||
}, new Delegate[] { _readcb, _writecb, _execcb, _tracecb, _threadwaitcb });
|
}, new Delegate[] { _readcb, _writecb, _execcb, _tracecb, _threadstartcb });
|
||||||
|
|
||||||
var bios7 = IsDSi || _syncSettings.UseRealBIOS
|
var bios7 = IsDSi || _syncSettings.UseRealBIOS
|
||||||
? CoreComm.CoreFileProvider.GetFirmwareOrThrow(new("NDS", "bios7"))
|
? CoreComm.CoreFileProvider.GetFirmwareOrThrow(new("NDS", "bios7"))
|
||||||
|
@ -112,7 +112,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
||||||
loadFlags |= LibMelonDS.LoadFlags.IS_DSI;
|
loadFlags |= LibMelonDS.LoadFlags.IS_DSI;
|
||||||
if (IsDSi && IsDSiWare)
|
if (IsDSi && IsDSiWare)
|
||||||
loadFlags |= LibMelonDS.LoadFlags.LOAD_DSIWARE;
|
loadFlags |= LibMelonDS.LoadFlags.LOAD_DSIWARE;
|
||||||
#if false
|
#if true
|
||||||
if (_settings.ThreadedRendering)
|
if (_settings.ThreadedRendering)
|
||||||
loadFlags |= LibMelonDS.LoadFlags.THREADED_RENDERING;
|
loadFlags |= LibMelonDS.LoadFlags.THREADED_RENDERING;
|
||||||
#endif
|
#endif
|
||||||
|
@ -209,7 +209,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Setting up waterbox thread for 0x{_frameThreadPtr:X16}");
|
Console.WriteLine($"Setting up waterbox thread for 0x{_frameThreadPtr:X16}");
|
||||||
_frameThreadStart = CallingConventionAdapters.GetWaterboxUnsafeUnwrapped().GetDelegateForFunctionPointer<Action>(_frameThreadPtr);
|
_frameThreadStart = CallingConventionAdapters.GetWaterboxUnsafeUnwrapped().GetDelegateForFunctionPointer<Action>(_frameThreadPtr);
|
||||||
_core.SetThreadWaitCallback(_threadwaitcb);
|
_core.SetThreadStartCallback(_threadstartcb);
|
||||||
}
|
}
|
||||||
|
|
||||||
_resampler = new SpeexResampler(SpeexResampler.Quality.QUALITY_DEFAULT, 32768, 44100, 32768, 44100, null, this);
|
_resampler = new SpeexResampler(SpeexResampler.Quality.QUALITY_DEFAULT, 32768, 44100, 32768, 44100, null, this);
|
||||||
|
@ -327,16 +327,9 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly IntPtr _frameThreadPtr;
|
|
||||||
private readonly Action _frameThreadStart;
|
|
||||||
private Task _frameThreadProcActive;
|
|
||||||
|
|
||||||
protected override LibWaterboxCore.FrameInfo FrameAdvancePrep(IController controller, bool render, bool rendersound)
|
protected override LibWaterboxCore.FrameInfo FrameAdvancePrep(IController controller, bool render, bool rendersound)
|
||||||
{
|
{
|
||||||
if (_frameThreadStart != null && render)
|
_render = render;
|
||||||
{
|
|
||||||
_frameThreadProcActive = Task.Run(_frameThreadStart);
|
|
||||||
}
|
|
||||||
_core.SetTraceCallback(Tracer.IsEnabled() ? _tracecb : null);
|
_core.SetTraceCallback(Tracer.IsEnabled() ? _tracecb : null);
|
||||||
return new LibMelonDS.FrameInfo
|
return new LibMelonDS.FrameInfo
|
||||||
{
|
{
|
||||||
|
@ -349,9 +342,26 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly LibMelonDS.ThreadWaitCallback _threadwaitcb;
|
private readonly IntPtr _frameThreadPtr;
|
||||||
|
private readonly Action _frameThreadStart;
|
||||||
|
private readonly LibMelonDS.ThreadStartCallback _threadstartcb;
|
||||||
|
|
||||||
private void ThreadWaitCallback()
|
private bool _render;
|
||||||
|
private Task _frameThreadProcActive;
|
||||||
|
|
||||||
|
private void ThreadStartCallback()
|
||||||
|
{
|
||||||
|
if (_render)
|
||||||
|
{
|
||||||
|
if (_frameThreadProcActive != null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Attempted to start render thread twice");
|
||||||
|
}
|
||||||
|
_frameThreadProcActive = Task.Run(_frameThreadStart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void FrameAdvancePost()
|
||||||
{
|
{
|
||||||
_frameThreadProcActive?.Wait();
|
_frameThreadProcActive?.Wait();
|
||||||
_frameThreadProcActive = null;
|
_frameThreadProcActive = null;
|
||||||
|
|
|
@ -72,7 +72,6 @@ typedef struct
|
||||||
} FirmwareSettings;
|
} FirmwareSettings;
|
||||||
|
|
||||||
extern std::stringstream* NANDFilePtr;
|
extern std::stringstream* NANDFilePtr;
|
||||||
extern bool Stopped;
|
|
||||||
|
|
||||||
static bool LoadDSiWare(u8* TmdData)
|
static bool LoadDSiWare(u8* TmdData)
|
||||||
{
|
{
|
||||||
|
@ -154,7 +153,6 @@ EXPORT bool Init(LoadFlags loadFlags, LoadData* loadData, FirmwareSettings* fwSe
|
||||||
}
|
}
|
||||||
if (biz_skip_fw) NDS::SetupDirectBoot("");
|
if (biz_skip_fw) NDS::SetupDirectBoot("");
|
||||||
NDS::Start();
|
NDS::Start();
|
||||||
Stopped = false;
|
|
||||||
Config::FirmwareOverrideSettings = false;
|
Config::FirmwareOverrideSettings = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -374,7 +372,6 @@ EXPORT void FrameAdvance(MyFrameInfo* f)
|
||||||
NDS::LoadBIOS();
|
NDS::LoadBIOS();
|
||||||
if (biz_skip_fw) NDS::SetupDirectBoot("");
|
if (biz_skip_fw) NDS::SetupDirectBoot("");
|
||||||
NDS::Start();
|
NDS::Start();
|
||||||
Stopped = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NDS::SetKeyMask(~f->Keys & 0xFFF);
|
NDS::SetKeyMask(~f->Keys & 0xFFF);
|
||||||
|
@ -477,7 +474,7 @@ EXPORT void SetTraceCallback(void (*callback)(u32 cpu, u32* regs, u32 opcode))
|
||||||
namespace Platform
|
namespace Platform
|
||||||
{
|
{
|
||||||
extern uintptr_t FrameThreadProc;
|
extern uintptr_t FrameThreadProc;
|
||||||
extern void (*ThreadWaitCallback)();
|
extern void (*ThreadStartCallback)();
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT uintptr_t GetFrameThreadProc()
|
EXPORT uintptr_t GetFrameThreadProc()
|
||||||
|
@ -485,9 +482,9 @@ EXPORT uintptr_t GetFrameThreadProc()
|
||||||
return Platform::FrameThreadProc;
|
return Platform::FrameThreadProc;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void SetThreadWaitCallback(void (*callback)())
|
EXPORT void SetThreadStartCallback(void (*callback)())
|
||||||
{
|
{
|
||||||
Platform::ThreadWaitCallback = callback;
|
Platform::ThreadStartCallback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT u32 GetNANDSize()
|
EXPORT u32 GetNANDSize()
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
bool NdsSaveRamIsDirty = false;
|
bool NdsSaveRamIsDirty = false;
|
||||||
std::stringstream* NANDFilePtr = NULL;
|
std::stringstream* NANDFilePtr = NULL;
|
||||||
bool Stopped = true;
|
|
||||||
|
|
||||||
namespace Platform
|
namespace Platform
|
||||||
{
|
{
|
||||||
|
@ -22,7 +21,6 @@ void DeInit()
|
||||||
|
|
||||||
void StopEmu()
|
void StopEmu()
|
||||||
{
|
{
|
||||||
Stopped = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetConfigInt(ConfigEntry entry)
|
int GetConfigInt(ConfigEntry entry)
|
||||||
|
@ -163,11 +161,11 @@ FILE* OpenLocalFile(std::string path, std::string mode)
|
||||||
|
|
||||||
uintptr_t FrameThreadProc = 0;
|
uintptr_t FrameThreadProc = 0;
|
||||||
std::function<void()> ThreadEntryFunc = nullptr;
|
std::function<void()> ThreadEntryFunc = nullptr;
|
||||||
void (*ThreadWaitCallback)() = nullptr;
|
void (*ThreadStartCallback)() = nullptr;
|
||||||
|
|
||||||
void ThreadEntry()
|
void ThreadEntry()
|
||||||
{
|
{
|
||||||
if (!Stopped) ThreadEntryFunc();
|
ThreadEntryFunc();
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread* Thread_Create(std::function<void()> func)
|
Thread* Thread_Create(std::function<void()> func)
|
||||||
|
@ -181,44 +179,30 @@ void Thread_Free(Thread* thread)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread_Wait(Thread* thread)
|
void Thread_Wait(Thread* thread) // hijacked to act as a thread start, consider this "wait for start of thread"
|
||||||
{
|
{
|
||||||
ThreadWaitCallback();
|
ThreadStartCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
Semaphore* Semaphore_Create()
|
Semaphore* Semaphore_Create()
|
||||||
{
|
{
|
||||||
int* s = new int;
|
return nullptr;
|
||||||
*s = 0;
|
|
||||||
return (Semaphore*)s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Semaphore_Free(Semaphore* sema)
|
void Semaphore_Free(Semaphore* sema)
|
||||||
{
|
{
|
||||||
abort();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Semaphore_Reset(Semaphore* sema)
|
void Semaphore_Reset(Semaphore* sema)
|
||||||
{
|
{
|
||||||
__atomic_store_n((int*)sema, 0, __ATOMIC_RELAXED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Semaphore_Wait(Semaphore* sema)
|
void Semaphore_Wait(Semaphore* sema)
|
||||||
{
|
{
|
||||||
int res;
|
|
||||||
loop:
|
|
||||||
res = __atomic_load_n((int*)sema, __ATOMIC_RELAXED);
|
|
||||||
if (!res) goto loop;
|
|
||||||
__atomic_sub_fetch((int*)sema, 1, __ATOMIC_RELAXED);
|
|
||||||
if (__atomic_load_n((int*)sema, __ATOMIC_RELAXED) < 0)
|
|
||||||
{
|
|
||||||
__atomic_store_n((int*)sema, 0, __ATOMIC_RELAXED);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Semaphore_Post(Semaphore* sema, int count)
|
void Semaphore_Post(Semaphore* sema, int count)
|
||||||
{
|
{
|
||||||
__atomic_add_fetch((int*)sema, (int)count, __ATOMIC_RELAXED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Mutex* Mutex_Create()
|
Mutex* Mutex_Create()
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 7e45e3582be653db468293189d63349c2632c3cb
|
Subproject commit 69d0437b289d87d49c6ec68f81e454cf97c8e7d8
|
Loading…
Reference in New Issue