Skip to content

Commit

Permalink
Merge #3076
Browse files Browse the repository at this point in the history
3076: [0.4/dx11] explicit library loading r=kvark a=kvark

Supposedly fixes 32bit windows mingw CI: https://treeherder.mozilla.org/logviewer.html#/jobs?job_id=274334639&repo=try&lineNumber=88036
Similar to #3068 but for dx11

PR checklist:
- [ ] `make` succeeds (on *nix)
- [ ] `make reftests` succeeds
- [x] tested examples with the following backends: dx11
- [ ] `rustfmt` run on changed code


Co-authored-by: Dzmitry Malyshau <dmalyshau@mozilla.com>
  • Loading branch information
bors[bot] and kvark authored Nov 4, 2019
2 parents 56de6d8 + a1674b4 commit 7ec3e7f
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 61 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Change Log

### backend-dx12-0.4.1 (01-11-2019)
- switch to explicit linking of "d3d12.dll" and "dxgi.dll"
### backend-dx12-0.4.1, backend-dx11-0.4.2 (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
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.2"
description = "DirectX-11 API backend for gfx-rs"
homepage = "https://github.com/gfx-rs/gfx"
repository = "https://github.com/gfx-rs/gfx"
Expand All @@ -22,6 +22,7 @@ gfx-hal = { path = "../../hal", version = "0.4" }
auxil = { path = "../../auxil/auxil", version = "0.1", package = "gfx-auxil" }
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,6 +1,6 @@
use hal::adapter::{AdapterInfo, DeviceType};

