mirror of
https://github.com/lucannez64/darling-lol.git
synced 2026-10-27 19:54:38 +00:00
From #61, without the default "AMD Radeon Pro 5500M" / 4 GB identity: the host GPU's name and Vulkan working set stay the default for every app, and the existing DARLING_METAL_GPU_NAME and DARLING_METAL_VRAM_MB overrides remain the opt-in. Reporting 4 GB on a 2 GB card invites allocation failures, and under-reports larger cards. Kept from #61: - registryID returns MTLDeviceInfo::kDefaultRegistryID instead of 0; a real Mac never reports 0 and apps key devices by it. - Vertex buffer layout and attribute arrays release the old item after retiring it; the retire step read the item after the release could free it. - newDepthStencilState, newSamplerState and the device name return nil (or the fallback name) when Indium throws, instead of unwinding through Objective-C. - MTLDepthStencilGetIndium is declared only with DARLING_METAL_ENABLED. - The replaceRegion trace probes at most `width` bytes, which stays inside the first row for every pixel format. metal.patch is regenerated in its existing file order, so the diff is these changes only. tests/test_metal_device_info.py compiles the host check against MTLDeviceInfo.h as shipped in the patch and runs in CI. Split from #61. Co-authored-by: DevWebeloper <[email protected]> Co-Authored-By: Claude Opus 5.5 <[email protected]>
47 lines
2.1 KiB
Python
47 lines
2.1 KiB
Python
"""Compile tools/test-metal-device-info.cpp against MTLDeviceInfo.h as shipped in patches/metal.patch."""
|
|
from pathlib import Path
|
|
import re
|
|
import shutil
|
|
import subprocess
|
|
import tempfile
|
|
import unittest
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
HEADER = 'private-include/Metal/MTLDeviceInfo.h'
|
|
|
|
|
|
def header_from_patch():
|
|
"""MTLDeviceInfo.h is a new file in the patch, so its text is the section's added lines."""
|
|
patch = (ROOT / 'patches/metal.patch').read_text()
|
|
section = re.search(r'(?ms)^diff --git a/%s b/%s\n.*?^@@ [^\n]*\n(.*?)(?=^diff --git |\Z)' % (HEADER, HEADER), patch)
|
|
if not section:
|
|
raise AssertionError(HEADER + ' is not a new file in patches/metal.patch')
|
|
lines = section.group(1).splitlines(keepends=True)
|
|
if not all(line.startswith('+') for line in lines):
|
|
raise AssertionError(HEADER + ' section has context or removed lines')
|
|
return ''.join(line[1:] for line in lines)
|
|
|
|
|
|
class MetalDeviceInfoTests(unittest.TestCase):
|
|
def test_host_check_passes(self):
|
|
compiler = shutil.which('c++')
|
|
if not compiler:
|
|
self.skipTest('no C++ compiler')
|
|
with tempfile.TemporaryDirectory() as folder:
|
|
include = Path(folder) / 'include/Metal'
|
|
include.mkdir(parents=True)
|
|
(include / 'MTLDeviceInfo.h').write_text(header_from_patch())
|
|
binary = Path(folder) / 'test-metal-device-info'
|
|
build = subprocess.run([compiler, '-std=c++17', '-Wall', '-Werror', '-I', str(include.parent),
|
|
str(ROOT / 'tools/test-metal-device-info.cpp'), '-o', str(binary)],
|
|
capture_output=True, text=True)
|
|
self.assertEqual(build.returncode, 0, build.stderr)
|
|
result = subprocess.run([str(binary)], capture_output=True, text=True, timeout=30)
|
|
self.assertEqual(result.returncode, 0, result.stdout)
|
|
self.assertIn('METAL_DEVICE_INFO failures=0 pass=1', result.stdout)
|
|
self.assertIn('PASS registry ID is non-zero', result.stdout)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|