Run IOP Vblank handler on the IOP thread (#1752)

This commit is contained in:
Ziemas 2022-08-14 23:21:02 +02:00 committed by GitHub
parent a77f8ae66d
commit 2acc5250f8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 48 additions and 5 deletions

View file

@ -7,6 +7,7 @@
#include <cstdio>
#include <functional>
#include <utility>
#include "display.h"
@ -49,6 +50,7 @@ void InitSettings(GfxSettings& settings) {
namespace Gfx {
std::function<void()> vsync_callback;
GfxGlobalSettings g_global_settings;
GfxSettings g_settings;
// const std::vector<const GfxRendererModule*> renderers = {&moduleOpenGL};
@ -149,8 +151,19 @@ u32 Exit() {
return 0;
}
void register_vsync_callback(std::function<void()> f) {
vsync_callback = std::move(f);
}
void clear_vsync_callback() {
vsync_callback = nullptr;
}
u32 vsync() {
if (GetCurrentRenderer()) {
// Inform the IOP kernel that we're vsyncing so it can run the vblank handler
if (vsync_callback != nullptr)
vsync_callback();
return GetCurrentRenderer()->vsync();
}
return 0;

View file

@ -125,6 +125,8 @@ void Loop(std::function<bool()> f);
u32 Exit();
u32 vsync();
void register_vsync_callback(std::function<void()> f);
void clear_vsync_callback();
u32 sync_path();
void send_chain(const void* data, u32 offset);
void texture_upload_now(const u8* tpage, int mode, u32 s7_ptr);

View file

@ -5,7 +5,6 @@
#include "common/util/Assert.h"
#include "game/graphics/gfx.h"
#include "game/overlord/srpc.h"
/*!
* Wait for rendering to complete.
@ -32,6 +31,5 @@ u32 sceGsSyncPath(u32 mode, u32 timeout) {
*/
u32 sceGsSyncV(u32 mode) {
ASSERT(mode == 0);
VBlank_Handler();
return Gfx::vsync();
}

View file

@ -39,7 +39,7 @@ int start_overlord(int argc, const char* const* argv) {
InitSound_Overlord();
}
InitRamdisk();
// RegisterVblankHandler(0, 0x20, VBlank_Handler, nullptr);
RegisterVblankHandler(0, 0x20, VBlank_Handler, nullptr);
ThreadParam thread_param;
thread_param.attr = TH_C;

View file

@ -440,7 +440,7 @@ void* RPC_Loader(unsigned int /*fno*/, void* data, int size) {
static s32 dmaid = 0;
s32 VBlank_Handler() {
s32 VBlank_Handler(void*) {
if (!gSoundEnable)
return 1;

View file

@ -170,7 +170,7 @@ extern s32 gMusicTweak;
u32 Thread_Loader();
u32 Thread_Player();
s32 VBlank_Handler();
s32 VBlank_Handler(void*);
// added for PC port
extern u32 gMusicFadeHack;

View file

@ -209,6 +209,7 @@ void iop_runner(SystemThreadInterface& iface) {
iop.reset_allocator();
ee::LIBRARY_sceSif_register(&iop);
iop::LIBRARY_register(&iop);
Gfx::register_vsync_callback([&iop]() { iop.kernel.signal_vblank(); });
// todo!
dma_init_globals();
@ -256,6 +257,8 @@ void iop_runner(SystemThreadInterface& iface) {
// So we can wait for that long or until something else needs it to wake up.
iop.wait_run_iop(iop.kernel.dispatch());
}
Gfx::clear_vsync_callback();
}
} // namespace

View file

@ -225,4 +225,11 @@ s32 WakeupThread(s32 thid) {
iop->kernel.WakeupThread(thid);
return 0;
}
s32 RegisterVblankHandler(int edge, int priority, int (*handler)(void*), void* userdata) {
(void)edge;
(void)priority;
return iop->kernel.RegisterVblankHandler(handler);
}
} // namespace iop

View file

@ -138,6 +138,8 @@ s32 WaitSema(s32 sema);
s32 SignalSema(s32 sema);
s32 PollSema(s32 sema);
s32 RegisterVblankHandler(int edge, int priority, int (*handler)(void*), void* userdata);
void FlushDcache();
u32 sceSifCheckInit();

View file

@ -243,9 +243,17 @@ void IOP_Kernel::processWakeups() {
* Run the next IOP thread.
*/
time_stamp IOP_Kernel::dispatch() {
// Check vblank interrupt
if (vblank_handler != nullptr && vblank_recieved) {
vblank_handler(nullptr);
vblank_recieved = false;
}
// Update thread states
updateDelay();
processWakeups();
// Run until all threads are idle
IopThread* next = schedNext();
while (next != nullptr) {
// printf("[IOP Kernel] Dispatch %s (%d)\n", next->name.c_str(), next->thID);

View file

@ -173,6 +173,13 @@ class IOP_Kernel {
s32 SignalSema(s32 id);
s32 PollSema(s32 id);
s32 RegisterVblankHandler(int (*handler)(void*)) {
vblank_handler = handler;
return 0;
}
void signal_vblank() { vblank_recieved = true; };
void read_disc_sectors(u32 sector, u32 sectors, void* buffer);
bool sif_busy(u32 id);
@ -193,6 +200,9 @@ class IOP_Kernel {
IopThread* schedNext();
time_stamp nextWakeup();
s32 (*vblank_handler)(void*);
std::atomic_bool vblank_recieved = false;
cothread_t kernel_thread;
s32 _nextThID = 0;
IopThread* _currentThread = nullptr;