Skip to content

feat(agc): sample border colors from the border color table - #1221

Closed
awake-devel wants to merge 1 commit into
boykopovar:mainfrom
awake-devel:feat/agc-sampler-border-color-table
Closed

awake-devel wants to merge 1 commit into
boykopovar:mainfrom
awake-devel:feat/agc-sampler-border-color-table

Conversation

@awake-devel

@awake-devel awake-devel commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

What

Closes #665.

A sampler with BORDER_COLOR_TYPE 3 whose clamp mode reads the border now takes its color from the border color table instead of throwing.

  • DecodeSamplerResource decodes BORDER_COLOR_PTR (S# word 3, bits 0–11). A table-type sampler that never reads its border decodes as before (fix(agc): accept a table border colour when no axis uses a border mode #941).
  • The entry is the 4 dwords at base + BORDER_COLOR_PTR × 16 (the radeonsi and radv layout), read from guest memory when the resources are built and passed to VK_EXT_custom_border_color as a float custom color with VK_FORMAT_UNDEFINED. The extension is enabled when the device has customBorderColors and customBorderColorWithoutFormat; without them such a sampler throws. Live custom-color samplers are counted against maxCustomBorderColorSamplers.
  • Base: draws take TA_BC_BASE_ADDR/_HI (context 0x20/0x21, added to DrawKeyRegisters), dispatches take TA_CS_BC_BASE_ADDR/_HI (user config 0x380/0x381), the pairs Mesa programs. A dispatch that reads a table color with the compute pair unset throws, with no fallback to the graphics pair, as agreed in AGC sampler: border colour table (BORDER_COLOR_TYPE 3) not implemented #665.
  • The entry's 4 dwords are part of the SamplerCache key. A ShaderResources that holds such a sampler is not reusable, so it is never cached or recorded as a recipe, and a rewritten table or a moved base is read again by the next draw or dispatch.
  • An integer-format texture paired with such a sampler throws: whether the console reads the entry as integers then is unverified. Recorded in TechnicalDebt together with the unconfirmed compute base. The shader-emulated color comparison path (fix(agc): emulate comparison sampling of color textures in the shader #668) still rejects table colors.
  • The existing comment above SamplerCache is edited to name the entry as part of the key; no comment is added.

#757 adds runtime-indexed sampler tables that create samplers without the entry. If both land, such a sampler throws instead of using a zero color: the decoded entry is an optional that Sampler requires.

Tested

Linux (Arch, GCC 16.2.1), GeForce GTX 1050 Ti Max-Q, NVIDIA 580.178.04. Full ctest: 400/400 pass.

  • New agc_driver_image_sample_border_color_table: compute dispatches sample a 13×7 RGBA8 image with image_sample_lz, image_sample_l and image_sample through point clamp-to-border table samplers, with unnormalized and normalized coordinates: table entries 0–3 (entry 3 holds the words ThisIsAkill dumped from PPSA21567 in AGC sampler: border colour table (BORDER_COLOR_TYPE 3) not implemented #665), an entry rewritten between dispatches, a second table, and the rejections (no base, base past 48 bits, integer texture). Also passes with APS5_NO_SAMPLER_CACHE=1. NVIDIA rounds the border color to the image's 8-bit precision (0.25 reads as 64/255), so the test allows half a step.
  • agc_driver_graphics: decode tests for the pointer (bits 0–11, recorded only when a border mode reads it) and the captured PPSA21567 sampler; mock Vulkan tests that the entry reaches vkCreateSampler bit for bit with VK_FORMAT_UNDEFINED, that a table-color build is not reusable while a fixed-color one is, and the device limit, missing extension and missing base. Each of these tests fails when the rule it covers is removed.
  • Under VK_LAYER_KHRONOS_validation 1.4.363.0 (core validation, errors and warnings): the full suite passes 400/400, and nothing this PR touches reports a message: the new test (with and without APS5_NO_SAMPLER_CACHE=1), agc_driver_graphics and agc_driver_emulated_color_compare are clean. As a control, leaving customBorderColors and customBorderColorWithoutFormat out of device creation makes the new test report VUID-VkSamplerCreateInfo-customBorderColors-04085 and VUID-VkSamplerCustomBorderColorCreateInfoEXT-format-04014 (the test itself still passes on NVIDIA), so the layer does check these samplers.
  • 23 other execution tests (flat and global loads, stores and atomics, image loads and stores, bvh64_intersect_ray, scalar_wide_loads, view_past_last_mip) report one VUID-vkDestroyDevice-device-05137 each: one or two VkBuffer/VkDeviceMemory pairs still alive at vkDestroyDevice. They report the same on main (cea1ef1) with the same object counts, so they predate this PR.
  • Not tested on a title: no known title samples through a table border (PPSA21567's table sampler clamps to the edge on every axis). Not tested on AMD or Windows.

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 in TechnicalDebt
  • 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
  • AI-assisted: yes

🤖 Generated with Claude Code

https://claude.ai/code/session_018RNrNcixatky8U4LfC7Ew5

A sampler with BORDER_COLOR_TYPE 3 whose clamp mode reads the border
takes its color from the border color table instead of throwing. The
entry is the 4 dwords at base + BORDER_COLOR_PTR * 16, read when the
resources are built and passed to VK_EXT_custom_border_color as a float
custom color. Draws take the base from TA_BC_BASE_ADDR, dispatches from
TA_CS_BC_BASE_ADDR; an unset base, a base past 48 bits and an
integer-format texture throw. Builds holding such a sampler are never
cached or recorded as recipes.

Closes boykopovar#665

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018RNrNcixatky8U4LfC7Ew5
@oneandonlydean

Copy link
Copy Markdown
Collaborator

Closing: no title samples through a table border colour on main. The table sampler from #665 clamps to the edge, and #941 already handles that. Please reopen when a title stops at the table border throw.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* docs needs rebase Conflicts with main, rebase needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AGC sampler: border colour table (BORDER_COLOR_TYPE 3) not implemented

2 participants