Add swapchain handling and 2d RTV creation

This commit is contained in:
msiglreith 2018-09-02 18:37:44 +02:00
parent 2aacc3b11b
commit 908c29ed7e
7 changed files with 180 additions and 5 deletions

View File

@ -5,4 +5,7 @@ authors = ["msiglreith <m.siglreith@gmail.com>"]
[dependencies]
bitflags = "1"
winapi = { version = "0.3", features = ["dxgi1_3","dxgi1_4","d3d12","d3d12sdklayers","d3dcommon","d3dcompiler","dxgiformat","winerror"] }
[dependencies.winapi]
version = "0.3"
features = ["dxgi1_2","dxgi1_3","dxgi1_4","d3d12","d3d12sdklayers","d3dcommon","d3dcompiler","dxgiformat","winerror"]

View File

@ -15,6 +15,10 @@ impl<T> WeakPtr<T> {
WeakPtr(ptr::null_mut())
}
pub unsafe fn from_raw(raw: *mut T) -> Self {
WeakPtr(raw)
}
pub fn is_null(&self) -> bool {
self.0.is_null()
}

View File

@ -103,6 +103,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) {
unsafe {
self.Dispatch(count[0], count[1], count[2]);

View File

@ -1,6 +1,7 @@
use com::WeakPtr;
use std::mem;
use std::ops::Range;
use winapi::shared::dxgiformat;
use winapi::um::d3d12;
use {Blob, D3DResult, Error, TextureAddressMode};
@ -198,3 +199,23 @@ impl RootSignature {
((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)
}
}

View File

@ -2,14 +2,14 @@
use com::WeakPtr;
use command_list::{CmdListType, CommandSignature, IndirectArgument};
use descriptor::{CpuDescriptor, HeapFlags, HeapType};
use descriptor::{CpuDescriptor, HeapFlags, HeapType, RenderTargetViewDesc};
use std::ops::Range;
use winapi::um::d3d12;
use winapi::Interface;
use {pso, query, queue};
use {
Blob, CachedPSO, CommandAllocator, CommandQueue, D3DResult, DescriptorHeap, FeatureLevel,
GraphicsCommandList, NodeMask, PipelineState, QueryHeap, RootSignature, Shader,
GraphicsCommandList, NodeMask, PipelineState, QueryHeap, Resource, RootSignature, Shader,
TextureAddressMode,
};
@ -265,4 +265,15 @@ impl Device {
(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);
}
}
}

View File

@ -1,7 +1,10 @@
use com::WeakPtr;
use winapi::shared::{dxgi, dxgi1_3, dxgi1_4};
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 D3DResult;
use {CommandQueue, D3DResult, Resource, SampleDesc, HRESULT};
bitflags! {
pub struct FactoryCreationFlags: u32 {
@ -9,8 +12,95 @@ bitflags! {
}
}
#[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> {
@ -26,6 +116,10 @@ impl Factory4 {
(factory, hr)
}
pub fn as2(&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 _) };
@ -33,3 +127,34 @@ impl Factory4 {
(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 as0(&self) -> SwapChain {
unsafe { SwapChain::from_raw(self.as_mut_ptr() as *mut _) }
}
}
impl SwapChain3 {
pub fn as0(&self) -> SwapChain {
unsafe { SwapChain::from_raw(self.as_mut_ptr() as *mut _) }
}
pub fn get_current_back_buffer_index(&self) -> u32 {
unsafe { self.GetCurrentBackBufferIndex() }
}
}

View File

@ -52,6 +52,11 @@ pub type WorkGroupCount = [u32; 3];
pub type TextureAddressMode = [d3d12::D3D12_TEXTURE_ADDRESS_MODE; 3];
pub struct SampleDesc {
pub count: u32,
pub quality: u32,
}
#[repr(u32)]
pub enum FeatureLevel {
L9_1 = d3dcommon::D3D_FEATURE_LEVEL_9_1,