mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Dynamic loading for D3D12 device and DXGI
This commit is contained in:
@@ -9,9 +9,13 @@ license = "MIT OR Apache-2.0"
|
||||
documentation = "https://docs.rs/d3d12"
|
||||
categories = ["memory-management"]
|
||||
|
||||
[features]
|
||||
libstatic = []
|
||||
|
||||
[dependencies]
|
||||
bitflags = "1"
|
||||
libloading = { version = "0.5", optional = true }
|
||||
|
||||
[dependencies.winapi]
|
||||
version = "0.3"
|
||||
features = ["dxgi1_2","dxgi1_3","dxgi1_4","d3d12","d3d12sdklayers","d3dcommon","d3dcompiler","dxgiformat","synchapi","winerror"]
|
||||
features = ["dxgi1_2","dxgi1_3","dxgi1_4","dxgidebug","d3d12","d3d12sdklayers","d3dcommon","d3dcompiler","dxgiformat","synchapi","winerror"]
|
||||
|
||||
@@ -24,3 +24,6 @@ install:
|
||||
build: false
|
||||
test_script:
|
||||
- cargo check
|
||||
- cargo check --features libloading
|
||||
- cargo check --features libstatic
|
||||
- cargo check --all-features
|
||||
|
||||
37
src/debug.rs
37
src/debug.rs
@@ -1,15 +1,40 @@
|
||||
use com::WeakPtr;
|
||||
use winapi::um::{d3d12, d3d12sdklayers};
|
||||
use winapi::Interface;
|
||||
use D3DResult;
|
||||
#[cfg(any(feature = "libloading", feature = "libstatic"))]
|
||||
use winapi::Interface as _;
|
||||
use winapi::um::d3d12sdklayers;
|
||||
|
||||
pub type Debug = WeakPtr<d3d12sdklayers::ID3D12Debug>;
|
||||
|
||||
impl Debug {
|
||||
pub fn get_interface() -> D3DResult<Self> {
|
||||
#[cfg(feature = "libloading")]
|
||||
impl crate::D3D12Lib {
|
||||
pub fn get_debug_interface(&self) -> libloading::Result<crate::D3DResult<Debug>> {
|
||||
type Fun = extern "system" fn(
|
||||
winapi::shared::guiddef::REFIID,
|
||||
*mut *mut winapi::ctypes::c_void,
|
||||
) -> crate::HRESULT;
|
||||
|
||||
let mut debug = Debug::null();
|
||||
let hr = unsafe {
|
||||
d3d12::D3D12GetDebugInterface(&d3d12sdklayers::ID3D12Debug::uuidof(), debug.mut_void())
|
||||
let func: libloading::Symbol<Fun> = self.lib.get(b"D3D12GetDebugInterface")?;
|
||||
func(
|
||||
&d3d12sdklayers::ID3D12Debug::uuidof(),
|
||||
debug.mut_void(),
|
||||
)
|
||||
};
|
||||
|
||||
Ok((debug, hr))
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug {
|
||||
#[cfg(feature = "libstatic")]
|
||||
pub fn get_interface() -> crate::D3DResult<Self> {
|
||||
let mut debug = Debug::null();
|
||||
let hr = unsafe {
|
||||
winapi::um::d3d12::D3D12GetDebugInterface(
|
||||
&d3d12sdklayers::ID3D12Debug::uuidof(),
|
||||
debug.mut_void(),
|
||||
)
|
||||
};
|
||||
|
||||
(debug, hr)
|
||||
|
||||
@@ -156,7 +156,6 @@ impl StaticSampler {
|
||||
pub fn new(
|
||||
visibility: ShaderVisibility,
|
||||
binding: Binding,
|
||||
|
||||
filter: d3d12::D3D12_FILTER,
|
||||
address_mode: TextureAddressMode,
|
||||
mip_lod_bias: f32,
|
||||
@@ -202,14 +201,57 @@ bitflags! {
|
||||
}
|
||||
|
||||
pub type RootSignature = WeakPtr<d3d12::ID3D12RootSignature>;
|
||||
pub type BlobResult = D3DResult<(Blob, Error)>;
|
||||
|
||||
#[cfg(feature = "libloading")]
|
||||
impl crate::D3D12Lib {
|
||||
pub fn serialize_root_signature(
|
||||
&self,
|
||||
version: RootSignatureVersion,
|
||||
parameters: &[RootParameter],
|
||||
static_samplers: &[StaticSampler],
|
||||
flags: RootSignatureFlags,
|
||||
) -> libloading::Result<BlobResult> {
|
||||
use winapi::um::d3dcommon::ID3DBlob;
|
||||
type Fun = extern "system" fn(
|
||||
*const d3d12::D3D12_ROOT_SIGNATURE_DESC,
|
||||
d3d12::D3D_ROOT_SIGNATURE_VERSION,
|
||||
*mut *mut ID3DBlob,
|
||||
*mut *mut ID3DBlob,
|
||||
) -> crate::HRESULT;
|
||||
|
||||
let desc = d3d12::D3D12_ROOT_SIGNATURE_DESC {
|
||||
NumParameters: parameters.len() as _,
|
||||
pParameters: parameters.as_ptr() as *const _,
|
||||
NumStaticSamplers: static_samplers.len() as _,
|
||||
pStaticSamplers: static_samplers.as_ptr() as _,
|
||||
Flags: flags.bits(),
|
||||
};
|
||||
|
||||
let mut blob = Blob::null();
|
||||
let mut error = Error::null();
|
||||
let hr = unsafe {
|
||||
let func: libloading::Symbol<Fun> = self.lib.get(b"D3D12SerializeRootSignature")?;
|
||||
func(
|
||||
&desc,
|
||||
version as _,
|
||||
blob.mut_void() as *mut *mut _,
|
||||
error.mut_void() as *mut *mut _,
|
||||
)
|
||||
};
|
||||
|
||||
Ok(((blob, error), hr))
|
||||
}
|
||||
}
|
||||
|
||||
impl RootSignature {
|
||||
#[cfg(feature = "libstatic")]
|
||||
pub fn serialize(
|
||||
version: RootSignatureVersion,
|
||||
parameters: &[RootParameter],
|
||||
static_samplers: &[StaticSampler],
|
||||
flags: RootSignatureFlags,
|
||||
) -> D3DResult<(Blob, Error)> {
|
||||
) -> BlobResult {
|
||||
let mut blob = Blob::null();
|
||||
let mut error = Error::null();
|
||||
|
||||
|
||||
@@ -9,17 +9,47 @@ use winapi::um::d3d12;
|
||||
use winapi::Interface;
|
||||
use {pso, query, queue};
|
||||
use {
|
||||
Blob, CachedPSO, CommandAllocator, CommandQueue, D3DResult, DescriptorHeap, FeatureLevel,
|
||||
Blob, CachedPSO, CommandAllocator, CommandQueue, D3DResult, DescriptorHeap,
|
||||
Fence, GraphicsCommandList, NodeMask, PipelineState, QueryHeap, Resource, RootSignature,
|
||||
Shader, TextureAddressMode,
|
||||
};
|
||||
|
||||
pub type Device = WeakPtr<d3d12::ID3D12Device>;
|
||||
|
||||
#[cfg(feature = "libloading")]
|
||||
impl crate::D3D12Lib {
|
||||
pub fn create_device<I: Interface>(
|
||||
&self,
|
||||
adapter: WeakPtr<I>,
|
||||
feature_level: crate::FeatureLevel,
|
||||
) -> libloading::Result<D3DResult<Device>> {
|
||||
type Fun = extern "system" fn(
|
||||
*mut winapi::um::unknwnbase::IUnknown,
|
||||
winapi::um::d3dcommon::D3D_FEATURE_LEVEL,
|
||||
winapi::shared::guiddef::REFGUID,
|
||||
*mut *mut winapi::ctypes::c_void,
|
||||
) -> crate::HRESULT;
|
||||
|
||||
let mut device = Device::null();
|
||||
let hr = unsafe {
|
||||
let func: libloading::Symbol<Fun> = self.lib.get(b"D3D12CreateDevice")?;
|
||||
func(
|
||||
adapter.as_unknown() as *const _ as *mut _,
|
||||
feature_level as _,
|
||||
&d3d12::ID3D12Device::uuidof(),
|
||||
device.mut_void(),
|
||||
)
|
||||
};
|
||||
|
||||
Ok((device, hr))
|
||||
}
|
||||
}
|
||||
|
||||
impl Device {
|
||||
#[cfg(feature = "libstatic")]
|
||||
pub fn create<I: Interface>(
|
||||
adapter: WeakPtr<I>,
|
||||
feature_level: FeatureLevel,
|
||||
feature_level: crate::FeatureLevel,
|
||||
) -> D3DResult<Self> {
|
||||
let mut device = Device::null();
|
||||
let hr = unsafe {
|
||||
|
||||
60
src/dxgi.rs
60
src/dxgi.rs
@@ -2,7 +2,7 @@ use com::WeakPtr;
|
||||
use std::ptr;
|
||||
use winapi::shared::windef::HWND;
|
||||
use winapi::shared::{dxgi, dxgi1_2, dxgi1_3, dxgi1_4, dxgiformat, dxgitype};
|
||||
use winapi::um::d3d12;
|
||||
use winapi::um::{dxgidebug, d3d12};
|
||||
use winapi::Interface;
|
||||
use {CommandQueue, D3DResult, Resource, SampleDesc, HRESULT};
|
||||
|
||||
@@ -42,10 +42,67 @@ pub enum AlphaMode {
|
||||
pub type Adapter1 = WeakPtr<dxgi::IDXGIAdapter1>;
|
||||
pub type Factory2 = WeakPtr<dxgi1_2::IDXGIFactory2>;
|
||||
pub type Factory4 = WeakPtr<dxgi1_4::IDXGIFactory4>;
|
||||
pub type InfoQueue = WeakPtr<dxgidebug::IDXGIInfoQueue>;
|
||||
pub type SwapChain = WeakPtr<dxgi::IDXGISwapChain>;
|
||||
pub type SwapChain1 = WeakPtr<dxgi1_2::IDXGISwapChain1>;
|
||||
pub type SwapChain3 = WeakPtr<dxgi1_4::IDXGISwapChain3>;
|
||||
|
||||
#[cfg(feature = "libloading")]
|
||||
pub struct DxgiLib {
|
||||
lib: libloading::Library,
|
||||
}
|
||||
|
||||
#[cfg(feature = "libloading")]
|
||||
impl DxgiLib {
|
||||
pub fn new() -> libloading::Result<Self> {
|
||||
libloading::Library::new("dxgi.dll")
|
||||
.map(|lib| DxgiLib {
|
||||
lib,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn create_factory2(
|
||||
&self, flags: FactoryCreationFlags
|
||||
) -> libloading::Result<D3DResult<Factory4>> {
|
||||
type Fun = extern "system" fn(
|
||||
winapi::shared::minwindef::UINT,
|
||||
winapi::shared::guiddef::REFIID,
|
||||
*mut *mut winapi::ctypes::c_void,
|
||||
) -> HRESULT;
|
||||
|
||||
let mut factory = Factory4::null();
|
||||
let hr = unsafe {
|
||||
let func: libloading::Symbol<Fun> = self.lib.get(b"CreateDXGIFactory2")?;
|
||||
func(
|
||||
flags.bits(),
|
||||
&dxgi1_4::IDXGIFactory4::uuidof(),
|
||||
factory.mut_void(),
|
||||
)
|
||||
};
|
||||
|
||||
Ok((factory, hr))
|
||||
}
|
||||
|
||||
pub fn get_debug_interface1(&self) -> libloading::Result<D3DResult<InfoQueue>> {
|
||||
type Fun = extern "system" fn(
|
||||
winapi::shared::minwindef::UINT,
|
||||
winapi::shared::guiddef::REFIID,
|
||||
*mut *mut winapi::ctypes::c_void,
|
||||
) -> HRESULT;
|
||||
|
||||
let mut queue = InfoQueue::null();
|
||||
let hr = unsafe {
|
||||
let func: libloading::Symbol<Fun> = self.lib.get(b"DXGIGetDebugInterface1")?;
|
||||
func(
|
||||
0,
|
||||
&dxgidebug::IDXGIInfoQueue::uuidof(),
|
||||
queue.mut_void(),
|
||||
)
|
||||
};
|
||||
Ok((queue, hr))
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: strong types
|
||||
pub struct SwapchainDesc {
|
||||
pub width: u32,
|
||||
@@ -103,6 +160,7 @@ impl Factory2 {
|
||||
}
|
||||
|
||||
impl Factory4 {
|
||||
#[cfg(feature = "libstatic")]
|
||||
pub fn create(flags: FactoryCreationFlags) -> D3DResult<Self> {
|
||||
let mut factory = Factory4::null();
|
||||
let hr = unsafe {
|
||||
|
||||
@@ -83,3 +83,8 @@ impl Error {
|
||||
CStr::from_ptr(data as *const _ as *const _)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "libloading")]
|
||||
pub struct D3D12Lib {
|
||||
lib: libloading::Library,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user