Commit Graph
50350 Commits
Author SHA1 Message Date
Henrik Rydgård f82a875d17 Merge pull request #22945 from hrydgard/net-hardening
Web server, HTTP client, inet: Check Origin and bound what the network can make us do
2026-11-05 19:41:22 +01:00
Henrik RydgårdandClaude Opus 5.5 59b42924b5 Inet, resolver: Check restored waits, bound lookups
- A wait restored from a savestate is retried with arguments nobody
  checked: validate them like the entry points do before each retry.
- Fail recvmsg with EMSGSIZE beyond 1024 iovecs (UIO_MAXIOV).
- Windows: a failed socket() is INVALID_SOCKET, which isn't < 0.
- infra-dns.json: skip non-string domain entries, which crashed.
- Resolver: read the host name only up to the end of memory, and try at
  most twice, since each attempt blocks the emulator.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 18:49:10 +01:00
Henrik RydgårdandClaude Opus 5.5 63a9a53bf9 HTTP client: Cap response size and redirects
A server could make us buffer a response until we ran out of memory,
inflate a small gzip body to 256 MB, or redirect forever.

- Responses are capped at 64 MB in memory and 1 GB for downloads to a
  file (which are buffered in memory too), over both the plain and the
  HTTPS client. A larger Content-Length fails up front.
- Gzip output gets the same cap.
- Remote ISO range reads accept no more than the range asked for.
- Stop after 10 redirects.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 18:49:10 +01:00
Henrik RydgårdandClaude Opus 5.5 bea3fcdeab Web server, debugger: Check Origin, bound connections, headers and buffers
Browsers let any page open a WebSocket to localhost, and the debugger can
write memory and save states to any path. Accept only pages from this
machine, from this server, or the official web debugger; clients that
send no Origin are unaffected.

- Cap request headers at 100 lines, 64 KB and 10 seconds, and stop
  leaking repeated User-Agent and Referer values. Header names are now
  matched exactly, not by prefix.
- Run at most 64 connections at once, and drop accepted sockets that
  select() can't take (fd >= FD_SETSIZE).
- Grow a WebSocket message as its data arrives, instead of to the
  length the frame claims.
- Drop a WebSocket client that stops reading, once 128 MB is queued,
  and stop waiting for a close frame that can't go out after 2 seconds.
- Uploads wait for data instead of spinning, and range downloads stop
  when the client stops reading.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 18:49:10 +01:00
Henrik Rydgård 5b3ddcc062 Merge pull request #22942 from hrydgard/update-libchdr
Update libchdr to the latest master
2026-11-05 17:19:57 +01:00
Henrik Rydgård 4866f356b5 Merge pull request #22943 from hrydgard/psx-graphics
POPS: Upload images the emulator writes to VRAM with the CPU
2026-11-05 17:19:15 +01:00
Henrik Rydgård c338f76ec9 Merge pull request #22939 from hrydgard/parser-hardening
Harden file format parsers against malformed input
2026-11-05 16:29:51 +01:00
Henrik RydgårdandClaude Opus 5.5 0097c2a3d8 Build all of lzma-sdk in Common on Windows, UWP and Android
libchdr's bundled LZMA now builds only LzmaDec, with its symbols renamed
to CHDR_*, so the 7z reader no longer gets Bra, Bra86, Delta and LzmaDec
from it. Build the same lzma-sdk sources ext/lzma-sdk/CMakeLists.txt does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 16:28:45 +01:00
Henrik Rydgård 697396c08b Merge pull request #22938 from hrydgard/libretro-inflight-3
libretro: Offer "Up to 2" buffered frames of graphics commands again
2026-11-05 16:08:32 +01:00
Henrik RydgårdandClaude Opus 5.5 ac4fb587fe POPS: Find the GP0 image load's row ends in every emulator version
The registers and the gp offset of the loop's state differ between
firmware versions and models (pops.prx and pops_0Xg.prx from 3.80 to
6.61), so it's matched by the shape of its four instructions, and the
offset is taken from them and kept in savestates. The exact words only
matched 6.60 and 6.61's 01g to 04g.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 16:08:25 +01:00
Henrik RydgårdandClaude Opus 5.5 05de369578 POPS: Upload images the emulator writes to VRAM with the CPU
The PS1 emulator writes an image that comes through the GP0 data port
(rather than by DMA) into VRAM one pixel at a time with the CPU. The
hardware renderers never saw those pixels, so a later copy out of the PS1
VRAM framebuffer read stale texels.

