mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-31 23:19:44 +08:00
6ee445f0c2
GFX10 stores a mip chain smallest-first: the mip tail packs into the first swizzle block, the remaining mips follow in decreasing size, and mip 0 ends up at the end of the allocation. We read the base level straight from the descriptor address, so every mipped sampled texture decoded as a collage of its own smaller mips - in Demon's Souls that showed up as scrambled menu text and repeated controller icons. GnmTiling.TryGetBaseMipPlacement ports the AddrLib chain-offset math from Gfx10Lib::ComputeSurfaceInfoMacroTiled/MicroTiled. It returns a byte offset to mip 0, or, when the whole chain fits inside the tail block, the element coordinates of mip 0 within that block. TryCreateGuestDrawTexture applies the offset to the sampled and storage guest reads, and TryDetileTextureSource lifts a tail-resident mip 0 out of the detiled block as a sub-rectangle. MAX_MIP is only decoded from extended descriptors, so resources without one, and single-level resources, keep the current behaviour. Tested on Demon's Souls (PPSA01342): menu text and icons decode correctly instead of showing shrunken copies of themselves. Verified offline by dumping the raw tiled bytes and the detiled output for a 4096x4096 UI atlas and checking the art lands at the sampled coordinates.