Repository navigation
fix(shader): read cube T#s through DIM 2D image_sample and image_load as face 0 - #5509
adriadam10 merged 3 commits into
Conversation
|
Windows test of #5509: Windows 10 (19045), MinGW-w64 GCC 15.2, Release, AI-assisted (Claude Code). |
|
Windows build check of #5509 (head AI-assisted (Claude Code). |
|
This no longer builds on main: |
* Metal semantics: run upstream image execution tests through the Metal driver The existing semantics shim binds only guest buffers. A second shim (tests/metal_semantics/driver_shim) runs the upstream execution tests that bind images, samplers and color targets through the native Metal driver: dispatches bind their descriptors with MetalShaderResources and draws go through MetalDraw::DrawSynchronously, as in a title. The tests' host arrays are the guest memory; the device borrows every range the shader's buffer and image descriptors and the color targets name. ImagePlaneAddressOnLine and ImageVolumeAddressOnPlane (already on main) now run on Metal and pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DgW4n3qYgi5jAAohEmXRQj * fix(shader): capture image descriptors read from constant buffers at uniform offsets Removes the tracker check that refused a T# whose dwords come from a ReadConstBuffer, so a T# loaded with s_buffer_load from a table record that user data selects is captured like any other runtime descriptor. Metal: tests/metal_semantics/ImageTableRecord.cpp runs the upstream program through the Metal driver (MetalShaderResources image binding) and checks that the record user data selects is the texture sampled. It fails on main with the removed "is not a valid runtime value" error. Ported from upstream PR boykopovar#5188 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DgW4n3qYgi5jAAohEmXRQj * fix(shader): accept TYPE=0 images during materialization A T# with TYPE=0 is null on AMD hardware even when its base and other words are nonzero; the materializer now accepts it as a null image instead of refusing it as invalid (reserved TYPE=1 is still refused). Upstream's frontend test is ported to tests/ShaderMemory.cpp. Metal: the Metal image binding already treats TYPE=0 as null (IsNullTextureResource), so such an image binds no texture. The Metal ImageTableRecord test now also samples a TYPE=0 record with a nonzero base and reads zero; on main it fails with "runtime image descriptor is invalid". Debt note added to docs/dev/TechnicalDebt.md. Ported from upstream PR boykopovar#5473 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DgW4n3qYgi5jAAohEmXRQj * fix(shader): read 1D T#s through 3D image_sample and image_load accesses A DIM 3D image_sample_lz, plain image_sample or mip-less image_load whose T# is 1D gets a runtime image mode that binds the 1D texture: the sample reads the texel u selects, and the load reads the x texel when z is 0 and zero otherwise, as measured on RDNA1. Other 3D accesses of such an image still throw. ImageResource gains flatVolumeLineCompatible, so the shader disk cache FormatVersion goes from 35 to 36. This is the only bump in this series: the later image-mode fields reuse it. Metal: the 1D mode binds through the existing Image1D shape (a 2D texture of height 1) with no new view. Upstream's ImageVolumeAddressOnLine execution test runs unchanged through the Metal driver (anyps5_metal_driver_semantics_imagevolumeaddressonline). It fails without the materializer hunk ("incompatible with the static runtime image interface"). Debt note added to docs/dev/TechnicalDebt.md. Ported from upstream PR boykopovar#5375 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DgW4n3qYgi5jAAohEmXRQj * fix(shader): sample single-level volumes through biased 2D accesses A pixel-stage, direct, plain 32-bit image_sample_b with DIM 2D whose T# is a one-slice, single-level 3D image gets the 3D runtime image mode: the sample supplies a zero third coordinate and keeps the bias, as measured on RDNA2. The binding requires a normalized point sampler and the descriptor one slice and mip zero; other cases throw. ImageResource gains singleMipPlaneBiasCompatible; it is encoded by the shader disk cache under the FormatVersion 36 bump of this series (upstream's own bump to 31 is not taken). Metal: the 3D mode binds the volume as the Image3D shape it already has, with no new view. Upstream's ImagePlaneBiasOnSingleLevelVolume execution test (a pixel draw) runs unchanged through MetalDraw (anyps5_metal_driver_semantics_imageplanebiasonsinglelevelvolume). It fails without the tracker hunk ("incompatible with the static runtime image interface"). Debt note added to docs/dev/TechnicalDebt.md. Ported from upstream PR boykopovar#5461 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DgW4n3qYgi5jAAohEmXRQj * fix(shader): decode forced degamma on biased RGBA8_UINT samples A direct RGBA8_UINT image sampled only by plain biased pixel accesses (the one-slice volume case of boykopovar#5461) through samplers that all set FORCE_DEGAMMA is materialized as RGBA8_SRGB, which returns the same decoded floats as the hardware. Mixed sampler states, indirect images, other accesses and formats still throw. Metal: MetalSampler refused every FORCE_DEGAMMA S#, so this (and the existing sRGB case of ImageSampleForceDegamma) could not bind. Metal now does what the Vulkan driver does: MetalShaderResources::Bindings creates the sampler with forceDegammaPaired and refuses a sampled image of a non-sRGB format paired with a forcing sampler (the same message as RequireDegammaFormat). The rewritten descriptor binds through the existing sRGB pixel-format view. Upstream's extended ImagePlaneBiasOnSingleLevelVolume and the existing ImageSampleForceDegamma tests now pass on Metal; both failed with "forces sRGB decoding which is not implemented". Debt note added to docs/dev/TechnicalDebt.md. Ported from upstream PR boykopovar#5472 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DgW4n3qYgi5jAAohEmXRQj * fix(shader): read cube T#s through DIM 2D image_sample and image_load as face 0 A DIM 2D image_sample_lz, plain image_sample, image_sample_l or mip-less image_load whose T# is a cube gets the cube runtime image mode and reads the T#'s BASE_ARRAY face with face coordinate 0, as measured on RDNA1. Other DIM 2D accesses through a cube T# still throw. ImageResource gains cubeFaceCompatible; encoded under the series' FormatVersion 36 bump. Metal: a cube T# is already a 2D-array texture of faces and the cube mode binds the Image2DArray shape, so no new view is needed. Upstream's ImagePlaneAddressOnCube execution test runs unchanged through the Metal driver (anyps5_metal_driver_semantics_imageplaneaddressoncube) and fails without the materializer hunk. Debt note added to docs/dev/TechnicalDebt.md. Ported from upstream PR boykopovar#5509 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DgW4n3qYgi5jAAohEmXRQj * fix(shader): compare through 2D image_sample_c on 1D T#s The flat-line (2D access through a 1D T#) compatibility now ignores the compare flag, so image_sample_c and image_sample_c_lz with DIM 2D on a 1D T# take the 1D mode like their non-compare forms. Metal: the 1D mode binds through the existing Image1D shape (a 2D texture of height 1), with no new view. Upstream's ImagePlaneCompareOnLine execution test runs unchanged through the Metal driver (anyps5_metal_driver_semantics_imageplanecompareonline) and fails without the tracker hunk. The debt note in docs/dev/TechnicalDebt.md is updated as upstream's. Ported from upstream PR boykopovar#5456 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DgW4n3qYgi5jAAohEmXRQj * fix(shader): apply the V# DST_SEL to formatted buffer stores buffer_store_format_* (D16 included) wrote memory component i from data VGPR i whatever the V#'s DST_SEL. A formatted store now writes each format component from the slot its selector names, only for the DST_SELs measured on RDNA2 or covered by conformance tests: the identity, Z,Y,X,W on 8_8_8_8_UNORM and 16_16_16_16_UINT, and 0,0,0,X on 8_UNORM and 8_UINT. Every other DST_SEL on a formatted store is refused: a host V# throws in DescriptorBindingBuilder::Prepare, and a GPU-selected V# records an invalid-descriptor BDA fault and skips the store. BufferResource gains formattedWritten; encoded under the series' FormatVersion 36 bump. Metal: the store is lowered in the shared SPIR-V (SpirvRuntimeBuffer), so no Metal binding change. Upstream's BufferStoreFormatDstSel execution test runs unchanged through the Metal driver (anyps5_metal_driver_semantics_bufferstoreformatdstsel). Without the SpirvRuntimeBuffer hunk it fails (Z,Y,X,W on 8_8_8_8_UNORM writes 0x4033bfff, expected 0x40ffbf33). Debt note added to docs/dev/TechnicalDebt.md. Ported from upstream PR boykopovar#5172 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DgW4n3qYgi5jAAohEmXRQj --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
da58289 to
ab8f319
Compare
|
Rebased on main. |
ab8f319 to
37c8994
Compare
… as face 0 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
37c8994 to
1df5ae9
Compare
|
Checked on the HW oracle (gfx1035, IEEE off): on 8x8 32_FLOAT cubes ( What we added on your branch:
Merging once the full Build is green. |
|
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.
|
|
Checked on the HW oracle (gfx1035, IEEE off): on 8x8 32_FLOAT cubes ( What we added on your branch:
Merging once the full Build is green. |
What
Before: a DIM 2D
image_sampleorimage_loadbound to a cube T# had no runtime image mode. The draw threw "image descriptor is incompatible with the static runtime image interface ... {class 1, dim 5, ..., cube 1, ...}". This is shape 2 of #4139: High on Life (PPSA15388) samples a 32x32 cube placeholder throughdim:SQ_RSRC_IMG_2D.After: these accesses get a cube mode, the one DIM CUBE accesses already use, with face coordinate 0. Sampling sees the
BASE_ARRAYface of the cube's 2D-array view at (u - 1, v - 1). A load reads texel (x, y) of that face. The mode is offered only when every access isimage_sample_lz, plainimage_sample,image_sample_lor a mip-lessimage_load; other DIM 2D accesses on a cube T# still throw. Shape 1 of #4139 (a non-image descriptor in an image slot) is not addressed here.Hardware semantics, measured on RDNA1 (gfx1010, AMD Radeon RX 5700 XT) with the
tools/hw-oracletemplate. The kernels were assembled with the Windows driver'samd_comgr_2.dlland launched with its HIP runtime. The cubes were 8x8 and 32x32 32_FLOAT, withDEPTH5 and 11 andBASE_ARRAY0 and 6, and every texel holds its own word index.image_sample_lzequals DIM CUBEimage_sample_lzwith face coordinate 0 on every row. That covers point and bilinear filters, wrap, clamp and mirror addressing,DISABLE_CUBE_WRAP0 and 1, and coordinates from -1 to 4. The same holds for plainimage_sample(one level, and six levels in 2x2 compute quads with steps of 1-32 texels) andimage_sample_l(the third address VGPR is the LOD, integer and fractional). Explicit LOD matched 24/24 rows and implicit LOD 24/24.BASE_ARRAYface.floor((u - 1) * width).image_loadreads texel (x, y) of theBASE_ARRAYface, the same word as a DIM 2D load on a 2D T# for base 0.The measurement write-up is attached.
measurement-results-cube-2d-gfx1010.md
Outside the face the translation follows the DIM CUBE path and samples the 2D-array view with the S# addressing. That matches the hardware only inside [1, 2). On the hardware:
DISABLE_CUBE_WRAPsetting measured;DISABLE_CUBE_WRAP0, a coordinate of 2 or more clamps to the last texel (point filter), and bilinear filtering blends texels of the neighbouring faces at the edges;DISABLE_CUBE_WRAP1, a coordinate of 2 or more follows the S# addressing.This is recorded in technical debt, together with the accesses that still throw.
Tested
agc_driver_image_plane_address_on_cuberuns DIM 2Dimage_sample_lz,image_sample_l, plainimage_sampleandimage_loadon an 8x8 32_FLOAT cube (six faces) over 32 lanes. The same kernel semantics ran on the RX 5700 XT through the oracle, and its expected values matched all 32 lanes. The test passes. Without the change it fails with the error above.ctest -R "image_|shader_memory|disk_cache|runtime_images|cube|sampl|emulated_color_compare": no test fails that does not also fail on unchangedmain(dacd785) on this machine.python3 tools/check_conventions.py --base origin/mainpasses.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)