diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 98fca8a29e..f623e1aece 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -245,12 +245,7 @@ impl super::Device { .as_ref() .map_err(|e| crate::PipelineError::Linkage(stage_bit, format!("{e}")))?; - let source_name = stage - .module - .raw_name - .as_ref() - .and_then(|cstr| cstr.to_str().ok()) - .unwrap_or_default(); + let source_name = stage.module.raw_name.as_deref(); // Compile with DXC if available, otherwise fall back to FXC let (result, log_level) = if let Some(ref dxc_container) = self.dxc_container { diff --git a/wgpu-hal/src/dx12/shader_compilation.rs b/wgpu-hal/src/dx12/shader_compilation.rs index df040dba15..f145b1d491 100644 --- a/wgpu-hal/src/dx12/shader_compilation.rs +++ b/wgpu-hal/src/dx12/shader_compilation.rs @@ -1,3 +1,4 @@ +use std::ffi::CStr; use std::ptr; pub(super) use dxc::{compile_dxc, get_dxc_container, DxcContainer}; @@ -13,8 +14,8 @@ use crate::auxil::dxgi::result::HResult; pub(super) fn compile_fxc( device: &super::Device, - source: &String, - source_name: &str, + source: &str, + source_name: Option<&CStr>, raw_ep: &std::ffi::CString, stage_bit: wgt::ShaderStages, full_stage: String, @@ -32,13 +33,17 @@ pub(super) fn compile_fxc( { compile_flags |= d3dcompiler::D3DCOMPILE_DEBUG | d3dcompiler::D3DCOMPILE_SKIP_OPTIMIZATION; } + + // If no name has been set, D3DCompile wants the null pointer. + let source_name = source_name.map(|cstr| cstr.as_ptr()).unwrap_or(ptr::null()); + let mut error = d3d12::Blob::null(); let hr = unsafe { profiling::scope!("d3dcompiler::D3DCompile"); d3dcompiler::D3DCompile( source.as_ptr().cast(), source.len(), - source_name.as_ptr().cast(), + source_name.cast(), ptr::null(), ptr::null_mut(), raw_ep.as_ptr(), @@ -78,6 +83,7 @@ pub(super) fn compile_fxc( // The Dxc implementation is behind a feature flag so that users who don't want to use dxc can disable the feature. #[cfg(feature = "dxc_shader_compiler")] mod dxc { + use std::ffi::CStr; use std::path::PathBuf; // Destructor order should be fine since _dxil and _dxc don't rely on each other. @@ -132,7 +138,7 @@ mod dxc { pub(crate) fn compile_dxc( device: &crate::dx12::Device, source: &str, - source_name: &str, + source_name: Option<&CStr>, raw_ep: &str, stage_bit: wgt::ShaderStages, full_stage: String, @@ -166,6 +172,10 @@ mod dxc { Err(e) => return (Err(e), log::Level::Error), }; + let source_name = source_name + .and_then(|cstr| cstr.to_str().ok()) + .unwrap_or(""); + let compiled = dxc_container.compiler.compile( &blob, source_name, @@ -263,6 +273,7 @@ mod dxc { // These are stubs for when the `dxc_shader_compiler` feature is disabled. #[cfg(not(feature = "dxc_shader_compiler"))] mod dxc { + use std::ffi::CStr; use std::path::PathBuf; pub(crate) struct DxcContainer {} @@ -280,7 +291,7 @@ mod dxc { pub(crate) fn compile_dxc( _device: &crate::dx12::Device, _source: &str, - _source_name: &str, + _source_name: Option<&CStr>, _raw_ep: &str, _stage_bit: wgt::ShaderStages, _full_stage: String,