Files
aurora/lib/dolphin/gx/GXDispList.cpp
T
2026-06-04 23:43:13 -06:00

89 lines
2.3 KiB
C++

#include "gx.hpp"
#include "__gx.h"
#include "../../gx/command_processor.hpp"
#include "../../gx/fifo.hpp"
#include <cstring>
static __GXData_struct sSavedGXData;
extern "C" {
void GXBeginDisplayList(void* list, u32 size) {
CHECK(!aurora::gx::fifo::in_display_list(), "Display list began twice!");
// Flush any pending dirty state before recording
if (__gx->dirtyState != 0) {
__GXSetDirtyState();
}
// Save current shadow register state if requested
if (__gx->dlSaveContext != 0) {
std::memcpy(&sSavedGXData, __gx, sizeof(sSavedGXData));
}
__gx->inDispList = 1;
// Redirect FIFO writes to the user-provided buffer
aurora::gx::fifo::begin_display_list(static_cast<u8*>(list), size);
}
u32 GXEndDisplayList() {
// Flush any pending dirty state into the display list
if (__gx->dirtyState != 0) {
__GXSetDirtyState();
}
// End FIFO redirection and get the byte count (ROUNDUP32)
u32 bytesWritten = aurora::gx::fifo::end_display_list();
// Restore saved shadow register state
if (__gx->dlSaveContext != 0) {
std::memcpy(__gx, &sSavedGXData, sizeof(*__gx));
}
__gx->inDispList = 0;
return bytesWritten;
}
void GXCallDisplayList(const void* data, u32 nbytes) {
// Flush any pending dirty state before calling
if (__gx->dirtyState != 0) {
__GXSetDirtyState();
}
// Flush pending primitives
if (*reinterpret_cast<u32*>(&__gx->vNum) != 0) {
__GXSendFlushPrim();
}
// Write display list contents to the FIFO
aurora::gx::fifo::write_data(data, nbytes);
// TEMP: debugging aid
// aurora::gx::fifo::drain();
// aurora::gx::fifo::process(static_cast<const u8*>(data), nbytes, true);
}
void GXCallDisplayListLE(const void* data, u32 nbytes) {
// Flush any pending dirty state before calling
if (__gx->dirtyState != 0) {
__GXSetDirtyState();
}
// Flush pending primitives
if (*reinterpret_cast<u32*>(&__gx->vNum) != 0) {
__GXSendFlushPrim();
}
// Drain the internal FIFO so that any pending CP register writes
// (VCD, VAT, etc.) are processed into g_gxState before the display
// list's draw commands reference them.
aurora::gx::fifo::drain();
// Process the display list through the command processor (little-endian)
aurora::gx::fifo::process(static_cast<const u8*>(data), nbytes, false);
}
}