Cover source retirement and indexed texture fallback on current master

This commit is contained in:
Matthew Stanley
2026-10-24 09:26:46 -07:00
parent aed7b1be1e
commit c5f67a1f4e
4 changed files with 42 additions and 3 deletions
+1 -1
View File
@@ -397,7 +397,7 @@ extern "C" void gpu_hd_textures_get_diag(GpuHdTextureDiag* out) {
out->diagnostic = session->diagnostics.back().c_str();
}
extern "C" int gpu_hd_textures_debug_uploads_at(int x, int y, char* out, size_t cap) {
if (out && cap) out[0] = '';
if (out && cap) out[0] = '\0';
return session ? hd_texture_pack_debug_uploads_at(session->beetle, (unsigned)x, (unsigned)y, out, cap) : 0;
}
extern "C" void gpu_hd_textures_note_applied(void) { if (session) ++session->diag.applied_draws; }
+1 -1
View File
@@ -1082,7 +1082,7 @@ int hd_texture_pack_debug_uploads_at(const HdTexturePack* pack, unsigned x, unsi
if (!out || cap == 0) return 0;
size_t pos = 0;
int n = 0;
out[0] = '';
out[0] = '\0';
if (!pack) return 0;
for (auto it = pack->uploads.rbegin(); it != pack->uploads.rend(); ++it) {
for (const Fragment& f : it->fragments) {
@@ -538,6 +538,26 @@ void split_coalesce_copy_parts(const fs::path& root) {
check(duck_texture_pack_match_draw(pack.get(),&q,0,&match) == HD_TEXTURE_LOOKUP_NONE,"single-cover API preserves native fallback for composed draw");
}
void release_while_another_source_splits(const fs::path& root) {
config(root,"MaxVRAMWriteSplits: 4\nDumpC16Textures: true\nDumpTextureWidthThreshold: 1\nDumpTextureHeightThreshold: 1\n");
std::vector<uint16_t> vram(1024*512);
place(vram,0,0,4,words(16)); place(vram,8,0,8,words(64));
auto pack=create(root); char error[512]{};
duck_texture_pack_track_upload(pack.get(),0,0,4,4,vram.data(),vram.size());
duck_texture_pack_track_upload(pack.get(),8,0,8,8,vram.data(),vram.size());
auto first=query(vram,0,0,2,0,3,0,3);
auto second=query(vram,0,0,2,8,15,0,7);
duck_texture_pack_dump_draw(pack.get(),&first,0,error,sizeof error);
duck_texture_pack_dump_draw(pack.get(),&second,0,error,sizeof error);
DuckTexturePackInfo before{},after{}; duck_texture_pack_get_info(pack.get(),&before);
check(before.pending_dump_sources==2,"both independent source observations are pending");
// Retires the first upload entirely, while the second keeps right and lower clips.
duck_texture_pack_invalidate(pack.get(),0,0,12,4);
duck_texture_pack_get_info(pack.get(),&after);
check(after.pending_dump_sources==1 && after.queued_dump_count==1,
"released source finalizes even when surviving upload splits keep the total count steady");
}
void resident_checkpoint(const fs::path& root) {
std::vector<uint16_t> vram(1024*512);
place(vram,0,0,8,std::vector<uint16_t>(8*16,0x3210));
@@ -604,7 +624,7 @@ int main(int argc, char** argv) {
palettes(root/"palettes"); st_alias_duplicates(root/"keys"); failed_payloads(root/"invalid"); dumping(root/"dump");
official_binary_oracle(root/"official-oracle"); defaults_and_options(root/"defaults");
immutable_palettes_and_pages(root/"snapshots"); split_coalesce_copy_parts(root/"lifecycle"); copied_pack_ownership(root/"ownership");
resident_checkpoint(root/"resident");
resident_checkpoint(root/"resident"); release_while_another_source_splits(root/"release-split");
/* Every artifact is created beneath this fresh, explicitly named test
* root. No user-provided paths participate in recursive cleanup. */
if (argc > 1 && !std::strcmp(argv[1],"--keep-artifacts")) std::printf("ARTIFACT_ROOT: %s\n",root.u8string().c_str());
+19
View File
@@ -211,6 +211,24 @@ HdTextureDrawQuery query4(const std::vector<uint16_t>& vram,
return query;
}
void test_indexed_palette_fallback() {
Fixture f;
std::ostringstream stem; stem<<std::hex<<f.upload_hash;
touch(f.replacements/(stem.str()+"-index.png"));
auto* pack=open_pack(f.root); if(!pack)return;
hd_texture_pack_track_upload(pack,10,20,8,4,f.upload_words.data(),f.upload_words.size(),nullptr);
auto q=query4(f.vram,0,31); HdTextureMatch match{};
check(hd_texture_pack_match(pack,&q,&match)==HD_TEXTURE_LOOKUP_FOUND &&
match.entry.palette_hash==f.palette4_hash,"exact palette wins over indexed fallback");
f.vram[7*1024+1020]^=1;
hd_texture_pack_invalidate(pack,1020,7,1,1);
check(hd_texture_pack_match(pack,&q,&match)==HD_TEXTURE_LOOKUP_FOUND &&
match.entry.palette_hash==HD_TEXTURE_PALETTE_INDEXED,"changed CLUT uses palette-independent index key");
q.depth=HD_TEXTURE_DEPTH_16BPP; q.u_last=7;
check(hd_texture_pack_match(pack,&q,&match)==HD_TEXTURE_LOOKUP_NONE,"16bpp never uses indexed palette fallback");
hd_texture_pack_destroy(pack);
}
void test_crc_exact_little_endian() {
const uint16_t ascii_words[] = {0x3231, 0x3433, 0x3635, 0x3837};
check(hd_texture_crc32_words_le(ascii_words, 4) == 0x9AE0DAAFu,
@@ -516,6 +534,7 @@ void test_bounded_async_decode(Fixture& fixture) {
int main() {
test_crc_exact_little_endian();
test_indexed_palette_fallback();
Fixture fixture;
test_scan_mapping(fixture);
test_palette_match_and_invalidation(fixture);