better bp caching, xf cache, optimize fifo with realloc and remove double lookups (#110)

* optimize fifo with realloc and remove double lookups

* bp cache, xf cache, and last pipeline ref cache

* remove double lookup from find/try_emplace

* change name

* Move xfRegCache

* Update gx_test_stubs.cpp

---------

Co-authored-by: Luke Street <luke@street.dev>
This commit is contained in:
qwertyquerty
2026-04-12 18:40:21 -07:00
committed by GitHub
parent eb17aab5e1
commit 5fee2ac628
5 changed files with 28 additions and 35 deletions
+5 -1
View File
@@ -504,6 +504,7 @@ static void handle_bp(u32 value, bool bigEndian) {
g_gxState.bpRegCache[0xFE] = 0x00FFFFFF;
const u32 merged = (g_gxState.bpRegCache[regId] & ~ssMask) | (value & ssMask);
value = (regId << 24) | (merged & 0x00FFFFFF);
if (g_gxState.bpRegCache[regId] == value) return;
g_gxState.bpRegCache[regId] = value;
}
@@ -1275,7 +1276,10 @@ static void handle_xf(const u8* data, u32& pos, u32 size, bool bigEndian) {
for (u32 i = 0; i < count; i++) {
u32 reg = xfAddr + i;
u32 val = read_u32(xfData + i * 4, bigEndian);
f32 fval = read_f32(xfData + i * 4, bigEndian);
// Skip scalar register writes that haven't changed (viewport/projection handled below)
if (reg <= 0x19 && val == g_gxState.xfRegCache[reg]) continue;
if (reg <= 0x19) g_gxState.xfRegCache[reg] = val;
switch (reg) {
case 0x08:
+6 -13
View File
@@ -2,6 +2,7 @@
#include "command_processor.hpp"
#include "../internal.hpp"
#include <cstdlib>
#include <cstring>
namespace aurora::gx::fifo {
@@ -19,8 +20,8 @@ uint32_t sDlWritePos = 0;
void init() {
constexpr uint32_t initialCapacity = 64 * 1024;
delete[] detail::sBufferData;
detail::sBufferData = new uint8_t[initialCapacity];
free(detail::sBufferData);
detail::sBufferData = static_cast<uint8_t*>(malloc(initialCapacity));
detail::sBufferSize = 0;
detail::sBufferCapacity = initialCapacity;
detail::sInDisplayList = false;
@@ -31,17 +32,9 @@ void init() {
void write_data_grow(const void* data, uint32_t length) {
uint32_t needed = detail::sBufferSize + length;
uint32_t newCap = detail::sBufferCapacity * 2;
if (newCap < needed) {
newCap = needed;
}
auto* newBuf = new uint8_t[newCap];
if (detail::sBufferSize > 0) {
std::memcpy(newBuf, detail::sBufferData, detail::sBufferSize);
}
std::memcpy(newBuf + detail::sBufferSize, data, length);
delete[] detail::sBufferData;
detail::sBufferData = newBuf;
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;
}
+1
View File
@@ -373,6 +373,7 @@ struct GXState {
regs[0xFE] = 0x00FFFFFF;
return regs;
}();
std::array<u32, 0x1A> xfRegCache;
void clearVtxSizeCache() { lastVtxFmt = GX_MAX_VTXFMT; }
};
+15 -17
View File
@@ -80,35 +80,35 @@ SDL_JoystickID add_controller(SDL_JoystickID which) noexcept {
}
void remove_controller(Uint32 instance) noexcept {
if (g_GameControllers.find(instance) != g_GameControllers.end()) {
SDL_CloseGamepad(g_GameControllers[instance].m_controller);
g_GameControllers.erase(instance);
if (auto it = g_GameControllers.find(instance); it != g_GameControllers.end()) {
SDL_CloseGamepad(it->second.m_controller);
g_GameControllers.erase(it);
}
}
bool is_gamecube(Uint32 instance) noexcept {
if (g_GameControllers.find(instance) != g_GameControllers.end()) {
return g_GameControllers[instance].m_isGameCube;
if (auto it = g_GameControllers.find(instance); it != g_GameControllers.end()) {
return it->second.m_isGameCube;
}
return false;
}
int32_t player_index(Uint32 instance) noexcept {
if (g_GameControllers.find(instance) != g_GameControllers.end()) {
return SDL_GetGamepadPlayerIndex(g_GameControllers[instance].m_controller);
if (auto it = g_GameControllers.find(instance); it != g_GameControllers.end()) {
return SDL_GetGamepadPlayerIndex(it->second.m_controller);
}
return -1;
}
void set_player_index(Uint32 instance, Sint32 index) noexcept {
if (g_GameControllers.find(instance) != g_GameControllers.end()) {
SDL_SetGamepadPlayerIndex(g_GameControllers[instance].m_controller, index);
if (auto it = g_GameControllers.find(instance); it != g_GameControllers.end()) {
SDL_SetGamepadPlayerIndex(it->second.m_controller, index);
}
}
std::string controller_name(Uint32 instance) noexcept {
if (g_GameControllers.find(instance) != g_GameControllers.end()) {
const auto* name = SDL_GetGamepadName(g_GameControllers[instance].m_controller);
if (auto it = g_GameControllers.find(instance); it != g_GameControllers.end()) {
const auto* name = SDL_GetGamepadName(it->second.m_controller);
if (name != nullptr) {
return {name};
}
@@ -117,18 +117,16 @@ std::string controller_name(Uint32 instance) noexcept {
}
bool controller_has_rumble(Uint32 instance) noexcept {
if (g_GameControllers.find(instance) != g_GameControllers.end()) {
return g_GameControllers[instance].m_hasRumble;
if (auto it = g_GameControllers.find(instance); it != g_GameControllers.end()) {
return it->second.m_hasRumble;
}
return false;
}
void controller_rumble(uint32_t instance, uint16_t low_freq_intensity, uint16_t high_freq_intensity,
uint16_t duration_ms) noexcept {
if (g_GameControllers.find(instance) != g_GameControllers.end()) {
SDL_RumbleGamepad(g_GameControllers[instance].m_controller, low_freq_intensity, high_freq_intensity, duration_ms);
if (auto it = g_GameControllers.find(instance); it != g_GameControllers.end()) {
SDL_RumbleGamepad(it->second.m_controller, low_freq_intensity, high_freq_intensity, duration_ms);
}
}
+1 -4
View File
@@ -70,10 +70,7 @@ namespace aurora::gx {
void populate_pipeline_config(PipelineConfig& config, GXPrimitive primitive, GXVtxFmt fmt) noexcept {
// No-op for tests
}
GXBindGroups build_bind_groups(const ShaderInfo& info, const ShaderConfig& config,
const BindGroupRanges& ranges) noexcept {
return {};
}
GXBindGroups build_bind_groups(const ShaderInfo& info) noexcept { return {}; }
ShaderInfo build_shader_info(const ShaderConfig& config) noexcept { return {}; }
gfx::Range build_uniform(const ShaderInfo& info, uint32_t vtxStart, const BindGroupRanges& ranges) noexcept {
return {};