From 77c7f391d163a75e06ef418f1255d550ea2de523 Mon Sep 17 00:00:00 2001 From: jaby Date: Sat, 5 Oct 2024 13:22:09 +0200 Subject: [PATCH] Establish VSyncCallback rendering --- .../PoolBox/application/src/application.cpp | 18 ++++++++-- include/PSX/GPU/gpu.hpp | 12 ++++--- .../internal-include/GPU/gpu_internal.hpp | 4 +++ src/Library/src/GPU/gpu.cpp | 36 ++++++++++++------- 4 files changed, 52 insertions(+), 18 deletions(-) diff --git a/examples/PoolBox/application/src/application.cpp b/examples/PoolBox/application/src/application.cpp index 9f245b33..bfe86b07 100644 --- a/examples/PoolBox/application/src/application.cpp +++ b/examples/PoolBox/application/src/application.cpp @@ -248,17 +248,31 @@ namespace LoadingScene { FontWriter::new_font_writer.render(); } + // TODO: No good name + static void test() { + const auto triangle1 = Make::POLY_F3({ + Make::Vertex(0, 0), + Make::Vertex(128, 128), + Make::Vertex(0, 128)}, + GPU::Color24::Blue()); + + GPU::swap_buffers(false); + GPU::render(triangle1); + } + static void run() { if(Shared::load_test || old_state_changer != state_changer) { update(); - GPU::swap_buffers_vsync(1); render(); - GPU::swap_buffers_vsync(1); + + GPU::set_vsync_callback(test); cd_player.push(); state_changer.asset_load(); old_state_changer = state_changer; cd_player.pop(); + + GPU::set_vsync_callback(nullptr); } state_changer.main(); diff --git a/include/PSX/GPU/gpu.hpp b/include/PSX/GPU/gpu.hpp index 12dc7943..d364829f 100644 --- a/include/PSX/GPU/gpu.hpp +++ b/include/PSX/GPU/gpu.hpp @@ -14,6 +14,11 @@ namespace JabyEngine { namespace GPU { + namespace internal { + void render(const uint32_t* data, size_t words); + void render_dma(const uint32_t* data); + } + struct Display { #ifdef JABYENGINE_PAL static constexpr size_t Width = 320; @@ -42,6 +47,7 @@ namespace JabyEngine { static void set_offset(int16_t x, int16_t y); }; + using VSyncCallback = void (*)(); static uint32_t update_id() { return Display::current_id; @@ -51,10 +57,7 @@ namespace JabyEngine { return Display::current_id ^ 1; } - namespace internal { - void render(const uint32_t* data, size_t words); - void render_dma(const uint32_t* data); - } + void set_vsync_callback(VSyncCallback callback); template static void render(const LinkedElement& linked_primitives) { @@ -75,6 +78,7 @@ namespace JabyEngine { while(!GPU_IO::GPUSTAT.read().is_set(GPU_IO_Values::GPUSTAT::GP0ReadyForCMD)); } + void swap_buffers(bool clear_screen = true); uint8_t swap_buffers_vsync(uint8_t syncs, bool clear_screen = true); } } \ No newline at end of file diff --git a/src/Library/internal-include/GPU/gpu_internal.hpp b/src/Library/internal-include/GPU/gpu_internal.hpp index bc55ba9c..2eb72ee5 100644 --- a/src/Library/internal-include/GPU/gpu_internal.hpp +++ b/src/Library/internal-include/GPU/gpu_internal.hpp @@ -24,6 +24,7 @@ namespace JabyEngine { static uint32_t exchange_buffer_and_display(); }; + extern bool vsync_lock_callback; void wait_vsync(uint8_t syncs); @@ -70,10 +71,12 @@ namespace JabyEngine { static void wait() { DMA_IO::GPU.wait(); + vsync_lock_callback = false; } static void end() { reset_cmd_buffer(); + vsync_lock_callback = false; } struct Receive { @@ -100,6 +103,7 @@ namespace JabyEngine { static void start(uint16_t blockCount, uint16_t wordsPerBlock = 0x10) { using SyncMode1 = DMA_IO_Values::BCR::SyncMode1; + vsync_lock_callback = true; #ifdef __SUPPORT_PS3__ DMA_IO::GPU.set_adr(MADR); DMA::MADR += (blockCount * wordsPerBlock) << 2; diff --git a/src/Library/src/GPU/gpu.cpp b/src/Library/src/GPU/gpu.cpp index 37aca7e3..aa7c14e6 100644 --- a/src/Library/src/GPU/gpu.cpp +++ b/src/Library/src/GPU/gpu.cpp @@ -15,8 +15,10 @@ namespace JabyEngine { static SysCall::InterruptVerifierResult interrupt_verifier(); static void interrupt_handler(uint32_t); - static uint8_t vsync_counter = 0; - auto irq_callback = SysCall::InterruptCallback::from(interrupt_verifier, interrupt_handler); + auto irq_callback = SysCall::InterruptCallback::from(interrupt_verifier, interrupt_handler); + VSyncCallback vsync_callback = nullptr; //< TODO: Typedef later + static uint8_t vsync_counter = 0; + bool vsync_lock_callback = false; static SysCall::InterruptVerifierResult interrupt_verifier() { if(Interrupt::is_irq(Interrupt::VBlank)) { @@ -33,6 +35,9 @@ namespace JabyEngine { vsync_counter++; MasterTime::value++; + if(vsync_callback && !vsync_lock_callback) { + vsync_callback(); + } //Callback::internal::VSync::execute(); SysCall::ReturnFromException(); } @@ -48,20 +53,19 @@ namespace JabyEngine { return draw_area_y; } - uint8_t dst_value = 0; - void wait_vsync(uint8_t syncs) { volatile auto& vsync_count = reinterpret_cast(vsync_counter); - - dst_value = vsync_count + syncs; - while(vsync_count != dst_value); + + const uint8_t vsync_dst_value = vsync_count + syncs; + while(vsync_count != vsync_dst_value); } void render(const uint32_t* data, size_t words) { wait_ready_for_CMD(); #ifdef __SUPPORT_PS3__ + // TODO: Doesn't matter anymore...? // The PS3 needs explict change to FiFo - GPU_IO::GP1.set_dma_direction(GPU_IO_Values::GPUSTAT::DMADirection::Fifo); + //GPU_IO::GP1.set_dma_direction(GPU_IO_Values::GPUSTAT::DMADirection::Fifo); #endif // __SUPPORT_PS3__ for(size_t n = 0; n < words; n++) { @@ -98,16 +102,24 @@ namespace JabyEngine { GPU_IO::GP1.set_vertical_display_range( y, y + Display::Height + PS3_CorrectionY); } - uint8_t swap_buffers_vsync(uint8_t syncs, bool clear_screen) { - // Waits for finish FIFO - internal::wait_ready_for_CMD(); + void set_vsync_callback(VSyncCallback callback) { + internal::vsync_callback = callback; + } - internal::wait_vsync(syncs); + void swap_buffers(bool clear_screen) { const int16_t draw_offset_y = internal::Display::exchange_buffer_and_display(); internal::set_draw_offset(GPU::PositionI16::create(0, draw_offset_y)); if(clear_screen) { internal::quick_fill_fast(Color24::Black(), AreaU16::create(0, static_cast(draw_offset_y), Display::Width, Display::Height)); } + } + + uint8_t swap_buffers_vsync(uint8_t syncs, bool clear_screen) { + // Waits for finish FIFO + internal::wait_ready_for_CMD(); + internal::wait_vsync(syncs); + + swap_buffers(clear_screen); return Display::current_id; } }