mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
Load FXC dynamically to remove the dependency on d3dcompiler_47.dll (#7588)
This commit is contained in:
parent
97794f12a9
commit
d190106c3f
@ -57,7 +57,7 @@ impl super::Adapter {
|
||||
library: &Arc<D3D12Lib>,
|
||||
instance_flags: wgt::InstanceFlags,
|
||||
memory_budget_thresholds: wgt::MemoryBudgetThresholds,
|
||||
dxc_container: Option<Arc<shader_compilation::DxcContainer>>,
|
||||
compiler_container: Arc<shader_compilation::CompilerContainer>,
|
||||
) -> Option<crate::ExposedAdapter<super::Api>> {
|
||||
// Create the device so that we can get the capabilities.
|
||||
let device = {
|
||||
@ -224,8 +224,8 @@ impl super::Adapter {
|
||||
}
|
||||
};
|
||||
|
||||
let shader_model = if let Some(ref dxc_container) = dxc_container {
|
||||
let max_shader_model = match dxc_container.max_shader_model {
|
||||
let shader_model = if let Some(max_shader_model) = compiler_container.max_shader_model() {
|
||||
let max_shader_model = match max_shader_model {
|
||||
wgt::DxcShaderModel::V6_0 => Direct3D12::D3D_SHADER_MODEL_6_0,
|
||||
wgt::DxcShaderModel::V6_1 => Direct3D12::D3D_SHADER_MODEL_6_1,
|
||||
wgt::DxcShaderModel::V6_2 => Direct3D12::D3D_SHADER_MODEL_6_2,
|
||||
@ -519,7 +519,7 @@ impl super::Adapter {
|
||||
presentation_timer,
|
||||
workarounds,
|
||||
memory_budget_thresholds,
|
||||
dxc_container,
|
||||
compiler_container,
|
||||
},
|
||||
info,
|
||||
features,
|
||||
@ -658,7 +658,7 @@ impl crate::Adapter for super::Adapter {
|
||||
self.private_caps,
|
||||
&self.library,
|
||||
self.memory_budget_thresholds,
|
||||
self.dxc_container.clone(),
|
||||
self.compiler_container.clone(),
|
||||
)?;
|
||||
Ok(crate::OpenDevice {
|
||||
device,
|
||||
|
||||
@ -46,7 +46,7 @@ impl super::Device {
|
||||
private_caps: super::PrivateCapabilities,
|
||||
library: &Arc<D3D12Lib>,
|
||||
memory_budget_thresholds: wgt::MemoryBudgetThresholds,
|
||||
dxc_container: Option<Arc<shader_compilation::DxcContainer>>,
|
||||
compiler_container: Arc<shader_compilation::CompilerContainer>,
|
||||
) -> Result<Self, crate::DeviceError> {
|
||||
if private_caps
|
||||
.instance_flags
|
||||
@ -202,7 +202,7 @@ impl super::Device {
|
||||
render_doc: Default::default(),
|
||||
null_rtv_handle,
|
||||
mem_allocator,
|
||||
dxc_container,
|
||||
compiler_container,
|
||||
counters: Default::default(),
|
||||
})
|
||||
}
|
||||
@ -325,27 +325,14 @@ impl super::Device {
|
||||
|
||||
let source_name = stage.module.raw_name.as_deref();
|
||||
|
||||
// Compile with DXC if available, otherwise fall back to FXC
|
||||
let result = if let Some(ref dxc_container) = self.dxc_container {
|
||||
shader_compilation::compile_dxc(
|
||||
self,
|
||||
&source,
|
||||
source_name,
|
||||
raw_ep,
|
||||
stage_bit,
|
||||
&full_stage,
|
||||
dxc_container,
|
||||
)
|
||||
} else {
|
||||
shader_compilation::compile_fxc(
|
||||
self,
|
||||
&source,
|
||||
source_name,
|
||||
raw_ep,
|
||||
stage_bit,
|
||||
&full_stage,
|
||||
)
|
||||
};
|
||||
let result = self.compiler_container.compile(
|
||||
self,
|
||||
&source,
|
||||
source_name,
|
||||
raw_ep,
|
||||
stage_bit,
|
||||
&full_stage,
|
||||
);
|
||||
|
||||
let log_level = if result.is_ok() {
|
||||
log::Level::Info
|
||||
|
||||
@ -10,7 +10,10 @@ use windows::{
|
||||
};
|
||||
|
||||
use super::SurfaceTarget;
|
||||
use crate::{auxil, dx12::D3D12Lib};
|
||||
use crate::{
|
||||
auxil,
|
||||
dx12::{shader_compilation::CompilerContainer, D3D12Lib},
|
||||
};
|
||||
|
||||
impl crate::Instance for super::Instance {
|
||||
type A = super::Api;
|
||||
@ -66,39 +69,34 @@ impl crate::Instance for super::Instance {
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize DXC shader compiler
|
||||
let dxc_container = match desc.backend_options.dx12.shader_compiler.clone() {
|
||||
// Initialize the shader compiler
|
||||
let compiler_container = match desc.backend_options.dx12.shader_compiler.clone() {
|
||||
wgt::Dx12Compiler::DynamicDxc {
|
||||
dxc_path,
|
||||
max_shader_model,
|
||||
} => {
|
||||
let container = super::shader_compilation::get_dynamic_dxc_container(
|
||||
dxc_path.into(),
|
||||
max_shader_model,
|
||||
)
|
||||
.map_err(|e| {
|
||||
} => CompilerContainer::new_dynamic_dxc(dxc_path.into(), max_shader_model).map_err(
|
||||
|e| {
|
||||
crate::InstanceError::with_source(String::from("Failed to load dynamic DXC"), e)
|
||||
})?;
|
||||
|
||||
Some(Arc::new(container))
|
||||
}
|
||||
wgt::Dx12Compiler::StaticDxc => {
|
||||
let container =
|
||||
super::shader_compilation::get_static_dxc_container().map_err(|e| {
|
||||
crate::InstanceError::with_source(
|
||||
String::from("Failed to load static DXC"),
|
||||
e,
|
||||
)
|
||||
})?;
|
||||
|
||||
Some(Arc::new(container))
|
||||
}
|
||||
wgt::Dx12Compiler::Fxc => None,
|
||||
},
|
||||
)?,
|
||||
wgt::Dx12Compiler::StaticDxc => CompilerContainer::new_static_dxc().map_err(|e| {
|
||||
crate::InstanceError::with_source(String::from("Failed to load static DXC"), e)
|
||||
})?,
|
||||
wgt::Dx12Compiler::Fxc => CompilerContainer::new_fxc().map_err(|e| {
|
||||
crate::InstanceError::with_source(String::from("Failed to load FXC"), e)
|
||||
})?,
|
||||
};
|
||||
|
||||
match dxc_container {
|
||||
Some(_) => log::debug!("Using DXC for shader compilation"),
|
||||
None => log::debug!("Using FXC for shader compilation"),
|
||||
match compiler_container {
|
||||
CompilerContainer::DynamicDxc(..) => {
|
||||
log::debug!("Using dynamic DXC for shader compilation")
|
||||
}
|
||||
CompilerContainer::StaticDxc(..) => {
|
||||
log::debug!("Using static DXC for shader compilation")
|
||||
}
|
||||
CompilerContainer::Fxc(..) => {
|
||||
log::debug!("Using FXC for shader compilation")
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
@ -110,7 +108,7 @@ impl crate::Instance for super::Instance {
|
||||
supports_allow_tearing,
|
||||
flags: desc.flags,
|
||||
memory_budget_thresholds: desc.memory_budget_thresholds,
|
||||
dxc_container,
|
||||
compiler_container: Arc::new(compiler_container),
|
||||
})
|
||||
}
|
||||
|
||||
@ -148,7 +146,7 @@ impl crate::Instance for super::Instance {
|
||||
&self.library,
|
||||
self.flags,
|
||||
self.memory_budget_thresholds,
|
||||
self.dxc_container.clone(),
|
||||
self.compiler_container.clone(),
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
|
||||
@ -460,7 +460,7 @@ pub struct Instance {
|
||||
_lib_dxgi: DxgiLib,
|
||||
flags: wgt::InstanceFlags,
|
||||
memory_budget_thresholds: wgt::MemoryBudgetThresholds,
|
||||
dxc_container: Option<Arc<shader_compilation::DxcContainer>>,
|
||||
compiler_container: Arc<shader_compilation::CompilerContainer>,
|
||||
}
|
||||
|
||||
impl Instance {
|
||||
@ -592,7 +592,7 @@ pub struct Adapter {
|
||||
#[allow(unused)]
|
||||
workarounds: Workarounds,
|
||||
memory_budget_thresholds: wgt::MemoryBudgetThresholds,
|
||||
dxc_container: Option<Arc<shader_compilation::DxcContainer>>,
|
||||
compiler_container: Arc<shader_compilation::CompilerContainer>,
|
||||
}
|
||||
|
||||
unsafe impl Send for Adapter {}
|
||||
@ -655,7 +655,7 @@ pub struct Device {
|
||||
render_doc: auxil::renderdoc::RenderDoc,
|
||||
null_rtv_handle: descriptor::Handle,
|
||||
mem_allocator: Allocator,
|
||||
dxc_container: Option<Arc<shader_compilation::DxcContainer>>,
|
||||
compiler_container: Arc<shader_compilation::CompilerContainer>,
|
||||
counters: Arc<wgt::HalCounters>,
|
||||
}
|
||||
|
||||
|
||||
@ -6,19 +6,224 @@ use crate::auxil::dxgi::result::HResult;
|
||||
use thiserror::Error;
|
||||
use windows::{
|
||||
core::{Interface, PCSTR, PCWSTR},
|
||||
Win32::Graphics::Direct3D::{Dxc, Fxc},
|
||||
Win32::Graphics::Direct3D::{Dxc, Fxc, ID3DBlob, D3D_SHADER_MACRO},
|
||||
};
|
||||
|
||||
pub(super) fn compile_fxc(
|
||||
pub(super) enum CompilerContainer {
|
||||
Fxc(CompilerFxc),
|
||||
DynamicDxc(CompilerDynamicDxc),
|
||||
#[cfg_attr(not(static_dxc), allow(unused))]
|
||||
StaticDxc(CompilerStaticDxc),
|
||||
}
|
||||
|
||||
pub(super) struct CompilerFxc {
|
||||
fxc: FxcLib,
|
||||
}
|
||||
|
||||
pub(super) struct CompilerDynamicDxc {
|
||||
max_shader_model: wgt::DxcShaderModel,
|
||||
compiler: Dxc::IDxcCompiler3,
|
||||
// Has to be held onto for the lifetime of the device otherwise shaders will fail to compile.
|
||||
// Only needed when using dynamic linking.
|
||||
_dxc: DxcLib,
|
||||
}
|
||||
|
||||
pub(super) struct CompilerStaticDxc {
|
||||
max_shader_model: wgt::DxcShaderModel,
|
||||
compiler: Dxc::IDxcCompiler3,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub(super) enum GetContainerError {
|
||||
#[error(transparent)]
|
||||
Device(#[from] crate::DeviceError),
|
||||
#[error("Failed to load {0}: {1}")]
|
||||
FailedToLoad(&'static str, libloading::Error),
|
||||
}
|
||||
|
||||
impl CompilerContainer {
|
||||
pub(super) fn new_fxc() -> Result<Self, GetContainerError> {
|
||||
FxcLib::new_dynamic().map(|fxc| Self::Fxc(CompilerFxc { fxc }))
|
||||
}
|
||||
|
||||
pub(super) fn new_dynamic_dxc(
|
||||
dxc_path: PathBuf,
|
||||
max_shader_model: wgt::DxcShaderModel,
|
||||
) -> Result<Self, GetContainerError> {
|
||||
let dxc = DxcLib::new_dynamic(dxc_path)
|
||||
.map_err(|e| GetContainerError::FailedToLoad("dxcompiler.dll", e))?;
|
||||
|
||||
let compiler = dxc.create_instance::<Dxc::IDxcCompiler3>()?;
|
||||
|
||||
Ok(Self::DynamicDxc(CompilerDynamicDxc {
|
||||
max_shader_model,
|
||||
compiler,
|
||||
_dxc: dxc,
|
||||
}))
|
||||
}
|
||||
|
||||
/// Creates a [`CompilerContainer`] that delegates to the statically-linked version of DXC.
|
||||
pub(super) fn new_static_dxc() -> Result<CompilerContainer, crate::DeviceError> {
|
||||
#[cfg(static_dxc)]
|
||||
{
|
||||
unsafe {
|
||||
let compiler = dxc_create_instance::<Dxc::IDxcCompiler3>(|clsid, iid, ppv| {
|
||||
windows_core::HRESULT(mach_dxcompiler_rs::DxcCreateInstance(
|
||||
clsid.cast(),
|
||||
iid.cast(),
|
||||
ppv,
|
||||
))
|
||||
})?;
|
||||
|
||||
Ok(CompilerContainer::StaticDxc(CompilerStaticDxc {
|
||||
max_shader_model: wgt::DxcShaderModel::V6_7,
|
||||
compiler,
|
||||
}))
|
||||
}
|
||||
}
|
||||
#[cfg(not(static_dxc))]
|
||||
{
|
||||
panic!("Attempted to create a static DXC shader compiler, but the static-dxc feature was not enabled")
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn max_shader_model(&self) -> Option<wgt::DxcShaderModel> {
|
||||
match self {
|
||||
CompilerContainer::Fxc(..) => None,
|
||||
CompilerContainer::DynamicDxc(CompilerDynamicDxc {
|
||||
max_shader_model, ..
|
||||
})
|
||||
| CompilerContainer::StaticDxc(CompilerStaticDxc {
|
||||
max_shader_model, ..
|
||||
}) => Some(max_shader_model.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn compile(
|
||||
&self,
|
||||
device: &super::Device,
|
||||
source: &str,
|
||||
source_name: Option<&CStr>,
|
||||
raw_ep: &str,
|
||||
stage_bit: wgt::ShaderStages,
|
||||
full_stage: &str,
|
||||
) -> Result<super::CompiledShader, crate::PipelineError> {
|
||||
match self {
|
||||
CompilerContainer::Fxc(CompilerFxc { fxc }) => compile_fxc(
|
||||
device,
|
||||
source,
|
||||
source_name,
|
||||
raw_ep,
|
||||
stage_bit,
|
||||
full_stage,
|
||||
fxc,
|
||||
),
|
||||
CompilerContainer::DynamicDxc(CompilerDynamicDxc { compiler, .. })
|
||||
| CompilerContainer::StaticDxc(CompilerStaticDxc { compiler, .. }) => compile_dxc(
|
||||
device,
|
||||
source,
|
||||
source_name,
|
||||
raw_ep,
|
||||
stage_bit,
|
||||
full_stage,
|
||||
compiler,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type D3DCompileFn = unsafe extern "system" fn(
|
||||
psrcdata: *const core::ffi::c_void,
|
||||
srcdatasize: usize,
|
||||
psourcename: PCSTR,
|
||||
pdefines: *const D3D_SHADER_MACRO,
|
||||
pinclude: *mut core::ffi::c_void,
|
||||
pentrypoint: PCSTR,
|
||||
ptarget: PCSTR,
|
||||
flags1: u32,
|
||||
flags2: u32,
|
||||
ppcode: *mut *mut core::ffi::c_void,
|
||||
pperrormsgs: *mut *mut core::ffi::c_void,
|
||||
) -> windows_core::HRESULT;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct FxcLib {
|
||||
// `d3dcompile_fn` points into `_lib`, so `_lib` must be held for as long
|
||||
// as we want to keep compiling shaders with FXC.
|
||||
_lib: crate::dx12::DynLib,
|
||||
d3dcompile_fn: D3DCompileFn,
|
||||
}
|
||||
|
||||
impl FxcLib {
|
||||
const PATH: &str = "d3dcompiler_47.dll";
|
||||
|
||||
fn new_dynamic() -> Result<Self, GetContainerError> {
|
||||
unsafe {
|
||||
let lib = crate::dx12::DynLib::new(Self::PATH)
|
||||
.map_err(|e| GetContainerError::FailedToLoad(FxcLib::PATH, e))?;
|
||||
let d3dcompile_fn: D3DCompileFn = *lib.get::<D3DCompileFn>(c"D3DCompile".to_bytes())?;
|
||||
|
||||
Ok(Self {
|
||||
_lib: lib,
|
||||
d3dcompile_fn,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn compile(
|
||||
&self,
|
||||
source: &str,
|
||||
source_name: Option<&CStr>,
|
||||
raw_ep: &str,
|
||||
full_stage: &str,
|
||||
compile_flags: u32,
|
||||
shader_data: &mut Option<ID3DBlob>,
|
||||
error: &mut Option<ID3DBlob>,
|
||||
) -> Result<windows_core::Result<()>, crate::DeviceError> {
|
||||
unsafe {
|
||||
let raw_ep = alloc::ffi::CString::new(raw_ep).unwrap();
|
||||
let full_stage = alloc::ffi::CString::new(full_stage).unwrap();
|
||||
|
||||
// If no name has been set, D3DCompile wants the null pointer.
|
||||
let source_name = source_name
|
||||
.map(|cstr| cstr.as_ptr().cast())
|
||||
.unwrap_or(core::ptr::null());
|
||||
|
||||
let shader_data: *mut Option<ID3DBlob> = shader_data;
|
||||
let error: *mut Option<ID3DBlob> = error;
|
||||
|
||||
{
|
||||
profiling::scope!("Fxc::D3DCompile");
|
||||
Ok((self.d3dcompile_fn)(
|
||||
source.as_ptr().cast(),
|
||||
source.len(),
|
||||
PCSTR(source_name),
|
||||
core::ptr::null(),
|
||||
core::ptr::null_mut(),
|
||||
PCSTR(raw_ep.as_ptr().cast()),
|
||||
PCSTR(full_stage.as_ptr().cast()),
|
||||
compile_flags,
|
||||
0,
|
||||
shader_data.cast(),
|
||||
error.cast(),
|
||||
)
|
||||
.ok())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn compile_fxc(
|
||||
device: &super::Device,
|
||||
source: &str,
|
||||
source_name: Option<&CStr>,
|
||||
raw_ep: &str,
|
||||
stage_bit: wgt::ShaderStages,
|
||||
full_stage: &str,
|
||||
fxc: &FxcLib,
|
||||
) -> Result<super::CompiledShader, crate::PipelineError> {
|
||||
profiling::scope!("compile_fxc");
|
||||
let mut shader_data = None;
|
||||
let mut compile_flags = Fxc::D3DCOMPILE_ENABLE_STRICTNESS;
|
||||
if device
|
||||
.shared
|
||||
@ -29,32 +234,17 @@ pub(super) fn compile_fxc(
|
||||
compile_flags |= Fxc::D3DCOMPILE_DEBUG | Fxc::D3DCOMPILE_SKIP_OPTIMIZATION;
|
||||
}
|
||||
|
||||
let raw_ep = alloc::ffi::CString::new(raw_ep).unwrap();
|
||||
let full_stage = alloc::ffi::CString::new(full_stage).unwrap();
|
||||
|
||||
// If no name has been set, D3DCompile wants the null pointer.
|
||||
let source_name = source_name
|
||||
.map(|cstr| cstr.as_ptr().cast())
|
||||
.unwrap_or(core::ptr::null());
|
||||
|
||||
let mut shader_data = None;
|
||||
let mut error = None;
|
||||
let hr = unsafe {
|
||||
profiling::scope!("Fxc::D3DCompile");
|
||||
Fxc::D3DCompile(
|
||||
// TODO: Update low-level bindings to accept a slice here
|
||||
source.as_ptr().cast(),
|
||||
source.len(),
|
||||
PCSTR(source_name),
|
||||
None,
|
||||
None,
|
||||
PCSTR(raw_ep.as_ptr().cast()),
|
||||
PCSTR(full_stage.as_ptr().cast()),
|
||||
compile_flags,
|
||||
0,
|
||||
&mut shader_data,
|
||||
Some(&mut error),
|
||||
)
|
||||
};
|
||||
let hr = fxc.compile(
|
||||
source,
|
||||
source_name,
|
||||
raw_ep,
|
||||
full_stage,
|
||||
compile_flags,
|
||||
&mut shader_data,
|
||||
&mut error,
|
||||
)?;
|
||||
|
||||
match hr {
|
||||
Ok(()) => {
|
||||
@ -132,64 +322,6 @@ unsafe fn dxc_create_instance<T: DxcObj>(
|
||||
result__.ok_or(crate::DeviceError::Unexpected)
|
||||
}
|
||||
|
||||
pub(super) struct DxcContainer {
|
||||
pub(super) max_shader_model: wgt::DxcShaderModel,
|
||||
compiler: Dxc::IDxcCompiler3,
|
||||
// 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>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub(super) enum GetDynamicDXCContainerError {
|
||||
#[error(transparent)]
|
||||
Device(#[from] crate::DeviceError),
|
||||
#[error("Failed to load {0}: {1}")]
|
||||
FailedToLoad(&'static str, libloading::Error),
|
||||
}
|
||||
|
||||
pub(super) fn get_dynamic_dxc_container(
|
||||
dxc_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 compiler = dxc.create_instance::<Dxc::IDxcCompiler3>()?;
|
||||
|
||||
Ok(DxcContainer {
|
||||
max_shader_model,
|
||||
compiler,
|
||||
_dxc: Some(dxc),
|
||||
})
|
||||
}
|
||||
|
||||
/// Creates a [`DxcContainer`] that delegates to the statically-linked version of DXC.
|
||||
pub(super) fn get_static_dxc_container() -> Result<DxcContainer, crate::DeviceError> {
|
||||
#[cfg(static_dxc)]
|
||||
{
|
||||
unsafe {
|
||||
let compiler = dxc_create_instance::<Dxc::IDxcCompiler3>(|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,
|
||||
_dxc: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
#[cfg(not(static_dxc))]
|
||||
{
|
||||
panic!("Attempted to create a static DXC shader compiler, but the static-dxc feature was not enabled")
|
||||
}
|
||||
}
|
||||
|
||||
/// Owned PCWSTR
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
struct OPCWSTR {
|
||||
@ -225,14 +357,14 @@ fn as_err_str(blob: &Dxc::IDxcBlobUtf8) -> Result<&str, crate::DeviceError> {
|
||||
.map_err(|_| crate::DeviceError::Unexpected)
|
||||
}
|
||||
|
||||
pub(super) fn compile_dxc(
|
||||
fn compile_dxc(
|
||||
device: &crate::dx12::Device,
|
||||
source: &str,
|
||||
source_name: Option<&CStr>,
|
||||
raw_ep: &str,
|
||||
stage_bit: wgt::ShaderStages,
|
||||
full_stage: &str,
|
||||
dxc_container: &DxcContainer,
|
||||
compiler: &Dxc::IDxcCompiler3,
|
||||
) -> Result<crate::dx12::CompiledShader, crate::PipelineError> {
|
||||
profiling::scope!("compile_dxc");
|
||||
|
||||
@ -279,12 +411,9 @@ pub(super) fn compile_dxc(
|
||||
Encoding: Dxc::DXC_CP_UTF8.0,
|
||||
};
|
||||
|
||||
let compile_res: Dxc::IDxcResult = unsafe {
|
||||
dxc_container
|
||||
.compiler
|
||||
.Compile(&buffer, Some(&compile_args), None)
|
||||
}
|
||||
.into_device_result("Compile")?;
|
||||
let compile_res: Dxc::IDxcResult =
|
||||
unsafe { compiler.Compile(&buffer, Some(&compile_args), None) }
|
||||
.into_device_result("Compile")?;
|
||||
|
||||
drop(compile_args);
|
||||
drop(source_name);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user