Auto install warp (#8458)

This commit is contained in:
Connor Fitzgerald 2025-11-12 10:56:54 -05:00 committed by GitHub
parent 39f7dbcaf5
commit 065329000b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 174 additions and 18 deletions

View File

@ -1,8 +1,8 @@
name: "Install WARP"
description: "Install WARP"
inputs:
target-dirs:
description: "Space-separated list of directories into which to install the WARP DLL."
target-dir:
description: "The directory into which to install the WARP DLL."
required: true
runs:
using: "composite"
@ -11,15 +11,4 @@ runs:
run: |
set -e
export WARP_VERSION="1.0.16.1"
# Make sure dxc is in path.
dxc --version
curl.exe -L --retry 5 https://www.nuget.org/api/v2/package/Microsoft.Direct3D.WARP/$WARP_VERSION -o warp.zip
7z.exe e warp.zip -owarp build/native/bin/x64/d3d10warp.dll
for dir in ${{ inputs.target-dirs }}; do
mkdir -p "$dir"
cp -v warp/d3d10warp.dll "$dir"
done
cargo xtask install-warp --target-dir ${{ inputs.target-dir }}

View File

@ -558,7 +558,7 @@ jobs:
if: matrix.os == 'windows-2022'
uses: ./.github/actions/install-warp
with:
target-dirs: "target/llvm-cov-target/debug target/llvm-cov-target/debug/deps"
target-dir: "target/llvm-cov-target/debug"
- name: (Windows) Install Mesa
if: matrix.os == 'windows-2022'

View File

@ -93,7 +93,7 @@ jobs:
if: matrix.os == 'windows-2022'
uses: ./.github/actions/install-warp
with:
target-dirs: "target/llvm-cov-target/debug"
target-dir: "target/llvm-cov-target/debug"
- name: (Linux) Install Mesa
if: matrix.os == 'ubuntu-24.04'

123
xtask/src/install_warp.rs Normal file
View File

@ -0,0 +1,123 @@
use anyhow::Context;
use pico_args::Arguments;
use xshell::Shell;
/// Keep this in sync with .github/actions/install-warp/action.yml
const WARP_VERSION: &str = "1.0.16.1";
/// Run the install-warp subcommand
pub fn run_install_warp(shell: Shell, mut args: Arguments) -> anyhow::Result<()> {
if cfg!(not(target_os = "windows")) {
anyhow::bail!("WARP installation is only supported on Windows");
}
// Accept either --target-dir or --profile, but not both
let target_dir_arg = args
.opt_value_from_str::<_, String>("--target-dir")
.ok()
.flatten();
let profile_arg = args
.opt_value_from_str::<_, String>("--profile")
.ok()
.flatten();
let target_dir = match (target_dir_arg, profile_arg) {
(Some(_), Some(_)) => {
anyhow::bail!("Cannot specify both --target-dir and --profile");
}
(Some(dir), None) => dir,
(None, Some(profile)) => format!("target/{profile}"),
(None, None) => "target/debug".to_string(),
};
install_warp(&shell, &target_dir)?;
Ok(())
}
/// Install WARP DLL on Windows for testing.
///
/// This downloads the Microsoft.Direct3D.WARP NuGet package and extracts
/// the d3d10warp.dll into the specified target directory and its deps subdirectory.
pub fn install_warp(shell: &Shell, target_dir: &str) -> anyhow::Result<()> {
// Check if WARP is already installed with the correct version
let version_file = format!("{target_dir}/warp.txt");
if let Ok(installed_version) = shell.read_file(&version_file) {
if installed_version.trim() == WARP_VERSION {
log::info!("WARP {WARP_VERSION} already installed, skipping download");
return Ok(());
} else {
log::info!(
"WARP version mismatch (installed: {}, required: {}), re-downloading",
installed_version.trim(),
WARP_VERSION
);
}
}
log::info!("Installing WARP {WARP_VERSION}");
let warp_url =
format!("https://www.nuget.org/api/v2/package/Microsoft.Direct3D.WARP/{WARP_VERSION}");
// Download WARP NuGet package
log::info!("Downloading WARP from {warp_url}");
shell
.cmd("curl.exe")
.args(["-L", "--retry", "5", &warp_url, "-o", "warp.zip"])
.run()
.context("Failed to download WARP package")?;
// Create target/warp directory
shell
.create_dir("target/warp")
.context("Failed to create target/warp directory")?;
// Extract the DLL using tar (available on Windows 10+)
log::info!("Extracting WARP DLL");
shell
.cmd("tar")
.args([
"-xf",
"warp.zip",
"-C",
"target/warp",
"build/native/bin/x64/d3d10warp.dll",
])
.run()
.context("Failed to extract WARP DLL using tar")?;
// Copy the DLL to target directory and deps subdirectory
let source = "target/warp/build/native/bin/x64/d3d10warp.dll";
let target_deps = format!("{target_dir}/deps");
let target_dirs = [target_dir, target_deps.as_str()];
for dir in &target_dirs {
// Create target directory if it doesn't exist
shell
.create_dir(dir)
.with_context(|| format!("Failed to create target directory: {dir}"))?;
let dest = format!("{dir}/d3d10warp.dll");
log::info!("Copying WARP DLL to {dir}");
shell
.copy_file(source, &dest)
.with_context(|| format!("Failed to copy WARP DLL to {dir}"))?;
}
// Write version file to track installed version (only at root)
let version_file = format!("{target_dir}/warp.txt");
shell
.write_file(&version_file, WARP_VERSION)
.context("Failed to write version file")?;
// Cleanup temporary files
let _ = shell.remove_path("warp.zip");
let _ = shell.remove_path("target/warp");
log::info!("WARP installation complete");
Ok(())
}

View File

@ -7,6 +7,7 @@ use anyhow::Context;
use pico_args::Arguments;
mod cts;
mod install_warp;
mod miri;
mod run_wasm;
mod test;
@ -59,6 +60,14 @@ Commands:
This is useful for testing changes to wasm-bindgen
--version String that can be passed to `git checkout` to checkout the wasm-bindgen repository.
install-warp
Download and install the WARP (D3D12 software implementation) DLL for D3D12 testing.
--target-dir <dir> The target directory to install WARP into.
--profile <profile> The cargo profile to install WARP for (default: debug)
Note: Cannot specify both --target-dir and --profile
Options:
-h, --help Print help
";
@ -106,6 +115,7 @@ fn main() -> anyhow::Result<ExitCode> {
Some("miri") => miri::run_miri(shell, args)?,
Some("test") => test::run_tests(shell, args, passthrough_args)?,
Some("vendor-web-sys") => vendor_web_sys::run_vendor_web_sys(shell, args)?,
Some("install-warp") => install_warp::run_install_warp(shell, args)?,
Some(subcommand) => {
bad_arguments!("Unknown subcommand: {}", subcommand)
}

View File

@ -4,7 +4,7 @@ use anyhow::Context;
use pico_args::Arguments;
use xshell::Shell;
use crate::util::flatten_args;
use crate::{install_warp, util::flatten_args};
pub fn run_tests(
shell: Shell,
@ -13,9 +13,43 @@ pub fn run_tests(
) -> anyhow::Result<()> {
let llvm_cov = args.contains("--llvm-cov");
let list = args.contains("--list");
let cargo_args = flatten_args(args, passthrough_args);
// Determine the build profile from arguments
let is_release = args.contains("--release");
let custom_profile = args
.opt_value_from_str::<_, String>("--cargo-profile")
.ok()
.flatten();
let profile = if is_release {
"release"
} else if let Some(ref p) = custom_profile {
p.as_str()
} else {
"debug"
};
let mut cargo_args = flatten_args(args, passthrough_args);
// Re-add profile flags that were consumed during argument parsing
if is_release {
cargo_args.insert(0, OsString::from("--release"));
} else if let Some(ref p) = custom_profile {
cargo_args.insert(0, OsString::from(format!("--cargo-profile={p}")));
}
// Retries handled by cargo nextest natively
// Install WARP on Windows for D3D12 testing
if cfg!(target_os = "windows") {
let llvm_cov_dir = if llvm_cov {
"target/llvm-cov-target"
} else {
"target"
};
let target_dir = format!("{llvm_cov_dir}/{profile}");
install_warp::install_warp(&shell, &target_dir)?;
}
// These needs to match the command in "run wgpu-info" in `.github/workflows/ci.yml`
let llvm_cov_flags: &[_] = if llvm_cov {
&["llvm-cov", "--no-cfg-coverage", "--no-report"]