Add GXDestroyCopyTex function (#141)

This commit is contained in:
Luke Street
2026-04-26 14:01:24 -06:00
committed by GitHub
parent 8af9057689
commit a6a3d3a65a
8 changed files with 75 additions and 0 deletions
+2
View File
@@ -59,6 +59,8 @@ extern "C" {
#define GX_LOAD_AURORA_DESTROY_TLUT 0x0033
#define GX_LOAD_AURORA_DESTROY_COPY_TEX 0x0034
/*
* Debug marker stuff
+1
View File
@@ -18,6 +18,7 @@ typedef struct {
void GXDestroyTexObj(GXTexObj* obj);
void GXDestroyTlutObj(GXTlutObj* obj);
void GXDestroyCopyTex(void* dest);
void GXColor4f32(float r, float g, float b, float a);
+7
View File
@@ -20,4 +20,11 @@ void GXDestroyTlutObj(GXTlutObj* obj_) {
}
obj->tlutObjId = 0;
}
void GXDestroyCopyTex(void* dest) {
if (dest != nullptr) {
GX_WRITE_AURORA(GX_LOAD_AURORA_DESTROY_COPY_TEX);
GX_WRITE_U64(reinterpret_cast<u64>(dest));
}
}
}
+4
View File
@@ -1776,6 +1776,10 @@ void handle_aurora(const u8* data, u32& pos, u32 size, bool bigEndian) {
CHECK(pos + 4 <= size, "GX_LOAD_AURORA_DESTROY_TLUT read overrun");
evict_tlut_object(read_u32(data + pos, bigEndian));
pos += 4;
} else if (subCmd == GX_LOAD_AURORA_DESTROY_COPY_TEX) {
CHECK(pos + 8 <= size, "GX_LOAD_AURORA_DESTROY_COPY_TEX read overrun");
evict_copy_texture(reinterpret_cast<const void*>(read_u64(data + pos, bigEndian)));
pos += 8;
} else if (subCmd == GX_LOAD_AURORA_DEBUG_GROUP_PUSH) {
auto label = read_string(data, pos, size, bigEndian);
gfx::push_debug_group(std::move(label));
+11
View File
@@ -379,6 +379,17 @@ void clear_copy_texture_cache() noexcept {
}
}
void evict_copy_texture(const void* dest) noexcept {
g_gxState.copyTextures.erase(dest);
for (auto it = g_gxState.copyTextureCache.begin(); it != g_gxState.copyTextureCache.end();) {
if (it->first.dest == dest) {
g_gxState.copyTextureCache.erase(it++);
} else {
++it;
}
}
}
void resolve_sampled_textures(const ShaderInfo& info) noexcept {
ZoneScoped;
+1
View File
@@ -388,6 +388,7 @@ struct ShaderInfo;
void initialize() noexcept;
void shutdown() noexcept;
void clear_copy_texture_cache() noexcept;
void evict_copy_texture(const void* dest) noexcept;
void evict_texture_object(u32 texObjId) noexcept;
void evict_tlut_object(u32 tlutObjId) noexcept;
Vec2<uint32_t> logical_fb_size() noexcept;
+39
View File
@@ -1461,6 +1461,45 @@ TEST_F(GXFifoTest, DestroyTlutObj_MarksLoadedSlotNoCacheUntilReloaded) {
EXPECT_FALSE(slot.no_cache());
}
TEST_F(GXFifoTest, DestroyCopyTex_EmitsAuroraDestroyCommand) {
alignas(32) u8 image[32]{};
GXDestroyCopyTex(image);
auto bytes = capture_fifo();
EXPECT_TRUE(has_aurora_cmd(bytes, GX_LOAD_AURORA_DESTROY_COPY_TEX));
reset_gx_state();
decode_fifo(bytes);
}
TEST_F(GXFifoTest, DestroyCopyTex_RemovesActiveCopyTextureAndCacheEntriesForPointer) {
alignas(32) u8 imageA[32]{};
alignas(32) u8 imageB[32]{};
const aurora::gx::GXState::CopyTextureRef ref{.revision = 1};
gxState().copyTextures[imageA] = ref;
gxState().copyTextures[imageB] = ref;
gxState().copyTextureCache.emplace(
aurora::gx::GXState::CopyTextureKey{.dest = imageA, .width = 32, .height = 32, .format = GX_TF_I4}, ref);
gxState().copyTextureCache.emplace(
aurora::gx::GXState::CopyTextureKey{.dest = imageA, .width = 64, .height = 64, .format = GX_TF_I8}, ref);
gxState().copyTextureCache.emplace(
aurora::gx::GXState::CopyTextureKey{.dest = imageB, .width = 32, .height = 32, .format = GX_TF_I4}, ref);
GXDestroyCopyTex(imageA);
auto bytes = capture_fifo();
decode_fifo(bytes);
EXPECT_FALSE(gxState().copyTextures.contains(imageA));
EXPECT_TRUE(gxState().copyTextures.contains(imageB));
for (const auto& [key, _] : gxState().copyTextureCache) {
EXPECT_NE(key.dest, imageA);
}
EXPECT_EQ(gxState().copyTextureCache.size(), 1u);
}
// ============================================================================
// BP genMode (requires __GXSetDirtyState() flush)
// ============================================================================
+10
View File
@@ -80,6 +80,16 @@ void evict_tlut_object(u32 tlutObjId) noexcept {
}
}
}
void evict_copy_texture(const void* dest) noexcept {
g_gxState.copyTextures.erase(dest);
for (auto it = g_gxState.copyTextureCache.begin(); it != g_gxState.copyTextureCache.end();) {
if (it->first.dest == dest) {
g_gxState.copyTextureCache.erase(it++);
} else {
++it;
}
}
}
void shutdown() noexcept {}
Vec2<uint32_t> logical_fb_size() noexcept { return {640, 480}; }
gfx::Viewport map_logical_viewport(const gfx::Viewport& logicalViewport) noexcept { return logicalViewport; }