Advance native Windows RR integration, kernel tooling and local packaging
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.
This commit is contained in:
1 parent
3345fffcd3
commit
247fe1092d
60 files changed
+7168
-66
No files matched your search
@@ -0,0 +1,125 @@
|
||||
"""Prepare a private portable RR model-tool bundle from pinned dependencies.
|
||||
|
||||
Downloads/extracts tools locally. Does not install Python, use pip, modify PATH,
|
||||
change policy, build a model, or install into a game.
|
||||
"""
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path, PurePosixPath
|
||||
import shutil
|
||||
import subprocess
|
||||
import urllib.request
|
||||
import uuid
|
||||
import zipfile
|
||||
|
||||
|
||||
DEPENDENCIES = {
|
||||
'python-3.12.10-embed-amd64.zip': (
|
||||
'https://www.python.org/ftp/python/3.12.10/python-3.12.10-embed-amd64.zip',
|
||||
'4acbed6dd1c744b0376e3b1cf57ce906f9dc9e95e68824584c8099a63025a3c3'),
|
||||
'numpy-2.4.6-cp312-cp312-win_amd64.whl': (
|
||||
'https://files.pythonhosted.org/packages/ab/ca/feab00bd44aa5fe1ad2c18f08b4d3bb92e26484b0b1d1443897809ed528c/numpy-2.4.6-cp312-cp312-win_amd64.whl',
|
||||
'd8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751'),
|
||||
'glslang-16.6.0-windows-x86_64-release.zip': (
|
||||
'https://github.com/KhronosGroup/glslang/releases/download/16.6.0/glslang-16.6.0-windows-x86_64-release.zip',
|
||||
'82bf434e69b9bb4829de7e2b4bc2c5e7a7861e53d66cf75e5cc70f5f694a8d9b'),
|
||||
'glslang-16.6.0-LICENSE.txt': (
|
||||
'https://raw.githubusercontent.com/KhronosGroup/glslang/16.6.0/LICENSE.txt',
|
||||
'17e70c676e1521ff3e4686f04a2053d93a7e28a33be8de7ec37ab0ff72feb677'),
|
||||
}
|
||||
|
||||
|
||||
def sha(path):
|
||||
with path.open('rb') as stream:
|
||||
return hashlib.file_digest(stream, 'sha256').hexdigest()
|
||||
|
||||
|
||||
def extract(archive, destination):
|
||||
with zipfile.ZipFile(archive) as source:
|
||||
for entry in source.infolist():
|
||||
name = PurePosixPath(entry.filename)
|
||||
if name.is_absolute() or '..' in name.parts or '\\' in entry.filename or ':' in entry.filename:
|
||||
raise RuntimeError('Unsafe dependency archive path')
|
||||
if entry.is_dir():
|
||||
continue
|
||||
target = destination.joinpath(*name.parts)
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
with source.open(entry) as data, target.open('xb') as out:
|
||||
shutil.copyfileobj(data, out)
|
||||
|
||||
|
||||
def main():
|
||||
repo = Path(__file__).resolve().parents[2]
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--output', required=True, type=lambda p: Path(p).resolve())
|
||||
parser.add_argument('--archive', type=lambda p: Path(p).resolve(), help='optional clean portable-tools ZIP, before any model build')
|
||||
parser.add_argument('--download-cache', type=lambda p: Path(p).resolve(), default=repo / '.tools/downloads')
|
||||
args = parser.parse_args()
|
||||
if args.output.exists() or not args.output.is_relative_to((repo / 'build').resolve()):
|
||||
parser.error('use a fresh output directory under ignored build/')
|
||||
if args.archive and (args.archive.exists() or not args.archive.is_relative_to((repo / 'build').resolve()) or args.archive.is_relative_to(args.output)):
|
||||
parser.error('use a fresh archive under build/, outside the bundle directory')
|
||||
args.download_cache.mkdir(parents=True, exist_ok=True)
|
||||
for name, (url, expected) in DEPENDENCIES.items():
|
||||
path = args.download_cache / name
|
||||
if not path.exists():
|
||||
print('RR_TOOLS_DOWNLOAD ' + name, flush=True)
|
||||
temporary = path.with_name(name + '.part-' + uuid.uuid4().hex)
|
||||
with urllib.request.urlopen(url, timeout=60) as response, temporary.open('xb') as out:
|
||||
shutil.copyfileobj(response, out)
|
||||
if sha(temporary) != expected:
|
||||
raise RuntimeError('Dependency download hash mismatch: ' + name)
|
||||
temporary.rename(path)
|
||||
if sha(path) != expected:
|
||||
raise RuntimeError('Cached dependency changed: ' + name)
|
||||
python = args.output / 'python'
|
||||
recipe = args.output / 'recipe'
|
||||
extract(args.download_cache / 'python-3.12.10-embed-amd64.zip', python)
|
||||
extract(args.download_cache / 'numpy-2.4.6-cp312-cp312-win_amd64.whl', recipe / '.tools/python/vendor')
|
||||
glslang = recipe / '.tools/glslang-16.6.0'
|
||||
extract(args.download_cache / 'glslang-16.6.0-windows-x86_64-release.zip', glslang)
|
||||
shutil.copy2(glslang / 'bin/glslang.exe', glslang / 'bin/glslangValidator.exe')
|
||||
if sha(glslang / 'bin/glslangValidator.exe') != '9643709c02c83e26773f96b6a87f197ab2e84f78be0879ad8fb3619418b5d9ad':
|
||||
raise RuntimeError('Extracted glslang identity mismatch')
|
||||
files = subprocess.check_output(['git', 'ls-files', '-z', 'engine', 'vulkan', 'kernels/tools'], cwd=repo).decode().split('\0')
|
||||
suffixes = {'.py', '.comp', '.glsl', '.h', '.inc', '.sh'}
|
||||
sources = [repo / name for name in files if name and Path(name).suffix in suffixes]
|
||||
sources += [repo / 'engine/rr/native_kernels.txt', repo / 'tools/windows/build_rr_model.py', repo / 'tools/windows/deploy_rr_model.py', repo / 'LICENSE']
|
||||
for source in sources:
|
||||
target = recipe / source.relative_to(repo)
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copy2(source, target)
|
||||
# Keep isolated imports: no user site-packages or PYTHONPATH dependence.
|
||||
paths = ['python312.zip', '.', '../recipe', '../recipe/engine', '../recipe/engine/rr',
|
||||
'../recipe/kernels/tools', '../recipe/vulkan', '../recipe/tools/windows', '../recipe/.tools/python/vendor']
|
||||
(python / 'python312._pth').write_text('\n'.join(paths) + '\n')
|
||||
licenses = args.output / 'licenses'
|
||||
licenses.mkdir()
|
||||
shutil.copy2(args.download_cache / 'glslang-16.6.0-LICENSE.txt', licenses / 'glslang-LICENSE.txt')
|
||||
shutil.copy2(python / 'LICENSE.txt', licenses / 'Python-LICENSE.txt')
|
||||
for source in (recipe / '.tools/python/vendor/numpy-2.4.6.dist-info').glob('licenses/*'):
|
||||
if source.is_file():
|
||||
shutil.copy2(source, licenses / ('numpy-' + source.name))
|
||||
manifest = {'kind': 'local-rr-model-tools', 'dependencies': {name: {'url': url, 'sha256': digest}
|
||||
for name, (url, digest) in DEPENDENCIES.items()}, 'sourceWorkingTree': 'local modified; file hashes authoritative',
|
||||
'files': {path.relative_to(args.output).as_posix(): sha(path) for path in sorted(args.output.rglob('*')) if path.is_file()},
|
||||
'modelsBundled': False, 'nvidiaBinariesBundled': False}
|
||||
(args.output / 'rr-tools.json').write_text(json.dumps(manifest, indent=2) + '\n')
|
||||
if args.archive:
|
||||
args.archive.parent.mkdir(parents=True, exist_ok=True)
|
||||
# Package only the recorded pristine tool inputs. Never sweep a used
|
||||
# bundle's model-build directory into a distributable archive.
|
||||
with zipfile.ZipFile(args.archive, 'x', zipfile.ZIP_DEFLATED, compresslevel=6) as archive:
|
||||
for name in (*manifest['files'], 'rr-tools.json'):
|
||||
archive.write(args.output / name, name)
|
||||
with zipfile.ZipFile(args.archive) as archive:
|
||||
for name, expected in manifest['files'].items():
|
||||
if hashlib.sha256(archive.read(name)).hexdigest() != expected:
|
||||
raise RuntimeError('Portable-tools ZIP hash mismatch: ' + name)
|
||||
print('RR_TOOLS_ARCHIVE sha256=' + sha(args.archive) + ' bytes=' + str(args.archive.stat().st_size))
|
||||
print('RR_TOOLS_READY ' + str(args.output))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in new issue
Block a user