Enable experimental native Windows RDNA3 and RDNA4 targets
Share explicit target metadata across build/runtime/package guards, preserve native gfx11 WMMA with a Windows LDS lane exchange, select HIP devices by D3D12 LUID, and reject wrong-target/vkd3d installations before changing game files. Review all issue #10 logs and document compile-only coverage plus RX9070XT regressions. Co-authored-by: realdody <[email protected]>
This commit is contained in:
1 parent
98de8e3a3e
commit
3fa963fd1b
32 files changed
+494
-162
No files matched your search
@@ -5,10 +5,12 @@ param(
|
||||
[string]$HipRoot = 'C:\Program Files\AMD\ROCm\7.2',
|
||||
[string]$ZludaRoot,
|
||||
[ValidateSet('cu','wgp')][string]$ShaderMode='cu',
|
||||
[ValidateSet('gfx1200','gfx1201')][string]$GpuArch='gfx1201',
|
||||
[string]$GpuArch='gfx1201',
|
||||
[string]$OutputDirectory
|
||||
)
|
||||
$ErrorActionPreference='Stop'
|
||||
. (Join-Path $PSScriptRoot 'gpu-target.ps1')
|
||||
[void](Get-D4RGpuTargetInfo $GpuArch)
|
||||
$repo=[IO.Path]::GetFullPath((Join-Path $PSScriptRoot '../..'))
|
||||
if (!$ZludaRoot) { $ZludaRoot=Join-Path $repo 'dist/zluda-windows-final' }
|
||||
if (!$OutputDirectory) { $OutputDirectory=Join-Path $repo "build/private-textures-$GpuArch" }
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string[]]$GpuArchitectures,
|
||||
[ValidateSet('stable','therock')][string]$RuntimeProfile='therock',
|
||||
[string]$ZludaRoot, [string]$DlssDll,
|
||||
[switch]$PackageGames,
|
||||
[string]$BuildRoot, [string]$OutputRoot, [string]$ArchiveDirectory
|
||||
)
|
||||
$ErrorActionPreference='Stop'
|
||||
. (Join-Path $PSScriptRoot 'gpu-target.ps1')
|
||||
$repo=[IO.Path]::GetFullPath((Join-Path $PSScriptRoot '../..'))
|
||||
if (!$GpuArchitectures) { $GpuArchitectures=@(Get-D4RGpuTargets | ForEach-Object { $_.architecture }) }
|
||||
foreach ($arch in $GpuArchitectures) { [void](Get-D4RGpuTargetInfo $arch) }
|
||||
if (@($GpuArchitectures | Select-Object -Unique).Count -ne $GpuArchitectures.Count) { throw 'Duplicate GPU target.' }
|
||||
if (!$BuildRoot) { $BuildRoot=Join-Path $repo 'build/windows-gpu-coverage' }
|
||||
if (!$OutputRoot) { $OutputRoot=Join-Path $repo 'dist/windows-gpu-coverage' }
|
||||
if (!$ZludaRoot) { $ZludaRoot=Join-Path $repo 'dist/zluda-windows-final' }
|
||||
if ($ArchiveDirectory -and !$PackageGames) { throw 'ArchiveDirectory requires PackageGames.' }
|
||||
if ($PackageGames -and (!$DlssDll -or ![IO.Path]::IsPathRooted($DlssDll) -or !(Test-Path -LiteralPath $DlssDll))) {
|
||||
throw 'PackageGames requires an absolute path to your local nvngx_dlss.dll; it will not be redistributed.'
|
||||
}
|
||||
New-Item -ItemType Directory -Force $BuildRoot | Out-Null
|
||||
if ($ArchiveDirectory) { New-Item -ItemType Directory -Force $ArchiveDirectory | Out-Null }
|
||||
$results=[Collections.Generic.List[object]]::new()
|
||||
foreach ($arch in $GpuArchitectures) {
|
||||
$build="$BuildRoot-$arch"; $diag="$OutputRoot-$arch"
|
||||
$log=Join-Path $BuildRoot "$arch-build.log"
|
||||
Write-Host "Building $arch (compile/package only; no GPU workloads). Log: $log"
|
||||
& (Join-Path $PSScriptRoot 'build-windows-rdna4.ps1') -RuntimeProfile $RuntimeProfile -GpuArch $arch `
|
||||
-ZludaRoot $ZludaRoot -BuildDirectory $build -InstallDirectory $diag *> $log
|
||||
$row=[ordered]@{architecture=$arch; compiled=$true; hardwareTestExecuted=$false; buildDirectory=$build; diagnosticRoot=$diag; log=$log}
|
||||
if ($PackageGames) {
|
||||
$k="$BuildRoot-native-k-$arch"; $m="$BuildRoot-native-m-$arch"; $game="$OutputRoot-game-$arch"
|
||||
& (Join-Path $PSScriptRoot 'stage-native-k.ps1') -DlssDll $DlssDll -PackageRoot $diag -GpuArch $arch -OutputDirectory $k
|
||||
& (Join-Path $PSScriptRoot 'stage-native-m.ps1') -DlssDll $DlssDll -PackageRoot $diag -GpuArch $arch -OutputDirectory $m
|
||||
$packageArgs=@{DiagnosticRoot=$diag; GpuArch=$arch; PackageRoot=$game; ZludaRoot=$ZludaRoot; KernelKRoot=$k; KernelMRoot=$m}
|
||||
if ($ArchiveDirectory) { $packageArgs.ArchivePath=Join-Path $ArchiveDirectory "d4r-windows-$arch.zip" }
|
||||
& (Join-Path $PSScriptRoot 'package-windows-game.ps1') @packageArgs
|
||||
$row.gamePackage=$game
|
||||
}
|
||||
$results.Add($row)
|
||||
$results | ConvertTo-Json -Depth 5 | Set-Content (Join-Path $BuildRoot 'matrix-build.json') -Encoding UTF8
|
||||
Write-Host "Compiled $arch; hardware validation remains separate."
|
||||
}
|
||||
@@ -2,13 +2,15 @@
|
||||
param(
|
||||
[string]$HipRoot = $env:HIP_PATH,
|
||||
[ValidateSet('stable', 'therock')][string]$RuntimeProfile = 'stable',
|
||||
[ValidateSet('gfx1200','gfx1201')][string]$GpuArch = 'gfx1201',
|
||||
[string]$GpuArch = 'gfx1201',
|
||||
[string]$ZludaRoot,
|
||||
[string]$ToolchainRoot,
|
||||
[string]$BuildDirectory,
|
||||
[string]$InstallDirectory
|
||||
)
|
||||
$ErrorActionPreference = 'Stop'
|
||||
. (Join-Path $PSScriptRoot 'gpu-target.ps1')
|
||||
[void](Get-D4RGpuTargetInfo $GpuArch)
|
||||
$repo = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot '../..'))
|
||||
if ($RuntimeProfile -eq 'therock') {
|
||||
if (!$PSBoundParameters.ContainsKey('HipRoot')) { $HipRoot = Join-Path $repo '.tools/therock-10.2.0a20260929/_rocm_sdk_core' }
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
# Read-only inventory before touching game files. It allocates no GPU memory
|
||||
# and executes no kernels; successful discovery is not hardware validation.
|
||||
function Invoke-D4RGpuPreflight([string]$PackageRoot, [string]$GameDirectory, [string]$Target, [string]$OutputDirectory) {
|
||||
New-Item -ItemType Directory -Force $OutputDirectory | Out-Null
|
||||
$result=[ordered]@{passed=$false; target=$Target; gpuWorkExecuted=$false; failure=$null}
|
||||
try {
|
||||
$proxy=Join-Path $GameDirectory 'd3d12.dll'
|
||||
if (Test-Path -LiteralPath $proxy) {
|
||||
$item=Get-Item -LiteralPath $proxy
|
||||
$result.localD3D12=@{path=$proxy; sha256=(Get-FileHash -LiteralPath $proxy).Hash; product=$item.VersionInfo.ProductName}
|
||||
# Identify known Vulkan/Wine proxies by their own strings. Do not
|
||||
# load, remove or replace a third-party game DLL.
|
||||
if ($item.Length -le 64MB -and [Text.Encoding]::ASCII.GetString([IO.File]::ReadAllBytes($proxy)) -match '(?i)vkd3d|wined3d') {
|
||||
throw 'Local d3d12.dll identifies as vkd3d/Wine. Restore the game native D3D12 installation before using this Windows backend.'
|
||||
}
|
||||
}
|
||||
$info=[Diagnostics.ProcessStartInfo]::new()
|
||||
$info.FileName=Join-Path $PackageRoot 'd4r/d4r_gpu_inventory.exe'
|
||||
$hip=Join-Path $PackageRoot 'd4r/hip'
|
||||
foreach ($value in @($hip,$OutputDirectory)) { if ($value.Contains('"')) { throw 'Unsupported quote in inventory path.' } }
|
||||
$info.Arguments='--hip-root "' + $hip + '" --output-dir "' + $OutputDirectory + '"'
|
||||
$info.UseShellExecute=$false; $info.CreateNoWindow=$true
|
||||
$info.EnvironmentVariables['D4R_DIAG_DIR']=$OutputDirectory
|
||||
$info.RedirectStandardOutput=$true; $info.RedirectStandardError=$true
|
||||
$process=[Diagnostics.Process]::new(); $process.StartInfo=$info
|
||||
try {
|
||||
if (!$process.Start()) { throw 'Cannot start GPU inventory.' }
|
||||
$stdout=$process.StandardOutput.ReadToEndAsync(); $stderr=$process.StandardError.ReadToEndAsync()
|
||||
$timedOut=!$process.WaitForExit(30000)
|
||||
if ($timedOut) { $process.Kill(); $process.WaitForExit() }
|
||||
$stdout.GetAwaiter().GetResult() | Set-Content (Join-Path $OutputDirectory 'gpu-inventory.stdout.log') -Encoding UTF8
|
||||
$stderr.GetAwaiter().GetResult() | Set-Content (Join-Path $OutputDirectory 'gpu-inventory.stderr.log') -Encoding UTF8
|
||||
$result.exitCode=$process.ExitCode
|
||||
$result.exceptionOrExitHex='0x{0:X8}' -f [BitConverter]::ToUInt32([BitConverter]::GetBytes([int]$process.ExitCode),0)
|
||||
if ($timedOut) { $result.timedOut=$true; throw 'HIP inventory timed out after 30 seconds.' }
|
||||
if ($process.ExitCode) { throw "HIP inventory failed (exit $($process.ExitCode))." }
|
||||
} finally { $process.Dispose() }
|
||||
$inventory=Get-Content (Join-Path $OutputDirectory 'gpu-inventory.json') -Raw | ConvertFrom-Json
|
||||
$result.inventory=$inventory
|
||||
if ($inventory.compiledTarget -ne $Target) { throw "Inventory executable targets $($inventory.compiledTarget); package requires $Target." }
|
||||
$matching=@($inventory.devices | Where-Object { $_.architecture -eq $Target -and $_.wavefrontSize -eq 32 })
|
||||
if (!$matching.Count) {
|
||||
$actual=@($inventory.devices | ForEach-Object { "$($_.architecture) ($($_.name))" }) -join ', '
|
||||
throw "GPU target mismatch: detected $actual; package requires $Target. Use the package for the actual HIP architecture; do not rename code objects."
|
||||
}
|
||||
$result.passed=$true
|
||||
Write-Host "D4R_PREFLIGHT target=$Target devices=$($matching.Count) gpu_work_executed=0"
|
||||
} catch {
|
||||
$result.failure=$_.Exception.Message
|
||||
$result | ConvertTo-Json -Depth 8 | Set-Content (Join-Path $OutputDirectory 'preflight.json') -Encoding UTF8
|
||||
try { Get-CimInstance Win32_VideoController | Select-Object Name,DriverVersion,DriverDate | ConvertTo-Json |
|
||||
Set-Content (Join-Path $OutputDirectory 'driver.json') -Encoding UTF8 } catch {}
|
||||
$bundle=$OutputDirectory+'.zip'
|
||||
Compress-Archive -Path (Join-Path $OutputDirectory '*') -DestinationPath $bundle -Force
|
||||
throw "$($result.failure) Diagnostic bundle: $bundle"
|
||||
}
|
||||
$result | ConvertTo-Json -Depth 8 | Set-Content (Join-Path $OutputDirectory 'preflight.json') -Encoding UTF8
|
||||
}
|
||||
@@ -1,19 +1,31 @@
|
||||
# Shared by the build, diagnostics, staging and game package scripts.
|
||||
function Get-D4RGpuTargets {
|
||||
$registry=Join-Path $PSScriptRoot 'gpu-targets.json'
|
||||
if (!(Test-Path -LiteralPath $registry)) { $registry=Join-Path $PSScriptRoot '../../tools/windows/gpu-targets.json' }
|
||||
$data=Get-Content -LiteralPath $registry -Raw | ConvertFrom-Json
|
||||
if ($data.schema -ne 1) { throw 'Unsupported GPU target registry schema.' }
|
||||
return $data.targets
|
||||
}
|
||||
function Get-D4RGpuTargetInfo([string]$Target) {
|
||||
$info=@(Get-D4RGpuTargets | Where-Object { $_.architecture -eq $Target })
|
||||
if ($info.Count -ne 1) { throw "Unsupported GPU target: $Target" }
|
||||
return $info[0]
|
||||
}
|
||||
function Get-D4RGpuTarget([string]$Root, [string]$Requested) {
|
||||
$configured=$null
|
||||
$targetFile=Join-Path $Root 'gpu-target.json'
|
||||
if (Test-Path -LiteralPath $targetFile) {
|
||||
$configured=(Get-Content -LiteralPath $targetFile -Raw | ConvertFrom-Json).architecture
|
||||
if ($configured -notin @('gfx1200','gfx1201')) { throw "Unsupported package GPU target: $configured" }
|
||||
[void](Get-D4RGpuTargetInfo $configured)
|
||||
}
|
||||
$target=if ($Requested) { $Requested } elseif ($configured) { $configured } else { 'gfx1201' }
|
||||
if ($target -notin @('gfx1200','gfx1201')) { throw "Unsupported GPU target: $target" }
|
||||
if (!$configured -and $target -ne 'gfx1201') { throw 'A gfx1200 build requires gpu-target.json; rebuild with -GpuArch gfx1200.' }
|
||||
[void](Get-D4RGpuTargetInfo $target)
|
||||
if (!$configured -and $target -ne 'gfx1201') { throw "A $target build requires gpu-target.json; rebuild with -GpuArch $target." }
|
||||
if ($configured -and $target -ne $configured) { throw "Requested $target differs from package target $configured" }
|
||||
return $target
|
||||
}
|
||||
function Assert-D4RCodeObjectTarget([string]$Path, [string]$Target) {
|
||||
if ($Target -notin @('gfx1200','gfx1201')) { throw "Unsupported GPU target: $Target" }
|
||||
$info=Get-D4RGpuTargetInfo $Target
|
||||
$reader=[IO.BinaryReader]::new([IO.File]::OpenRead($Path))
|
||||
try { $header=$reader.ReadBytes(64) } finally { $reader.Dispose() }
|
||||
if ($header.Length -ne 64 -or $header[0] -ne 127 -or $header[1] -ne 69 -or $header[2] -ne 76 -or $header[3] -ne 70 -or
|
||||
@@ -21,6 +33,6 @@ function Assert-D4RCodeObjectTarget([string]$Path, [string]$Target) {
|
||||
throw "Invalid AMDGPU ELF64 code object: $Path"
|
||||
}
|
||||
# LLVM AMDGPU e_flags machine IDs; inspect, never patch or spoof them.
|
||||
$expected=if ($Target -eq 'gfx1200') { 0x48 } else { 0x4e }
|
||||
$expected=$info.elfMachine
|
||||
if ($header[48] -ne $expected) { throw "Code object does not target ${Target}: $Path (ELF machine=$($header[48]))" }
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
param(
|
||||
[string]$PackageRoot, [string]$DiagnosticRoot, [string]$OptiScalerRoot,
|
||||
[string]$ZludaRoot, [string]$HipRoot, [string]$KernelKRoot, [string]$KernelMRoot,
|
||||
[ValidateSet('gfx1200','gfx1201')][string]$GpuArch,
|
||||
[string]$GpuArch,
|
||||
[string]$ArchivePath
|
||||
)
|
||||
$ErrorActionPreference = 'Stop'
|
||||
@@ -15,7 +15,7 @@ foreach ($name in $defaults.Keys) {
|
||||
if (!(Get-Variable -Name $name -ValueOnly)) { Set-Variable -Name $name -Value (Join-Path $repo $defaults[$name]) }
|
||||
}
|
||||
$GpuArch=Get-D4RGpuTarget $DiagnosticRoot $GpuArch
|
||||
if ($GpuArch -eq 'gfx1200' -and !$PSBoundParameters.ContainsKey('PackageRoot')) { $PackageRoot += '-gfx1200' }
|
||||
if ($GpuArch -ne 'gfx1201' -and !$PSBoundParameters.ContainsKey('PackageRoot')) { $PackageRoot += "-$GpuArch" }
|
||||
if (!$KernelKRoot) { $KernelKRoot=Join-Path $repo "build/native-k-$GpuArch" }
|
||||
if (!$KernelMRoot) { $KernelMRoot=Join-Path $repo "build/native-m-$GpuArch" }
|
||||
foreach ($directory in @($KernelKRoot,$KernelMRoot)) {
|
||||
@@ -46,6 +46,7 @@ Stage (Join-Path $DiagnosticRoot 'bin/d4r_nvngx.dll') 'd4r/_nvngx.dll'
|
||||
Stage (Join-Path $DiagnosticRoot "bin/pixel_convert_${GpuArch}.hsaco") "d4r/pixel_convert_${GpuArch}.hsaco"
|
||||
Stage (Join-Path $DiagnosticRoot 'nvapi-compat/nvapi64.dll') 'd4r/nvapi/nvapi64.dll'
|
||||
Stage (Join-Path $DiagnosticRoot 'bin/d4r_debug_launcher.exe') 'd4r/d4r_debug_launcher.exe'
|
||||
Stage (Join-Path $DiagnosticRoot 'bin/d4r_gpu_inventory.exe') 'd4r/d4r_gpu_inventory.exe'
|
||||
foreach ($file in @('nvcuda.dll','nvapi64.dll','libc++.dll','libunwind.dll')) { Stage (Join-Path $ZludaRoot $file) "d4r/zluda/$file" }
|
||||
foreach ($file in @('amdhip64_7.dll','amd_comgr.dll','hiprtc0717.dll','hiprtc-builtins0717.dll','rocm_kpack.dll','AMD.ROCM.Comgr.MANIFEST','.hipVersion')) {
|
||||
Stage (Join-Path $HipRoot "bin/$file") "d4r/hip/bin/$file"
|
||||
@@ -66,6 +67,8 @@ if ($entries.Count -ne 16) { throw "Expected 11 K and 5 M native objects; found
|
||||
$stagedFiles.Add('d4r/native/d4r-kernels.txt')
|
||||
Stage (Join-Path $repo 'scripts/windows/windows-game.ps1') 'windows-game.ps1'
|
||||
Stage (Join-Path $repo 'scripts/windows/gpu-target.ps1') 'gpu-target.ps1'
|
||||
Stage (Join-Path $repo 'scripts/windows/gpu-preflight.ps1') 'gpu-preflight.ps1'
|
||||
Stage (Join-Path $repo 'tools/windows/gpu-targets.json') 'gpu-targets.json'
|
||||
if (Test-Path -LiteralPath (Join-Path $DiagnosticRoot 'gpu-target.json')) {
|
||||
Stage (Join-Path $DiagnosticRoot 'gpu-target.json') 'gpu-target.json'
|
||||
} else {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[CmdletBinding()]
|
||||
param([Parameter(Mandatory=$true)][string]$DlssDll, [string]$PackageRoot, [string]$OutputDirectory, [ValidateSet('gfx1200','gfx1201')][string]$GpuArch)
|
||||
param([Parameter(Mandatory=$true)][string]$DlssDll, [string]$PackageRoot, [string]$OutputDirectory, [string]$GpuArch)
|
||||
$ErrorActionPreference = 'Stop'
|
||||
. (Join-Path $PSScriptRoot 'gpu-target.ps1')
|
||||
$repo = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot '../..'))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[CmdletBinding()]
|
||||
param([Parameter(Mandatory=$true)][string]$DlssDll, [string]$PackageRoot, [string]$OutputDirectory, [ValidateSet('gfx1200','gfx1201')][string]$GpuArch)
|
||||
param([Parameter(Mandatory=$true)][string]$DlssDll, [string]$PackageRoot, [string]$OutputDirectory, [string]$GpuArch)
|
||||
$ErrorActionPreference = 'Stop'
|
||||
. (Join-Path $PSScriptRoot 'gpu-target.ps1')
|
||||
$repo = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot '../..'))
|
||||
|
||||
@@ -4,7 +4,7 @@ param(
|
||||
[ValidateSet('stable', 'therock')][string]$RuntimeProfile = 'stable',
|
||||
[string]$ZludaRoot,
|
||||
[string]$PackageRoot,
|
||||
[ValidateSet('gfx1200','gfx1201')][string]$GpuArch,
|
||||
[string]$GpuArch,
|
||||
[string]$OutputDirectory,
|
||||
[string]$NgxCore = $env:D4R_NGX_CORE,
|
||||
[string]$DlssDll = $env:D4R_DLSS_DLL,
|
||||
|
||||
@@ -27,6 +27,7 @@ param(
|
||||
)
|
||||
$ErrorActionPreference = 'Stop'
|
||||
. (Join-Path $PSScriptRoot 'gpu-target.ps1')
|
||||
. (Join-Path $PSScriptRoot 'gpu-preflight.ps1')
|
||||
if ($ProfileGpuBoundary -and !$AsyncInterop) { throw '-ProfileGpuBoundary requires -AsyncInterop.' }
|
||||
if ($ProfileKernels -and $ProfileKernelsDeferred) { throw 'Choose either serializing or deferred kernel profiling.' }
|
||||
if ($ProfileLegacyStream -and !$ProfileKernelsDeferred) { throw '-ProfileLegacyStream requires -ProfileKernelsDeferred.' }
|
||||
@@ -74,6 +75,7 @@ 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.' }
|
||||
Invoke-D4RGpuPreflight $package $game $GpuArch (Join-Path $package ('results/preflight-' + (Get-Date -Format 'yyyyMMdd-HHmmss-fff')))
|
||||
$textureFiles=@(); $textureManifest=@()
|
||||
if ($LocalTextureKernels) {
|
||||
$LocalTextureKernels=(Get-Item -LiteralPath $LocalTextureKernels -ErrorAction Stop).FullName
|
||||
@@ -193,6 +195,7 @@ $settings = @{
|
||||
# false have the same numerical effect; unset reuses the validated cache.
|
||||
D4R_ZLUDA_IGNORE_DENORMAL=$null; D4R_ZLUDA_FAST_MATH=$null;
|
||||
D4R_ZLUDA_WMMA_F32ACC=$null; D4R_ZLUDA_WAVE64=$null;
|
||||
D4R_ZLUDA_WMMA_LAYOUT=$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 });
|
||||
|
||||
Reference in new issue
Block a user