Commit Graph

16 Commits

Author SHA1 Message Date
Dean 1f4fd94fa8
Merge pull request #1639 from gerardlesan/fix/agc-zx-mip-tail-limits
fix(agc): use gfx1013's smaller mip tail limits for 8 and 16 bpp SW_64KB_Z_X
2026-10-10 17:40:18 +13:00
Dean afb8cd2239
Merge pull request #1609 from krishnaraya4/fix/agc-display-xor-volumes-thick
fix(agc): lay out 3D SW_64KB_D_X textures as thick volumes
2026-10-10 17:19:44 +13:00
Gerard L. b6a9530723 fix(agc): use gfx1013's smaller mip tail limits for 8 and 16 bpp SW_64KB_Z_X
The smallest mip levels of a tiled surface are packed together into one
block, the mip tail. A size limit decides which level is the first to
go into the tail.

For SW_64KB_Z_X, AnyPS5 used the same limit as the other 64 KiB modes.
In addrlib, that is only the case on Navi10. On every other GFX10 chip,
including the PS5's gfx1013, addrlib halves the limit for 8 and 16 bpp
Z_X surfaces: the width at both sizes, and also the height at 8 bpp.
The setting behind this is dsMipmapHtileFix (see HwlConvertChipFamily
and ComputeSurfaceInfoMacroTiled in gfx10addrlib.cpp).

With the larger limit, the tail started too early. For example, a
256x256 R8 surface with 9 levels started its tail at mip 1 instead of
mip 2, and took 131072 bytes instead of 196608. Every level was then
read and written back at the wrong offset.

GetMipTailLayout now halves the limits the same way. Only the level
where the tail starts changes; the tail slot positions stay the same.
This follows addrlib's setting for gfx1013. The console's own layout
has not been measured.

Fixes #1590

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 20:06:51 +02:00
krishnaraya e5da5fd2a3 fix(agc): lay out 3D SW_64KB_D_X textures as thick volumes
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 18:28:19 -04:00
krishnaraya b719eedaa5 fix(agc): round linear volume mip extents up as addrlib does
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 18:28:18 -04:00
Gjon Gojcevic 2191d60393 fix(agc): lay out block-compressed thick volumes in blocks
ComputeThickLayout refused block-compressed formats. Compute the mip
chain, padding and mip tail from the volume's block dimensions, as the thin
layout does, so BC volumes in SW_4KB_S, SW_64KB_S and SW_64KB_S_X detile
like volumes of their blocks.
2026-10-07 21:13:13 -04:00
Claude ace10fdba3 feat(agc): detile the display, T and 4 KiB XOR swizzle modes
Textures in SW_256B_D, SW_4KB_D, SW_64KB_D, SW_64KB_S_T, SW_64KB_D_T,
SW_4KB_S_X and SW_4KB_D_X (tile modes 2, 6, 10, 17, 18, 21 and 22)
threw while their T# was decoded. They are detiled with address
equations generated from AMD addrlib's GFX10 swizzle patterns for the
same 16-pipe non-RB+ configuration as the 64 KiB XOR table, and share
the block shape and mip tail placement of the standard mode of their
block size. The pipe/bank XOR base check of the XOR and T modes now
uses the block size.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 16:11:05 -05:00
Claude c10401e390 feat(agc): detile 3D textures in SW_64KB_Z_X and SW_64KB_S_X
3D textures in the 64 KiB Z and S XOR swizzles threw. As in AMD
addrlib's GFX10 rules, a Z_X volume is thin: each depth slice is laid
out like an array slice with the 2D Z_X equation, as the R_X and D_X
volumes already were. An S_X volume is thick: it takes the standard
64 KiB thick block and mip tail with its own S3 XOR equation, generated
from addrlib for the same configuration as the other equations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 16:19:11 +00:00
Dean Galvin 16f19c51ad feat(agc): thick mip tails of mipmapped 3D textures
3D textures in SW_4KB_S or SW_64KB_S whose smaller levels reach the mip
tail were refused ("3D texture mip tails are not implemented"). The
tail now follows addrlib's GFX10 thick layout
(Gfx10Lib::ComputeSurfaceInfoMacroTiled):

- a level enters the tail once its size, rounded up, fits the thick
  tail extent (the block with its height halved for 4 KiB blocks and
  its width halved for 64 KiB blocks) and at most GetMaxNumMipsInTail
  levels remain (5 for 4 KiB, 10 for 64 KiB);
- each slab starts with one tail block, then the other levels from the
  smallest to level 0;
