Skip to content

feat(agc): sample 8 and 8_8 sRGB textures through an RGBA8 sRGB copy - #6054

Merged
adriadam10 merged 5 commits into
boykopovar:mainfrom
Dextroid17:feat/srgb-copy-pr
Oct 18, 2026
Merged

adriadam10 merged 5 commits into
boykopovar:mainfrom
Dextroid17:feat/srgb-copy-pr

Conversation

@Dextroid17

@Dextroid17 Dextroid17 commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

What

On a Vulkan device that cannot sample R8_SRGB or R8G8_SRGB, 8_SRGB and 8_8_SRGB textures were decoded in the shader. A shader decode runs after the sampler has filtered, so bilinear and gather results were wrong: the sRGB decode has to come before the filter. This samples those textures through an RGBA8 UNORM image viewed as RGBA8 sRGB, filled by a one-to-one blit of the R8 or RG8 texels (a snapshot's upload, or a storage image's texels, refreshed when its Version changes). The sampler then decodes and filters in the right order.

  • The recompiler gets the shader-decode mask only for formats the device cannot blit, or when APS5_SRGB_SHADER_DECODE=1 forces the old path.
  • 3D textures and storage images that do not match fall back to the snapshot path (CanSrgbExpandFrom).
  • Loads of a sampled texture read the copy and get the device's own decode on such devices. Storage-image loads are unchanged.
  • Multisampled and depth views of these formats get no copy (stated in the docs). I believe this is unreachable (it needs an R8_SRGB MSAA attachment on a device that cannot sample R8_SRGB) but have not verified it.
  • Cost: the copy is 4x (R8) or 2x (RG8) the guest size and is counted in SampledTextureMemory.

Relation to #5371: it decodes in the shader for direct single-mip 2D images. This PR decodes before filtering through the device for the same formats. They can coexist: the shader path stays for devices that cannot blit and under the flag. Happy to rebase or drop whichever the maintainers prefer.

Docs: docs/dev/debt/shader.md and libSceAgcDriver.md updated.

Tested

Linux (CachyOS, kernel 7.2.9), lavapipe only. The CI device is lavapipe; no real GPU and no title or homebrew were run.

  • New ImageSrgbSampleCopy: point, bilinear and gather on 8_SRGB and 8_8_SRGB including the second channel. Bilinear of a 0/255 pair must be 0.5 (filtering before decoding would give 0.21). A pending-storage-image case (store, sample, second store with different data, sample) checks the Version refresh.
  • Mutation: APS5_SRGB_SHADER_DECODE=1 makes the new test exit 1. Disabling refreshSrgbExpand makes the storage case fail ("thread 4 sampled 0.0, expected 0.0144").
  • 60/60 of the related AGC regression tests pass on this branch alone, and 10/10 repeats of the new test.
  • Not covered by a test: mip chains, arrays, and cube or 3D snapshot copies of the new path.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Unblocks: none
  • GPUs tested: lavapipe (llvmpipe, Mesa 26.2.4, LLVM 23.1.1) on CachyOS Linux 7.2.9; no hardware GPU
  • AI-assisted: yes

