Skip to content

Commit

Permalink
[ll] Implement surface and swapchain handling for d3d12
Browse files Browse the repository at this point in the history
  • Loading branch information
msiglreith committed Jan 19, 2017
1 parent ec61901 commit 3cd6964
Show file tree
Hide file tree
Showing 6 changed files with 203 additions and 4 deletions.
12 changes: 9 additions & 3 deletions examples/trianglell/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,21 @@
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate env_logger;
extern crate gfx_corell;

#[cfg(all(target_os = "windows", not(feature = "vulkan")))]
extern crate gfx_device_dx12ll as back;
#[cfg(feature = "vulkan")]
extern crate gfx_device_vulkanll as back;

extern crate winit;

use gfx_corell::{Instance, PhysicalDevice};
use gfx_corell::{Instance, PhysicalDevice, Surface, SwapChain};

pub type ColorFormat = gfx_corell::format::Rgba8;

fn main() {
env_logger::init().unwrap();
let window = winit::WindowBuilder::new()
.with_dimensions(1024, 768)
.with_title("triangle (Low Level)".to_string())
Expand All @@ -40,6 +43,9 @@ fn main() {
// build a new device and associated command queues
let (device, queues) = physical_devices[0].open();

let surface = back::Surface::from_window(&window, &instance);
let mut swap_chain = surface.build_swapchain::<ColorFormat>(1024, 768, &queues[0]);

'main: loop {
for event in window.poll_events() {
match event {
Expand All @@ -49,6 +55,6 @@ fn main() {
}
}

// swap_chain.present();
swap_chain.present();
}
}
1 change: 1 addition & 0 deletions src/backend/dx12ll/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ dxgi-sys = "0.2"
dxguid-sys = "0.2"
comptr = { git = "https://github.com/msiglreith/comptr-rs.git" }
winapi = "0.2"
winit = "0.5"
129 changes: 129 additions & 0 deletions src/backend/dx12ll/src/data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// Copyright 2017 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use core::format::Format;
use winapi::*;

pub fn map_format(format: Format, is_target: bool) -> Option<DXGI_FORMAT> {
use core::format::SurfaceType::*;
use core::format::ChannelType::*;
Some(match format.0 {
R4_G4 | R4_G4_B4_A4 | R5_G5_B5_A1 | R5_G6_B5 => return None,
R8 => match format.1 {
Int => DXGI_FORMAT_R8_SINT,
Uint => DXGI_FORMAT_R8_UINT,
Inorm => DXGI_FORMAT_R8_SNORM,
Unorm => DXGI_FORMAT_R8_UNORM,
_ => return None,
},
R8_G8 => match format.1 {
Int => DXGI_FORMAT_R8G8_SINT,
Uint => DXGI_FORMAT_R8G8_UINT,
Inorm => DXGI_FORMAT_R8G8_SNORM,
Unorm => DXGI_FORMAT_R8G8_UNORM,
_ => return None,
},
R8_G8_B8_A8 => match format.1 {
Int => DXGI_FORMAT_R8G8B8A8_SINT,
Uint => DXGI_FORMAT_R8G8B8A8_UINT,
Inorm => DXGI_FORMAT_R8G8B8A8_SNORM,
Unorm => DXGI_FORMAT_R8G8B8A8_UNORM,
Srgb => DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
_ => return None,
},
R10_G10_B10_A2 => match format.1 {
Uint => DXGI_FORMAT_R10G10B10A2_UINT,
Unorm => DXGI_FORMAT_R10G10B10A2_UNORM,
_ => return None,
},
R11_G11_B10 => match format.1 {
Float => DXGI_FORMAT_R11G11B10_FLOAT,
_ => return None,
},
R16 => match format.1 {
Int => DXGI_FORMAT_R16_SINT,
Uint => DXGI_FORMAT_R16_UINT,
Inorm => DXGI_FORMAT_R16_SNORM,
Unorm => DXGI_FORMAT_R16_UNORM,
Float => DXGI_FORMAT_R16_FLOAT,
_ => return None,
},
R16_G16 => match format.1 {
Int => DXGI_FORMAT_R16G16_SINT,
Uint => DXGI_FORMAT_R16G16_UINT,
Inorm => DXGI_FORMAT_R16G16_SNORM,
Unorm => DXGI_FORMAT_R16G16_UNORM,
Float => DXGI_FORMAT_R16G16_FLOAT,
_ => return None,
},
R16_G16_B16 => return None,
R16_G16_B16_A16 => match format.1 {
Int => DXGI_FORMAT_R16G16B16A16_SINT,
Uint => DXGI_FORMAT_R16G16B16A16_UINT,
Inorm => DXGI_FORMAT_R16G16B16A16_SNORM,
Unorm => DXGI_FORMAT_R16G16B16A16_UNORM,
Float => DXGI_FORMAT_R16G16B16A16_FLOAT,
_ => return None,
},
R32 => match format.1 {
Int => DXGI_FORMAT_R32_SINT,
Uint => DXGI_FORMAT_R32_UINT,
Float => DXGI_FORMAT_R32_FLOAT,
_ => return None,
},
R32_G32 => match format.1 {
Int => DXGI_FORMAT_R32G32_SINT,
Uint => DXGI_FORMAT_R32G32_UINT,
Float => DXGI_FORMAT_R32G32_FLOAT,
_ => return None,
},
R32_G32_B32 => match format.1 {
Int => DXGI_FORMAT_R32G32B32_SINT,
Uint => DXGI_FORMAT_R32G32B32_UINT,
Float => DXGI_FORMAT_R32G32B32_FLOAT,
_ => return None,
},
R32_G32_B32_A32 => match format.1 {
Int => DXGI_FORMAT_R32G32B32A32_SINT,
Uint => DXGI_FORMAT_R32G32B32A32_UINT,
Float => DXGI_FORMAT_R32G32B32A32_FLOAT,
_ => return None,
},
B8_G8_R8_A8 => match format.1 {
Unorm => DXGI_FORMAT_B8G8R8A8_UNORM,
_ => return None,
},
D16 => match (is_target, format.1) {
(true, _) => DXGI_FORMAT_D16_UNORM,
(false, Unorm) => DXGI_FORMAT_R16_UNORM,
_ => return None,
},
D24 => match (is_target, format.1) {
(true, _) => DXGI_FORMAT_D24_UNORM_S8_UINT,
(false, Unorm) => DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
_ => return None,
},
D24_S8 => match (is_target, format.1) {
(true, _) => DXGI_FORMAT_D24_UNORM_S8_UINT,
(false, Unorm) => DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
(false, Uint) => DXGI_FORMAT_X24_TYPELESS_G8_UINT,
_ => return None,
},
D32 => match (is_target, format.1) {
(true, _) => DXGI_FORMAT_D32_FLOAT,
(false, Float) => DXGI_FORMAT_R32_FLOAT,
_ => return None,
},
})
}
57 changes: 56 additions & 1 deletion src/backend/dx12ll/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,17 @@ extern crate dxgi;
extern crate dxguid;
extern crate gfx_corell as core;
extern crate winapi;
extern crate winit;

use comptr::ComPtr;
use std::ptr;
use std::os::raw::c_void;
use std::os::windows::ffi::OsStringExt;
use std::ffi::OsString;
use winapi::BOOL;
use winit::os::windows::WindowExt;

mod data;

#[derive(Clone)]
pub struct PhysicalDevice {
Expand Down Expand Up @@ -102,11 +107,61 @@ impl core::CommandQueue for CommandQueue {
}

pub struct Surface {

factory: ComPtr<winapi::IDXGIFactory4>,
wnd_handle: winapi::HWND,
}

impl core::Surface for Surface {
type B = Backend;
type Window = winit::Window;

fn from_window(window: &winit::Window, instance: &Instance) -> Surface {
Surface {
factory: instance.inner.clone(),
wnd_handle: window.get_hwnd() as *mut _,
}
}

fn build_swapchain<T: core::format::RenderFormat>(&self, width: u32, height: u32, present_queue: &CommandQueue) -> SwapChain {
let mut swap_chain = ComPtr::<winapi::IDXGISwapChain1>::new(ptr::null_mut());

// TODO: double-check values
let desc = winapi::DXGI_SWAP_CHAIN_DESC1 {
AlphaMode: winapi::DXGI_ALPHA_MODE(0),
BufferCount: 2,
Width: width,
Height: height,
Format: data::map_format(T::get_format(), true).unwrap(), // TODO: error handling
Flags: 0,
BufferUsage: winapi::DXGI_USAGE_RENDER_TARGET_OUTPUT,
SampleDesc: winapi::DXGI_SAMPLE_DESC {
Count: 1,
Quality: 0,
},
Scaling: winapi::DXGI_SCALING(0),
Stereo: false as BOOL,
SwapEffect: winapi::DXGI_SWAP_EFFECT(4), // TODO: FLIP_DISCARD
};

let hr = unsafe {
(**self.factory.as_ref()).CreateSwapChainForHwnd(
present_queue.inner.as_mut_ptr() as *mut _ as *mut winapi::IUnknown,
self.wnd_handle,
&desc,
ptr::null(),
ptr::null_mut(),
swap_chain.as_mut() as *mut *mut _,
)
};

if !winapi::SUCCEEDED(hr) {
error!("error on swapchain creation {:x}", hr);
}

SwapChain {
inner: swap_chain,
}
}
}

pub struct SwapChain {
Expand Down
1 change: 1 addition & 0 deletions src/backend/vulkanll/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ shared_library = "0.1"
gfx_corell = { path = "../../corell", version = "0.1.0" }
ash = "0.14.0"
spirv-utils = { git = "https://github.com/msiglreith/spirv-utils.git", branch = "gfx" }
winit = "0.5"
7 changes: 7 additions & 0 deletions src/corell/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,14 @@ pub trait CommandQueue {

/// A `Surface` abstracts the surface of a native window, which will be presented
pub trait Surface {
type B: Backend;
type Window;

fn from_window(window: &Self::Window, instance: &<<Self as Surface>::B as Backend>::Instance) -> Self;

fn build_swapchain<T: format::RenderFormat>(&self,
width: u32, height: u32,
present_queue: &<<Self as Surface>::B as Backend>::CommandQueue) -> <<Self as Surface>::B as Backend>::SwapChain;
}

/// The `SwapChain` is the backend representation of the surface.
Expand Down

0 comments on commit 3cd6964

Please sign in to comment.