406 Commits
Author SHA1 Message Date
LibretroAdmin e961638263 Texture cache: hash whole buffers with libretro-common's encoding_crc32
Most of the texture cache's hashing is one whole buffer a frame: the
XFB, checked against its copy before it is shown. On x86-64 with
VPCLMULQDQ on ZMM, a whole buffer of 512 bytes or more is now the
CRC-32 of libretro-common's encoding_crc32, which folds 512 bits at a
time; smaller and sampled hashes, and every other CPU, keep the four
CRC32C chains. Folding 128 bits at a time is no quicker than the
chains, so PCLMULQDQ alone keeps them too.

Throughput here (Zen 5), chains against encoding_crc32:
  512 B 25 to 44 GB/s, 2 KiB 25 to 70, 32 KiB 26 to 91,
  a 600 KiB XFB 25 to 52-67.

encoding_crc32.c, its tables and crc32.h are copied unchanged from
libretro/libretro-common.

States keep texture cache hashes, and a copy whose picture is only on
the host would be lost to a mismatch: the first check of a copy a
state brought back also takes the old hash of its memory
(common_hash64_v1), and keeps the new one from then on. A state the
parent saved, loaded by this build, takes its XFB copy that way.
2026-11-10 03:53:30 +01:00
LibretroAdmin 9b7bdaeaec Texture cache: a copy filled with the uninitialized pattern has its shape's hash
An EFB or XFB copy kept only in VRAM fills its RAM with the uninitialized
pattern, then hashed all of it back to record it unchanged. Those are the
same bytes for the same row size, stride, rows and sample count every
time, so the hash is kept per shape (four of them) and taken from there
when the entry's shape is the fill's; the first copy of a shape hashes
the memory as before. On the stutter corpus the kept hash matched the
memory's in every one of 8500 copies, and retro_run, single core, went
from 323M instructions to 266M.
2026-11-10 03:10:58 +01:00
LibretroAdmin 8f1331adab Hash in C89
The texture hash, the CRC32 helpers, Adler-32 and the Ector hash are C;
the texture hash picks CRC32 or MurmurHash3 once with a branch instead
of calling through a function pointer each time, CPUDetect still
deciding which. The hashes are bit for bit the old ones, so cached and
saved hashes stay valid.
2026-11-09 21:34:27 +01:00
LibretroAdmin 8a022edefc Remove the video statistics nothing reads
Every Statistics counter, the projection copies and the widescreen ratio
averages were only written since the debug UI went; the counters bumped
per primitive, per triangle and per pixel in the software rasterizer.
The widescreen heuristic keeps only the two vertex counts it compares,
from one projection/viewport ratio per flush instead of up to three.
GetCPRegInfo, the CP register describer, has no caller.
2026-11-09 20:17:05 +01:00
LibretroAdmin 12208e7303 Texture pool kept within a budget, not three frames
A pooled texture unused past the threshold stays while the pool holds
less than 64 MB, the oldest dropped first, so a config that comes back
reuses one where a new image was made. Over the corpus, textures made
after boot fall from 1031 to under 51, and the core's thread's
allocations from 1079 to 62.
2026-11-09 06:35:18 +01:00
LibretroAdmin 01c993b7bd EFB copies to RAM: one encoder per format, built before the game
An encoder reads the rest of the copy (the EFB's format, depth, YUV,
filter rows, overflow, gamma) from its uniforms, in what was the
block's padding, so one per copy format draws them all. Where copies
to RAM may be made, every format's is built on the workers before the
game starts: a copy to RAM has no other pipeline to draw with. The
gate checks pictures with copies to RAM too, and fails one that waits
for its encoder; the corpus made the parent build 201 on the draw path.
2026-11-09 04:42:40 +01:00
LibretroAdmin d946f4d333 Vulkan: textures decoded on the GPU ahead of the draws
With GPU texture decoding, the decoding dispatch and the copy into the
texture are recorded in the init command buffer, which runs before the
draws, instead of between them: decoding a texture no longer ends the
render pass. The scratch texture is used there alone, and a decoded
texture is new or from the pool, which this command buffer's draws do
not use, so the layouts each tracks still hold. Other backends record it
in order, as before.

The stutter gate counts a frame as differing only when the pictures it
was presented as have none in common between the two runs.
2026-11-08 23:05:53 +01:00
LibretroAdmin 4e90104ba0 EFB copies to VRAM drawn by a pipeline per format, never built on a draw
The EFB copy pixel shader reads the copy's filter rows, overflow,
gamma, alpha, depth and intensity from its uniforms, each branch taking
the path a shader built for that copy would, so one is built per
format. One more, built with the shared pipelines, reads the format
from them as well and draws a format's copies until the format's own is
built on a worker.

