mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Adds D3D11 DXGI Support and COM Helper Chain (#37)
* Add older dxgi methods * Add create_swapchain_for_composition * Add DXGIFactory6 * Write COM inheritance chain macro * Add DXGIAdapter chain * Make accessing base of inheritance chain easy * Add `mut_self` to WeakPtr * Add TryFrom<u32> for FeatureLevel * Fix compile error on 1.51 * Comments
This commit is contained in:
committed by
GitHub
parent
a9ef6577b6
commit
ffe5e261da
@@ -22,7 +22,7 @@ libloading = { version = "0.7", optional = true }
|
||||
|
||||
[dependencies.winapi]
|
||||
version = "0.3"
|
||||
features = ["dxgi1_2","dxgi1_3","dxgi1_4","dxgidebug","d3d12","d3d12sdklayers","d3dcommon","d3dcompiler","dxgiformat","synchapi","winerror"]
|
||||
features = ["dxgi1_2","dxgi1_3","dxgi1_4","dxgi1_5","dxgi1_6","dxgidebug","d3d12","d3d12sdklayers","d3dcommon","d3dcompiler","dxgiformat","synchapi","winerror"]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
default-target = "x86_64-pc-windows-msvc"
|
||||
|
||||
163
src/com.rs
163
src/com.rs
@@ -31,9 +31,13 @@ impl<T> WeakPtr<T> {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub unsafe fn mut_void(&mut self) -> *mut *mut c_void {
|
||||
pub fn mut_void(&mut self) -> *mut *mut c_void {
|
||||
&mut self.0 as *mut *mut _ as *mut *mut _
|
||||
}
|
||||
|
||||
pub fn mut_self(&mut self) -> *mut *mut T {
|
||||
&mut self.0 as *mut *mut _
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Interface> WeakPtr<T> {
|
||||
@@ -100,3 +104,160 @@ impl<T> Hash for WeakPtr<T> {
|
||||
self.0.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
/// Macro that allows generation of an easy to use enum for dealing with many different possible versions of a COM object.
|
||||
///
|
||||
/// Give the variants so that parents come before children. This often manifests as going up in order (1 -> 2 -> 3). This is vital for safety.
|
||||
///
|
||||
/// Three function names need to be attached to each variant. The examples are given for the MyComObject1 variant below:
|
||||
/// - the from function (`WeakPtr<actual::ComObject1> -> Self`)
|
||||
/// - the as function (`&self -> Option<WeakPtr<actual::ComObject1>>`)
|
||||
/// - the unwrap function (`&self -> WeakPtr<actual::ComObject1>` panicing on failure to cast)
|
||||
///
|
||||
/// ```rust
|
||||
/// # pub use d3d12::weak_com_inheritance_chain;
|
||||
/// # mod actual {
|
||||
/// # pub struct ComObject; impl winapi::Interface for ComObject { fn uuidof() -> winapi::shared::guiddef::GUID { todo!() } }
|
||||
/// # pub struct ComObject1; impl winapi::Interface for ComObject1 { fn uuidof() -> winapi::shared::guiddef::GUID { todo!() } }
|
||||
/// # pub struct ComObject2; impl winapi::Interface for ComObject2 { fn uuidof() -> winapi::shared::guiddef::GUID { todo!() } }
|
||||
/// # }
|
||||
/// weak_com_inheritance_chain! {
|
||||
/// pub enum MyComObject {
|
||||
/// MyComObject(actual::ComObject), from_my_com_object, as_my_com_object, my_com_object; // First variant doesn't use "unwrap" as it can never fail
|
||||
/// MyComObject1(actual::ComObject1), from_my_com_object1, as_my_com_object1, unwrap_my_com_object1;
|
||||
/// MyComObject2(actual::ComObject2), from_my_com_object2, as_my_com_object2, unwrap_my_com_object2;
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! weak_com_inheritance_chain {
|
||||
// We first match a human readable enum style, before going into the recursive section.
|
||||
//
|
||||
// Internal calls to the macro have either the prefix
|
||||
// - @recursion_logic for the recursion and termination
|
||||
// - @render_members for the actual call to fill in the members.
|
||||
(
|
||||
$(#[$meta:meta])*
|
||||
$vis:vis enum $name:ident {
|
||||
$first_variant:ident($first_type:ty), $first_from_name:ident, $first_as_name:ident, $first_unwrap_name:ident $(;)?
|
||||
$($variant:ident($type:ty), $from_name:ident, $as_name:ident, $unwrap_name:ident);* $(;)?
|
||||
}
|
||||
) => {
|
||||
$(#[$meta])*
|
||||
$vis enum $name {
|
||||
$first_variant($crate::WeakPtr<$first_type>),
|
||||
$(
|
||||
$variant($crate::WeakPtr<$type>)
|
||||
),+
|
||||
}
|
||||
impl $name {
|
||||
$vis unsafe fn destroy(&self) {
|
||||
match *self {
|
||||
Self::$first_variant(v) => v.destroy(),
|
||||
$(
|
||||
Self::$variant(v) => v.destroy(),
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
$crate::weak_com_inheritance_chain! {
|
||||
@recursion_logic,
|
||||
$vis,
|
||||
;
|
||||
$first_variant($first_type), $first_from_name, $first_as_name, $first_unwrap_name;
|
||||
$($variant($type), $from_name, $as_name, $unwrap_name);*
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for $name {
|
||||
type Target = $crate::WeakPtr<$first_type>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.$first_unwrap_name()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// This is the iteration case of the recursion. We instantiate the member functions for the variant we
|
||||
// are currently at, recursing on ourself for the next variant. Note we only keep track of the previous
|
||||
// variant name, not the functions names, as those are not needed.
|
||||
(
|
||||
@recursion_logic,
|
||||
$vis:vis,
|
||||
$(,)? $($prev_variant:ident),* $(,)?;
|
||||
$this_variant:ident($this_type:ty), $this_from_name:ident, $this_as_name:ident, $this_unwrap_name:ident $(;)?
|
||||
$($next_variant:ident($next_type:ty), $next_from_name:ident, $next_as_name:ident, $next_unwrap_name:ident);*
|
||||
) => {
|
||||
// Actually generate the members for this variant. Needs the previous and future variant names.
|
||||
$crate::weak_com_inheritance_chain! {
|
||||
@render_members,
|
||||
$vis,
|
||||
$this_from_name, $this_as_name, $this_unwrap_name;
|
||||
$($prev_variant),*;
|
||||
$this_variant($this_type);
|
||||
$($next_variant),*;
|
||||
}
|
||||
|
||||
// Recurse on ourselves. If there is no future variants left, we'll hit the base case as the final expansion returns no tokens.
|
||||
$crate::weak_com_inheritance_chain! {
|
||||
@recursion_logic,
|
||||
$vis,
|
||||
$($prev_variant),* , $this_variant;
|
||||
$($next_variant($next_type), $next_from_name, $next_as_name, $next_unwrap_name);*
|
||||
}
|
||||
};
|
||||
// Base case for recursion. There are no more variants left
|
||||
(
|
||||
@recursion_logic,
|
||||
$vis:vis,
|
||||
$($prev_variant:ident),*;
|
||||
) => {};
|
||||
|
||||
|
||||
// This is where we generate the members using the given names.
|
||||
(
|
||||
@render_members,
|
||||
$vis:vis,
|
||||
$from_name:ident, $as_name:ident, $unwrap_name:ident;
|
||||
$($prev_variant:ident),*;
|
||||
$variant:ident($type:ty);
|
||||
$($next_variant:ident),*;
|
||||
) => {
|
||||
// Construct this enum from weak pointer to this interface. For best usability, always use the highest constructor you can. This doesn't try to upcast.
|
||||
$vis unsafe fn $from_name(value: $crate::WeakPtr<$type>) -> Self {
|
||||
Self::$variant(value)
|
||||
}
|
||||
|
||||
// Returns Some if the value implements the interface otherwise returns None.
|
||||
$vis fn $as_name(&self) -> Option<&$crate::WeakPtr<$type>> {
|
||||
match *self {
|
||||
$(
|
||||
Self::$prev_variant(_) => None,
|
||||
)*
|
||||
Self::$variant(ref v) => Some(v),
|
||||
$(
|
||||
Self::$next_variant(ref v) => {
|
||||
// v is &WeakPtr<NextType> and se cast to &WeakPtr<Type>
|
||||
Some(unsafe { std::mem::transmute(v) })
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the interface if the value implements it, otherwise panics.
|
||||
#[track_caller]
|
||||
$vis fn $unwrap_name(&self) -> &$crate::WeakPtr<$type> {
|
||||
match *self {
|
||||
$(
|
||||
Self::$prev_variant(_) => panic!(concat!("Tried to unwrap a ", stringify!($prev_variant), " as a ", stringify!($variant))),
|
||||
)*
|
||||
Self::$variant(ref v) => &*v,
|
||||
$(
|
||||
Self::$next_variant(ref v) => {
|
||||
// v is &WeakPtr<NextType> and se cast to &WeakPtr<Type>
|
||||
unsafe { std::mem::transmute(v) }
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -156,6 +156,7 @@ impl RootParameter {
|
||||
impl fmt::Debug for RootParameter {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)] // False-positive
|
||||
enum Inner<'a> {
|
||||
Table(&'a [DescriptorRange]),
|
||||
Constants { binding: Binding, num: u32 },
|
||||
|
||||
184
src/dxgi.rs
184
src/dxgi.rs
@@ -1,8 +1,11 @@
|
||||
use crate::{com::WeakPtr, CommandQueue, D3DResult, Resource, SampleDesc, HRESULT};
|
||||
use crate::{com::WeakPtr, D3DResult, Resource, SampleDesc, HRESULT};
|
||||
use std::ptr;
|
||||
use winapi::{
|
||||
shared::{dxgi, dxgi1_2, dxgi1_3, dxgi1_4, dxgiformat, dxgitype, windef::HWND},
|
||||
um::{d3d12, dxgidebug},
|
||||
shared::{
|
||||
dxgi, dxgi1_2, dxgi1_3, dxgi1_4, dxgi1_5, dxgi1_6, dxgiformat, dxgitype, minwindef::TRUE,
|
||||
windef::HWND,
|
||||
},
|
||||
um::{d3d12, dxgidebug, unknwnbase::IUnknown},
|
||||
Interface,
|
||||
};
|
||||
|
||||
@@ -39,13 +42,53 @@ pub enum AlphaMode {
|
||||
ForceDword = dxgi1_2::DXGI_ALPHA_MODE_FORCE_DWORD,
|
||||
}
|
||||
|
||||
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 Adapter1 = WeakPtr<dxgi::IDXGIAdapter1>;
|
||||
pub type Adapter2 = WeakPtr<dxgi1_2::IDXGIAdapter2>;
|
||||
pub type Adapter3 = WeakPtr<dxgi1_4::IDXGIAdapter3>;
|
||||
pub type Adapter4 = WeakPtr<dxgi1_6::IDXGIAdapter4>;
|
||||
crate::weak_com_inheritance_chain! {
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Hash)]
|
||||
pub enum DxgiAdapter {
|
||||
Adapter1(dxgi::IDXGIAdapter1), from_adapter1, as_adapter1, adapter1;
|
||||
Adapter2(dxgi1_2::IDXGIAdapter2), from_adapter2, as_adapter2, unwrap_adapter2;
|
||||
Adapter3(dxgi1_4::IDXGIAdapter3), from_adapter3, as_adapter3, unwrap_adapter3;
|
||||
Adapter4(dxgi1_6::IDXGIAdapter4), from_adapter4, as_adapter4, unwrap_adapter4;
|
||||
}
|
||||
}
|
||||
|
||||
pub type Factory1 = WeakPtr<dxgi::IDXGIFactory1>;
|
||||
pub type Factory2 = WeakPtr<dxgi1_2::IDXGIFactory2>;
|
||||
pub type Factory3 = WeakPtr<dxgi1_3::IDXGIFactory3>;
|
||||
pub type Factory4 = WeakPtr<dxgi1_4::IDXGIFactory4>;
|
||||
pub type Factory5 = WeakPtr<dxgi1_5::IDXGIFactory5>;
|
||||
pub type Factory6 = WeakPtr<dxgi1_6::IDXGIFactory6>;
|
||||
crate::weak_com_inheritance_chain! {
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Hash)]
|
||||
pub enum DxgiFactory {
|
||||
Factory1(dxgi::IDXGIFactory1), from_factory1, as_factory1, factory1;
|
||||
Factory2(dxgi1_2::IDXGIFactory2), from_factory2, as_factory2, unwrap_factory2;
|
||||
Factory3(dxgi1_3::IDXGIFactory3), from_factory3, as_factory3, unwrap_factory3;
|
||||
Factory4(dxgi1_4::IDXGIFactory4), from_factory4, as_factory4, unwrap_factory4;
|
||||
Factory5(dxgi1_5::IDXGIFactory5), from_factory5, as_factory5, unwrap_factory5;
|
||||
Factory6(dxgi1_6::IDXGIFactory6), from_factory6, as_factory6, unwrap_factory6;
|
||||
}
|
||||
}
|
||||
|
||||
pub type SwapChain = WeakPtr<dxgi::IDXGISwapChain>;
|
||||
pub type SwapChain1 = WeakPtr<dxgi1_2::IDXGISwapChain1>;
|
||||
pub type SwapChain2 = WeakPtr<dxgi1_3::IDXGISwapChain2>;
|
||||
pub type SwapChain3 = WeakPtr<dxgi1_4::IDXGISwapChain3>;
|
||||
crate::weak_com_inheritance_chain! {
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Hash)]
|
||||
pub enum DxgiSwapchain {
|
||||
SwapChain(dxgi::IDXGISwapChain), from_swap_chain, as_swap_chain, swap_chain;
|
||||
SwapChain1(dxgi1_2::IDXGISwapChain1), from_swap_chain1, as_swap_chain1, unwrap_swap_chain1;
|
||||
SwapChain2(dxgi1_3::IDXGISwapChain2), from_swap_chain2, as_swap_chain2, unwrap_swap_chain2;
|
||||
SwapChain3(dxgi1_4::IDXGISwapChain3), from_swap_chain3, as_swap_chain3, unwrap_swap_chain3;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "libloading")]
|
||||
#[derive(Debug)]
|
||||
@@ -82,6 +125,21 @@ impl DxgiLib {
|
||||
Ok((factory, hr))
|
||||
}
|
||||
|
||||
pub fn create_factory1(&self) -> Result<D3DResult<Factory1>, libloading::Error> {
|
||||
type Fun = extern "system" fn(
|
||||
winapi::shared::guiddef::REFIID,
|
||||
*mut *mut winapi::ctypes::c_void,
|
||||
) -> HRESULT;
|
||||
|
||||
let mut factory = Factory1::null();
|
||||
let hr = unsafe {
|
||||
let func: libloading::Symbol<Fun> = self.lib.get(b"CreateDXGIFactory1")?;
|
||||
func(&dxgi::IDXGIFactory1::uuidof(), factory.mut_void())
|
||||
};
|
||||
|
||||
Ok((factory, hr))
|
||||
}
|
||||
|
||||
pub fn get_debug_interface1(&self) -> Result<D3DResult<InfoQueue>, libloading::Error> {
|
||||
type Fun = extern "system" fn(
|
||||
winapi::shared::minwindef::UINT,
|
||||
@@ -112,38 +170,80 @@ pub struct SwapchainDesc {
|
||||
pub alpha_mode: AlphaMode,
|
||||
pub flags: u32,
|
||||
}
|
||||
impl SwapchainDesc {
|
||||
pub fn to_desc1(&self) -> dxgi1_2::DXGI_SWAP_CHAIN_DESC1 {
|
||||
dxgi1_2::DXGI_SWAP_CHAIN_DESC1 {
|
||||
AlphaMode: self.alpha_mode as _,
|
||||
BufferCount: self.buffer_count,
|
||||
Width: self.width,
|
||||
Height: self.height,
|
||||
Format: self.format,
|
||||
Flags: self.flags,
|
||||
BufferUsage: self.buffer_usage,
|
||||
SampleDesc: dxgitype::DXGI_SAMPLE_DESC {
|
||||
Count: self.sample.count,
|
||||
Quality: self.sample.quality,
|
||||
},
|
||||
Scaling: self.scaling as _,
|
||||
Stereo: self.stereo as _,
|
||||
SwapEffect: self.swap_effect as _,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Factory1 {
|
||||
pub fn create_swapchain(
|
||||
&self,
|
||||
queue: *mut IUnknown,
|
||||
hwnd: HWND,
|
||||
desc: &SwapchainDesc,
|
||||
) -> D3DResult<SwapChain> {
|
||||
let mut desc = dxgi::DXGI_SWAP_CHAIN_DESC {
|
||||
BufferDesc: dxgitype::DXGI_MODE_DESC {
|
||||
Width: desc.width,
|
||||
Height: desc.width,
|
||||
RefreshRate: dxgitype::DXGI_RATIONAL {
|
||||
Numerator: 1,
|
||||
Denominator: 60,
|
||||
},
|
||||
Format: desc.format,
|
||||
ScanlineOrdering: dxgitype::DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED,
|
||||
Scaling: dxgitype::DXGI_MODE_SCALING_UNSPECIFIED,
|
||||
},
|
||||
SampleDesc: dxgitype::DXGI_SAMPLE_DESC {
|
||||
Count: desc.sample.count,
|
||||
Quality: desc.sample.quality,
|
||||
},
|
||||
BufferUsage: desc.buffer_usage,
|
||||
BufferCount: desc.buffer_count,
|
||||
OutputWindow: hwnd,
|
||||
Windowed: TRUE,
|
||||
SwapEffect: desc.swap_effect as _,
|
||||
Flags: desc.flags,
|
||||
};
|
||||
|
||||
let mut swapchain = SwapChain::null();
|
||||
let hr =
|
||||
unsafe { self.CreateSwapChain(queue, &mut desc, swapchain.mut_void() as *mut *mut _) };
|
||||
|
||||
(swapchain, hr)
|
||||
}
|
||||
}
|
||||
|
||||
impl Factory2 {
|
||||
// TODO: interface not complete
|
||||
pub fn create_swapchain_for_hwnd(
|
||||
&self,
|
||||
queue: CommandQueue,
|
||||
queue: *mut IUnknown,
|
||||
hwnd: HWND,
|
||||
desc: &SwapchainDesc,
|
||||
) -> D3DResult<SwapChain1> {
|
||||
let desc = dxgi1_2::DXGI_SWAP_CHAIN_DESC1 {
|
||||
AlphaMode: desc.alpha_mode as _,
|
||||
BufferCount: desc.buffer_count,
|
||||
Width: desc.width,
|
||||
Height: desc.height,
|
||||
Format: desc.format,
|
||||
Flags: desc.flags,
|
||||
BufferUsage: desc.buffer_usage,
|
||||
SampleDesc: dxgitype::DXGI_SAMPLE_DESC {
|
||||
Count: desc.sample.count,
|
||||
Quality: desc.sample.quality,
|
||||
},
|
||||
Scaling: desc.scaling as _,
|
||||
Stereo: desc.stereo as _,
|
||||
SwapEffect: desc.swap_effect as _,
|
||||
};
|
||||
|
||||
let mut swap_chain = SwapChain1::null();
|
||||
let hr = unsafe {
|
||||
self.CreateSwapChainForHwnd(
|
||||
queue.as_mut_ptr() as *mut _,
|
||||
queue,
|
||||
hwnd,
|
||||
&desc,
|
||||
&desc.to_desc1(),
|
||||
ptr::null(),
|
||||
ptr::null_mut(),
|
||||
swap_chain.mut_void() as *mut *mut _,
|
||||
@@ -152,6 +252,24 @@ impl Factory2 {
|
||||
|
||||
(swap_chain, hr)
|
||||
}
|
||||
|
||||
pub fn create_swapchain_for_composition(
|
||||
&self,
|
||||
queue: *mut IUnknown,
|
||||
desc: &SwapchainDesc,
|
||||
) -> D3DResult<SwapChain1> {
|
||||
let mut swap_chain = SwapChain1::null();
|
||||
let hr = unsafe {
|
||||
self.CreateSwapChainForComposition(
|
||||
queue,
|
||||
&desc.to_desc1(),
|
||||
ptr::null_mut(),
|
||||
swap_chain.mut_void() as *mut *mut _,
|
||||
)
|
||||
};
|
||||
|
||||
(swap_chain, hr)
|
||||
}
|
||||
}
|
||||
|
||||
impl Factory4 {
|
||||
@@ -169,10 +287,6 @@ impl Factory4 {
|
||||
(factory, hr)
|
||||
}
|
||||
|
||||
pub fn as_factory2(&self) -> Factory2 {
|
||||
unsafe { Factory2::from_raw(self.as_mut_ptr() as *mut _) }
|
||||
}
|
||||
|
||||
pub fn enumerate_adapters(&self, id: u32) -> D3DResult<Adapter1> {
|
||||
let mut adapter = Adapter1::null();
|
||||
let hr = unsafe { self.EnumAdapters1(id, adapter.mut_void() as *mut *mut _) };
|
||||
@@ -214,17 +328,7 @@ impl SwapChain {
|
||||
}
|
||||
}
|
||||
|
||||
impl SwapChain1 {
|
||||
pub fn as_swapchain0(&self) -> SwapChain {
|
||||
unsafe { SwapChain::from_raw(self.as_mut_ptr() as *mut _) }
|
||||
}
|
||||
}
|
||||
|
||||
impl SwapChain3 {
|
||||
pub fn as_swapchain0(&self) -> SwapChain {
|
||||
unsafe { SwapChain::from_raw(self.as_mut_ptr() as *mut _) }
|
||||
}
|
||||
|
||||
pub fn get_current_back_buffer_index(&self) -> u32 {
|
||||
unsafe { self.GetCurrentBackBufferIndex() }
|
||||
}
|
||||
|
||||
22
src/lib.rs
22
src/lib.rs
@@ -1,7 +1,7 @@
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
|
||||
use std::ffi::CStr;
|
||||
use std::{convert::TryFrom, ffi::CStr};
|
||||
use winapi::{
|
||||
shared::dxgiformat,
|
||||
um::{d3d12, d3dcommon},
|
||||
@@ -64,6 +64,7 @@ pub struct SampleDesc {
|
||||
}
|
||||
|
||||
#[repr(u32)]
|
||||
#[non_exhaustive]
|
||||
pub enum FeatureLevel {
|
||||
L9_1 = d3dcommon::D3D_FEATURE_LEVEL_9_1,
|
||||
L9_2 = d3dcommon::D3D_FEATURE_LEVEL_9_2,
|
||||
@@ -76,6 +77,25 @@ pub enum FeatureLevel {
|
||||
L12_1 = d3dcommon::D3D_FEATURE_LEVEL_12_1,
|
||||
}
|
||||
|
||||
impl TryFrom<u32> for FeatureLevel {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: u32) -> Result<Self, Self::Error> {
|
||||
Ok(match value {
|
||||
d3dcommon::D3D_FEATURE_LEVEL_9_1 => Self::L9_1,
|
||||
d3dcommon::D3D_FEATURE_LEVEL_9_2 => Self::L9_2,
|
||||
d3dcommon::D3D_FEATURE_LEVEL_9_3 => Self::L9_3,
|
||||
d3dcommon::D3D_FEATURE_LEVEL_10_0 => Self::L10_0,
|
||||
d3dcommon::D3D_FEATURE_LEVEL_10_1 => Self::L10_1,
|
||||
d3dcommon::D3D_FEATURE_LEVEL_11_0 => Self::L11_0,
|
||||
d3dcommon::D3D_FEATURE_LEVEL_11_1 => Self::L11_1,
|
||||
d3dcommon::D3D_FEATURE_LEVEL_12_0 => Self::L12_0,
|
||||
d3dcommon::D3D_FEATURE_LEVEL_12_1 => Self::L12_1,
|
||||
_ => return Err(()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub type Blob = WeakPtr<d3dcommon::ID3DBlob>;
|
||||
|
||||
pub type Error = WeakPtr<d3dcommon::ID3DBlob>;
|
||||
|
||||
Reference in New Issue
Block a user