The software renderer drops a color test that only rejects black under blending that adds to the
destination, since rejecting black then only skips adding nothing. With dithering on it doesn't:
a rejected pixel keeps the destination, an accepted black one gets the dither added. Ridge Racer 2
(20839) adds a glow that way and came out one step darker wherever the dither matrix was negative;
Burnout Legends' bloom (16119) too. Fog and logic ops would change the destination the same way.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The software renderer kept depth linear in VRAM, where the GE stores it
in the layout GPU/Common/DepthSwizzle.h describes, from the EDRAM address
translation and the color format. So a texture or anything else sharing
VRAM with a depth buffer saw depth land in the wrong places (the player's
shadow in Silent Hill: Origins, #22415). Now every depth access goes
through the layout: the generic pixel functions, the 2x2 depth test, the
depth clear in 16-pixel runs, and the x86 pixel JIT, whose IDs carry the
translation so the layout's constants are compiled in. It changes with
the color format and sceGeEdramSetAddrTranslation, after a flush.
Reading VRAM through its 0x04200000 and 0x04600000 mirrors undoes the
layout, as the GE does: texturing from them (drawn from a linear copy
made after a flush), and block transfers from or to them (Hayate no
Gotoku restores its depth buffer through 0x04600000, #17878). Saved and
debugger depth buffers read through the layout, so they're linear.
Socom's lens flare dump now matches a PSP replay where it changes. About
2-3% more cycles in God of War, Tekken 6, Wipeout and Burnout.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The stencil test compares ref against the buffer's value, the other way
around from the alpha test, but shared its shortcuts: GREATER with ref 0 and
LESS with ref 0xFF became NOTEQUAL instead of NEVER, so those draws wrote
pixels the PSP rejects. Its own shortcuts are mirrored (gpu/probe exp120:
every function and op in 8888, 5551 and 4444, exact).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
With the separate-CLUT bit, mip level n puts n above the index bits, wrapped
to the CLUT: CLUT4 adds n * 16 as before, CLUT8 with a 16-bit palette adds
(n & 1) * 256, and a 32-bit palette's 256 entries wrap it back to 0
(gpu/probe exp90). Also in the x86 sampler JIT.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
If we don't need to write stencil on sfail/zfail, we can do the depthtest
early, which allows us to more often skip texture sampling.
This gives a good improvement in Chains of Olympus.
This is slightly abusing PixelFuncID, but the intent is to provide some
memory that's easily accessible from the jit func, but still associated
with that calculation (i.e. not global.)