vk: BC3 levels that halve evenly on AMD (the terrain grid in Hyrule Field) #705

Merged
madebyjordan merged 3 commits from amd/uneven-bc-levels into main 2026-11-08 21:37:42 +00:00
madebyjordan commented 2026-11-08 17:54:43 +00:00 (Migrated from github.com)

What this fixes

On AMD, the terrain in Hyrule Field draws a grid of dark lines along its seams, worse in the distance.

AMD's drivers sample a BC level wrong when its block grid isn't level 0's halved. For example, 1365 texels are 342 blocks, but level 2 (341 texels) is 86 blocks, not 342 >> 2 = 85. The big ASTC textures kept as BC3 include Ocarina's terrain material arrays (1365 x 1365 x 90), which hit this. Lichii #448 found the same on an RX 6600 XT.

Change

On AMD, an ASTC texture that would be kept as BC3 with uneven block levels is now:

  • encoded at the nearest size whose blocks halve evenly down to its 16-texel levels (1365 -> 1536, 683 -> 768; 768 and 1536 stay), through a second scratch and a filtered blit;
  • given only the levels that halve evenly (the ones dropped are under 16 texels).

The game samples with normalized coordinates, so a resized level covers the same area. Copies into part of a resized texture, out of one, or into a level it left out are skipped and logged. When resizing would grow it by more than a quarter, or past the scratch, it stays RGBA8.

  • RX_VK_UNEVEN_BC=1: BC3 as before; =0: this on other cards too.
  • RX_VK_UNEVEN_RGBA8=1: RGBA8 instead of resizing.
  • gpu/vk/bc_levels.h holds the size maths; tests/test_bc_levels.py checks it (tests/run_all.py picks it up).

Tested

RX 6700 XT, Adrenalin 32.0.21045.16010, Windows 11:

  • Hyrule Field: the grid is gone, with no visible quality loss up close or in the distance.

  • Keeping these textures RGBA8 also removed the grid but used about 3 GB more VRAM. This path made 466 textures BC3 (256 resized, 210 with fewer levels, none RGBA8), about 2.1 GB less than RGBA8; the texture budget averaged 4.7 GB instead of 3.9 GB.

  • v2.0.2 with this change: a 20-minute run through Hyrule Field, the grid stayed gone. The log shows 846 textures taking this path (512 resized, 334 with fewer levels, none RGBA8), no copies skipped, and the texture budget held at its full 6 GB.

🤖 Generated with Claude Code

## What this fixes On AMD, the terrain in Hyrule Field draws a grid of dark lines along its seams, worse in the distance. AMD's drivers sample a BC level wrong when its block grid isn't level 0's halved. For example, 1365 texels are 342 blocks, but level 2 (341 texels) is 86 blocks, not 342 >> 2 = 85. The big ASTC textures kept as BC3 include Ocarina's terrain material arrays (1365 x 1365 x 90), which hit this. Lichii #448 found the same on an RX 6600 XT. ## Change On AMD, an ASTC texture that would be kept as BC3 with uneven block levels is now: - encoded at the nearest size whose blocks halve evenly down to its 16-texel levels (1365 -> 1536, 683 -> 768; 768 and 1536 stay), through a second scratch and a filtered blit; - given only the levels that halve evenly (the ones dropped are under 16 texels). The game samples with normalized coordinates, so a resized level covers the same area. Copies into part of a resized texture, out of one, or into a level it left out are skipped and logged. When resizing would grow it by more than a quarter, or past the scratch, it stays RGBA8. - `RX_VK_UNEVEN_BC=1`: BC3 as before; `=0`: this on other cards too. - `RX_VK_UNEVEN_RGBA8=1`: RGBA8 instead of resizing. - `gpu/vk/bc_levels.h` holds the size maths; `tests/test_bc_levels.py` checks it (`tests/run_all.py` picks it up). ## Tested RX 6700 XT, Adrenalin 32.0.21045.16010, Windows 11: - Hyrule Field: the grid is gone, with no visible quality loss up close or in the distance. - Keeping these textures RGBA8 also removed the grid but used about 3 GB more VRAM. This path made 466 textures BC3 (256 resized, 210 with fewer levels, none RGBA8), about 2.1 GB less than RGBA8; the texture budget averaged 4.7 GB instead of 3.9 GB. - v2.0.2 with this change: a 20-minute run through Hyrule Field, the grid stayed gone. The log shows 846 textures taking this path (512 resized, 334 with fewer levels, none RGBA8), no copies skipped, and the texture budget held at its full 6 GB. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Commenting is not possible because the repository is archived.
No description provided.