29#include <EASTL/array.h>
30#include <EASTL/atomic.h>
31#include <EASTL/fixed_list.h>
32#include <EASTL/functional.h>
33#include <EASTL/utility.h>
54namespace timer_literals {
64consteval uint32_t
operator""_ns(
unsigned long long int value) {
return value / 1'000; }
65consteval uint32_t
operator""_us(
unsigned long long int value) {
return value; }
66consteval uint32_t
operator""_ms(
unsigned long long int value) {
return value * 1'000; }
67consteval uint32_t
operator""_s(
unsigned long long int value) {
return value * 1'000'000; }
68consteval uint32_t
operator""_ns(
long double value) {
return value / 1'000; }
69consteval uint32_t
operator""_us(
long double value) {
return value; }
70consteval uint32_t
operator""_ms(
long double value) {
return value * 1'000; }
71consteval uint32_t
operator""_s(
long double value) {
return value * 1'000'000; }
85 TimerAwaiter(
GPU &gpu, uint32_t deadline) : m_gpu(gpu), m_deadline(deadline) {}
87 constexpr bool await_ready()
const {
return false; }
88 void await_suspend(std::coroutine_handle<> handle) {
89 m_gpu.armTimer(m_deadline, [handle](uint32_t) { handle.resume(); });
91 void await_resume() {}
153 eastl::atomic_signal_fence(eastl::memory_order_acquire);
191 void getClear(Prim::FastFill &ff,
Color bg = {{0, 0, 0}})
const;
242 void uploadToVRAM(
const uint16_t *data, Rect region, eastl::function<
void()> &&callback,
251 template <Fragment Frag>
253 sendFragment(
reinterpret_cast<const uint32_t *
>(&fragment.head + 1), fragment.getActualFragmentSize());
265 template <Fragment Frag>
266 void sendFragment(
const Frag &fragment, eastl::function<
void()> &&callback,
268 sendFragment(
reinterpret_cast<const uint32_t *
>(&fragment.head + 1), fragment.getActualFragmentSize(),
269 eastl::move(callback), dmaCallback);
325 template <Primitive Prim>
328 const uint32_t *
ptr =
reinterpret_cast<const uint32_t *
>(&primitive);
329 constexpr size_t size =
sizeof(Prim) /
sizeof(uint32_t);
330 for (
int i = 0;
i <
size;
i++) {
349 template <Fragment Frag>
351 chain(&fragment.head, &fragment.head, fragment.getActualFragmentSize());
363 template <Fragment Frag1, Fragment Frag2>
364 void chain(Frag1 *first, Frag2 *last) {
365 auto count = last->getActualFragmentSize();
367 chain(&first->head, &last->head, last->getActualFragmentSize());
378 template <
size_t N, Safe safety = Safe::Yes>
390 template <Safe safety = Safe::Yes>
392 size_t n = table.
size();
459 uint32_t
now()
const {
return m_currentTime; }
478 uintptr_t
armTimer(uint32_t deadline, eastl::function<
void(uint32_t)> &&callback);
491 TimerAwaiter
delay(uint32_t microseconds) {
return {*
this,
now() + microseconds}; }
504 uintptr_t
armPeriodicTimer(uint32_t period, eastl::function<
void(uint32_t)> &&callback);
569 static constexpr unsigned c_oversizedShift = 4;
570 static constexpr unsigned c_maxNodeWords = 255;
573 GPU(
const GPU &) =
delete;
575 GPU &operator=(
const GPU &) =
delete;
576 GPU &operator=(
GPU &&) =
delete;
578 void sendFragment(
const uint32_t *data,
size_t count, eastl::function<
void()> &&callback,
580 void scheduleNormalDMA(uintptr_t data,
size_t count);
581 void scheduleChainedDMA(uintptr_t
head);
582 void chain(uintptr_t *first, uintptr_t *last,
size_t count);
583 void scheduleOTC(uintptr_t *
start, uint32_t
count);
584 void checkOTCAndTriggerCallback();
586 void prepareForTakeover();
588 eastl::function<void(
void)> m_dmaCallback =
nullptr;
589 unsigned m_refreshRate = 0;
592 uint32_t m_currentTime = 0;
593 uint32_t m_previousFrameCount = 0;
595 uint32_t m_lastLongFieldFrame = 0x80000000;
596 unsigned m_parity = 0;
597 uintptr_t *m_chainHead =
nullptr;
598 uintptr_t *m_chainTail =
nullptr;
599 size_t m_chainTailCount = 0;
600 enum { CHAIN_IDLE, CHAIN_TRANSFERRING, CHAIN_TRANSFERRED } m_chainStatus = CHAIN_IDLE;
602 eastl::function<void(uint32_t)> callback;
605 int32_t pausedRemaining;
609 eastl::fixed_list<Timer, 32> m_timers;
610 struct ScheduledOTC {
614 eastl::fixed_list<ScheduledOTC, 32> m_OTCs[2];
615 uintptr_t *m_chainNext =
nullptr;
617 uint16_t m_lastHSyncCounter = 0;
618 bool m_interlaced =
false;
619 bool m_fromISR =
false;
620 bool m_flushCacheAfterDMA =
false;
623 bool m_chainNextOversized =
false;
624 bool m_chainHeadOversized =
false;
uint32_t start
Definition cdlgetlocp.c:252
The application class.
Definition application.hh:49
An ordering table whose bucket count is chosen at runtime.
Definition ordering-table.hh:128
size_t size() const
Definition ordering-table.hh:158
psyqo::Fragments::ChainEntry * m_table
Definition ordering-table.hh:161
The singleton GPU class.
Definition gpu.hh:83
bool isChainIdle() const
Gets the status of the background DMA transfer operation when initiated by a frame flip.
Definition gpu.cpp:582
unsigned getParity() const
Get the index of the current display buffer.
Definition gpu.hh:170
void sendFragment(const Frag &fragment)
Immediately sends a fragment to the GPU. This is a blocking operation. See the fragments....
Definition gpu.hh:252
static constexpr uint32_t US_PER_HBLANK
Definition gpu.hh:106
void sendPrimitive(const Prim &primitive)
Sends a primitive to the GPU. This is a blocking call.
Definition gpu.hh:326
void waitChainIdle()
Waits until the background DMA transfer operation initiated by a frame flip is complete.
Definition gpu.hh:438
uint32_t getFrameCount() const
Returns the number of frames rendered by the GPU so far.
Definition gpu.hh:143
Interlace
Definition gpu.hh:101
uintptr_t armTimer(uint32_t deadline, eastl::function< void(uint32_t)> &&callback)
Creates a single-use timer.
Definition gpu.cpp:597
void sendFragment(const Frag &fragment, eastl::function< void()> &&callback, DMA::DmaCallback dmaCallback=DMA::FROM_MAIN_LOOP)
Sends a fragment to the GPU as a non-blocking call.
Definition gpu.hh:266
void disableScissor()
Immediately disables the scissoring of the VRAM.
Definition gpu.cpp:339
void chain(DynamicOrderingTable< safety > &table)
Chains a runtime-sized ordering table to the next DMA chain transfer.
Definition gpu.hh:391
static constexpr unsigned c_maxOversizedWords
Largest fragment chain accepts, in words.
Definition gpu.hh:121
void getClear(Prim::FastFill &ff, Color bg={{0, 0, 0}}) const
Sets a FastFill primitive to clear the current drawing buffer.
Definition gpu.cpp:379
void chain(Frag1 *first, Frag2 *last)
Chains an already constructed DMA chain to the next DMA chain transfer.
Definition gpu.hh:364
TimerAwaiter delay(uint32_t microseconds)
Delays the coroutine for a specified amount of time.
Definition gpu.hh:491
uintptr_t armPeriodicTimer(uint32_t period, eastl::function< void(uint32_t)> &&callback)
Creates a periodic timer.
Definition gpu.cpp:602
void enableScissor()
Enables the scissoring of the VRAM.
Definition gpu.cpp:344
void waitReady()
Waits until the GPU is ready to send a command.
Definition gpu.cpp:41
void getNextScissor(Prim::Scissor &scissor)
Gets the next scissoring region.
Definition gpu.cpp:361
void reinitialize(const Configuration &config)
Definition gpu.cpp:72
uint32_t now() const
Gets the current timestamp in microseconds.
Definition gpu.hh:459
void chain(OrderingTable< N, safety > &table)
Chains an ordering table to the next DMA chain transfer.
Definition gpu.hh:379
void initialize(const Configuration &config)
Definition gpu.cpp:148
unsigned getRefreshRate() const
Returns the refresh rate of the GPU.
Definition gpu.hh:129
MiscSetting
Definition gpu.hh:102
void sendChain()
Immediately sends the current DMA chain.
Definition gpu.cpp:528
ColorMode
Definition gpu.hh:100
void changeTimerPeriod(uintptr_t id, uint32_t period, bool reset=false)
Changes the period of a periodic timer.
Definition gpu.cpp:607
void pauseTimer(uintptr_t id)
Pauses a timer.
Definition gpu.cpp:623
void pumpCallbacks()
Runs one round of event processing.
Definition gpu.cpp:651
Resolution
Definition gpu.hh:98
void cancelTimer(uintptr_t id)
Cancels a timer.
Definition gpu.cpp:643
bool isChainTransferred() const
Gets the status of the background DMA transfer operation when initiated by a frame flip.
Definition gpu.cpp:592
VideoMode
Definition gpu.hh:99
void uploadToVRAM(const uint16_t *data, Rect region)
Uploads a buffer to the VRAM as a blocking call.
Definition gpu.cpp:397
void getNextClear(Prim::FastFill &ff, Color bg={{0, 0, 0}}) const
Sets a FastFill primitive to clear the next drawing buffer.
Definition gpu.cpp:387
static void sendRaw(uint32_t data)
Sends a raw 32 bits value to the Data register of the GPU.
Definition gpu.hh:317
uint32_t getLiveFrameCount() const
Returns the number of vsyncs since the GPU was initialized, as of now.
Definition gpu.hh:152
void waitFifo()
Waits until the GPU's FIFO is ready to receive data.
Definition gpu.cpp:47
void resumeTimer(uintptr_t id)
Resumes a paused timer.
Definition gpu.cpp:633
bool isChainTransferring() const
Gets the status of the background DMA transfer operation when initiated by a frame flip.
Definition gpu.cpp:587
void clear(Color bg={{0, 0, 0}})
Immediately clears the drawing buffer.
Definition gpu.cpp:373
void chain(Frag &fragment)
Chains a fragment to the next DMA chain transfer.
Definition gpu.hh:350
static constexpr unsigned c_chainThreshold
Definition gpu.hh:107
void getScissor(Prim::Scissor &scissor)
Gets the current scissoring region.
Definition gpu.cpp:350
static constexpr unsigned c_oversizedGranularity
Granularity of an oversized DMA chain fragment, in words.
Definition gpu.hh:117
The ordering table. Used to sort fragments before sending them to the GPU.
Definition ordering-table.hh:61
psyqo::Fragments::ChainEntry m_table[N+1]
Definition ordering-table.hh:114
#define head
Definition alloc.c:111
static int size
Definition string.h:149
volatile uint32_t * ptr
Definition cop0.c:80
uint32_t psyqoFrameCounter
Definition gpu.hh:50
int i
Definition gte-regio.c:299
#define N
Definition main.c:37
DmaCallback
Definition kernel.hh:38
@ FROM_MAIN_LOOP
Definition kernel.hh:40
Register< 0x0810 > Data
Definition gpu.cpp:29
void assert(bool condition, const char *message, std::source_location location=std::source_location::current())
A simple assert macro.
Definition kernel.hh:366
void takeOverKernel()
Takes over the kernel. Can only be called once inside the main function.
Definition kernel.cpp:140
uintptr_t head
Definition fragments.hh:89
Definition configuration.hh:29
A compounded Scissor primitive.
Definition control.hh:156
static int value
Definition syscalls.h:553
static const void size_t count
Definition syscalls.h:196
The Color struct.
Definition common.hh:91