The stutter corpus copies the EFB to a texture in every colour,
intensity and depth format, with the EFB with and without alpha, draws
it back textured, and cycles the copy filter and gamma. Each frame
draws its number, which the harness reads back, so the picture check
compares the two cores frame by frame in both synchronous modes. The
baseline is the new corpus's.
2026-11-08 20:39:57 +01:00
LibretroAdmin 85b64dc7b0 VideoCommon: video globals and backend objects as plain pointers 2026-11-08 03:21:40 +01:00
LibretroAdmin eac19c3216 VideoCommon: textures, framebuffers and vertex formats as plain pointers 2026-11-08 03:21:36 +01:00
LibretroAdmin 5dbbaddcc1 VideoCommon: texture cache references and pending copies in plain arrays
An entry keeps its first few references in place and more on the heap,
XFB stitching keeps its candidates in an array it reuses and sorts by
insertion, and the EFB copies waiting for RAM sit in an array counted as
handles would count them, in the order they flush.
2026-11-08 01:17:32 +01:00
LibretroAdmin cc94cf99a1 VideoCommon: the texture pool is an array of slots
Textures kept for reuse sit in a plain array, found by their packed
config and swapped out of it when taken or dropped; it grows only past
the most a game has had pooled at once.
2026-11-08 00:43:49 +01:00
LibretroAdmin 2b5178e5f9 VideoCommon: the texture cache indexes its entries in treaps of pooled nodes
The address and hash indexes keep the order a multimap kept, equal keys
as they went in, and a node stays where it is while others come and go,
so every walk and savestate sees the textures as before. Their nodes are
reused, so caching a texture while the game runs allocates none.
2026-11-08 00:43:45 +01:00
LibretroAdmin cf888bebca VideoCommon: texture cache entries from a pool, counted in place
Entries come from chunks kept for the core's life and go back to them
when their last handle goes, so a texture cached while the game runs
allocates no entry. Their handles count in the entry itself, with plain
increments on the video thread.
2026-11-08 00:43:41 +01:00
LibretroAdmin f0f8757c91 VideoCommon: one texture cache for every backend
The software renderer's EFB encode and the null renderer's empty copies
are picked by the backend kind, so the cache has no virtual calls.
2026-11-07 22:25:36 +01:00
LibretroAdmin 03810f4a91 VideoCommon: an XFB copy lost from VRAM keeps the shown picture
XFB copies kept only in VRAM go with the texture cache when the video
backend is made again or a state is loaded. RAM then holds only the
uninitialized marker, so no picture is fetched from it and the frontend
keeps the one it shows until the game's next XFB copy.
2026-11-07 18:25:34 +01:00
LibretroAdmin 361bcaf7a1 Video: textures and XFBs decode straight into the backend's upload memory
AbstractTexture::LendLoad lends the upload stream's memory for a level,
and CommitLoad uploads it: Vulkan for any rows, Direct3D 12 for rows at
its pitch alignment. The texture cache decodes textures and XFBs into
it; it decodes into its own buffer and Loads that where the backend
lends none, or when the arbitrary mipmap detection reads the levels
back. The detector keeps its levels in a fixed array.
2026-11-07 17:53:42 +01:00
LibretroAdmin 6bdbdfefd5 TextureCache: EFB copies kept across a savestate load on OpenGL too
Loading a state on OpenGL no longer throws the texture cache away after
restoring it: the EFB copies the state carries, the XFB copies among
them, are found again as on the other backends, instead of the next
picture being decoded from RAM, which the copies never wrote, and shown
as garbage.
2026-11-07 00:43:00 +01:00
LibretroAdmin f7d5095739 Core, InputCommon, VideoCommon: remove the remaining locks
Every std::mutex, lock_guard, unique_lock, scoped_lock,
condition_variable, call_once and semaphore left in Source/Core is
replaced by a lock-free design:

- Input: the device list, control bindings, stick calibration and
  default device are published snapshots read under a quiesce; a
  rebind requested while another thread is rebinding is handed to
  that thread instead of waited for.
- WiimoteReal: the pool thread owns the slots and runs commands from
  an MPSC queue; the active Wiimotes are atomic slots.
- EXI/SI/IOS devices: socket and packet traffic goes through SPSC
  rings or MPSC handoffs owned by one thread; USB scanning publishes
  its device list, and libusb transfers drain through a CallGate.
- Memory cards: the flush thread applies change records queued by
  the CPU thread.
- Custom assets: loads are scheduled as a published batch with an
  atomic cursor, results come back over an MPSC stack, and busy
  assets are skipped and retried.
