Measured on hardware (ppsspp-re geprobe exp177-202, docs/ge-texture-cache.md): 64 lines of 16 bytes x 8
rows in 16 sets of 4 ways, LRU, the set index split between column and band bits by texel size. A line is
tagged by its position in the texture and its mip level only, so another texture read without TEXFLUSH
gets the first one's bytes where their lines coincide; lines load raw bytes on first read and nothing but
TEXFLUSH drops them, not rendering into the texture, block transfers or CPU writes.
TexCache steps every textured primitive through that, in submission order, from its texel footprint. A
line remembers where it came from and its bytes are copied only before that memory changes (drawing, block
transfers, copies, and anything at all when the CPU is about to run). While every line is from the one
texture read since TEXFLUSH and nothing has been copied, nothing read can differ from memory, so primitives
only log what they read, and TEXFLUSH usually drops the log unread. A primitive that reads bytes differing
from memory, or draws over what it reads, is drawn alone from its texture with what it read from the cache
laid over memory. That replaces SelfTextureSnapshot and its "fits in 8 KB" rule.
All the cache experiments match the PSP exactly except exp177, which samples a block transfer's
destination without TEXSYNC. Within a primitive this still loads every line before it draws; the GE loads
them as it rasterizes (serpentine rows, writes reaching memory a 16-byte block late), which Split
Second's blur (the one dump that changes) depends on. About 2% slower in Tekken 6 and God of War.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Where the GE stores each depth pixel, from the EDRAM address translation
and the color format: with 32-bit color, address bits 5 up to log2(T) - 1
rotate left by one, then (T << 3) | 0x40 is XORed in (0x600, and bits 9
and 10 swapped, at T 0). The CPU sees the same mapping through VRAM's
0x04200000 and 0x04600000 mirrors. Measured in ppsspp-re geprobe exp8-10
(every pixel of 512x272 buffers at each T) and exp88; the unit test checks
it against the model fitted there.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The float24 truncations, reciprocal and rsqrt tables, GE adder and row sums,
the setup reciprocal for planes, the mip log2, texture coordinate precision,
the lighting pow and color scaling, and the antialiased line alpha, from
TransformUnit, Rasterizer and Lighting, so they can be unit tested. No
behavior change.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Use the existing expandTo32bit mode in the texture decoder instead of
the backend-specific switches and stuff.
Just gets rid of a bunch of redundant code and makes further changes
easier.
We no longer support non-NEON ARM.
It's nice also to have the NEON and SSE implementations "close" to each
other, easier to port optimizations back and forth etc.