@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
PR 6179 core/libs/prx/libSceAgcDriver/CMakeLists.txt L1890
PR 6280 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp L240, L388-389
PR 6501 core/libs/prx/libSceAgcDriver/CMakeLists.txt L1890
PR 7085 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp L388-389
PR 7484 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp L3517-3518

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 1341 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 1368 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 1395 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 2434 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/debt/libSceAgcDriver.md
PR 4040 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 4072 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
PR 4448 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
docs/dev/debt/libSceAgcDriver.md
PR 4650 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/debt/libSceAgcDriver.md
PR 4891 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 5021 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/debt/shader.md
PR 5058 docs/dev/debt/libSceAgcDriver.md
PR 5371 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/shader.md
PR 5372 docs/dev/debt/libSceAgcDriver.md
PR 5426 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/shader.md
PR 5441 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 5499 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/debt/libSceAgcDriver.md
PR 5500 docs/dev/debt/shader.md
PR 5609 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 5925 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/debt/libSceAgcDriver.md
PR 5941 docs/dev/debt/shader.md
PR 6009 docs/dev/debt/shader.md
PR 6044 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6176 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6177 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6185 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6186 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6188 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6192 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6194 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6197 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6222 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/debt/libSceAgcDriver.md
docs/dev/debt/shader.md
PR 6223 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6235 docs/dev/debt/shader.md
PR 6259 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6273 docs/dev/debt/libSceAgcDriver.md
PR 6292 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6300 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6320 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6360 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6373 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6412 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
docs/dev/debt/libSceAgcDriver.md
docs/dev/debt/shader.md
PR 6414 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6472 docs/dev/debt/libSceAgcDriver.md
PR 6481 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6488 docs/dev/debt/shader.md
PR 6490 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6499 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6503 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6529 docs/dev/debt/libSceAgcDriver.md
PR 6535 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6539 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6548 docs/dev/debt/libSceAgcDriver.md
PR 6549 docs/dev/debt/libSceAgcDriver.md
PR 6553 core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6563 docs/dev/debt/libSceAgcDriver.md
PR 6615 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6741 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6747 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6763 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
PR 6767 docs/dev/debt/shader.md
PR 6786 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6788 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6808 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6867 docs/dev/debt/libSceAgcDriver.md
PR 6868 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6905 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6937 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6971 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6972 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6977 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
docs/dev/debt/libSceAgcDriver.md
docs/dev/debt/shader.md
PR 7201 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7223 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/shader.md
PR 7390 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7426 docs/dev/debt/libSceAgcDriver.md
docs/dev/debt/shader.md
PR 7464 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7505 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md

@github-actions github-actions Bot added docs agc libSceAgc* labels Oct 14, 2026
@Dextroid17

Copy link
Copy Markdown
Contributor Author

