Add an experimental FSR Ray Regeneration backend for D3D12 RR requests: - Convert depth, motion, normals and albedos into AMD denoiser inputs. - Split and recompose diffuse/specular signals, then run Super Sampling. - Add stability/detail controls, demodulation guards and halo limiting. - Handle AMD provider discovery under NVIDIA GPU spoofing. - Add runtime probes, synthetic reference scenes and per-dispatch profiling. Add exact gfx11 DLSS-RR inference using f16 cooperative matrices: - Reproduce FP8 conversions, accumulation and camera reprojection arithmetic. - Widen model weights and avoid requiring VK_EXT_shader_float8. - Extend model building, replay tools and descriptor metadata. Expand motion preprocessing and experimental AW2 native-motion support: - Add tiled LDS dilation, padded allocation handling and thin-only sky fill. - Order dilation with input waits and NGX on the selected stream. - Add jitter-aligned native composition, hybrid routing and wire history repair. - Add prepared masks, sparse repair and independent motion/repair controls. Add optional fused R11G11B10 input/output conversion, sampled stage timings and profile summarization. Extend configuration, packaging, documentation, FidelityFX headers and CPU/GPU regression coverage.
73 lines
3.0 KiB
Python
73 lines
3.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Summarize warm D4R_PROFILE samples without merging feature instances or sizes.
|
|
|
|
GPU pass fields and delayed vk_* fields are summarized independently. Their
|
|
per-line difference is deliberately not calculated; they describe different frames.
|
|
"""
|
|
import argparse
|
|
from collections import defaultdict
|
|
import json
|
|
import math
|
|
from pathlib import Path
|
|
import re
|
|
import statistics
|
|
|
|
GROUP_FIELDS = ('render', 'output', 'preset', 'quality', 'flags', 'input_wait',
|
|
'feature', 'native_field', 'native_substitute', 'wire_requested', 'gpu_completion', 'vk_output_mode', 'vk_input_mode')
|
|
|
|
FIELDS = ('vk_total', 'dlss_gpu', 'vk_input', 'vk_dlss_wait', 'vk_output',
|
|
'native_motion_gpu', 'wire_repair_gpu', 'marker_wait', 'pipeline',
|
|
'throughput_interval')
|
|
|
|
|
|
def summarize(text, min_frame=300, since_clock=None, until_clock=None):
|
|
groups = defaultdict(list)
|
|
instance = 0
|
|
for line in text.splitlines():
|
|
if 'NVSDK_NGX_D3D12_CreateFeature(feature=' in line:
|
|
instance += 1
|
|
if 'D4R_PROFILE frame=' not in line:
|
|
continue
|
|
if since_clock is not None or until_clock is not None:
|
|
clock = re.search(r'^\[\s*([0-9.]+)\]', line)
|
|
if clock is None:
|
|
continue
|
|
seconds = float(clock[1])
|
|
if since_clock is not None and seconds < since_clock:
|
|
continue
|
|
if until_clock is not None and seconds > until_clock:
|
|
continue
|
|
values = dict(re.findall(r'(\w+)=([^\s]+)', line))
|
|
if int(values['frame']) < min_frame or values.get('reset') != '0':
|
|
continue
|
|
key = (instance, *(values.get(k, 'unknown') for k in
|
|
GROUP_FIELDS))
|
|
groups[key].append(values)
|
|
result = []
|
|
for key, samples in groups.items():
|
|
row = dict(zip(('feature_instance', *GROUP_FIELDS), key))
|
|
row.update(samples=len(samples), first_frame=int(samples[0]['frame']), last_frame=int(samples[-1]['frame']))
|
|
row['timings_ms'] = {}
|
|
for field in FIELDS:
|
|
values = [float(s.get(field, '-1')) for s in samples]
|
|
valid = [v for v in values if math.isfinite(v) and v >= 0]
|
|
row['timings_ms'][field] = (dict(n=len(valid), median=statistics.median(valid),
|
|
min=min(valid), max=max(valid)) if valid else None)
|
|
result.append(row)
|
|
return result
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument('log', type=Path)
|
|
parser.add_argument('--min-frame', type=int, default=300)
|
|
parser.add_argument('--since-clock', type=float, help='minimum bracketed log-clock seconds')
|
|
parser.add_argument('--until-clock', type=float, help='maximum bracketed log-clock seconds')
|
|
args = parser.parse_args()
|
|
print(json.dumps(summarize(args.log.read_text(errors='replace'), args.min_frame,
|
|
args.since_clock, args.until_clock), indent=2))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|