8_8_8_8_GAMMA resolve update:
This hopefully settles how safe resolves of gamma RTs are handled, because it's almost certainly not settled by destination.
It's now believed that gamma sources seen by resolve are always being decoded, and that's a decode that's keyed only on the source format, where every destination is fed linear values, and any encode is now just removed rather than conditional.
These sources are re-alised as plain before resolving, which is the same exact idea that preserves float 2_10_10_10 bits through a resolve too.
Integer texture fetch scaling update:
Unsigned-biased components were using the regular unsigned scale even though the conversion had remapped the sample [0, 1] to [-1, 1].
Scale bits data is now increased from 5 to 6 bits and use the new bit to mark unsigned-biased components. DXBC/SPIR-V use half of the unsigned scale and add a -0.5 offset.
This fixes post-processing in 415608B2 and will likely improve other titles w/ EDRAM transports through affected textures, but perhaps not so dramatically.
Roughly matching D3D12, R16G16B16A16_UNORM is used for gamma RTs when sampled and blendable color attachments are supported. The host target is kept linear for blending, and converted during ownership transfers, clears, and readbacks.
Shares the PWL conversion helpers between the translator and RT cache. Raw gamma bytes are decoded to safe linear midpoints so round trips preserve the original bytes.
Implements resolution scale selection, per surface, for both backends.
Surfaces with pitches at or below the defined threshold render at 1x1 while everything else scales. This catches downscaled post-process chains that gain nothing from upscaling and often break from it. 0 leaves everything scaled.
Class is a function of pitch and MSAA samples, baked into RenderTargetKey, and the caches create, clear, transfer, and dump per that class. Transfer shaders carry separate dest and source scales. Pixel shaders get a modification bit so 1x1 draws translate with 1x addressing for param_gen and memexport, and per-draw viewports, point sizes, and divisors pull from RT cache instead of draw_resolution_scale_x/y.
1x1 resolves copy unscaled data straight into shared memory and unmark the range from scaled resolve page tracking, so textures pick up the correct copy. Readback resolves skip downscaling when appropriate. ZPD normalizes per segment so mixed reports don't undercount.
Host RT only. ROV/FSI EDRAM layout assumes a single global scale and, while implementing support for scale selection is probably doable, it's likely an enormous task.
Implements readback for resolution-scaled resolves in both D3D12 & Vulkan backends, mostly mirroring Xenia Edge's approach, with a few small adjustments.
The scaled resolve buffer stores each texel as a group aligned scale_x by scale_y block. A small CS now reverses that packing per 32x32 tile and writes 1x. So far, this is Edge's approach verbatim. This slightly diverges from Edge since now the source window is bound at the written extent, not the texture base & the tail after the last whole tile is no longer copied.
Dest format and texel size are the same ResolveInfo the written extent was calculated with rather than rereading RB_COPY_DEST_INFO, which probably matters for depth resolves where the register holds k_8. 128bpp dests, extents that aren't group-aligned, and extents outside the scaled range skip readback.
This resolves the TODO in GetColorClearShaderConstants about which 32 bit portion is in which register.
For 64bpp formats, RB_COLOR_CLEAR_LO holds the lower 32 bits of the packed clear value, and RB_COLOR_CLEAR holds the upper 32 bits.
RegisterFile zeroes the whole register file at construction, but a real
console comes up with non-zero values in several of the context
registers. If a game reads one of those before writing it, it gets 0
under emulation and the real default on hardware.
I read the reset values off a retail console (read-only) and checked
them against the AMD R6xx register reference and the r600g defaults in
Mesa, which set the same registers to the same values at context init.
Where the hardware read matches the driver default it's a genuine
power-on default, not leftover runtime state.
Left the tessellation levels out on purpose: they reset to 1.0f too, but
the backends do register + 1.0f, so seeding them here would change the
effective reset factor. That needs its own change.
Thanks to latest change there is no need to use hardcoded nanosleep, so we can go back to previous stuff.
Hopefully it will fix some random issues with audio introduced lately
Integer num_format fetches now get their scale CPU-side instead of trying to guess in the shader. This is authoritative; no cvar. Both translators now use texture_integer_scale_bits after signs/gamma and before exponent bias. This alone fixes black screens and a bunch of rendering bugs across at least several dozen titles.
This new information lives in the updated FormatInfo table, including fixed component widths.
Resolve also has two new fixes.
8_8_8_8_GAMMA EDRAM sources can now decode through the PWL curve while still in linear space, before MSAA resolve or format conversion, then re-encoded for gamma destinations. This is also now default enabled via gamma_decode_pwl_resolve and has improved blowout in at least 4 titles, with no obvious regressions thus far.
Full resolve can also now pack fixed destinations according to copy_dest_number.
Check shared memory validity before marking textures up to date and installing watches. If the backing range was invalidated, leave the texture outdated so it can be reloaded later.
Use new archive input to rework artifacts.
Add runs-on and llvm_version inputs and ubuntu_base output to Lint so it can be passed to the Linux job.
Remove broken config input.
Upgrade Windows to VS2026.
Replace the x64 STVL/STVR lowering with explicit byte stores that preserve the
guest-visible vector byte order.
The previous vector shuffle/blend path could write incorrect bytes for partial
vector stores, which broke optimized guest memcpy implementations using
stvlx/stvrx for unaligned heads and tails. In 4156081C this corrupted skinned
model render command data and eventually caused render-thread crashes.
Add regression coverage for StoreVectorLeft/StoreVectorRight across common
unaligned offsets, plus a memcpy-head style case matching the affected guest
instruction pattern.