[d3d12] remove the need for dxil.dll (#7566)

This commit is contained in:
Teodor Tanasoaia 2025-04-17 16:21:36 +02:00 committed by GitHub
parent c7330a8b49
commit 6ea7962da7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 12 additions and 69 deletions

View File

@ -547,7 +547,7 @@ jobs:
set -e
curl.exe -L --retry 5 https://github.com/microsoft/DirectXShaderCompiler/releases/download/$DXC_RELEASE/$DXC_FILENAME -o dxc.zip
7z.exe e dxc.zip -odxc bin/x64/{dxc.exe,dxcompiler.dll,dxil.dll}
7z.exe e dxc.zip -odxc bin/x64/{dxc.exe,dxcompiler.dll}
# We need to use cygpath to convert PWD to a windows path as we're using bash.
cygpath --windows "$PWD/dxc" >> "$GITHUB_PATH"

View File

@ -64,7 +64,7 @@ jobs:
set -e
curl.exe -L --retry 5 https://github.com/microsoft/DirectXShaderCompiler/releases/download/$DXC_RELEASE/$DXC_FILENAME -o dxc.zip
7z.exe e dxc.zip -odxc bin/x64/{dxc.exe,dxcompiler.dll,dxil.dll}
7z.exe e dxc.zip -odxc bin/x64/{dxc.exe,dxcompiler.dll}
# We need to use cygpath to convert PWD to a windows path as we're using bash.
cygpath --windows "$PWD/dxc" >> "$GITHUB_PATH"

View File

@ -67,6 +67,10 @@ Naga now infers the correct binding layout when a resource appears only in an as
- Mark `readonly_and_readwrite_storage_textures` & `packed_4x8_integer_dot_product` language extensions as implemented. By @teoxoy in [#7543](https://github.com/gfx-rs/wgpu/pull/7543)
#### D3D12
- Remove the need for dxil.dll. By @teoxoy in [#7566](https://github.com/gfx-rs/wgpu/pull/7566)
### Bug Fixes
#### Naga

View File

@ -168,7 +168,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`, `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_DX12_COMPILER` with the DX12 shader compiler you wish to use (`dxc`, `static-dxc`, or `fxc`). Note that `dxc` requires `dxcompiler.dll` (min v1.8.2502) 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).

View File

@ -69,13 +69,11 @@ impl crate::Instance for super::Instance {
// Initialize DXC shader compiler
let dxc_container = match desc.backend_options.dx12.shader_compiler.clone() {
wgt::Dx12Compiler::DynamicDxc {
dxil_path,
dxc_path,
max_shader_model,
} => {
let container = super::shader_compilation::get_dynamic_dxc_container(
dxc_path.into(),
dxil_path.into(),
max_shader_model,
)
.map_err(|e| {

View File

@ -7,10 +7,6 @@ use windows::{
Win32::Graphics::Direct3D::{Dxc, Fxc},
};
// Currently this will use Dxc if it is chosen as the dx12 compiler at `Instance` creation time, and will
// fallback to FXC if the Dxc libraries (dxil.dll and dxcompiler.dll) are not found, or if Fxc is chosen at'
// `Instance` creation time.
pub(super) fn compile_fxc(
device: &super::Device,
source: &str,
@ -134,18 +130,12 @@ unsafe fn dxc_create_instance<T: DxcObj>(
result__.ok_or(crate::DeviceError::Unexpected)
}
// Destructor order should be fine since _dxil and _dxc don't rely on each other.
pub(super) struct DxcContainer {
pub(super) max_shader_model: wgt::DxcShaderModel,
compiler: Dxc::IDxcCompiler3,
utils: Dxc::IDxcUtils,
validator: Option<Dxc::IDxcValidator>,
// Has to be held onto for the lifetime of the device otherwise shaders will fail to compile.
// Only needed when using dynamic linking.
_dxc: Option<DxcLib>,
// Also Has to be held onto for the lifetime of the device otherwise shaders will fail to validate.
// Only needed when using dynamic linking.
_dxil: Option<DxcLib>,
}
#[derive(Debug, Error)]
@ -158,26 +148,17 @@ pub(super) enum GetDynamicDXCContainerError {
pub(super) fn get_dynamic_dxc_container(
dxc_path: PathBuf,
dxil_path: PathBuf,
max_shader_model: wgt::DxcShaderModel,
) -> Result<DxcContainer, GetDynamicDXCContainerError> {
let dxc = DxcLib::new_dynamic(dxc_path)
.map_err(|e| GetDynamicDXCContainerError::FailedToLoad("dxcompiler.dll", e))?;
let dxil = DxcLib::new_dynamic(dxil_path)
.map_err(|e| GetDynamicDXCContainerError::FailedToLoad("dxil.dll", e))?;
let compiler = dxc.create_instance::<Dxc::IDxcCompiler3>()?;
let utils = dxc.create_instance::<Dxc::IDxcUtils>()?;
let validator = dxil.create_instance::<Dxc::IDxcValidator>()?;
Ok(DxcContainer {
max_shader_model,
compiler,
utils,
validator: Some(validator),
_dxc: Some(dxc),
_dxil: Some(dxil),
})
}
@ -193,21 +174,11 @@ pub(super) fn get_static_dxc_container() -> Result<DxcContainer, crate::DeviceEr
ppv,
))
})?;
let utils = dxc_create_instance::<Dxc::IDxcUtils>(|clsid, iid, ppv| {
windows_core::HRESULT(mach_dxcompiler_rs::DxcCreateInstance(
clsid.cast(),
iid.cast(),
ppv,
))
})?;
Ok(DxcContainer {
max_shader_model: wgt::DxcShaderModel::V6_7,
compiler,
utils,
validator: None,
_dxc: None,
_dxil: None,
})
}
}
@ -286,10 +257,6 @@ pub(super) fn compile_dxc(
Dxc::DXC_ARG_ENABLE_STRICTNESS,
]);
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
.shared
.private_caps
@ -335,25 +302,5 @@ pub(super) fn compile_dxc(
let blob = get_output::<Dxc::IDxcBlob>(&compile_res, Dxc::DXC_OUT_OBJECT)?;
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")?
};
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))
}

View File

@ -394,9 +394,6 @@ pub enum DxcShaderModel {
}
/// Selects which DX12 shader compiler to use.
///
/// If the `DynamicDxc` option is selected, but `dxcompiler.dll` and `dxil.dll` files aren't found,
/// then this will fall back to the Fxc compiler at runtime and log an error.
#[derive(Clone, Debug, Default)]
pub enum Dx12Compiler {
/// The Fxc compiler (default) is old, slow and unmaintained.
@ -406,17 +403,15 @@ pub enum Dx12Compiler {
Fxc,
/// The Dxc compiler is new, fast and maintained.
///
/// However, it requires both `dxcompiler.dll` and `dxil.dll` to be shipped with the application.
/// However, it requires `dxcompiler.dll` to be shipped with the application.
/// These files can be downloaded from <https://github.com/microsoft/DirectXShaderCompiler/releases>.
///
/// Minimum supported version: [v1.5.2010](https://github.com/microsoft/DirectXShaderCompiler/releases/tag/v1.5.2010)
/// Minimum supported version: [v1.8.2502](https://github.com/microsoft/DirectXShaderCompiler/releases/tag/v1.8.2502)
///
/// It also requires WDDM 2.1 (Windows 10 version 1607).
DynamicDxc {
/// Path to `dxcompiler.dll`.
dxc_path: String,
/// Path to `dxil.dll`.
dxil_path: String,
/// Maximum shader model the given dll supports.
max_shader_model: DxcShaderModel,
},
@ -430,12 +425,11 @@ pub enum Dx12Compiler {
impl Dx12Compiler {
/// Helper function to construct a `DynamicDxc` variant with default paths.
///
/// The dll must support at least shader model 6.5.
/// The dll must support at least shader model 6.8.
pub fn default_dynamic_dxc() -> Self {
Self::DynamicDxc {
dxc_path: String::from("dxcompiler.dll"),
dxil_path: String::from("dxil.dll"),
max_shader_model: DxcShaderModel::V6_5,
max_shader_model: DxcShaderModel::V6_7, // should be 6.8 but the variant is missing
}
}

View File

@ -121,7 +121,7 @@ serde = ["wgpu-core?/serde", "wgpu-types/serde"]
## 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][dxc]).
## must be shipped alongside `dxcompiler.dll` (min v1.8.2502) (which can be downloaded from [Microsoft's GitHub][dxc]).
## This feature statically links a version of DXC so that no external binaries are required
## to compile DX12 shaders.
##