Add native K/M/RR inference engines, HIP kernels, replay and validation harnesses, and Windows DLSS setup and runtime support. Include GPU profiling tools, build and packaging scripts, platform integration patches, and implementation documentation.
114 lines
8.1 KiB
PowerShell
114 lines
8.1 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;
|
|
nativeFp8M=[bool]$metadata.nativeFp8M; tokenLanesM=[bool]$metadata.tokenLanesM;
|
|
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-E.cmd'; arguments='-Preset 5'},@{name='START-K.cmd'; arguments='-Preset 11'},
|
|
@{name='START-L.cmd'; arguments='-Preset 12'},@{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)"
|