Files
nxnative-easy/dm/gfx/tests/test_imga_binding_source.py
T
seeddsandb4f8abbb24dbf56a7d0280f296e16eeb c3a0880304 Guard Metal image atomics and reject unsupported bindings
Apply the generalized image-atomic bounds and backing checks from PR #178.
Also reject unsupported descriptor formats before integer fallback and fail
unresolved bindless atomics instead of silently deleting them. Rebuild the
translator and record chain 467efdfd0b62, with regression tests and findings.

Validation: compiler/helper and sanitizer tests, 96 Metal compile/link checks,
ten GPU probes, all 28,603 Z-A shaders for Mac and iPhone, and a 240-second
Mac station-area run reaching 6,987 frames without a freeze or GPU fault.
Reported iPhone cases and the station-to-world transition remain unverified.

Co-authored-by: b4f8abbb24dbf56a7d0280f296e16eeb <51352400+b4f8abbb24dbf56a7d0280f296e16eeb@users.noreply.github.com>
2026-10-25 23:37:28 +08:00

36 lines
1.7 KiB
Python

"""Narrow production wiring checks, not a native Metal execution fixture."""
from pathlib import Path
import unittest
SOURCE = (Path(__file__).resolve().parents[1] / "nvn/nvn_mtl.m").read_text()
class BindingWiring(unittest.TestCase):
def test_failed_scratch_never_falls_back_to_dummy(self):
branch = SOURCE.split('storage = atom_scratch(tt, need);', 1)[1].split('} else {', 1)[0]
self.assertIn('!storage || !gpu || !nvn_imga_capacity', branch)
self.assertIn('MDIE(', branch)
self.assertIn('refusing short dummy', branch)
self.assertNotIn('dummy_buf', branch)
def test_actual_image_is_shared_by_pair(self):
self.assertIn('atomic_img[r] = img_binding(tid, ib,', SOURCE)
self.assertIn('atomic_desc[reg] ? atomic_img[reg]', SOURCE)
self.assertIn('id<MTLTexture> image = atomic_img[reg]', SOURCE)
self.assertIn('missing IMG partner', SOURCE)
self.assertIn('ambiguous IMG partner', SOURCE)
def test_direct_path_checks_actual_backing(self):
branch = SOURCE.split('if (linear) {', 1)[1].split('} else if (tt) {', 1)[0]
for token in ('image.buffer == storage', 'image.bufferOffset', 'image.bufferBytesPerRow',
'!image.parentTexture', 'nvn_imga_direct_ok(&d)', 'MDIE('):
self.assertIn(token, branch)
self.assertNotIn('atom_scratch', branch)
self.assertNotIn('dummy_buf', branch)
def test_rejection_precedes_argument_publication(self):
body = SOURCE.split('static int encode_args_(id<MTLCommandEncoder> en, NvShader *sh, int nvn_stage, int metal_vertex) {', 1)[1]
self.assertLess(body.index('refusing short dummy'), body.index('memcpy((uint8_t *)ab.contents'))
if __name__ == '__main__':
unittest.main()