The two row ends of that loop now go to an HLE call, which uploads the
finished rectangle with a new PerformWriteRectFromMemory().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 16:08:25 +01:00
Henrik Rydgård 5b5465c78b Merge pull request #22941 from hrydgard/more-ui-work
More UI work
2026-11-05 16:08:06 +01:00
Henrik RydgårdandClaude Opus 5.5 5fcb29d37e Savestates: Allocate the load buffer with malloc rather than new (std::nothrow)
new (std::nothrow) doesn't work with DbgNew.h's new macro in Windows debug
builds. The buffer is only ever freed in two places, so switch them to free().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 14:08:56 +01:00
Henrik Rydgård f2b7732780 Another hint, misc 2026-11-05 13:55:18 +01:00
Henrik Rydgård bfb3f0f23f Turn off the quick scroll bar from #22796 by default on desktop 2026-11-05 13:39:40 +01:00
Henrik Rydgård 307e43b8de Firmware and savedata screen tweaks 2026-11-05 13:34:48 +01:00
Henrik RydgårdandClaude Opus 5.5 4811df6dcb Update libchdr to the latest master
Picks up upstream's hardening against crafted CHD maps and codec payloads
(rtissera/libchdr#198), hunk CRC verification for v3/v4 maps, and RLE/sparse
map fixes.

Upstream split libchdr_chd.c into a file per codec, and its bundled LZMA is now
just a symbol-namespaced LzmaDec.c, so the source lists change in every build.
The zlib codec now defaults to a bundled miniz, so define CHDR_SYSTEM_ZLIB and
CHDR_SYSTEM_ZSTD to keep using our zlib and zstd.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 13:33:12 +01:00
Henrik RydgårdandClaude Opus 5.5 ebafb89215 UI, texture packs, headless: Validate values from files
- textures.ini skipLastDXT1Blocks* is subtracted from the hashed size after
  the memory check, so a large value (or a small one with reduceHash)
  underflowed it and hashed ~4 GB. Clamp it to the blocks there are.
- SND0.AT3 loops with a negative or backwards range pointed playback before
  the data. Ignore those, and loops outside the data.
- impose.rsc sprite bounds were checked as x + w in 32 bits, which wraps.
- Store entries are also uninstalled by name, so require a plain filename
  (. or / was the whole GAME directory).
- Headless screenshot compare read (and converted in place) w x h pixels of a
  reference PNG that could be smaller.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 13:21:52 +01:00
Henrik RydgårdandClaude Opus 5.5 bc99dbeae9 libretro: Offer "Up to 2" buffered frames of graphics commands again
6bb91bf2f0 removed the option along with lowering the default. The default stays at "Up to 1"; this only
brings back the choice, which the standalone app still has.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:30:59 +01:00
Henrik RydgårdandClaude Opus 5.5 128cf1b7c4 PGD: Don't trust the header's data size, or a guest MAC key's pad size
- npdrmRead clamped the read with a signed compare against data_size, so a
  forged header with data_size >= 2^31 turned it into a ~2 GB copy past the
  guest's buffer. Clamp to what's left of the file, unsigned.
- sceDrmBBMacUpdate/Final take a MAC key in guest memory, and only checked
  pad_size > 16, so a negative one wrote at an arbitrary offset.
- Repeating the PGD ioctl leaked the previous descriptor, and pgd_open
  didn't check its allocation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:26:53 +01:00
Henrik RydgårdandClaude Opus 5.5 04bdf46bc6 Line info: Bound the DWARF line program parse
- An extended opcode's length was added to the position unchecked, so a huge
  one wrapped back to the opcode itself and looped forever (and, with a row
  in the loop, grew the table until memory ran out). Lengths must now fit in
  the unit. This runs on every loaded module and on a .elf next to the EBOOT.
- Cap the rows at a couple per instruction and the distinct files at 65536,
  since one-byte opcodes and short names could otherwise make gigabytes of
  tables from a large file.
- ELF and unit bounds checks in 64 bits (they wrapped on 32-bit hosts), the
  section headers copied out rather than read unaligned, a bounded compare
  for the section name, and line and SLEB arithmetic that can't overflow.
- Rows at the same address now keep the last, as the comment says.
  std::unique kept the first, so an end-of-sequence row could hide the next
  sequence's first row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:26:53 +01:00
Henrik RydgårdandClaude Opus 5.5 d5bded2dbd Translations: Add the why-disabled setting messages
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:25:02 +01:00
Henrik RydgårdandClaude Opus 5.5 366a0744e6 Savestates, cheats, symbols, misc: Bound parsing of untrusted data
- Savestates: containers of non-raw elements (strings, classes) now grow as
  their data is read, since a count bounded only by the bytes left could still
  ask for gigabytes. Cap the decompressed size at 256 MB and fail cleanly if a
  buffer can't be allocated, instead of terminating.
- Symbol maps: a line starting with a NUL underflowed the newline trimming,
  which then walked back through the stack writing NULs. These load
  automatically from next to the ISO.
- Cheats: stop if an IfAddr skip wraps the line index (32-bit hosts), which
  ran the same code forever.
- Atrac: reject negative chunk sizes in ParseWaveAT3 (an infinite loop), and
  check the AA3 header and fact chunk are long enough for what's read.
- SND0 loop count check divided rather than multiplied (wrapped on 32-bit).
- Replays: don't index an empty data vector, or report more bytes than were
  copied.
- UTF-8: u8_nextchar read past the end when called there, and the emoji check
  re-measured its string_view with strlen. StringWriter::F moved backwards on
  vsnprintf errors. JSON getInt clamps instead of an undefined cast.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:23:17 +01:00
Henrik Rydgård fd81cf7e6b Merge pull request #22937 from hrydgard/skinned-minmax
GPU: Skip the min/max depth discard on skinned draws that stay inside the range
2026-11-05 12:22:55 +01:00
Henrik Rydgård 546e00c697 Merge pull request #22934 from hrydgard/vr-vulkan
VR: OpenXR on Vulkan, with single-pass stereo (Quest)
2026-11-05 12:22:43 +01:00
Henrik RydgårdandClaude Opus 5.5 c5673294ab Firmware, PS1, PKG: Fix wrapping offsets
- PSAR: an entry's chunk size could wrap the u32 position back to an earlier
  entry, looping forever (this runs on a disc's DATA.BIN at boot). Entries
  must now end inside the archive.
- MDS: the session offset check wrapped in u32, and the track name block
  wasn't checked at all, both reading gigabytes past the file.
- PKG: check the data range without the u64 sum that could wrap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:17:59 +01:00
Henrik RydgårdandClaude Opus 5.5 50e9b6691c Archives, caches, HTTP: Bound sizes from headers and servers
- Zip VFS: cap entries at 512 MB (the old 4 GB cap let a 2^32 size wrap the
  allocation to nothing on 32-bit hosts), fail reads that come up short
  instead of returning uninitialized memory, and return 0 rather than
  (size_t)-1 from Read on a corrupt stream, which crashed texture loading.
- Zipped disc images are capped at 4 GB and must fit a size_t before we
  allocate them.
- Installing a zipped ISO took the name after the last '/' only, so a name
  using backslashes could write outside the games folder on Windows. Require
  a safe filename, and report failures instead of always succeeding (which
  could delete the source zip after a failed extract).
- Disk cache files: reject block sizes we don't create (0 divided by zero),
  drop index entries that share a block (eviction then never finished), and
  stop evicting when no progress is possible. Negative or empty reads no
  longer index the cache out of bounds.
- HTTP: reject implausible Content-Length values, and don't cache files in RAM
  that can't fit (the size wrapped on 32-bit hosts, overflowing the buffer).
- Gzip-encoded HTTP responses are capped at 256 MB decompressed.
- Directory VFS: don't open directories as files, check Ftell, and bound the
  case-insensitive index recursion.
- Skip zip entries without a name when identifying zips.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:16:53 +01:00
Henrik RydgårdandClaude Opus 5.5 382a8eecea Images: Limit sizes, and handle ZIM and JPEG load failures
- JPEGs over 8192 pixels in either dimension are rejected (in jpgd, so it
  covers sceJpeg too), and its allocation size is computed in size_t, since
  the int product overflowed and gave a heap overflow. Image loading also
  checks the caller's maximum before decoding.
- Image loading premultiplied a ZIM that failed to load (null pointer), and
  treated 16-bit ZIMs as 32-bit (twice the buffer). Reject those, and ZIMs
  over 8192, and a zlib stream that ends early.
- PNG: pngLoadPtr's error path could free a caller's uninitialized pointer,
  and pngLoad didn't check its allocation or decode.
- Texture replacements: reject header sizes of 0 or over 8192 for every
  format (DDS sizes overflowed an int), transcode KTX2 mips with their own
  height, and don't copy more ZIM rows than were decoded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:11:00 +01:00
Henrik RydgårdandClaude Opus 5.5 56cf35ac95 ELF, modules: Bound header fields before using them
- ElfReader: do the relocation segment and table bounds checks in 64 bits
  (p_offset + p_filesz wrapped, and relocations were read gigabytes past the
  file), range-check R_MIPS_32's four bytes, require section names to end
  inside the file, and check the Rel2 field widths fit the 16-bit commands.
- Pair HI16 relocations with their LO16 in linear time, and cap the total
  relocation data processed at the file size. Several sections can point at
  the same table, and a table of only HI16s was quadratic.
- PRX: reject decrypted sizes larger than the input, and check the KIRK input
  (which starts past the header) fits rather than only the output.
- Module loading: cap elf_size before allocating, zero the buffer, give gzip
  the real input length, range-check the module info, export entries and
  their NID tables and thread parameters instead of their first byte, and
  don't trust header names to be terminated.
- PBP modules need the offsets that are read, sceKernelLoadModuleByID copes
  with a seek past the end, and sceKernelLoadModuleBufferUsbWlan checks the
  buffer.
- ParamSFO: table offset math in 64 bits (wrapped on 32-bit hosts).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:07:13 +01:00
Henrik RydgårdandClaude Opus 5.5 3413784d8e Block devices, ISO: Validate disc image headers and tables
- CSO: ReadBlocks with count 0 no longer runs off the index (the path table
  ioctl did this for any table under a sector), plain frames are only copied
  from what's actually in the read buffer, and images over 8 GB are rejected,
  here and in the compressor (whose index is sized from it).
- UDF: do the allocation descriptor bounds check in 64 bits, cap and
  range-check the root directory before allocating it, and require a full
  file identifier descriptor.
- CHD: reject unit sizes the block math can't handle (divide by zero, reads
  outside the hunk), report short reads to libchdr, and don't hand out a
  failed hunk.
- NPDRM: only treat the block buffer as cached once it was filled.
- LZRC: stop match copies at the end of the output, reject distance 0.
- ISO: cap directory sizes at 4 MB, check that a record's header fits in
  the sector, and mark a directory read on errors so its children aren't
  appended again on every lookup.
- Cap the PARAM.SFO reads at 1 MB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 11:59:21 +01:00
Henrik RydgårdandClaude Opus 5.5 1cb9b1d3ef UI: Allow a custom why-disabled message on views and setting items
View::SetDisabledReason, and SettingItem::DisabledReason for settings
pages. When set, it's shown instead of the message worked out from the
enabled pointer, and it also works for items with enabled callbacks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 11:58:36 +01:00
Henrik RydgårdandClaude Opus 5.5 6f709515e3 UI: Say which setting is in the way when activating a disabled item
Tapping a disabled item, or pressing accept on a focused one, shows an
info message naming the setting that has to be on or off, when the item
is disabled by one (SetEnabledPtr/SetDisabledPtr on a config setting).
Items disabled through a callback show nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 11:53:32 +01:00
Henrik RydgårdandClaude Opus 5.5 d5e0bf2ef5 UI: Let disabled items take keyboard focus
They still ignore keys and touches. A focused disabled item keeps its
disabled background and gets a thin outline in the focus color instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 11:48:27 +01:00
Henrik RydgårdandClaude Opus 5.5 e0efa821c7 UI: Tighten the space between a setting's title and its hint
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 11:39:35 +01:00
Henrik RydgårdandClaude Opus 5.5 13d14e9ad2 GPU: Give skinned draws the min/max depth discard only when they reach past the range
Without clip distances, the depth range's min/max is a discard in the fragment shader. Skinned and morphed draws
skip the bounding box test, so they got it whenever a game narrowed the range, though skinned ones are rarely
past it, and the discard costs fill rate. Nearly every draw in Tekken 6 is skinned, and without the discard on
them it ran 25% faster at 4x on a Mali-G57 (OpenGL), and 15% faster on a PowerVR GE8320 (OpenGL).

A skinned draw now gets MinMaxZCheck instead. At flush, its vertices are decoded into RAM, where they go anyway,
and it gets the discard only if their screen Z reaches past the range. Morphed draws are rare and keep it.

On a GPU without clip distances, the whole framedump set renders the same as before. Only 0.6% of the skinned
vertices still get the discard, in ten dumps (Pursuit Force's split depth range among them).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 11:35:42 +01:00
Henrik RydgårdandClaude Opus 5.5 eeb25d0f57 GPU: Remove leftovers of hardware skinning
The vertex decoder always skins now (except for the software renderer's own), so NormalizeVertices never sees
weights to apply, and the GLES shaders have no bone uniforms to look up.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 10:36:41 +01:00
Henrik RydgårdandClaude Opus 5.5 ef3c7985ee UI: Draw setting hints inside their Choice or CheckBox
ClickableItem gets a hint text, drawn small under the item's own content,
so it highlights and clicks along with it instead of being a separate
SettingHint view below. Settings pages attach it with .Hint() on the item
it belongs to, and search matches it as part of that item.

SettingHint stays for the few hints that have no item to go in: custom
settings views that aren't ClickableItems, and cheat comments under a title.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 10:35:23 +01:00
Henrik Rydgård 9f5c502d8f Merge pull request #22936 from hrydgard/cpu-clip
GPU: Clip and cull on the CPU while keeping hardware transform, with CPU-lit clipped triangles
2026-11-05 10:04:43 +01:00
Henrik RydgårdandClaude Opus 5.5 05b5ef163f GPU: Light the triangles the CPU clips, in a second vertex stream
The GE clips lit triangles after lighting, interpolating the lit colors. So that lit draws can take the CPU clip
path too, the CPU now lights the ends of the edges it clips, once per vertex, and the vertices clipping makes take
the interpolated colors. They come in a second vertex stream, 8 bytes a vertex (cpulit0 for color0, cpulit1 for
color1, its alpha set where they are to be used), and the vertex shader uses them in place of its own lighting
there (VS_BIT_CPU_LIT). The original vertices keep the shader's lighting.

Every lit draw gets the stream where the CPU lights the triangles it clips (no clip distances, or a game flagged
CorrectCullAfterClip), with a static buffer of zeroes when nothing is clipped, so whether a draw is clipped
doesn't change its pipeline. The colors take attribute locations 3 and 4, those of the skinning weights, which
are never vertex attributes, to stay within GLES2's eight.

Implemented for Vulkan, OpenGL, D3D11 and Metal. Shader cache versions are bumped (new shader ID bit and vertex
format bit).

Regression risk: a new vertex shader input and second vertex buffer on GPUs without clip distances, every lit
draw on those. Tested on Mali (G52, G71, G78) and PowerVR (BXM, GE8320) phones.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 00:53:12 +01:00
Henrik RydgårdandClaude Opus 5.5 e1ba8145db GPU: Clip and cull draws crossing the Z planes on the CPU, keeping hardware transform
Where the GPU can't clip and cull like the GE (no clip or cull distances, the near plane not on the minimum Z,
or a game flagged CorrectCullAfterClip), a draw whose bounding box crosses a Z plane used to go to software
transform. Mixing that with hardware transform on other passes over the same surface made their depth tests
fail on PowerVR.

Now the CPU decodes such a draw to RAM, clips its triangles at the near plane like the GE (into one triangle or
two), drops those entirely beyond the far plane, and range culls the vertices clipping makes. The vertices,
including the new ones interpolated from the decoded ones, then go through hardware transform like the rest.

Lit draws, flat shading and normal-based texgen aren't linear in the decoded vertices, so they're left to the
clip distance where there is one, and culled only when culled whole. Without clip distances, lit draws still
take software transform.

Regression risk: draws that cross a Z plane on GPUs without clip or cull distances, and the flagged games, now
take a new path, on every backend.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 00:42:26 +01:00
Henrik RydgårdandClaude Opus 5.5 39b7e8dc2f Vulkan, OpenGL, Metal: Let draws bind a second vertex stream
Vulkan pipelines can have a second vertex binding, and draws a second vertex buffer for it. OpenGL input
layout entries can come from a second buffer, with its own stride, given with the draw. Metal gets a second
vertex buffer index. Nothing uses them yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 00:29:16 +01:00
Henrik Rydgård 0051dca319 Merge pull request #22935 from hrydgard/gpu-misc-fixes
GPU: Fix black frame dump replays, the depth clamp range, and DBZ's culling
2026-11-05 00:20:40 +01:00
Henrik RydgårdandClaude Opus 5.5 1676765456 GE dump: Only draw the zero-normal reset patch on the software renderer
Only the software renderer keeps the sign it resets, and on the hardware renderers the patch made about 70 of
the frame dumps replay black (MX vs. ATV Untamed among them).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 23:52:20 +01:00
Henrik RydgårdandClaude Opus 5.5 48aa69c748 Compat: Clip and cull DBZ Tenkaichi Tag Team after clipping
With clip and cull distances, the GPU drops ground textures on modded maps (#18561): 25551 pixels off the PSP
render on a Pixel 3a, against 1987 with the flag.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 23:06:22 +01:00
Henrik RydgårdandClaude Opus 5.5 cabbea312b GPU: Count only what's drawn in the Z range for the depth clamp
With depth clipping, what's behind the near plane is clipped away, but its screen Z still counted, and behind
the eye it's meaningless. Every draw crossing the near plane then took the fragment shader depth clamp on GPUs
without depth clamp, whose depth doesn't match the other draws' rasterized depth, so equal-depth passes failed
(Monster Hunter 3rd HD's ground on PowerVR GLES). The near plane's Z counts instead, and doesn't need the clamp
at exactly zero, where losing what rounds below is the near clip.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 23:06:12 +01:00
Henrik RydgårdandClaude Opus 5.5 b62bcc9e12 Vulkan: Allow it on Motorola's PowerVR BXM-8-256 phones with any driver
The entry hid the Vulkan option on those (Moto G54 and similar) with drivers before 0x005d9576, for the crash
in #18681. Vulkan is the default there, and works on a G54 with that driver. The list is only used on Mac
now, so it and its check are only built there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 23:05:36 +01:00
Henrik RydgårdandClaude Opus 5.5 5a5c11f984 Headless: Print the number of pipelines created
Vulkan and Metal pipelines, and OpenGL programs, including those precompiled from the shader cache. Benchmark
times include the compiles, so this shows when two builds differ in how many they need.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 23:05:36 +01:00
Henrik RydgårdandClaude Opus 5.5 77e417e59f CrossSIMD: Make the Store functions const
They only write to the destination.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 23:05:36 +01:00
Henrik Rydgård c68f43c731 Merge pull request #22911 from hrydgard/texcache-index
TextureCache: Find the textures a block transfer overlaps through a flat index
2026-11-04 19:28:05 +01:00
Henrik Rydgård 9366aa7dc2 Merge pull request #22933 from hrydgard/more-ui-work
Fix a bunch of UI bugs
2026-11-04 19:12:03 +01:00