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:
CasualPokePlayer 2022-03-16 19:19:36 -07:00
parent 57c453ea68
commit 7150a97e07
7 changed files with 36 additions and 45 deletions

Binary file not shown.

View File

@ -132,10 +132,10 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
public abstract IntPtr GetFrameThreadProc();
[UnmanagedFunctionPointer(CC)]
public delegate void ThreadWaitCallback();
public delegate void ThreadStartCallback();
[BizImport(CC)]
public abstract void SetThreadWaitCallback(ThreadWaitCallback callback);
public abstract void SetThreadStartCallback(ThreadStartCallback callback);
[BizImport(CC)]
public abstract int GetNANDSize();

View File

@ -32,7 +32,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
public class NDSSettings
{
#if false
#if true
[DisplayName("Threaded Rendering")]
[Description("")]
[DefaultValue(true)]

View File

@ -54,7 +54,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
InitMemoryCallbacks();
_tracecb = MakeTrace;
_threadwaitcb = ThreadWaitCallback;
_threadstartcb = ThreadStartCallback;
_core = PreInit<LibMelonDS>(new WaterboxOptions
{
@ -66,7 +66,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
MmapHeapSizeKB = 1024 * 1024,
SkipCoreConsistencyCheck = CoreComm.CorePreferences.HasFlag(CoreComm.CorePreferencesFlags.WaterboxCoreConsistencyCheck),
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
? CoreComm.CoreFileProvider.GetFirmwareOrThrow(new("NDS", "bios7"))
@ -112,7 +112,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
loadFlags |= LibMelonDS.LoadFlags.IS_DSI;
if (IsDSi && IsDSiWare)
loadFlags |= LibMelonDS.LoadFlags.LOAD_DSIWARE;
#if false
#if true
if (_settings.ThreadedRendering)
loadFlags |= LibMelonDS.LoadFlags.THREADED_RENDERING;
#endif
@ -209,7 +209,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
{
Console.WriteLine($"Setting up waterbox thread for 0x{_frameThreadPtr:X16}");
_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);
@ -327,16 +327,9 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
return b;
}
private readonly IntPtr _frameThreadPtr;
private readonly Action _frameThreadStart;
private Task _frameThreadProcActive;
protected override LibWaterboxCore.FrameInfo FrameAdvancePrep(IController controller, bool render, bool rendersound)
{
if (_frameThreadStart != null && render)
{
_frameThreadProcActive = Task.Run(_frameThreadStart);
}
_render = render;
_core.SetTraceCallback(Tracer.IsEnabled() ? _tracecb : null);
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 = null;

View File

@ -72,7 +72,6 @@ typedef struct
} FirmwareSettings;
extern std::stringstream* NANDFilePtr;
extern bool Stopped;
static bool LoadDSiWare(u8* TmdData)
{
@ -154,7 +153,6 @@ EXPORT bool Init(LoadFlags loadFlags, LoadData* loadData, FirmwareSettings* fwSe
}
if (biz_skip_fw) NDS::SetupDirectBoot("");
NDS::Start();
Stopped = false;
Config::FirmwareOverrideSettings = false;
return true;
}
@ -374,7 +372,6 @@ EXPORT void FrameAdvance(MyFrameInfo* f)
NDS::LoadBIOS();
if (biz_skip_fw) NDS::SetupDirectBoot("");
NDS::Start();
Stopped = false;
}
NDS::SetKeyMask(~f->Keys & 0xFFF);
@ -477,7 +474,7 @@ EXPORT void SetTraceCallback(void (*callback)(u32 cpu, u32* regs, u32 opcode))
namespace Platform
{
extern uintptr_t FrameThreadProc;
extern void (*ThreadWaitCallback)();
extern void (*ThreadStartCallback)();
}
EXPORT uintptr_t GetFrameThreadProc()
@ -485,9 +482,9 @@ EXPORT uintptr_t GetFrameThreadProc()
return Platform::FrameThreadProc;
}
EXPORT void SetThreadWaitCallback(void (*callback)())
EXPORT void SetThreadStartCallback(void (*callback)())
{
Platform::ThreadWaitCallback = callback;
Platform::ThreadStartCallback = callback;
}
EXPORT u32 GetNANDSize()

View File

@ -7,7 +7,6 @@
bool NdsSaveRamIsDirty = false;
std::stringstream* NANDFilePtr = NULL;
bool Stopped = true;
namespace Platform
{
@ -22,7 +21,6 @@ void DeInit()
void StopEmu()
{
Stopped = true;
}
int GetConfigInt(ConfigEntry entry)
@ -163,11 +161,11 @@ FILE* OpenLocalFile(std::string path, std::string mode)
uintptr_t FrameThreadProc = 0;
std::function<void()> ThreadEntryFunc = nullptr;
void (*ThreadWaitCallback)() = nullptr;
void (*ThreadStartCallback)() = nullptr;
void ThreadEntry()
{
if (!Stopped) ThreadEntryFunc();
ThreadEntryFunc();
}
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()
{
int* s = new int;
*s = 0;
return (Semaphore*)s;
return nullptr;
}
void Semaphore_Free(Semaphore* sema)
{
abort();
}
void Semaphore_Reset(Semaphore* sema)
{
__atomic_store_n((int*)sema, 0, __ATOMIC_RELAXED);
}
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)
{
__atomic_add_fetch((int*)sema, (int)count, __ATOMIC_RELAXED);
}
Mutex* Mutex_Create()

@ -1 +1 @@
Subproject commit 7e45e3582be653db468293189d63349c2632c3cb
Subproject commit 69d0437b289d87d49c6ec68f81e454cf97c8e7d8