Status check on the current head 9130522, merged into main 6239cef (66 commits ahead of this PR's base): no conflicts, and the merge builds.

Run on lavapipe (llvmpipe, Mesa 26.2.4, LLVM 23.1.1; CachyOS, Linux 7.2.9; default CMake build with CMAKE_BUILD_TYPE empty, so unoptimized), 3 runs each, all exit 0:

By reading, not run: #4487 (already in this PR's base) gives R8/R8G8 no sRGB twin when context.srgbDecodeFormats has their bit (12d07b8). This PR leaves that field as the full mask (VulkanDevice.cpp:3437) and narrows only the copy given to the recompiler (:3310), so the two agree.

The logs show lavapipe here decodes 8_SRGB/8_8_SRGB in the shader (textures created as R8_UNORM/R8G8_UNORM), and the storage case logs "sRGB copy of storage image", so the copy path ran.

Not checked: a run with the test's source reverted, any other GPU or OS, and any title.

AI-assisted: yes

@Jacmd

Jacmd commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

Tested on Windows hardware. There's one build break on Windows. Otherwise the PR passes on both GPUs here, but neither GPU takes the new copy path.

Setup: Windows 11 Pro 10.0.26200, WinLibs GCC 15.2.0 r7, Release, BUILD_TESTING=ON, ANYPS5_ENABLE_SPIRV_TOOLS=ON. The PR head 913052267 was merged into main 8276a1d05 with no conflicts. ANYPS5_REQUIRE_VULKAN=1.

  • NVIDIA GeForce RTX 4090 (10de:2684), driver 617.42
  • AMD Radeon 610M (1002:164e, RDNA2 iGPU), AMD proprietary driver 25.10.30.02

1. ImageSrgbSampleCopy.cpp doesn't compile with MinGW

ImageSrgbSampleCopy.cpp:279:31: error: expected unqualified-id before '=' token
ImageSrgbSampleCopy.cpp:280:30: error: expected unqualified-id before '=' token

near and far are empty macros in <windows.h> (minwindef.h). Renaming the two locals fixes it, and it's the only change I made:

-            const double near = Decode(Code(format, second, base));
-            const double far = Decode(Code(format, second, base + 1u));
-            const std::array<double, 4> expected{near, far, far, near};
+            const double low = Decode(Code(format, second, base));
+            const double high = Decode(Code(format, second, base + 1u));
+            const std::array<double, 4> expected{low, high, high, low};

2. Results with that rename

RTX 4090 Radeon 610M
agc_driver_image_srgb_sample_copy pass 5/5 pass 5/5
agc_driver_image_srgb_load, agc_driver_srgb8_color_target, agc_driver_emulated_color_compare_srgb_decode pass 5/5 pass 5/5
new test with APS5_SRGB_SHADER_DECODE=1 exit 1 (samples or gathers an sRGB image the device cannot sample, which is not implemented) same

All runs used ANYPS5_NO_SHADER_CACHE=1.

Full suite on the 4090: 1,272 of 1,274 passed. The same 15 skips as unmodified main on this machine (display, Linux-only and extension skips). The two failures don't look related to this PR:

3. Coverage caveat

Both devices report SAMPLED_IMAGE and SAMPLED_IMAGE_FILTER_LINEAR with optimal tiling for R8_SRGB and R8G8_SRGB. So SrgbDecodeFormats returns 0 and SrgbCopyFormats returns 0 on both. The runs above cover:

  • This PR on the native-sampling path: no regression.
  • The new test's expected values against hardware sRGB filtering: they match, including the 0.5 bilinear midpoint.

They don't cover the RGBA8 copy itself on hardware. As far as I can tell, there's no switch that forces the copy path on a device that samples these formats natively. APS5_SRGB_SHADER_DECODE=1 only forces the old shader decode. If you want hardware coverage of the copy path, a switch that forces it would let any GPU run it.

Tested with Claude Code.

This was referenced Oct 15, 2026
@Dextroid17

Copy link
Copy Markdown
Contributor Author

@Jacmd thanks for testing on Windows, and for the fix. Both points are now on the branch:

  • b6359f04b renames near and far to low and high, as in your diff. You are listed as co-author.
  • b29b0476f adds APS5_SRGB_SHADER_DECODE=copy. It forces the RGBA8 copy for 8_SRGB and 8_8_SRGB on a device that samples those formats natively, as long as it can blit R8 and RG8 to RGBA8. If it cannot, the forced entry fails with its own message. A second ctest entry, agc_driver_image_srgb_sample_copy_forced, runs the same test with it set. The test also checks the selection with a stub device that samples R8_SRGB and R8G8_SRGB natively: with copy it must select both formats for the copy; unset or with =1, neither. So that check runs even without a GPU. The debt note in docs/dev/debt/shader.md names the switch. APS5_SRGB_SHADER_DECODE=1 is unchanged.

Results on lavapipe (llvmpipe, Mesa 26.2.4, LLVM 23.1.1). The tests ran on 5cc034a6c; the pushed b29b0476f differs from it only in the wording of the debt note. 5cc034a6c was merged into main b7cedd900 with no conflicts. Each run used a clean environment (env -i with HOME, PATH, VK_ICD_FILENAMES, ANYPS5_REQUIRE_VULKAN=1 and GALLIUM_OVERRIDE_CPU_CAPS=avx; ctest adds ANYPS5_NO_SHADER_CACHE=1). lavapipe cannot sample R8_SRGB or R8G8_SRGB, so on lavapipe both entries take the copy on the device, and the two entries differ only in the stub check.

  • agc_driver_image_srgb_sample_copy, agc_driver_image_srgb_sample_copy_forced, agc_driver_image_srgb_load, agc_driver_srgb8_color_target, agc_driver_emulated_color_compare, agc_driver_emulated_color_compare_srgb_decode: 6/6 passed, 3 runs out of 3.
  • With the one-line change in TextureFormat.cpp reverted (so copy is ignored), the forced entry fails 3 runs out of 3: selected sRGB copy formats 0 with APS5_SRGB_SHADER_DECODE='copy', expected 3. The unforced entry still passes.

On your RTX 4090 or Radeon 610M, agc_driver_image_srgb_sample_copy_forced should now run the copy on hardware. If you have time to run it again, that would cover the case lavapipe cannot: the copy on a GPU that also samples these formats natively.

AI-assisted: yes

@jotitadev jotitadev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardware run of the copy path, for the request above. On this NVIDIA device the copy is taken even without the switch, for 8_8_SRGB.

Ubuntu 26.04 (kernel 7.0.0-38), NVIDIA GeForce RTX 3070, driver 595.99.02, GCC 15.2, Release, BUILD_TESTING=ON, ANYPS5_GPU set to the 3070 (the log shows Selected GPU name=NVIDIA GeForce RTX 3070 vendor=0x10de). Head b29b0476f merged onto main 44df21632, no conflicts.

  • vulkaninfo --show-formats on this driver lists R8_SRGB with SAMPLED_IMAGE and SAMPLED_IMAGE_FILTER_LINEAR, and lists R8G8_SRGB under "Unsupported Formats". This device is the mixed case: native sampling for 8_SRGB, none for 8_8_SRGB.
  • agc_driver_image_srgb_sample_copy and agc_driver_image_srgb_sample_copy_forced: pass, 3 of 3 runs each.
  • In the verbose log, the unforced entry creates the 8_SRGB texture as vk=15 (R8_SRGB) and the 8_8_SRGB textures as vk=16 (R8G8_UNORM). With APS5_SRGB_SHADER_DECODE=copy, the 8_SRGB texture becomes vk=9 (R8_UNORM), and the storage case logs sRGB copy of storage image (guest format 128). Going by SrgbCopyFormats, 8_8_SRGB takes the RGBA8 copy here in both entries, because R8G8_SRGB cannot be sampled and R8G8_UNORM can be blitted.
  • With only the test applied on main, the test does not compile (SrgbCopyFormats is not a member of AgcDriver::Graphics), as expected for a new function.
  • ctest -R "^agc" -E "agc_display_buffer_dcc|agc_driver_flip|agc_driver_lds_atomics64|display" -j1: 594 of 595 pass, 3 skipped. The failure is agc_driver_store_over_untracked, which also fails on unmodified main on this machine: 9 of 10 runs with other builds running, all with the result did not reach a block the CPU left alone. It is the same test as #6347 and #6383, which report it on Windows. On an idle machine, main passes 593 of 593 with the same 3 skips.

Not run: any title.

GPUs tested: NVIDIA GeForce RTX 3070, driver 595.99.02, Vulkan 1.4.329, Ubuntu 26.04 (kernel 7.0.0-38)

Written with AI assistance (Claude Code). I ran the builds and tests above on my machine.

@Dextroid17

Copy link
Copy Markdown
Contributor Author

@jotitadev, thanks for the 3070 run. On the 3070, 8_SRGB samples natively and 8_8_SRGB takes the RGBA8 copy without the switch (going by SrgbCopyFormats; its textures were created as R8G8_UNORM). With copy, 8_SRGB takes it too. lavapipe cannot show that mixed case.

The branch is now rebased onto main 3f171d0 as 4a6f4df41, and it still merges cleanly into main aff725b. There was a one-line conflict in docs/dev/debt/libSceAgcDriver.md, where main added the PM4 ring entry next to the sRGB one; both entries are kept.

Re-run on Linux, lavapipe (llvmpipe, Mesa 26.2.4, LLVM 23.1.1), Release build, clean environment (env -i with the lavapipe ICD and ANYPS5_REQUIRE_VULKAN=1). agc_driver_image_srgb_sample_copy, agc_driver_image_srgb_sample_copy_forced, agc_driver_image_srgb_load, agc_driver_srgb8_color_target, agc_driver_emulated_color_compare and agc_driver_emulated_color_compare_srgb_decode pass, 6/6, 3 runs out of 3. Not run: any non-lavapipe GPU, any title.

AI-assisted: yes

@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 16, 2026
@adriadam10 adriadam10 self-assigned this Oct 16, 2026
@adriadam10

Copy link
Copy Markdown
Collaborator

Checked on lavapipe: agc_driver_image_srgb_sample_copy, _forced, image_srgb_load, image_sample_force_degamma and the other sRGB tests pass; the new test does not build without the change and fails with APS5_SRGB_SHADER_DECODE=1. Blit/barrier/layout sequence, the upload image lifetime and the debt entries look right, and the MinGW near/far fix from @Jacmd is in. Hardware confirmations from @Jacmd (Windows, RTX 4090 / Radeon 610M) and @jotitadev (RTX 3070, mixed case). Merging once the full Build is green.

@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 18, 2026
Dextroid17 and others added 5 commits October 18, 2026 07:27
A device that cannot sample R8_SRGB or R8G8_SRGB had its sRGB textures
decoded in the shader, which cannot serve filtered samples: the decode must
come before the filter. The texture is now an RGBA8 UNORM image viewed as
RGBA8 sRGB, filled by a one-to-one blit of the R8 or RG8 texels (a snapshot's
upload, or a storage image's texels refreshed when its Version changes), so
the sampler decodes and then filters, and every sample, gather and load of
these images is an ordinary sRGB one. The recompiler is given the decode mask
only for formats the device cannot blit, or when APS5_SRGB_SHADER_DECODE=1
forces the shader decode. Tests run on lavapipe only.
Co-authored-by: Jacmd <59657462+Jacmd@users.noreply.github.com>
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 18, 2026
@Dextroid17

Copy link
Copy Markdown
Contributor Author

Fresh lavapipe run of the current head, after today's push (192a37d0 test, c81cfce7 docs).

Setup: head c81cfce7c merged onto upstream/main 0d078f75d (merges with no conflict), Release, BUILD_TESTING=ON, ANYPS5_ENABLE_SPIRV_TOOLS=ON, GCC 16.2.1, device llvmpipe (LLVM 23.1.1, 256 bits), Mesa 26.2.4, GALLIUM_OVERRIDE_CPU_CAPS=avx as in build.yml.

sRGB tests, ctest -R "srgb|degamma" --repeat until-fail:3: 6/6 pass (18/18 runs), among them:

  • agc_driver_image_srgb_sample_copy
  • agc_driver_image_srgb_sample_copy_forced
  • agc_driver_image_srgb_load
  • agc_driver_image_sample_force_degamma
  • agc_driver_srgb8_color_target

The switch decides the path. Same binary, tests/agc_driver_image_srgb_sample_copy_tests, only the variable changed:

  • APS5_SRGB_SHADER_DECODE=copy: exit 0, image sRGB sample copy tests passed
  • APS5_SRGB_SHADER_DECODE=1: exit 1, ShaderRecompiler::Recompile: samples or gathers an sRGB image the device cannot sample, which is not implemented

So the forced test only passes through the copy, which matches the lavapipe result above from @adriadam10.

Full suite: 1447/1448 pass. The one failure is agc_compute_pipeline_replay (replay did not export a pipeline cache header). It fails the same way, 3 of 3, on plain upstream/main 0d078f75d without this PR, and it passes in the main CI run 39125777568 on the same commit, so it is not from this PR. It is specific to my machine: CI ran Ubuntu 24.04 mesa-vulkan-drivers 25.2.8, and I ran Mesa 26.2.4 / LLVM 23.1.1 / GCC 16.2.1, so I have not narrowed it down to Mesa alone.

@adriadam10
adriadam10 merged commit cd04995 into boykopovar:main Oct 18, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants