Measure Windows submission costs and validate faster private K output stores

This commit is contained in:
Codex committed 2026-10-01 19:54:41 +03:00
1 parent d556747bad
commit 73ee2e5ecc
14 files changed
+453 -24

No files matched your search

+15
View File
@@ -0,0 +1,15 @@
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)][string]$DlssDll,
[string]$Kernel = 'hiluma_engine_output_depthinv_mvlo_hdr_max_v2_rel',
[string]$HipRoot = 'C:\Program Files\AMD\ROCm\7.2',
[string]$ZludaRoot,
[string]$OutputDirectory
)
$ErrorActionPreference='Stop'
$repo=[IO.Path]::GetFullPath((Join-Path $PSScriptRoot '../..'))
if (!$ZludaRoot) { $ZludaRoot=Join-Path $repo 'dist/zluda-windows-profile' }
if (!$OutputDirectory) { $OutputDirectory=Join-Path $repo 'build/private-textures-gfx1201' }
& python (Join-Path $repo 'tools/windows/build_native_texture.py') --dlss-dll $DlssDll --hip-root $HipRoot `
--zluda-root $ZludaRoot --kernel $Kernel --output-directory $OutputDirectory
if ($LASTEXITCODE) { throw "Native texture build failed ($LASTEXITCODE); inspect the output work directory." }
+1 -1
View File
@@ -6,7 +6,7 @@ param(
$ErrorActionPreference = 'Stop'
$repo = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot '../..'))
$defaults = @{PackageRoot='dist/windows-rdna4-game'; DiagnosticRoot='dist/windows-rdna4-command-list';
OptiScalerRoot='dist/optiscaler-windows-d4r'; ZludaRoot='dist/zluda-windows-f16-reference';
OptiScalerRoot='dist/optiscaler-windows-d4r'; ZludaRoot='dist/zluda-windows-profile';
HipRoot='.tools/therock-10.2.0a20260929/_rocm_sdk_core';
KernelKRoot='build/native-k-gfx1201'; KernelMRoot='build/native-m-gfx1201'}
foreach ($name in $defaults.Keys) {
+52
View File
@@ -0,0 +1,52 @@
[CmdletBinding()]
param([string]$TextureRoot, [string]$OutputDirectory, [int]$Iterations=8, [string]$OutputResolution='512x288')
$ErrorActionPreference='Stop'
$repo=[IO.Path]::GetFullPath((Join-Path $PSScriptRoot '../..'))
if (!$TextureRoot) { $TextureRoot=Join-Path $repo 'build/private-textures-gfx1201' }
if (!$OutputDirectory) { $OutputDirectory=Join-Path $repo 'test-results/k-native-texture-reference' }
if ($OutputResolution -notmatch '^([0-9]+)x([0-9]+)$') { throw 'OutputResolution must be WIDTHxHEIGHT.' }
$outputWidth=[int]$Matches[1]; $outputHeight=[int]$Matches[2]
$combined=Join-Path $OutputDirectory 'private-native'
New-Item -ItemType Directory -Force $combined | Out-Null
foreach ($directory in @((Join-Path $repo 'build/native-k-gfx1201'),$TextureRoot)) {
Get-ChildItem -LiteralPath $directory -Filter '*.hsaco' | Copy-Item -Destination $combined -Force
}
& python (Join-Path $repo 'kernels/tools/kernel_manifest.py') $combined (Join-Path $repo 'nvngx_dlss.dll')
if ($LASTEXITCODE) { throw 'Combined private manifest failed.' }
$settings=@{D4R_VALIDATE_OUTPUT='1'; D4R_PROFILE_STAGES='1'; D4R_ZLUDA_PROFILE='1'; D4R_QUIET_API='1';
ZLUDA_CACHE_DIR=(Join-Path $repo 'build/zluda-cache-windows'); PYTHONPATH=(Join-Path $repo '.tools/python/vendor');
D4R_ZLUDA_NATIVE_DIR=$null}
$old=@{}
try {
foreach ($key in $settings.Keys) { $old[$key]=[Environment]::GetEnvironmentVariable($key,'Process'); [Environment]::SetEnvironmentVariable($key,$settings[$key],'Process') }
foreach ($flags in @(0,11)) {
foreach ($mode in @('control','candidate')) {
$env:D4R_ZLUDA_NATIVE_DIR=if ($mode -eq 'control') { Join-Path $repo 'build/native-k-gfx1201' } else { $combined }
$arguments=@{RuntimeProfile='therock'; ZludaRoot=(Join-Path $repo 'dist/zluda-windows-profile');
PackageRoot=(Join-Path $repo 'dist/windows-rdna4-command-list'); NgxCore=(Join-Path $repo '_nvngx.dll');
DlssDll=(Join-Path $repo 'nvngx_dlss.dll'); NgxMode='d3d12'; NgxAbi='project-legacy'; Preset=11;
NgxCreateFlags=$flags; NgxOutputResolution=$OutputResolution; NgxOnly=$true; RequireNativeNetwork=$true; CommandListBackend=$true;
PixelProfile='depth-stencil'; BarrierMode='inherited-legacy'; CaptureExceptions=$true; EarlyIndirectProbe=$true;
Iterations=$Iterations; TimeoutSeconds=300; OptiScalerDll=(Join-Path $repo 'dist/optiscaler-windows-d4r/OptiScaler.dll');
OutputDirectory=(Join-Path $OutputDirectory "$mode-$flags")}
& (Join-Path $PSScriptRoot 'test-windows-rdna4.ps1') @arguments
if ($LASTEXITCODE) { throw "Texture $mode flags=$flags workload failed." }
& python (Join-Path $repo 'tools/windows/profile_report.py') $arguments.OutputDirectory --output (Join-Path $arguments.OutputDirectory 'profile.json')
if ($LASTEXITCODE) { throw 'Texture profile report failed.' }
}
$control=Join-Path $OutputDirectory "control-$flags"; $candidate=Join-Path $OutputDirectory "candidate-$flags"
$kernel=if ($flags -eq 11) { 'hiluma_engine_output_depthinv_mvlo_hdr_max_v2_rel' } else { 'hiluma_engine_output_depthreg_mvhi_ldr_max_v2_rel' }
$stderr=Get-Content -LiteralPath (Join-Path $candidate 'd3d12-evaluate-preset-11.stderr.log') -Raw
$hits=[regex]::Matches($stderr, ('\[d4r-launch\] kernel="' + $kernel + '" backend=native')).Count
if ($hits -ne $Iterations) { throw "Texture override was not executed on every frame: $kernel hits=$hits" }
& python (Join-Path $repo 'tools/windows/frame_compare.py') --reference $control --actual $candidate --width $outputWidth --height $outputHeight --exact
if ($LASTEXITCODE) { throw "Texture flags=$flags full-frame RGB mismatch; preserve baseline." }
}
@{passed=$true; architecture='gfx1201'; framesPerVariant=$Iterations; outputResolution=$OutputResolution; createFlags=@(0,11); strictRgb=$true;
manifestSha256=(Get-FileHash -LiteralPath (Join-Path $TextureRoot 'd4r-kernels.txt') -Algorithm SHA256).Hash.ToLowerInvariant();
privateNvidiaDerivedCode=$true; source=(Get-Content -LiteralPath (Join-Path $TextureRoot 'build-info.json') -Raw | ConvertFrom-Json)} |
ConvertTo-Json -Depth 12 | Set-Content -LiteralPath (Join-Path $TextureRoot 'validation.json') -Encoding UTF8
Write-Host "PASS: both private K output variants executed and matched every RGB component. $OutputDirectory"
} finally {
foreach ($key in $old.Keys) { [Environment]::SetEnvironmentVariable($key,$old[$key],'Process') }
}
+12 -2
View File
@@ -11,6 +11,8 @@ param(
[ValidateSet('driver','sdk','project','project-legacy')][string]$NgxAbi = 'driver',
[string]$OptiScalerDll,
[ValidateSet(5, 11, 13)][int]$Preset = 11,
[ValidateSet(0,11)][int]$NgxCreateFlags = 0,
[string]$NgxOutputResolution = '512x288',
[switch]$NgxOnly,
[switch]$Trace,
[switch]$RequireNativeNetwork,
@@ -311,7 +313,8 @@ DisableSplash=true
$summary.optiScaler = @{path=$OptiScalerDll; mode='standalone'; preset=$Preset}
$ngxArguments += @('--ngx-frontend', 'optiscaler')
}
$ngxArguments += @('--module', $localShim, '--pixel-profile', $PixelProfile, '--barrier-mode', $BarrierMode)
$ngxArguments += @('--module', $localShim, '--pixel-profile', $PixelProfile, '--barrier-mode', $BarrierMode,
'--ngx-create-flags', "$NgxCreateFlags", '--ngx-output-resolution', $NgxOutputResolution)
if ($EarlyIndirectProbe) {
if (!$CommandListBackend) { throw '-EarlyIndirectProbe requires -CommandListBackend' }
$ngxArguments += @('--early-indirect', '1')
@@ -366,7 +369,14 @@ DisableSplash=true
[IO.Path]::GetFileName($resolvedRuntime) -notmatch '^d4r-ngx-[0-9a-f]{32}$') {
throw 'Refusing to remove a path outside the private NGX temporary runtime.'
}
Remove-Item -LiteralPath $resolvedRuntime -Recurse -Force
# A scanner can briefly hold the just-unloaded DLL open. Cleanup must
# not skip environment restoration or discard the completed GPU logs.
$cleanupError=$null
foreach ($attempt in 1..10) {
try { Remove-Item -LiteralPath $resolvedRuntime -Recurse -Force -ErrorAction Stop; $cleanupError=$null; break }
catch { $cleanupError=$_.Exception.Message; if ($attempt -lt 10) { Start-Sleep -Milliseconds 300 } }
}
if ($cleanupError) { $summary.cleanupError=$cleanupError; $exitStatus=1; Write-Warning "Private runtime cleanup failed: $cleanupError" }
}
$summary.passed = $exitStatus -eq 0
$summary | ConvertTo-Json -Depth 8 | Set-Content -LiteralPath (Join-Path $OutputDirectory 'summary.json') -Encoding UTF8
+47 -7
View File
@@ -7,10 +7,13 @@ param(
[int]$RunSeconds = 0,
[string]$DiagnosticResolution,
[string]$CacheDirectory = $env:ZLUDA_CACHE_DIR,
[string]$LocalTextureKernels,
[switch]$ValidateOutput,
[switch]$ProfileStages,
[switch]$ProfileKernels,
[switch]$VerboseRuntime,
[string[]]$GameArguments = @('-dx12','-windowed','-ResX=1280','-ResY=720'),
[switch]$CaptureExceptions,
[string[]]$GameArguments = @('-dx12'),
[string]$OutputDirectory
)
$ErrorActionPreference = 'Stop'
@@ -56,13 +59,40 @@ foreach ($file in $metadata.files) {
if ((Get-FileHash -LiteralPath (Join-Path $package $file.path) -Algorithm SHA256).Hash -ne $file.sha256) { throw "Package file changed; rebuild package: $($file.path)" }
}
if ((Get-FileHash -LiteralPath $DlssDll -Algorithm SHA256).Hash -ne $metadata.dlssSha256) { throw 'DLSS DLL does not match the validated 310.9.1 native manifest. Rebuild and validate native manifests for this DLL first.' }
$textureFiles=@(); $textureManifest=@()
if ($LocalTextureKernels) {
$LocalTextureKernels=(Get-Item -LiteralPath $LocalTextureKernels -ErrorAction Stop).FullName
$validation=Get-Content -LiteralPath (Join-Path $LocalTextureKernels 'validation.json') -Raw | ConvertFrom-Json
if (!$validation.passed -or !$validation.strictRgb -or $validation.architecture -ne 'gfx1201' -or
$validation.source.dlssSha256 -ne $metadata.dlssSha256 -or !$validation.source.accuracy) {
throw 'Local texture kernels must pass test-native-texture.ps1 with the exact packaged DLSS identity.'
}
foreach ($object in $validation.source.objects.PSObject.Properties) {
if ($object.Name -notin @('hiluma_engine_output_depthinv_mvlo_hdr_max_v2_rel.hsaco','hiluma_engine_output_depthreg_mvhi_ldr_max_v2_rel.hsaco')) {
throw "Unvalidated local texture variant: $($object.Name)"
}
$path=Join-Path $LocalTextureKernels $object.Name
if ((Get-FileHash -LiteralPath $path -Algorithm SHA256).Hash.ToLowerInvariant() -ne $object.Value) { throw 'Local texture object changed after validation.' }
$textureFiles+=Get-Item -LiteralPath $path
}
if ($textureFiles.Count -ne 2) { throw 'Expected both validated local K output variants.' }
# Use the manifest covered by validation, rather than a mutable extra file.
foreach ($line in Get-Content -LiteralPath (Join-Path $LocalTextureKernels 'd4r-kernels.txt')) {
if (!$line.Trim() -or $line.StartsWith('#')) { continue }
if ($line -notmatch '^([A-Za-z0-9_]+) ([0-9a-f]{16})$' -or ($Matches[1]+'.hsaco') -notin @($textureFiles.Name)) { throw 'Invalid local texture manifest.' }
$textureManifest+=$line
}
if ($textureManifest.Count -ne 2) { throw 'Expected two local texture manifest identities.' }
if ((Get-FileHash -LiteralPath (Join-Path $LocalTextureKernels 'd4r-kernels.txt') -Algorithm SHA256).Hash.ToLowerInvariant() -ne $validation.manifestSha256) { throw 'Local texture manifest changed after validation.' }
}
$manifest = if (Test-Path -LiteralPath $manifestPath) { Get-Content -LiteralPath $manifestPath -Raw | ConvertFrom-Json } else { [pscustomobject]@{game=$GameExe; files=@()} }
if ($manifest.game -ne $GameExe) { throw 'Backup manifest belongs to another executable.' }
if (!(Test-Path -LiteralPath $manifestPath) -and (Test-Path -LiteralPath (GamePath 'd4r'))) { throw 'An existing d4r directory has no installation manifest; preserved.' }
New-Item -ItemType Directory -Force $backup | Out-Null
function InstallFile([string]$source, [string]$relative) {
$relative=$relative.Replace('/','\')
$path = GamePath $relative
$entry = @($manifest.files | Where-Object path -eq $relative) | Select-Object -First 1
$entry = @($manifest.files | Where-Object { $_.path.Replace('/','\') -eq $relative }) | Select-Object -First 1
if ($entry) {
if ((Test-Path -LiteralPath $path) -and (Get-FileHash -LiteralPath $path -Algorithm SHA256).Hash -ne $entry.installedHash) { throw "Installed file changed; preserved: $path" }
} else {
@@ -82,6 +112,13 @@ function InstallFile([string]$source, [string]$relative) {
}
InstallFile (Join-Path $package 'OptiScaler.dll') 'dxgi.dll'
foreach ($file in Get-ChildItem -LiteralPath (Join-Path $package 'd4r') -Recurse -File) { InstallFile $file.FullName $file.FullName.Substring($package.Length+1) }
if ($LocalTextureKernels) {
foreach ($file in $textureFiles) { InstallFile $file.FullName ('d4r/native/' + $file.Name) }
$combinedManifest=Join-Path $backup 'generated-native-manifest.txt'
@(Get-Content -LiteralPath (Join-Path $package 'd4r/native/d4r-kernels.txt')) + $textureManifest |
Set-Content -LiteralPath $combinedManifest -Encoding ASCII
InstallFile $combinedManifest 'd4r/native/d4r-kernels.txt'
}
# Private local test copies only; these are never added to the public package.
InstallFile $NgxCore 'd4r/vendor/_nvngx.dll'
InstallFile $DlssDll 'd4r/vendor/nvngx_dlss.dll'
@@ -136,13 +173,14 @@ $settings = @{
D4R_ZLUDA_IGNORE_DENORMAL=$null; D4R_ZLUDA_FAST_MATH=$null;
D4R_ZLUDA_WMMA_F32ACC=$null; D4R_ZLUDA_WAVE64=$null;
D4R_QUIET_API=$(if ($VerboseRuntime) { $null } else { '1' });
D4R_VALIDATE_OUTPUT=$(if ($ValidateOutput) { '1' } else { $null });
D4R_PROFILE_STAGES=$(if ($ProfileStages) { '1' } else { $null });
D4R_ZLUDA_PROFILE=$(if ($ProfileKernels) { '1' } else { $null });
D4R_DIAG_DIR=$OutputDirectory; ZLUDA_LOG_DIR=(Join-Path $OutputDirectory 'zluda-trace');
ZLUDA_CACHE_DIR=$CacheDirectory; PATH=((GamePath 'd4r/hip/bin') + ';' + (GamePath 'd4r/zluda') + ';' + $env:PATH)
}
$old = @{}; $process = $null; $originalSettings = @()
$outFile = $null; $errFile = $null; $outTask = $null; $errTask = $null
if ($ValidateOutput) { $settings['D4R_VALIDATE_OUTPUT']='1' }
if ($ProfileStages) { $settings['D4R_PROFILE_STAGES']='1' }
try {
if ($DiagnosticResolution) {
if ([IO.Path]::GetFileName($GameExe) -ne 'SHProto-Win64-Shipping.exe' -or $DiagnosticResolution -notmatch '^([0-9]{3,4})x([0-9]{3,4})$') { throw 'DiagnosticResolution currently supports Silent Hill 2 only; use e.g. 1280x720.' }
@@ -173,10 +211,12 @@ try {
Write-Host "Temporary diagnostic resolution: $DiagnosticResolution; original settings restore at exit."
}
foreach ($key in $settings.Keys) { $old[$key] = [Environment]::GetEnvironmentVariable($key,'Process'); [Environment]::SetEnvironmentVariable($key,$settings[$key],'Process') }
@{preset=$Preset; game=$GameExe; package=$metadata; driver=@(Get-CimInstance Win32_VideoController | Select-Object Name,DriverVersion,DriverDate); arguments=$GameArguments} |
@{preset=$Preset; game=$GameExe; package=$metadata; attachedDebugger=[bool]$CaptureExceptions; driver=@(Get-CimInstance Win32_VideoController | Select-Object Name,DriverVersion,DriverDate); arguments=$GameArguments} |
ConvertTo-Json -Depth 12 | Set-Content -LiteralPath (Join-Path $OutputDirectory 'environment.json') -Encoding UTF8
function Quote([string]$value) { if ($value.Contains('"')) { throw 'A command argument contains an unsupported quote.' }; return '"' + $value + '"' }
$arguments = @('--output-directory', (Quote $OutputDirectory), '--', (Quote $GameExe)) + @($GameArguments | ForEach-Object { Quote $_ })
$arguments = @('--output-directory', (Quote $OutputDirectory))
if (!$CaptureExceptions) { $arguments += '--no-debug' }
$arguments += @('--', (Quote $GameExe)) + @($GameArguments | ForEach-Object { Quote $_ })
# Drain raw bytes concurrently. PowerShell's line-oriented redirection can
# throttle a verbose game and distort the very timings we are collecting.
$info = [Diagnostics.ProcessStartInfo]::new()
@@ -186,7 +226,7 @@ try {
$info.UseShellExecute = $false; $info.CreateNoWindow = $true
$info.RedirectStandardOutput = $true; $info.RedirectStandardError = $true
$process = [Diagnostics.Process]::new(); $process.StartInfo = $info
if (!$process.Start()) { throw 'Game debugger launch failed.' }
if (!$process.Start()) { throw 'Game diagnostic launch failed.' }
$outFile = [IO.File]::Open((Join-Path $OutputDirectory 'd4r.stdout.log'), [IO.FileMode]::Create, [IO.FileAccess]::Write, [IO.FileShare]::Read)
$errFile = [IO.File]::Open((Join-Path $OutputDirectory 'd4r.stderr.log'), [IO.FileMode]::Create, [IO.FileAccess]::Write, [IO.FileShare]::Read)
$outTask = $process.StandardOutput.BaseStream.CopyToAsync($outFile)