The copies went through the thread pool, where they could wait behind other tasks like pipeline
compiles, and one core already saturates memory bandwidth.
A filename with a parent dir component left the texture in CANCEL_INIT, which the texture cache
keeps polling forever. Treat it like a missing file instead. Also remove an unused lastUsed field.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
An [indexed] entry set to gpu uploads the indices as an R8 image, and
the CLUT8_INDEXED depal shader applies the palette. A texture whose
palette changes a lot then costs no CPU time per palette, and keeps one
texture instead of one per palette.
Once such a replacement is found, the texture is looked up without the
CLUT hash, like with the TextureCLUTInShader compat flag. Only the first
mip level is used, and the replacer's filtering overrides are skipped
since filtering indices mixes up palette entries. Without shader bitwise
ops it falls back to coloring on the CPU.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- Fixes#15145
A replacement listed in a new [indexed] section of textures.ini holds
palette indices instead of colors: a palette PNG (the file's palette index)
or an 8-bit grayscale PNG (the gray value), at any resolution. When the
texture is built, the indices go through the game's current CLUT, including
the CLUT index shift, mask and start position, and the result is uploaded as
an ordinary RGBA texture. A game that swaps or customizes a palette keeps
working with a high-resolution replacement.
[indexed] keys use the [hashes] format and are matched with the same
wildcards, so a key with a zero CLUT hash covers every palette of the
texture. The contents hash only covers the indices, so one image is shared
by all palettes (the loaded data is shared, each palette still has its own
texture cache entry).
Saving does not dump indexed textures yet.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- Reloading the ini clears the per-key lookup caches, which could keep
saying "no replacement" for textures the new ini replaces.
- With ignoreAddress, hash ranges were skipped when sizing the
replacement, though ComputeHash applies them. cache_ is now keyed by
the full key, so its lookups hit too.
- Textures sharing files but differing in size, hash range or filtering
no longer share one ReplacedTexture (the first one's settings won).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
These own GPU objects, memory or refcounts in their destructors (or assert
there that they were torn down), so a copy would double-free. Nothing copies
them today; this keeps it that way. The manager base classes cover every
backend's subclass.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- DDS files with mips stored level 0's file reference in level 1 too, so it
was freed twice.
- The VFS was deleted on config changes (and ini reloads) while load tasks
still used it. Now each cached texture waits for its task and releases its
file references through the old VFS first, and reloads afterwards.
- A failed ini reload turns replacement off instead of leaving it on without
a VFS.
- Release file references on purge.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Vuln 17: ReplacedTexture::LoadLevelData let a KTX2/DDS file at a higher
mip level resize the shared data_ vector to its own (attacker-controlled)
mip count, so data_[mipLevel + i] indexed out of bounds and the KTX2
branch resized a different element than it wrote to. Disallow mixing
image formats across mip levels, cap the container mip count, and resize
the same element that is used as the transcode destination.
Vuln 18: DecodeTextureLevel only validated the start address for
non-DXT textures, so guest-controlled w/h/bufw could drive reads past
mapped RAM. Validate the needed range like the DXT path does and clamp
the height; ReadIndexedTex now takes the clamped w/h.
* Rename LogType to Log
* Explicitly use the Log:: enum when logging. Allows for autocomplete when editing.
* Mac/ARM64 buildfix
* Do the same with the hle result log macros
* Rename the log names to mixed case while at it.
* iOS buildfix
* Qt buildfix attempt, ARM32 buildfix