- D3D state and GL program caches use insert-only atomic maps
  (Common/AtomicHashMap.h).
- Logging appends with O_APPEND / FILE_APPEND_DATA; FatFs reports
  busy instead of waiting; per-socket WSAStartup/WSACleanup.

Deleted as unused by the libretro core: the profiler, the FIFO
recorder, the volume verifier, the touch InputOverrider and the
GameCube adapter's libusb path.
2026-11-05 20:11:31 +01:00
LibretroAdmin 472dc5ae3f Remove user post-processing shaders and graphics-mod custom shaders
Both fed user-written GLSL to the backends at runtime, which the move to
bytecode emitted straight from the shader generators leaves no compiler
for. The frontend's own shader pipeline covers post-processing.

The presentation pass keeps a plain copy and the built-in correction
shader for output resampling, colour space and gamma correction and HDR
scaling, now compiled in rather than loaded from Sys/Shaders. The
graphics-mod system keeps its draw, EFB, projection and texture actions;
custom pipelines, materials, shader, mesh and sampler assets, the custom
constant buffers in every backend and the two mods built on them are
gone, along with the shader generators' custom-shader hooks.
2026-11-05 15:57:56 +01:00
Craig Carnell eb97db0652 Merge tag '2609' into 2606a-update
Release for September 2026
2026-09-24 10:15:25 +01:00
iwubcode 9263f6b7c6 VideoCommon: separate out reinterpret and palette texture creation from rendering 2026-08-31 19:51:30 -05:00
Craig Carnell 3d070f498a libretro: update to 2606 2026-06-25 09:54:48 +01:00
JosJuice 74bb80544e Merge pull request #14565 from SuperSamus/cpp-argument-move-reference
Improve usage of std::move and const references parameters
2026-04-18 21:02:30 +02:00
cristian64 6059045c59 Core: Address -Wrange-loop-construct warning.
The warning can be seen since 1f72403ec7 when GCC 13.3.0 is used:

```counterexample
[1540/1898] Building CXX object Source/Core/VideoCommon/CMakeFiles/videocommon.dir/TextureCacheBase.cpp.o
/w/dolphin/Source/Core/VideoCommon/TextureCacheBase.cpp: In member function 'void TextureCacheBase::ApplyMaterialToCacheEntry(const VideoCommon::MaterialResource&, TCacheEntry*)':
/w/dolphin/Source/Core/VideoCommon/TextureCacheBase.cpp:3136:19: warning: loop variable 'texture' creates a copy from type 'const VideoCommon::MaterialResource::TextureLikeReference' [-Wrange-loop-construct]
 3136 |   for (const auto texture : material_data->GetTextures())
      |                   ^~~~~~~
/w/dolphin/Source/Core/VideoCommon/TextureCacheBase.cpp:3136:19: note: use reference type to prevent copying
 3136 |   for (const auto texture : material_data->GetTextures())
      |                   ^~~~~~~
      |                   &
```
2026-04-18 10:23:55 +01:00
Martino Fontana 95dec13203 Improve usage of std::move and const references parameters
Accomplished using `run-clang-tidy` with `performance-move-const-arg,performance-unnecessary-value-param,modernize-pass-by-value`.

Changed arguments to const references, removed them where inappropriate (e.g. sink parameters). Same with std::move.

Manually reviewed each change to make sure that it makes sense, and do something more appropriate if possible.
2026-04-17 12:39:46 +02:00
iwubcode 1f72403ec7 VideoCommon: optionally apply materials to EFBs
After an EFB operation is turned into a texture, if there is a graphics mod action that provides a custom material, update the EFB texture with the material
2026-03-26 20:13:16 -05:00
iwubcode 6ba2d2e081 VideoCommon: update graphics mod action interface
* Add a 'AfterEFB' function to graphics mod action that can return a Material
* Rename previous EFB graphics mod function to 'BeforeEFB' to differentiate from 'AfterEFB'
* Rename previous XFB graphics mod function to 'BeforeXFB' to mirror EFB
2026-03-26 18:52:01 -05:00
TellowKrinkle 56845b2b93 VideoCommon: Fix no mips hack 2026-03-21 00:35:06 -05:00
Craig Carnell 7743c7e1dd Merge in upstream dolphin/master into libretro 2026-02-22 09:07:47 +00:00
JosJuice fb07406f10 VideoCommon: Defer creating TextureInfo
TextureCacheBase::LoadImpl has a hot path where the passed-in
TextureInfo never gets used. Instead of passing in a TextureInfo, let's
pass in the stage and create the TextureInfo from the stage if needed.

