Commit Graph
357 Commits
Author SHA1 Message Date
Henrik RydgårdandClaude Opus 5.5 d272703721 SoftGPU: Keep the vertex position, normal and light vectors as Vec4F32
The position is read once as (x, y, z, 1) for the clip, fog, texgen and
light vector rows, and lighting works on Vec4F32 throughout, without
going through arrays. Each light's constant term, its position minus
the world translation, is computed once per state instead of per
vertex. The texture matrix rows are now prepared with the transform
state, so loading that matrix dirties it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-09 09:07:12 +02:00
Henrik RydgårdandClaude Opus 5.5 ae32477764 Core: Let 16-bit CPU accesses through the depth mirrors see the GE's layout
With the software renderer, which now stores depth as the GE does, a
16-bit read or write at VRAM's 0x04200000 or 0x04600000 mirror goes to
where the GE's 16-bit or 32-bit color layout puts that depth pixel
(ppsspp-re geprobe exp88: the mirrors are the layout's exact inverse).
Games access depth there with nothing else, so other widths stay plain.

The accessors check the address, then whether the GPU core is the
software renderer (CoreParameter); the hardware renderers keep depth plain
and handle the layout their own way. The renderer keeps the layouts up to
date with the EDRAM address translation. With it, the JITs send 16-bit
loads and stores to the interpreter, and the IR passes don't change a
load's width to or from 16 bits.
The pspautotests that read depth through the mirrors now do so 16 bits
at a time, re-recorded on hardware unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 18:37:23 +02:00
Henrik RydgårdandClaude Opus 5.5 a11fd22553 SoftGPU: Store depth in VRAM as the GE does
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>
2026-10-08 18:35:48 +02:00
Henrik RydgårdandClaude Opus 5.5 3c3025a087 SoftGPU: Keep drawing queued when a display list stalls
Returning to the CPU flushed all queued drawing, also when a list only reached its stall address.
Wipeout Pure builds its lists as it goes and stalls about a hundred times a frame, so the main thread
spent a third of its time finishing the drawing at those flushes. A stalled list isn't done, so now
only a finished one flushes there, which makes Wipeout Pure 15% faster.

What relied on that flush now flushes itself: memory copies, sets, readbacks and uploads that overlap
the queued drawing, and save states, before memory is saved or loaded (FlushPendingDrawing). Syncs and
the display already did. Queued drawing still reads textures from PSP memory when it runs, so a game
that rewrites a texture between stalls without syncing would see the new one; on hardware the GE has
usually drawn with the old one by then.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-05 14:55:04 -06:00
Henrik RydgårdandClaude Opus 5.5 fb79979e01 SoftGPU: Small self-textures stay cached until TEXFLUSH
A texture that fits in the GE's 8 KB texture cache keeps what was first
read until TEXFLUSH, across primitives and draws, so a later self-textured
draw doesn't see an earlier one's writes (gpu/probe exp174: three passes
over a 16x16 4444 buffer differ in 177 pixels with and without a flush
between them, both now exact). FF Type-0's (NPJH50443) blur; two of its
PSP replays become exact.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 15:09:43 -06:00
Henrik RydgårdandClaude Opus 5.5 cadf5d8b2d SoftGPU: Evaluate spline patches as the GE does
De Boor at t = k/256 with the Bezier path's lerps. Each blending factor
(t - knot) / span is quantized in 1/256 from the nearer of its two knots,
and a segment's last point is evaluated as the next one's first. Colors,
texture coordinates, generated UVs and normals work as for Bezier
patches. Bit exact on gpu/probe exp144-146; software renderer only.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 15:09:43 -06:00
Henrik RydgårdandClaude Opus 5.5 04c03ad922 SoftGPU: Evaluate Bezier patches as the GE does
Columns before rows, de Casteljau at t = k/256 (rounded toward the patch
middle). Positions and UVs lerp in 16-bit fixed point at the larger
operand's exponent; colors in 15-bit fixed point. Generated UVs are k/256.
Bit exact on gpu/probe exp48-51 and exp139-140. Software renderer only,
since it's about 15x slower than the float weights.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 15:09:43 -06:00
Henrik RydgårdandClaude Opus 5.5 2d3c8fa0cb SoftGPU: Apply UV scale and offset like the GE
In UV gen mode 0 the software renderer now decodes UVs without the prescale
and applies u * scale + offset itself: the product as a float24, then the
GE's guard-bit-less add. Bit exact on gpu/probe exp66 for float, 16-bit and
8-bit UVs (which are unsigned).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 15:09:42 -06:00
Henrik RydgårdandClaude Opus 5.5 192dc5b345 SoftGPU: Fix black screenshots with the DarkStalkers present hack
The hack skips the game's stretch blit, so the display framebuffer stays
black and savestate thumbnails and screenshots came out empty. Do the
stretch from the source image when reading back the display framebuffer.

AGENTS.md: Commit finished work without asking, push only when asked

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-01 12:57:36 -06:00
Henrik RydgårdandClaude Opus 5.5 a6849661ba Shade mapping: Use the light vector as lighting sees it
Environment map S and T are (N.L + 1) / 2 with L the light's vector as
lighting uses it: from the vertex to the light for point and spot lights,
a zero vector staying zero, and the half vector for a light that does
specular. Whether lighting or the light is enabled still doesn't matter
(gpu/lighting/shademap).

The vertex shader ID now carries the type and computation of the shade
mapping lights (the ubershader reads them from u_lightControl), so both
shader caches get a new version.

Fixes the hair shine in iDOLM@STER SP (#12376).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 15:47:16 -06:00
Henrik RydgårdandClaude Opus 5.5 d6f8615d2a SoftGPU: Fix block transfer and self-render overlap tracking
- The block transfer overlap check passed the stride in pixels where bytes
  are expected, so it only covered part of the rectangle.
- A selfrender/selfdepth flush in UpdateState dropped the current draw's
  pending writes and reads, so later transfers didn't wait for it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 10:33:32 -06:00
Henrik RydgårdandClaude Opus 5.5 8f66065f53 GPU: Add a clear cost, disabled for now
Full-screen clears measured on a PSP (pspautotests gpu/timing/blittiming):
0.49ms on a 16-bit framebuffer whatever is cleared, 0.69ms on 8888, 1.02ms on
8888 with depth. Charging them may help games that spin hard on an empty
screen, but it's off (chargeClearTime) until tried on some. The video blit
cost moves into the same function, now EstimateFillCycles.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 17:18:42 -06:00
Henrik RydgårdandClaude Opus 5.5 242ef0a984 GPU: Track video frames in GPUCommon, so they expire for the blit cost too
The blit cost remembered only the last buffer a decoder wrote into, forever.
Move the texture cache's video list (with its ageing out a few flips after
the last write) into GPUCommon, so the texture cache, the blit cost and
SoftGPU all share one. That also counts both of a double-buffered player's
frames, which exposed that a clear drawn with texturing still enabled was
being charged as a blit - skip clears and draws without texture coordinates.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 17:00:11 -06:00
Henrik RydgårdandClaude Opus 5.5 a0b812bc31 Charge hardware-measured time for movie decode, colour conversion and blit
Movie players like the one in Star Wars: Lethal Alliance present every decoded
frame after a single vblank wait, with no clock or timestamp check, so the
frame rate depends on decode, CSC, ATRAC decode and the GE blit adding up to
more than a vblank. We charged nearly nothing for any of them, so such movies
ran at 60 fps until the ringbuffer's slack ran out.

Costs measured on a PSP with a copy of that player (pspautotests
video/mpeg/playertiming), for a 480x272 frame:

- sceVideocodecDecode: 3.4ms (sceMpegAvcDecode 5.8ms less sceMpegAvcCsc 2.4ms)
- sceMpegBaseCscAvc: 2.4ms, was a flat 4ms
- sceAudiocodecDecode, ATRAC3+ only: 2.5ms per frame
- GE: 9.7ms for a through-mode rectangle blit from a decoded video frame,
  charged by area, only for textures in the buffer a decoder last wrote.

GE time also now carries across stall address updates. Before, a list sent
in stalled chunks only had its last chunk's time counted, so sceGeDrawSync
returned 39us after a blit that takes 9.7ms. This affects every game that
builds its lists incrementally, so GE-timing-sensitive games need checking.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 15:23:08 -06:00
Henrik Rydgård c5e4d0d90d Rename the get-memory-pointer functions to make it clear where CPU exceptions can happen. 2026-08-12 14:06:16 +02:00
Henrik Rydgård 3eb056ad86 Move Common/GraphicsContext.h to Common/GPU/GraphicsContext.h 2026-07-26 13:58:17 +02:00
Henrik Rydgård 18a9de3eca Move AdvanceVerts to GPUStateCache 2026-07-14 15:28:21 +02:00
Henrik Rydgård 6d2948a09b Remove the cached UVScale in gstate_c. Conversion is cheap enough to do directly from gstate, no point in caching. 2026-07-03 13:17:35 +02:00
Henrik Rydgård 48084e9c3e Cleanup, fix some oversights 2026-06-03 15:23:17 +02:00
Henrik Rydgård 0dc6e36d19 Delete redundant implementation of vertex preview in SoftGpu 2026-06-02 15:43:11 +02:00
Henrik Rydgård bb573e6e0c Well, it builds, but doesn't work yet. 2026-06-02 12:33:53 +02:00
Henrik Rydgård f0d715feaa During culling, evaluate minZ,maxZ,minW,maxW, and use them to cull some things. Also, assorted vshader work. 2026-05-30 19:07:58 +02:00
Henrik Rydgård ae98055cec Delete a lot of legacy depth and viewport code, fix OpenGL 2026-05-30 19:07:58 +02:00
Henrik Rydgård f60e27a9b7 Just some refactoring of the GPUStatistics struct, and more use of StringWriter 2026-05-29 14:40:31 +02:00
Henrik Rydgård 5513fcb223 Merge pull request #21705 from GermanAizek/constexpr-cpp17
GPU: modernize use C++17 constexpr for precalculate compilation
2026-05-27 12:21:39 +02:00
Henrik Rydgård 06a7793f57 Fix some y-flip issues in D3D11. It got broken by recent refactorings.
Fixes #21726
2026-05-26 15:51:24 +02:00
Henrik Rydgård 0d33cd0a65 Convert the BBOX/BJUMP culling to use the worldviewproj matrix and a screen space check. 2026-05-23 14:40:15 +02:00
Henrik Rydgård 5cfbf50111 Keep updated products of view*proj and world*view*proj matrices. Use to simplify bbox culling. 2026-05-21 19:18:32 +02:00
Herman Semenoff 400d136f51 GPU: modernize use C++17 constexpr for precalculate compilation 2026-05-19 21:57:45 +03:00
Henrik Rydgård e71ffc59a6 Remove unnecessary IsStarted method 2026-02-17 10:18:08 +01:00
Henrik Rydgård eb234a1563 Finish the split. Greatly simplifies the render code in EmuScreen. 2026-02-08 10:46:16 +01:00
Henrik Rydgård 814713e932 More refactor 2026-02-08 01:06:35 +01:00
Henrik Rydgård c139d4aaff Split up Presentation::CopyToOutput into passes and output. 2026-02-08 01:06:35 +01:00
Henrik Rydgård f01aaeafb1 Split CopyDisplayToOutput in preparation for the next step 2026-02-08 01:06:32 +01:00
Henrik Rydgård 5f7a937466 Rename ValidSize to ClampValidSizeAt 2025-12-30 20:31:07 +01:00
Henrik Rydgård 7853881210 GPU header cleanup: Avoid including GPUCommon.h in some places 2025-11-23 20:37:37 +01:00
Henrik Rydgård 67010ff2af Split the display layout config between landscape and portrait orientations 2025-11-05 12:49:51 +01:00
Henrik Rydgård a7a33dc414 Fix potential sign issue in Accessible() (though I don't quite get how it's failing). 2025-06-24 17:16:59 +02:00
Henrik Rydgård 14b593cdfc Try to get more info out of the crash. 2025-06-24 16:08:37 +02:00
Henrik Rydgård 6cfea96e58 Remove D3D9 support, to make future changes easier 2025-06-10 15:07:16 +02:00
Henrik Rydgård 44d06ec42f Add some sanity checks guided by Android crash reports 2025-06-07 16:35:19 +02:00
Henrik Rydgård b421c0791f Perform screenshot processing (including image encode) on background tasks 2025-03-20 20:48:51 +01:00
Henrik Rydgård ae8f8c4abd Refactor TakeGameScreenshot a bit. 2025-03-20 17:41:44 +01:00
Henrik Rydgård 1ca63161b3 More minor fixes 2025-02-04 10:19:34 -06:00
Henrik Rydgård 3e198c53b2 More include cleanup 2024-12-18 13:57:26 +01:00
Henrik Rydgård ee297e974d Move more code into SoftwareTransformCommon, cleanup 2024-12-18 13:57:26 +01:00
Henrik Rydgård 54d18bb343 Lift some more debugging functionality into GPUCommon 2024-12-15 14:03:05 +01:00
Henrik Rydgård 190af89d9f Plumb in a GPUCommon pointer in the draw engines. (Hopefully can get rid of this later) 2024-12-15 13:53:27 +01:00
Henrik Rydgård 638607d29a Refactor: Make GPUCommon own the framedump "recorder". 2024-12-15 12:07:44 +01:00
Henrik Rydgård b10c4f7fae Crashfix, warning fix, cleanup 2024-10-22 14:15:47 +02:00