Skip to content

Commit 6c2f23c

Browse files
committed
[d3d12] simplify create_factory() fn
1 parent dd01b6d commit 6c2f23c

File tree

3 files changed

+26
-117
lines changed

3 files changed

+26
-117
lines changed

wgpu-hal/src/auxil/dxgi/factory.rs

Lines changed: 16 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,7 @@ use windows::{core::Interface as _, Win32::Graphics::Dxgi};
44

55
use crate::dx12::DxgiLib;
66

7-
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
8-
pub enum DxgiFactoryType {
9-
Factory2,
10-
Factory4,
11-
Factory6,
12-
}
7+
// We can rely on the presence of DXGI 1.4 since D3D12 requires WDDM 2.0, Windows 10 (1507), and so does DXGI 1.4.
138

149
fn should_keep_adapter(adapter: &Dxgi::IDXGIAdapter1) -> bool {
1510
let desc = unsafe { adapter.GetDesc1() }.unwrap();
@@ -167,52 +162,37 @@ pub fn enumerate_adapters(factory: DxgiFactory) -> Vec<DxgiAdapter> {
167162

168163
#[derive(Clone, Debug)]
169164
pub enum DxgiFactory {
170-
Factory1(Dxgi::IDXGIFactory1),
171-
Factory2(Dxgi::IDXGIFactory2),
165+
/// Provided by DXGI 1.4
172166
Factory4(Dxgi::IDXGIFactory4),
167+
/// Provided by DXGI 1.5
168+
Factory5(Dxgi::IDXGIFactory5),
169+
/// Provided by DXGI 1.6
173170
Factory6(Dxgi::IDXGIFactory6),
174171
}
175172

176173
impl Deref for DxgiFactory {
177-
type Target = Dxgi::IDXGIFactory1;
174+
type Target = Dxgi::IDXGIFactory4;
178175

179176
fn deref(&self) -> &Self::Target {
180177
match self {
181-
DxgiFactory::Factory1(f) => f,
182-
DxgiFactory::Factory2(f) => f,
183178
DxgiFactory::Factory4(f) => f,
179+
DxgiFactory::Factory5(f) => f,
184180
DxgiFactory::Factory6(f) => f,
185181
}
186182
}
187183
}
188184

189185
impl DxgiFactory {
190-
pub fn as_factory2(&self) -> Option<&Dxgi::IDXGIFactory2> {
191-
match self {
192-
Self::Factory1(_) => None,
193-
Self::Factory2(f) => Some(f),
194-
Self::Factory4(f) => Some(f),
195-
Self::Factory6(f) => Some(f),
196-
}
197-
}
198-
199-
pub fn unwrap_factory2(&self) -> &Dxgi::IDXGIFactory2 {
200-
self.as_factory2().unwrap()
201-
}
202-
203186
pub fn as_factory5(&self) -> Option<&Dxgi::IDXGIFactory5> {
204187
match self {
205-
Self::Factory1(_) | Self::Factory2(_) | Self::Factory4(_) => None,
188+
Self::Factory4(_) => None,
189+
Self::Factory5(f) => Some(f),
206190
Self::Factory6(f) => Some(f),
207191
}
208192
}
209193
}
210194

211-
/// Tries to create a [`Dxgi::IDXGIFactory6`], then a [`Dxgi::IDXGIFactory4`], then a [`Dxgi::IDXGIFactory2`], then a [`Dxgi::IDXGIFactory1`],
212-
/// returning the one that succeeds, or if the required_factory_type fails to be
213-
/// created.
214195
pub fn create_factory(
215-
required_factory_type: DxgiFactoryType,
216196
instance_flags: wgt::InstanceFlags,
217197
) -> Result<(DxgiLib, DxgiFactory), crate::InstanceError> {
218198
let lib_dxgi = DxgiLib::new().map_err(|e| {
@@ -233,75 +213,23 @@ pub fn create_factory(
233213
super::exception::register_exception_handler();
234214
}
235215

236-
// Try to create IDXGIFactory4
237216
let factory4 = match lib_dxgi.create_factory4(factory_flags) {
238-
Ok(factory) => Some(factory),
239-
// If we require factory4, hard error.
240-
Err(err) if required_factory_type == DxgiFactoryType::Factory4 => {
217+
Ok(factory) => factory,
218+
Err(err) => {
241219
return Err(crate::InstanceError::with_source(
242220
String::from("IDXGIFactory4 creation failed"),
243221
err,
244222
));
245223
}
246-
// If we don't print it to warn as all win7 will hit this case.
247-
Err(err) => {
248-
log::warn!("IDXGIFactory4 creation function not found: {err:?}");
249-
None
250-
}
251224
};
252225

253-
if let Some(factory4) = factory4 {
254-
// Try to cast the IDXGIFactory4 into IDXGIFactory6
255-
let factory6 = factory4.cast::<Dxgi::IDXGIFactory6>();
256-
match factory6 {
257-
Ok(factory6) => {
258-
return Ok((lib_dxgi, DxgiFactory::Factory6(factory6)));
259-
}
260-
// If we require factory6, hard error.
261-
Err(err) if required_factory_type == DxgiFactoryType::Factory6 => {
262-
// err is a Cow<str>, not an Error implementor
263-
return Err(crate::InstanceError::new(format!(
264-
"failed to cast IDXGIFactory4 to IDXGIFactory6: {err:?}"
265-
)));
266-
}
267-
// If we don't print it to warn.
268-
Err(err) => {
269-
log::warn!("Failed to cast IDXGIFactory4 to IDXGIFactory6: {:?}", err);
270-
return Ok((lib_dxgi, DxgiFactory::Factory4(factory4)));
271-
}
272-
}
226+
if let Ok(factory6) = factory4.cast::<Dxgi::IDXGIFactory6>() {
227+
return Ok((lib_dxgi, DxgiFactory::Factory6(factory6)));
273228
}
274229

275-
// Try to create IDXGIFactory1
276-
let factory1 = match lib_dxgi.create_factory1() {
277-
Ok(factory) => factory,
278-
Err(err) => {
279-
return Err(crate::InstanceError::with_source(
280-
String::from("IDXGIFactory1 creation failed"),
281-
err,
282-
));
283-
}
284-
};
285-
286-
// Try to cast the IDXGIFactory1 into IDXGIFactory2
287-
let factory2 = factory1.cast::<Dxgi::IDXGIFactory2>();
288-
match factory2 {
289-
Ok(factory2) => {
290-
return Ok((lib_dxgi, DxgiFactory::Factory2(factory2)));
291-
}
292-
// If we require factory2, hard error.
293-
Err(err) if required_factory_type == DxgiFactoryType::Factory2 => {
294-
// err is a Cow<str>, not an Error implementor
295-
return Err(crate::InstanceError::new(format!(
296-
"failed to cast IDXGIFactory1 to IDXGIFactory2: {err:?}"
297-
)));
298-
}
299-
// If we don't print it to warn.
300-
Err(err) => {
301-
log::warn!("Failed to cast IDXGIFactory1 to IDXGIFactory2: {:?}", err);
302-
}
230+
if let Ok(factory5) = factory4.cast::<Dxgi::IDXGIFactory5>() {
231+
return Ok((lib_dxgi, DxgiFactory::Factory5(factory5)));
303232
}
304233

305-
// We tried to create 4 and 2, but only succeeded with 1.
306-
Ok((lib_dxgi, DxgiFactory::Factory1(factory1)))
234+
Ok((lib_dxgi, DxgiFactory::Factory4(factory4)))
307235
}

wgpu-hal/src/dx12/instance.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,7 @@ impl crate::Instance for super::Instance {
5252
}
5353
}
5454

55-
// Create DXGIFactory4
56-
let (lib_dxgi, factory) = auxil::dxgi::factory::create_factory(
57-
auxil::dxgi::factory::DxgiFactoryType::Factory4,
58-
desc.flags,
59-
)?;
55+
let (lib_dxgi, factory) = auxil::dxgi::factory::create_factory(desc.flags)?;
6056

6157
// Create IDXGIFactoryMedia
6258
let factory_media = lib_dxgi.create_factory_media().ok();

wgpu-hal/src/dx12/mod.rs

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -225,24 +225,7 @@ impl DxgiLib {
225225
result__.ok_or(crate::DeviceError::Unexpected)
226226
}
227227

228-
pub fn create_factory1(&self) -> Result<Dxgi::IDXGIFactory1, crate::DeviceError> {
229-
// Calls windows::Win32::Graphics::Dxgi::CreateDXGIFactory1 on dxgi.dll
230-
type Fun = extern "system" fn(
231-
riid: *const windows_core::GUID,
232-
ppfactory: *mut *mut core::ffi::c_void,
233-
) -> windows_core::HRESULT;
234-
let func: libloading::Symbol<Fun> = unsafe { self.lib.get(b"CreateDXGIFactory1") }?;
235-
236-
let mut result__ = None;
237-
238-
(func)(&Dxgi::IDXGIFactory1::IID, <*mut _>::cast(&mut result__))
239-
.ok()
240-
.into_device_result("create_factory1")?;
241-
242-
result__.ok_or(crate::DeviceError::Unexpected)
243-
}
244-
245-
/// Will error with crate::DeviceError::Unexpected if DXGI 1.3 is not available.
228+
/// Will error with crate::DeviceError::Unexpected if DXGI 1.4 is not available.
246229
pub fn create_factory4(
247230
&self,
248231
factory_flags: Dxgi::DXGI_CREATE_FACTORY_FLAGS,
@@ -1092,11 +1075,13 @@ impl crate::Surface for Surface {
10921075
};
10931076
let swap_chain1 = match self.target {
10941077
SurfaceTarget::Visual(_) | SurfaceTarget::SwapChainPanel(_) => {
1095-
profiling::scope!("IDXGIFactory4::CreateSwapChainForComposition");
1078+
profiling::scope!("IDXGIFactory2::CreateSwapChainForComposition");
10961079
unsafe {
1097-
self.factory
1098-
.unwrap_factory2()
1099-
.CreateSwapChainForComposition(&device.present_queue, &desc, None)
1080+
self.factory.CreateSwapChainForComposition(
1081+
&device.present_queue,
1082+
&desc,
1083+
None,
1084+
)
11001085
}
11011086
}
11021087
SurfaceTarget::SurfaceHandle(handle) => {
@@ -1116,9 +1101,9 @@ impl crate::Surface for Surface {
11161101
}
11171102
}
11181103
SurfaceTarget::WndHandle(hwnd) => {
1119-
profiling::scope!("IDXGIFactory4::CreateSwapChainForHwnd");
1104+
profiling::scope!("IDXGIFactory2::CreateSwapChainForHwnd");
11201105
unsafe {
1121-
self.factory.unwrap_factory2().CreateSwapChainForHwnd(
1106+
self.factory.CreateSwapChainForHwnd(
11221107
&device.present_queue,
11231108
hwnd,
11241109
&desc,

0 commit comments

Comments
 (0)