Files
d4r/scripts/windows/package-windows-quick-test.ps1

110 lines
7.9 KiB
PowerShell

[CmdletBinding()]
param(
[string]$GamePackagePrefix, [Parameter(Mandatory=$true)][string]$PackageRoot,
[string]$ArchivePath,
[string]$NvidiaDirectory, [string]$NvidiaLicensePath
)
$ErrorActionPreference='Stop'
. (Join-Path $PSScriptRoot 'gpu-target.ps1')
$repo=[IO.Path]::GetFullPath((Join-Path $PSScriptRoot '../..'))
if (!$GamePackagePrefix) { $GamePackagePrefix=Join-Path $repo 'dist/windows-gpu-coverage-game' }
$PackageRoot=[IO.Path]::GetFullPath($PackageRoot)
if (Test-Path -LiteralPath $PackageRoot) { throw 'Use a new output directory to avoid mixing releases.' }
$commit=(& git -C $repo rev-parse HEAD).Trim()
if ($ArchivePath -and [bool](& git -C $repo status --porcelain)) { throw 'Commit source changes before creating a public ZIP.' }
New-Item -ItemType Directory -Force $PackageRoot | Out-Null
$files=[Collections.Generic.List[object]]::new()
function Stage([string]$Source,[string]$Relative) {
$destination=Join-Path $PackageRoot $Relative
New-Item -ItemType Directory -Force (Split-Path $destination) | Out-Null
Copy-Item -LiteralPath $Source -Destination $destination
$item=Get-Item -LiteralPath $destination
$entry=@{path=$Relative.Replace('\','/'); sha256=(Get-FileHash -LiteralPath $destination -Algorithm SHA256).Hash; version=$item.VersionInfo.FileVersion}
$files.Add($entry)
return $entry
}
$targets=[ordered]@{}; $common=@(); $baseline=$null
foreach ($gpu in Get-D4RGpuTargets) {
$arch=$gpu.architecture; $source="$GamePackagePrefix-$arch"
$metadata=Get-Content -LiteralPath (Join-Path $source 'package.json') -Raw | ConvertFrom-Json
if ($metadata.architecture -ne $arch -or $metadata.d4rWorkingTreeDirty) { throw "Uncommitted or wrong-target input: $source" }
$targetFiles=@()
foreach ($file in $metadata.files) {
$relative=$file.path.Replace('\','/')
if ((Get-FileHash -LiteralPath (Join-Path $source $file.path) -Algorithm SHA256).Hash -ne $file.sha256) { throw "Input file changed: $source/$relative" }
if ($relative.EndsWith('.hsaco')) { Assert-D4RCodeObjectTarget (Join-Path $source $file.path) $arch }
if ($relative -eq 'gpu-target.json' -or $relative -eq 'd4r/_nvngx.dll' -or $relative -eq 'd4r/d4r_gpu_inventory.exe' -or $relative -eq 'd4r/d4r_debug_launcher.exe' -or $relative -eq 'd4r/nvapi/nvapi64.dll' -or
$relative.StartsWith('d4r/native/') -or $relative -like 'd4r/pixel_convert_*.hsaco') {
$entry=Stage (Join-Path $source $file.path) "files/targets/$arch/$relative"
$targetFiles+=@{path=$relative; sha256=$entry.sha256; version=$entry.version}
} elseif ($relative -eq 'OptiScaler.dll' -or $relative.StartsWith('d4r/') -or $relative.StartsWith('licenses/')) {
$publicPath=if ($relative.StartsWith('licenses/')) { $relative } else { "files/common/$relative" }
if (!$baseline) {
$entry=Stage (Join-Path $source $file.path) $publicPath
if (!$relative.StartsWith('licenses/')) { $common+=@{path=$relative; sha256=$entry.sha256; version=$entry.version} }
} elseif ((Get-FileHash -LiteralPath (Join-Path $PackageRoot $publicPath) -Algorithm SHA256).Hash -ne $file.sha256) {
throw "Shared runtime differs in $arch : $relative"
}
}
}
if (@($targetFiles | Where-Object { $_.path.EndsWith('.hsaco') }).Count -ne 17) { throw "Expected 17 code objects for $arch" }
$targets[$arch]=@{binarySourceCommit=$metadata.d4rCommit; hardwareValidation=$metadata.hardwareValidation; dlssSha256=$metadata.dlssSha256; files=$targetFiles}
if (!$baseline) { $baseline=$metadata }
if ($metadata.dlssSha256 -ne $baseline.dlssSha256 -or $metadata.zludaBuild.sourceCommit -ne $baseline.zludaBuild.sourceCommit) { throw 'Input packages do not use the same validated dependencies.' }
}
foreach ($name in @('windows-game.ps1','game-summary.ps1','gpu-target.ps1','gpu-preflight.ps1')) {
$entry=Stage (Join-Path $PSScriptRoot $name) "files/common/$name"
$common+=@{path=$name; sha256=$entry.sha256; version=$entry.version}
}
$entry=Stage (Join-Path $repo 'tools/windows/gpu-targets.json') 'files/common/gpu-targets.json'
$common+=@{path='gpu-targets.json'; sha256=$entry.sha256; version=$entry.version}
[void](Stage (Join-Path $PSScriptRoot 'quick-test.ps1') 'files/quick-test.ps1')
[void](Stage (Join-Path $repo 'docs/windows-quick-test.txt') 'READ-ME-FIRST.txt')
foreach ($launch in @(@{name='START-K.cmd'; arguments='-Preset 11'},@{name='START-M.cmd'; arguments='-Preset 13'},@{name='RESTORE-GAME.cmd'; arguments='-Action restore'})) {
$path=Join-Path $PackageRoot $launch.name
@('@echo off','cd /d "%~dp0"',('"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -STA -ExecutionPolicy Bypass -File "%~dp0files\quick-test.ps1" '+$launch.arguments),'pause') |
Set-Content -LiteralPath $path -Encoding ASCII
$files.Add(@{path=$launch.name; sha256=(Get-FileHash -LiteralPath $path -Algorithm SHA256).Hash; version=$null})
}
$ngxCoreSha256='66767018C36B3BAB46398DADE3ADF173DAA3730FDA75965689EA848C9BC4E79B'
$bundledNvidia=$null
if ($NvidiaDirectory) {
# Opt-in for local testing or a distributor with appropriate permission.
# A matching hash establishes binary identity, not redistribution rights.
if (!$NvidiaLicensePath -or !(Test-Path -LiteralPath $NvidiaLicensePath -PathType Leaf)) {
throw 'Bundled NVIDIA files require -NvidiaLicensePath with their applicable license. This option does not establish redistribution permission.'
}
$core=Join-Path $NvidiaDirectory '_nvngx.dll'
$dlss=Join-Path $NvidiaDirectory 'nvngx_dlss.dll'
if ((Get-FileHash -LiteralPath $core -Algorithm SHA256).Hash -ne $ngxCoreSha256 -or
(Get-FileHash -LiteralPath $dlss -Algorithm SHA256).Hash -ne $baseline.dlssSha256) {
throw 'Bundled NVIDIA files must match the validated original NGX and DLSS hashes.'
}
[void](Stage $core 'files/nvidia/_nvngx.dll')
[void](Stage $dlss 'files/nvidia/nvngx_dlss.dll')
[void](Stage $NvidiaLicensePath 'licenses/NVIDIA-RTX.txt')
$bundledNvidia=@{ngxCore='nvidia/_nvngx.dll'; dlssDll='nvidia/nvngx_dlss.dll'; license='licenses/NVIDIA-RTX.txt'}
} elseif ($NvidiaLicensePath) { throw '-NvidiaLicensePath requires -NvidiaDirectory.' }
$metadata=[ordered]@{schema=1; packageCommit=$commit; binarySourceCommit=$baseline.d4rCommit;
ngxCoreSha256=$ngxCoreSha256; bundledNvidia=$bundledNvidia;
dependencies=@{optiScalerSourceCommit=$baseline.optiScaler.sourceCommit; zludaSourceCommit=$baseline.zludaBuild.sourceCommit;
llvmSource=$baseline.zludaBuild.llvmSource; hipRuntime=$baseline.hipRuntime};
commonFiles=$common; targets=$targets; files=$files}
$metadata | ConvertTo-Json -Depth 12 | Set-Content -LiteralPath (Join-Path $PackageRoot 'files/package.json') -Encoding UTF8
if ($ArchivePath) {
$ArchivePath=[IO.Path]::GetFullPath($ArchivePath)
if ($ArchivePath.StartsWith($PackageRoot+'\',[StringComparison]::OrdinalIgnoreCase)) { throw 'Place the ZIP outside the output directory.' }
New-Item -ItemType Directory -Force (Split-Path $ArchivePath) | Out-Null
Add-Type -AssemblyName System.IO.Compression,System.IO.Compression.FileSystem
$stream=[IO.File]::Open($ArchivePath,[IO.FileMode]::Create,[IO.FileAccess]::ReadWrite,[IO.FileShare]::None)
$archive=$null
try {
$archive=[IO.Compression.ZipArchive]::new($stream,[IO.Compression.ZipArchiveMode]::Create)
foreach ($relative in @($files.path)+@('files/package.json')) {
[void][IO.Compression.ZipFileExtensions]::CreateEntryFromFile($archive,(Join-Path $PackageRoot $relative),$relative,[IO.Compression.CompressionLevel]::Optimal)
}
} finally { if ($archive) { $archive.Dispose() }; $stream.Dispose() }
}
$nvidiaMode=if ($bundledNvidia) { 'bundled NVIDIA files; distributor must have appropriate permission' } else { 'user-supplied NVIDIA files' }
Write-Host "Quick-test package: $PackageRoot (11 targets, automatic GPU selection, $nvidiaMode)"