Files
wiicompiled/aurora-main/lib/gx/fifo.cpp
T
patchzyy 6f14bde26a Kartpad upstream fixes (#244)
* Preserve interrupted registers and unwind alarm guards before rescheduling

Adapt the RFL interrupt-context and alarm reschedule fixes from KartPad ed8e4ca and 0c9bff0. Keep caller registers private and release the recursion guard before a woken fiber can pump callbacks.

* Keep local Wii identity services available when networking is disabled

Adapt KartPad a0f3fb5. Only IP and SSL devices require network access; KD request/time and NCD management remain available for offline save and license initialization.

* Share repeated LR continuation dispatch in translated functions

Adapt KartPad be91d8f/a3f90eb without its floating-point ABI changes. Preserve upstream continuation discovery and all resume labels. Validation: 640 translator tests passed.

* Reject inconsistent GPU cache sizes before allocation or copying

Adapt KartPad runtime 70951022. Validate raw lengths, compression tags and Zstd frame lengths on the size probe as well as the fetch. Tested against malformed SQLite rows and valid raw/compressed round trips.

* Wake compiler workers when pipeline work becomes runnable

Adapt KartPad runtime 956d811e. Wake all consumers of the shared condition variable after queue insertion or promotion; retain upstream desktop prewarm policy. A blocked-compiler probe verified progress by an idle worker.

* Reuse and release one Metal view per SDL window

Adapt KartPad 3606741. Surface recreation reuses the existing view and window property cleanup owns its lifetime. Reviewed against SDL3 cleanup semantics; Apple hardware validation remains outstanding.

* Avoid overreading packed three-byte vertex attributes

Adapt KartPad 0f6b274. Do not read a second storage word when all three requested bytes fit in the first. Preserve upstream depth and fog corrections.

* Keep interpolation history within each split-screen viewport

Adapt KartPad d6299b5. Scope exact, material and sibling-palette matching to the logical viewport so identical meshes from different cameras cannot share transforms.

* Report graphics startup failures and safely clean up partial ImGui initialization

Adapt KartPad runtime 70dc9380 and c4566e50 using the existing WiiCompiled exception/reporting path. A dummy-video-driver probe verified error return and repeated partial shutdown without aborting.

* Preserve GX draw boundaries and GPU staging and readback state

Adapt the validated renderer fixes from KartPad runtime 31add0c3, 7393dafe, b7f515de, cf46a9c7, fad42a7b, 7cd09b69, 9feea6b2 and Android 2505ae22 to current upstream. Preserve complete primitives and fresh vertex layouts, split staging batches before overflow, retain offscreen state, scope asynchronous callbacks and frame state, and complete texture-copy sources.

Add unit regressions and an optional ROM-free GPU pixel test. Validation: 250 GX tests and actual D3D12 pixel/readback, capacity, interpolation and frame-worker checks passed with Dawn validation enabled.
2026-09-23 19:27:51 +02:00

107 lines
3.1 KiB
C++

#include "fifo.hpp"
#include "command_processor.hpp"
#include "../gfx/common.hpp"
#include "../internal.hpp"
#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "tracy/Tracy.hpp"
namespace aurora::gx::fifo {
static Module Log("aurora::gx::fifo");
namespace detail {
uint8_t* sBufferData = nullptr;
uint32_t sBufferSize = 0;
uint32_t sBufferCapacity = 0;
bool sInDisplayList = false;
uint8_t* sDlBuffer = nullptr;
uint32_t sDlSize = 0;
uint32_t sDlWritePos = 0;
} // namespace detail
void init() {
constexpr uint32_t initialCapacity = 64 * 1024;
reset_cp_register_cache();
free(detail::sBufferData);
detail::sBufferData = static_cast<uint8_t*>(malloc(initialCapacity));
detail::sBufferSize = 0;
detail::sBufferCapacity = initialCapacity;
detail::sInDisplayList = false;
detail::sDlBuffer = nullptr;
detail::sDlSize = 0;
detail::sDlWritePos = 0;
}
void write_data_grow(const void* data, uint32_t length) {
uint32_t needed = detail::sBufferSize + length;
uint32_t newCap = std::max(detail::sBufferCapacity * 2, needed);
detail::sBufferData = static_cast<uint8_t*>(realloc(detail::sBufferData, newCap));
std::memcpy(detail::sBufferData + detail::sBufferSize, data, length);
detail::sBufferSize = needed;
detail::sBufferCapacity = newCap;
}
void begin_display_list(uint8_t* buf, uint32_t size) {
detail::sInDisplayList = true;
detail::sDlBuffer = buf;
detail::sDlSize = size;
detail::sDlWritePos = 0;
}
uint32_t end_display_list() {
detail::sInDisplayList = false;
uint32_t bytesWritten = detail::sDlWritePos;
uint32_t padded = (bytesWritten + 31) & ~31u;
while (detail::sDlWritePos < padded && detail::sDlWritePos < detail::sDlSize) {
detail::sDlBuffer[detail::sDlWritePos++] = 0;
}
detail::sDlBuffer = nullptr;
detail::sDlSize = 0;
detail::sDlWritePos = 0;
return padded;
}
bool in_display_list() { return detail::sInDisplayList; }
// How much of the producer's frame is spent blocked before it may decode the next batch of GX commands.
static void note_drain_wait(uint64_t nanos) noexcept {
ZoneScopedN("FIFO drain wait");
TracyPlot("aurora: fifoDrainWaitUs", static_cast<int64_t>(nanos / 1000));
}
void drain() {
// SEALED, not DONE.
const auto waited = aurora::wait_for_frame_worker_sealed();
if (waited.count() > 0) UNLIKELY {
note_drain_wait(static_cast<uint64_t>(waited.count()));
}
if (detail::sBufferSize == 0) {
return;
}
uint32_t consumed = 0;
bool retried = false;
while (consumed < detail::sBufferSize) {
const auto count = process(detail::sBufferData + consumed, detail::sBufferSize - consumed, true);
if (count == 0 && retried)
throw gfx::StagingCapacityError("FIFO draw does not fit after capacity submission");
consumed += count;
if (consumed == detail::sBufferSize) break;
// process returned with its renderer lock released. No recursive drain.
gfx::split_staging_batch();
retried = true;
}
detail::sBufferSize = 0;
}
const uint8_t* get_buffer_data() { return detail::sBufferData; }
uint32_t get_buffer_size() { return detail::sBufferSize; }
void clear_buffer() {
detail::sBufferSize = 0;
}
} // namespace aurora::gx::fifo