- tail level i sits in slot maxMipsInTail - 1 - i, at the element offset
  addrlib derives from that slot's byte offset and the 256-byte thick
  micro block, at every depth slice.

The tests check element addresses of five volumes (4 KiB and 64 KiB
blocks, 1 to 16 bytes per element, odd sizes, a chain that starts in
the tail) against Mesa addrlib's Addr2ComputeSurfaceAddrFromCoord for
a Navi10 configuration.
2026-10-05 21:32:06 +13:00
Dean Galvin a3ec50aefa fix(agc): keep the guest's bytes in the padding a storage write-back stores
A GPU-direct storage write-back retiles the image's elements into an
uninitialised device scratch buffer and then copies whole ranges of it
into the import or the import's unit shadow. The retile writes only the
bytes elements occupy, so every other byte of the copied ranges was
stored from uninitialised scratch memory: the padding of the tile blocks
a surface covers only partly (its last block column and row), mip tail
blocks, the bytes between mips and the pitch padding of linear surfaces.
Another surface over the same memory, or the CPU, then read garbage
there instead of what the memory held. Both the block-window path and
the whole-layer path did this.

Before the retile, the bytes of the copied ranges that no element holds
are now copied into the scratch from where they are current (a fresh unit
shadow, else the import), so the write-back stores them unchanged. Whole
tile blocks every byte of which holds an element are left out
(CoveredMipBytes), so only partly covered blocks pay for the extra copy.

Tests: CoveredMipBytes against the XOR address equations of the four
64 KiB XOR modes at every element size; a device test that stores
cleared images over patterned memory (tiled with and without mip chains,
off a 64 KiB boundary, 4 KiB standard, linear; plain and watched memory)
and checks every byte that is not a texel kept its pattern.
2026-10-05 20:51:34 +13:00
Michon 66a46259d1 fix(agc): pad tiled 3D mip levels from their size rounded up, as addrlib does
addrlib sizes a non-tail level with ShiftCeil; the layout used the image's
rounded-down extent, so volumes with a non-power-of-two width or height (33x20x12
in the new test) got a different layout.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-04 10:27:32 +02:00
Michon efde918a62 feat(graphics): mipmapped 3D textures
3D textures with more than one mip level were refused. Each slab of
blockDepth slices of a thick (SW_4KB_S / SW_64KB_S) volume now holds the
whole mip chain, smallest level first and level 0 last, as 2D chains are
laid out. A level's depth halves per level, so the texture loops skip the
slices a level does not have. Thin 3D (D/R 64KB_X) chains use the 2D mip
layout per depth slice. Thick mip tails still throw.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-04 10:27:32 +02:00
STL1te 6b36c050fe style: drop the branch's code comments per CONVENTIONS.md
Only the lines this branch added lose their comments; the commits before
keep them, with the reasoning behind each change, for whoever digs into
that code later.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 21:25:29 +03:00
STL1te c8913314bc test(agc-driver): the graphics and BDA device tests link and run to the end
Both suites stopped at their first stale expectation, so nothing after
it ran; the BDA device tests did not link.

- the BDA device tests define the one recorder entry Resources.cpp
  reaches (no recorder) and fail loudly on the others
- Buffer::Invalidate refuses memory that is not host mapped again (lost
  in 8a69fef); the device tests expect it for a device-local buffer
- APS5_PIN_WAIT_MS (60000 by default, unchanged) bounds the wait before
  a mutation of a leased range is refused, and the refusal names it; the
  graphics tests set 200 ms, as they expect about a dozen refusals
- the expectations follow the behaviour the code chose since: a buffer's
  four-DWORD V# is refused as a T#, a sampler exceeds the mock's zero
  sampler slots, a V# at unmapped memory binds its committed pages only,
  a rect-list fragment input without a vertex export reads as zero,
  detiled rows span the padded block width, mip ranges are checked in
  address order, block-compressed and 128/129/132 formats use render
  target tiling, an XOR swizzle is refused only over a base that is not
  64 KiB aligned, DCC and partial mip chain views decode, a cube reads as
  a 2D array, the sampler fixture's max LOD fits the 4.8 field, a BDA
  program with barriers is accepted, a tessellation control stage is
  refused, a corrupt request fails on its signature and a newer one on
  its version
- the DCC comment in the texture decoder no longer claims metadata
  compression is refused

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 21:22:23 +03:00
boykopovar fa6d023b1b feat(agc): support rendertarget64kb shader textures 2026-09-24 11:18:35 +03:00
boykopovar b521e1f811 test(agc): add texture resource and detiling coverage 2026-09-23 10:57:27 +03:00