Implement native NGX feature-13 RR through a LUID-matched D3D12/Vulkan shared-memory and timeline-fence bridge. Add owned parameter snapshots, GPU resource lifetime handling, inherited/enhanced barriers, optional guides, sampled input formats and depth-plane support with stencil preservation. Separate RR initialization from the SR CUDA runtime and expose explicit backend/model selection through player configuration. Add synthetic bridge, snapshot and NGX lifecycle harnesses covering camera/history/reset, parameter mutation, delayed submission, early release, capability gating and unsupported-input rejection. Add exact gfx11 D/E model generation, verified caches, versioned local deployment with configuration backups, and isolated portable model tools with pinned Python, NumPy and glslang dependencies. Extend Windows K benchmarking and private native-cache selection. Fix LLVM 22 emitter/helper compatibility and preserve exact-output validation for local output-kernel optimization. Add native FSR RR provider diagnostics, local development package refresh tooling, installer/checker updates, FidelityFX headers and Windows parity documentation. Keep NVIDIA binaries, derived models and private optimized kernels out of distributable packages. Native RR evidence remains synthetic; game validation, FSR RR dispatch, installer integration and Linux performance parity remain incomplete.
73 lines
3.7 KiB
Python
73 lines
3.7 KiB
Python
"""Stamp or verify local RR build artifacts against sources, tools and DLL identity."""
|
|
import argparse
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
import sys
|
|
|
|
|
|
def sha(path):
|
|
return hashlib.sha256(path.read_bytes()).hexdigest()
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument('action', choices=('write', 'check'))
|
|
parser.add_argument('--model', type=Path, required=True)
|
|
parser.add_argument('--dll', type=Path, required=True)
|
|
parser.add_argument('--preset', choices=('D', 'E'), required=True)
|
|
parser.add_argument('--glslang', type=Path, required=True)
|
|
parser.add_argument('--bash', type=Path, required=True)
|
|
args = parser.parse_args()
|
|
repo = Path(__file__).resolve().parents[2]
|
|
model = args.model.resolve()
|
|
if not model.is_relative_to((repo / 'build').resolve()):
|
|
parser.error('model cache must stay under ignored build/')
|
|
import numpy
|
|
sources = {}
|
|
for directory in ('engine', 'vulkan', 'kernels/tools', 'scripts/windows'):
|
|
for path in sorted((repo / directory).rglob('*')):
|
|
if path.is_file() and path.suffix in ('.py', '.ps1', '.sh', '.comp', '.glsl', '.h', '.inc', '.txt'):
|
|
sources[path.relative_to(repo).as_posix()] = sha(path)
|
|
identity = dict(schema=1, preset=args.preset, architecture='gfx1101', arithmetic='exact-gfx11',
|
|
numpyVersion=numpy.__version__, sources=sources,
|
|
tools={name: sha(path) for name, path in (
|
|
('dll', args.dll), ('glslang', args.glslang),
|
|
('bash', args.bash), ('python', Path(sys.executable)))})
|
|
stamp = model / 'windows-rr-cache.json'
|
|
products = {path.name: sha(path) for path in sorted(model.iterdir())
|
|
if path.is_file() and path.name not in (stamp.name, stamp.name + '.tmp')}
|
|
for name in ('rr.txt', 'model.json', 'enc0_m.spv', 'dec0_m.spv', 'hkpn.spv', 'enc0.args', 'hkpn.args'):
|
|
if name not in products:
|
|
raise RuntimeError(f'incomplete model: {name}')
|
|
manifest = (model / 'rr.txt').read_text().splitlines()
|
|
if (not manifest or manifest[0] != 'D4RR0001' or
|
|
f'preset {4 if args.preset == "D" else 5}' not in manifest or
|
|
'arithmetic gfx11' not in manifest):
|
|
raise RuntimeError('RR manifest preset/arithmetic does not match requested cache identity')
|
|
stages = [line.split() for line in manifest if line.startswith('stage ')]
|
|
expected_stages = {'enc0', 'enc1', 'enc2', 'enc3', 'enc4', 'enc5',
|
|
'dec4', 'dec3', 'dec2', 'dec1', 'dec0', 'hkpn'}
|
|
if len(stages) != 12 or {fields[1] for fields in stages} != expected_stages:
|
|
raise RuntimeError('RR stage list is incomplete or duplicated')
|
|
for fields in stages:
|
|
for name in (fields[2], fields[4]):
|
|
if name != '-' and name not in products:
|
|
raise RuntimeError(f'RR stage artifact missing or outside model directory: {name}')
|
|
if args.action == 'check':
|
|
cached = json.loads(stamp.read_text())
|
|
if cached.get('identity') != identity:
|
|
raise RuntimeError('RR cache identity changed; use a new output directory to rebuild')
|
|
if cached.get('products') != products:
|
|
raise RuntimeError('RR cache artifacts changed; use a new output directory to rebuild')
|
|
print(f'RR_CACHE_HIT preset={args.preset} artifacts={len(products)} model={model}')
|
|
else:
|
|
temporary = stamp.with_name(stamp.name + '.tmp')
|
|
temporary.write_text(json.dumps(dict(identity=identity, products=products), indent=2) + '\n')
|
|
temporary.replace(stamp)
|
|
print(f'RR_CACHE_WRITTEN preset={args.preset} artifacts={len(products)} model={model}')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|