From 61bfc96f400f34d2e9c995dd6ce518058336a53e Mon Sep 17 00:00:00 2001 From: Douglas Dwyer Date: Wed, 20 Nov 2024 22:00:24 -0500 Subject: [PATCH 1/6] Add dependency on mach-dxcompiler-rs and support statically linking DXC --- Cargo.lock | 10 +++ Cargo.toml | 1 + wgpu-hal/Cargo.toml | 3 + wgpu-hal/src/dx12/instance.rs | 20 ++++- wgpu-hal/src/dx12/shader_compilation.rs | 108 ++++++++++++++++-------- wgpu-types/src/lib.rs | 3 + wgpu/Cargo.toml | 3 + 7 files changed, 109 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8ff6df69e7..5fd91ca764 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1778,6 +1778,15 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "mach-dxcompiler-rs" +version = "2023.12.14+0b7073b.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b7857414cb65eb5f03cf0365ac801f089fdbfbb0c47f3f257941eda735aebdf" +dependencies = [ + "windows-core", +] + [[package]] name = "malloc_buf" version = "0.0.6" @@ -3692,6 +3701,7 @@ dependencies = [ "libc", "libloading", "log", + "mach-dxcompiler-rs", "metal", "naga", "ndk-sys", diff --git a/Cargo.toml b/Cargo.toml index 5e11425756..74cadd8f9f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -149,6 +149,7 @@ gpu-descriptor = "0.3" bit-set = "0.8" gpu-allocator = { version = "0.27", default-features = false } range-alloc = "0.1" +mach-dxcompiler-rs = { version = "2023.12.14+0b7073b.1", default-features = false } windows-core = { version = "0.58", default-features = false } # Gles dependencies diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index 35e85f45da..60b2894552 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -91,6 +91,8 @@ dx12 = [ "windows/Win32_System_Threading", "windows/Win32_UI_WindowsAndMessaging", ] +## Enables the static DXC compiler using the `mach-dxcompiler-rs` crate. +mach-dxcompiler-rs = ["dep:mach-dxcompiler-rs"] renderdoc = ["dep:libloading", "dep:renderdoc-sys"] fragile-send-sync-non-atomic-wasm = ["wgt/fragile-send-sync-non-atomic-wasm"] # Panic when running into an out-of-memory error (for debugging purposes). @@ -158,6 +160,7 @@ windows = { workspace = true, optional = true } bit-set = { workspace = true, optional = true } range-alloc = { workspace = true, optional = true } gpu-allocator = { workspace = true, optional = true } +mach-dxcompiler-rs = { workspace = true, optional = true } # For core macros. This crate is also reexported as windows::core. windows-core = { workspace = true, optional = true } diff --git a/wgpu-hal/src/dx12/instance.rs b/wgpu-hal/src/dx12/instance.rs index 31d0511d39..4d5a78d545 100644 --- a/wgpu-hal/src/dx12/instance.rs +++ b/wgpu-hal/src/dx12/instance.rs @@ -80,10 +80,22 @@ impl crate::Instance for super::Instance { dxil_path, dxc_path, } => { - let container = super::shader_compilation::get_dxc_container(dxc_path, dxil_path) - .map_err(|e| { - crate::InstanceError::with_source(String::from("Failed to load DXC"), e) - })?; + let container = + super::shader_compilation::get_dynamic_dxc_container(dxc_path, dxil_path) + .map_err(|e| { + crate::InstanceError::with_source(String::from("Failed to load DXC"), e) + })?; + + container.map(Arc::new) + } + wgt::Dx12Compiler::MachDxc => { + let container = + super::shader_compilation::get_mach_dxc_container().map_err(|e| { + crate::InstanceError::with_source( + String::from("Failed to load Mach DXC"), + e, + ) + })?; container.map(Arc::new) } diff --git a/wgpu-hal/src/dx12/shader_compilation.rs b/wgpu-hal/src/dx12/shader_compilation.rs index b95ccaa5a5..b504a8b25b 100644 --- a/wgpu-hal/src/dx12/shader_compilation.rs +++ b/wgpu-hal/src/dx12/shader_compilation.rs @@ -78,6 +78,12 @@ pub(super) fn compile_fxc( } } +type DxcCreateInstanceFn = unsafe extern "system" fn( + rclsid: *const windows_core::GUID, + riid: *const windows_core::GUID, + ppv: *mut *mut core::ffi::c_void, +) -> windows_core::HRESULT; + trait DxcObj: Interface { const CLSID: windows::core::GUID; } @@ -97,7 +103,10 @@ struct DxcLib { } impl DxcLib { - fn new(lib_path: Option, lib_name: &'static str) -> Result { + fn new_dynamic( + lib_path: Option, + lib_name: &'static str, + ) -> Result { let lib_path = if let Some(lib_path) = lib_path { if lib_path.is_file() { lib_path @@ -111,15 +120,19 @@ impl DxcLib { } pub fn create_instance(&self) -> Result { - type Fun = extern "system" fn( - rclsid: *const windows_core::GUID, - riid: *const windows_core::GUID, - ppv: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT; - let func: libloading::Symbol = unsafe { self.lib.get(b"DxcCreateInstance\0") }?; + unsafe { + let func: libloading::Symbol = + self.lib.get(b"DxcCreateInstance\0")?; + dxc_create_instance::(*func) + } + } +} +/// Invokes the provided library function to create a DXC object. +unsafe fn dxc_create_instance(f: DxcCreateInstanceFn) -> Result { + unsafe { let mut result__ = None; - (func)(&T::CLSID, &T::IID, <*mut _>::cast(&mut result__)) + f(&T::CLSID, &T::IID, <*mut _>::cast(&mut result__)) .ok() .into_device_result("DxcCreateInstance")?; result__.ok_or(crate::DeviceError::Unexpected) @@ -130,18 +143,20 @@ impl DxcLib { pub(super) struct DxcContainer { compiler: Dxc::IDxcCompiler3, utils: Dxc::IDxcUtils, - validator: Dxc::IDxcValidator, + validator: Option, // Has to be held onto for the lifetime of the device otherwise shaders will fail to compile. - _dxc: DxcLib, + // Only needed when using dynamic linking. + _dxc: Option, // Also Has to be held onto for the lifetime of the device otherwise shaders will fail to validate. - _dxil: DxcLib, + // Only needed when using dynamic linking. + _dxil: Option, } -pub(super) fn get_dxc_container( +pub(super) fn get_dynamic_dxc_container( dxc_path: Option, dxil_path: Option, ) -> Result, crate::DeviceError> { - let dxc = match DxcLib::new(dxc_path, "dxcompiler.dll") { + let dxc = match DxcLib::new_dynamic(dxc_path, "dxcompiler.dll") { Ok(dxc) => dxc, Err(e) => { log::warn!( @@ -153,7 +168,7 @@ pub(super) fn get_dxc_container( } }; - let dxil = match DxcLib::new(dxil_path, "dxil.dll") { + let dxil = match DxcLib::new_dynamic(dxil_path, "dxil.dll") { Ok(dxil) => dxil, Err(e) => { log::warn!( @@ -172,12 +187,37 @@ pub(super) fn get_dxc_container( Ok(Some(DxcContainer { compiler, utils, - validator, - _dxc: dxc, - _dxil: dxil, + validator: Some(validator), + _dxc: Some(dxc), + _dxil: Some(dxil), })) } +/// Creates a [`DxcContainer`] that delegates to the statically-linked `mach-dxcompiler` library. +pub(super) fn get_mach_dxc_container() -> Result, crate::DeviceError> { + #[cfg(feature = "mach-dxcompiler-rs")] + { + unsafe { + let compiler = + dxc_create_instance::(mach_dxcompiler_rs::DxcCreateInstance)?; + let utils = + dxc_create_instance::(mach_dxcompiler_rs::DxcCreateInstance)?; + + Ok(Some(DxcContainer { + compiler, + utils, + validator: None, + _dxc: None, + _dxil: None, + })) + } + } + #[cfg(not(feature = "mach-dxcompiler-rs"))] + { + panic!("Attempted to create a Mach DXC shader compiler, but the mach-dxcompiler-rs feature was not enabled") + } +} + /// Owned PCWSTR #[allow(clippy::upper_case_acronyms)] struct OPCWSTR { @@ -288,26 +328,24 @@ pub(super) fn compile_dxc( let blob = get_output::(&compile_res, Dxc::DXC_OUT_OBJECT)?; - let err_blob = { - let res = unsafe { - dxc_container - .validator - .Validate(&blob, Dxc::DxcValidatorFlags_InPlaceEdit) - } - .into_device_result("Validate")?; + if let Some(validator) = &dxc_container.validator { + let err_blob = { + let res = unsafe { validator.Validate(&blob, Dxc::DxcValidatorFlags_InPlaceEdit) } + .into_device_result("Validate")?; - unsafe { res.GetErrorBuffer() }.into_device_result("GetErrorBuffer")? - }; + unsafe { res.GetErrorBuffer() }.into_device_result("GetErrorBuffer")? + }; - let size = unsafe { err_blob.GetBufferSize() }; - if size != 0 { - let err_blob = unsafe { dxc_container.utils.GetBlobAsUtf8(&err_blob) } - .into_device_result("GetBlobAsUtf8")?; - let err = as_err_str(&err_blob)?; - return Err(crate::PipelineError::Linkage( - stage_bit, - format!("DXC validation error: {err}"), - )); + let size = unsafe { err_blob.GetBufferSize() }; + if size != 0 { + let err_blob = unsafe { dxc_container.utils.GetBlobAsUtf8(&err_blob) } + .into_device_result("GetBlobAsUtf8")?; + let err = as_err_str(&err_blob)?; + return Err(crate::PipelineError::Linkage( + stage_bit, + format!("DXC validation error: {err}"), + )); + } } Ok(crate::dx12::CompiledShader::Dxc(blob)) diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 8053c57238..29d822b5d5 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -7401,6 +7401,9 @@ pub enum Dx12Compiler { /// Path to the `dxcompiler.dll` file, or path to the directory containing `dxcompiler.dll` file. Passing `None` will use standard platform specific dll loading rules. dxc_path: Option, }, + /// The statically-linked variant of Dxc, sourced from the [`mach-dxcompiler-rs`](https://crates.io/crates/mach-dxcompiler-rs) crate. + /// The `mach-dxcompiler-rs` feature is required to use this. + MachDxc, } /// Selects which OpenGL ES 3 minor version to request. diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index ed630133e2..eafc98aa67 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -73,6 +73,9 @@ glsl = ["naga/glsl-in", "wgc/glsl"] ## Enable accepting WGSL shaders as input. wgsl = ["wgc?/wgsl"] +## Enables the static DXC compiler using the `mach-dxcompiler-rs` crate. +mach-dxcompiler-rs = ["hal/mach-dxcompiler-rs"] + ## Enable accepting naga IR shaders as input. naga-ir = ["dep:naga"] From 38346d655c711a3606aa0566f72c7d08bbd1d9e3 Mon Sep 17 00:00:00 2001 From: Douglas Dwyer Date: Wed, 20 Nov 2024 22:19:36 -0500 Subject: [PATCH 2/6] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dee57f6e78..193fda3b36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -105,6 +105,7 @@ By @ErichDonGubler in [#6456](https://github.com/gfx-rs/wgpu/pull/6456), [#6148] - Return submission index in `map_async` and `on_submitted_work_done` to track down completion of async callbacks. By @eliemichel in [#6360](https://github.com/gfx-rs/wgpu/pull/6360). - Move raytracing alignments into HAL instead of in core. By @Vecvec in [#6563](https://github.com/gfx-rs/wgpu/pull/6563). +- Allow for statically linking DXC rather than including separate `.dll` files. By @DouglasDwyer in [#6574](https://github.com/gfx-rs/wgpu/pull/6574). ### Changes From 9868e0bf09a86732ed187526a271b00daa66d095 Mon Sep 17 00:00:00 2001 From: Douglas Dwyer Date: Fri, 22 Nov 2024 16:54:30 -0500 Subject: [PATCH 3/6] Update to newer version of mach-dxcompiler-rs --- Cargo.lock | 7 +--- Cargo.toml | 2 +- wgpu-hal/src/dx12/shader_compilation.rs | 53 ++++++++++++++++--------- 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5fd91ca764..cfcd6a78ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1780,12 +1780,9 @@ dependencies = [ [[package]] name = "mach-dxcompiler-rs" -version = "2023.12.14+0b7073b.1" +version = "0.1.0+2024.11.22-df583a3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b7857414cb65eb5f03cf0365ac801f089fdbfbb0c47f3f257941eda735aebdf" -dependencies = [ - "windows-core", -] +checksum = "f1adb8f5a21376264c903e4b6b0b5deb97236ccf8c49d9bd7e557bfe7d241388" [[package]] name = "malloc_buf" diff --git a/Cargo.toml b/Cargo.toml index 74cadd8f9f..1f01415298 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -149,7 +149,7 @@ gpu-descriptor = "0.3" bit-set = "0.8" gpu-allocator = { version = "0.27", default-features = false } range-alloc = "0.1" -mach-dxcompiler-rs = { version = "2023.12.14+0b7073b.1", default-features = false } +mach-dxcompiler-rs = { version = "0.1.0", default-features = false } windows-core = { version = "0.58", default-features = false } # Gles dependencies diff --git a/wgpu-hal/src/dx12/shader_compilation.rs b/wgpu-hal/src/dx12/shader_compilation.rs index b504a8b25b..31817e6270 100644 --- a/wgpu-hal/src/dx12/shader_compilation.rs +++ b/wgpu-hal/src/dx12/shader_compilation.rs @@ -78,12 +78,6 @@ pub(super) fn compile_fxc( } } -type DxcCreateInstanceFn = unsafe extern "system" fn( - rclsid: *const windows_core::GUID, - riid: *const windows_core::GUID, - ppv: *mut *mut core::ffi::c_void, -) -> windows_core::HRESULT; - trait DxcObj: Interface { const CLSID: windows::core::GUID; } @@ -121,22 +115,33 @@ impl DxcLib { pub fn create_instance(&self) -> Result { unsafe { + type DxcCreateInstanceFn = unsafe extern "system" fn( + rclsid: *const windows_core::GUID, + riid: *const windows_core::GUID, + ppv: *mut *mut core::ffi::c_void, + ) + -> windows_core::HRESULT; + let func: libloading::Symbol = self.lib.get(b"DxcCreateInstance\0")?; - dxc_create_instance::(*func) + dxc_create_instance::(|clsid, iid, ppv| func(clsid, iid, ppv)) } } } /// Invokes the provided library function to create a DXC object. -unsafe fn dxc_create_instance(f: DxcCreateInstanceFn) -> Result { - unsafe { - let mut result__ = None; - f(&T::CLSID, &T::IID, <*mut _>::cast(&mut result__)) - .ok() - .into_device_result("DxcCreateInstance")?; - result__.ok_or(crate::DeviceError::Unexpected) - } +unsafe fn dxc_create_instance( + f: impl Fn( + *const windows_core::GUID, + *const windows_core::GUID, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, +) -> Result { + let mut result__ = None; + f(&T::CLSID, &T::IID, <*mut _>::cast(&mut result__)) + .ok() + .into_device_result("DxcCreateInstance")?; + result__.ok_or(crate::DeviceError::Unexpected) } // Destructor order should be fine since _dxil and _dxc don't rely on each other. @@ -198,10 +203,20 @@ pub(super) fn get_mach_dxc_container() -> Result, crate::De #[cfg(feature = "mach-dxcompiler-rs")] { unsafe { - let compiler = - dxc_create_instance::(mach_dxcompiler_rs::DxcCreateInstance)?; - let utils = - dxc_create_instance::(mach_dxcompiler_rs::DxcCreateInstance)?; + let compiler = dxc_create_instance::(|clsid, iid, ppv| { + windows_core::HRESULT(mach_dxcompiler_rs::DxcCreateInstance( + clsid.cast(), + iid.cast(), + ppv, + )) + })?; + let utils = dxc_create_instance::(|clsid, iid, ppv| { + windows_core::HRESULT(mach_dxcompiler_rs::DxcCreateInstance( + clsid.cast(), + iid.cast(), + ppv, + )) + })?; Ok(Some(DxcContainer { compiler, From 79ac1d1ef7ec66ffdb7e6619020f1b198579cbe5 Mon Sep 17 00:00:00 2001 From: Douglas Dwyer Date: Wed, 27 Nov 2024 19:31:32 -0500 Subject: [PATCH 4/6] Only pass DXC_ARG_SKIP_VALIDATION if there is a validator to use later --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- wgpu-hal/src/dx12/shader_compilation.rs | 5 ++++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cfcd6a78ba..2e7a7141aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1780,9 +1780,9 @@ dependencies = [ [[package]] name = "mach-dxcompiler-rs" -version = "0.1.0+2024.11.22-df583a3.1" +version = "0.1.2+2024.11.22-df583a3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1adb8f5a21376264c903e4b6b0b5deb97236ccf8c49d9bd7e557bfe7d241388" +checksum = "a30a333be477f592794a1c1c5739b1a64021ec0e5fb10a1bb5f0feab5b913f5f" [[package]] name = "malloc_buf" diff --git a/Cargo.toml b/Cargo.toml index 1f01415298..e08cd1a1ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -149,7 +149,7 @@ gpu-descriptor = "0.3" bit-set = "0.8" gpu-allocator = { version = "0.27", default-features = false } range-alloc = "0.1" -mach-dxcompiler-rs = { version = "0.1.0", default-features = false } +mach-dxcompiler-rs = { version = "0.1.2", default-features = false } windows-core = { version = "0.58", default-features = false } # Gles dependencies diff --git a/wgpu-hal/src/dx12/shader_compilation.rs b/wgpu-hal/src/dx12/shader_compilation.rs index 31817e6270..41ae6d1303 100644 --- a/wgpu-hal/src/dx12/shader_compilation.rs +++ b/wgpu-hal/src/dx12/shader_compilation.rs @@ -300,9 +300,12 @@ pub(super) fn compile_dxc( windows::core::w!("2018"), // Use HLSL 2018, Naga doesn't supported 2021 yet. windows::core::w!("-no-warnings"), Dxc::DXC_ARG_ENABLE_STRICTNESS, - Dxc::DXC_ARG_SKIP_VALIDATION, // Disable implicit validation to work around bugs when dxil.dll isn't in the local directory. ]); + if dxc_container.validator.is_some() { + compile_args.push(Dxc::DXC_ARG_SKIP_VALIDATION); // Disable implicit validation to work around bugs when dxil.dll isn't in the local directory.) + } + if device .private_caps .instance_flags From bc317add2d2b4f30bca9eb7e42a6179fb0e4f7b4 Mon Sep 17 00:00:00 2001 From: Douglas Dwyer Date: Sun, 1 Dec 2024 20:44:49 -0500 Subject: [PATCH 5/6] Rename mach DXC to static DXC --- wgpu-hal/Cargo.toml | 4 ++-- wgpu-hal/examples/ray-traced-triangle/main.rs | 2 +- wgpu-hal/src/dx12/instance.rs | 13 ++++++++----- wgpu-hal/src/dx12/shader_compilation.rs | 10 +++++----- wgpu-types/src/lib.rs | 8 ++++---- wgpu/Cargo.toml | 15 ++++++++++++--- wgpu/src/util/init.rs | 2 +- 7 files changed, 33 insertions(+), 21 deletions(-) diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index 60b2894552..72e765f1af 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -91,8 +91,8 @@ dx12 = [ "windows/Win32_System_Threading", "windows/Win32_UI_WindowsAndMessaging", ] -## Enables the static DXC compiler using the `mach-dxcompiler-rs` crate. -mach-dxcompiler-rs = ["dep:mach-dxcompiler-rs"] +## Enables statically linking DXC. +static-dxc = ["dep:mach-dxcompiler-rs"] renderdoc = ["dep:libloading", "dep:renderdoc-sys"] fragile-send-sync-non-atomic-wasm = ["wgt/fragile-send-sync-non-atomic-wasm"] # Panic when running into an out-of-memory error (for debugging purposes). diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index 7212988f48..6754dc36a9 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -239,7 +239,7 @@ impl Example { let instance_desc = hal::InstanceDescriptor { name: "example", flags: wgt::InstanceFlags::default(), - dx12_shader_compiler: wgt::Dx12Compiler::Dxc { + dx12_shader_compiler: wgt::Dx12Compiler::DynamicDxc { dxil_path: None, dxc_path: None, }, diff --git a/wgpu-hal/src/dx12/instance.rs b/wgpu-hal/src/dx12/instance.rs index 4d5a78d545..389843a21c 100644 --- a/wgpu-hal/src/dx12/instance.rs +++ b/wgpu-hal/src/dx12/instance.rs @@ -76,23 +76,26 @@ impl crate::Instance for super::Instance { // Initialize DXC shader compiler let dxc_container = match desc.dx12_shader_compiler.clone() { - wgt::Dx12Compiler::Dxc { + wgt::Dx12Compiler::DynamicDxc { dxil_path, dxc_path, } => { let container = super::shader_compilation::get_dynamic_dxc_container(dxc_path, dxil_path) .map_err(|e| { - crate::InstanceError::with_source(String::from("Failed to load DXC"), e) + crate::InstanceError::with_source( + String::from("Failed to load dynamic DXC"), + e, + ) })?; container.map(Arc::new) } - wgt::Dx12Compiler::MachDxc => { + wgt::Dx12Compiler::StaticDxc => { let container = - super::shader_compilation::get_mach_dxc_container().map_err(|e| { + super::shader_compilation::get_static_dxc_container().map_err(|e| { crate::InstanceError::with_source( - String::from("Failed to load Mach DXC"), + String::from("Failed to load static DXC"), e, ) })?; diff --git a/wgpu-hal/src/dx12/shader_compilation.rs b/wgpu-hal/src/dx12/shader_compilation.rs index 41ae6d1303..96865b9080 100644 --- a/wgpu-hal/src/dx12/shader_compilation.rs +++ b/wgpu-hal/src/dx12/shader_compilation.rs @@ -198,9 +198,9 @@ pub(super) fn get_dynamic_dxc_container( })) } -/// Creates a [`DxcContainer`] that delegates to the statically-linked `mach-dxcompiler` library. -pub(super) fn get_mach_dxc_container() -> Result, crate::DeviceError> { - #[cfg(feature = "mach-dxcompiler-rs")] +/// Creates a [`DxcContainer`] that delegates to the statically-linked version of DXC. +pub(super) fn get_static_dxc_container() -> Result, crate::DeviceError> { + #[cfg(feature = "static-dxc")] { unsafe { let compiler = dxc_create_instance::(|clsid, iid, ppv| { @@ -227,9 +227,9 @@ pub(super) fn get_mach_dxc_container() -> Result, crate::De })) } } - #[cfg(not(feature = "mach-dxcompiler-rs"))] + #[cfg(not(feature = "static-dxc"))] { - panic!("Attempted to create a Mach DXC shader compiler, but the mach-dxcompiler-rs feature was not enabled") + panic!("Attempted to create a static DXC shader compiler, but the static-dxc feature was not enabled") } } diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 29d822b5d5..c8d0ccb699 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -7395,15 +7395,15 @@ pub enum Dx12Compiler { /// Minimum supported version: [v1.5.2010](https://github.com/microsoft/DirectXShaderCompiler/releases/tag/v1.5.2010) /// /// It also requires WDDM 2.1 (Windows 10 version 1607). - Dxc { + DynamicDxc { /// Path to the `dxil.dll` file, or path to the directory containing `dxil.dll` file. Passing `None` will use standard platform specific dll loading rules. dxil_path: Option, /// Path to the `dxcompiler.dll` file, or path to the directory containing `dxcompiler.dll` file. Passing `None` will use standard platform specific dll loading rules. dxc_path: Option, }, - /// The statically-linked variant of Dxc, sourced from the [`mach-dxcompiler-rs`](https://crates.io/crates/mach-dxcompiler-rs) crate. - /// The `mach-dxcompiler-rs` feature is required to use this. - MachDxc, + /// The statically-linked variant of Dxc. + /// The `static-dxc` feature is required to use this. + StaticDxc, } /// Selects which OpenGL ES 3 minor version to request. diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index eafc98aa67..d05731958d 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -73,9 +73,6 @@ glsl = ["naga/glsl-in", "wgc/glsl"] ## Enable accepting WGSL shaders as input. wgsl = ["wgc?/wgsl"] -## Enables the static DXC compiler using the `mach-dxcompiler-rs` crate. -mach-dxcompiler-rs = ["hal/mach-dxcompiler-rs"] - ## Enable accepting naga IR shaders as input. naga-ir = ["dep:naga"] @@ -120,6 +117,18 @@ fragile-send-sync-non-atomic-wasm = [ "wgt/fragile-send-sync-non-atomic-wasm", ] + +#! ### External libraries +# -------------------------------------------------------------------- +#! The following features facilitate integration with third-party supporting libraries. + +## Enables statically linking DXC. +## Normally, to use the modern DXC shader compiler with WGPU, the final application +## must be shipped alongside `dxcompiler.dll` and `dxil.dll` (which can be downloaded from Microsoft's GitHub). +## This feature statically links a version of DXC so that no external binaries are required +## to compile DX12 shaders. +static-dxc = ["hal/static-dxc"] + # wgpu-core is always available as an optional dependency, "wgc". # Whenever wgpu-core is selected, we want raw window handle support. [dependencies.wgc] diff --git a/wgpu/src/util/init.rs b/wgpu/src/util/init.rs index 573fe3bd80..f1f63c3f86 100644 --- a/wgpu/src/util/init.rs +++ b/wgpu/src/util/init.rs @@ -107,7 +107,7 @@ pub fn dx12_shader_compiler_from_env() -> Option { .map(str::to_lowercase) .as_deref() { - Ok("dxc") => wgt::Dx12Compiler::Dxc { + Ok("dxc") => wgt::Dx12Compiler::DynamicDxc { dxil_path: None, dxc_path: None, }, From 55e80b7512ca4aa5ffd28ff72c4f298eac8b8da9 Mon Sep 17 00:00:00 2001 From: Douglas Dwyer Date: Sun, 1 Dec 2024 22:49:05 -0500 Subject: [PATCH 6/6] Add test command line flag for static-dxc --- README.md | 2 +- wgpu/src/util/init.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bdd587b573..fb571bd016 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ All testing and example infrastructure share the same set of environment variabl - `WGPU_ADAPTER_NAME` with a substring of the name of the adapter you want to use (ex. `1080` will match `NVIDIA GeForce 1080ti`). - `WGPU_BACKEND` with a comma-separated list of the backends you want to use (`vulkan`, `metal`, `dx12`, or `gl`). - `WGPU_POWER_PREF` with the power preference to choose when a specific adapter name isn't specified (`high`, `low` or `none`) -- `WGPU_DX12_COMPILER` with the DX12 shader compiler you wish to use (`dxc` or `fxc`, note that `dxc` requires `dxil.dll` and `dxcompiler.dll` to be in the working directory otherwise it will fall back to `fxc`) +- `WGPU_DX12_COMPILER` with the DX12 shader compiler you wish to use (`dxc`, `static-dxc`, or `fxc`). Note that `dxc` requires `dxil.dll` and `dxcompiler.dll` to be in the working directory, and `static-dxc` requires the `static-dxc` crate feature to be enabled. Otherwise, it will fall back to `fxc`. - `WGPU_GLES_MINOR_VERSION` with the minor OpenGL ES 3 version number to request (`0`, `1`, `2` or `automatic`). - `WGPU_ALLOW_UNDERLYING_NONCOMPLIANT_ADAPTER` with a boolean whether non-compliant drivers are enumerated (`0` for false, `1` for true). diff --git a/wgpu/src/util/init.rs b/wgpu/src/util/init.rs index f1f63c3f86..2419f4be9c 100644 --- a/wgpu/src/util/init.rs +++ b/wgpu/src/util/init.rs @@ -111,6 +111,8 @@ pub fn dx12_shader_compiler_from_env() -> Option { dxil_path: None, dxc_path: None, }, + #[cfg(feature = "static-dxc")] + Ok("static-dxc") => wgt::Dx12Compiler::StaticDxc, Ok("fxc") => wgt::Dx12Compiler::Fxc, _ => return None, },