Skip to content

Commit

Permalink
[dx11] explicit library loading
Browse files Browse the repository at this point in the history
  • Loading branch information
kvark committed Nov 4, 2019
1 parent a7840f0 commit f32b4c4
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 27 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Change Log

### backend-dx12-0.4.1, backend-dx11-0.4.1 (01-11-2019)
- switch to explicit linking of "d3d12.dll", "d3d11.dll" and "dxgi.dll"

## hal-0.4.0 (23-10-2019)
- all strongly typed HAL wrappers are removed
- all use of `failure` is removed
Expand Down
3 changes: 2 additions & 1 deletion src/backend/dx11/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "gfx-backend-dx11"
version = "0.4.0"
version = "0.4.1"
description = "DirectX-11 API backend for gfx-rs"
homepage = "https://github.com/gfx-rs/gfx"
repository = "https://github.com/gfx-rs/gfx"
Expand All @@ -23,6 +23,7 @@ auxil = { path = "../../auxil/auxil", version = "0.2", package = "gfx-auxil", fe
hal = { path = "../../hal", version = "0.4", package = "gfx-hal" }
range-alloc = { path = "../../auxil/range-alloc", version = "0.1" }
bitflags = "1"
libloading = "0.5"
log = { version = "0.4" }
smallvec = "0.6"
spirv_cross = { version = "0.16", features = ["hlsl"] }
Expand Down
28 changes: 19 additions & 9 deletions src/backend/dx11/src/dxgi.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use hal::adapter::{AdapterInfo, DeviceType};

use winapi::{
shared::{dxgi, dxgi1_2, dxgi1_3, dxgi1_4, dxgi1_5, guiddef::GUID, winerror},
shared::{dxgi, dxgi1_2, dxgi1_3, dxgi1_4, dxgi1_5, guiddef::{GUID, REFIID}, winerror},
um::unknwnbase::IUnknown,
Interface,
};
Expand Down Expand Up @@ -65,10 +65,14 @@ pub(crate) enum DxgiVersion {
Dxgi1_5,
}

fn create_dxgi_factory1(guid: &GUID) -> Result<ComPtr<dxgi::IDXGIFactory>, winerror::HRESULT> {
type DxgiFun = extern "system" fn(REFIID, *mut *mut winapi::ctypes::c_void) -> winerror::HRESULT;

fn create_dxgi_factory1(
func: &DxgiFun, guid: &GUID
) -> Result<ComPtr<dxgi::IDXGIFactory>, winerror::HRESULT> {
let mut factory: *mut IUnknown = ptr::null_mut();

let hr = unsafe { dxgi::CreateDXGIFactory1(guid, &mut factory as *mut *mut _ as *mut *mut _) };
let hr = func(guid, &mut factory as *mut *mut _ as *mut *mut _);

if winerror::SUCCEEDED(hr) {
Ok(unsafe { ComPtr::from_raw(factory as *mut _) })
Expand All @@ -79,29 +83,35 @@ fn create_dxgi_factory1(guid: &GUID) -> Result<ComPtr<dxgi::IDXGIFactory>, winer

pub(crate) fn get_dxgi_factory(
) -> Result<(ComPtr<dxgi::IDXGIFactory>, DxgiVersion), winerror::HRESULT> {
let library = libloading::Library::new("dxgi.dll")
.map_err(|_| -1)?;
let func: libloading::Symbol<DxgiFun> = unsafe {
library.get(b"CreateDXGIFactory1")
}.map_err(|_| -1)?;

// TODO: do we even need `create_dxgi_factory2`?
if let Ok(factory) = create_dxgi_factory1(&dxgi1_5::IDXGIFactory5::uuidof()) {
if let Ok(factory) = create_dxgi_factory1(&func, &dxgi1_5::IDXGIFactory5::uuidof()) {
return Ok((factory, DxgiVersion::Dxgi1_5));
}

if let Ok(factory) = create_dxgi_factory1(&dxgi1_4::IDXGIFactory4::uuidof()) {
if let Ok(factory) = create_dxgi_factory1(&func, &dxgi1_4::IDXGIFactory4::uuidof()) {
return Ok((factory, DxgiVersion::Dxgi1_4));
}

if let Ok(factory) = create_dxgi_factory1(&dxgi1_3::IDXGIFactory3::uuidof()) {
if let Ok(factory) = create_dxgi_factory1(&func, &dxgi1_3::IDXGIFactory3::uuidof()) {
return Ok((factory, DxgiVersion::Dxgi1_3));
}

if let Ok(factory) = create_dxgi_factory1(&dxgi1_2::IDXGIFactory2::uuidof()) {
if let Ok(factory) = create_dxgi_factory1(&func, &dxgi1_2::IDXGIFactory2::uuidof()) {
return Ok((factory, DxgiVersion::Dxgi1_2));
}

if let Ok(factory) = create_dxgi_factory1(&dxgi::IDXGIFactory1::uuidof()) {
if let Ok(factory) = create_dxgi_factory1(&func, &dxgi::IDXGIFactory1::uuidof()) {
return Ok((factory, DxgiVersion::Dxgi1_0));
}

// TODO: any reason why above would fail and this wouldnt?
match create_dxgi_factory1(&dxgi::IDXGIFactory::uuidof()) {
match create_dxgi_factory1(&func, &dxgi::IDXGIFactory::uuidof()) {
Ok(factory) => Ok((factory, DxgiVersion::Dxgi1_0)),
Err(hr) => Err(hr),
}
Expand Down
59 changes: 42 additions & 17 deletions src/backend/dx11/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use winapi::{
shared::{
dxgi::{IDXGIAdapter, IDXGIFactory, IDXGISwapChain},
dxgiformat,
minwindef::{FALSE, UINT},
minwindef::{FALSE, UINT, HMODULE},
windef::{HWND, RECT},
winerror,
},
Expand Down Expand Up @@ -105,6 +105,7 @@ impl fmt::Debug for ViewInfo {
pub struct Instance {
pub(crate) factory: ComPtr<IDXGIFactory>,
pub(crate) dxgi_version: dxgi::DxgiVersion,
library: libloading::Library,
}

unsafe impl Send for Instance {}
Expand Down Expand Up @@ -245,9 +246,12 @@ impl hal::Instance<Backend> for Instance {
match dxgi::get_dxgi_factory() {
Ok((factory, dxgi_version)) => {
info!("DXGI version: {:?}", dxgi_version);
let library = libloading::Library::new("d3d11.dll")
.map_err(|_| hal::UnsupportedBackend)?;
Ok(Instance {
factory,
dxgi_version,
library,
})
}
Err(hr) => {
Expand All @@ -258,9 +262,32 @@ impl hal::Instance<Backend> for Instance {
}

fn enumerate_adapters(&self) -> Vec<adapter::Adapter<Backend>> {
type Fun = extern "system" fn(
*mut IDXGIAdapter,
UINT,
HMODULE,
UINT,
*const UINT,
UINT,
UINT,
*mut *mut d3d11::ID3D11Device,
*mut UINT,
*mut *mut d3d11::ID3D11DeviceContext,
) -> winerror::HRESULT;

let mut adapters = Vec::new();
let mut idx = 0;

let func: libloading::Symbol<Fun> = match unsafe {
self.library.get(b"D3D11CreateDevice")
} {
Ok(func) => func,
Err(e) => {
error!("Unable to get device creation function: {:?}", e);
return Vec::new();
}
};

while let Ok((adapter, info)) =
dxgi::get_adapter(idx, self.factory.as_raw(), self.dxgi_version)
{
Expand All @@ -273,20 +300,18 @@ impl hal::Instance<Backend> for Instance {
let feature_level = get_feature_level(adapter.as_raw());

let mut device = ptr::null_mut();
let hr = unsafe {
d3d11::D3D11CreateDevice(
adapter.as_raw() as *mut _,
d3dcommon::D3D_DRIVER_TYPE_UNKNOWN,
ptr::null_mut(),
0,
[feature_level].as_ptr(),
1,
d3d11::D3D11_SDK_VERSION,
&mut device as *mut *mut _ as *mut *mut _,
ptr::null_mut(),
ptr::null_mut(),
)
};
let hr = func(
adapter.as_raw() as *mut _,
d3dcommon::D3D_DRIVER_TYPE_UNKNOWN,
ptr::null_mut(),
0,
[feature_level].as_ptr(),
1,
d3d11::D3D11_SDK_VERSION,
&mut device as *mut *mut _ as *mut *mut _,
ptr::null_mut(),
ptr::null_mut(),
);

if !winerror::SUCCEEDED(hr) {
continue;
Expand Down Expand Up @@ -536,7 +561,7 @@ impl adapter::PhysicalDevice<Backend> for PhysicalDevice {
// TODO: deferred context => 1 cxt/queue?
let queue_groups = families
.into_iter()
.map(|&(family, prio)| {
.map(|&(_family, prio)| {
assert_eq!(prio.len(), 1);
let mut group = queue::QueueGroup::new(queue::QueueFamilyId(0));

Expand Down Expand Up @@ -700,7 +725,7 @@ impl window::Surface<Backend> for Surface {
true
}

fn capabilities(&self, physical_device: &PhysicalDevice) -> window::SurfaceCapabilities {
fn capabilities(&self, _physical_device: &PhysicalDevice) -> window::SurfaceCapabilities {
let current_extent = unsafe {
let mut rect: RECT = mem::zeroed();
assert_ne!(
Expand Down

0 comments on commit f32b4c4

Please sign in to comment.