From 2aa4a82499d4becd2284cdb482213d541b8804dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 16:29:10 +0200 Subject: Adding upstream version 86.0.1. Signed-off-by: Daniel Baumann --- third_party/rust/d3d12/src/dxgi.rs | 219 +++++++++++++++++++++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 third_party/rust/d3d12/src/dxgi.rs (limited to 'third_party/rust/d3d12/src/dxgi.rs') diff --git a/third_party/rust/d3d12/src/dxgi.rs b/third_party/rust/d3d12/src/dxgi.rs new file mode 100644 index 0000000000..991d1d0db4 --- /dev/null +++ b/third_party/rust/d3d12/src/dxgi.rs @@ -0,0 +1,219 @@ +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::{dxgidebug, d3d12}; +use winapi::Interface; +use {CommandQueue, D3DResult, Resource, SampleDesc, HRESULT}; + +bitflags! { + pub struct FactoryCreationFlags: u32 { + const DEBUG = dxgi1_3::DXGI_CREATE_FACTORY_DEBUG; + } +} + +#[repr(u32)] +#[derive(Debug, Copy, Clone)] +pub enum Scaling { + Stretch = dxgi1_2::DXGI_SCALING_STRETCH, + Identity = dxgi1_2::DXGI_SCALING_NONE, + Aspect = dxgi1_2::DXGI_SCALING_ASPECT_RATIO_STRETCH, +} + +#[repr(u32)] +#[derive(Debug, Copy, Clone)] +pub enum SwapEffect { + Discard = dxgi::DXGI_SWAP_EFFECT_DISCARD, + Sequential = dxgi::DXGI_SWAP_EFFECT_SEQUENTIAL, + FlipDiscard = dxgi::DXGI_SWAP_EFFECT_FLIP_DISCARD, + FlipSequential = dxgi::DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, +} + +#[repr(u32)] +#[derive(Debug, Copy, Clone)] +pub enum AlphaMode { + Unspecified = dxgi1_2::DXGI_ALPHA_MODE_UNSPECIFIED, + Premultiplied = dxgi1_2::DXGI_ALPHA_MODE_PREMULTIPLIED, + Straight = dxgi1_2::DXGI_ALPHA_MODE_STRAIGHT, + Ignore = dxgi1_2::DXGI_ALPHA_MODE_IGNORE, + ForceDword = dxgi1_2::DXGI_ALPHA_MODE_FORCE_DWORD, +} + +pub type Adapter1 = WeakPtr; +pub type Factory2 = WeakPtr; +pub type Factory4 = WeakPtr; +pub type InfoQueue = WeakPtr; +pub type SwapChain = WeakPtr; +pub type SwapChain1 = WeakPtr; +pub type SwapChain3 = WeakPtr; + +#[cfg(feature = "libloading")] +#[derive(Debug)] +pub struct DxgiLib { + lib: libloading::Library, +} + +#[cfg(feature = "libloading")] +impl DxgiLib { + pub fn new() -> libloading::Result { + libloading::Library::new("dxgi.dll") + .map(|lib| DxgiLib { + lib, + }) + } + + pub fn create_factory2( + &self, flags: FactoryCreationFlags + ) -> libloading::Result> { + 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 = 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> { + 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 = 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, + pub height: u32, + pub format: dxgiformat::DXGI_FORMAT, + pub stereo: bool, + pub sample: SampleDesc, + pub buffer_usage: dxgitype::DXGI_USAGE, + pub buffer_count: u32, + pub scaling: Scaling, + pub swap_effect: SwapEffect, + pub alpha_mode: AlphaMode, + pub flags: u32, +} + +impl Factory2 { + // TODO: interface not complete + pub fn create_swapchain_for_hwnd( + &self, + queue: CommandQueue, + hwnd: HWND, + desc: &SwapchainDesc, + ) -> D3DResult { + 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 _, + hwnd, + &desc, + ptr::null(), + ptr::null_mut(), + swap_chain.mut_void() as *mut *mut _, + ) + }; + + (swap_chain, hr) + } +} + +impl Factory4 { + #[cfg(feature = "implicit-link")] + pub fn create(flags: FactoryCreationFlags) -> D3DResult { + let mut factory = Factory4::null(); + let hr = unsafe { + dxgi1_3::CreateDXGIFactory2( + flags.bits(), + &dxgi1_4::IDXGIFactory4::uuidof(), + factory.mut_void(), + ) + }; + + (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 { + let mut adapter = Adapter1::null(); + let hr = unsafe { self.EnumAdapters1(id, adapter.mut_void() as *mut *mut _) }; + + (adapter, hr) + } +} + +impl SwapChain { + pub fn get_buffer(&self, id: u32) -> D3DResult { + let mut resource = Resource::null(); + let hr = + unsafe { self.GetBuffer(id, &d3d12::ID3D12Resource::uuidof(), resource.mut_void()) }; + + (resource, hr) + } + + // TODO: present flags + pub fn present(&self, interval: u32, flags: u32) -> HRESULT { + unsafe { self.Present(interval, flags) } + } +} + +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() } + } +} -- cgit v1.2.3