use winapi::shared::guiddef::GUID;
use winapi::shared::guiddef::{GUID, REFIID};
use winapi::shared::{dxgi, dxgi1_2, dxgi1_3, dxgi1_4, dxgi1_5, winerror};
use winapi::um::unknwnbase::IUnknown;
use winapi::Interface;
Expand Down Expand Up @@ -67,10 +67,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 @@ -81,29 +85,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
128 changes: 79 additions & 49 deletions src/backend/dx11/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ extern crate auxil;
extern crate range_alloc;
#[macro_use]
extern crate bitflags;
extern crate libloading;
#[macro_use]
extern crate log;
extern crate parking_lot;
Expand Down Expand Up @@ -39,7 +40,7 @@ use hal::{
use range_alloc::RangeAllocator;

use winapi::shared::dxgi::{IDXGIAdapter, IDXGIFactory, IDXGISwapChain};
use winapi::shared::minwindef::{FALSE, UINT};
use winapi::shared::minwindef::{FALSE, UINT, HMODULE};
use winapi::shared::windef::{HWND, RECT};
use winapi::shared::{dxgiformat, winerror};
use winapi::um::winuser::GetClientRect;
Expand Down Expand Up @@ -96,6 +97,19 @@ mod dxgi;
mod internal;
mod shader;

type CreateFun = extern "system" fn(
*mut IDXGIAdapter,
UINT,
HMODULE,
UINT,
*const UINT,
UINT,
UINT,
*mut *mut d3d11::ID3D11Device,
*mut UINT,
*mut *mut d3d11::ID3D11DeviceContext,
) -> winerror::HRESULT;

#[derive(Clone)]
pub(crate) struct ViewInfo {
resource: *mut d3d11::ID3D11Resource,
Expand All @@ -116,6 +130,7 @@ impl fmt::Debug for ViewInfo {
pub struct Instance {
pub(crate) factory: ComPtr<IDXGIFactory>,
pub(crate) dxgi_version: dxgi::DxgiVersion,
library: Arc<libloading::Library>,
}

unsafe impl Send for Instance {}
Expand Down Expand Up @@ -256,9 +271,14 @@ impl hal::Instance<Backend> for Instance {
match dxgi::get_dxgi_factory() {
Ok((factory, dxgi_version)) => {
info!("DXGI version: {:?}", dxgi_version);
let library = Arc::new(
libloading::Library::new("d3d11.dll")
.map_err(|_| hal::UnsupportedBackend)?
);
Ok(Instance {
factory,
dxgi_version,
library,
})
}
Err(hr) => {
Expand All @@ -272,6 +292,16 @@ impl hal::Instance<Backend> for Instance {
let mut adapters = Vec::new();
let mut idx = 0;

let func: libloading::Symbol<CreateFun> = 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 @@ -281,23 +311,21 @@ impl hal::Instance<Backend> for Instance {

// TODO: move into function?
let (device, feature_level) = {
let feature_level = get_feature_level(adapter.as_raw());
let feature_level = get_feature_level(&func, 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 @@ -384,6 +412,7 @@ impl hal::Instance<Backend> for Instance {

let physical_device = PhysicalDevice {
adapter,
library: Arc::clone(&self.library),
features,
limits,
memory_properties,
Expand Down Expand Up @@ -421,6 +450,7 @@ impl hal::Instance<Backend> for Instance {

pub struct PhysicalDevice {
adapter: ComPtr<IDXGIAdapter>,
library: Arc<libloading::Library>,
features: hal::Features,
limits: hal::Limits,
memory_properties: adapter::MemoryProperties,
Expand All @@ -437,7 +467,7 @@ unsafe impl Send for PhysicalDevice {}
unsafe impl Sync for PhysicalDevice {}

// TODO: does the adapter we get earlier matter for feature level?
fn get_feature_level(adapter: *mut IDXGIAdapter) -> d3dcommon::D3D_FEATURE_LEVEL {
fn get_feature_level(func: &CreateFun, adapter: *mut IDXGIAdapter) -> d3dcommon::D3D_FEATURE_LEVEL {
let requested_feature_levels = [
d3dcommon::D3D_FEATURE_LEVEL_11_1,
d3dcommon::D3D_FEATURE_LEVEL_11_0,
Expand All @@ -449,40 +479,36 @@ fn get_feature_level(adapter: *mut IDXGIAdapter) -> d3dcommon::D3D_FEATURE_LEVEL
];

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

if !winerror::SUCCEEDED(hr) {
// if there is no 11.1 runtime installed, requesting
// `D3D_FEATURE_LEVEL_11_1` will return E_INVALIDARG so we just retry
// without that
if hr == winerror::E_INVALIDARG {
let hr = unsafe {
d3d11::D3D11CreateDevice(
adapter,
d3dcommon::D3D_DRIVER_TYPE_UNKNOWN,
ptr::null_mut(),
0,
requested_feature_levels[1 ..].as_ptr(),
(requested_feature_levels.len() - 1) as _,
d3d11::D3D11_SDK_VERSION,
ptr::null_mut(),
&mut feature_level as *mut _,
ptr::null_mut(),
)
};
let hr = func(
adapter,
d3dcommon::D3D_DRIVER_TYPE_UNKNOWN,
ptr::null_mut(),
0,
requested_feature_levels[1 ..].as_ptr(),
(requested_feature_levels.len() - 1) as _,
d3d11::D3D11_SDK_VERSION,
ptr::null_mut(),
&mut feature_level as *mut _,
ptr::null_mut(),
);

if !winerror::SUCCEEDED(hr) {
// TODO: device might not support any feature levels?
Expand All @@ -501,12 +527,16 @@ impl adapter::PhysicalDevice<Backend> for PhysicalDevice {
families: &[(&QueueFamily, &[queue::QueuePriority])],
requested_features: hal::Features,
) -> Result<adapter::Gpu<Backend>, hal::device::CreationError> {
let func: libloading::Symbol<CreateFun> = self.library
.get(b"D3D11CreateDevice")
.unwrap();

let (device, cxt) = {
if !self.features().contains(requested_features) {
return Err(hal::device::CreationError::MissingFeature);
}

let feature_level = get_feature_level(self.adapter.as_raw());
let feature_level = get_feature_level(&func, self.adapter.as_raw());
let mut returned_level = d3dcommon::D3D_FEATURE_LEVEL_9_1;

#[cfg(debug_assertions)]
Expand All @@ -517,7 +547,7 @@ impl adapter::PhysicalDevice<Backend> for PhysicalDevice {
// TODO: request debug device only on debug config?
let mut device = ptr::null_mut();
let mut cxt = ptr::null_mut();
let hr = d3d11::D3D11CreateDevice(
let hr = func(
self.adapter.as_raw() as *mut _,
d3dcommon::D3D_DRIVER_TYPE_UNKNOWN,
ptr::null_mut(),
Expand Down Expand Up @@ -547,7 +577,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 @@ -711,7 +741,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 7ec3e7f

Please sign in to comment.