This unlocks somewhere above an additional 4% performance boost in the
Hoth level of Rogue Squadron 2 on my PC. Performance varies, making it
difficult for me to measure, so treat this as a very approximate number.
2026-01-18 13:04:06 +01:00
JMC47 035bcffc63 Merge pull request #14289 from Sintendo/typos
Fix various typos and spelling mistakes
2026-01-17 19:10:50 -05:00
iwubcode b556bd99d7 Merge pull request #14268 from JoshuaVandaele/std-tounderlying
c++23: Replace Common::ToUnderlying with std::to_underlying
2026-01-17 16:49:57 -06:00
Sintendo 1e0473e44f Fix various typos and spelling mistakes 2026-01-17 20:11:38 +01:00
JosJuice f7b4d2738b VideoCommon: Don't create mipmap vector in TextureInfo
The TextureInfo constructor creates a vector of MipLevels. This could be
good for performance if MipLevels are accessed very often for each
TextureInfo, but that's not the case. Dolphin creates thousands of
TextureInfos per second that it never accesses the mipmap levels of
because there's a hit in the texture cache, and in the uncommon case of
a texture cache miss, the mipmap levels only get looped through once.

To make the common case of texture cache hits as fast as possible, let's
not create a vector in the TextureInfo constructor. This commit
implements a custom iterator for MipLevels instead.

In my testing on the Death Star level of Rogue Squadron 2, this speeds
up TextureInfo::FromStage by 200%, giving an overall emulation speedup
of a bit over 1%. Results on the Hoth level are even better, with
TextureInfo::FromStage being close to 300% faster and overall emulation
being over 4% faster. (Single core, no GPU texture decoding.)
2026-01-17 17:57:07 +01:00
Joshua Vandaële 55f0715ad4 c++23: Replace Common::ToUnderlying with std::to_underlying
Requires at least GCC 11, Clang 13, MSVC 19.30 (VS2022 17.0), or AppleClang 13.1.6 (XCode 13.3).
2026-01-09 23:49:10 +01:00
iwubcode 2d21a99205 VideoCommon: separate the concept of a 'resource' from an 'asset'. A resource is potentially multiple assets that are chained together but represent one type of data to the rest of the system. An example is a 'material'. A 'material' is a collection of textures, a custom shader, and some metadata that all comes together to form what the concept of the material is. There will be a 'material' resource. For now, start small by introducing the interface and change our texture loading which used assets from the old resource manager, to an actual resource. 2025-11-23 11:04:24 -06:00
iwubcode 59d9c1772a VideoCommon: rename 'IsAnisostropicEnhancementSafe' to 'IsAnisotropicEnhancementSafe' in TextureCacheBase 2025-11-23 11:04:24 -06:00
Craig Carnell ae98a5fa9e Small refactor for upstream changes, add single core mode 2025-11-16 16:25:15 +00:00
Craig Carnell f011bebbad Merge upstream/master into libretro 2025-11-16 16:22:40 +00:00
TellowKrinkle 21ac489d57 VideoCommon: Fix render to texture in wrong layout 2025-10-30 20:50:17 -05:00
Craig Carnell 71fd149aa6 Refactor base code for libretro usage 2025-10-10 09:23:54 +01:00
Admiral H. Curtiss 3fb80bec9b Merge pull request #13780 from jordan-woyak/fix-text-filter-nearest
VideoCommon: Fix "Force Nearest" texture filter setting.
2025-08-01 21:59:04 +02:00
Sintendo f2392e4048 Avoid map/set double lookups
Fix some common anti-patterns with these data structures.

- You can dereference the iterator returned by `find` to access the
  underlying value directly, without an extra `operator[]`/`at`.
- Rather than checking for an element before insertion/deletion, you can
  just do the operation and if needed check the return value to
  determine if the insertion/deletion succeeded.
2025-07-08 06:53:42 +02:00
Jordan Woyak 60156f4f94 VideoCommon: Fix "Force Nearest" texture filter setting. 2025-06-28 15:52:27 -05:00
iwubcode 7afa9e6c6f VideoCommon: use CustomResourceManager in the texture cache and hook up to our hires textures 2025-06-06 23:03:02 -05:00
JMC47 ad3650abfc Merge pull request #13093 from mitaclaw/ranges-modernization-4-projection
Ranges Algorithms Modernization - Projection
2025-03-23 15:56:13 -04:00
Jordan Woyak 561aee7707 Config: Expose Default and 1x Anisotropic Filtering setting. 2025-03-17 20:46:24 -05:00
Pokechu22 79a1e480ca Enable anisotropic filtering when the game requests it 2025-03-17 20:46:19 -05:00
mitaclaw e4efe011d7 Modernize std::max_element with ranges and projections 2025-03-09 13:26:39 -07:00