mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 08:13:27 +00:00
Merge #4
4: Factory, swapchain and more r=kvark a=msiglreith Additionally renaming the crate to `d3d12` Co-authored-by: msiglreith <m.siglreith@gmail.com>
This commit is contained in:
commit
6369df29e8
@ -1,8 +1,11 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "d3d12-rs"
|
name = "d3d12"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["msiglreith <m.siglreith@gmail.com>"]
|
authors = ["msiglreith <m.siglreith@gmail.com>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bitflags = "1"
|
bitflags = "1"
|
||||||
winapi = { version = "0.3", features = ["d3d12","d3dcommon","d3dcompiler","dxgiformat","winerror"] }
|
|
||||||
|
[dependencies.winapi]
|
||||||
|
version = "0.3"
|
||||||
|
features = ["dxgi1_2","dxgi1_3","dxgi1_4","d3d12","d3d12sdklayers","d3dcommon","d3dcompiler","dxgiformat","synchapi","winerror"]
|
||||||
|
@ -15,6 +15,10 @@ impl<T> WeakPtr<T> {
|
|||||||
WeakPtr(ptr::null_mut())
|
WeakPtr(ptr::null_mut())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub unsafe fn from_raw(raw: *mut T) -> Self {
|
||||||
|
WeakPtr(raw)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_null(&self) -> bool {
|
pub fn is_null(&self) -> bool {
|
||||||
self.0.is_null()
|
self.0.is_null()
|
||||||
}
|
}
|
||||||
|
@ -57,9 +57,14 @@ impl IndirectArgument {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub type CommandSignature = WeakPtr<d3d12::ID3D12CommandSignature>;
|
pub type CommandSignature = WeakPtr<d3d12::ID3D12CommandSignature>;
|
||||||
|
pub type CommandList = WeakPtr<d3d12::ID3D12CommandList>;
|
||||||
pub type GraphicsCommandList = WeakPtr<d3d12::ID3D12GraphicsCommandList>;
|
pub type GraphicsCommandList = WeakPtr<d3d12::ID3D12GraphicsCommandList>;
|
||||||
|
|
||||||
impl GraphicsCommandList {
|
impl GraphicsCommandList {
|
||||||
|
pub fn as_list(&self) -> CommandList {
|
||||||
|
unsafe { CommandList::from_raw(self.as_mut_ptr() as *mut _) }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn close(&self) -> HRESULT {
|
pub fn close(&self) -> HRESULT {
|
||||||
unsafe { self.Close() }
|
unsafe { self.Close() }
|
||||||
}
|
}
|
||||||
@ -103,6 +108,12 @@ impl GraphicsCommandList {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn clear_render_target_view(&self, rtv: CpuDescriptor, color: [f32; 4], rects: &[Rect]) {
|
||||||
|
unsafe {
|
||||||
|
self.ClearRenderTargetView(rtv, &color, rects.len() as _, rects.as_ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn dispatch(&self, count: WorkGroupCount) {
|
pub fn dispatch(&self, count: WorkGroupCount) {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.Dispatch(count[0], count[1], count[2]);
|
self.Dispatch(count[0], count[1], count[2]);
|
||||||
|
21
src/debug.rs
Normal file
21
src/debug.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
use com::WeakPtr;
|
||||||
|
use winapi::um::{d3d12, d3d12sdklayers};
|
||||||
|
use winapi::Interface;
|
||||||
|
use D3DResult;
|
||||||
|
|
||||||
|
pub type Debug = WeakPtr<d3d12sdklayers::ID3D12Debug>;
|
||||||
|
|
||||||
|
impl Debug {
|
||||||
|
pub fn get_interface() -> D3DResult<Self> {
|
||||||
|
let mut debug = Debug::null();
|
||||||
|
let hr = unsafe {
|
||||||
|
d3d12::D3D12GetDebugInterface(&d3d12sdklayers::ID3D12Debug::uuidof(), debug.mut_void())
|
||||||
|
};
|
||||||
|
|
||||||
|
(debug, hr)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn enable_layer(&self) {
|
||||||
|
unsafe { self.EnableDebugLayer() }
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
use com::WeakPtr;
|
use com::WeakPtr;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
use winapi::shared::dxgiformat;
|
||||||
use winapi::um::d3d12;
|
use winapi::um::d3d12;
|
||||||
use {Blob, D3DResult, Error, TextureAddressMode};
|
use {Blob, D3DResult, Error, TextureAddressMode};
|
||||||
|
|
||||||
@ -198,3 +199,23 @@ impl RootSignature {
|
|||||||
((blob, error), hr)
|
((blob, error), hr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct RenderTargetViewDesc(pub(crate) d3d12::D3D12_RENDER_TARGET_VIEW_DESC);
|
||||||
|
|
||||||
|
impl RenderTargetViewDesc {
|
||||||
|
pub fn texture_2d(format: dxgiformat::DXGI_FORMAT, mip_slice: u32, plane_slice: u32) -> Self {
|
||||||
|
let mut desc = d3d12::D3D12_RENDER_TARGET_VIEW_DESC {
|
||||||
|
Format: format,
|
||||||
|
ViewDimension: d3d12::D3D12_RTV_DIMENSION_TEXTURE2D,
|
||||||
|
..unsafe { mem::zeroed() }
|
||||||
|
};
|
||||||
|
|
||||||
|
*unsafe { desc.u.Texture2D_mut() } = d3d12::D3D12_TEX2D_RTV {
|
||||||
|
MipSlice: mip_slice,
|
||||||
|
PlaneSlice: plane_slice,
|
||||||
|
};
|
||||||
|
|
||||||
|
RenderTargetViewDesc(desc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2,15 +2,15 @@
|
|||||||
|
|
||||||
use com::WeakPtr;
|
use com::WeakPtr;
|
||||||
use command_list::{CmdListType, CommandSignature, IndirectArgument};
|
use command_list::{CmdListType, CommandSignature, IndirectArgument};
|
||||||
use descriptor::{CpuDescriptor, HeapFlags, HeapType};
|
use descriptor::{CpuDescriptor, HeapFlags, HeapType, RenderTargetViewDesc};
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
use winapi::um::d3d12;
|
use winapi::um::d3d12;
|
||||||
use winapi::Interface;
|
use winapi::Interface;
|
||||||
use {pso, query, queue};
|
use {pso, query, queue};
|
||||||
use {
|
use {
|
||||||
Blob, CachedPSO, CommandAllocator, CommandQueue, D3DResult, DescriptorHeap, FeatureLevel,
|
Blob, CachedPSO, CommandAllocator, CommandQueue, D3DResult, DescriptorHeap, FeatureLevel,
|
||||||
GraphicsCommandList, NodeMask, PipelineState, QueryHeap, RootSignature, Shader,
|
Fence, GraphicsCommandList, NodeMask, PipelineState, QueryHeap, Resource, RootSignature,
|
||||||
TextureAddressMode,
|
Shader, TextureAddressMode,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub type Device = WeakPtr<d3d12::ID3D12Device>;
|
pub type Device = WeakPtr<d3d12::ID3D12Device>;
|
||||||
@ -265,4 +265,30 @@ impl Device {
|
|||||||
|
|
||||||
(signature, hr)
|
(signature, hr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn create_render_target_view(
|
||||||
|
&self,
|
||||||
|
resource: Resource,
|
||||||
|
desc: &RenderTargetViewDesc,
|
||||||
|
descriptor: CpuDescriptor,
|
||||||
|
) {
|
||||||
|
unsafe {
|
||||||
|
self.CreateRenderTargetView(resource.as_mut_ptr(), &desc.0 as *const _, descriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: interface not complete
|
||||||
|
pub fn create_fence(&self, initial: u64) -> D3DResult<Fence> {
|
||||||
|
let mut fence = Fence::null();
|
||||||
|
let hr = unsafe {
|
||||||
|
self.CreateFence(
|
||||||
|
initial,
|
||||||
|
d3d12::D3D12_FENCE_FLAG_NONE,
|
||||||
|
&d3d12::ID3D12Fence::uuidof(),
|
||||||
|
fence.mut_void(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
(fence, hr)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
160
src/dxgi.rs
Normal file
160
src/dxgi.rs
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
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::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<dxgi::IDXGIAdapter1>;
|
||||||
|
pub type Factory2 = WeakPtr<dxgi1_2::IDXGIFactory2>;
|
||||||
|
pub type Factory4 = WeakPtr<dxgi1_4::IDXGIFactory4>;
|
||||||
|
pub type SwapChain = WeakPtr<dxgi::IDXGISwapChain>;
|
||||||
|
pub type SwapChain1 = WeakPtr<dxgi1_2::IDXGISwapChain1>;
|
||||||
|
pub type SwapChain3 = WeakPtr<dxgi1_4::IDXGISwapChain3>;
|
||||||
|
|
||||||
|
// 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<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 _,
|
||||||
|
hwnd,
|
||||||
|
&desc,
|
||||||
|
ptr::null(),
|
||||||
|
ptr::null_mut(),
|
||||||
|
swap_chain.mut_void() as *mut *mut _,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
(swap_chain, hr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Factory4 {
|
||||||
|
pub fn create(flags: FactoryCreationFlags) -> D3DResult<Self> {
|
||||||
|
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<Adapter1> {
|
||||||
|
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<Resource> {
|
||||||
|
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() }
|
||||||
|
}
|
||||||
|
}
|
@ -9,8 +9,10 @@ use winapi::um::{d3d12, d3dcommon};
|
|||||||
mod com;
|
mod com;
|
||||||
pub mod command_allocator;
|
pub mod command_allocator;
|
||||||
pub mod command_list;
|
pub mod command_list;
|
||||||
|
pub mod debug;
|
||||||
pub mod descriptor;
|
pub mod descriptor;
|
||||||
pub mod device;
|
pub mod device;
|
||||||
|
pub mod dxgi;
|
||||||
pub mod pso;
|
pub mod pso;
|
||||||
pub mod query;
|
pub mod query;
|
||||||
pub mod queue;
|
pub mod queue;
|
||||||
@ -20,6 +22,7 @@ pub mod sync;
|
|||||||
pub use self::com::WeakPtr;
|
pub use self::com::WeakPtr;
|
||||||
pub use self::command_allocator::CommandAllocator;
|
pub use self::command_allocator::CommandAllocator;
|
||||||
pub use self::command_list::{CommandSignature, GraphicsCommandList};
|
pub use self::command_list::{CommandSignature, GraphicsCommandList};
|
||||||
|
pub use self::debug::Debug;
|
||||||
pub use self::descriptor::{CpuDescriptor, DescriptorHeap, GpuDescriptor, RootSignature};
|
pub use self::descriptor::{CpuDescriptor, DescriptorHeap, GpuDescriptor, RootSignature};
|
||||||
pub use self::device::Device;
|
pub use self::device::Device;
|
||||||
pub use self::pso::{CachedPSO, PipelineState, Shader};
|
pub use self::pso::{CachedPSO, PipelineState, Shader};
|
||||||
@ -49,6 +52,11 @@ pub type WorkGroupCount = [u32; 3];
|
|||||||
|
|
||||||
pub type TextureAddressMode = [d3d12::D3D12_TEXTURE_ADDRESS_MODE; 3];
|
pub type TextureAddressMode = [d3d12::D3D12_TEXTURE_ADDRESS_MODE; 3];
|
||||||
|
|
||||||
|
pub struct SampleDesc {
|
||||||
|
pub count: u32,
|
||||||
|
pub quality: u32,
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum FeatureLevel {
|
pub enum FeatureLevel {
|
||||||
L9_1 = d3dcommon::D3D_FEATURE_LEVEL_9_1,
|
L9_1 = d3dcommon::D3D_FEATURE_LEVEL_9_1,
|
||||||
|
28
src/sync.rs
28
src/sync.rs
@ -1,14 +1,34 @@
|
|||||||
use com::WeakPtr;
|
use com::WeakPtr;
|
||||||
|
use std::ptr;
|
||||||
use winapi::um::d3d12;
|
use winapi::um::d3d12;
|
||||||
use winapi::um::winnt;
|
use winapi::um::{synchapi, winnt};
|
||||||
use HRESULT;
|
use HRESULT;
|
||||||
|
|
||||||
pub type Event = winnt::HANDLE;
|
#[derive(Copy, Clone)]
|
||||||
pub type Fence = WeakPtr<d3d12::ID3D12Fence>;
|
#[repr(transparent)]
|
||||||
|
pub struct Event(winnt::HANDLE);
|
||||||
|
impl Event {
|
||||||
|
pub fn create(manual_reset: bool, initial_state: bool) -> Self {
|
||||||
|
Event(unsafe {
|
||||||
|
synchapi::CreateEventA(
|
||||||
|
ptr::null_mut(),
|
||||||
|
manual_reset as _,
|
||||||
|
initial_state as _,
|
||||||
|
ptr::null(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: return value
|
||||||
|
pub fn wait(&self, timeout_ms: u32) -> u32 {
|
||||||
|
unsafe { synchapi::WaitForSingleObject(self.0, timeout_ms) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Fence = WeakPtr<d3d12::ID3D12Fence>;
|
||||||
impl Fence {
|
impl Fence {
|
||||||
pub fn set_event_on_completion(&self, event: Event, value: u64) -> HRESULT {
|
pub fn set_event_on_completion(&self, event: Event, value: u64) -> HRESULT {
|
||||||
unsafe { self.SetEventOnCompletion(value, event) }
|
unsafe { self.SetEventOnCompletion(value, event.0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_value(&self) -> u64 {
|
pub fn get_value(&self) -> u64 {
|
||||||
|
Loading…
Reference in New Issue
Block a user