mirror of
https://github.com/encounter/aurora.git
synced 2026-07-09 18:19:33 -07:00
Add GXDestroyCopyTex function (#141)
This commit is contained in:
@@ -59,6 +59,8 @@ extern "C" {
|
||||
|
||||
#define GX_LOAD_AURORA_DESTROY_TLUT 0x0033
|
||||
|
||||
#define GX_LOAD_AURORA_DESTROY_COPY_TEX 0x0034
|
||||
|
||||
|
||||
/*
|
||||
* Debug marker stuff
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
// ============================================================================
|
||||
|
||||
@@ -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; }
|
||||
|
||||
Reference in New Issue
Block a user