Repository navigation
fix(shader): keep cube image gradients out of the face coordinate bias - #4209
Conversation
|
For the record, from @fma-rc's census of the shaders nine titles submit (https://github.com/fma-rc/AnyPS5/tree/evidence/shader-census: 749 shaders, 301,896 instructions; see #4061): there is no It stays a correctness fix for titles that sample cubes with explicit gradients. The new test shows what they get on |
image_sample_d and image_sample_cd on a cube pass their gradients through the same conversion as the face coordinates, which subtracts 1.0 to move AMD's [1, 2] face range to [0, 1]. A gradient is a difference of coordinates, so the bias turned a one-texel gradient into one of about -1 and the sample read the smallest mip. Gradients now skip the bias. agc_driver_image_sample_cube_derivatives samples every face of a 16x16 cube at five levels through image_sample_d and checks the level and face it read. TechnicalDebt records that the gradient handling follows Mesa and was not measured on hardware.
…radients Co-Authored-By: Claude <noreply@anthropic.com>
|
Measured on RDNA2 (gfx1035) with the hardware oracle: on a 16x16, five-level cube, the level What we added on your branch:
Merging once the full build is green. |
d1dc1aa to
3973e5a
Compare
What
image_sample_dandimage_sample_cdon a cube image now pass their gradients to the host sample unchanged. Before, the gradients were run through the coordinate conversion and lost 1.0 on each axis, so the sample read the smallest mip whatever the gradient.Background. Cubes are bound as 2D arrays.
CoordF32maps AMD's cube face coordinates from their [1, 2] range to [0, 1] by subtracting 1.0 from x and y (CubeAxis). The derivative path builds the gradient operands with the same function (SpirvImageEmitter.cpp, theRdnaImageSampleFlagDerivativebranch of the sample emitter), so a cube's gradients were biased too. A gradient is a difference of coordinates, so the bias doesn't belong there. A gradient of one texel, 1/16 on a 16×16 face, became about -0.94, and the LOD came out near the last level.Source. Mesa's AMD texture lowering,
src/amd/common/nir/ac_nir_lower_tex_coords.c,prepare_cube_coords:deriv_sc * invma - deriv_ma * sc, and the same fortc.sc + 1.5,tc + 1.5), never to the derivatives.So the hardware takes unbiased face-space gradients next to [1, 2] coordinates.
How.
CoordF32takes agradientflag, and the two gradient operands pass it, which skipsCubeAxis. Coordinates,image_get_lodand every non-cube image are unchanged.Tested
Windows 11, MinGW-w64 GCC 15.2.0, Release. Devices:
GALLIUM_OVERRIDE_CPU_CAPS=avx.This round's four changes were built and tested together on
mainat bca7a29 (cube image gradients, early depth tests, bindless table search, LDS fence; one pull request each, in unrelated code). The branch is rebased onto 34ba918. Its two new commits touch onlyGuestMemory.cppand thePreparedShaders.cppfixture.agc_driver_image_sample_cube_derivatives:image_sample_d. One gradient is set to 2^(level - 0.25) texels to select levels 0 to 4, the others are 0.image_sample_d cube: thread 0 (face 0, level 0) component 0 is 4.000000, expected 0. Every level-0 to level-3 sample read the last level.agc_driver_image_sample_derivatives,agc_driver_emulated_color_compareandagc_driver_image_sample_lod_clamppass. The last is skipped on the Intel UHD, which has noshaderResourceMinLod.agc_driver_*,agc_shader_*,agc_spirv_*,vector_*,agc_masked_select,agc_validate_program,agc_denormal*,agc_float16_*; 338 tests):agc_driver_prepared_shaders_registered_workgroup_sync, which fails the same way onmainat bca7a29 (fixed since by test(agc): read lane 63 of the vertex index in the registered workgroup fixture #4177). I left out the BDA tests that lose the device on driver 591.86 (Recompiler: NVIDIA hangs (device lost) when read_bda_span lanes split between in-place loads and the fallback; branch and commit ready #3291):agc_driver_flat_loads*,agc_driver_global_loads*,agc_driver_flat_apertures*,agc_driver_pixel_interlock.main:agc_driver_ds_swizzle,agc_driver_f32_dot2_roundingandagc_driver_prepared_shaders_registered_workgroup_sync. Also,agc_driver_compute_user_data_calls_registeredexited with 0xc0000374 once under the suite's load, then passed three runs on its own.agc_driver_prepared_shaders_registered_workgroup_sync, as onmain.Limits.
TechnicalDebt.mdrecords that.image_sample_d.image_sample_cdtakes the same gradient path.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt.mdfiles or images added to the repository (attach them to this PR)