From 9daffe1259a8a991d072e9c88ab1898bdbce9b00 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Thu, 28 Apr 2016 22:44:01 -0400 Subject: [PATCH 01/69] Dummy vulkan backend/window projects --- Cargo.toml | 3 +++ src/backend/vulkan/Cargo.toml | 21 +++++++++++++++++++++ src/backend/vulkan/build.rs | 16 ++++++++++++++++ src/backend/vulkan/src/lib.rs | 27 +++++++++++++++++++++++++++ src/window/vulkan/Cargo.toml | 18 ++++++++++++++++++ src/window/vulkan/src/lib.rs | 26 ++++++++++++++++++++++++++ 6 files changed, 111 insertions(+) create mode 100644 src/backend/vulkan/Cargo.toml create mode 100644 src/backend/vulkan/build.rs create mode 100644 src/backend/vulkan/src/lib.rs create mode 100644 src/window/vulkan/Cargo.toml create mode 100644 src/window/vulkan/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 4cf118c6908..a71611dbcbc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ authors = ["The Gfx-rs Developers"] [features] unstable = [] + [lib] name = "gfx_app" @@ -19,7 +20,9 @@ glutin = "0.6" winit = "0.5.1" gfx_core = { path = "src/core", version = "0.4" } gfx_device_gl = { path = "src/backend/gl", version = "0.11" } +gfx_device_vulkan = { path = "src/backend/vulkan", version = "0.1" } gfx_window_glutin = { path = "src/window/glutin", version = "0.12" } +gfx_window_vulkan = { path = "src/window/vulkan", version = "0.1" } gfx = { path = "src/render", version = "0.12" } [target.'cfg(unix)'.dependencies] diff --git a/src/backend/vulkan/Cargo.toml b/src/backend/vulkan/Cargo.toml new file mode 100644 index 00000000000..1e8a660284a --- /dev/null +++ b/src/backend/vulkan/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "gfx_device_vulkan" +version = "0.1.0" +description = "Vulkan API backend for gfx-rs" +homepage = "https://github.com/gfx-rs/gfx" +repository = "https://github.com/gfx-rs/gfx" +keywords = ["graphics", "gamedev"] +license = "Apache-2.0" +authors = ["The Gfx-rs Developers"] +build = "build.rs" + +[lib] +name = "gfx_device_vulkan" + +[dependencies] +vk = "0.0.1" +winit = "0.5" +gfx_core = { path = "../../core", version = "0.2" } + +[build-dependencies] +vk-sys = { path = "../../../../vulkano/vk-sys" } \ No newline at end of file diff --git a/src/backend/vulkan/build.rs b/src/backend/vulkan/build.rs new file mode 100644 index 00000000000..671403cbbae --- /dev/null +++ b/src/backend/vulkan/build.rs @@ -0,0 +1,16 @@ +extern crate vk_sys; + +use std::env; +use std::fs::File; +use std::path::Path; + +fn main() { + // tell Cargo that this build script never needs to be rerun + println!("cargo:rerun-if-changed=build.rs"); + + let dest = env::var("OUT_DIR").unwrap(); + let dest = Path::new(&dest); + + let mut file_output = File::create(&dest.join("vk_bindings.rs")).unwrap(); + vk_sys::write_bindings(&mut file_output).unwrap(); +} diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs new file mode 100644 index 00000000000..92037cd34ec --- /dev/null +++ b/src/backend/vulkan/src/lib.rs @@ -0,0 +1,27 @@ +// Copyright 2016 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. + +extern crate gfx_core; + +mod vk { + #![allow(dead_code)] + #![allow(non_upper_case_globals)] + #![allow(non_snake_case)] + #![allow(non_camel_case_types)] + include!(concat!(env!("OUT_DIR"), "/vk_bindings.rs")); +} + +pub struct Backend { + instance: vk::Instance, +} \ No newline at end of file diff --git a/src/window/vulkan/Cargo.toml b/src/window/vulkan/Cargo.toml new file mode 100644 index 00000000000..2bc496afae9 --- /dev/null +++ b/src/window/vulkan/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "gfx_window_vulkan" +version = "0.1.0" +description = "Vulkan window for gfx-rs" +homepage = "https://github.com/gfx-rs/gfx" +repository = "https://github.com/gfx-rs/gfx" +keywords = ["graphics", "gamedev"] +license = "Apache-2.0" +authors = ["The Gfx-rs Developers"] + +[lib] +name = "gfx_window_vulkan" + +[dependencies] +vk = "0.0.1" +winit = "0.5" +gfx_core = { path = "../../core", version = "0.2" } +gfx_device_vulkan = { path = "../../backend/vulkan", version = "0.1" } diff --git a/src/window/vulkan/src/lib.rs b/src/window/vulkan/src/lib.rs new file mode 100644 index 00000000000..2826fead931 --- /dev/null +++ b/src/window/vulkan/src/lib.rs @@ -0,0 +1,26 @@ +// Copyright 2016 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. + +extern crate vk; +extern crate winit; +extern crate gfx_core; +extern crate gfx_device_vulkan; + +pub fn init(builder: winit::WindowBuilder) -> (winit::Window) { + use winit::os::unix::WindowExt; + let win = builder.build().unwrap(); + //Surface::from_xlib(instance, win.get_xlib_display().unwrap(), + // win.get_xlib_window().unwrap()) + win +} From 812fd8722faeba132ea4ebf06b4549a6337096c5 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Fri, 29 Apr 2016 22:46:26 -0400 Subject: [PATCH 02/69] [vk] basic application info --- src/backend/vulkan/src/lib.rs | 67 ++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index 92037cd34ec..a56e6580516 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -14,6 +14,9 @@ extern crate gfx_core; +use std::ffi::CString; +use std::ptr; + mod vk { #![allow(dead_code)] #![allow(non_upper_case_globals)] @@ -22,6 +25,68 @@ mod vk { include!(concat!(env!("OUT_DIR"), "/vk_bindings.rs")); } + +/// Information that can be given to the Vulkan driver so that it can identify your application. +pub struct ApplicationInfo<'a> { + /// Name of the application. + pub application_name: &'a str, + /// An opaque number that contains the version number of the application. + pub application_version: u32, + /// Name of the engine used to power the application. + pub engine_name: &'a str, + /// An opaque number that contains the version number of the engine. + pub engine_version: u32, +} + + +struct PhysicalDeviceInfo { + device: vk::PhysicalDevice, + properties: vk::PhysicalDeviceProperties, + queue_families: Vec, + memory: vk::PhysicalDeviceMemoryProperties, + //available_features: Features, +} + pub struct Backend { instance: vk::Instance, -} \ No newline at end of file + pointers: vk::InstancePointers, + devices: Vec, +} + +pub fn create(app_info: Option<&ApplicationInfo>) -> Backend { + let mut c_app_name: CString; + let mut c_engine_name: CString; + let mut vk_info: vk::ApplicationInfo; + + let info_ptr = if let Some(info) = app_info { + c_app_name = CString::new(info.application_name).unwrap(); + c_engine_name = CString::new(info.engine_name).unwrap(); + vk_info = vk::ApplicationInfo { + sType: vk::STRUCTURE_TYPE_APPLICATION_INFO, + pNext: ptr::null(), + pApplicationName: c_app_name.as_ptr(), + applicationVersion: info.application_version, + pEngineName: c_engine_name.as_ptr(), + engineVersion: info.engine_version, + apiVersion: 0x1000, //TODO + }; + &vk_info as *const _ + }else { + ptr::null() + }; + + let create_info = vk::InstanceCreateInfo { + sType: vk::STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + pApplicationInfo: info_ptr, + enabledLayerCount: 0, //TODO + ppEnabledLayerNames: ptr::null(), //TODO + enabledExtensionCount: 0, //TODO + ppEnabledExtensionNames: ptr::null(), //TODO + }; + + Backend { + + } +} From 280126cc4cee52024ab9b08ccec3cba77e9ab901 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Sat, 30 Apr 2016 23:43:32 -0400 Subject: [PATCH 03/69] [vk] successful instance creation --- src/backend/vulkan/Cargo.toml | 5 ++- src/backend/vulkan/src/lib.rs | 84 +++++++++++++++++++++++++++++++---- src/window/vulkan/Cargo.toml | 2 +- 3 files changed, 80 insertions(+), 11 deletions(-) diff --git a/src/backend/vulkan/Cargo.toml b/src/backend/vulkan/Cargo.toml index 1e8a660284a..8a4ea0cc313 100644 --- a/src/backend/vulkan/Cargo.toml +++ b/src/backend/vulkan/Cargo.toml @@ -13,9 +13,10 @@ build = "build.rs" name = "gfx_device_vulkan" [dependencies] -vk = "0.0.1" +vk = "0.0" +shared_library = "0.1" winit = "0.5" -gfx_core = { path = "../../core", version = "0.2" } +gfx_core = { path = "../../core", version = "0.3" } [build-dependencies] vk-sys = { path = "../../../../vulkano/vk-sys" } \ No newline at end of file diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index a56e6580516..a83991d8713 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -12,10 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. +extern crate shared_library; extern crate gfx_core; +use std::{fmt, mem, ptr}; use std::ffi::CString; -use std::ptr; +use std::path::Path; +use shared_library::dynamic_library::DynamicLibrary; mod vk { #![allow(dead_code)] @@ -48,15 +51,27 @@ struct PhysicalDeviceInfo { } pub struct Backend { + dynamic_lib: DynamicLibrary, + library: vk::Static, instance: vk::Instance, - pointers: vk::InstancePointers, + inst_pointers: vk::InstancePointers, + functions: vk::EntryPoints, devices: Vec, } -pub fn create(app_info: Option<&ApplicationInfo>) -> Backend { - let mut c_app_name: CString; - let mut c_engine_name: CString; - let mut vk_info: vk::ApplicationInfo; +pub fn create(app_info: Option) -> Backend { + let c_app_name: CString; + let c_engine_name: CString; + let vk_info: vk::ApplicationInfo; + + let dynamic_lib = DynamicLibrary::open(Some(Path::new("libvulkan.so"))).unwrap(); + let lib = vk::Static::load(|name| unsafe { + let name = name.to_str().unwrap(); + dynamic_lib.symbol(name).unwrap() + }); + let entry_points = vk::EntryPoints::load(|name| unsafe { + mem::transmute(lib.GetInstanceProcAddr(0, name.as_ptr())) + }); let info_ptr = if let Some(info) = app_info { c_app_name = CString::new(info.application_name).unwrap(); @@ -68,7 +83,7 @@ pub fn create(app_info: Option<&ApplicationInfo>) -> Backend { applicationVersion: info.application_version, pEngineName: c_engine_name.as_ptr(), engineVersion: info.engine_version, - apiVersion: 0x1000, //TODO + apiVersion: 0x400000, //TODO }; &vk_info as *const _ }else { @@ -86,7 +101,60 @@ pub fn create(app_info: Option<&ApplicationInfo>) -> Backend { ppEnabledExtensionNames: ptr::null(), //TODO }; - Backend { + let instance = unsafe { + let mut ptr = mem::uninitialized(); + let status = entry_points.CreateInstance(&create_info, ptr::null(), &mut ptr); + if status != vk::SUCCESS { + panic!("vkCreateInstance: {:?}", Error(status)); + } + ptr + }; + let inst_ppinters = vk::InstancePointers::load(|name| unsafe { + mem::transmute(lib.GetInstanceProcAddr(instance, name.as_ptr())) + }); + + Backend { + dynamic_lib: dynamic_lib, + library: lib, + instance: instance, + inst_pointers: inst_ppinters, + functions: entry_points, + devices: Vec::new(), } } + + +#[derive(Clone, PartialEq, Eq)] +pub struct Error(vk::Result); + +impl fmt::Debug for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(match self.0 { + vk::SUCCESS => "success", + vk::NOT_READY => "not ready", + vk::TIMEOUT => "timeout", + vk::EVENT_SET => "event_set", + vk::EVENT_RESET => "event_reset", + vk::INCOMPLETE => "incomplete", + vk::ERROR_OUT_OF_HOST_MEMORY => "out of host memory", + vk::ERROR_OUT_OF_DEVICE_MEMORY => "out of device memory", + vk::ERROR_INITIALIZATION_FAILED => "initialization failed", + vk::ERROR_DEVICE_LOST => "device lost", + vk::ERROR_MEMORY_MAP_FAILED => "memory map failed", + vk::ERROR_LAYER_NOT_PRESENT => "layer not present", + vk::ERROR_EXTENSION_NOT_PRESENT => "extension not present", + vk::ERROR_FEATURE_NOT_PRESENT => "feature not present", + vk::ERROR_INCOMPATIBLE_DRIVER => "incompatible driver", + vk::ERROR_TOO_MANY_OBJECTS => "too many objects", + vk::ERROR_FORMAT_NOT_SUPPORTED => "format not supported", + vk::ERROR_SURFACE_LOST_KHR => "surface lost (KHR)", + vk::ERROR_NATIVE_WINDOW_IN_USE_KHR => "native window in use (KHR)", + vk::SUBOPTIMAL_KHR => "suboptimal (KHR)", + vk::ERROR_OUT_OF_DATE_KHR => "out of date (KHR)", + vk::ERROR_INCOMPATIBLE_DISPLAY_KHR => "incompatible display (KHR)", + vk::ERROR_VALIDATION_FAILED_EXT => "validation failed (EXT)", + _ => "unknown", + }) + } +} \ No newline at end of file diff --git a/src/window/vulkan/Cargo.toml b/src/window/vulkan/Cargo.toml index 2bc496afae9..5009e179d2d 100644 --- a/src/window/vulkan/Cargo.toml +++ b/src/window/vulkan/Cargo.toml @@ -14,5 +14,5 @@ name = "gfx_window_vulkan" [dependencies] vk = "0.0.1" winit = "0.5" -gfx_core = { path = "../../core", version = "0.2" } +gfx_core = { path = "../../core", version = "0.3" } gfx_device_vulkan = { path = "../../backend/vulkan", version = "0.1" } From 8a9129b5b8834247e70a47b864998cbd494e86bf Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Sun, 1 May 2016 00:10:29 -0400 Subject: [PATCH 04/69] [vk] basic device queries --- src/backend/vulkan/src/lib.rs | 53 +++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index a83991d8713..cad641c25e6 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -41,13 +41,42 @@ pub struct ApplicationInfo<'a> { pub engine_version: u32, } - struct PhysicalDeviceInfo { device: vk::PhysicalDevice, properties: vk::PhysicalDeviceProperties, queue_families: Vec, memory: vk::PhysicalDeviceMemoryProperties, - //available_features: Features, + features: vk::PhysicalDeviceFeatures, +} + +impl PhysicalDeviceInfo { + pub fn new(dev: vk::PhysicalDevice, vk: &vk::InstancePointers) -> PhysicalDeviceInfo { + PhysicalDeviceInfo { + device: dev, + properties: unsafe { + let mut out = mem::zeroed(); + vk.GetPhysicalDeviceProperties(dev, &mut out); + out + }, + queue_families: unsafe { + let mut num = 4; + let mut families = Vec::with_capacity(num as usize); + vk.GetPhysicalDeviceQueueFamilyProperties(dev, &mut num, families.as_mut_ptr()); + families.set_len(num as usize); + families + }, + memory: unsafe { + let mut out = mem::zeroed(); + vk.GetPhysicalDeviceMemoryProperties(dev, &mut out); + out + }, + features: unsafe { + let mut out = mem::zeroed(); + vk.GetPhysicalDeviceFeatures(dev, &mut out); + out + }, + } + } } pub struct Backend { @@ -102,7 +131,7 @@ pub fn create(app_info: Option) -> Backend { }; let instance = unsafe { - let mut ptr = mem::uninitialized(); + let mut ptr = mem::zeroed(); let status = entry_points.CreateInstance(&create_info, ptr::null(), &mut ptr); if status != vk::SUCCESS { panic!("vkCreateInstance: {:?}", Error(status)); @@ -110,17 +139,29 @@ pub fn create(app_info: Option) -> Backend { ptr }; - let inst_ppinters = vk::InstancePointers::load(|name| unsafe { + let inst_pointers = vk::InstancePointers::load(|name| unsafe { mem::transmute(lib.GetInstanceProcAddr(instance, name.as_ptr())) }); + let mut physical_devices: [vk::PhysicalDevice; 4] = unsafe { mem::zeroed() }; + let mut num = physical_devices.len() as u32; + let status = unsafe { + inst_pointers.EnumeratePhysicalDevices(instance, &mut num, physical_devices.as_mut_ptr()) + }; + if status != vk::SUCCESS { + panic!("vkEnumeratePhysicalDevices: {:?}", Error(status)); + } + let devices = physical_devices[..num as usize].iter() + .map(|dev| PhysicalDeviceInfo::new(*dev, &inst_pointers)) + .collect(); + Backend { dynamic_lib: dynamic_lib, library: lib, instance: instance, - inst_pointers: inst_ppinters, + inst_pointers: inst_pointers, functions: entry_points, - devices: Vec::new(), + devices: devices, } } From 2e262a887bcd8ce24e93fb854342bcb0e3f067e3 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Sun, 1 May 2016 20:17:11 -0400 Subject: [PATCH 05/69] [vk] Removed ApplicationInfo --- src/backend/vulkan/src/lib.rs | 44 ++++++++--------------------------- 1 file changed, 10 insertions(+), 34 deletions(-) diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index cad641c25e6..d712792aab2 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -29,18 +29,6 @@ mod vk { } -/// Information that can be given to the Vulkan driver so that it can identify your application. -pub struct ApplicationInfo<'a> { - /// Name of the application. - pub application_name: &'a str, - /// An opaque number that contains the version number of the application. - pub application_version: u32, - /// Name of the engine used to power the application. - pub engine_name: &'a str, - /// An opaque number that contains the version number of the engine. - pub engine_version: u32, -} - struct PhysicalDeviceInfo { device: vk::PhysicalDevice, properties: vk::PhysicalDeviceProperties, @@ -88,11 +76,7 @@ pub struct Backend { devices: Vec, } -pub fn create(app_info: Option) -> Backend { - let c_app_name: CString; - let c_engine_name: CString; - let vk_info: vk::ApplicationInfo; - +pub fn create(app_name: &str, app_version: u32) -> Backend { let dynamic_lib = DynamicLibrary::open(Some(Path::new("libvulkan.so"))).unwrap(); let lib = vk::Static::load(|name| unsafe { let name = name.to_str().unwrap(); @@ -102,28 +86,20 @@ pub fn create(app_info: Option) -> Backend { mem::transmute(lib.GetInstanceProcAddr(0, name.as_ptr())) }); - let info_ptr = if let Some(info) = app_info { - c_app_name = CString::new(info.application_name).unwrap(); - c_engine_name = CString::new(info.engine_name).unwrap(); - vk_info = vk::ApplicationInfo { - sType: vk::STRUCTURE_TYPE_APPLICATION_INFO, - pNext: ptr::null(), - pApplicationName: c_app_name.as_ptr(), - applicationVersion: info.application_version, - pEngineName: c_engine_name.as_ptr(), - engineVersion: info.engine_version, - apiVersion: 0x400000, //TODO - }; - &vk_info as *const _ - }else { - ptr::null() + let app_info = vk::ApplicationInfo { + sType: vk::STRUCTURE_TYPE_APPLICATION_INFO, + pNext: ptr::null(), + pApplicationName: app_name.as_ptr() as *const i8, + applicationVersion: app_version, + pEngineName: "gfx-rs".as_ptr() as *const i8, + engineVersion: 0x1000, //TODO + apiVersion: 0x400000, //TODO }; - let create_info = vk::InstanceCreateInfo { sType: vk::STRUCTURE_TYPE_INSTANCE_CREATE_INFO, pNext: ptr::null(), flags: 0, - pApplicationInfo: info_ptr, + pApplicationInfo: &app_info, enabledLayerCount: 0, //TODO ppEnabledLayerNames: ptr::null(), //TODO enabledExtensionCount: 0, //TODO From d6204602be1f37d646348168f091e38f5d558090 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Mon, 2 May 2016 00:17:37 -0400 Subject: [PATCH 06/69] [vk] basic device creation --- Cargo.toml | 1 + src/backend/vulkan/src/lib.rs | 62 +++++++++++++++++++++++++++++------ src/window/vulkan/src/lib.rs | 2 ++ 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a71611dbcbc..c841f401656 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -93,6 +93,7 @@ rand = "0.3" genmesh = "0.4" noise = "0.1" image = "0.6" +winit = "0.5" [target.x86_64-unknown-linux-gnu.dev_dependencies] glfw = "0.5" diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index d712792aab2..641de1ec194 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -16,8 +16,6 @@ extern crate shared_library; extern crate gfx_core; use std::{fmt, mem, ptr}; -use std::ffi::CString; -use std::path::Path; use shared_library::dynamic_library::DynamicLibrary; mod vk { @@ -73,10 +71,13 @@ pub struct Backend { instance: vk::Instance, inst_pointers: vk::InstancePointers, functions: vk::EntryPoints, - devices: Vec, + device: vk::Device, } -pub fn create(app_name: &str, app_version: u32) -> Backend { +pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[&str]) -> Backend { + use std::ffi::CString; + use std::path::Path; + let dynamic_lib = DynamicLibrary::open(Some(Path::new("libvulkan.so"))).unwrap(); let lib = vk::Static::load(|name| unsafe { let name = name.to_str().unwrap(); @@ -95,15 +96,22 @@ pub fn create(app_name: &str, app_version: u32) -> Backend { engineVersion: 0x1000, //TODO apiVersion: 0x400000, //TODO }; + + let cstrings = layers.iter().chain(extensions.iter()) + .map(|&s| CString::new(s).unwrap()) + .collect::>(); + let str_pointers = cstrings.iter().map(|s| s.as_ptr()) + .collect::>(); + let create_info = vk::InstanceCreateInfo { sType: vk::STRUCTURE_TYPE_INSTANCE_CREATE_INFO, pNext: ptr::null(), flags: 0, pApplicationInfo: &app_info, - enabledLayerCount: 0, //TODO - ppEnabledLayerNames: ptr::null(), //TODO - enabledExtensionCount: 0, //TODO - ppEnabledExtensionNames: ptr::null(), //TODO + enabledLayerCount: layers.len() as u32, + ppEnabledLayerNames: str_pointers.as_ptr(), + enabledExtensionCount: extensions.len() as u32, + ppEnabledExtensionNames: str_pointers[layers.len()..].as_ptr(), }; let instance = unsafe { @@ -129,7 +137,41 @@ pub fn create(app_name: &str, app_version: u32) -> Backend { } let devices = physical_devices[..num as usize].iter() .map(|dev| PhysicalDeviceInfo::new(*dev, &inst_pointers)) - .collect(); + .collect::>(); + + let device = { + let physical = devices[0].device; + let ext = CString::new("VK_KHR_swapchain").unwrap(); + let queue_info = vk::DeviceQueueCreateInfo { + sType: vk::STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + queueFamilyIndex: 0, + queueCount: 1, + pQueuePriorities: &1.0, + }; + let features = unsafe{ mem::zeroed() }; + let dev_info = vk::DeviceCreateInfo { + sType: vk::STRUCTURE_TYPE_DEVICE_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + queueCreateInfoCount: 1, + pQueueCreateInfos: &queue_info, + enabledLayerCount: 0, + ppEnabledLayerNames: ptr::null(), + enabledExtensionCount: 1, + ppEnabledExtensionNames: &ext.as_ptr(), + pEnabledFeatures: &features, + }; + unsafe { + let mut out = mem::zeroed(); + let status = inst_pointers.CreateDevice(physical, &dev_info, ptr::null(), &mut out); + if status != vk::SUCCESS { + panic!("vkCreateDevice: {:?}", Error(status)); + } + out + } + }; Backend { dynamic_lib: dynamic_lib, @@ -137,7 +179,7 @@ pub fn create(app_name: &str, app_version: u32) -> Backend { instance: instance, inst_pointers: inst_pointers, functions: entry_points, - devices: devices, + device: device, } } diff --git a/src/window/vulkan/src/lib.rs b/src/window/vulkan/src/lib.rs index 2826fead931..0c8733cc4f4 100644 --- a/src/window/vulkan/src/lib.rs +++ b/src/window/vulkan/src/lib.rs @@ -17,8 +17,10 @@ extern crate winit; extern crate gfx_core; extern crate gfx_device_vulkan; + pub fn init(builder: winit::WindowBuilder) -> (winit::Window) { use winit::os::unix::WindowExt; + let _ = gfx_device_vulkan::create(&builder.window.title, 1, &[], &["VK_KHR_surface", "VK_KHR_xcb_surface"]); let win = builder.build().unwrap(); //Surface::from_xlib(instance, win.get_xlib_display().unwrap(), // win.get_xlib_window().unwrap()) From dbcc311ba25ee62980c249d12e8b23c7d852afba Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Mon, 2 May 2016 23:00:01 -0400 Subject: [PATCH 07/69] [vk] basic swapchain creation --- src/backend/vulkan/src/lib.rs | 82 ++++++++++++++++++++++++----------- src/window/vulkan/Cargo.toml | 1 - src/window/vulkan/src/lib.rs | 76 +++++++++++++++++++++++++++++--- 3 files changed, 127 insertions(+), 32 deletions(-) diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index 641de1ec194..1425f34e353 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -18,7 +18,7 @@ extern crate gfx_core; use std::{fmt, mem, ptr}; use shared_library::dynamic_library::DynamicLibrary; -mod vk { +pub mod vk { #![allow(dead_code)] #![allow(non_upper_case_globals)] #![allow(non_snake_case)] @@ -72,9 +72,26 @@ pub struct Backend { inst_pointers: vk::InstancePointers, functions: vk::EntryPoints, device: vk::Device, + dev_pointers: vk::DevicePointers, } -pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[&str]) -> Backend { +impl Backend { + pub fn instance(&self) -> vk::Instance { + self.instance + } + pub fn inst_pointers(&self) -> &vk::InstancePointers { + &self.inst_pointers + } + pub fn device(&self) -> vk::Device { + self.device + } + pub fn dev_pointers(&self) -> &vk::DevicePointers { + &self.dev_pointers + } +} + +pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[&str], + dev_extensions: &[&str]) -> Backend { use std::ffi::CString; use std::path::Path; @@ -97,30 +114,32 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& apiVersion: 0x400000, //TODO }; - let cstrings = layers.iter().chain(extensions.iter()) + + let instance = { + let cstrings = layers.iter().chain(extensions.iter()) .map(|&s| CString::new(s).unwrap()) .collect::>(); - let str_pointers = cstrings.iter().map(|s| s.as_ptr()) - .collect::>(); - - let create_info = vk::InstanceCreateInfo { - sType: vk::STRUCTURE_TYPE_INSTANCE_CREATE_INFO, - pNext: ptr::null(), - flags: 0, - pApplicationInfo: &app_info, - enabledLayerCount: layers.len() as u32, - ppEnabledLayerNames: str_pointers.as_ptr(), - enabledExtensionCount: extensions.len() as u32, - ppEnabledExtensionNames: str_pointers[layers.len()..].as_ptr(), - }; + let str_pointers = cstrings.iter().map(|s| s.as_ptr()) + .collect::>(); - let instance = unsafe { - let mut ptr = mem::zeroed(); - let status = entry_points.CreateInstance(&create_info, ptr::null(), &mut ptr); - if status != vk::SUCCESS { - panic!("vkCreateInstance: {:?}", Error(status)); + let create_info = vk::InstanceCreateInfo { + sType: vk::STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + pApplicationInfo: &app_info, + enabledLayerCount: layers.len() as u32, + ppEnabledLayerNames: str_pointers.as_ptr(), + enabledExtensionCount: extensions.len() as u32, + ppEnabledExtensionNames: str_pointers[layers.len()..].as_ptr(), + }; + unsafe { + let mut ptr = mem::zeroed(); + let status = entry_points.CreateInstance(&create_info, ptr::null(), &mut ptr); + if status != vk::SUCCESS { + panic!("vkCreateInstance: {:?}", Error(status)); + } + ptr } - ptr }; let inst_pointers = vk::InstancePointers::load(|name| unsafe { @@ -141,7 +160,12 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& let device = { let physical = devices[0].device; - let ext = CString::new("VK_KHR_swapchain").unwrap(); + let cstrings = layers.iter().chain(dev_extensions.iter()) + .map(|&s| CString::new(s).unwrap()) + .collect::>(); + let str_pointers = cstrings.iter().map(|s| s.as_ptr()) + .collect::>(); + let queue_info = vk::DeviceQueueCreateInfo { sType: vk::STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, pNext: ptr::null(), @@ -151,6 +175,7 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& pQueuePriorities: &1.0, }; let features = unsafe{ mem::zeroed() }; + let dev_info = vk::DeviceCreateInfo { sType: vk::STRUCTURE_TYPE_DEVICE_CREATE_INFO, pNext: ptr::null(), @@ -159,8 +184,8 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& pQueueCreateInfos: &queue_info, enabledLayerCount: 0, ppEnabledLayerNames: ptr::null(), - enabledExtensionCount: 1, - ppEnabledExtensionNames: &ext.as_ptr(), + enabledExtensionCount: str_pointers.len() as u32, + ppEnabledExtensionNames: str_pointers.as_ptr(), pEnabledFeatures: &features, }; unsafe { @@ -173,6 +198,10 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& } }; + let dev_pointers = vk::DevicePointers::load(|name| unsafe { + inst_pointers.GetDeviceProcAddr(device, name.as_ptr()) as *const _ + }); + Backend { dynamic_lib: dynamic_lib, library: lib, @@ -180,12 +209,13 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& inst_pointers: inst_pointers, functions: entry_points, device: device, + dev_pointers: dev_pointers, } } #[derive(Clone, PartialEq, Eq)] -pub struct Error(vk::Result); +pub struct Error(pub vk::Result); impl fmt::Debug for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { diff --git a/src/window/vulkan/Cargo.toml b/src/window/vulkan/Cargo.toml index 5009e179d2d..ff877636428 100644 --- a/src/window/vulkan/Cargo.toml +++ b/src/window/vulkan/Cargo.toml @@ -12,7 +12,6 @@ authors = ["The Gfx-rs Developers"] name = "gfx_window_vulkan" [dependencies] -vk = "0.0.1" winit = "0.5" gfx_core = { path = "../../core", version = "0.3" } gfx_device_vulkan = { path = "../../backend/vulkan", version = "0.1" } diff --git a/src/window/vulkan/src/lib.rs b/src/window/vulkan/src/lib.rs index 0c8733cc4f4..eaf96286db9 100644 --- a/src/window/vulkan/src/lib.rs +++ b/src/window/vulkan/src/lib.rs @@ -12,17 +12,83 @@ // See the License for the specific language governing permissions and // limitations under the License. -extern crate vk; extern crate winit; extern crate gfx_core; extern crate gfx_device_vulkan; +use std::{mem, ptr}; +use gfx_device_vulkan::vk; + pub fn init(builder: winit::WindowBuilder) -> (winit::Window) { use winit::os::unix::WindowExt; - let _ = gfx_device_vulkan::create(&builder.window.title, 1, &[], &["VK_KHR_surface", "VK_KHR_xcb_surface"]); + let backend = gfx_device_vulkan::create(&builder.window.title, 1, &[], + &["VK_KHR_surface", "VK_KHR_xcb_surface"], &["VK_KHR_swapchain"]); + let (width, height) = builder.window.dimensions.unwrap_or((640, 400)); let win = builder.build().unwrap(); - //Surface::from_xlib(instance, win.get_xlib_display().unwrap(), - // win.get_xlib_window().unwrap()) - win + + let surface = { + let vk = backend.inst_pointers(); + let info = vk::XcbSurfaceCreateInfoKHR { + sType: vk::STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR, + pNext: ptr::null(), + flags: 0, + connection: ptr::null_mut(), //TODO + window: ptr::null_mut(), //TODO + }; + + unsafe { + let mut out = mem::zeroed(); + let status = vk.CreateXcbSurfaceKHR(backend.instance(), &info, ptr::null(), &mut out); + if status != vk::SUCCESS { + panic!("vkCreateXcbSurfaceKHR: {:?}", gfx_device_vulkan::Error(status)); + } + out + } + }; + + { + let vk = backend.dev_pointers(); + let mut images: [vk::Image; 2] = [0; 2]; + let mut num = images.len() as u32; + + let info = vk::SwapchainCreateInfoKHR { + sType: vk::STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, + pNext: ptr::null(), + flags: 0, + surface: surface, + minImageCount: num, + imageFormat: vk::FORMAT_R8G8B8A8_UNORM, + imageColorSpace: vk::COLORSPACE_SRGB_NONLINEAR_KHR, + imageExtent: vk::Extent2D { width: width, height: height }, + imageArrayLayers: 1, + imageUsage: vk::IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + imageSharingMode: vk::SHARING_MODE_EXCLUSIVE, + queueFamilyIndexCount: 1, + pQueueFamilyIndices: &0, + preTransform: vk::SURFACE_TRANSFORM_IDENTITY_BIT_KHR, + compositeAlpha: vk::COMPOSITE_ALPHA_OPAQUE_BIT_KHR, + presentMode: vk::PRESENT_MODE_FIFO_RELAXED_KHR, + clipped: vk::TRUE, + oldSwapchain: 0, + }; + + let swapchain = unsafe { + let mut out = mem::zeroed(); + let status = vk.CreateSwapchainKHR(backend.device(), &info, ptr::null(), &mut out); + if status != vk::SUCCESS { + panic!("vkCreateSwapchainKHR: {:?}", gfx_device_vulkan::Error(status)); + } + out + }; + + let status = unsafe { + vk.GetSwapchainImagesKHR(backend.device(), swapchain, &mut num, images.as_mut_ptr()) + }; + if status != vk::SUCCESS { + panic!("vkGetSwapchainImagesKHR: {:?}", gfx_device_vulkan::Error(status)); + } + }; + + win } From 37b26e13600dc42536425f1da1cdde5221213fef Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Tue, 10 May 2016 23:27:44 -0400 Subject: [PATCH 08/69] [vk] - graphics queue selection --- src/backend/vulkan/Cargo.toml | 1 + src/backend/vulkan/src/lib.rs | 19 ++++++++++++---- src/window/vulkan/src/lib.rs | 41 +++++++++++++++++------------------ 3 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/backend/vulkan/Cargo.toml b/src/backend/vulkan/Cargo.toml index 8a4ea0cc313..2cc1fcefbca 100644 --- a/src/backend/vulkan/Cargo.toml +++ b/src/backend/vulkan/Cargo.toml @@ -13,6 +13,7 @@ build = "build.rs" name = "gfx_device_vulkan" [dependencies] +log = "0.3" vk = "0.0" shared_library = "0.1" winit = "0.5" diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index 1425f34e353..856afbebbb5 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -12,10 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +#[macro_use] +extern crate log; extern crate shared_library; extern crate gfx_core; -use std::{fmt, mem, ptr}; +use std::{fmt, iter, mem, ptr}; use shared_library::dynamic_library::DynamicLibrary; pub mod vk { @@ -158,8 +160,13 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& .map(|dev| PhysicalDeviceInfo::new(*dev, &inst_pointers)) .collect::>(); + let (ph_dev, (qf_id, _)) = devices.iter() + .flat_map(|d| iter::repeat(d.device).zip(d.queue_families.iter().enumerate())) + .find(|&(_, (_, qf))| qf.queueFlags & vk::QUEUE_GRAPHICS_BIT != 0) + .unwrap(); + info!("Chosen physical device {:p} with queue family {}", ph_dev as *const (), qf_id); + let device = { - let physical = devices[0].device; let cstrings = layers.iter().chain(dev_extensions.iter()) .map(|&s| CString::new(s).unwrap()) .collect::>(); @@ -170,7 +177,7 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& sType: vk::STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, pNext: ptr::null(), flags: 0, - queueFamilyIndex: 0, + queueFamilyIndex: qf_id as u32, queueCount: 1, pQueuePriorities: &1.0, }; @@ -190,7 +197,7 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& }; unsafe { let mut out = mem::zeroed(); - let status = inst_pointers.CreateDevice(physical, &dev_info, ptr::null(), &mut out); + let status = inst_pointers.CreateDevice(ph_dev, &dev_info, ptr::null(), &mut out); if status != vk::SUCCESS { panic!("vkCreateDevice: {:?}", Error(status)); } @@ -213,6 +220,10 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& } } +pub struct GraphicsQueue { + queue: vk::Queue, +} + #[derive(Clone, PartialEq, Eq)] pub struct Error(pub vk::Result); diff --git a/src/window/vulkan/src/lib.rs b/src/window/vulkan/src/lib.rs index eaf96286db9..ba9b5c4aec5 100644 --- a/src/window/vulkan/src/lib.rs +++ b/src/window/vulkan/src/lib.rs @@ -21,33 +21,33 @@ use gfx_device_vulkan::vk; pub fn init(builder: winit::WindowBuilder) -> (winit::Window) { - use winit::os::unix::WindowExt; + //use winit::os::unix::WindowExt; let backend = gfx_device_vulkan::create(&builder.window.title, 1, &[], &["VK_KHR_surface", "VK_KHR_xcb_surface"], &["VK_KHR_swapchain"]); let (width, height) = builder.window.dimensions.unwrap_or((640, 400)); let win = builder.build().unwrap(); - let surface = { - let vk = backend.inst_pointers(); - let info = vk::XcbSurfaceCreateInfoKHR { - sType: vk::STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR, - pNext: ptr::null(), - flags: 0, - connection: ptr::null_mut(), //TODO - window: ptr::null_mut(), //TODO - }; + if false { + let surface = { + let vk = backend.inst_pointers(); + let info = vk::XcbSurfaceCreateInfoKHR { + sType: vk::STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR, + pNext: ptr::null(), + flags: 0, + connection: ptr::null_mut(), //TODO + window: ptr::null_mut(), //TODO + }; - unsafe { - let mut out = mem::zeroed(); - let status = vk.CreateXcbSurfaceKHR(backend.instance(), &info, ptr::null(), &mut out); - if status != vk::SUCCESS { - panic!("vkCreateXcbSurfaceKHR: {:?}", gfx_device_vulkan::Error(status)); + unsafe { + let mut out = mem::zeroed(); + let status = vk.CreateXcbSurfaceKHR(backend.instance(), &info, ptr::null(), &mut out); + if status != vk::SUCCESS { + panic!("vkCreateXcbSurfaceKHR: {:?}", gfx_device_vulkan::Error(status)); + } + out } - out - } - }; + }; - { let vk = backend.dev_pointers(); let mut images: [vk::Image; 2] = [0; 2]; let mut num = images.len() as u32; @@ -88,7 +88,6 @@ pub fn init(builder: winit::WindowBuilder) -> (winit::Window) { if status != vk::SUCCESS { panic!("vkGetSwapchainImagesKHR: {:?}", gfx_device_vulkan::Error(status)); } - }; - + } win } From 617c2e7aeb9308816be45815089579509bf01ba7 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Tue, 10 May 2016 23:56:10 -0400 Subject: [PATCH 09/69] [vk] dummy command buffer and graphics queue --- src/backend/vulkan/src/command.rs | 91 +++++++++++++++++++++++++++++++ src/backend/vulkan/src/lib.rs | 38 ++++++++++--- src/window/vulkan/src/lib.rs | 16 ++++-- 3 files changed, 134 insertions(+), 11 deletions(-) create mode 100644 src/backend/vulkan/src/command.rs diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs new file mode 100644 index 00000000000..45970027a53 --- /dev/null +++ b/src/backend/vulkan/src/command.rs @@ -0,0 +1,91 @@ +// Copyright 2016 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 vk; +use gfx_core::{self, draw, pso, shade, target, tex}; +use gfx_core::state::RefValues; +use gfx_core::{IndexType, VertexCount}; +use {Resources}; + + +pub struct Buffer { + inner: vk::CommandBuffer, +} + +impl draw::CommandBuffer for Buffer { + fn clone_empty(&self) -> Buffer { Buffer {inner: self.inner} } + fn reset(&mut self) {} + fn bind_pipeline_state(&mut self, _: ()) {} + fn bind_vertex_buffers(&mut self, _: pso::VertexBufferSet) {} + fn bind_constant_buffers(&mut self, _: &[pso::ConstantBufferParam]) {} + fn bind_global_constant(&mut self, _: shade::Location, _: shade::UniformValue) {} + fn bind_resource_views(&mut self, _: &[pso::ResourceViewParam]) {} + fn bind_unordered_views(&mut self, _: &[pso::UnorderedViewParam]) {} + fn bind_samplers(&mut self, _: &[pso::SamplerParam]) {} + fn bind_pixel_targets(&mut self, _: pso::PixelTargetSet) {} + fn bind_index(&mut self, _: (), _: IndexType) {} + fn set_scissor(&mut self, _: target::Rect) {} + fn set_ref_values(&mut self, _: RefValues) {} + fn update_buffer(&mut self, _: (), _: &[u8], _: usize) {} + fn update_texture(&mut self, _: (), _: tex::Kind, _: Option, + _: &[u8], _: tex::RawImageInfo) {} + fn generate_mipmap(&mut self, _: ()) {} + fn clear_color(&mut self, _: (), _: draw::ClearColor) {} + fn clear_depth_stencil(&mut self, _: (), _: Option, + _: Option) {} + fn call_draw(&mut self, _: VertexCount, _: VertexCount, _: draw::InstanceOption) {} + fn call_draw_indexed(&mut self, _: VertexCount, _: VertexCount, + _: VertexCount, _: draw::InstanceOption) {} +} + + +pub struct GraphicsQueue { + queue: vk::Queue, + capabilities: gfx_core::Capabilities, +} + +impl GraphicsQueue { + #[doc(hidden)] + pub fn new(q: vk::Queue) -> GraphicsQueue { + let caps = gfx_core::Capabilities { + max_vertex_count: 0, + max_index_count: 0, + max_texture_size: 0, + instance_base_supported: false, + instance_call_supported: false, + instance_rate_supported: false, + vertex_base_supported: false, + srgb_color_supported: false, + constant_buffer_supported: false, + unordered_access_view_supported: false, + separate_blending_slots_supported: false, + }; + GraphicsQueue { + queue: q, + capabilities: caps, + } + } +} + +impl gfx_core::Device for GraphicsQueue { + type Resources = Resources; + type CommandBuffer = Buffer; + + fn get_capabilities(&self) -> &gfx_core::Capabilities { + &self.capabilities + } + fn pin_submitted_resources(&mut self, _: &gfx_core::handle::Manager) {} + fn submit(&mut self, _: &mut Buffer) {} + fn cleanup(&mut self) {} +} diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index 856afbebbb5..947a72072ed 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -20,6 +20,7 @@ extern crate gfx_core; use std::{fmt, iter, mem, ptr}; use shared_library::dynamic_library::DynamicLibrary; +pub mod command; pub mod vk { #![allow(dead_code)] #![allow(non_upper_case_globals)] @@ -93,7 +94,7 @@ impl Backend { } pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[&str], - dev_extensions: &[&str]) -> Backend { + dev_extensions: &[&str]) -> (Backend, command::GraphicsQueue) { use std::ffi::CString; use std::path::Path; @@ -209,7 +210,14 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& inst_pointers.GetDeviceProcAddr(device, name.as_ptr()) as *const _ }); - Backend { + let queue = unsafe { + let mut out = mem::zeroed(); + dev_pointers.GetDeviceQueue(device, qf_id as u32, 0, &mut out); + out + }; + let gfx_device = command::GraphicsQueue::new(queue); + + let backend = Backend { dynamic_lib: dynamic_lib, library: lib, instance: instance, @@ -217,11 +225,9 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& functions: entry_points, device: device, dev_pointers: dev_pointers, - } -} + }; -pub struct GraphicsQueue { - queue: vk::Queue, + (backend, gfx_device) } @@ -257,4 +263,22 @@ impl fmt::Debug for Error { _ => "unknown", }) } -} \ No newline at end of file +} + + +#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] +pub enum Resources {} + +impl gfx_core::Resources for Resources { + type Buffer = (); + type Shader = (); + type Program = (); + type PipelineStateObject = (); + type Texture = (); + type ShaderResourceView = (); + type UnorderedAccessView = (); + type RenderTargetView = (); + type DepthStencilView = (); + type Sampler = (); + type Fence = (); +} diff --git a/src/window/vulkan/src/lib.rs b/src/window/vulkan/src/lib.rs index ba9b5c4aec5..23ca9b79b14 100644 --- a/src/window/vulkan/src/lib.rs +++ b/src/window/vulkan/src/lib.rs @@ -19,13 +19,16 @@ extern crate gfx_device_vulkan; use std::{mem, ptr}; use gfx_device_vulkan::vk; +pub struct Window { + pub backend: gfx_device_vulkan::Backend, + pub win: winit::Window, +} -pub fn init(builder: winit::WindowBuilder) -> (winit::Window) { +pub fn init(builder: winit::WindowBuilder) -> (Window, gfx_device_vulkan::command::GraphicsQueue) { //use winit::os::unix::WindowExt; - let backend = gfx_device_vulkan::create(&builder.window.title, 1, &[], + let (backend, device) = gfx_device_vulkan::create(&builder.window.title, 1, &[], &["VK_KHR_surface", "VK_KHR_xcb_surface"], &["VK_KHR_swapchain"]); let (width, height) = builder.window.dimensions.unwrap_or((640, 400)); - let win = builder.build().unwrap(); if false { let surface = { @@ -89,5 +92,10 @@ pub fn init(builder: winit::WindowBuilder) -> (winit::Window) { panic!("vkGetSwapchainImagesKHR: {:?}", gfx_device_vulkan::Error(status)); } } - win + + let win = Window { + backend: backend, + win: builder.build().unwrap(), + }; + (win, device) } From 9e11262069b950f27700666e59e5723259b18aff Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Wed, 11 May 2016 00:24:43 -0400 Subject: [PATCH 10/69] Removed clone_empty() and implemented gfx_app::Factory for simpler cbuf creation for the launcher --- examples/shadow/main.rs | 17 +++++------ src/backend/dx11/src/command.rs | 5 ---- src/backend/dx11/src/lib.rs | 7 ----- src/backend/gl/src/command.rs | 4 --- src/backend/vulkan/src/command.rs | 1 - src/core/src/draw.rs | 2 -- src/core/src/dummy.rs | 1 - src/lib.rs | 50 +++++++++++++++++++++++-------- src/render/src/encoder.rs | 9 ------ 9 files changed, 46 insertions(+), 50 deletions(-) diff --git a/examples/shadow/main.rs b/examples/shadow/main.rs index ba91c09b545..37b92b30506 100644 --- a/examples/shadow/main.rs +++ b/examples/shadow/main.rs @@ -194,14 +194,13 @@ struct Scene> { // Section-4: scene construction routines /// Create a full scene -fn create_scene(factory: &mut F, encoder: &gfx::Encoder, +fn create_scene(factory: &mut F, out_color: gfx::handle::RenderTargetView, out_depth: gfx::handle::DepthStencilView, shadow_pso: gfx::PipelineState) - -> Scene where + -> Scene where R: gfx::Resources, - F: gfx::Factory, - C: gfx::CommandBuffer, + F: gfx_app::Factory, { use cgmath::{SquareMatrix, Matrix4, deg}; use gfx::traits::FactoryExt; @@ -264,7 +263,7 @@ fn create_scene(factory: &mut F, encoder: &gfx::Encoder, shadow: factory.view_texture_as_depth_stencil( &shadow_tex, 0, Some(i as gfx::Layer), gfx::tex::DepthStencilFlags::empty(), ).unwrap(), - encoder: encoder.clone_empty(), + encoder: factory.create_encoder(), }).collect(); let light_buf = factory.create_constant_buffer(MAX_LIGHTS); @@ -424,8 +423,8 @@ impl gfx_app::ApplicationBase for App where R: gfx::Resources + 'static, C: gfx::CommandBuffer + Send + 'static, { - fn new(mut factory: F, encoder: gfx::Encoder, init: gfx_app::Init) -> Self where - F: gfx::Factory + fn new(mut factory: F, init: gfx_app::Init) -> Self where + F: gfx_app::Factory, { use std::env; use gfx::traits::FactoryExt; @@ -487,7 +486,7 @@ impl gfx_app::ApplicationBase for App where ).unwrap() }; - let scene = create_scene(&mut factory, &encoder, + let scene = create_scene(&mut factory, init.color.clone(), init.depth.clone(), shadow_pso); @@ -495,7 +494,7 @@ impl gfx_app::ApplicationBase for App where init: init, is_parallel: is_parallel, forward_pso: forward_pso, - encoder: encoder, + encoder: factory.create_encoder(), scene: scene, } } diff --git a/src/backend/dx11/src/command.rs b/src/backend/dx11/src/command.rs index 90ef6d276ae..042382a56a3 100644 --- a/src/backend/dx11/src/command.rs +++ b/src/backend/dx11/src/command.rs @@ -119,7 +119,6 @@ pub struct CommandBuffer

{ } pub trait Parser: Sized { - fn clone_empty(&self) -> Self; fn reset(&mut self); fn parse(&mut self, Command); fn update_buffer(&mut self, Buffer, &[u8], usize); @@ -144,10 +143,6 @@ impl CommandBuffer

{ } impl draw::CommandBuffer for CommandBuffer

{ - fn clone_empty(&self) -> CommandBuffer

{ - self.parser.clone_empty().into() - } - fn reset(&mut self) { self.parser.reset(); self.cache = Cache::new(); diff --git a/src/backend/dx11/src/lib.rs b/src/backend/dx11/src/lib.rs index 27a3c32eaaf..b1554367343 100644 --- a/src/backend/dx11/src/lib.rs +++ b/src/backend/dx11/src/lib.rs @@ -268,9 +268,6 @@ impl CommandList { } } impl command::Parser for CommandList { - fn clone_empty(&self) -> CommandList { - CommandList(Vec::with_capacity(self.0.capacity()), command::DataBuffer::new()) - } fn reset(&mut self) { self.0.clear(); self.1.reset(); @@ -300,10 +297,6 @@ impl Drop for DeferredContext { } } impl command::Parser for DeferredContext { - fn clone_empty(&self) -> DeferredContext { - unsafe { (*self.0).AddRef() }; - DeferredContext(self.0, None) - } fn reset(&mut self) { if let Some(cl) = self.1 { unsafe { (*cl).Release() }; diff --git a/src/backend/gl/src/command.rs b/src/backend/gl/src/command.rs index b2ff468b6fe..219e92aeb29 100644 --- a/src/backend/gl/src/command.rs +++ b/src/backend/gl/src/command.rs @@ -184,10 +184,6 @@ impl CommandBuffer { } impl c::draw::CommandBuffer for CommandBuffer { - fn clone_empty(&self) -> CommandBuffer { - CommandBuffer::new(self.fbo) - } - fn reset(&mut self) { self.buf.clear(); self.data.0.clear(); diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs index 45970027a53..ae74ef7b4db 100644 --- a/src/backend/vulkan/src/command.rs +++ b/src/backend/vulkan/src/command.rs @@ -24,7 +24,6 @@ pub struct Buffer { } impl draw::CommandBuffer for Buffer { - fn clone_empty(&self) -> Buffer { Buffer {inner: self.inner} } fn reset(&mut self) {} fn bind_pipeline_state(&mut self, _: ()) {} fn bind_vertex_buffers(&mut self, _: pso::VertexBufferSet) {} diff --git a/src/core/src/draw.rs b/src/core/src/draw.rs index f57ab25742d..04323ad075c 100644 --- a/src/core/src/draw.rs +++ b/src/core/src/draw.rs @@ -38,8 +38,6 @@ pub type InstanceOption = Option<(InstanceCount, VertexCount)>; /// efficient API-specific manner, to be ready for execution on the device. #[allow(missing_docs)] pub trait CommandBuffer { - /// Clone as an empty buffer - fn clone_empty(&self) -> Self; /// Reset the command buffer contents, retain the allocated storage fn reset(&mut self); /// Bind a pipeline state object diff --git a/src/core/src/dummy.rs b/src/core/src/dummy.rs index b8968c5d63d..9fa4d3f4a48 100644 --- a/src/core/src/dummy.rs +++ b/src/core/src/dummy.rs @@ -68,7 +68,6 @@ impl DummyDevice { /// Dummy command buffer, which ignores all the calls. pub struct DummyCommandBuffer; impl draw::CommandBuffer for DummyCommandBuffer { - fn clone_empty(&self) -> DummyCommandBuffer { DummyCommandBuffer } fn reset(&mut self) {} fn bind_pipeline_state(&mut self, _: ()) {} fn bind_vertex_buffers(&mut self, _: pso::VertexBufferSet) {} diff --git a/src/lib.rs b/src/lib.rs index eaf249c8b32..702dc821aa2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -90,9 +90,15 @@ impl Drop for Harness { } } +pub trait Factory: gfx::Factory { + type CommandBuffer: gfx::CommandBuffer; + fn create_encoder(&mut self) -> gfx::Encoder; +} + + pub trait ApplicationBase> { - fn new(F, gfx::Encoder, Init) -> Self where - F: gfx::Factory; + fn new(F, Init) -> Self where + F: Factory; fn render(&mut self, &mut D) where D: gfx::Device; } @@ -134,11 +140,11 @@ impl ApplicationBase for Wrap where C: gfx::CommandBuffer, A: Application { - fn new(factory: F, encoder: gfx::Encoder, init: Init) -> Self where - F: gfx::Factory + fn new(mut factory: F, init: Init) -> Self where + F: Factory, { Wrap { - encoder: encoder, + encoder: factory.create_encoder(), app: A::new(factory, init), } } @@ -166,6 +172,14 @@ pub trait ApplicationD3D11 { fn launch(&str, Config); } + +impl Factory for gfx_device_gl::Factory { + type CommandBuffer = gfx_device_gl::CommandBuffer; + fn create_encoder(&mut self) -> gfx::Encoder { + self.create_command_buffer().into() + } +} + impl ApplicationGL for A where A: ApplicationBase @@ -189,7 +203,7 @@ impl ApplicationGL for A where let combuf = factory.create_command_buffer(); let shade_lang = device.get_info().shading_language; - let mut app = Self::new(factory, combuf.into(), Init { + let mut app = Self::new(factory, Init { backend: if shade_lang.is_embedded { shade::Backend::GlslEs(shade_lang) } else { @@ -219,6 +233,14 @@ impl ApplicationGL for A where } } +#[cfg(target_os = "macos")] +impl Factory for gfx_device_metal::Factory { + type CommandBuffer = gfx_device_meta::CommandBuffer; + fn create_encoder(&mut self) -> gfx::Encoder { + self.create_command_buffer().into() + } +} + #[cfg(target_os = "macos")] impl< A: ApplicationBase @@ -262,6 +284,14 @@ impl< } } +#[cfg(target_os = "windows")] +impl Factory for gfx_device_dx11::Factory { + type CommandBuffer = D3D11CommandBuffer; + fn create_encoder(&mut self) -> gfx::Encoder { + self.create_command_buffer_native().into() + } +} + #[cfg(target_os = "windows")] impl< A: ApplicationBase @@ -270,22 +300,18 @@ impl< use gfx::traits::{Device, Factory}; env_logger::init().unwrap(); - let (window, device, mut factory, main_color) = + let (window, device, factory, main_color) = gfx_window_dxgi::init::(title, config.size.0, config.size.1) .unwrap(); let main_depth = factory.create_depth_stencil_view_only( window.size.0, window.size.1).unwrap(); - //let combuf = factory.create_command_buffer(); - let combuf = factory.create_command_buffer_native(); - - let mut app = Self::new(factory, combuf.into(), Init { + let mut app = Self::new(factory, Init { backend: shade::Backend::Hlsl(device.get_shader_model()), color: main_color, depth: main_depth, aspect_ratio: window.size.0 as f32 / window.size.1 as f32, }); - let mut device: gfx_device_dx11::Deferred = device.into(); let mut harness = Harness::new(); diff --git a/src/render/src/encoder.rs b/src/render/src/encoder.rs index dc8819c2bd5..bf183c6e8bd 100644 --- a/src/render/src/encoder.rs +++ b/src/render/src/encoder.rs @@ -110,15 +110,6 @@ impl> Encoder { self.handles.clear(); } - /// Clone the renderer shared data but ignore the commands. - pub fn clone_empty(&self) -> Encoder { - Encoder { - command_buffer: self.command_buffer.clone_empty(), - raw_pso_data: pso::RawDataSet::new(), - handles: handle::Manager::new(), - } - } - /// Update a buffer with a slice of data. pub fn update_buffer(&mut self, buf: &handle::Buffer, data: &[T], offset_elements: usize) From 4f4b3c0d6fa868a122b90698ca97d7a5ccaee4ba Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Wed, 11 May 2016 23:47:43 -0400 Subject: [PATCH 11/69] [vk] implemented submit() --- src/backend/vulkan/src/command.rs | 35 ++++++++++++++++++++++++++++--- src/backend/vulkan/src/lib.rs | 7 +------ src/window/vulkan/src/lib.rs | 2 +- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs index ae74ef7b4db..ff7ad4d6fe9 100644 --- a/src/backend/vulkan/src/command.rs +++ b/src/backend/vulkan/src/command.rs @@ -12,11 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::mem; use vk; use gfx_core::{self, draw, pso, shade, target, tex}; use gfx_core::state::RefValues; use gfx_core::{IndexType, VertexCount}; -use {Resources}; +use {Error, Resources}; pub struct Buffer { @@ -51,12 +52,13 @@ impl draw::CommandBuffer for Buffer { pub struct GraphicsQueue { queue: vk::Queue, + functions: vk::DevicePointers, capabilities: gfx_core::Capabilities, } impl GraphicsQueue { #[doc(hidden)] - pub fn new(q: vk::Queue) -> GraphicsQueue { + pub fn new(q: vk::Queue, fun: vk::DevicePointers) -> GraphicsQueue { let caps = gfx_core::Capabilities { max_vertex_count: 0, max_index_count: 0, @@ -72,9 +74,14 @@ impl GraphicsQueue { }; GraphicsQueue { queue: q, + functions: fun, capabilities: caps, } } + + pub fn get_functions(&self) -> &vk::DevicePointers { + &self.functions + } } impl gfx_core::Device for GraphicsQueue { @@ -84,7 +91,29 @@ impl gfx_core::Device for GraphicsQueue { fn get_capabilities(&self) -> &gfx_core::Capabilities { &self.capabilities } + fn pin_submitted_resources(&mut self, _: &gfx_core::handle::Manager) {} - fn submit(&mut self, _: &mut Buffer) {} + + fn submit(&mut self, com: &mut Buffer) { + let status = unsafe { + self.functions.EndCommandBuffer(com.inner) + }; + if status != vk::SUCCESS { + panic!("vkEndCommandBuffer: {:?}", Error(status)); + } + let info = vk::SubmitInfo { + sType: vk::STRUCTURE_TYPE_SUBMIT_INFO, + commandBufferCount: 1, + pCommandBuffers: &com.inner, + .. unsafe { mem::zeroed() } + }; + let status = unsafe { + self.functions.QueueSubmit(self.queue, 1, &info, 0) + }; + if status != vk::SUCCESS { + panic!("vkQueueSubmit: {:?}", Error(status)); + } + } + fn cleanup(&mut self) {} } diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index 947a72072ed..a0bce5b562a 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -75,7 +75,6 @@ pub struct Backend { inst_pointers: vk::InstancePointers, functions: vk::EntryPoints, device: vk::Device, - dev_pointers: vk::DevicePointers, } impl Backend { @@ -88,9 +87,6 @@ impl Backend { pub fn device(&self) -> vk::Device { self.device } - pub fn dev_pointers(&self) -> &vk::DevicePointers { - &self.dev_pointers - } } pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[&str], @@ -215,7 +211,7 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& dev_pointers.GetDeviceQueue(device, qf_id as u32, 0, &mut out); out }; - let gfx_device = command::GraphicsQueue::new(queue); + let gfx_device = command::GraphicsQueue::new(queue, dev_pointers); let backend = Backend { dynamic_lib: dynamic_lib, @@ -224,7 +220,6 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& inst_pointers: inst_pointers, functions: entry_points, device: device, - dev_pointers: dev_pointers, }; (backend, gfx_device) diff --git a/src/window/vulkan/src/lib.rs b/src/window/vulkan/src/lib.rs index 23ca9b79b14..91195f5e9f1 100644 --- a/src/window/vulkan/src/lib.rs +++ b/src/window/vulkan/src/lib.rs @@ -51,7 +51,7 @@ pub fn init(builder: winit::WindowBuilder) -> (Window, gfx_device_vulkan::comman } }; - let vk = backend.dev_pointers(); + let vk = device.get_functions(); let mut images: [vk::Image; 2] = [0; 2]; let mut num = images.len() as u32; From 8eb42e30e01828f2ebd9408839a89121aaba6164 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Wed, 11 May 2016 23:55:36 -0400 Subject: [PATCH 12/69] [vk] factory mock --- src/backend/vulkan/src/command.rs | 12 +-- src/backend/vulkan/src/factory.rs | 137 ++++++++++++++++++++++++++++++ src/backend/vulkan/src/lib.rs | 1 + 3 files changed, 144 insertions(+), 6 deletions(-) create mode 100644 src/backend/vulkan/src/factory.rs diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs index ff7ad4d6fe9..d1f2f757741 100644 --- a/src/backend/vulkan/src/command.rs +++ b/src/backend/vulkan/src/command.rs @@ -14,7 +14,7 @@ use std::mem; use vk; -use gfx_core::{self, draw, pso, shade, target, tex}; +use gfx_core::{self as core, draw, pso, shade, target, tex}; use gfx_core::state::RefValues; use gfx_core::{IndexType, VertexCount}; use {Error, Resources}; @@ -53,13 +53,13 @@ impl draw::CommandBuffer for Buffer { pub struct GraphicsQueue { queue: vk::Queue, functions: vk::DevicePointers, - capabilities: gfx_core::Capabilities, + capabilities: core::Capabilities, } impl GraphicsQueue { #[doc(hidden)] pub fn new(q: vk::Queue, fun: vk::DevicePointers) -> GraphicsQueue { - let caps = gfx_core::Capabilities { + let caps = core::Capabilities { max_vertex_count: 0, max_index_count: 0, max_texture_size: 0, @@ -84,15 +84,15 @@ impl GraphicsQueue { } } -impl gfx_core::Device for GraphicsQueue { +impl core::Device for GraphicsQueue { type Resources = Resources; type CommandBuffer = Buffer; - fn get_capabilities(&self) -> &gfx_core::Capabilities { + fn get_capabilities(&self) -> &core::Capabilities { &self.capabilities } - fn pin_submitted_resources(&mut self, _: &gfx_core::handle::Manager) {} + fn pin_submitted_resources(&mut self, _: &core::handle::Manager) {} fn submit(&mut self, com: &mut Buffer) { let status = unsafe { diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs new file mode 100644 index 00000000000..51eb57cd1a1 --- /dev/null +++ b/src/backend/vulkan/src/factory.rs @@ -0,0 +1,137 @@ +// Copyright 2016 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 std::slice; +use std::os::raw::c_void; +use gfx_core::{self as core, handle as h, factory as f}; +use {Resources as R}; + + +#[derive(Copy, Clone)] +pub struct RawMapping { + pointer: *mut c_void, +} + +impl core::mapping::Raw for RawMapping { + unsafe fn set(&self, index: usize, val: T) { + *(self.pointer as *mut T).offset(index as isize) = val; + } + + unsafe fn to_slice(&self, len: usize) -> &[T] { + slice::from_raw_parts(self.pointer as *const T, len) + } + + unsafe fn to_mut_slice(&self, len: usize) -> &mut [T] { + slice::from_raw_parts_mut(self.pointer as *mut T, len) + } +} + +struct Factory { +} + +impl core::Factory for Factory { + type Mapper = RawMapping; + + fn get_capabilities(&self) -> &core::Capabilities { + unimplemented!() + } + + fn create_buffer_raw(&mut self, _info: f::BufferInfo) -> Result, f::BufferError> { + unimplemented!() + } + + fn create_buffer_const_raw(&mut self, _data: &[u8], _stride: usize, _role: f::BufferRole, _bind: f::Bind) + -> Result, f::BufferError> { + unimplemented!() + } + + fn create_shader(&mut self, _stage: core::shade::Stage, _code: &[u8]) + -> Result, core::shade::CreateShaderError> { + unimplemented!() + } + + fn create_program(&mut self, _shader_set: &core::ShaderSet) + -> Result, core::shade::CreateProgramError> { + unimplemented!() + } + + fn create_pipeline_state_raw(&mut self, _program: &h::Program, _desc: &core::pso::Descriptor) + -> Result, core::pso::CreationError> { + unimplemented!() + } + + fn create_texture_raw(&mut self, _desc: core::tex::Descriptor, _hint: Option, + _data_opt: Option<&[&[u8]]>) -> Result, core::tex::Error> { + unimplemented!() + } + + fn view_buffer_as_shader_resource_raw(&mut self, _hbuf: &h::RawBuffer) + -> Result, f::ResourceViewError> { + Err(f::ResourceViewError::Unsupported) //TODO + } + + fn view_buffer_as_unordered_access_raw(&mut self, _hbuf: &h::RawBuffer) + -> Result, f::ResourceViewError> { + Err(f::ResourceViewError::Unsupported) //TODO + } + + fn view_texture_as_shader_resource_raw(&mut self, _htex: &h::RawTexture, _desc: core::tex::ResourceDesc) + -> Result, f::ResourceViewError> { + unimplemented!() + } + + fn view_texture_as_unordered_access_raw(&mut self, _htex: &h::RawTexture) + -> Result, f::ResourceViewError> { + Err(f::ResourceViewError::Unsupported) //TODO + } + + fn view_texture_as_render_target_raw(&mut self, _htex: &h::RawTexture, _desc: core::tex::RenderDesc) + -> Result, f::TargetViewError> + { + unimplemented!() + } + + fn view_texture_as_depth_stencil_raw(&mut self, _htex: &h::RawTexture, _desc: core::tex::DepthStencilDesc) + -> Result, f::TargetViewError> + { + unimplemented!() + } + + fn create_sampler(&mut self, _info: core::tex::SamplerInfo) -> h::Sampler { + unimplemented!() + } + + fn map_buffer_raw(&mut self, _buf: &h::RawBuffer, _access: f::MapAccess) -> RawMapping { + unimplemented!() + } + + fn unmap_buffer_raw(&mut self, _map: RawMapping) { + unimplemented!() + } + + fn map_buffer_readable(&mut self, _buf: &h::Buffer) + -> core::mapping::Readable { + unimplemented!() + } + + fn map_buffer_writable(&mut self, _buf: &h::Buffer) + -> core::mapping::Writable { + unimplemented!() + } + + fn map_buffer_rw(&mut self, _buf: &h::Buffer) + -> core::mapping::RW { + unimplemented!() + } +} \ No newline at end of file diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index a0bce5b562a..4de29be6c0b 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -21,6 +21,7 @@ use std::{fmt, iter, mem, ptr}; use shared_library::dynamic_library::DynamicLibrary; pub mod command; +mod factory; pub mod vk { #![allow(dead_code)] #![allow(non_upper_case_globals)] From 188ab22e2780c33f2a2ef144363238aae0255066 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Thu, 12 May 2016 00:18:58 -0400 Subject: [PATCH 13/69] [vk] moved the backend into the Arc-shared struct --- src/backend/vulkan/src/command.rs | 17 ++++++++-------- src/backend/vulkan/src/factory.rs | 34 ++++++++++++++++++++++++++++--- src/backend/vulkan/src/lib.rs | 30 +++++++++++++++++++-------- src/window/vulkan/src/lib.rs | 18 ++++++---------- 4 files changed, 67 insertions(+), 32 deletions(-) diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs index d1f2f757741..68ca3bee4bb 100644 --- a/src/backend/vulkan/src/command.rs +++ b/src/backend/vulkan/src/command.rs @@ -17,7 +17,7 @@ use vk; use gfx_core::{self as core, draw, pso, shade, target, tex}; use gfx_core::state::RefValues; use gfx_core::{IndexType, VertexCount}; -use {Error, Resources}; +use {Error, Resources, Share, SharePointer}; pub struct Buffer { @@ -51,14 +51,14 @@ impl draw::CommandBuffer for Buffer { pub struct GraphicsQueue { + share: SharePointer, queue: vk::Queue, - functions: vk::DevicePointers, capabilities: core::Capabilities, } impl GraphicsQueue { #[doc(hidden)] - pub fn new(q: vk::Queue, fun: vk::DevicePointers) -> GraphicsQueue { + pub fn new(share: SharePointer, q: vk::Queue) -> GraphicsQueue { let caps = core::Capabilities { max_vertex_count: 0, max_index_count: 0, @@ -73,14 +73,14 @@ impl GraphicsQueue { separate_blending_slots_supported: false, }; GraphicsQueue { + share: share, queue: q, - functions: fun, capabilities: caps, } } - pub fn get_functions(&self) -> &vk::DevicePointers { - &self.functions + pub fn get_share(&self) -> &Share { + &self.share } } @@ -95,8 +95,9 @@ impl core::Device for GraphicsQueue { fn pin_submitted_resources(&mut self, _: &core::handle::Manager) {} fn submit(&mut self, com: &mut Buffer) { + let vk = self.share.dev_pointers(); let status = unsafe { - self.functions.EndCommandBuffer(com.inner) + vk.EndCommandBuffer(com.inner) }; if status != vk::SUCCESS { panic!("vkEndCommandBuffer: {:?}", Error(status)); @@ -108,7 +109,7 @@ impl core::Device for GraphicsQueue { .. unsafe { mem::zeroed() } }; let status = unsafe { - self.functions.QueueSubmit(self.queue, 1, &info, 0) + vk.QueueSubmit(self.queue, 1, &info, 0) }; if status != vk::SUCCESS { panic!("vkQueueSubmit: {:?}", Error(status)); diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index 51eb57cd1a1..2373dfcf659 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -12,10 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::slice; +use std::{mem, ptr, slice}; use std::os::raw::c_void; use gfx_core::{self as core, handle as h, factory as f}; -use {Resources as R}; +use vk; +use command; +use {Resources as R, SharePointer}; #[derive(Copy, Clone)] @@ -37,7 +39,33 @@ impl core::mapping::Raw for RawMapping { } } -struct Factory { +pub struct Factory { + share: SharePointer, + command_pool: vk::CommandPool, +} + +impl Factory { + pub fn new(share: SharePointer, qf_index: u32) -> Factory { + let com_info = vk::CommandPoolCreateInfo { + sType: vk::STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + queueFamilyIndex: qf_index, + }; + let com_pool = unsafe { + let vk = share.dev_pointers(); + let mut out = mem::zeroed(); + assert_eq!(vk::SUCCESS, vk.CreateCommandPool(share.device(), &com_info, ptr::null(), &mut out)); + out + }; + Factory { + share: share, + command_pool: com_pool, + } + } + pub fn create_command_buffer(&mut self) -> command::Buffer { + unimplemented!() + } } impl core::Factory for Factory { diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index 4de29be6c0b..89c7108c347 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -18,9 +18,13 @@ extern crate shared_library; extern crate gfx_core; use std::{fmt, iter, mem, ptr}; +use std::sync::Arc; use shared_library::dynamic_library::DynamicLibrary; -pub mod command; +pub use self::command::GraphicsQueue; +pub use self::factory::Factory; + +mod command; mod factory; pub mod vk { #![allow(dead_code)] @@ -69,16 +73,20 @@ impl PhysicalDeviceInfo { } } -pub struct Backend { + +pub struct Share { dynamic_lib: DynamicLibrary, library: vk::Static, instance: vk::Instance, inst_pointers: vk::InstancePointers, functions: vk::EntryPoints, device: vk::Device, + dev_pointers: vk::DevicePointers, } -impl Backend { +pub type SharePointer = Arc; + +impl Share { pub fn instance(&self) -> vk::Instance { self.instance } @@ -88,10 +96,13 @@ impl Backend { pub fn device(&self) -> vk::Device { self.device } + pub fn dev_pointers(&self) -> &vk::DevicePointers { + &self.dev_pointers + } } pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[&str], - dev_extensions: &[&str]) -> (Backend, command::GraphicsQueue) { + dev_extensions: &[&str]) -> (command::GraphicsQueue, factory::Factory) { use std::ffi::CString; use std::path::Path; @@ -206,24 +217,25 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& let dev_pointers = vk::DevicePointers::load(|name| unsafe { inst_pointers.GetDeviceProcAddr(device, name.as_ptr()) as *const _ }); - let queue = unsafe { let mut out = mem::zeroed(); dev_pointers.GetDeviceQueue(device, qf_id as u32, 0, &mut out); out }; - let gfx_device = command::GraphicsQueue::new(queue, dev_pointers); - let backend = Backend { + let share = Arc::new(Share { dynamic_lib: dynamic_lib, library: lib, instance: instance, inst_pointers: inst_pointers, functions: entry_points, device: device, - }; + dev_pointers: dev_pointers, + }); + let gfx_device = command::GraphicsQueue::new(share.clone(), queue); + let gfx_factory = factory::Factory::new(share.clone(), qf_id as u32); - (backend, gfx_device) + (gfx_device, gfx_factory) } diff --git a/src/window/vulkan/src/lib.rs b/src/window/vulkan/src/lib.rs index 91195f5e9f1..9c43070ddae 100644 --- a/src/window/vulkan/src/lib.rs +++ b/src/window/vulkan/src/lib.rs @@ -19,18 +19,16 @@ extern crate gfx_device_vulkan; use std::{mem, ptr}; use gfx_device_vulkan::vk; -pub struct Window { - pub backend: gfx_device_vulkan::Backend, - pub win: winit::Window, -} -pub fn init(builder: winit::WindowBuilder) -> (Window, gfx_device_vulkan::command::GraphicsQueue) { +pub fn init(builder: winit::WindowBuilder) -> (winit::Window, gfx_device_vulkan::GraphicsQueue, gfx_device_vulkan::Factory) { //use winit::os::unix::WindowExt; - let (backend, device) = gfx_device_vulkan::create(&builder.window.title, 1, &[], + let (device, factory) = gfx_device_vulkan::create(&builder.window.title, 1, &[], &["VK_KHR_surface", "VK_KHR_xcb_surface"], &["VK_KHR_swapchain"]); let (width, height) = builder.window.dimensions.unwrap_or((640, 400)); + let win = builder.build().unwrap(); if false { + let backend = device.get_share(); let surface = { let vk = backend.inst_pointers(); let info = vk::XcbSurfaceCreateInfoKHR { @@ -51,7 +49,7 @@ pub fn init(builder: winit::WindowBuilder) -> (Window, gfx_device_vulkan::comman } }; - let vk = device.get_functions(); + let vk = backend.dev_pointers(); let mut images: [vk::Image; 2] = [0; 2]; let mut num = images.len() as u32; @@ -93,9 +91,5 @@ pub fn init(builder: winit::WindowBuilder) -> (Window, gfx_device_vulkan::comman } } - let win = Window { - backend: backend, - win: builder.build().unwrap(), - }; - (win, device) + (win, device, factory) } From 9262429c176f86018c7bb985f8b2d797afbdf6f5 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Thu, 12 May 2016 00:39:46 -0400 Subject: [PATCH 14/69] [vk] command buffer creation, refactored all error checks --- src/backend/vulkan/src/command.rs | 37 ++++++++++++++++++------------- src/backend/vulkan/src/factory.rs | 28 ++++++++++++++++++++--- src/backend/vulkan/src/lib.rs | 35 +++++++++-------------------- src/window/vulkan/src/lib.rs | 26 +++++++--------------- 4 files changed, 64 insertions(+), 62 deletions(-) diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs index 68ca3bee4bb..02c552aa588 100644 --- a/src/backend/vulkan/src/command.rs +++ b/src/backend/vulkan/src/command.rs @@ -17,13 +17,28 @@ use vk; use gfx_core::{self as core, draw, pso, shade, target, tex}; use gfx_core::state::RefValues; use gfx_core::{IndexType, VertexCount}; -use {Error, Resources, Share, SharePointer}; +use {Resources, SharePointer}; pub struct Buffer { inner: vk::CommandBuffer, } +impl Buffer { + #[doc(hidden)] + pub fn new(b: vk::CommandBuffer) -> Buffer { + Buffer { + inner: b, + } + } +} + +impl Drop for Buffer { + fn drop(&mut self) { + //TODO + } +} + impl draw::CommandBuffer for Buffer { fn reset(&mut self) {} fn bind_pipeline_state(&mut self, _: ()) {} @@ -78,10 +93,6 @@ impl GraphicsQueue { capabilities: caps, } } - - pub fn get_share(&self) -> &Share { - &self.share - } } impl core::Device for GraphicsQueue { @@ -95,25 +106,19 @@ impl core::Device for GraphicsQueue { fn pin_submitted_resources(&mut self, _: &core::handle::Manager) {} fn submit(&mut self, com: &mut Buffer) { - let vk = self.share.dev_pointers(); - let status = unsafe { + let (_, vk) = self.share.get_device(); + assert_eq!(vk::SUCCESS, unsafe { vk.EndCommandBuffer(com.inner) - }; - if status != vk::SUCCESS { - panic!("vkEndCommandBuffer: {:?}", Error(status)); - } + }); let info = vk::SubmitInfo { sType: vk::STRUCTURE_TYPE_SUBMIT_INFO, commandBufferCount: 1, pCommandBuffers: &com.inner, .. unsafe { mem::zeroed() } }; - let status = unsafe { + assert_eq!(vk::SUCCESS, unsafe { vk.QueueSubmit(self.queue, 1, &info, 0) - }; - if status != vk::SUCCESS { - panic!("vkQueueSubmit: {:?}", Error(status)); - } + }); } fn cleanup(&mut self) {} diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index 2373dfcf659..8ecc7425168 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -53,9 +53,9 @@ impl Factory { queueFamilyIndex: qf_index, }; let com_pool = unsafe { - let vk = share.dev_pointers(); + let (dev, vk) = share.get_device(); let mut out = mem::zeroed(); - assert_eq!(vk::SUCCESS, vk.CreateCommandPool(share.device(), &com_info, ptr::null(), &mut out)); + assert_eq!(vk::SUCCESS, vk.CreateCommandPool(dev, &com_info, ptr::null(), &mut out)); out }; Factory { @@ -63,8 +63,30 @@ impl Factory { command_pool: com_pool, } } + pub fn create_command_buffer(&mut self) -> command::Buffer { - unimplemented!() + let info = vk::CommandBufferAllocateInfo { + sType: vk::STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + pNext: ptr::null(), + commandPool: self.command_pool, + level: vk::COMMAND_BUFFER_LEVEL_PRIMARY, + commandBufferCount: 1, + }; + let (dev, vk) = self.share.get_device(); + unsafe { + let mut out = mem::zeroed(); + assert_eq!(vk::SUCCESS, vk.AllocateCommandBuffers(dev, &info, &mut out)); + command::Buffer::new(out) + } + } +} + +impl Drop for Factory { + fn drop(&mut self) { + let (dev, vk) = self.share.get_device(); + unsafe { + vk.DestroyCommandPool(dev, self.command_pool, ptr::null()) + }; } } diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index 89c7108c347..c781b0d4d1a 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -87,22 +87,16 @@ pub struct Share { pub type SharePointer = Arc; impl Share { - pub fn instance(&self) -> vk::Instance { - self.instance + pub fn get_instance(&self) -> (vk::Instance, &vk::InstancePointers) { + (self.instance, &self.inst_pointers) } - pub fn inst_pointers(&self) -> &vk::InstancePointers { - &self.inst_pointers - } - pub fn device(&self) -> vk::Device { - self.device - } - pub fn dev_pointers(&self) -> &vk::DevicePointers { - &self.dev_pointers + pub fn get_device(&self) -> (vk::Device, &vk::DevicePointers) { + (self.device, &self.dev_pointers) } } pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[&str], - dev_extensions: &[&str]) -> (command::GraphicsQueue, factory::Factory) { + dev_extensions: &[&str]) -> (command::GraphicsQueue, factory::Factory, SharePointer) { use std::ffi::CString; use std::path::Path; @@ -145,10 +139,7 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& }; unsafe { let mut ptr = mem::zeroed(); - let status = entry_points.CreateInstance(&create_info, ptr::null(), &mut ptr); - if status != vk::SUCCESS { - panic!("vkCreateInstance: {:?}", Error(status)); - } + assert_eq!(vk::SUCCESS, entry_points.CreateInstance(&create_info, ptr::null(), &mut ptr)); ptr } }; @@ -159,12 +150,9 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& let mut physical_devices: [vk::PhysicalDevice; 4] = unsafe { mem::zeroed() }; let mut num = physical_devices.len() as u32; - let status = unsafe { + assert_eq!(vk::SUCCESS, unsafe { inst_pointers.EnumeratePhysicalDevices(instance, &mut num, physical_devices.as_mut_ptr()) - }; - if status != vk::SUCCESS { - panic!("vkEnumeratePhysicalDevices: {:?}", Error(status)); - } + }); let devices = physical_devices[..num as usize].iter() .map(|dev| PhysicalDeviceInfo::new(*dev, &inst_pointers)) .collect::>(); @@ -206,10 +194,7 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& }; unsafe { let mut out = mem::zeroed(); - let status = inst_pointers.CreateDevice(ph_dev, &dev_info, ptr::null(), &mut out); - if status != vk::SUCCESS { - panic!("vkCreateDevice: {:?}", Error(status)); - } + assert_eq!(vk::SUCCESS, inst_pointers.CreateDevice(ph_dev, &dev_info, ptr::null(), &mut out)); out } }; @@ -235,7 +220,7 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& let gfx_device = command::GraphicsQueue::new(share.clone(), queue); let gfx_factory = factory::Factory::new(share.clone(), qf_id as u32); - (gfx_device, gfx_factory) + (gfx_device, gfx_factory, share) } diff --git a/src/window/vulkan/src/lib.rs b/src/window/vulkan/src/lib.rs index 9c43070ddae..09466fc2dcd 100644 --- a/src/window/vulkan/src/lib.rs +++ b/src/window/vulkan/src/lib.rs @@ -22,15 +22,14 @@ use gfx_device_vulkan::vk; pub fn init(builder: winit::WindowBuilder) -> (winit::Window, gfx_device_vulkan::GraphicsQueue, gfx_device_vulkan::Factory) { //use winit::os::unix::WindowExt; - let (device, factory) = gfx_device_vulkan::create(&builder.window.title, 1, &[], + let (device, factory, backend) = gfx_device_vulkan::create(&builder.window.title, 1, &[], &["VK_KHR_surface", "VK_KHR_xcb_surface"], &["VK_KHR_swapchain"]); let (width, height) = builder.window.dimensions.unwrap_or((640, 400)); let win = builder.build().unwrap(); if false { - let backend = device.get_share(); let surface = { - let vk = backend.inst_pointers(); + let (inst, vk) = backend.get_instance(); let info = vk::XcbSurfaceCreateInfoKHR { sType: vk::STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR, pNext: ptr::null(), @@ -41,15 +40,12 @@ pub fn init(builder: winit::WindowBuilder) -> (winit::Window, gfx_device_vulkan: unsafe { let mut out = mem::zeroed(); - let status = vk.CreateXcbSurfaceKHR(backend.instance(), &info, ptr::null(), &mut out); - if status != vk::SUCCESS { - panic!("vkCreateXcbSurfaceKHR: {:?}", gfx_device_vulkan::Error(status)); - } + assert_eq!(vk::SUCCESS, vk.CreateXcbSurfaceKHR(inst, &info, ptr::null(), &mut out)); out } }; - let vk = backend.dev_pointers(); + let (dev, vk) = backend.get_device(); let mut images: [vk::Image; 2] = [0; 2]; let mut num = images.len() as u32; @@ -76,19 +72,13 @@ pub fn init(builder: winit::WindowBuilder) -> (winit::Window, gfx_device_vulkan: let swapchain = unsafe { let mut out = mem::zeroed(); - let status = vk.CreateSwapchainKHR(backend.device(), &info, ptr::null(), &mut out); - if status != vk::SUCCESS { - panic!("vkCreateSwapchainKHR: {:?}", gfx_device_vulkan::Error(status)); - } + assert_eq!(vk::SUCCESS, vk.CreateSwapchainKHR(dev, &info, ptr::null(), &mut out)); out }; - let status = unsafe { - vk.GetSwapchainImagesKHR(backend.device(), swapchain, &mut num, images.as_mut_ptr()) - }; - if status != vk::SUCCESS { - panic!("vkGetSwapchainImagesKHR: {:?}", gfx_device_vulkan::Error(status)); - } + assert_eq!(vk::SUCCESS, unsafe { + vk.GetSwapchainImagesKHR(dev, swapchain, &mut num, images.as_mut_ptr()) + }); } (win, device, factory) From 78b0e2fde4631ac222065139965f9878de7b424e Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Thu, 12 May 2016 22:26:29 -0400 Subject: [PATCH 15/69] [vk] added missing BeginCommandInfo calls --- src/backend/vulkan/src/command.rs | 15 ++++++++++++--- src/backend/vulkan/src/factory.rs | 11 +++++++++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs index 02c552aa588..c424307924f 100644 --- a/src/backend/vulkan/src/command.rs +++ b/src/backend/vulkan/src/command.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::mem; +use std::{mem, ptr}; use vk; use gfx_core::{self as core, draw, pso, shade, target, tex}; use gfx_core::state::RefValues; @@ -110,14 +110,23 @@ impl core::Device for GraphicsQueue { assert_eq!(vk::SUCCESS, unsafe { vk.EndCommandBuffer(com.inner) }); - let info = vk::SubmitInfo { + let submit_info = vk::SubmitInfo { sType: vk::STRUCTURE_TYPE_SUBMIT_INFO, commandBufferCount: 1, pCommandBuffers: &com.inner, .. unsafe { mem::zeroed() } }; assert_eq!(vk::SUCCESS, unsafe { - vk.QueueSubmit(self.queue, 1, &info, 0) + vk.QueueSubmit(self.queue, 1, &submit_info, 0) + }); + let begin_info = vk::CommandBufferBeginInfo { + sType: vk::STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + pNext: ptr::null(), + flags: 0, + pInheritanceInfo: ptr::null(), + }; + assert_eq!(vk::SUCCESS, unsafe { + vk.BeginCommandBuffer(com.inner, &begin_info) }); } diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index 8ecc7425168..ba149bea432 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -65,17 +65,24 @@ impl Factory { } pub fn create_command_buffer(&mut self) -> command::Buffer { - let info = vk::CommandBufferAllocateInfo { + let alloc_info = vk::CommandBufferAllocateInfo { sType: vk::STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, pNext: ptr::null(), commandPool: self.command_pool, level: vk::COMMAND_BUFFER_LEVEL_PRIMARY, commandBufferCount: 1, }; + let begin_info = vk::CommandBufferBeginInfo { + sType: vk::STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + pNext: ptr::null(), + flags: 0, + pInheritanceInfo: ptr::null(), + }; let (dev, vk) = self.share.get_device(); unsafe { let mut out = mem::zeroed(); - assert_eq!(vk::SUCCESS, vk.AllocateCommandBuffers(dev, &info, &mut out)); + assert_eq!(vk::SUCCESS, vk.AllocateCommandBuffers(dev, &alloc_info, &mut out)); + assert_eq!(vk::SUCCESS, vk.BeginCommandBuffer(out, &begin_info)); command::Buffer::new(out) } } From 987fbb7e56a4c85bc984107c255448c7f86110d5 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Thu, 12 May 2016 22:58:07 -0400 Subject: [PATCH 16/69] [vk] added Shader struct --- src/backend/vulkan/src/lib.rs | 3 +- src/backend/vulkan/src/native.rs | 56 ++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 src/backend/vulkan/src/native.rs diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index c781b0d4d1a..d84b8c50760 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -26,6 +26,7 @@ pub use self::factory::Factory; mod command; mod factory; +mod native; pub mod vk { #![allow(dead_code)] #![allow(non_upper_case_globals)] @@ -264,7 +265,7 @@ pub enum Resources {} impl gfx_core::Resources for Resources { type Buffer = (); - type Shader = (); + type Shader = native::Shader; type Program = (); type PipelineStateObject = (); type Texture = (); diff --git a/src/backend/vulkan/src/native.rs b/src/backend/vulkan/src/native.rs new file mode 100644 index 00000000000..bc5dcc56284 --- /dev/null +++ b/src/backend/vulkan/src/native.rs @@ -0,0 +1,56 @@ +// Copyright 2016 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 std::ffi::CStr; +use std::{fmt, hash}; +use vk; + +//Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync; + + +pub struct Shader(pub vk::PipelineShaderStageCreateInfo); + +impl Clone for Shader { + fn clone(&self) -> Shader { + Shader(vk::PipelineShaderStageCreateInfo { + .. self.0 + }) + } +} + +impl fmt::Debug for Shader { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let name = unsafe { CStr::from_ptr(self.0.pName) }.to_str().unwrap(); + write!(f, "Shader({}, {}, {})", self.0.stage, name, self.0.module) + } +} + +impl hash::Hash for Shader { + fn hash(&self, state: &mut H) where H: hash::Hasher { + self.0.stage.hash(state); + //self.0.pName.hash(state); + self.0.module.hash(state); + } +} + +impl PartialEq for Shader { + fn eq(&self, other: &Shader) -> bool { + self.0.stage == other.0.stage && + self.0.module == other.0.module + } +} + +impl Eq for Shader {} +unsafe impl Send for Shader {} +unsafe impl Sync for Shader {} From c24159e7067534e722b260f1abf91485dc2d1ac6 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Thu, 12 May 2016 23:20:16 -0400 Subject: [PATCH 17/69] [vk] Shader creation and deletion --- src/backend/vulkan/src/command.rs | 21 ++++++++++++++- src/backend/vulkan/src/factory.rs | 29 ++++++++++++++++++--- src/backend/vulkan/src/lib.rs | 27 +++++++++---------- src/backend/vulkan/src/native.rs | 43 +++---------------------------- 4 files changed, 63 insertions(+), 57 deletions(-) diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs index c424307924f..24fddeacf92 100644 --- a/src/backend/vulkan/src/command.rs +++ b/src/backend/vulkan/src/command.rs @@ -130,5 +130,24 @@ impl core::Device for GraphicsQueue { }); } - fn cleanup(&mut self) {} + fn cleanup(&mut self) { + let (dev, mut functions) = self.share.get_device(); + use gfx_core::handle::Producer; + //self.frame_handles.clear(); + self.share.handles.borrow_mut().clean_with(&mut functions, + |_, _v| (), //buffer + |vk, s| unsafe { //shader + vk.DestroyShaderModule(dev, *s, ptr::null()); + }, + |_, _p| (), //program + |_, _v| (), //PSO + |_, _v| (), //texture + |_, _v| (), //SRV + |_, _| (), //UAV + |_, _v| (), //RTV + |_, _v| (), //DSV + |_, _v| (), //sampler + |_, _| (), //fence + ); + } } diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index ba149bea432..445d5ed9bdb 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -16,7 +16,7 @@ use std::{mem, ptr, slice}; use std::os::raw::c_void; use gfx_core::{self as core, handle as h, factory as f}; use vk; -use command; +use {command}; use {Resources as R, SharePointer}; @@ -113,9 +113,23 @@ impl core::Factory for Factory { unimplemented!() } - fn create_shader(&mut self, _stage: core::shade::Stage, _code: &[u8]) + fn create_shader(&mut self, _stage: core::shade::Stage, code: &[u8]) -> Result, core::shade::CreateShaderError> { - unimplemented!() + use gfx_core::handle::Producer; + let (dev, vk) = self.share.get_device(); + let info = vk::ShaderModuleCreateInfo { + sType: vk::STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + codeSize: code.len(), + pCode: code.as_ptr() as *const _, + }; + let shader = unsafe { + let mut out = mem::zeroed(); + assert_eq!(vk::SUCCESS, vk.CreateShaderModule(dev, &info, ptr::null(), &mut out)); + out + }; + Ok(self.share.handles.borrow_mut().make_shader(shader)) } fn create_program(&mut self, _shader_set: &core::ShaderSet) @@ -125,6 +139,15 @@ impl core::Factory for Factory { fn create_pipeline_state_raw(&mut self, _program: &h::Program, _desc: &core::pso::Descriptor) -> Result, core::pso::CreationError> { + /*let shader = native::Shader(vk::PipelineShaderStageCreateInfo { + sType: vk::STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + stage: 0, //TODO + module: !0, //TODO + pName: ptr::null(), + pSpecializationInfo: ptr::null(), + });*/ unimplemented!() } diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index d84b8c50760..fb9d39a5cbb 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -18,6 +18,7 @@ extern crate shared_library; extern crate gfx_core; use std::{fmt, iter, mem, ptr}; +use std::cell::RefCell; use std::sync::Arc; use shared_library::dynamic_library::DynamicLibrary; @@ -38,17 +39,17 @@ pub mod vk { struct PhysicalDeviceInfo { device: vk::PhysicalDevice, - properties: vk::PhysicalDeviceProperties, + _properties: vk::PhysicalDeviceProperties, queue_families: Vec, - memory: vk::PhysicalDeviceMemoryProperties, - features: vk::PhysicalDeviceFeatures, + _memory: vk::PhysicalDeviceMemoryProperties, + _features: vk::PhysicalDeviceFeatures, } impl PhysicalDeviceInfo { pub fn new(dev: vk::PhysicalDevice, vk: &vk::InstancePointers) -> PhysicalDeviceInfo { PhysicalDeviceInfo { device: dev, - properties: unsafe { + _properties: unsafe { let mut out = mem::zeroed(); vk.GetPhysicalDeviceProperties(dev, &mut out); out @@ -60,12 +61,12 @@ impl PhysicalDeviceInfo { families.set_len(num as usize); families }, - memory: unsafe { + _memory: unsafe { let mut out = mem::zeroed(); vk.GetPhysicalDeviceMemoryProperties(dev, &mut out); out }, - features: unsafe { + _features: unsafe { let mut out = mem::zeroed(); vk.GetPhysicalDeviceFeatures(dev, &mut out); out @@ -76,13 +77,13 @@ impl PhysicalDeviceInfo { pub struct Share { - dynamic_lib: DynamicLibrary, - library: vk::Static, + _dynamic_lib: DynamicLibrary, + _library: vk::Static, instance: vk::Instance, inst_pointers: vk::InstancePointers, - functions: vk::EntryPoints, device: vk::Device, dev_pointers: vk::DevicePointers, + handles: RefCell>, } pub type SharePointer = Arc; @@ -210,13 +211,13 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& }; let share = Arc::new(Share { - dynamic_lib: dynamic_lib, - library: lib, + _dynamic_lib: dynamic_lib, + _library: lib, instance: instance, inst_pointers: inst_pointers, - functions: entry_points, device: device, dev_pointers: dev_pointers, + handles: RefCell::new(gfx_core::handle::Manager::new()), }); let gfx_device = command::GraphicsQueue::new(share.clone(), queue); let gfx_factory = factory::Factory::new(share.clone(), qf_id as u32); @@ -265,7 +266,7 @@ pub enum Resources {} impl gfx_core::Resources for Resources { type Buffer = (); - type Shader = native::Shader; + type Shader = vk::ShaderModule; type Program = (); type PipelineStateObject = (); type Texture = (); diff --git a/src/backend/vulkan/src/native.rs b/src/backend/vulkan/src/native.rs index bc5dcc56284..eee47ef8473 100644 --- a/src/backend/vulkan/src/native.rs +++ b/src/backend/vulkan/src/native.rs @@ -12,45 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::ffi::CStr; -use std::{fmt, hash}; -use vk; +//use std::ffi::CStr; +//use std::{fmt, hash}; +//use vk; //Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync; - - -pub struct Shader(pub vk::PipelineShaderStageCreateInfo); - -impl Clone for Shader { - fn clone(&self) -> Shader { - Shader(vk::PipelineShaderStageCreateInfo { - .. self.0 - }) - } -} - -impl fmt::Debug for Shader { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let name = unsafe { CStr::from_ptr(self.0.pName) }.to_str().unwrap(); - write!(f, "Shader({}, {}, {})", self.0.stage, name, self.0.module) - } -} - -impl hash::Hash for Shader { - fn hash(&self, state: &mut H) where H: hash::Hasher { - self.0.stage.hash(state); - //self.0.pName.hash(state); - self.0.module.hash(state); - } -} - -impl PartialEq for Shader { - fn eq(&self, other: &Shader) -> bool { - self.0.stage == other.0.stage && - self.0.module == other.0.module - } -} - -impl Eq for Shader {} -unsafe impl Send for Shader {} -unsafe impl Sync for Shader {} From ebfc11d6804cee29dcf675a87e4fdb97d68e02d9 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Sat, 14 May 2016 00:28:56 -0400 Subject: [PATCH 18/69] [vk] Texture creation --- src/backend/vulkan/src/command.rs | 8 ++- src/backend/vulkan/src/factory.rs | 83 +++++++++++++++++++++++++++++-- src/backend/vulkan/src/lib.rs | 6 +-- src/backend/vulkan/src/native.rs | 52 +++++++++++++++++-- 4 files changed, 138 insertions(+), 11 deletions(-) diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs index 24fddeacf92..edede11f084 100644 --- a/src/backend/vulkan/src/command.rs +++ b/src/backend/vulkan/src/command.rs @@ -17,6 +17,7 @@ use vk; use gfx_core::{self as core, draw, pso, shade, target, tex}; use gfx_core::state::RefValues; use gfx_core::{IndexType, VertexCount}; +use native; use {Resources, SharePointer}; @@ -53,7 +54,7 @@ impl draw::CommandBuffer for Buffer { fn set_scissor(&mut self, _: target::Rect) {} fn set_ref_values(&mut self, _: RefValues) {} fn update_buffer(&mut self, _: (), _: &[u8], _: usize) {} - fn update_texture(&mut self, _: (), _: tex::Kind, _: Option, + fn update_texture(&mut self, _: native::Texture, _: tex::Kind, _: Option, _: &[u8], _: tex::RawImageInfo) {} fn generate_mipmap(&mut self, _: ()) {} fn clear_color(&mut self, _: (), _: draw::ClearColor) {} @@ -141,7 +142,10 @@ impl core::Device for GraphicsQueue { }, |_, _p| (), //program |_, _v| (), //PSO - |_, _v| (), //texture + |vk, t| unsafe { //texture + vk.DestroyImage(dev, t.image, ptr::null()); + vk.FreeMemory(dev, t.memory, ptr::null()); + }, |_, _v| (), //SRV |_, _| (), //UAV |_, _v| (), //RTV diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index 445d5ed9bdb..b55ed852487 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -16,7 +16,7 @@ use std::{mem, ptr, slice}; use std::os::raw::c_void; use gfx_core::{self as core, handle as h, factory as f}; use vk; -use {command}; +use {command, native}; use {Resources as R, SharePointer}; @@ -151,9 +151,86 @@ impl core::Factory for Factory { unimplemented!() } - fn create_texture_raw(&mut self, _desc: core::tex::Descriptor, _hint: Option, + fn create_texture_raw(&mut self, desc: core::tex::Descriptor, _hint: Option, _data_opt: Option<&[&[u8]]>) -> Result, core::tex::Error> { - unimplemented!() + use gfx_core::factory::{Usage, RENDER_TARGET, DEPTH_STENCIL, SHADER_RESOURCE, UNORDERED_ACCESS}; + use gfx_core::handle::Producer; + use gfx_core::tex::Kind; + + let (w, h, d, _aa) = desc.kind.get_dimensions(); + let slices = desc.kind.get_num_slices(); + let im_type = match desc.kind { + Kind::D1(..) | Kind::D1Array(..) => vk::IMAGE_TYPE_1D, + Kind::D2(..) | Kind::D2Array(..) => vk::IMAGE_TYPE_2D, + Kind::D3(..) => vk::IMAGE_TYPE_3D, + Kind::Cube(..) | Kind::CubeArray(..) => vk::IMAGE_TYPE_2D, + }; + let mut usage = 0; + if desc.bind.contains(RENDER_TARGET) { + usage |= vk::IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + } + if desc.bind.contains(DEPTH_STENCIL) { + usage |= vk::IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + } + if desc.bind.contains(SHADER_RESOURCE) { + usage |= vk::IMAGE_USAGE_SAMPLED_BIT; + } + if desc.bind.contains(UNORDERED_ACCESS) { + usage |= vk::IMAGE_USAGE_STORAGE_BIT; + } + let tiling = match desc.usage { + Usage::Const => vk::IMAGE_TILING_OPTIMAL, + Usage::GpuOnly => { + //TODO: not always needed + usage |= vk::IMAGE_USAGE_TRANSFER_SRC_BIT | vk::IMAGE_USAGE_TRANSFER_DST_BIT; + vk::IMAGE_TILING_OPTIMAL + }, + Usage::Dynamic => { + usage |= vk::IMAGE_USAGE_TRANSFER_DST_BIT; + vk::IMAGE_TILING_LINEAR + }, + Usage::CpuOnly(_) => vk::IMAGE_TILING_LINEAR, + }; + let image_info = vk::ImageCreateInfo { + sType: vk::STRUCTURE_TYPE_IMAGE_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + imageType: im_type, + format: 0, //TODO + extent: vk::Extent3D { + width: w as u32, + height: h as u32, + depth: if slices.is_none() {d as u32} else {1}, + }, + mipLevels: desc.levels as u32, + arrayLayers: slices.unwrap_or(1) as u32, + samples: vk::SAMPLE_COUNT_1_BIT, //TODO + tiling: tiling, + usage: usage, + sharingMode: vk::SHARING_MODE_EXCLUSIVE, + queueFamilyIndexCount: 0, + pQueueFamilyIndices: ptr::null(), + initialLayout: vk::IMAGE_LAYOUT_PREINITIALIZED, + }; + let mut alloc_info = vk::MemoryAllocateInfo { + sType: vk::STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + pNext: ptr::null(), + allocationSize: 0, + memoryTypeIndex: 0, //TODO + }; + let (dev, vk) = self.share.get_device(); + let tex = unsafe { + let mut image = mem::zeroed(); + assert_eq!(vk::SUCCESS, vk.CreateImage(dev, &image_info, ptr::null(), &mut image)); + let mut reqs = mem::zeroed(); + vk.GetImageMemoryRequirements(dev, image, &mut reqs); + alloc_info.allocationSize = reqs.size; + let mut mem = mem::zeroed(); + assert_eq!(vk::SUCCESS, vk.AllocateMemory(dev, &alloc_info, ptr::null(), &mut mem)); + assert_eq!(vk::SUCCESS, vk.BindImageMemory(dev, image, mem, 0)); + native::Texture { image: image, memory: mem } + }; + Ok(self.share.handles.borrow_mut().make_texture(tex, desc)) } fn view_buffer_as_shader_resource_raw(&mut self, _hbuf: &h::RawBuffer) diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index fb9d39a5cbb..87dc5158fd8 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -114,9 +114,9 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& let app_info = vk::ApplicationInfo { sType: vk::STRUCTURE_TYPE_APPLICATION_INFO, pNext: ptr::null(), - pApplicationName: app_name.as_ptr() as *const i8, + pApplicationName: app_name.as_ptr() as *const _, applicationVersion: app_version, - pEngineName: "gfx-rs".as_ptr() as *const i8, + pEngineName: "gfx-rs".as_ptr() as *const _, engineVersion: 0x1000, //TODO apiVersion: 0x400000, //TODO }; @@ -269,7 +269,7 @@ impl gfx_core::Resources for Resources { type Shader = vk::ShaderModule; type Program = (); type PipelineStateObject = (); - type Texture = (); + type Texture = native::Texture; type ShaderResourceView = (); type UnorderedAccessView = (); type RenderTargetView = (); diff --git a/src/backend/vulkan/src/native.rs b/src/backend/vulkan/src/native.rs index eee47ef8473..a02742682ad 100644 --- a/src/backend/vulkan/src/native.rs +++ b/src/backend/vulkan/src/native.rs @@ -12,8 +12,54 @@ // See the License for the specific language governing permissions and // limitations under the License. -//use std::ffi::CStr; -//use std::{fmt, hash}; -//use vk; +use std::ffi::CStr; +use std::{fmt, hash}; +use vk; //Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync; + + +pub struct Shader(pub vk::PipelineShaderStageCreateInfo); + +impl Clone for Shader { + fn clone(&self) -> Shader { + Shader(vk::PipelineShaderStageCreateInfo { + .. self.0 + }) + } +} + +impl fmt::Debug for Shader { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let name = unsafe { CStr::from_ptr(self.0.pName) }.to_str().unwrap(); + write!(f, "Shader({}, {}, {})", self.0.stage, name, self.0.module) + } +} + +impl hash::Hash for Shader { + fn hash(&self, state: &mut H) where H: hash::Hasher { + self.0.stage.hash(state); + //self.0.pName.hash(state); + self.0.module.hash(state); + } +} + +impl PartialEq for Shader { + fn eq(&self, other: &Shader) -> bool { + self.0.stage == other.0.stage && + self.0.module == other.0.module + } +} + +impl Eq for Shader {} +unsafe impl Send for Shader {} +unsafe impl Sync for Shader {} + + +#[derive(Clone, Debug, Hash, Eq, PartialEq)] +pub struct Texture { + pub image: vk::Image, + pub memory: vk::DeviceMemory, +} +unsafe impl Send for Texture {} +unsafe impl Sync for Texture {} From e0102c5ab181efd7fd4bdfab7d1cb27febecb286 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Sat, 14 May 2016 02:39:40 -0400 Subject: [PATCH 19/69] [vk] added data module for enum translation --- src/backend/vulkan/src/data.rs | 63 +++++++++++++++++++++++++++++++ src/backend/vulkan/src/factory.rs | 43 +++------------------ src/backend/vulkan/src/lib.rs | 1 + 3 files changed, 69 insertions(+), 38 deletions(-) create mode 100644 src/backend/vulkan/src/data.rs diff --git a/src/backend/vulkan/src/data.rs b/src/backend/vulkan/src/data.rs new file mode 100644 index 00000000000..98ec3f1a16c --- /dev/null +++ b/src/backend/vulkan/src/data.rs @@ -0,0 +1,63 @@ +// Copyright 2016 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 gfx_core::{factory as f, tex}; +use vk; + + +pub fn map_image_type(kind: tex::Kind) -> vk::ImageType { + match kind { + tex::Kind::D1(..) | tex::Kind::D1Array(..) => vk::IMAGE_TYPE_1D, + tex::Kind::D2(..) | tex::Kind::D2Array(..) => vk::IMAGE_TYPE_2D, + tex::Kind::D3(..) => vk::IMAGE_TYPE_3D, + tex::Kind::Cube(..) | tex::Kind::CubeArray(..) => vk::IMAGE_TYPE_2D, + } +} + +pub fn map_usage_tiling(gfx_usage: f::Usage, bind: f::Bind) -> (vk::ImageUsageFlags, vk::ImageTiling) { + let mut usage = 0; + if bind.contains(f::RENDER_TARGET) { + usage |= vk::IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + } + if bind.contains(f::DEPTH_STENCIL) { + usage |= vk::IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + } + if bind.contains(f::SHADER_RESOURCE) { + usage |= vk::IMAGE_USAGE_SAMPLED_BIT; + } + if bind.contains(f::UNORDERED_ACCESS) { + usage |= vk::IMAGE_USAGE_STORAGE_BIT; + } + let tiling = match gfx_usage { + f::Usage::Const => vk::IMAGE_TILING_OPTIMAL, + f::Usage::GpuOnly => { + //TODO: not always needed + usage |= vk::IMAGE_USAGE_TRANSFER_SRC_BIT | vk::IMAGE_USAGE_TRANSFER_DST_BIT; + vk::IMAGE_TILING_OPTIMAL + }, + f::Usage::Dynamic => { + usage |= vk::IMAGE_USAGE_TRANSFER_DST_BIT; + vk::IMAGE_TILING_LINEAR + }, + f::Usage::CpuOnly(map) => { + usage |= match map { + f::MapAccess::Readable => vk::IMAGE_USAGE_TRANSFER_DST_BIT, + f::MapAccess::Writable => vk::IMAGE_USAGE_TRANSFER_SRC_BIT, + f::MapAccess::RW => vk::IMAGE_USAGE_TRANSFER_SRC_BIT | vk::IMAGE_USAGE_TRANSFER_DST_BIT, + }; + vk::IMAGE_TILING_LINEAR + }, + }; + (usage, tiling) +} diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index b55ed852487..463bad626c1 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -16,7 +16,7 @@ use std::{mem, ptr, slice}; use std::os::raw::c_void; use gfx_core::{self as core, handle as h, factory as f}; use vk; -use {command, native}; +use {command, data, native}; use {Resources as R, SharePointer}; @@ -153,49 +153,16 @@ impl core::Factory for Factory { fn create_texture_raw(&mut self, desc: core::tex::Descriptor, _hint: Option, _data_opt: Option<&[&[u8]]>) -> Result, core::tex::Error> { - use gfx_core::factory::{Usage, RENDER_TARGET, DEPTH_STENCIL, SHADER_RESOURCE, UNORDERED_ACCESS}; use gfx_core::handle::Producer; - use gfx_core::tex::Kind; - let (w, h, d, _aa) = desc.kind.get_dimensions(); + let (w, h, d, aa) = desc.kind.get_dimensions(); let slices = desc.kind.get_num_slices(); - let im_type = match desc.kind { - Kind::D1(..) | Kind::D1Array(..) => vk::IMAGE_TYPE_1D, - Kind::D2(..) | Kind::D2Array(..) => vk::IMAGE_TYPE_2D, - Kind::D3(..) => vk::IMAGE_TYPE_3D, - Kind::Cube(..) | Kind::CubeArray(..) => vk::IMAGE_TYPE_2D, - }; - let mut usage = 0; - if desc.bind.contains(RENDER_TARGET) { - usage |= vk::IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - } - if desc.bind.contains(DEPTH_STENCIL) { - usage |= vk::IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; - } - if desc.bind.contains(SHADER_RESOURCE) { - usage |= vk::IMAGE_USAGE_SAMPLED_BIT; - } - if desc.bind.contains(UNORDERED_ACCESS) { - usage |= vk::IMAGE_USAGE_STORAGE_BIT; - } - let tiling = match desc.usage { - Usage::Const => vk::IMAGE_TILING_OPTIMAL, - Usage::GpuOnly => { - //TODO: not always needed - usage |= vk::IMAGE_USAGE_TRANSFER_SRC_BIT | vk::IMAGE_USAGE_TRANSFER_DST_BIT; - vk::IMAGE_TILING_OPTIMAL - }, - Usage::Dynamic => { - usage |= vk::IMAGE_USAGE_TRANSFER_DST_BIT; - vk::IMAGE_TILING_LINEAR - }, - Usage::CpuOnly(_) => vk::IMAGE_TILING_LINEAR, - }; + let (usage, tiling) = data::map_usage_tiling(desc.usage, desc.bind); let image_info = vk::ImageCreateInfo { sType: vk::STRUCTURE_TYPE_IMAGE_CREATE_INFO, pNext: ptr::null(), flags: 0, - imageType: im_type, + imageType: data::map_image_type(desc.kind), format: 0, //TODO extent: vk::Extent3D { width: w as u32, @@ -204,7 +171,7 @@ impl core::Factory for Factory { }, mipLevels: desc.levels as u32, arrayLayers: slices.unwrap_or(1) as u32, - samples: vk::SAMPLE_COUNT_1_BIT, //TODO + samples: aa.get_num_fragments() as vk::SampleCountFlagBits, tiling: tiling, usage: usage, sharingMode: vk::SHARING_MODE_EXCLUSIVE, diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index 87dc5158fd8..6fcb300af36 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -26,6 +26,7 @@ pub use self::command::GraphicsQueue; pub use self::factory::Factory; mod command; +mod data; mod factory; mod native; pub mod vk { From f067cd7fd151d2943cb55235a35a366d7fa96fe7 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Sat, 14 May 2016 16:25:18 -0400 Subject: [PATCH 20/69] [vk] format translation --- src/backend/vulkan/src/data.rs | 161 +++++++++++++++++++++++++++--- src/backend/vulkan/src/factory.rs | 8 +- 2 files changed, 153 insertions(+), 16 deletions(-) diff --git a/src/backend/vulkan/src/data.rs b/src/backend/vulkan/src/data.rs index 98ec3f1a16c..1a40e3de6b5 100644 --- a/src/backend/vulkan/src/data.rs +++ b/src/backend/vulkan/src/data.rs @@ -12,20 +12,23 @@ // See the License for the specific language governing permissions and // limitations under the License. -use gfx_core::{factory as f, tex}; +use gfx_core::factory::{Bind, MapAccess, Usage}; +use gfx_core::format::{SurfaceType, ChannelType}; +use gfx_core::tex::Kind; use vk; -pub fn map_image_type(kind: tex::Kind) -> vk::ImageType { +pub fn map_image_type(kind: Kind) -> vk::ImageType { match kind { - tex::Kind::D1(..) | tex::Kind::D1Array(..) => vk::IMAGE_TYPE_1D, - tex::Kind::D2(..) | tex::Kind::D2Array(..) => vk::IMAGE_TYPE_2D, - tex::Kind::D3(..) => vk::IMAGE_TYPE_3D, - tex::Kind::Cube(..) | tex::Kind::CubeArray(..) => vk::IMAGE_TYPE_2D, + Kind::D1(..) | Kind::D1Array(..) => vk::IMAGE_TYPE_1D, + Kind::D2(..) | Kind::D2Array(..) => vk::IMAGE_TYPE_2D, + Kind::D3(..) => vk::IMAGE_TYPE_3D, + Kind::Cube(..) | Kind::CubeArray(..) => vk::IMAGE_TYPE_2D, } } -pub fn map_usage_tiling(gfx_usage: f::Usage, bind: f::Bind) -> (vk::ImageUsageFlags, vk::ImageTiling) { +pub fn map_usage_tiling(gfx_usage: Usage, bind: Bind) -> (vk::ImageUsageFlags, vk::ImageTiling) { + use gfx_core::factory as f; let mut usage = 0; if bind.contains(f::RENDER_TARGET) { usage |= vk::IMAGE_USAGE_COLOR_ATTACHMENT_BIT; @@ -40,24 +43,154 @@ pub fn map_usage_tiling(gfx_usage: f::Usage, bind: f::Bind) -> (vk::ImageUsageFl usage |= vk::IMAGE_USAGE_STORAGE_BIT; } let tiling = match gfx_usage { - f::Usage::Const => vk::IMAGE_TILING_OPTIMAL, - f::Usage::GpuOnly => { + Usage::Const => vk::IMAGE_TILING_OPTIMAL, + Usage::GpuOnly => { //TODO: not always needed usage |= vk::IMAGE_USAGE_TRANSFER_SRC_BIT | vk::IMAGE_USAGE_TRANSFER_DST_BIT; vk::IMAGE_TILING_OPTIMAL }, - f::Usage::Dynamic => { + Usage::Dynamic => { usage |= vk::IMAGE_USAGE_TRANSFER_DST_BIT; vk::IMAGE_TILING_LINEAR }, - f::Usage::CpuOnly(map) => { + Usage::CpuOnly(map) => { usage |= match map { - f::MapAccess::Readable => vk::IMAGE_USAGE_TRANSFER_DST_BIT, - f::MapAccess::Writable => vk::IMAGE_USAGE_TRANSFER_SRC_BIT, - f::MapAccess::RW => vk::IMAGE_USAGE_TRANSFER_SRC_BIT | vk::IMAGE_USAGE_TRANSFER_DST_BIT, + MapAccess::Readable => vk::IMAGE_USAGE_TRANSFER_DST_BIT, + MapAccess::Writable => vk::IMAGE_USAGE_TRANSFER_SRC_BIT, + MapAccess::RW => vk::IMAGE_USAGE_TRANSFER_SRC_BIT | vk::IMAGE_USAGE_TRANSFER_DST_BIT, }; vk::IMAGE_TILING_LINEAR }, }; (usage, tiling) } + +pub fn map_format(surface: SurfaceType, chan: ChannelType) -> Option { + use gfx_core::format::SurfaceType::*; + use gfx_core::format::ChannelType::*; + Some(match surface { + R4_G4 => match chan { + Unorm => vk::FORMAT_R4G4_UNORM_PACK8, + _ => return None, + }, + R4_G4_B4_A4 => match chan { + Unorm => vk::FORMAT_R4G4B4A4_UNORM_PACK16, + _ => return None, + }, + R5_G5_B5_A1 => match chan { + Unorm => vk::FORMAT_R5G5B5A1_UNORM_PACK16, + _ => return None, + }, + R5_G6_B5 => match chan { + Unorm => vk::FORMAT_R5G6B5_UNORM_PACK16, + _ => return None, + }, + R8 => match chan { + Int => vk::FORMAT_R8_SINT, + Uint => vk::FORMAT_R8_UINT, + Inorm => vk::FORMAT_R8_SNORM, + Unorm => vk::FORMAT_R8_UNORM, + Srgb => vk::FORMAT_R8_SRGB, + _ => return None, + }, + R8_G8 => match chan { + Int => vk::FORMAT_R8G8_SINT, + Uint => vk::FORMAT_R8G8_UINT, + Inorm => vk::FORMAT_R8G8_SNORM, + Unorm => vk::FORMAT_R8G8_UNORM, + Srgb => vk::FORMAT_R8G8_SRGB, + _ => return None, + }, + R8_G8_B8_A8 => match chan { + Int => vk::FORMAT_R8G8B8A8_SINT, + Uint => vk::FORMAT_R8G8B8A8_UINT, + Inorm => vk::FORMAT_R8G8B8A8_SNORM, + Unorm => vk::FORMAT_R8G8B8A8_UNORM, + Srgb => vk::FORMAT_R8G8B8A8_SRGB, + _ => return None, + }, + R10_G10_B10_A2 => match chan { + Int => vk::FORMAT_A2R10G10B10_SINT_PACK32, + Uint => vk::FORMAT_A2R10G10B10_UINT_PACK32, + Inorm => vk::FORMAT_A2R10G10B10_SNORM_PACK32, + Unorm => vk::FORMAT_A2R10G10B10_UNORM_PACK32, + _ => return None, + }, + R11_G11_B10 => match chan { + Float => vk::FORMAT_B10G11R11_UFLOAT_PACK32, + _ => return None, + }, + R16 => match chan { + Int => vk::FORMAT_R16_SINT, + Uint => vk::FORMAT_R16_UINT, + Inorm => vk::FORMAT_R16_SNORM, + Unorm => vk::FORMAT_R16_UNORM, + Float => vk::FORMAT_R16_SFLOAT, + _ => return None, + }, + R16_G16 => match chan { + Int => vk::FORMAT_R16G16_SINT, + Uint => vk::FORMAT_R16G16_UINT, + Inorm => vk::FORMAT_R16G16_SNORM, + Unorm => vk::FORMAT_R16G16_UNORM, + Float => vk::FORMAT_R16G16_SFLOAT, + _ => return None, + }, + R16_G16_B16 => match chan { + Int => vk::FORMAT_R16G16B16_SINT, + Uint => vk::FORMAT_R16G16B16_UINT, + Inorm => vk::FORMAT_R16G16B16_SNORM, + Unorm => vk::FORMAT_R16G16B16_UNORM, + Float => vk::FORMAT_R16G16B16_SFLOAT, + _ => return None, + }, + R16_G16_B16_A16 => match chan { + Int => vk::FORMAT_R16G16B16A16_SINT, + Uint => vk::FORMAT_R16G16B16A16_UINT, + Inorm => vk::FORMAT_R16G16B16A16_SNORM, + Unorm => vk::FORMAT_R16G16B16A16_UNORM, + Float => vk::FORMAT_R16G16B16A16_SFLOAT, + _ => return None, + }, + R32 => match chan { + Int => vk::FORMAT_R32_SINT, + Uint => vk::FORMAT_R32_UINT, + Float => vk::FORMAT_R32_SFLOAT, + _ => return None, + }, + R32_G32 => match chan { + Int => vk::FORMAT_R32G32_SINT, + Uint => vk::FORMAT_R32G32_UINT, + Float => vk::FORMAT_R32G32_SFLOAT, + _ => return None, + }, + R32_G32_B32 => match chan { + Int => vk::FORMAT_R32G32B32_SINT, + Uint => vk::FORMAT_R32G32B32_UINT, + Float => vk::FORMAT_R32G32B32_SFLOAT, + _ => return None, + }, + R32_G32_B32_A32 => match chan { + Int => vk::FORMAT_R32G32B32A32_SINT, + Uint => vk::FORMAT_R32G32B32A32_UINT, + Float => vk::FORMAT_R32G32B32A32_SFLOAT, + _ => return None, + }, + D16 => match chan { + Unorm => vk::FORMAT_D16_UNORM, + _ => return None, + }, + D24 => match chan { + Unorm => vk::FORMAT_X8_D24_UNORM_PACK32, + _ => return None, + }, + D24_S8 => match chan { + Unorm => vk::FORMAT_D24_UNORM_S8_UINT, + _ => return None, + }, + D32 => match chan { + Float => vk::FORMAT_D32_SFLOAT, + _ => return None, + }, + }) +} diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index 463bad626c1..fbeb2d53a27 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -151,19 +151,23 @@ impl core::Factory for Factory { unimplemented!() } - fn create_texture_raw(&mut self, desc: core::tex::Descriptor, _hint: Option, + fn create_texture_raw(&mut self, desc: core::tex::Descriptor, hint: Option, _data_opt: Option<&[&[u8]]>) -> Result, core::tex::Error> { use gfx_core::handle::Producer; let (w, h, d, aa) = desc.kind.get_dimensions(); let slices = desc.kind.get_num_slices(); let (usage, tiling) = data::map_usage_tiling(desc.usage, desc.bind); + let chan_type = hint.unwrap_or(core::format::ChannelType::Uint); let image_info = vk::ImageCreateInfo { sType: vk::STRUCTURE_TYPE_IMAGE_CREATE_INFO, pNext: ptr::null(), flags: 0, imageType: data::map_image_type(desc.kind), - format: 0, //TODO + format: match data::map_format(desc.format, chan_type) { + Some(f) => f, + None => return Err(core::tex::Error::Format(desc.format, hint)), + }, extent: vk::Extent3D { width: w as u32, height: h as u32, From 5e974a4e631492a66d611a216fc7617c166df0a2 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Sat, 14 May 2016 16:41:25 -0400 Subject: [PATCH 21/69] [vk] image layout and flags --- src/backend/vulkan/src/data.rs | 10 ++++++++++ src/backend/vulkan/src/factory.rs | 5 +++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/backend/vulkan/src/data.rs b/src/backend/vulkan/src/data.rs index 1a40e3de6b5..2a842e3d1bf 100644 --- a/src/backend/vulkan/src/data.rs +++ b/src/backend/vulkan/src/data.rs @@ -65,6 +65,16 @@ pub fn map_usage_tiling(gfx_usage: Usage, bind: Bind) -> (vk::ImageUsageFlags, v (usage, tiling) } +pub fn map_image_layout(bind: Bind) -> vk::ImageLayout { + use gfx_core::factory as f; + match bind { + f::RENDER_TARGET => vk::IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + f::DEPTH_STENCIL => vk::IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + f::SHADER_RESOURCE => vk::IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + _ => vk::IMAGE_LAYOUT_GENERAL, + } +} + pub fn map_format(surface: SurfaceType, chan: ChannelType) -> Option { use gfx_core::format::SurfaceType::*; use gfx_core::format::ChannelType::*; diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index fbeb2d53a27..06de68dbb09 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -162,7 +162,8 @@ impl core::Factory for Factory { let image_info = vk::ImageCreateInfo { sType: vk::STRUCTURE_TYPE_IMAGE_CREATE_INFO, pNext: ptr::null(), - flags: 0, + flags: vk::IMAGE_CREATE_MUTABLE_FORMAT_BIT | + (if desc.kind.is_cube() {vk::IMAGE_CREATE_CUBE_COMPATIBLE_BIT} else {0}), imageType: data::map_image_type(desc.kind), format: match data::map_format(desc.format, chan_type) { Some(f) => f, @@ -181,7 +182,7 @@ impl core::Factory for Factory { sharingMode: vk::SHARING_MODE_EXCLUSIVE, queueFamilyIndexCount: 0, pQueueFamilyIndices: ptr::null(), - initialLayout: vk::IMAGE_LAYOUT_PREINITIALIZED, + initialLayout: data::map_image_layout(desc.bind), }; let mut alloc_info = vk::MemoryAllocateInfo { sType: vk::STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, From 375dc5cfe068d276a167c8d0216aa65fbd86b086 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Sat, 14 May 2016 19:36:53 -0400 Subject: [PATCH 22/69] [vk] sampler creation --- src/backend/vulkan/src/data.rs | 45 ++++++++++++++++++++++++++++++- src/backend/vulkan/src/factory.rs | 42 ++++++++++++++++++++++++++--- src/backend/vulkan/src/lib.rs | 2 +- 3 files changed, 84 insertions(+), 5 deletions(-) diff --git a/src/backend/vulkan/src/data.rs b/src/backend/vulkan/src/data.rs index 2a842e3d1bf..37bdb7aca35 100644 --- a/src/backend/vulkan/src/data.rs +++ b/src/backend/vulkan/src/data.rs @@ -14,7 +14,8 @@ use gfx_core::factory::{Bind, MapAccess, Usage}; use gfx_core::format::{SurfaceType, ChannelType}; -use gfx_core::tex::Kind; +use gfx_core::tex::{FilterMethod, Kind, PackedColor, WrapMode}; +use gfx_core::state; use vk; @@ -204,3 +205,45 @@ pub fn map_format(surface: SurfaceType, chan: ChannelType) -> Option }, }) } + +pub fn map_filter(filter: FilterMethod) -> (vk::Filter, vk::Filter, vk::SamplerMipmapMode, f32) { + match filter { + FilterMethod::Scale => (vk::FILTER_NEAREST, vk::FILTER_NEAREST, vk::SAMPLER_MIPMAP_MODE_NEAREST, 0.0), + FilterMethod::Mipmap => (vk::FILTER_NEAREST, vk::FILTER_NEAREST, vk::SAMPLER_MIPMAP_MODE_LINEAR, 0.0), + FilterMethod::Bilinear => (vk::FILTER_LINEAR, vk::FILTER_LINEAR, vk::SAMPLER_MIPMAP_MODE_NEAREST, 0.0), + FilterMethod::Trilinear => (vk::FILTER_LINEAR, vk::FILTER_LINEAR, vk::SAMPLER_MIPMAP_MODE_LINEAR, 0.0), + FilterMethod::Anisotropic(a) => (vk::FILTER_LINEAR, vk::FILTER_LINEAR, vk::SAMPLER_MIPMAP_MODE_LINEAR, a as f32), + } +} + +pub fn map_wrap(wrap: WrapMode) -> vk::SamplerAddressMode { + match wrap { + WrapMode::Tile => vk::SAMPLER_ADDRESS_MODE_REPEAT, + WrapMode::Mirror => vk::SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, + WrapMode::Clamp => vk::SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + WrapMode::Border => vk::SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, + } +} + +pub fn map_border_color(col: PackedColor) -> Option { + match col.0 { + 0x00000000 => Some(vk::BORDER_COLOR_FLOAT_TRANSPARENT_BLACK), + 0xFF000000 => Some(vk::BORDER_COLOR_FLOAT_OPAQUE_BLACK), + 0xFFFFFFFF => Some(vk::BORDER_COLOR_FLOAT_OPAQUE_WHITE), + _ => None + } +} + +pub fn map_comparison(fun: state::Comparison) -> vk::CompareOp { + use gfx_core::state::Comparison::*; + match fun { + Never => vk::COMPARE_OP_NEVER, + Less => vk::COMPARE_OP_LESS, + LessEqual => vk::COMPARE_OP_LESS_OR_EQUAL, + Equal => vk::COMPARE_OP_EQUAL, + GreaterEqual => vk::COMPARE_OP_GREATER_OR_EQUAL, + Greater => vk::COMPARE_OP_GREATER, + NotEqual => vk::COMPARE_OP_NOT_EQUAL, + Always => vk::COMPARE_OP_ALWAYS, + } +} diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index 06de68dbb09..5be245b703c 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -14,7 +14,7 @@ use std::{mem, ptr, slice}; use std::os::raw::c_void; -use gfx_core::{self as core, handle as h, factory as f}; +use gfx_core::{self as core, handle as h, factory as f, state}; use vk; use {command, data, native}; use {Resources as R, SharePointer}; @@ -237,8 +237,44 @@ impl core::Factory for Factory { unimplemented!() } - fn create_sampler(&mut self, _info: core::tex::SamplerInfo) -> h::Sampler { - unimplemented!() + fn create_sampler(&mut self, info: core::tex::SamplerInfo) -> h::Sampler { + use gfx_core::handle::Producer; + + let (min, mag, mip, aniso) = data::map_filter(info.filter); + let native_info = vk::SamplerCreateInfo { + sType: vk::STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + magFilter: mag, + minFilter: min, + mipmapMode: mip, + addressModeU: data::map_wrap(info.wrap_mode.0), + addressModeV: data::map_wrap(info.wrap_mode.1), + addressModeW: data::map_wrap(info.wrap_mode.2), + mipLodBias: info.lod_bias.into(), + anisotropyEnable: if aniso > 0.0 { vk::TRUE } else { vk::FALSE }, + maxAnisotropy: aniso, + compareEnable: if info.comparison.is_some() { vk::TRUE } else { vk::FALSE }, + compareOp: data::map_comparison(info.comparison.unwrap_or(state::Comparison::Never)), + minLod: info.lod_range.0.into(), + maxLod: info.lod_range.1.into(), + borderColor: match data::map_border_color(info.border) { + Some(bc) => bc, + None => { + error!("Unsupported border color {:x}", info.border.0); + vk::BORDER_COLOR_FLOAT_TRANSPARENT_BLACK + } + }, + unnormalizedCoordinates: vk::FALSE, + }; + + let (dev, vk) = self.share.get_device(); + let sampler = unsafe { + let mut out = mem::zeroed(); + assert_eq!(vk::SUCCESS, vk.CreateSampler(dev, &native_info, ptr::null(), &mut out)); + out + }; + self.share.handles.borrow_mut().make_sampler(sampler, info) } fn map_buffer_raw(&mut self, _buf: &h::RawBuffer, _access: f::MapAccess) -> RawMapping { diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index 6fcb300af36..9ed3a6551b8 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -275,6 +275,6 @@ impl gfx_core::Resources for Resources { type UnorderedAccessView = (); type RenderTargetView = (); type DepthStencilView = (); - type Sampler = (); + type Sampler = vk::Sampler; type Fence = (); } From ac751c129b7d9514a97ecf2af953e36eebeb7f75 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Sun, 15 May 2016 00:12:02 -0400 Subject: [PATCH 23/69] [vk] xcb surface hookup for the window --- src/window/vulkan/Cargo.toml | 1 + src/window/vulkan/src/lib.rs | 168 +++++++++++++++++++++++++---------- 2 files changed, 122 insertions(+), 47 deletions(-) diff --git a/src/window/vulkan/Cargo.toml b/src/window/vulkan/Cargo.toml index ff877636428..75dc9144d6d 100644 --- a/src/window/vulkan/Cargo.toml +++ b/src/window/vulkan/Cargo.toml @@ -13,5 +13,6 @@ name = "gfx_window_vulkan" [dependencies] winit = "0.5" +xcb = "0.7" gfx_core = { path = "../../core", version = "0.3" } gfx_device_vulkan = { path = "../../backend/vulkan", version = "0.1" } diff --git a/src/window/vulkan/src/lib.rs b/src/window/vulkan/src/lib.rs index 09466fc2dcd..5f3180ab398 100644 --- a/src/window/vulkan/src/lib.rs +++ b/src/window/vulkan/src/lib.rs @@ -13,6 +13,7 @@ // limitations under the License. extern crate winit; +extern crate xcb; extern crate gfx_core; extern crate gfx_device_vulkan; @@ -20,66 +21,139 @@ use std::{mem, ptr}; use gfx_device_vulkan::vk; -pub fn init(builder: winit::WindowBuilder) -> (winit::Window, gfx_device_vulkan::GraphicsQueue, gfx_device_vulkan::Factory) { - //use winit::os::unix::WindowExt; - let (device, factory, backend) = gfx_device_vulkan::create(&builder.window.title, 1, &[], +pub fn init_winit(builder: winit::WindowBuilder) -> (winit::Window, gfx_device_vulkan::GraphicsQueue, gfx_device_vulkan::Factory) { + let (device, factory, _backend) = gfx_device_vulkan::create(&builder.window.title, 1, &[], &["VK_KHR_surface", "VK_KHR_xcb_surface"], &["VK_KHR_swapchain"]); - let (width, height) = builder.window.dimensions.unwrap_or((640, 400)); let win = builder.build().unwrap(); + (win, device, factory) +} - if false { - let surface = { - let (inst, vk) = backend.get_instance(); - let info = vk::XcbSurfaceCreateInfoKHR { - sType: vk::STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR, - pNext: ptr::null(), - flags: 0, - connection: ptr::null_mut(), //TODO - window: ptr::null_mut(), //TODO - }; - - unsafe { - let mut out = mem::zeroed(); - assert_eq!(vk::SUCCESS, vk.CreateXcbSurfaceKHR(inst, &info, ptr::null(), &mut out)); - out - } +pub struct Window { + connection: xcb::Connection, + _foreground: u32, + window: u32, + _swapchain: vk::SwapchainKHR, + _images: Vec, +} + +impl Window { + pub fn wait_draw(&mut self) -> Option { + let ev = match self.connection.wait_for_event() { + Some(ev) => ev, + None => return None, }; + //self.connection.flush(); + match ev.response_type() & 0x80 { + xcb::EXPOSE => Some(true), + xcb::KEY_PRESS => None, + _ => Some(false) + } + } +} - let (dev, vk) = backend.get_device(); - let mut images: [vk::Image; 2] = [0; 2]; - let mut num = images.len() as u32; +impl Drop for Window { + fn drop(&mut self) { + xcb::unmap_window(&self.connection, self.window); + xcb::destroy_window(&self.connection, self.window); + self.connection.flush(); + } +} + +pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vulkan::GraphicsQueue, gfx_device_vulkan::Factory) { + let (device, factory, backend) = gfx_device_vulkan::create(title, 1, &[], + &["VK_KHR_surface", "VK_KHR_xcb_surface"], &["VK_KHR_swapchain"]); - let info = vk::SwapchainCreateInfoKHR { - sType: vk::STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, + let (conn, screen_num) = xcb::Connection::connect(None).unwrap(); + let (window, foreground) = { + let setup = conn.get_setup(); + let screen = setup.roots().nth(screen_num as usize).unwrap(); + + let foreground = conn.generate_id(); + xcb::create_gc(&conn, foreground, screen.root(), &[ + (xcb::GC_FOREGROUND, screen.black_pixel()), + (xcb::GC_GRAPHICS_EXPOSURES, 0), + ]); + + let win = conn.generate_id(); + xcb::create_window(&conn, + xcb::COPY_FROM_PARENT as u8, + win, + screen.root(), + 0, 0, + width as u16, height as u16, + 10, + xcb::WINDOW_CLASS_INPUT_OUTPUT as u16, + screen.root_visual(), &[ + (xcb::CW_BACK_PIXEL, screen.white_pixel()), + (xcb::CW_EVENT_MASK, xcb::EVENT_MASK_KEY_PRESS | xcb::EVENT_MASK_EXPOSURE), + ] + ); + (win, foreground) + }; + + xcb::map_window(&conn, window); + xcb::change_property(&conn, xcb::PROP_MODE_REPLACE as u8, window, + xcb::ATOM_WM_NAME, xcb::ATOM_STRING, 8, title.as_bytes()); + conn.flush(); + + let surface = { + let (inst, vk) = backend.get_instance(); + let info = vk::XcbSurfaceCreateInfoKHR { + sType: vk::STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR, pNext: ptr::null(), flags: 0, - surface: surface, - minImageCount: num, - imageFormat: vk::FORMAT_R8G8B8A8_UNORM, - imageColorSpace: vk::COLORSPACE_SRGB_NONLINEAR_KHR, - imageExtent: vk::Extent2D { width: width, height: height }, - imageArrayLayers: 1, - imageUsage: vk::IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, - imageSharingMode: vk::SHARING_MODE_EXCLUSIVE, - queueFamilyIndexCount: 1, - pQueueFamilyIndices: &0, - preTransform: vk::SURFACE_TRANSFORM_IDENTITY_BIT_KHR, - compositeAlpha: vk::COMPOSITE_ALPHA_OPAQUE_BIT_KHR, - presentMode: vk::PRESENT_MODE_FIFO_RELAXED_KHR, - clipped: vk::TRUE, - oldSwapchain: 0, + connection: conn.get_raw_conn() as *const _, + window: window, }; - let swapchain = unsafe { + unsafe { let mut out = mem::zeroed(); - assert_eq!(vk::SUCCESS, vk.CreateSwapchainKHR(dev, &info, ptr::null(), &mut out)); + assert_eq!(vk::SUCCESS, vk.CreateXcbSurfaceKHR(inst, &info, ptr::null(), &mut out)); out - }; + } + }; - assert_eq!(vk::SUCCESS, unsafe { - vk.GetSwapchainImagesKHR(dev, swapchain, &mut num, images.as_mut_ptr()) - }); - } + let (dev, vk) = backend.get_device(); + let mut images: [vk::Image; 2] = [0; 2]; + let mut num = images.len() as u32; + + let info = vk::SwapchainCreateInfoKHR { + sType: vk::STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, + pNext: ptr::null(), + flags: 0, + surface: surface, + minImageCount: num, + imageFormat: vk::FORMAT_R8G8B8A8_UNORM, + imageColorSpace: vk::COLORSPACE_SRGB_NONLINEAR_KHR, + imageExtent: vk::Extent2D { width: width, height: height }, + imageArrayLayers: 1, + imageUsage: vk::IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + imageSharingMode: vk::SHARING_MODE_EXCLUSIVE, + queueFamilyIndexCount: 1, + pQueueFamilyIndices: &0, + preTransform: vk::SURFACE_TRANSFORM_IDENTITY_BIT_KHR, + compositeAlpha: vk::COMPOSITE_ALPHA_OPAQUE_BIT_KHR, + presentMode: vk::PRESENT_MODE_FIFO_RELAXED_KHR, + clipped: vk::TRUE, + oldSwapchain: 0, + }; + + let swapchain = unsafe { + let mut out = mem::zeroed(); + assert_eq!(vk::SUCCESS, vk.CreateSwapchainKHR(dev, &info, ptr::null(), &mut out)); + out + }; + + assert_eq!(vk::SUCCESS, unsafe { + vk.GetSwapchainImagesKHR(dev, swapchain, &mut num, images.as_mut_ptr()) + }); + let win = Window { + connection: conn, + _foreground: foreground, + window: window, + _swapchain: swapchain, + _images: images[..num as usize].to_vec(), + }; (win, device, factory) } From 2d005e5624c8c34768e9fdf231bc50ba0caada01 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Mon, 16 May 2016 00:07:28 -0400 Subject: [PATCH 24/69] [vk] updated to vk-sys change, it's no longer a generator --- src/backend/vulkan/Cargo.toml | 5 +---- src/backend/vulkan/build.rs | 16 ---------------- src/backend/vulkan/src/lib.rs | 10 ++-------- src/window/vulkan/Cargo.toml | 1 + src/window/vulkan/src/lib.rs | 6 +++--- 5 files changed, 7 insertions(+), 31 deletions(-) delete mode 100644 src/backend/vulkan/build.rs diff --git a/src/backend/vulkan/Cargo.toml b/src/backend/vulkan/Cargo.toml index 2cc1fcefbca..8596481a708 100644 --- a/src/backend/vulkan/Cargo.toml +++ b/src/backend/vulkan/Cargo.toml @@ -7,7 +7,6 @@ repository = "https://github.com/gfx-rs/gfx" keywords = ["graphics", "gamedev"] license = "Apache-2.0" authors = ["The Gfx-rs Developers"] -build = "build.rs" [lib] name = "gfx_device_vulkan" @@ -15,9 +14,7 @@ name = "gfx_device_vulkan" [dependencies] log = "0.3" vk = "0.0" +vk-sys = { path = "../../../../vulkano/vk-sys" } shared_library = "0.1" winit = "0.5" gfx_core = { path = "../../core", version = "0.3" } - -[build-dependencies] -vk-sys = { path = "../../../../vulkano/vk-sys" } \ No newline at end of file diff --git a/src/backend/vulkan/build.rs b/src/backend/vulkan/build.rs deleted file mode 100644 index 671403cbbae..00000000000 --- a/src/backend/vulkan/build.rs +++ /dev/null @@ -1,16 +0,0 @@ -extern crate vk_sys; - -use std::env; -use std::fs::File; -use std::path::Path; - -fn main() { - // tell Cargo that this build script never needs to be rerun - println!("cargo:rerun-if-changed=build.rs"); - - let dest = env::var("OUT_DIR").unwrap(); - let dest = Path::new(&dest); - - let mut file_output = File::create(&dest.join("vk_bindings.rs")).unwrap(); - vk_sys::write_bindings(&mut file_output).unwrap(); -} diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index 9ed3a6551b8..752c145b3e3 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -16,6 +16,7 @@ extern crate log; extern crate shared_library; extern crate gfx_core; +extern crate vk_sys as vk; use std::{fmt, iter, mem, ptr}; use std::cell::RefCell; @@ -29,13 +30,6 @@ mod command; mod data; mod factory; mod native; -pub mod vk { - #![allow(dead_code)] - #![allow(non_upper_case_globals)] - #![allow(non_snake_case)] - #![allow(non_camel_case_types)] - include!(concat!(env!("OUT_DIR"), "/vk_bindings.rs")); -} struct PhysicalDeviceInfo { @@ -103,7 +97,7 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& use std::ffi::CString; use std::path::Path; - let dynamic_lib = DynamicLibrary::open(Some(Path::new("libvulkan.so"))).unwrap(); + let dynamic_lib = DynamicLibrary::open(Some(Path::new("libvulkan.so.1"))).unwrap(); let lib = vk::Static::load(|name| unsafe { let name = name.to_str().unwrap(); dynamic_lib.symbol(name).unwrap() diff --git a/src/window/vulkan/Cargo.toml b/src/window/vulkan/Cargo.toml index 75dc9144d6d..d03fde1e7b2 100644 --- a/src/window/vulkan/Cargo.toml +++ b/src/window/vulkan/Cargo.toml @@ -14,5 +14,6 @@ name = "gfx_window_vulkan" [dependencies] winit = "0.5" xcb = "0.7" +vk-sys = { path = "../../../../vulkano/vk-sys" } gfx_core = { path = "../../core", version = "0.3" } gfx_device_vulkan = { path = "../../backend/vulkan", version = "0.1" } diff --git a/src/window/vulkan/src/lib.rs b/src/window/vulkan/src/lib.rs index 5f3180ab398..2df3e32d767 100644 --- a/src/window/vulkan/src/lib.rs +++ b/src/window/vulkan/src/lib.rs @@ -14,11 +14,11 @@ extern crate winit; extern crate xcb; +extern crate vk_sys as vk; extern crate gfx_core; extern crate gfx_device_vulkan; use std::{mem, ptr}; -use gfx_device_vulkan::vk; pub fn init_winit(builder: winit::WindowBuilder) -> (winit::Window, gfx_device_vulkan::GraphicsQueue, gfx_device_vulkan::Factory) { @@ -84,7 +84,7 @@ pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vul 10, xcb::WINDOW_CLASS_INPUT_OUTPUT as u16, screen.root_visual(), &[ - (xcb::CW_BACK_PIXEL, screen.white_pixel()), + (xcb::CW_BACK_PIXEL, screen.black_pixel()), (xcb::CW_EVENT_MASK, xcb::EVENT_MASK_KEY_PRESS | xcb::EVENT_MASK_EXPOSURE), ] ); @@ -103,7 +103,7 @@ pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vul pNext: ptr::null(), flags: 0, connection: conn.get_raw_conn() as *const _, - window: window, + window: window as *const _, //HACK! TODO: fix the bindings }; unsafe { From 958c6cca51c4ce5322f6b5befbca5053698fbd7f Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Mon, 16 May 2016 23:48:21 -0400 Subject: [PATCH 25/69] [vk] image views --- src/backend/dx11/src/factory.rs | 1 + src/backend/vulkan/src/command.rs | 6 ++-- src/backend/vulkan/src/data.rs | 35 +++++++++++++++++++++-- src/backend/vulkan/src/factory.rs | 47 +++++++++++++++++++++++++++++-- src/backend/vulkan/src/lib.rs | 2 +- src/core/src/factory.rs | 16 +++++++++-- src/core/src/tex.rs | 3 +- src/render/src/lib.rs | 2 +- 8 files changed, 101 insertions(+), 11 deletions(-) diff --git a/src/backend/dx11/src/factory.rs b/src/backend/dx11/src/factory.rs index 13888516b49..1df2a520b9e 100644 --- a/src/backend/dx11/src/factory.rs +++ b/src/backend/dx11/src/factory.rs @@ -610,6 +610,7 @@ impl core::Factory for Factory { use winapi::UINT; use gfx_core::tex::{AaMode, Kind}; use data::map_format; + //TODO: support desc.layer parsing let (dim, layers, has_levels) = match htex.get_info().kind { Kind::D1(_) => diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs index edede11f084..aca752dfcb1 100644 --- a/src/backend/vulkan/src/command.rs +++ b/src/backend/vulkan/src/command.rs @@ -56,7 +56,7 @@ impl draw::CommandBuffer for Buffer { fn update_buffer(&mut self, _: (), _: &[u8], _: usize) {} fn update_texture(&mut self, _: native::Texture, _: tex::Kind, _: Option, _: &[u8], _: tex::RawImageInfo) {} - fn generate_mipmap(&mut self, _: ()) {} + fn generate_mipmap(&mut self, _: vk::ImageView) {} fn clear_color(&mut self, _: (), _: draw::ClearColor) {} fn clear_depth_stencil(&mut self, _: (), _: Option, _: Option) {} @@ -146,7 +146,9 @@ impl core::Device for GraphicsQueue { vk.DestroyImage(dev, t.image, ptr::null()); vk.FreeMemory(dev, t.memory, ptr::null()); }, - |_, _v| (), //SRV + |vk, v| unsafe { //SRV + vk.DestroyImageView(dev, *v, ptr::null()); + }, |_, _| (), //UAV |_, _v| (), //RTV |_, _v| (), //DSV diff --git a/src/backend/vulkan/src/data.rs b/src/backend/vulkan/src/data.rs index 37bdb7aca35..0861f9c087c 100644 --- a/src/backend/vulkan/src/data.rs +++ b/src/backend/vulkan/src/data.rs @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -use gfx_core::factory::{Bind, MapAccess, Usage}; +use gfx_core::factory::{Bind, MapAccess, Usage, LayerError}; use gfx_core::format::{SurfaceType, ChannelType}; -use gfx_core::tex::{FilterMethod, Kind, PackedColor, WrapMode}; +use gfx_core::tex::{FilterMethod, Kind, Layer, PackedColor, WrapMode}; use gfx_core::state; use vk; @@ -28,6 +28,37 @@ pub fn map_image_type(kind: Kind) -> vk::ImageType { } } +pub fn map_image_view_type(kind: Kind, layer: Option) -> Result { + match (kind, layer) { + (Kind::D1(..), Some(_)) | (Kind::D2(..), Some(_)) | (Kind::D3(..), Some(_)) | + (Kind::Cube(..), Some(_)) => Err(LayerError::NotExpected(kind)), + (Kind::D1Array(_, n), Some(l)) if n<=l => Err(LayerError::OutOfBounds(l, n)), + (Kind::D2Array(_, _, n, _), Some(l)) if n<=l => Err(LayerError::OutOfBounds(l, n)), + (Kind::CubeArray(_, n), Some(l)) if n<=l => Err(LayerError::OutOfBounds(l, n)), + (Kind::D1(..), None) | (Kind::D1Array(..), Some(_)) => Ok(vk::IMAGE_VIEW_TYPE_1D), + (Kind::D1Array(..), None) => Ok(vk::IMAGE_VIEW_TYPE_1D_ARRAY), + (Kind::D2(..), None) | (Kind::D2Array(..), Some(_)) => Ok(vk::IMAGE_VIEW_TYPE_2D), + (Kind::D2Array(..), None) => Ok(vk::IMAGE_VIEW_TYPE_2D_ARRAY), + (Kind::D3(..), None) => Ok(vk::IMAGE_VIEW_TYPE_3D), + (Kind::Cube(..), None) | (Kind::CubeArray(..), Some(_)) => Ok(vk::IMAGE_VIEW_TYPE_CUBE), + (Kind::CubeArray(..), None) => Ok(vk::IMAGE_VIEW_TYPE_CUBE_ARRAY), + } +} + +pub fn map_image_aspect(surface: SurfaceType, channel: ChannelType) -> vk::ImageAspectFlags { + match surface { + SurfaceType::D16 | SurfaceType::D24 | SurfaceType::D24_S8 | SurfaceType::D32 => match channel { + ChannelType::Float => vk::IMAGE_ASPECT_DEPTH_BIT, + ChannelType::Uint => vk::IMAGE_ASPECT_STENCIL_BIT, + _ => { + error!("Unexpected depth/stencil channel {:?}", channel); + vk::IMAGE_ASPECT_DEPTH_BIT + } + }, + _ => vk::IMAGE_ASPECT_COLOR_BIT, + } +} + pub fn map_usage_tiling(gfx_usage: Usage, bind: Bind) -> (vk::ImageUsageFlags, vk::ImageTiling) { use gfx_core::factory as f; let mut usage = 0; diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index 5be245b703c..6310b55b125 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -42,6 +42,7 @@ impl core::mapping::Raw for RawMapping { pub struct Factory { share: SharePointer, command_pool: vk::CommandPool, + frame_handles: h::Manager, } impl Factory { @@ -61,6 +62,7 @@ impl Factory { Factory { share: share, command_pool: com_pool, + frame_handles: h::Manager::new(), } } @@ -215,9 +217,50 @@ impl core::Factory for Factory { Err(f::ResourceViewError::Unsupported) //TODO } - fn view_texture_as_shader_resource_raw(&mut self, _htex: &h::RawTexture, _desc: core::tex::ResourceDesc) + fn view_texture_as_shader_resource_raw(&mut self, htex: &h::RawTexture, desc: core::tex::ResourceDesc) -> Result, f::ResourceViewError> { - unimplemented!() + use gfx_core::handle::Producer; + + let raw_tex = self.frame_handles.ref_texture(htex); + let td = htex.get_info(); + let info = vk::ImageViewCreateInfo { + sType: vk::STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + image: raw_tex.image, + viewType: match data::map_image_view_type(td.kind, desc.layer) { + Ok(vt) => vt, + Err(e) => return Err(f::ResourceViewError::Layer(e)), + }, + format: match data::map_format(td.format, desc.channel) { + Some(f) => f, + None => return Err(f::ResourceViewError::Channel(desc.channel)), + }, + components: vk::ComponentMapping { + r: vk::COMPONENT_SWIZZLE_R, + g: vk::COMPONENT_SWIZZLE_G, + b: vk::COMPONENT_SWIZZLE_B, + a: vk::COMPONENT_SWIZZLE_A, + }, + subresourceRange: vk::ImageSubresourceRange { + aspectMask: data::map_image_aspect(td.format, desc.channel), + baseMipLevel: desc.min as u32, + levelCount: (desc.max + 1 - desc.min) as u32, + baseArrayLayer: desc.layer.unwrap_or(0) as u32, + layerCount: match desc.layer { + Some(_) => 1, + None => td.kind.get_num_slices().unwrap_or(1) as u32, + }, + }, + }; + + let (dev, vk) = self.share.get_device(); + let view = unsafe { + let mut out = mem::zeroed(); + assert_eq!(vk::SUCCESS, vk.CreateImageView(dev, &info, ptr::null(), &mut out)); + out + }; + Ok(self.share.handles.borrow_mut().make_texture_srv(view, htex)) } fn view_texture_as_unordered_access_raw(&mut self, _htex: &h::RawTexture) diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index 752c145b3e3..6f32542f67d 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -265,7 +265,7 @@ impl gfx_core::Resources for Resources { type Program = (); type PipelineStateObject = (); type Texture = native::Texture; - type ShaderResourceView = (); + type ShaderResourceView = vk::ImageView; //TODO: buffer view type UnorderedAccessView = (); type RenderTargetView = (); type DepthStencilView = (); diff --git a/src/core/src/factory.rs b/src/core/src/factory.rs index d33720af2af..6dc4af7d7ae 100644 --- a/src/core/src/factory.rs +++ b/src/core/src/factory.rs @@ -152,7 +152,7 @@ impl Error for BufferError { } /// An error happening on buffer updates. -#[derive(Clone, PartialEq, Debug)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub enum BufferUpdateError { /// Trying to change the contents outside of the allocation. OutOfBounds, @@ -173,6 +173,15 @@ impl Error for BufferUpdateError { } } +/// An error associated with selected texture layer. +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub enum LayerError { + /// The source texture kind doesn't support array slices. + NotExpected(tex::Kind), + /// Selected layer is outside of the provided range. + OutOfBounds(target::Layer, target::Layer), +} + /// Error creating either a ShaderResourceView, or UnorderedAccessView. #[derive(Clone, PartialEq, Debug)] pub enum ResourceViewError { @@ -180,6 +189,8 @@ pub enum ResourceViewError { NoBindFlag, /// Selected channel type is not supported for this texture. Channel(format::ChannelType), + /// Selected layer can not be viewed for this texture. + Layer(LayerError), /// The backend was refused for some reason. Unsupported, } @@ -212,7 +223,7 @@ pub enum TargetViewError { /// Selected mip level doesn't exist. BadLevel(target::Level), /// Selected array layer doesn't exist. - BadLayer(target::Layer), + Layer(LayerError), /// Selected channel type is not supported for this texture. Channel(format::ChannelType), /// The backend was refused for some reason. @@ -454,6 +465,7 @@ pub trait Factory { assert!(levels.0 <= levels.1); let desc = tex::ResourceDesc { channel: ::get_channel_type(), + layer: None, min: levels.0, max: levels.1, swizzle: swizzle, diff --git a/src/core/src/tex.rs b/src/core/src/tex.rs index 7919f684ae3..9159a154eb7 100644 --- a/src/core/src/tex.rs +++ b/src/core/src/tex.rs @@ -218,7 +218,7 @@ impl Kind { } } /// Return the number of slices for an array, or None for non-arrays. - pub fn get_num_slices(&self) -> Option { + pub fn get_num_slices(&self) -> Option { match *self { Kind::D1(..) | Kind::D2(..) | Kind::D3(..) | Kind::Cube(..) => None, Kind::D1Array(_, a) => Some(a), @@ -419,6 +419,7 @@ impl Descriptor { #[derive(Eq, Ord, PartialEq, PartialOrd, Hash, Copy, Clone, Debug)] pub struct ResourceDesc { pub channel: format::ChannelType, + pub layer: Option, pub min: Level, pub max: Level, pub swizzle: format::Swizzle, diff --git a/src/render/src/lib.rs b/src/render/src/lib.rs index a8bb5e37adf..01e6b665fd2 100644 --- a/src/render/src/lib.rs +++ b/src/render/src/lib.rs @@ -40,7 +40,7 @@ pub use gfx_core::{ShaderSet, VertexShader, HullShader, DomainShader, pub use gfx_core::{format, handle, tex}; pub use gfx_core::factory::{Factory, Typed, Usage, Bind, MapAccess, BufferRole, BufferInfo, BufferError, BufferUpdateError, - ResourceViewError, TargetViewError, CombinedError, + LayerError, ResourceViewError, TargetViewError, CombinedError, RENDER_TARGET, DEPTH_STENCIL, SHADER_RESOURCE, UNORDERED_ACCESS, cast_slice}; pub use gfx_core::draw::{CommandBuffer, InstanceOption}; From ed2ff5df6a03b71f9158734bf188fae9e24ad518 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Tue, 17 May 2016 00:31:54 -0400 Subject: [PATCH 26/69] [vk] RTV and SRV creation/deletion --- src/backend/vulkan/src/command.rs | 10 ++- src/backend/vulkan/src/data.rs | 31 +++++-- src/backend/vulkan/src/factory.rs | 133 ++++++++++++++++++++---------- src/backend/vulkan/src/lib.rs | 2 +- 4 files changed, 123 insertions(+), 53 deletions(-) diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs index aca752dfcb1..03d37008576 100644 --- a/src/backend/vulkan/src/command.rs +++ b/src/backend/vulkan/src/command.rs @@ -57,7 +57,7 @@ impl draw::CommandBuffer for Buffer { fn update_texture(&mut self, _: native::Texture, _: tex::Kind, _: Option, _: &[u8], _: tex::RawImageInfo) {} fn generate_mipmap(&mut self, _: vk::ImageView) {} - fn clear_color(&mut self, _: (), _: draw::ClearColor) {} + fn clear_color(&mut self, _: vk::ImageView, _: draw::ClearColor) {} fn clear_depth_stencil(&mut self, _: (), _: Option, _: Option) {} fn call_draw(&mut self, _: VertexCount, _: VertexCount, _: draw::InstanceOption) {} @@ -142,15 +142,17 @@ impl core::Device for GraphicsQueue { }, |_, _p| (), //program |_, _v| (), //PSO - |vk, t| unsafe { //texture + |vk, t| if t.memory != 0 {unsafe { //texture vk.DestroyImage(dev, t.image, ptr::null()); vk.FreeMemory(dev, t.memory, ptr::null()); - }, + }}, |vk, v| unsafe { //SRV vk.DestroyImageView(dev, *v, ptr::null()); }, |_, _| (), //UAV - |_, _v| (), //RTV + |vk, v| unsafe { //RTV + vk.DestroyImageView(dev, *v, ptr::null()); + }, |_, _v| (), //DSV |_, _v| (), //sampler |_, _| (), //fence diff --git a/src/backend/vulkan/src/data.rs b/src/backend/vulkan/src/data.rs index 0861f9c087c..c860a8be150 100644 --- a/src/backend/vulkan/src/data.rs +++ b/src/backend/vulkan/src/data.rs @@ -13,7 +13,7 @@ // limitations under the License. use gfx_core::factory::{Bind, MapAccess, Usage, LayerError}; -use gfx_core::format::{SurfaceType, ChannelType}; +use gfx_core::format::{SurfaceType, ChannelType, Swizzle, ChannelSource}; use gfx_core::tex::{FilterMethod, Kind, Layer, PackedColor, WrapMode}; use gfx_core::state; use vk; @@ -45,11 +45,12 @@ pub fn map_image_view_type(kind: Kind, layer: Option) -> Result vk::ImageAspectFlags { +pub fn map_image_aspect(surface: SurfaceType, channel: ChannelType, is_target: bool) -> vk::ImageAspectFlags { match surface { - SurfaceType::D16 | SurfaceType::D24 | SurfaceType::D24_S8 | SurfaceType::D32 => match channel { - ChannelType::Float => vk::IMAGE_ASPECT_DEPTH_BIT, - ChannelType::Uint => vk::IMAGE_ASPECT_STENCIL_BIT, + SurfaceType::D16 | SurfaceType::D24 | SurfaceType::D24_S8 | SurfaceType::D32 => match (is_target, channel) { + (true, _) => vk::IMAGE_ASPECT_DEPTH_BIT | vk::IMAGE_ASPECT_STENCIL_BIT, + (false, ChannelType::Float) => vk::IMAGE_ASPECT_DEPTH_BIT, + (false, ChannelType::Uint) => vk::IMAGE_ASPECT_STENCIL_BIT, _ => { error!("Unexpected depth/stencil channel {:?}", channel); vk::IMAGE_ASPECT_DEPTH_BIT @@ -59,6 +60,26 @@ pub fn map_image_aspect(surface: SurfaceType, channel: ChannelType) -> vk::Image } } +pub fn map_channel_source(source: ChannelSource) -> vk::ComponentSwizzle { + match source { + ChannelSource::Zero => vk::COMPONENT_SWIZZLE_ZERO, + ChannelSource::One => vk::COMPONENT_SWIZZLE_ONE, + ChannelSource::X => vk::COMPONENT_SWIZZLE_R, + ChannelSource::Y => vk::COMPONENT_SWIZZLE_G, + ChannelSource::Z => vk::COMPONENT_SWIZZLE_B, + ChannelSource::W => vk::COMPONENT_SWIZZLE_A, + } +} + +pub fn map_swizzle(swizzle: Swizzle) -> vk::ComponentMapping { + vk::ComponentMapping { + r: map_channel_source(swizzle.0), + g: map_channel_source(swizzle.1), + b: map_channel_source(swizzle.2), + a: map_channel_source(swizzle.3), + } +} + pub fn map_usage_tiling(gfx_usage: Usage, bind: Bind) -> (vk::ImageUsageFlags, vk::ImageTiling) { use gfx_core::factory as f; let mut usage = 0; diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index 6310b55b125..30b24cf6cc9 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -88,6 +88,74 @@ impl Factory { command::Buffer::new(out) } } + + fn view_texture(&mut self, htex: &h::RawTexture, desc: core::tex::ResourceDesc, is_target: bool) + -> Result { + let raw_tex = self.frame_handles.ref_texture(htex); + let td = htex.get_info(); + let info = vk::ImageViewCreateInfo { + sType: vk::STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + image: raw_tex.image, + viewType: match data::map_image_view_type(td.kind, desc.layer) { + Ok(vt) => vt, + Err(e) => return Err(f::ResourceViewError::Layer(e)), + }, + format: match data::map_format(td.format, desc.channel) { + Some(f) => f, + None => return Err(f::ResourceViewError::Channel(desc.channel)), + }, + components: data::map_swizzle(desc.swizzle), + subresourceRange: vk::ImageSubresourceRange { + aspectMask: data::map_image_aspect(td.format, desc.channel, is_target), + baseMipLevel: desc.min as u32, + levelCount: (desc.max + 1 - desc.min) as u32, + baseArrayLayer: desc.layer.unwrap_or(0) as u32, + layerCount: match desc.layer { + Some(_) => 1, + None => td.kind.get_num_slices().unwrap_or(1) as u32, + }, + }, + }; + + let (dev, vk) = self.share.get_device(); + Ok(unsafe { + let mut out = mem::zeroed(); + assert_eq!(vk::SUCCESS, vk.CreateImageView(dev, &info, ptr::null(), &mut out)); + out + }) + } + + + #[doc(hidden)] + pub fn view_swapchain_image(&mut self, image: vk::Image, format: core::format::Format, size: (u32, u32)) + -> Result, f::TargetViewError> { + use gfx_core::Factory; + use gfx_core::handle::Producer; + use gfx_core::tex as t; + + let raw_tex = native::Texture { + image: image, + memory: 0, + }; + let tex_desc = t::Descriptor { + kind: t::Kind::D2(size.0 as t::Size, size.1 as t::Size, t::AaMode::Single), + levels: 1, + format: format.0, + bind: f::RENDER_TARGET, + usage: f::Usage::GpuOnly, + }; + let tex = self.frame_handles.make_texture(raw_tex, tex_desc); + let view_desc = t::RenderDesc { + channel: format.1, + level: 0, + layer: None, + }; + + self.view_texture_as_render_target_raw(&tex, view_desc) + } + } impl Drop for Factory { @@ -220,47 +288,8 @@ impl core::Factory for Factory { fn view_texture_as_shader_resource_raw(&mut self, htex: &h::RawTexture, desc: core::tex::ResourceDesc) -> Result, f::ResourceViewError> { use gfx_core::handle::Producer; - - let raw_tex = self.frame_handles.ref_texture(htex); - let td = htex.get_info(); - let info = vk::ImageViewCreateInfo { - sType: vk::STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - pNext: ptr::null(), - flags: 0, - image: raw_tex.image, - viewType: match data::map_image_view_type(td.kind, desc.layer) { - Ok(vt) => vt, - Err(e) => return Err(f::ResourceViewError::Layer(e)), - }, - format: match data::map_format(td.format, desc.channel) { - Some(f) => f, - None => return Err(f::ResourceViewError::Channel(desc.channel)), - }, - components: vk::ComponentMapping { - r: vk::COMPONENT_SWIZZLE_R, - g: vk::COMPONENT_SWIZZLE_G, - b: vk::COMPONENT_SWIZZLE_B, - a: vk::COMPONENT_SWIZZLE_A, - }, - subresourceRange: vk::ImageSubresourceRange { - aspectMask: data::map_image_aspect(td.format, desc.channel), - baseMipLevel: desc.min as u32, - levelCount: (desc.max + 1 - desc.min) as u32, - baseArrayLayer: desc.layer.unwrap_or(0) as u32, - layerCount: match desc.layer { - Some(_) => 1, - None => td.kind.get_num_slices().unwrap_or(1) as u32, - }, - }, - }; - - let (dev, vk) = self.share.get_device(); - let view = unsafe { - let mut out = mem::zeroed(); - assert_eq!(vk::SUCCESS, vk.CreateImageView(dev, &info, ptr::null(), &mut out)); - out - }; - Ok(self.share.handles.borrow_mut().make_texture_srv(view, htex)) + self.view_texture(htex, desc, false).map(|view| + self.share.handles.borrow_mut().make_texture_srv(view, htex)) } fn view_texture_as_unordered_access_raw(&mut self, _htex: &h::RawTexture) @@ -268,10 +297,28 @@ impl core::Factory for Factory { Err(f::ResourceViewError::Unsupported) //TODO } - fn view_texture_as_render_target_raw(&mut self, _htex: &h::RawTexture, _desc: core::tex::RenderDesc) + fn view_texture_as_render_target_raw(&mut self, htex: &h::RawTexture, desc: core::tex::RenderDesc) -> Result, f::TargetViewError> { - unimplemented!() + use gfx_core::handle::Producer; + let rdesc = core::tex::ResourceDesc { + channel: desc.channel, + layer: desc.layer, + min: 0, + max: 0, + swizzle: core::format::Swizzle::new(), + }; + let mut dim = htex.get_info().kind.get_dimensions(); + if rdesc.layer.is_some() { + dim.2 = 1; // slice of the depth/array + } + match self.view_texture(htex, rdesc, true) { + Ok(view) => Ok(self.share.handles.borrow_mut().make_rtv(view, htex, dim)), + Err(f::ResourceViewError::NoBindFlag) => Err(f::TargetViewError::NoBindFlag), + Err(f::ResourceViewError::Channel(ct)) => Err(f::TargetViewError::Channel(ct)), + Err(f::ResourceViewError::Layer(le)) => Err(f::TargetViewError::Layer(le)), + Err(f::ResourceViewError::Unsupported) => Err(f::TargetViewError::Unsupported), + } } fn view_texture_as_depth_stencil_raw(&mut self, _htex: &h::RawTexture, _desc: core::tex::DepthStencilDesc) diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index 6f32542f67d..63a5c4a9580 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -267,7 +267,7 @@ impl gfx_core::Resources for Resources { type Texture = native::Texture; type ShaderResourceView = vk::ImageView; //TODO: buffer view type UnorderedAccessView = (); - type RenderTargetView = (); + type RenderTargetView = vk::ImageView; type DepthStencilView = (); type Sampler = vk::Sampler; type Fence = (); From 0a245375d3ed5ab1511194581c734ffa1953316d Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Tue, 17 May 2016 00:32:22 -0400 Subject: [PATCH 27/69] [vk] creating swapchain target views --- src/window/vulkan/src/lib.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/window/vulkan/src/lib.rs b/src/window/vulkan/src/lib.rs index 2df3e32d767..e73bc217eb4 100644 --- a/src/window/vulkan/src/lib.rs +++ b/src/window/vulkan/src/lib.rs @@ -19,6 +19,7 @@ extern crate gfx_core; extern crate gfx_device_vulkan; use std::{mem, ptr}; +use gfx_core::format; pub fn init_winit(builder: winit::WindowBuilder) -> (winit::Window, gfx_device_vulkan::GraphicsQueue, gfx_device_vulkan::Factory) { @@ -33,7 +34,7 @@ pub struct Window { _foreground: u32, window: u32, _swapchain: vk::SwapchainKHR, - _images: Vec, + _targets: Vec>, } impl Window { @@ -60,7 +61,7 @@ impl Drop for Window { } pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vulkan::GraphicsQueue, gfx_device_vulkan::Factory) { - let (device, factory, backend) = gfx_device_vulkan::create(title, 1, &[], + let (device, mut factory, backend) = gfx_device_vulkan::create(title, 1, &[], &["VK_KHR_surface", "VK_KHR_xcb_surface"], &["VK_KHR_swapchain"]); let (conn, screen_num) = xcb::Connection::connect(None).unwrap(); @@ -117,7 +118,7 @@ pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vul let mut images: [vk::Image; 2] = [0; 2]; let mut num = images.len() as u32; - let info = vk::SwapchainCreateInfoKHR { + let swapchain_info = vk::SwapchainCreateInfoKHR { sType: vk::STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, pNext: ptr::null(), flags: 0, @@ -140,7 +141,7 @@ pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vul let swapchain = unsafe { let mut out = mem::zeroed(); - assert_eq!(vk::SUCCESS, vk.CreateSwapchainKHR(dev, &info, ptr::null(), &mut out)); + assert_eq!(vk::SUCCESS, vk.CreateSwapchainKHR(dev, &swapchain_info, ptr::null(), &mut out)); out }; @@ -148,12 +149,19 @@ pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vul vk.GetSwapchainImagesKHR(dev, swapchain, &mut num, images.as_mut_ptr()) }); + let format = format::Format(format::SurfaceType::R8_G8_B8_A8, format::ChannelType::Unorm); + let targets = images[.. num as usize].iter().map(|image| { + use gfx_core::factory::Typed; + let raw_view = factory.view_swapchain_image(*image, format, (width, height)).unwrap(); + Typed::new(raw_view) + }).collect(); + let win = Window { connection: conn, _foreground: foreground, window: window, _swapchain: swapchain, - _images: images[..num as usize].to_vec(), + _targets: targets, }; (win, device, factory) } From ea25e88af55253179b4a0b08b6c807eb661f7a9d Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Tue, 17 May 2016 23:11:56 -0400 Subject: [PATCH 28/69] [vk] frame and swapchain mechanics --- src/backend/vulkan/src/command.rs | 10 +++- src/backend/vulkan/src/factory.rs | 15 +++++- src/backend/vulkan/src/lib.rs | 2 +- src/window/vulkan/src/lib.rs | 87 ++++++++++++++++++++++++++----- 4 files changed, 99 insertions(+), 15 deletions(-) diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs index 03d37008576..a07a877a734 100644 --- a/src/backend/vulkan/src/command.rs +++ b/src/backend/vulkan/src/command.rs @@ -18,7 +18,7 @@ use gfx_core::{self as core, draw, pso, shade, target, tex}; use gfx_core::state::RefValues; use gfx_core::{IndexType, VertexCount}; use native; -use {Resources, SharePointer}; +use {Resources, Share, SharePointer}; pub struct Buffer { @@ -94,6 +94,14 @@ impl GraphicsQueue { capabilities: caps, } } + #[doc(hidden)] + pub fn get_share(&self) -> &Share { + &self.share + } + #[doc(hidden)] + pub fn get_queue(&self) -> vk::Queue { + self.queue + } } impl core::Device for GraphicsQueue { diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index 30b24cf6cc9..e967e0faf89 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -50,7 +50,7 @@ impl Factory { let com_info = vk::CommandPoolCreateInfo { sType: vk::STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, pNext: ptr::null(), - flags: 0, + flags: vk::COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex: qf_index, }; let com_pool = unsafe { @@ -156,6 +156,19 @@ impl Factory { self.view_texture_as_render_target_raw(&tex, view_desc) } + pub fn create_fence(&mut self, signalled: bool) -> vk::Fence { + let info = vk::FenceCreateInfo { + sType: vk::STRUCTURE_TYPE_FENCE_CREATE_INFO, + pNext: ptr::null(), + flags: if signalled { vk::FENCE_CREATE_SIGNALED_BIT } else { 0 }, + }; + let (dev, vk) = self.share.get_device(); + unsafe { + let mut out = mem::zeroed(); + assert_eq!(vk::SUCCESS, vk.CreateFence(dev, &info, ptr::null(), &mut out)); + out + } + } } impl Drop for Factory { diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index 63a5c4a9580..d6309212cbc 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -270,5 +270,5 @@ impl gfx_core::Resources for Resources { type RenderTargetView = vk::ImageView; type DepthStencilView = (); type Sampler = vk::Sampler; - type Fence = (); + type Fence = vk::Fence; } diff --git a/src/window/vulkan/src/lib.rs b/src/window/vulkan/src/lib.rs index e73bc217eb4..b0654c5219d 100644 --- a/src/window/vulkan/src/lib.rs +++ b/src/window/vulkan/src/lib.rs @@ -29,25 +29,83 @@ pub fn init_winit(builder: winit::WindowBuilder) -> (winit::Window, gfx_device_v (win, device, factory) } +pub type TargetHandle = gfx_core::handle::RenderTargetView; + +pub struct SwapTarget { + _image: vk::Image, + target: TargetHandle, + _fence: vk::Fence, +} + pub struct Window { connection: xcb::Connection, _foreground: u32, window: u32, - _swapchain: vk::SwapchainKHR, - _targets: Vec>, + swapchain: vk::SwapchainKHR, + targets: Vec, + queue: gfx_device_vulkan::GraphicsQueue, +} + +pub struct Frame<'a> { + window: &'a mut Window, + target_id: u32, +} + +impl<'a> Frame<'a> { + pub fn get_target(&self) -> TargetHandle { + self.window.targets[self.target_id as usize].target.clone() + } + pub fn get_queue(&mut self) -> &mut gfx_device_vulkan::GraphicsQueue { + &mut self.window.queue + } +} + +impl<'a> Drop for Frame<'a> { + fn drop(&mut self) { + let mut result = vk::SUCCESS; + let info = vk::PresentInfoKHR { + sType: vk::STRUCTURE_TYPE_PRESENT_INFO_KHR, + pNext: ptr::null(), + waitSemaphoreCount: 0, + pWaitSemaphores: ptr::null(), + swapchainCount: 1, + pSwapchains: &self.window.swapchain, + pImageIndices: &self.target_id, + pResults: &mut result, + }; + let (_dev, vk) = self.window.queue.get_share().get_device(); + unsafe { + vk.QueuePresentKHR(self.window.queue.get_queue(), &info); + } + assert_eq!(vk::SUCCESS, result); + } } impl Window { - pub fn wait_draw(&mut self) -> Option { + pub fn wait_draw(&mut self) -> Result, ()> { let ev = match self.connection.wait_for_event() { Some(ev) => ev, - None => return None, + None => return Err(()), }; //self.connection.flush(); match ev.response_type() & 0x80 { - xcb::EXPOSE => Some(true), - xcb::KEY_PRESS => None, - _ => Some(false) + xcb::EXPOSE => Ok(Some(self.start_frame())), + xcb::KEY_PRESS => Err(()), + _ => Ok(None) + } + } + + pub fn start_frame(&mut self) -> Frame { + //TODO: handle window resize + let index = unsafe { + let (dev, vk) = self.queue.get_share().get_device(); + let mut i = 0; + vk.AcquireNextImageKHR(dev, self.swapchain, 60, 0, 0, &mut i); + i + }; + Frame { + window: self, + target_id: index, } } } @@ -60,7 +118,7 @@ impl Drop for Window { } } -pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vulkan::GraphicsQueue, gfx_device_vulkan::Factory) { +pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vulkan::Factory) { let (device, mut factory, backend) = gfx_device_vulkan::create(title, 1, &[], &["VK_KHR_surface", "VK_KHR_xcb_surface"], &["VK_KHR_swapchain"]); @@ -153,15 +211,20 @@ pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vul let targets = images[.. num as usize].iter().map(|image| { use gfx_core::factory::Typed; let raw_view = factory.view_swapchain_image(*image, format, (width, height)).unwrap(); - Typed::new(raw_view) + SwapTarget { + _image: *image, + target: Typed::new(raw_view), + _fence: factory.create_fence(true), + } }).collect(); let win = Window { connection: conn, _foreground: foreground, window: window, - _swapchain: swapchain, - _targets: targets, + swapchain: swapchain, + targets: targets, + queue: device, }; - (win, device, factory) + (win, factory) } From ce254ebd10c9a37c16456f813658bc4c185f8eff Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Wed, 18 May 2016 00:00:55 -0400 Subject: [PATCH 29/69] [vk] image barriers for the presentable layouts --- src/backend/vulkan/src/command.rs | 48 +++++++++++++++++++++++++++++-- src/backend/vulkan/src/factory.rs | 9 ++++-- src/backend/vulkan/src/lib.rs | 2 +- src/window/vulkan/src/lib.rs | 14 +++++++-- 4 files changed, 64 insertions(+), 9 deletions(-) diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs index a07a877a734..5c49405fb5a 100644 --- a/src/backend/vulkan/src/command.rs +++ b/src/backend/vulkan/src/command.rs @@ -23,13 +23,17 @@ use {Resources, Share, SharePointer}; pub struct Buffer { inner: vk::CommandBuffer, + family: u32, + share: SharePointer, } impl Buffer { #[doc(hidden)] - pub fn new(b: vk::CommandBuffer) -> Buffer { + pub fn new(b: vk::CommandBuffer, f: u32, s: SharePointer) -> Buffer { Buffer { inner: b, + family: f, + share: s, } } } @@ -40,6 +44,43 @@ impl Drop for Buffer { } } +impl Buffer { + pub fn image_barrier(&mut self, image: vk::Image, aspect: vk::ImageAspectFlags, + old_layout: vk::ImageLayout, new_layout: vk::ImageLayout) { + let barrier = vk::ImageMemoryBarrier { + sType: vk::STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + pNext: ptr::null(), + srcAccessMask: if old_layout == vk::IMAGE_LAYOUT_PREINITIALIZED || new_layout == vk::IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL { + vk::ACCESS_HOST_WRITE_BIT | vk::ACCESS_TRANSFER_WRITE_BIT + } else {0}, + dstAccessMask: match new_layout { + vk::IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL | vk::IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL => + vk::ACCESS_TRANSFER_READ_BIT | vk::ACCESS_HOST_WRITE_BIT | vk::ACCESS_TRANSFER_WRITE_BIT, + vk::IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL => vk::ACCESS_SHADER_READ_BIT, + _ => 0, + }, + oldLayout: old_layout, + newLayout: new_layout, + srcQueueFamilyIndex: self.family, + dstQueueFamilyIndex: self.family, + image: image, + subresourceRange: vk::ImageSubresourceRange { + aspectMask: aspect, + baseMipLevel: 0, + levelCount: 1, + baseArrayLayer: 0, + layerCount: 1, + }, + }; + let (_dev, vk) = self.share.get_device(); + unsafe { + vk.CmdPipelineBarrier(self.inner, + vk::PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, + 0, ptr::null(), 0, ptr::null(), 1, &barrier); + } + } +} + impl draw::CommandBuffer for Buffer { fn reset(&mut self) {} fn bind_pipeline_state(&mut self, _: ()) {} @@ -68,13 +109,14 @@ impl draw::CommandBuffer for Buffer { pub struct GraphicsQueue { share: SharePointer, + family: u32, queue: vk::Queue, capabilities: core::Capabilities, } impl GraphicsQueue { #[doc(hidden)] - pub fn new(share: SharePointer, q: vk::Queue) -> GraphicsQueue { + pub fn new(share: SharePointer, q: vk::Queue, qf_id: u32) -> GraphicsQueue { let caps = core::Capabilities { max_vertex_count: 0, max_index_count: 0, @@ -90,6 +132,7 @@ impl GraphicsQueue { }; GraphicsQueue { share: share, + family: qf_id, queue: q, capabilities: caps, } @@ -115,6 +158,7 @@ impl core::Device for GraphicsQueue { fn pin_submitted_resources(&mut self, _: &core::handle::Manager) {} fn submit(&mut self, com: &mut Buffer) { + assert_eq!(self.family, com.family); let (_, vk) = self.share.get_device(); assert_eq!(vk::SUCCESS, unsafe { vk.EndCommandBuffer(com.inner) diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index e967e0faf89..759b7e067f5 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -41,6 +41,7 @@ impl core::mapping::Raw for RawMapping { pub struct Factory { share: SharePointer, + qf_index: u32, command_pool: vk::CommandPool, frame_handles: h::Manager, } @@ -61,6 +62,7 @@ impl Factory { }; Factory { share: share, + qf_index: qf_index, command_pool: com_pool, frame_handles: h::Manager::new(), } @@ -81,12 +83,13 @@ impl Factory { pInheritanceInfo: ptr::null(), }; let (dev, vk) = self.share.get_device(); - unsafe { + let buf = unsafe { let mut out = mem::zeroed(); assert_eq!(vk::SUCCESS, vk.AllocateCommandBuffers(dev, &alloc_info, &mut out)); assert_eq!(vk::SUCCESS, vk.BeginCommandBuffer(out, &begin_info)); - command::Buffer::new(out) - } + out + }; + command::Buffer::new(buf, self.qf_index, self.share.clone()) } fn view_texture(&mut self, htex: &h::RawTexture, desc: core::tex::ResourceDesc, is_target: bool) diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index d6309212cbc..886e6404908 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -214,7 +214,7 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& dev_pointers: dev_pointers, handles: RefCell::new(gfx_core::handle::Manager::new()), }); - let gfx_device = command::GraphicsQueue::new(share.clone(), queue); + let gfx_device = command::GraphicsQueue::new(share.clone(), queue, qf_id as u32); let gfx_factory = factory::Factory::new(share.clone(), qf_id as u32); (gfx_device, gfx_factory, share) diff --git a/src/window/vulkan/src/lib.rs b/src/window/vulkan/src/lib.rs index b0654c5219d..7f8d545b02f 100644 --- a/src/window/vulkan/src/lib.rs +++ b/src/window/vulkan/src/lib.rs @@ -88,7 +88,7 @@ impl Window { None => return Err(()), }; //self.connection.flush(); - match ev.response_type() & 0x80 { + match ev.response_type() & 0x7F { xcb::EXPOSE => Ok(Some(self.start_frame())), xcb::KEY_PRESS => Err(()), _ => Ok(None) @@ -100,7 +100,7 @@ impl Window { let index = unsafe { let (dev, vk) = self.queue.get_share().get_device(); let mut i = 0; - vk.AcquireNextImageKHR(dev, self.swapchain, 60, 0, 0, &mut i); + assert_eq!(vk::SUCCESS, vk.AcquireNextImageKHR(dev, self.swapchain, 60, 0, 0, &mut i)); i }; Frame { @@ -119,7 +119,7 @@ impl Drop for Window { } pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vulkan::Factory) { - let (device, mut factory, backend) = gfx_device_vulkan::create(title, 1, &[], + let (mut device, mut factory, backend) = gfx_device_vulkan::create(title, 1, &[], &["VK_KHR_surface", "VK_KHR_xcb_surface"], &["VK_KHR_swapchain"]); let (conn, screen_num) = xcb::Connection::connect(None).unwrap(); @@ -207,9 +207,12 @@ pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vul vk.GetSwapchainImagesKHR(dev, swapchain, &mut num, images.as_mut_ptr()) }); + let mut cbuf = factory.create_command_buffer(); + let format = format::Format(format::SurfaceType::R8_G8_B8_A8, format::ChannelType::Unorm); let targets = images[.. num as usize].iter().map(|image| { use gfx_core::factory::Typed; + cbuf.image_barrier(*image, vk::IMAGE_ASPECT_COLOR_BIT, vk::IMAGE_LAYOUT_UNDEFINED, vk::IMAGE_LAYOUT_PRESENT_SRC_KHR); let raw_view = factory.view_swapchain_image(*image, format, (width, height)).unwrap(); SwapTarget { _image: *image, @@ -218,6 +221,11 @@ pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vul } }).collect(); + { + use gfx_core::Device; + device.submit(&mut cbuf); + } + let win = Window { connection: conn, _foreground: foreground, From 67529f4387155bf80e29745aa44f79353e3413d3 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Wed, 18 May 2016 23:10:44 -0400 Subject: [PATCH 30/69] [vk] extended RTV/SRV to also carry the layout and sub range --- src/backend/vulkan/src/command.rs | 8 ++++---- src/backend/vulkan/src/factory.rs | 19 +++++++++++++++---- src/backend/vulkan/src/lib.rs | 4 ++-- src/backend/vulkan/src/native.rs | 22 ++++++++++++++++++++-- 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs index 5c49405fb5a..e50d007570b 100644 --- a/src/backend/vulkan/src/command.rs +++ b/src/backend/vulkan/src/command.rs @@ -97,8 +97,8 @@ impl draw::CommandBuffer for Buffer { fn update_buffer(&mut self, _: (), _: &[u8], _: usize) {} fn update_texture(&mut self, _: native::Texture, _: tex::Kind, _: Option, _: &[u8], _: tex::RawImageInfo) {} - fn generate_mipmap(&mut self, _: vk::ImageView) {} - fn clear_color(&mut self, _: vk::ImageView, _: draw::ClearColor) {} + fn generate_mipmap(&mut self, _: native::TextureView) {} + fn clear_color(&mut self, _: native::TextureView, _: draw::ClearColor) {} fn clear_depth_stencil(&mut self, _: (), _: Option, _: Option) {} fn call_draw(&mut self, _: VertexCount, _: VertexCount, _: draw::InstanceOption) {} @@ -199,11 +199,11 @@ impl core::Device for GraphicsQueue { vk.FreeMemory(dev, t.memory, ptr::null()); }}, |vk, v| unsafe { //SRV - vk.DestroyImageView(dev, *v, ptr::null()); + vk.DestroyImageView(dev, v.view, ptr::null()); }, |_, _| (), //UAV |vk, v| unsafe { //RTV - vk.DestroyImageView(dev, *v, ptr::null()); + vk.DestroyImageView(dev, v.view, ptr::null()); }, |_, _v| (), //DSV |_, _v| (), //sampler diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index 759b7e067f5..1eb0b535db2 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::{mem, ptr, slice}; +use std::{cell, mem, ptr, slice}; use std::os::raw::c_void; use gfx_core::{self as core, handle as h, factory as f, state}; use vk; @@ -93,7 +93,7 @@ impl Factory { } fn view_texture(&mut self, htex: &h::RawTexture, desc: core::tex::ResourceDesc, is_target: bool) - -> Result { + -> Result { let raw_tex = self.frame_handles.ref_texture(htex); let td = htex.get_info(); let info = vk::ImageViewCreateInfo { @@ -123,10 +123,16 @@ impl Factory { }; let (dev, vk) = self.share.get_device(); - Ok(unsafe { + let view = unsafe { let mut out = mem::zeroed(); assert_eq!(vk::SUCCESS, vk.CreateImageView(dev, &info, ptr::null(), &mut out)); out + }; + Ok(native::TextureView { + image: raw_tex.image, + view: view, + layout: raw_tex.layout.get(), //care! + sub_range: info.subresourceRange, }) } @@ -140,6 +146,7 @@ impl Factory { let raw_tex = native::Texture { image: image, + layout: cell::Cell::new(vk::IMAGE_LAYOUT_GENERAL), memory: 0, }; let tex_desc = t::Descriptor { @@ -286,7 +293,11 @@ impl core::Factory for Factory { let mut mem = mem::zeroed(); assert_eq!(vk::SUCCESS, vk.AllocateMemory(dev, &alloc_info, ptr::null(), &mut mem)); assert_eq!(vk::SUCCESS, vk.BindImageMemory(dev, image, mem, 0)); - native::Texture { image: image, memory: mem } + native::Texture { + image: image, + layout: cell::Cell::new(image_info.initialLayout), + memory: mem, + } }; Ok(self.share.handles.borrow_mut().make_texture(tex, desc)) } diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index 886e6404908..33e3df94488 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -265,9 +265,9 @@ impl gfx_core::Resources for Resources { type Program = (); type PipelineStateObject = (); type Texture = native::Texture; - type ShaderResourceView = vk::ImageView; //TODO: buffer view + type ShaderResourceView = native::TextureView; //TODO: buffer view type UnorderedAccessView = (); - type RenderTargetView = vk::ImageView; + type RenderTargetView = native::TextureView; type DepthStencilView = (); type Sampler = vk::Sampler; type Fence = vk::Fence; diff --git a/src/backend/vulkan/src/native.rs b/src/backend/vulkan/src/native.rs index a02742682ad..c7753d21d15 100644 --- a/src/backend/vulkan/src/native.rs +++ b/src/backend/vulkan/src/native.rs @@ -13,7 +13,7 @@ // limitations under the License. use std::ffi::CStr; -use std::{fmt, hash}; +use std::{cell, fmt, hash}; use vk; //Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync; @@ -56,10 +56,28 @@ unsafe impl Send for Shader {} unsafe impl Sync for Shader {} -#[derive(Clone, Debug, Hash, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq)] pub struct Texture { pub image: vk::Image, + pub layout: cell::Cell, pub memory: vk::DeviceMemory, } +impl hash::Hash for Texture { + fn hash(&self, state: &mut H) where H: hash::Hasher { + self.image.hash(state); + self.layout.get().hash(state); + self.memory.hash(state); + } +} unsafe impl Send for Texture {} unsafe impl Sync for Texture {} + +#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)] +pub struct TextureView { + pub image: vk::Image, + pub view: vk::ImageView, + pub layout: vk::ImageLayout, + pub sub_range: vk::ImageSubresourceRange, +} +unsafe impl Send for TextureView {} +unsafe impl Sync for TextureView {} From c06425c73a8306047de5cd6dcecf0ecf6688e8c5 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Thu, 19 May 2016 00:04:46 -0400 Subject: [PATCH 31/69] [vk] color clear command --- src/backend/vulkan/src/command.rs | 15 ++++++++++++++- src/backend/vulkan/src/lib.rs | 8 ++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs index e50d007570b..5dc75401978 100644 --- a/src/backend/vulkan/src/command.rs +++ b/src/backend/vulkan/src/command.rs @@ -98,9 +98,22 @@ impl draw::CommandBuffer for Buffer { fn update_texture(&mut self, _: native::Texture, _: tex::Kind, _: Option, _: &[u8], _: tex::RawImageInfo) {} fn generate_mipmap(&mut self, _: native::TextureView) {} - fn clear_color(&mut self, _: native::TextureView, _: draw::ClearColor) {} + + fn clear_color(&mut self, tv: native::TextureView, color: draw::ClearColor) { + let (_, vk) = self.share.get_device(); + let value = match color { + draw::ClearColor::Float(v) => vk::ClearColorValue::float32(v), + draw::ClearColor::Int(v) => vk::ClearColorValue::int32(v), + draw::ClearColor::Uint(v) => vk::ClearColorValue::uint32(v), + }; + unsafe { + vk.CmdClearColorImage(self.inner, tv.image, tv.layout, &value, 1, &tv.sub_range); + } + } + fn clear_depth_stencil(&mut self, _: (), _: Option, _: Option) {} + fn call_draw(&mut self, _: VertexCount, _: VertexCount, _: draw::InstanceOption) {} fn call_draw_indexed(&mut self, _: VertexCount, _: VertexCount, _: VertexCount, _: draw::InstanceOption) {} diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index 33e3df94488..7489aa22551 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -161,11 +161,11 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& info!("Chosen physical device {:p} with queue family {}", ph_dev as *const (), qf_id); let device = { - let cstrings = layers.iter().chain(dev_extensions.iter()) - .map(|&s| CString::new(s).unwrap()) - .collect::>(); + let cstrings = dev_extensions.iter() + .map(|&s| CString::new(s).unwrap()) + .collect::>(); let str_pointers = cstrings.iter().map(|s| s.as_ptr()) - .collect::>(); + .collect::>(); let queue_info = vk::DeviceQueueCreateInfo { sType: vk::STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, From a4686b78027360fc3e38ba233eda3d77792b8911 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Thu, 19 May 2016 00:05:01 -0400 Subject: [PATCH 32/69] [vk] validation layers support --- src/window/vulkan/src/lib.rs | 60 ++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/src/window/vulkan/src/lib.rs b/src/window/vulkan/src/lib.rs index 7f8d545b02f..7438ff24411 100644 --- a/src/window/vulkan/src/lib.rs +++ b/src/window/vulkan/src/lib.rs @@ -18,7 +18,9 @@ extern crate vk_sys as vk; extern crate gfx_core; extern crate gfx_device_vulkan; +use std::ffi::CStr; use std::{mem, ptr}; +use std::os::raw; use gfx_core::format; @@ -41,6 +43,7 @@ pub struct Window { connection: xcb::Connection, _foreground: u32, window: u32, + _debug_callback: Option, swapchain: vk::SwapchainKHR, targets: Vec, queue: gfx_device_vulkan::GraphicsQueue, @@ -118,9 +121,61 @@ impl Drop for Window { } } +const LAYERS: &'static [&'static str] = &[ +]; +const LAYERS_DEBUG: &'static [&'static str] = &[ + "VK_LAYER_LUNARG_standard_validation", +]; +const EXTENSIONS: &'static [&'static str] = &[ + "VK_KHR_surface", + "VK_KHR_xcb_surface", +]; +const EXTENSIONS_DEBUG: &'static [&'static str] = &[ + "VK_KHR_surface", + "VK_KHR_xcb_surface", + "VK_EXT_debug_report", +]; +const DEV_EXTENSIONS: &'static [&'static str] = &[ + "VK_KHR_swapchain", +]; + +extern "system" fn callback(flags: vk::DebugReportFlagsEXT, + _ob_type: vk::DebugReportObjectTypeEXT, _object: u64, _location: usize, + _msg_code: i32, layer_prefix_c: *const raw::c_char, + description_c: *const raw::c_char, _user_data: *mut raw::c_void) -> u32 +{ + let layer_prefix = unsafe { CStr::from_ptr(layer_prefix_c) }.to_str().unwrap(); + let description = unsafe { CStr::from_ptr(description_c) }.to_str().unwrap(); + println!("Vk flags {:x} in layer {}: {}", flags, layer_prefix, description); + vk::FALSE +} + pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vulkan::Factory) { - let (mut device, mut factory, backend) = gfx_device_vulkan::create(title, 1, &[], - &["VK_KHR_surface", "VK_KHR_xcb_surface"], &["VK_KHR_swapchain"]); + let debug = true; + let (mut device, mut factory, backend) = gfx_device_vulkan::create(title, 1, + if debug {LAYERS_DEBUG} else {LAYERS}, + if debug {EXTENSIONS_DEBUG} else {EXTENSIONS}, + DEV_EXTENSIONS); + + let debug_callback = if debug { + let info = vk::DebugReportCallbackCreateInfoEXT { + sType: vk::STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT, + pNext: ptr::null(), + flags: vk::DEBUG_REPORT_INFORMATION_BIT_EXT | vk::DEBUG_REPORT_WARNING_BIT_EXT | + vk::DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT | vk::DEBUG_REPORT_ERROR_BIT_EXT | + vk::DEBUG_REPORT_DEBUG_BIT_EXT, + pfnCallback: callback, + pUserData: ptr::null_mut(), + }; + let (inst, vk) = backend.get_instance(); + Some(unsafe { + let mut out = mem::zeroed(); + assert_eq!(vk::SUCCESS, vk.CreateDebugReportCallbackEXT(inst, &info, ptr::null(), &mut out)); + out + }) + }else { + None + }; let (conn, screen_num) = xcb::Connection::connect(None).unwrap(); let (window, foreground) = { @@ -230,6 +285,7 @@ pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vul connection: conn, _foreground: foreground, window: window, + _debug_callback: debug_callback, swapchain: swapchain, targets: targets, queue: device, From a9c47e0a4be43b4a054715390df700fb41186a6b Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Thu, 19 May 2016 23:02:40 -0400 Subject: [PATCH 33/69] [vk] querying proper memory types --- src/backend/vulkan/src/command.rs | 1 + src/backend/vulkan/src/factory.rs | 18 +++++++++++++----- src/backend/vulkan/src/lib.rs | 23 +++++++++++++++-------- src/window/vulkan/src/lib.rs | 9 +++++---- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs index 5dc75401978..eff1bbba361 100644 --- a/src/backend/vulkan/src/command.rs +++ b/src/backend/vulkan/src/command.rs @@ -196,6 +196,7 @@ impl core::Device for GraphicsQueue { }); } + //note: this should really live elsewhere (Factory?) fn cleanup(&mut self) { let (dev, mut functions) = self.share.get_device(); use gfx_core::handle::Producer; diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index 1eb0b535db2..9bec7d2ce45 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -41,13 +41,15 @@ impl core::mapping::Raw for RawMapping { pub struct Factory { share: SharePointer, - qf_index: u32, + queue_family_index: u32, + mem_video_id: u32, + mem_system_id: u32, command_pool: vk::CommandPool, frame_handles: h::Manager, } impl Factory { - pub fn new(share: SharePointer, qf_index: u32) -> Factory { + pub fn new(share: SharePointer, qf_index: u32, mvid: u32, msys: u32) -> Factory { let com_info = vk::CommandPoolCreateInfo { sType: vk::STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, pNext: ptr::null(), @@ -62,7 +64,9 @@ impl Factory { }; Factory { share: share, - qf_index: qf_index, + queue_family_index: qf_index, + mem_video_id: mvid, + mem_system_id: msys, command_pool: com_pool, frame_handles: h::Manager::new(), } @@ -89,7 +93,7 @@ impl Factory { assert_eq!(vk::SUCCESS, vk.BeginCommandBuffer(out, &begin_info)); out }; - command::Buffer::new(buf, self.qf_index, self.share.clone()) + command::Buffer::new(buf, self.queue_family_index, self.share.clone()) } fn view_texture(&mut self, htex: &h::RawTexture, desc: core::tex::ResourceDesc, is_target: bool) @@ -281,7 +285,11 @@ impl core::Factory for Factory { sType: vk::STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, pNext: ptr::null(), allocationSize: 0, - memoryTypeIndex: 0, //TODO + memoryTypeIndex: if let f::Usage::CpuOnly(_) = desc.usage { + self.mem_system_id + }else { + self.mem_video_id + }, }; let (dev, vk) = self.share.get_device(); let tex = unsafe { diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index 7489aa22551..7f9f78508a7 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -27,7 +27,7 @@ pub use self::command::GraphicsQueue; pub use self::factory::Factory; mod command; -mod data; +pub mod data; mod factory; mod native; @@ -36,7 +36,7 @@ struct PhysicalDeviceInfo { device: vk::PhysicalDevice, _properties: vk::PhysicalDeviceProperties, queue_families: Vec, - _memory: vk::PhysicalDeviceMemoryProperties, + memory: vk::PhysicalDeviceMemoryProperties, _features: vk::PhysicalDeviceFeatures, } @@ -56,7 +56,7 @@ impl PhysicalDeviceInfo { families.set_len(num as usize); families }, - _memory: unsafe { + memory: unsafe { let mut out = mem::zeroed(); vk.GetPhysicalDeviceMemoryProperties(dev, &mut out); out @@ -154,11 +154,18 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& .map(|dev| PhysicalDeviceInfo::new(*dev, &inst_pointers)) .collect::>(); - let (ph_dev, (qf_id, _)) = devices.iter() - .flat_map(|d| iter::repeat(d.device).zip(d.queue_families.iter().enumerate())) + let (dev, (qf_id, _)) = devices.iter() + .flat_map(|d| iter::repeat(d).zip(d.queue_families.iter().enumerate())) .find(|&(_, (_, qf))| qf.queueFlags & vk::QUEUE_GRAPHICS_BIT != 0) .unwrap(); - info!("Chosen physical device {:p} with queue family {}", ph_dev as *const (), qf_id); + info!("Chosen physical device {:?} with queue family {}", dev.device, qf_id); + + let mvid_id = dev.memory.memoryTypes.iter().take(dev.memory.memoryTypeCount as usize) + .position(|mt| mt.propertyFlags & vk::MEMORY_PROPERTY_DEVICE_LOCAL_BIT != 0) + .unwrap() as u32; + let msys_id = dev.memory.memoryTypes.iter().take(dev.memory.memoryTypeCount as usize) + .position(|mt| mt.propertyFlags & vk::MEMORY_PROPERTY_HOST_COHERENT_BIT != 0) + .unwrap() as u32; let device = { let cstrings = dev_extensions.iter() @@ -191,7 +198,7 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& }; unsafe { let mut out = mem::zeroed(); - assert_eq!(vk::SUCCESS, inst_pointers.CreateDevice(ph_dev, &dev_info, ptr::null(), &mut out)); + assert_eq!(vk::SUCCESS, inst_pointers.CreateDevice(dev.device, &dev_info, ptr::null(), &mut out)); out } }; @@ -215,7 +222,7 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& handles: RefCell::new(gfx_core::handle::Manager::new()), }); let gfx_device = command::GraphicsQueue::new(share.clone(), queue, qf_id as u32); - let gfx_factory = factory::Factory::new(share.clone(), qf_id as u32); + let gfx_factory = factory::Factory::new(share.clone(), qf_id as u32, mvid_id, msys_id); (gfx_device, gfx_factory, share) } diff --git a/src/window/vulkan/src/lib.rs b/src/window/vulkan/src/lib.rs index 7438ff24411..adb28580552 100644 --- a/src/window/vulkan/src/lib.rs +++ b/src/window/vulkan/src/lib.rs @@ -31,7 +31,8 @@ pub fn init_winit(builder: winit::WindowBuilder) -> (winit::Window, gfx_device_v (win, device, factory) } -pub type TargetHandle = gfx_core::handle::RenderTargetView; +pub type TargetFormat = format::Srgba8; +pub type TargetHandle = gfx_core::handle::RenderTargetView; pub struct SwapTarget { _image: vk::Image, @@ -151,7 +152,7 @@ extern "system" fn callback(flags: vk::DebugReportFlagsEXT, } pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vulkan::Factory) { - let debug = true; + let debug = false; let (mut device, mut factory, backend) = gfx_device_vulkan::create(title, 1, if debug {LAYERS_DEBUG} else {LAYERS}, if debug {EXTENSIONS_DEBUG} else {EXTENSIONS}, @@ -230,6 +231,7 @@ pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vul let (dev, vk) = backend.get_device(); let mut images: [vk::Image; 2] = [0; 2]; let mut num = images.len() as u32; + let format = ::get_format(); let swapchain_info = vk::SwapchainCreateInfoKHR { sType: vk::STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, @@ -237,7 +239,7 @@ pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vul flags: 0, surface: surface, minImageCount: num, - imageFormat: vk::FORMAT_R8G8B8A8_UNORM, + imageFormat: gfx_device_vulkan::data::map_format(format.0, format.1).unwrap(), imageColorSpace: vk::COLORSPACE_SRGB_NONLINEAR_KHR, imageExtent: vk::Extent2D { width: width, height: height }, imageArrayLayers: 1, @@ -264,7 +266,6 @@ pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vul let mut cbuf = factory.create_command_buffer(); - let format = format::Format(format::SurfaceType::R8_G8_B8_A8, format::ChannelType::Unorm); let targets = images[.. num as usize].iter().map(|image| { use gfx_core::factory::Typed; cbuf.image_barrier(*image, vk::IMAGE_ASPECT_COLOR_BIT, vk::IMAGE_LAYOUT_UNDEFINED, vk::IMAGE_LAYOUT_PRESENT_SRC_KHR); From fb706e71be6010d0b56b258723e7c571be659367 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Thu, 19 May 2016 23:24:39 -0400 Subject: [PATCH 34/69] [vk] buffer creation and deletion --- src/backend/vulkan/src/command.rs | 9 ++-- src/backend/vulkan/src/factory.rs | 78 ++++++++++++++++++++++--------- src/backend/vulkan/src/lib.rs | 2 +- src/backend/vulkan/src/native.rs | 9 ++++ 4 files changed, 71 insertions(+), 27 deletions(-) diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs index eff1bbba361..ced4292fae4 100644 --- a/src/backend/vulkan/src/command.rs +++ b/src/backend/vulkan/src/command.rs @@ -91,10 +91,10 @@ impl draw::CommandBuffer for Buffer { fn bind_unordered_views(&mut self, _: &[pso::UnorderedViewParam]) {} fn bind_samplers(&mut self, _: &[pso::SamplerParam]) {} fn bind_pixel_targets(&mut self, _: pso::PixelTargetSet) {} - fn bind_index(&mut self, _: (), _: IndexType) {} + fn bind_index(&mut self, _: native::Buffer, _: IndexType) {} fn set_scissor(&mut self, _: target::Rect) {} fn set_ref_values(&mut self, _: RefValues) {} - fn update_buffer(&mut self, _: (), _: &[u8], _: usize) {} + fn update_buffer(&mut self, _: native::Buffer, _: &[u8], _: usize) {} fn update_texture(&mut self, _: native::Texture, _: tex::Kind, _: Option, _: &[u8], _: tex::RawImageInfo) {} fn generate_mipmap(&mut self, _: native::TextureView) {} @@ -202,7 +202,10 @@ impl core::Device for GraphicsQueue { use gfx_core::handle::Producer; //self.frame_handles.clear(); self.share.handles.borrow_mut().clean_with(&mut functions, - |_, _v| (), //buffer + |vk, b| unsafe { //buffer + vk.DestroyBuffer(dev, b.buffer, ptr::null()); + vk.FreeMemory(dev, b.memory, ptr::null()); + }, |vk, s| unsafe { //shader vk.DestroyShaderModule(dev, *s, ptr::null()); }, diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index 9bec7d2ce45..5eb48409c92 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -183,6 +183,25 @@ impl Factory { out } } + + fn alloc(&mut self, usage: f::Usage, size: vk::DeviceSize) -> vk::DeviceMemory { + let info = vk::MemoryAllocateInfo { + sType: vk::STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + pNext: ptr::null(), + allocationSize: size, + memoryTypeIndex: if let f::Usage::CpuOnly(_) = usage { + self.mem_system_id + }else { + self.mem_video_id + }, + }; + let (dev, vk) = self.share.get_device(); + unsafe { + let mut out = mem::zeroed(); + assert_eq!(vk::SUCCESS, vk.AllocateMemory(dev, &info, ptr::null(), &mut out)); + out + } + } } impl Drop for Factory { @@ -201,8 +220,30 @@ impl core::Factory for Factory { unimplemented!() } - fn create_buffer_raw(&mut self, _info: f::BufferInfo) -> Result, f::BufferError> { - unimplemented!() + fn create_buffer_raw(&mut self, info: f::BufferInfo) -> Result, f::BufferError> { + use gfx_core::handle::Producer; + let mem = self.alloc(info.usage, info.size as vk::DeviceSize); + let (usage, _) = data::map_usage_tiling(info.usage, info.bind); + let native_info = vk::BufferCreateInfo { + sType: vk::STRUCTURE_TYPE_BUFFER_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + size: info.size as vk::DeviceSize, + usage: usage, + sharingMode: vk::SHARING_MODE_EXCLUSIVE, + queueFamilyIndexCount: 1, + pQueueFamilyIndices: &self.queue_family_index, + }; + let (dev, vk) = self.share.get_device(); + let buf = native::Buffer { + buffer: unsafe { + let mut out = mem::zeroed(); + assert_eq!(vk::SUCCESS, vk.CreateBuffer(dev, &native_info, ptr::null(), &mut out)); + out + }, + memory: mem, + }; + Ok(self.share.handles.borrow_mut().make_buffer(buf, info)) } fn create_buffer_const_raw(&mut self, _data: &[u8], _stride: usize, _role: f::BufferRole, _bind: f::Bind) @@ -281,32 +322,23 @@ impl core::Factory for Factory { pQueueFamilyIndices: ptr::null(), initialLayout: data::map_image_layout(desc.bind), }; - let mut alloc_info = vk::MemoryAllocateInfo { - sType: vk::STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, - pNext: ptr::null(), - allocationSize: 0, - memoryTypeIndex: if let f::Usage::CpuOnly(_) = desc.usage { - self.mem_system_id - }else { - self.mem_video_id - }, - }; - let (dev, vk) = self.share.get_device(); - let tex = unsafe { + let (image, reqs) = unsafe { + let (dev, vk) = self.share.get_device(); let mut image = mem::zeroed(); assert_eq!(vk::SUCCESS, vk.CreateImage(dev, &image_info, ptr::null(), &mut image)); let mut reqs = mem::zeroed(); vk.GetImageMemoryRequirements(dev, image, &mut reqs); - alloc_info.allocationSize = reqs.size; - let mut mem = mem::zeroed(); - assert_eq!(vk::SUCCESS, vk.AllocateMemory(dev, &alloc_info, ptr::null(), &mut mem)); - assert_eq!(vk::SUCCESS, vk.BindImageMemory(dev, image, mem, 0)); - native::Texture { - image: image, - layout: cell::Cell::new(image_info.initialLayout), - memory: mem, - } + (image, reqs) + }; + let tex = native::Texture { + image: image, + layout: cell::Cell::new(image_info.initialLayout), + memory: self.alloc(desc.usage, reqs.size), }; + let (dev, vk) = self.share.get_device(); + assert_eq!(vk::SUCCESS, unsafe { + vk.BindImageMemory(dev, image, tex.memory, 0) + }); Ok(self.share.handles.borrow_mut().make_texture(tex, desc)) } diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index 7f9f78508a7..dc6a6dda41f 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -267,7 +267,7 @@ impl fmt::Debug for Error { pub enum Resources {} impl gfx_core::Resources for Resources { - type Buffer = (); + type Buffer = native::Buffer; type Shader = vk::ShaderModule; type Program = (); type PipelineStateObject = (); diff --git a/src/backend/vulkan/src/native.rs b/src/backend/vulkan/src/native.rs index c7753d21d15..ed699520222 100644 --- a/src/backend/vulkan/src/native.rs +++ b/src/backend/vulkan/src/native.rs @@ -56,6 +56,15 @@ unsafe impl Send for Shader {} unsafe impl Sync for Shader {} +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct Buffer { + pub buffer: vk::Buffer, + pub memory: vk::DeviceMemory, +} +unsafe impl Send for Buffer {} +unsafe impl Sync for Buffer {} + + #[derive(Clone, Debug, Eq, PartialEq)] pub struct Texture { pub image: vk::Image, From 28d1cf95275ac229b888f1539f5cf6001cbb1a17 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Thu, 19 May 2016 23:35:03 -0400 Subject: [PATCH 35/69] [vk] refined buffer memory allocation --- src/backend/vulkan/src/factory.rs | 32 +++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index 5eb48409c92..b542b98d5a9 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -184,11 +184,11 @@ impl Factory { } } - fn alloc(&mut self, usage: f::Usage, size: vk::DeviceSize) -> vk::DeviceMemory { + fn alloc(&self, usage: f::Usage, reqs: vk::MemoryRequirements) -> vk::DeviceMemory { let info = vk::MemoryAllocateInfo { sType: vk::STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, pNext: ptr::null(), - allocationSize: size, + allocationSize: reqs.size, memoryTypeIndex: if let f::Usage::CpuOnly(_) = usage { self.mem_system_id }else { @@ -222,7 +222,6 @@ impl core::Factory for Factory { fn create_buffer_raw(&mut self, info: f::BufferInfo) -> Result, f::BufferError> { use gfx_core::handle::Producer; - let mem = self.alloc(info.usage, info.size as vk::DeviceSize); let (usage, _) = data::map_usage_tiling(info.usage, info.bind); let native_info = vk::BufferCreateInfo { sType: vk::STRUCTURE_TYPE_BUFFER_CREATE_INFO, @@ -235,15 +234,21 @@ impl core::Factory for Factory { pQueueFamilyIndices: &self.queue_family_index, }; let (dev, vk) = self.share.get_device(); - let buf = native::Buffer { - buffer: unsafe { - let mut out = mem::zeroed(); - assert_eq!(vk::SUCCESS, vk.CreateBuffer(dev, &native_info, ptr::null(), &mut out)); - out - }, - memory: mem, + let (buf, reqs) = unsafe { + let mut buf = mem::zeroed(); + assert_eq!(vk::SUCCESS, vk.CreateBuffer(dev, &native_info, ptr::null(), &mut buf)); + let mut reqs = mem::zeroed(); + vk.GetBufferMemoryRequirements(dev, buf, &mut reqs); + (buf, reqs) }; - Ok(self.share.handles.borrow_mut().make_buffer(buf, info)) + let buffer = native::Buffer { + buffer: buf, + memory: self.alloc(info.usage, reqs), + }; + assert_eq!(vk::SUCCESS, unsafe { + vk.BindBufferMemory(dev, buf, buffer.memory, 0) + }); + Ok(self.share.handles.borrow_mut().make_buffer(buffer, info)) } fn create_buffer_const_raw(&mut self, _data: &[u8], _stride: usize, _role: f::BufferRole, _bind: f::Bind) @@ -322,8 +327,8 @@ impl core::Factory for Factory { pQueueFamilyIndices: ptr::null(), initialLayout: data::map_image_layout(desc.bind), }; + let (dev, vk) = self.share.get_device(); let (image, reqs) = unsafe { - let (dev, vk) = self.share.get_device(); let mut image = mem::zeroed(); assert_eq!(vk::SUCCESS, vk.CreateImage(dev, &image_info, ptr::null(), &mut image)); let mut reqs = mem::zeroed(); @@ -333,9 +338,8 @@ impl core::Factory for Factory { let tex = native::Texture { image: image, layout: cell::Cell::new(image_info.initialLayout), - memory: self.alloc(desc.usage, reqs.size), + memory: self.alloc(desc.usage, reqs), }; - let (dev, vk) = self.share.get_device(); assert_eq!(vk::SUCCESS, unsafe { vk.BindImageMemory(dev, image, tex.memory, 0) }); From 8f82b55d55e4726999f27e8a54a6c1dd3c71adb8 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Thu, 19 May 2016 23:43:40 -0400 Subject: [PATCH 36/69] [vk] first bits of pipelines --- src/backend/vulkan/src/command.rs | 2 +- src/backend/vulkan/src/factory.rs | 28 ++++++++++++++++++++++------ src/backend/vulkan/src/lib.rs | 2 +- src/backend/vulkan/src/native.rs | 7 +++++++ 4 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs index ced4292fae4..23e3caa9613 100644 --- a/src/backend/vulkan/src/command.rs +++ b/src/backend/vulkan/src/command.rs @@ -83,7 +83,7 @@ impl Buffer { impl draw::CommandBuffer for Buffer { fn reset(&mut self) {} - fn bind_pipeline_state(&mut self, _: ()) {} + fn bind_pipeline_state(&mut self, _: native::Pipeline) {} fn bind_vertex_buffers(&mut self, _: pso::VertexBufferSet) {} fn bind_constant_buffers(&mut self, _: &[pso::ConstantBufferParam]) {} fn bind_global_constant(&mut self, _: shade::Location, _: shade::UniformValue) {} diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index b542b98d5a9..192e8f42a0f 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -259,7 +259,6 @@ impl core::Factory for Factory { fn create_shader(&mut self, _stage: core::shade::Stage, code: &[u8]) -> Result, core::shade::CreateShaderError> { use gfx_core::handle::Producer; - let (dev, vk) = self.share.get_device(); let info = vk::ShaderModuleCreateInfo { sType: vk::STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, pNext: ptr::null(), @@ -267,11 +266,11 @@ impl core::Factory for Factory { codeSize: code.len(), pCode: code.as_ptr() as *const _, }; - let shader = unsafe { - let mut out = mem::zeroed(); - assert_eq!(vk::SUCCESS, vk.CreateShaderModule(dev, &info, ptr::null(), &mut out)); - out - }; + let (dev, vk) = self.share.get_device(); + let mut shader = 0; + assert_eq!(vk::SUCCESS, unsafe { + vk.CreateShaderModule(dev, &info, ptr::null(), &mut shader) + }); Ok(self.share.handles.borrow_mut().make_shader(shader)) } @@ -282,6 +281,23 @@ impl core::Factory for Factory { fn create_pipeline_state_raw(&mut self, _program: &h::Program, _desc: &core::pso::Descriptor) -> Result, core::pso::CreationError> { + use gfx_core::handle::Producer; + let (dev, vk) = self.share.get_device(); + + let layout = { + let info = vk::DescriptorSetLayoutCreateInfo { + sType: vk::STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + bindingCount: 0, + pBindings: ptr::null(), //TODO + }; + let mut out = 0; + assert_eq!(vk::SUCCESS, unsafe { + vk.CreateDescriptorSetLayout(dev, &info, ptr::null(), &mut out) + }); + out + }; /*let shader = native::Shader(vk::PipelineShaderStageCreateInfo { sType: vk::STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, pNext: ptr::null(), diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index dc6a6dda41f..e4845a4a2f2 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -270,7 +270,7 @@ impl gfx_core::Resources for Resources { type Buffer = native::Buffer; type Shader = vk::ShaderModule; type Program = (); - type PipelineStateObject = (); + type PipelineStateObject = native::Pipeline; type Texture = native::Texture; type ShaderResourceView = native::TextureView; //TODO: buffer view type UnorderedAccessView = (); diff --git a/src/backend/vulkan/src/native.rs b/src/backend/vulkan/src/native.rs index ed699520222..35314b53584 100644 --- a/src/backend/vulkan/src/native.rs +++ b/src/backend/vulkan/src/native.rs @@ -90,3 +90,10 @@ pub struct TextureView { } unsafe impl Send for TextureView {} unsafe impl Sync for TextureView {} + +#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)] +pub struct Pipeline { + pipeline: vk::Pipeline, + desc_layout: vk::DescriptorSetLayout, + desc_pool: vk::DescriptorPool, +} From 4379b5fcdbf7e2d96f980466487266d23e886cc3 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Thu, 19 May 2016 23:56:29 -0400 Subject: [PATCH 37/69] [vk] minor refactor of the unsafe vulkan calls --- src/backend/vulkan/src/factory.rs | 88 ++++++++++++++++--------------- src/backend/vulkan/src/lib.rs | 20 +++---- src/window/vulkan/src/lib.rs | 32 ++++++----- 3 files changed, 70 insertions(+), 70 deletions(-) diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index 192e8f42a0f..ac6a8de9b5a 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -56,12 +56,11 @@ impl Factory { flags: vk::COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex: qf_index, }; - let com_pool = unsafe { + let mut com_pool = 0; + assert_eq!(vk::SUCCESS, unsafe { let (dev, vk) = share.get_device(); - let mut out = mem::zeroed(); - assert_eq!(vk::SUCCESS, vk.CreateCommandPool(dev, &com_info, ptr::null(), &mut out)); - out - }; + vk.CreateCommandPool(dev, &com_info, ptr::null(), &mut com_pool) + }); Factory { share: share, queue_family_index: qf_index, @@ -87,12 +86,13 @@ impl Factory { pInheritanceInfo: ptr::null(), }; let (dev, vk) = self.share.get_device(); - let buf = unsafe { - let mut out = mem::zeroed(); - assert_eq!(vk::SUCCESS, vk.AllocateCommandBuffers(dev, &alloc_info, &mut out)); - assert_eq!(vk::SUCCESS, vk.BeginCommandBuffer(out, &begin_info)); - out - }; + let mut buf = 0; + assert_eq!(vk::SUCCESS, unsafe { + vk.AllocateCommandBuffers(dev, &alloc_info, &mut buf) + }); + assert_eq!(vk::SUCCESS, unsafe { + vk.BeginCommandBuffer(buf, &begin_info) + }); command::Buffer::new(buf, self.queue_family_index, self.share.clone()) } @@ -127,11 +127,10 @@ impl Factory { }; let (dev, vk) = self.share.get_device(); - let view = unsafe { - let mut out = mem::zeroed(); - assert_eq!(vk::SUCCESS, vk.CreateImageView(dev, &info, ptr::null(), &mut out)); - out - }; + let mut view = 0; + assert_eq!(vk::SUCCESS, unsafe { + vk.CreateImageView(dev, &info, ptr::null(), &mut view) + }); Ok(native::TextureView { image: raw_tex.image, view: view, @@ -177,11 +176,11 @@ impl Factory { flags: if signalled { vk::FENCE_CREATE_SIGNALED_BIT } else { 0 }, }; let (dev, vk) = self.share.get_device(); - unsafe { - let mut out = mem::zeroed(); - assert_eq!(vk::SUCCESS, vk.CreateFence(dev, &info, ptr::null(), &mut out)); - out - } + let mut fence = 0; + assert_eq!(vk::SUCCESS, unsafe { + vk.CreateFence(dev, &info, ptr::null(), &mut fence) + }); + fence } fn alloc(&self, usage: f::Usage, reqs: vk::MemoryRequirements) -> vk::DeviceMemory { @@ -196,11 +195,11 @@ impl Factory { }, }; let (dev, vk) = self.share.get_device(); - unsafe { - let mut out = mem::zeroed(); - assert_eq!(vk::SUCCESS, vk.AllocateMemory(dev, &info, ptr::null(), &mut out)); - out - } + let mut mem = 0; + assert_eq!(vk::SUCCESS, unsafe { + vk.AllocateMemory(dev, &info, ptr::null(), &mut mem) + }); + mem } } @@ -234,12 +233,14 @@ impl core::Factory for Factory { pQueueFamilyIndices: &self.queue_family_index, }; let (dev, vk) = self.share.get_device(); - let (buf, reqs) = unsafe { - let mut buf = mem::zeroed(); - assert_eq!(vk::SUCCESS, vk.CreateBuffer(dev, &native_info, ptr::null(), &mut buf)); - let mut reqs = mem::zeroed(); - vk.GetBufferMemoryRequirements(dev, buf, &mut reqs); - (buf, reqs) + let mut buf = 0; + assert_eq!(vk::SUCCESS, unsafe { + vk.CreateBuffer(dev, &native_info, ptr::null(), &mut buf) + }); + let reqs = unsafe { + let mut out = mem::zeroed(); + vk.GetBufferMemoryRequirements(dev, buf, &mut out); + out }; let buffer = native::Buffer { buffer: buf, @@ -344,12 +345,14 @@ impl core::Factory for Factory { initialLayout: data::map_image_layout(desc.bind), }; let (dev, vk) = self.share.get_device(); - let (image, reqs) = unsafe { - let mut image = mem::zeroed(); - assert_eq!(vk::SUCCESS, vk.CreateImage(dev, &image_info, ptr::null(), &mut image)); - let mut reqs = mem::zeroed(); - vk.GetImageMemoryRequirements(dev, image, &mut reqs); - (image, reqs) + let mut image = 0; + assert_eq!(vk::SUCCESS, unsafe { + vk.CreateImage(dev, &image_info, ptr::null(), &mut image) + }); + let reqs = unsafe { + let mut out = mem::zeroed(); + vk.GetImageMemoryRequirements(dev, image, &mut out); + out }; let tex = native::Texture { image: image, @@ -446,11 +449,10 @@ impl core::Factory for Factory { }; let (dev, vk) = self.share.get_device(); - let sampler = unsafe { - let mut out = mem::zeroed(); - assert_eq!(vk::SUCCESS, vk.CreateSampler(dev, &native_info, ptr::null(), &mut out)); - out - }; + let mut sampler = 0; + assert_eq!(vk::SUCCESS, unsafe { + vk.CreateSampler(dev, &native_info, ptr::null(), &mut sampler) + }); self.share.handles.borrow_mut().make_sampler(sampler, info) } diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index e4845a4a2f2..bc097c594f4 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -134,11 +134,11 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& enabledExtensionCount: extensions.len() as u32, ppEnabledExtensionNames: str_pointers[layers.len()..].as_ptr(), }; - unsafe { - let mut ptr = mem::zeroed(); - assert_eq!(vk::SUCCESS, entry_points.CreateInstance(&create_info, ptr::null(), &mut ptr)); - ptr - } + let mut out = 0; + assert_eq!(vk::SUCCESS, unsafe { + entry_points.CreateInstance(&create_info, ptr::null(), &mut out) + }); + out }; let inst_pointers = vk::InstancePointers::load(|name| unsafe { @@ -196,11 +196,11 @@ pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[& ppEnabledExtensionNames: str_pointers.as_ptr(), pEnabledFeatures: &features, }; - unsafe { - let mut out = mem::zeroed(); - assert_eq!(vk::SUCCESS, inst_pointers.CreateDevice(dev.device, &dev_info, ptr::null(), &mut out)); - out - } + let mut out = 0; + assert_eq!(vk::SUCCESS, unsafe { + inst_pointers.CreateDevice(dev.device, &dev_info, ptr::null(), &mut out) + }); + out }; let dev_pointers = vk::DevicePointers::load(|name| unsafe { diff --git a/src/window/vulkan/src/lib.rs b/src/window/vulkan/src/lib.rs index adb28580552..3862fdd0e16 100644 --- a/src/window/vulkan/src/lib.rs +++ b/src/window/vulkan/src/lib.rs @@ -19,7 +19,7 @@ extern crate gfx_core; extern crate gfx_device_vulkan; use std::ffi::CStr; -use std::{mem, ptr}; +use std::ptr; use std::os::raw; use gfx_core::format; @@ -169,11 +169,11 @@ pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vul pUserData: ptr::null_mut(), }; let (inst, vk) = backend.get_instance(); - Some(unsafe { - let mut out = mem::zeroed(); - assert_eq!(vk::SUCCESS, vk.CreateDebugReportCallbackEXT(inst, &info, ptr::null(), &mut out)); - out - }) + let mut out = 0; + assert_eq!(vk::SUCCESS, unsafe { + vk.CreateDebugReportCallbackEXT(inst, &info, ptr::null(), &mut out) + }); + Some(out) }else { None }; @@ -220,12 +220,11 @@ pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vul connection: conn.get_raw_conn() as *const _, window: window as *const _, //HACK! TODO: fix the bindings }; - - unsafe { - let mut out = mem::zeroed(); - assert_eq!(vk::SUCCESS, vk.CreateXcbSurfaceKHR(inst, &info, ptr::null(), &mut out)); - out - } + let mut out = 0; + assert_eq!(vk::SUCCESS, unsafe { + vk.CreateXcbSurfaceKHR(inst, &info, ptr::null(), &mut out) + }); + out }; let (dev, vk) = backend.get_device(); @@ -254,11 +253,10 @@ pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vul oldSwapchain: 0, }; - let swapchain = unsafe { - let mut out = mem::zeroed(); - assert_eq!(vk::SUCCESS, vk.CreateSwapchainKHR(dev, &swapchain_info, ptr::null(), &mut out)); - out - }; + let mut swapchain = 0; + assert_eq!(vk::SUCCESS, unsafe { + vk.CreateSwapchainKHR(dev, &swapchain_info, ptr::null(), &mut swapchain) + }); assert_eq!(vk::SUCCESS, unsafe { vk.GetSwapchainImagesKHR(dev, swapchain, &mut num, images.as_mut_ptr()) From 7f952814c732cc9e4ffc2497c0a6e3e0cf92690e Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Fri, 20 May 2016 00:07:39 -0400 Subject: [PATCH 38/69] [vk] dummy pipeline layout and descriptor pool creation for PSO --- src/backend/vulkan/src/factory.rs | 44 ++++++++++++++++++++++++++++--- src/backend/vulkan/src/native.rs | 7 ++--- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index ac6a8de9b5a..47f19b5a7d0 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -280,12 +280,13 @@ impl core::Factory for Factory { unimplemented!() } - fn create_pipeline_state_raw(&mut self, _program: &h::Program, _desc: &core::pso::Descriptor) + fn create_pipeline_state_raw(&mut self, program: &h::Program, _desc: &core::pso::Descriptor) -> Result, core::pso::CreationError> { use gfx_core::handle::Producer; let (dev, vk) = self.share.get_device(); - let layout = { + let pipeline = 0; + let set_layout = { let info = vk::DescriptorSetLayoutCreateInfo { sType: vk::STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, pNext: ptr::null(), @@ -299,6 +300,37 @@ impl core::Factory for Factory { }); out }; + let pipe_layout = { + let info = vk::PipelineLayoutCreateInfo { + sType: vk::STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + setLayoutCount: 1, + pSetLayouts: &set_layout, + pushConstantRangeCount: 0, + pPushConstantRanges: ptr::null(), + }; + let mut out = 0; + assert_eq!(vk::SUCCESS, unsafe { + vk.CreatePipelineLayout(dev, &info, ptr::null(), &mut out) + }); + out + }; + let pool = { + let info = vk::DescriptorPoolCreateInfo { + sType: vk::STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + maxSets: 100, //TODO + poolSizeCount: 0, + pPoolSizes: ptr::null(), + }; + let mut out = 0; + assert_eq!(vk::SUCCESS, unsafe { + vk.CreateDescriptorPool(dev, &info, ptr::null(), &mut out) + }); + out + }; /*let shader = native::Shader(vk::PipelineShaderStageCreateInfo { sType: vk::STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, pNext: ptr::null(), @@ -308,7 +340,13 @@ impl core::Factory for Factory { pName: ptr::null(), pSpecializationInfo: ptr::null(), });*/ - unimplemented!() + let pso = native::Pipeline { + pipeline: pipeline, + pipe_layout: pipe_layout, + desc_layout: set_layout, + desc_pool: pool, + }; + Ok(self.share.handles.borrow_mut().make_pso(pso, program)) } fn create_texture_raw(&mut self, desc: core::tex::Descriptor, hint: Option, diff --git a/src/backend/vulkan/src/native.rs b/src/backend/vulkan/src/native.rs index 35314b53584..fc77a912762 100644 --- a/src/backend/vulkan/src/native.rs +++ b/src/backend/vulkan/src/native.rs @@ -93,7 +93,8 @@ unsafe impl Sync for TextureView {} #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)] pub struct Pipeline { - pipeline: vk::Pipeline, - desc_layout: vk::DescriptorSetLayout, - desc_pool: vk::DescriptorPool, + pub pipeline: vk::Pipeline, + pub pipe_layout: vk::PipelineLayout, + pub desc_layout: vk::DescriptorSetLayout, + pub desc_pool: vk::DescriptorPool, } From 2082434dd336c5b902899a6560dcaeb488b7bb58 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Fri, 20 May 2016 00:13:58 -0400 Subject: [PATCH 39/69] [vk] PSO deletion --- src/backend/vulkan/src/command.rs | 7 ++++++- src/backend/vulkan/src/factory.rs | 21 ++++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs index 23e3caa9613..33cc906deed 100644 --- a/src/backend/vulkan/src/command.rs +++ b/src/backend/vulkan/src/command.rs @@ -210,7 +210,12 @@ impl core::Device for GraphicsQueue { vk.DestroyShaderModule(dev, *s, ptr::null()); }, |_, _p| (), //program - |_, _v| (), //PSO + |vk, p| unsafe { //PSO + vk.DestroyPipeline(dev, p.pipeline, ptr::null()); + vk.DestroyPipelineLayout(dev, p.pipe_layout, ptr::null()); + vk.DestroyDescriptorSetLayout(dev, p.desc_layout, ptr::null()); + vk.DestroyDescriptorPool(dev, p.desc_pool, ptr::null()); + }, |vk, t| if t.memory != 0 {unsafe { //texture vk.DestroyImage(dev, t.image, ptr::null()); vk.FreeMemory(dev, t.memory, ptr::null()); diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index 47f19b5a7d0..bef7da19611 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -285,7 +285,6 @@ impl core::Factory for Factory { use gfx_core::handle::Producer; let (dev, vk) = self.share.get_device(); - let pipeline = 0; let set_layout = { let info = vk::DescriptorSetLayoutCreateInfo { sType: vk::STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, @@ -331,6 +330,26 @@ impl core::Factory for Factory { }); out }; + let pipeline = { + let info = vk::GraphicsPipelineCreateInfo { + sType: vk::STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + stageCount: 0, + pStages: ptr::null(), //TODO + layout: pipe_layout, + renderPass: 0, //TODO + subpass: 0, + basePipelineHandle: 0, + basePipelineIndex: 0, + .. unsafe { mem::zeroed() } //TODO + }; + let mut out = 0; + assert_eq!(vk::SUCCESS, unsafe { + vk.CreateGraphicsPipelines(dev, 0, 1, &info, ptr::null(), &mut out) + }); + out + }; /*let shader = native::Shader(vk::PipelineShaderStageCreateInfo { sType: vk::STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, pNext: ptr::null(), From 2b3d2c23ab7c3fd05add53794171d0bac89e3174 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Sat, 21 May 2016 22:08:04 -0400 Subject: [PATCH 40/69] [vk] dummy program creation --- src/backend/vulkan/src/factory.rs | 31 ++++++++++++++++++-- src/backend/vulkan/src/lib.rs | 2 +- src/backend/vulkan/src/native.rs | 48 +++++++------------------------ src/core/src/handle.rs | 22 +++++++------- src/core/src/lib.rs | 2 ++ 5 files changed, 52 insertions(+), 53 deletions(-) diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index bef7da19611..007583dc938 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -253,7 +253,7 @@ impl core::Factory for Factory { } fn create_buffer_const_raw(&mut self, _data: &[u8], _stride: usize, _role: f::BufferRole, _bind: f::Bind) - -> Result, f::BufferError> { + -> Result, f::BufferError> { unimplemented!() } @@ -275,9 +275,34 @@ impl core::Factory for Factory { Ok(self.share.handles.borrow_mut().make_shader(shader)) } - fn create_program(&mut self, _shader_set: &core::ShaderSet) + fn create_program(&mut self, shader_set: &core::ShaderSet) -> Result, core::shade::CreateProgramError> { - unimplemented!() + use gfx_core::handle::Producer; + use gfx_core::shade as s; + + let prog = match shader_set.clone() { + core::ShaderSet::Simple(vs, ps) => native::Program { + vertex: vs, + geometry: None, + pixel: ps, + }, + core::ShaderSet::Geometry(vs, gs, ps) => native::Program { + vertex: vs, + geometry: Some(gs), + pixel: ps, + }, + }; + let info = s::ProgramInfo { + vertex_attributes: Vec::new(), + globals: Vec::new(), + constant_buffers: Vec::new(), + textures: Vec::new(), + unordereds: Vec::new(), + samplers: Vec::new(), + outputs: Vec::new(), + knows_outputs: false, + }; + Ok(self.share.handles.borrow_mut().make_program(prog, info)) } fn create_pipeline_state_raw(&mut self, program: &h::Program, _desc: &core::pso::Descriptor) diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index bc097c594f4..ab2993e5ff8 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -269,7 +269,7 @@ pub enum Resources {} impl gfx_core::Resources for Resources { type Buffer = native::Buffer; type Shader = vk::ShaderModule; - type Program = (); + type Program = native::Program; type PipelineStateObject = native::Pipeline; type Texture = native::Texture; type ShaderResourceView = native::TextureView; //TODO: buffer view diff --git a/src/backend/vulkan/src/native.rs b/src/backend/vulkan/src/native.rs index fc77a912762..ea4a6291118 100644 --- a/src/backend/vulkan/src/native.rs +++ b/src/backend/vulkan/src/native.rs @@ -12,48 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::ffi::CStr; -use std::{cell, fmt, hash}; +use std::{cell, hash}; use vk; +use gfx_core; +use Resources as R; -//Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync; - -pub struct Shader(pub vk::PipelineShaderStageCreateInfo); - -impl Clone for Shader { - fn clone(&self) -> Shader { - Shader(vk::PipelineShaderStageCreateInfo { - .. self.0 - }) - } -} - -impl fmt::Debug for Shader { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let name = unsafe { CStr::from_ptr(self.0.pName) }.to_str().unwrap(); - write!(f, "Shader({}, {}, {})", self.0.stage, name, self.0.module) - } -} - -impl hash::Hash for Shader { - fn hash(&self, state: &mut H) where H: hash::Hasher { - self.0.stage.hash(state); - //self.0.pName.hash(state); - self.0.module.hash(state); - } +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub struct Program { + pub vertex: gfx_core::VertexShader, + pub geometry: Option>, + pub pixel: gfx_core::PixelShader, } - -impl PartialEq for Shader { - fn eq(&self, other: &Shader) -> bool { - self.0.stage == other.0.stage && - self.0.module == other.0.module - } -} - -impl Eq for Shader {} -unsafe impl Send for Shader {} -unsafe impl Sync for Shader {} +unsafe impl Send for Program {} +unsafe impl Sync for Program {} #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] diff --git a/src/core/src/handle.rs b/src/core/src/handle.rs index de89ec184c0..897dc46ca37 100644 --- a/src/core/src/handle.rs +++ b/src/core/src/handle.rs @@ -33,7 +33,7 @@ impl RawBuffer { } /// Type-safe buffer handle -#[derive(Clone, Debug, Hash, PartialEq)] +#[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct Buffer(RawBuffer, PhantomData); impl Typed for Buffer { @@ -62,7 +62,7 @@ impl Buffer { } /// Shader Handle -#[derive(Clone, Debug, Hash, PartialEq)] +#[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct Shader(Arc); /// Program Handle @@ -79,11 +79,11 @@ impl Program { pub struct RawPipelineState(Arc, Arc); /// Raw texture object -#[derive(Clone, Debug, Hash, PartialEq)] +#[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct RawTexture(Arc, tex::Descriptor); /// Typed texture object -#[derive(Clone, Debug, Hash, PartialEq)] +#[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct Texture(RawTexture, PhantomData); impl RawTexture { @@ -106,18 +106,18 @@ impl Texture { pub fn get_info(&self) -> &tex::Descriptor { self.raw().get_info() } } -#[derive(Clone, Debug, Hash, PartialEq)] +#[derive(Clone, Debug, Eq, Hash, PartialEq)] enum ViewSource { Buffer(Arc), Texture(Arc), } /// Raw Shader Resource View Handle -#[derive(Clone, Debug, Hash, PartialEq)] +#[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct RawShaderResourceView(Arc, ViewSource); /// Type-safe Shader Resource View Handle -#[derive(Clone, Debug, Hash, PartialEq)] +#[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct ShaderResourceView(RawShaderResourceView, PhantomData); impl Typed for ShaderResourceView { @@ -131,11 +131,11 @@ impl Typed for ShaderResourceView { } /// Raw Unordered Access View Handle -#[derive(Clone, Debug, Hash, PartialEq)] +#[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct RawUnorderedAccessView(Arc, ViewSource); /// Type-safe Unordered Access View Handle -#[derive(Clone, Debug, Hash, PartialEq)] +#[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct UnorderedAccessView(RawUnorderedAccessView, PhantomData); impl Typed for UnorderedAccessView { @@ -213,7 +213,7 @@ impl Typed for DepthStencilView { } /// Sampler Handle -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq)] pub struct Sampler(Arc, tex::SamplerInfo); impl Sampler { @@ -222,7 +222,7 @@ impl Sampler { } /// Fence Handle -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq)] pub struct Fence(Arc); /// Stores reference-counted resources used in a command buffer. diff --git a/src/core/src/lib.rs b/src/core/src/lib.rs index 4f433d4fbcd..d8285a18b2d 100644 --- a/src/core/src/lib.rs +++ b/src/core/src/lib.rs @@ -75,6 +75,7 @@ pub type SamplerSlot = u8; macro_rules! define_shaders { ($($name:ident),+) => {$( #[allow(missing_docs)] + #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct $name(handle::Shader); impl $name { #[allow(missing_docs)] @@ -88,6 +89,7 @@ macro_rules! define_shaders { define_shaders!(VertexShader, HullShader, DomainShader, GeometryShader, PixelShader); /// A complete set of shaders to link a program. +#[derive(Clone, Debug, Eq, Hash, PartialEq)] pub enum ShaderSet { /// Simple program: Vs-Ps Simple(VertexShader, PixelShader), From d77b4566dc82b8003c991f6b338cf9eb46680556 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Sat, 21 May 2016 22:34:05 -0400 Subject: [PATCH 41/69] [vk] pipeline shader stages --- src/backend/vulkan/src/factory.rs | 55 ++++++++++++++++++++++++------- src/backend/vulkan/src/native.rs | 3 +- src/core/src/handle.rs | 17 ++++++++-- 3 files changed, 61 insertions(+), 14 deletions(-) diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index 007583dc938..f6213d306fe 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -201,6 +201,46 @@ impl Factory { }); mem } + + fn get_shader_stages(&mut self, program: &h::Program) -> Vec { + let prog = self.frame_handles.ref_program(program); + let entry_name = b"main\0"; //TODO + let mut stages = Vec::with_capacity(3); + if true { + stages.push(vk::PipelineShaderStageCreateInfo { + sType: vk::STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + stage: vk::SHADER_STAGE_VERTEX_BIT, + module: *prog.vertex.reference(&mut self.frame_handles), + pName: entry_name.as_ptr() as *const i8, + pSpecializationInfo: ptr::null(), + }); + } + if let Some(ref geom) = prog.geometry { + stages.push(vk::PipelineShaderStageCreateInfo { + sType: vk::STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + stage: vk::SHADER_STAGE_GEOMETRY_BIT, + module: *geom.reference(&mut self.frame_handles), + pName: entry_name.as_ptr() as *const i8, + pSpecializationInfo: ptr::null(), + }); + } + if true { + stages.push(vk::PipelineShaderStageCreateInfo { + sType: vk::STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + stage: vk::SHADER_STAGE_FRAGMENT_BIT, + module: *prog.pixel.reference(&mut self.frame_handles), + pName: entry_name.as_ptr() as *const i8, + pSpecializationInfo: ptr::null(), + }); + } + stages + } } impl Drop for Factory { @@ -308,6 +348,7 @@ impl core::Factory for Factory { fn create_pipeline_state_raw(&mut self, program: &h::Program, _desc: &core::pso::Descriptor) -> Result, core::pso::CreationError> { use gfx_core::handle::Producer; + let stages = self.get_shader_stages(program); let (dev, vk) = self.share.get_device(); let set_layout = { @@ -360,8 +401,8 @@ impl core::Factory for Factory { sType: vk::STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, pNext: ptr::null(), flags: 0, - stageCount: 0, - pStages: ptr::null(), //TODO + stageCount: stages.len() as u32, + pStages: stages.as_ptr(), layout: pipe_layout, renderPass: 0, //TODO subpass: 0, @@ -375,20 +416,12 @@ impl core::Factory for Factory { }); out }; - /*let shader = native::Shader(vk::PipelineShaderStageCreateInfo { - sType: vk::STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - pNext: ptr::null(), - flags: 0, - stage: 0, //TODO - module: !0, //TODO - pName: ptr::null(), - pSpecializationInfo: ptr::null(), - });*/ let pso = native::Pipeline { pipeline: pipeline, pipe_layout: pipe_layout, desc_layout: set_layout, desc_pool: pool, + program: program.clone(), }; Ok(self.share.handles.borrow_mut().make_pso(pso, program)) } diff --git a/src/backend/vulkan/src/native.rs b/src/backend/vulkan/src/native.rs index ea4a6291118..c88d93f1bef 100644 --- a/src/backend/vulkan/src/native.rs +++ b/src/backend/vulkan/src/native.rs @@ -63,10 +63,11 @@ pub struct TextureView { unsafe impl Send for TextureView {} unsafe impl Sync for TextureView {} -#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)] +#[derive(Clone, Debug, Hash, Eq, PartialEq)] pub struct Pipeline { pub pipeline: vk::Pipeline, pub pipe_layout: vk::PipelineLayout, pub desc_layout: vk::DescriptorSetLayout, pub desc_pool: vk::DescriptorPool, + pub program: gfx_core::handle::Program, } diff --git a/src/core/src/handle.rs b/src/core/src/handle.rs index 897dc46ca37..4c63f2093b3 100644 --- a/src/core/src/handle.rs +++ b/src/core/src/handle.rs @@ -16,7 +16,7 @@ //! Device resource handles -use std::mem; +use std::{cmp, hash, mem}; use std::marker::PhantomData; use std::sync::Arc; use {shade, tex, Resources}; @@ -66,13 +66,26 @@ impl Buffer { pub struct Shader(Arc); /// Program Handle -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug)] pub struct Program(Arc, shade::ProgramInfo); +// custom implementations due to the limitations of `ProgramInfo` impl Program { /// Get program info pub fn get_info(&self) -> &shade::ProgramInfo { &self.1 } } +impl hash::Hash for Program { + fn hash(&self, state: &mut H) where H: hash::Hasher { + self.0.hash(state); + } +} +impl cmp::PartialEq for Program { + fn eq(&self, other: &Program) -> bool { + self.0.eq(&other.0) + } +} +impl cmp::Eq for Program {} + /// Raw Pipeline State Handle #[derive(Clone, Debug, PartialEq)] From fd58a15e76da4f7b22298f362e745c7e5c7d51e4 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Sat, 21 May 2016 22:41:07 -0400 Subject: [PATCH 42/69] [vk] added render pass to the pipeline --- src/backend/vulkan/src/factory.rs | 21 ++++++++++++++++++++- src/backend/vulkan/src/native.rs | 1 + 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index f6213d306fe..908d9116a29 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -396,6 +396,24 @@ impl core::Factory for Factory { }); out }; + let render_pass = { + let info = vk::RenderPassCreateInfo { + sType: vk::STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + attachmentCount: 0, //TODO + pAttachments: ptr::null(), + subpassCount: 0, + pSubpasses: ptr::null(), + dependencyCount: 0, + pDependencies: ptr::null(), + }; + let mut out = 0; + assert_eq!(vk::SUCCESS, unsafe { + vk.CreateRenderPass(dev, &info, ptr::null(), &mut out) + }); + out + }; let pipeline = { let info = vk::GraphicsPipelineCreateInfo { sType: vk::STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, @@ -404,7 +422,7 @@ impl core::Factory for Factory { stageCount: stages.len() as u32, pStages: stages.as_ptr(), layout: pipe_layout, - renderPass: 0, //TODO + renderPass: render_pass, subpass: 0, basePipelineHandle: 0, basePipelineIndex: 0, @@ -421,6 +439,7 @@ impl core::Factory for Factory { pipe_layout: pipe_layout, desc_layout: set_layout, desc_pool: pool, + render_pass: render_pass, program: program.clone(), }; Ok(self.share.handles.borrow_mut().make_pso(pso, program)) diff --git a/src/backend/vulkan/src/native.rs b/src/backend/vulkan/src/native.rs index c88d93f1bef..1444d8dafb7 100644 --- a/src/backend/vulkan/src/native.rs +++ b/src/backend/vulkan/src/native.rs @@ -69,5 +69,6 @@ pub struct Pipeline { pub pipe_layout: vk::PipelineLayout, pub desc_layout: vk::DescriptorSetLayout, pub desc_pool: vk::DescriptorPool, + pub render_pass: vk::RenderPass, pub program: gfx_core::handle::Program, } From c32e7feab199710e4f334820801b34218b1f24e9 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Sat, 21 May 2016 22:56:43 -0400 Subject: [PATCH 43/69] [vk] implemented rough create_buffer_const_raw() --- src/backend/vulkan/src/factory.rs | 91 ++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 31 deletions(-) diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index 908d9116a29..cd57e101e1d 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -183,6 +183,38 @@ impl Factory { fence } + fn create_buffer_impl(&mut self, info: &f::BufferInfo) -> native::Buffer { + let (usage, _) = data::map_usage_tiling(info.usage, info.bind); + let native_info = vk::BufferCreateInfo { + sType: vk::STRUCTURE_TYPE_BUFFER_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + size: info.size as vk::DeviceSize, + usage: usage, + sharingMode: vk::SHARING_MODE_EXCLUSIVE, + queueFamilyIndexCount: 1, + pQueueFamilyIndices: &self.queue_family_index, + }; + let (dev, vk) = self.share.get_device(); + let mut buf = 0; + assert_eq!(vk::SUCCESS, unsafe { + vk.CreateBuffer(dev, &native_info, ptr::null(), &mut buf) + }); + let reqs = unsafe { + let mut out = mem::zeroed(); + vk.GetBufferMemoryRequirements(dev, buf, &mut out); + out + }; + let mem = self.alloc(info.usage, reqs); + assert_eq!(vk::SUCCESS, unsafe { + vk.BindBufferMemory(dev, buf, mem, 0) + }); + native::Buffer { + buffer: buf, + memory: mem, + } + } + fn alloc(&self, usage: f::Usage, reqs: vk::MemoryRequirements) -> vk::DeviceMemory { let info = vk::MemoryAllocateInfo { sType: vk::STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, @@ -261,40 +293,29 @@ impl core::Factory for Factory { fn create_buffer_raw(&mut self, info: f::BufferInfo) -> Result, f::BufferError> { use gfx_core::handle::Producer; - let (usage, _) = data::map_usage_tiling(info.usage, info.bind); - let native_info = vk::BufferCreateInfo { - sType: vk::STRUCTURE_TYPE_BUFFER_CREATE_INFO, - pNext: ptr::null(), - flags: 0, - size: info.size as vk::DeviceSize, - usage: usage, - sharingMode: vk::SHARING_MODE_EXCLUSIVE, - queueFamilyIndexCount: 1, - pQueueFamilyIndices: &self.queue_family_index, - }; - let (dev, vk) = self.share.get_device(); - let mut buf = 0; - assert_eq!(vk::SUCCESS, unsafe { - vk.CreateBuffer(dev, &native_info, ptr::null(), &mut buf) - }); - let reqs = unsafe { - let mut out = mem::zeroed(); - vk.GetBufferMemoryRequirements(dev, buf, &mut out); - out - }; - let buffer = native::Buffer { - buffer: buf, - memory: self.alloc(info.usage, reqs), - }; - assert_eq!(vk::SUCCESS, unsafe { - vk.BindBufferMemory(dev, buf, buffer.memory, 0) - }); + let buffer = self.create_buffer_impl(&info); Ok(self.share.handles.borrow_mut().make_buffer(buffer, info)) } - fn create_buffer_const_raw(&mut self, _data: &[u8], _stride: usize, _role: f::BufferRole, _bind: f::Bind) + fn create_buffer_const_raw(&mut self, data: &[u8], stride: usize, role: f::BufferRole, bind: f::Bind) -> Result, f::BufferError> { - unimplemented!() + use gfx_core::handle::Producer; + let info = f::BufferInfo { + role: role, + usage: f::Usage::Const, + bind: bind, + size: data.len(), + stride: stride, + }; + let buffer = self.create_buffer_impl(&info); + let (dev, vk) = self.share.get_device(); + unsafe { + let mut ptr = ptr::null_mut(); + assert_eq!(vk::SUCCESS, vk.MapMemory(dev, buffer.memory, 0, data.len() as u64, 0, &mut ptr)); + ptr::copy_nonoverlapping(data.as_ptr(), ptr as *mut u8, data.len()); + vk.UnmapMemory(dev, buffer.memory); + } + Ok(self.share.handles.borrow_mut().make_buffer(buffer, info)) } fn create_shader(&mut self, _stage: core::shade::Stage, code: &[u8]) @@ -421,12 +442,20 @@ impl core::Factory for Factory { flags: 0, stageCount: stages.len() as u32, pStages: stages.as_ptr(), + pVertexInputState: ptr::null(), //TODO + pInputAssemblyState: ptr::null(), //TODO + pTessellationState: ptr::null(), + pViewportState: ptr::null(), //TODO + pRasterizationState: ptr::null(), //TODO + pMultisampleState: ptr::null(), //TODO + pDepthStencilState: ptr::null(), //TODO + pColorBlendState: ptr::null(), //TODO + pDynamicState: ptr::null(), layout: pipe_layout, renderPass: render_pass, subpass: 0, basePipelineHandle: 0, basePipelineIndex: 0, - .. unsafe { mem::zeroed() } //TODO }; let mut out = 0; assert_eq!(vk::SUCCESS, unsafe { From 87eebc4349a0be87e8f88ef51f54d5ae5b194255 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Sun, 22 May 2016 22:24:52 -0400 Subject: [PATCH 44/69] [vk] render pass attachments --- src/backend/vulkan/src/data.rs | 9 +++--- src/backend/vulkan/src/factory.rs | 47 ++++++++++++++++++++++++++----- src/core/src/pso.rs | 2 +- src/render/src/pso/target.rs | 6 ++-- 4 files changed, 49 insertions(+), 15 deletions(-) diff --git a/src/backend/vulkan/src/data.rs b/src/backend/vulkan/src/data.rs index c860a8be150..50bd0ea66eb 100644 --- a/src/backend/vulkan/src/data.rs +++ b/src/backend/vulkan/src/data.rs @@ -119,11 +119,12 @@ pub fn map_usage_tiling(gfx_usage: Usage, bind: Bind) -> (vk::ImageUsageFlags, v } pub fn map_image_layout(bind: Bind) -> vk::ImageLayout { - use gfx_core::factory as f; + //use gfx_core::factory as f; + // can't use optimal layouts for the fact PSO descriptor doesn't know about them match bind { - f::RENDER_TARGET => vk::IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - f::DEPTH_STENCIL => vk::IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - f::SHADER_RESOURCE => vk::IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + //f::RENDER_TARGET => vk::IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + //f::DEPTH_STENCIL => vk::IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + //f::SHADER_RESOURCE => vk::IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, _ => vk::IMAGE_LAYOUT_GENERAL, } } diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index cd57e101e1d..3e2a4eec30a 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -237,7 +237,7 @@ impl Factory { fn get_shader_stages(&mut self, program: &h::Program) -> Vec { let prog = self.frame_handles.ref_program(program); let entry_name = b"main\0"; //TODO - let mut stages = Vec::with_capacity(3); + let mut stages = Vec::new(); if true { stages.push(vk::PipelineShaderStageCreateInfo { sType: vk::STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, @@ -366,7 +366,7 @@ impl core::Factory for Factory { Ok(self.share.handles.borrow_mut().make_program(prog, info)) } - fn create_pipeline_state_raw(&mut self, program: &h::Program, _desc: &core::pso::Descriptor) + fn create_pipeline_state_raw(&mut self, program: &h::Program, desc: &core::pso::Descriptor) -> Result, core::pso::CreationError> { use gfx_core::handle::Producer; let stages = self.get_shader_stages(program); @@ -418,12 +418,45 @@ impl core::Factory for Factory { out }; let render_pass = { + let mut attachments = Vec::new(); + for col in desc.color_targets.iter().filter_map(|c| c.as_ref()) { + attachments.push(vk::AttachmentDescription { + flags: 0, + format: match data::map_format((col.0).0, (col.0).1) { + Some(fm) => fm, + None => return Err(core::pso::CreationError), + }, + samples: vk::SAMPLE_COUNT_1_BIT, //TODO + loadOp: vk::ATTACHMENT_LOAD_OP_LOAD, + storeOp: vk::ATTACHMENT_STORE_OP_STORE, + stencilLoadOp: vk::ATTACHMENT_LOAD_OP_DONT_CARE, + stencilStoreOp: vk::ATTACHMENT_STORE_OP_DONT_CARE, + initialLayout: vk::IMAGE_LAYOUT_GENERAL, //TODO + finalLayout: vk::IMAGE_LAYOUT_GENERAL, + }); + } + if let Some(ds) = desc.depth_stencil { + attachments.push(vk::AttachmentDescription { + flags: 0, + format: match data::map_format((ds.0).0, (ds.0).1) { + Some(fm) => fm, + None => return Err(core::pso::CreationError), + }, + samples: vk::SAMPLE_COUNT_1_BIT, //TODO + loadOp: vk::ATTACHMENT_LOAD_OP_LOAD, + storeOp: vk::ATTACHMENT_STORE_OP_STORE, + stencilLoadOp: vk::ATTACHMENT_LOAD_OP_LOAD, + stencilStoreOp: vk::ATTACHMENT_STORE_OP_STORE, + initialLayout: vk::IMAGE_LAYOUT_GENERAL, //TODO + finalLayout: vk::IMAGE_LAYOUT_GENERAL, + }); + } let info = vk::RenderPassCreateInfo { sType: vk::STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, pNext: ptr::null(), flags: 0, - attachmentCount: 0, //TODO - pAttachments: ptr::null(), + attachmentCount: attachments.len() as u32, + pAttachments: attachments.as_ptr(), subpassCount: 0, pSubpasses: ptr::null(), dependencyCount: 0, @@ -482,7 +515,7 @@ impl core::Factory for Factory { let slices = desc.kind.get_num_slices(); let (usage, tiling) = data::map_usage_tiling(desc.usage, desc.bind); let chan_type = hint.unwrap_or(core::format::ChannelType::Uint); - let image_info = vk::ImageCreateInfo { + let info = vk::ImageCreateInfo { sType: vk::STRUCTURE_TYPE_IMAGE_CREATE_INFO, pNext: ptr::null(), flags: vk::IMAGE_CREATE_MUTABLE_FORMAT_BIT | @@ -510,7 +543,7 @@ impl core::Factory for Factory { let (dev, vk) = self.share.get_device(); let mut image = 0; assert_eq!(vk::SUCCESS, unsafe { - vk.CreateImage(dev, &image_info, ptr::null(), &mut image) + vk.CreateImage(dev, &info, ptr::null(), &mut image) }); let reqs = unsafe { let mut out = mem::zeroed(); @@ -519,7 +552,7 @@ impl core::Factory for Factory { }; let tex = native::Texture { image: image, - layout: cell::Cell::new(image_info.initialLayout), + layout: cell::Cell::new(info.initialLayout), memory: self.alloc(desc.usage, reqs), }; assert_eq!(vk::SUCCESS, unsafe { diff --git a/src/core/src/pso.rs b/src/core/src/pso.rs index 547f477e985..9c32dad9342 100644 --- a/src/core/src/pso.rs +++ b/src/core/src/pso.rs @@ -137,7 +137,7 @@ pub type AttributeDesc = (Element, InstanceRate); /// PSO color target descriptor pub type ColorTargetDesc = (format::Format, ColorInfo); /// PSO depth-stencil target descriptor -pub type DepthStencilDesc = (format::SurfaceType, DepthStencilInfo); +pub type DepthStencilDesc = (format::Format, DepthStencilInfo); /// All the information surrounding a shader program that is required /// for PSO creation, including the formats of vertex buffers and pixel targets; diff --git a/src/render/src/pso/target.rs b/src/render/src/pso/target.rs index 1be4d3c2aae..0535ca316e5 100644 --- a/src/render/src/pso/target.rs +++ b/src/render/src/pso/target.rs @@ -145,7 +145,7 @@ impl<'a, T: format::DepthFormat> DataLink<'a> for DepthTarget { fn new() -> Self { DepthTarget(PhantomData) } fn is_active(&self) -> bool { true } fn link_depth_stencil(&mut self, init: &Self::Init) -> Option { - Some((T::get_format().0, (*init).into())) + Some((T::get_format(), (*init).into())) } } @@ -162,7 +162,7 @@ impl<'a, T: format::StencilFormat> DataLink<'a> for StencilTarget { fn new() -> Self { StencilTarget(PhantomData) } fn is_active(&self) -> bool { true } fn link_depth_stencil(&mut self, init: &Self::Init) -> Option { - Some((T::get_format().0, (*init).into())) + Some((T::get_format(), (*init).into())) } } @@ -180,7 +180,7 @@ impl<'a, T: format::DepthStencilFormat> DataLink<'a> for DepthStencilTarget { fn new() -> Self { DepthStencilTarget(PhantomData) } fn is_active(&self) -> bool { true } fn link_depth_stencil(&mut self, init: &Self::Init) -> Option { - Some((T::get_format().0, (*init).into())) + Some((T::get_format(), (*init).into())) } } From 924637a6bc1481ec7c8e6b0d65a896a5acf7a5b3 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Sun, 22 May 2016 22:38:54 -0400 Subject: [PATCH 45/69] [vk] render sub pass --- src/backend/vulkan/src/factory.rs | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index 3e2a4eec30a..b3373a585fa 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -419,7 +419,13 @@ impl core::Factory for Factory { }; let render_pass = { let mut attachments = Vec::new(); + let mut color_refs = Vec::new(); for col in desc.color_targets.iter().filter_map(|c| c.as_ref()) { + let layout = vk::IMAGE_LAYOUT_GENERAL; //TODO + color_refs.push(vk::AttachmentReference { + attachment: attachments.len() as u32, + layout: layout, + }); attachments.push(vk::AttachmentDescription { flags: 0, format: match data::map_format((col.0).0, (col.0).1) { @@ -431,10 +437,14 @@ impl core::Factory for Factory { storeOp: vk::ATTACHMENT_STORE_OP_STORE, stencilLoadOp: vk::ATTACHMENT_LOAD_OP_DONT_CARE, stencilStoreOp: vk::ATTACHMENT_STORE_OP_DONT_CARE, - initialLayout: vk::IMAGE_LAYOUT_GENERAL, //TODO - finalLayout: vk::IMAGE_LAYOUT_GENERAL, + initialLayout: layout, + finalLayout: layout, }); } + let ds_ref = vk::AttachmentReference { + attachment: attachments.len() as u32, + layout: vk::IMAGE_LAYOUT_GENERAL, //TODO + }; if let Some(ds) = desc.depth_stencil { attachments.push(vk::AttachmentDescription { flags: 0, @@ -451,14 +461,26 @@ impl core::Factory for Factory { finalLayout: vk::IMAGE_LAYOUT_GENERAL, }); } + let subpass = vk::SubpassDescription { + flags: 0, + pipelineBindPoint: vk::PIPELINE_BIND_POINT_GRAPHICS, + inputAttachmentCount: 0, + pInputAttachments: ptr::null(), + colorAttachmentCount: color_refs.len() as u32, + pColorAttachments: color_refs.as_ptr(), + pResolveAttachments: ptr::null(), + pDepthStencilAttachment: if desc.depth_stencil.is_some() {&ds_ref} else {ptr::null()}, + preserveAttachmentCount: 0, + pPreserveAttachments: ptr::null(), + }; let info = vk::RenderPassCreateInfo { sType: vk::STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, pNext: ptr::null(), flags: 0, attachmentCount: attachments.len() as u32, pAttachments: attachments.as_ptr(), - subpassCount: 0, - pSubpasses: ptr::null(), + subpassCount: 1, + pSubpasses: &subpass, dependencyCount: 0, pDependencies: ptr::null(), }; From f5de7955b686858008040e6897755046ad585608 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Mon, 23 May 2016 00:06:53 -0400 Subject: [PATCH 46/69] [pso] Moved the buffer descriptor out of the AttributeDesc --- src/backend/gl/src/command.rs | 13 +++++---- src/backend/gl/src/factory.rs | 12 ++++++-- src/backend/gl/src/lib.rs | 31 +++++++++++--------- src/backend/vulkan/src/factory.rs | 19 +++++++++++- src/core/src/pso.rs | 17 ++++++++++- src/render/src/macros/pso.rs | 8 +++++ src/render/src/macros/structure.rs | 5 +--- src/render/src/pso/buffer.rs | 47 ++++++++++++++++++++---------- src/render/src/pso/mod.rs | 3 ++ 9 files changed, 113 insertions(+), 42 deletions(-) diff --git a/src/backend/gl/src/command.rs b/src/backend/gl/src/command.rs index 219e92aeb29..c19216a4f15 100644 --- a/src/backend/gl/src/command.rs +++ b/src/backend/gl/src/command.rs @@ -19,7 +19,7 @@ use gfx_core as c; use gfx_core::draw; use gfx_core::state as s; use gfx_core::target::{ColorValue, Depth, Mirror, Rect, Stencil}; -use {Buffer, Program, FrameBuffer, Texture, +use {Buffer, BufferElement, Program, FrameBuffer, Texture, NewTexture, Resources, PipelineState, ResourceView, TargetView}; @@ -68,6 +68,7 @@ impl DataBuffer { } } + ///Serialized device command. #[derive(Clone, Copy, Debug)] pub enum Command { @@ -78,7 +79,7 @@ pub enum Command { BindUnorderedView(c::pso::UnorderedViewParam), BindSampler(c::pso::SamplerParam, Option), BindPixelTargets(c::pso::PixelTargetSet), - BindAttribute(c::AttributeSlot, Buffer, c::pso::AttributeDesc), + BindAttribute(c::AttributeSlot, Buffer, BufferElement), BindIndex(Buffer), BindFrameBuffer(Access, FrameBuffer), BindUniform(c::shade::Location, c::shade::UniformValue), @@ -134,7 +135,7 @@ pub const RESET: [Command; 13] = [ struct Cache { primitive: gl::types::GLenum, index_type: c::IndexType, - attributes: [Option; c::MAX_VERTEX_ATTRIBUTES], + attributes: [Option; c::MAX_VERTEX_ATTRIBUTES], resource_binds: [Option; c::MAX_RESOURCE_VIEWS], scissor: bool, stencil: Option, @@ -215,9 +216,9 @@ impl c::draw::CommandBuffer for CommandBuffer { (None, Some(fm)) => { error!("No vertex input provided for slot {} of format {:?}", i, fm) }, - (Some((buffer, offset)), Some(mut format)) => { - format.0.offset += offset as gl::types::GLuint; - self.buf.push(Command::BindAttribute(i as c::AttributeSlot, buffer, format)); + (Some((buffer, offset)), Some(mut bel)) => { + bel.elem.offset += offset as gl::types::GLuint; + self.buf.push(Command::BindAttribute(i as c::AttributeSlot, buffer, bel)); }, (_, None) => (), } diff --git a/src/backend/gl/src/factory.rs b/src/backend/gl/src/factory.rs index 29630908b5b..2b1c44159fc 100644 --- a/src/backend/gl/src/factory.rs +++ b/src/backend/gl/src/factory.rs @@ -28,7 +28,8 @@ use gfx_core::tex as t; use command::{CommandBuffer, COLOR_DEFAULT}; use {Resources as R, Share, OutputMerger}; -use {Buffer, FatSampler, NewTexture, PipelineState, ResourceView, TargetView}; +use {Buffer, BufferElement, FatSampler, NewTexture, + PipelineState, ResourceView, TargetView}; fn role_to_target(role: f::BufferRole) -> gl::types::GLenum { @@ -261,10 +262,17 @@ impl d::Factory for Factory { } } } + let mut inputs = [None; d::MAX_VERTEX_ATTRIBUTES]; + for i in 0 .. d::MAX_VERTEX_ATTRIBUTES { + inputs[i] = desc.attributes[i].map(|at| BufferElement { + desc: desc.vertex_buffers[at.0 as usize].unwrap(), + elem: at.1, + }); + } let pso = PipelineState { program: *self.frame_handles.ref_program(program), primitive: desc.primitive, - input: desc.attributes, + input: inputs, scissor: desc.scissor, rasterizer: desc.rasterizer, output: output, diff --git a/src/backend/gl/src/lib.rs b/src/backend/gl/src/lib.rs index d2edac45b2e..fc2608bec9b 100644 --- a/src/backend/gl/src/lib.rs +++ b/src/backend/gl/src/lib.rs @@ -75,6 +75,12 @@ impl d::Resources for Resources { type Fence = Fence; } +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +pub struct BufferElement { + pub desc: d::pso::BufferDesc, + pub elem: d::pso::Element, +} + #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct OutputMerger { pub draw_mask: u32, @@ -87,7 +93,7 @@ pub struct OutputMerger { pub struct PipelineState { program: Program, primitive: d::Primitive, - input: [Option; d::MAX_VERTEX_ATTRIBUTES], + input: [Option; d::MAX_VERTEX_ATTRIBUTES], scissor: bool, rasterizer: s::Rasterizer, output: OutputMerger, @@ -294,11 +300,10 @@ impl Device { &self.info } - fn bind_attribute(&mut self, slot: d::AttributeSlot, buffer: Buffer, - (elem, instance_rate): d::pso::AttributeDesc) { + fn bind_attribute(&mut self, slot: d::AttributeSlot, buffer: Buffer, bel: BufferElement) { use gfx_core::format::SurfaceType as S; use gfx_core::format::ChannelType as C; - let (fm8, fm16, fm32) = match elem.format.1 { + let (fm8, fm16, fm32) = match bel.elem.format.1 { C::Int | C::Inorm => (gl::BYTE, gl::SHORT, gl::INT), C::Uint | C::Unorm => @@ -309,7 +314,7 @@ impl Device { return } }; - let (count, gl_type) = match elem.format.0 { + let (count, gl_type) = match bel.elem.format.0 { S::R8 => (1, fm8), S::R8_G8 => (2, fm8), S::R8_G8_B8_A8 => (4, fm8), @@ -322,15 +327,15 @@ impl Device { S::R32_G32_B32 => (3, fm32), S::R32_G32_B32_A32 => (4, fm32), _ => { - error!("Unsupported element type: {:?}", elem.format.0); + error!("Unsupported element type: {:?}", bel.elem.format.0); return } }; let gl = &self.share.context; unsafe { gl.BindBuffer(gl::ARRAY_BUFFER, buffer) }; - let offset = elem.offset as *const gl::types::GLvoid; - let stride = elem.stride as gl::types::GLint; - match elem.format.1 { + let offset = bel.elem.offset as *const gl::types::GLvoid; + let stride = bel.desc.stride as gl::types::GLint; + match bel.elem.format.1 { C::Int | C::Uint => unsafe { gl.VertexAttribIPointer(slot as gl::types::GLuint, count, gl_type, stride, offset); @@ -352,8 +357,8 @@ impl Device { unsafe { gl.EnableVertexAttribArray(slot as gl::types::GLuint) }; if self.share.capabilities.instance_rate_supported { unsafe { gl.VertexAttribDivisor(slot as gl::types::GLuint, - instance_rate as gl::types::GLuint) }; - }else if instance_rate != 0 { + bel.desc.rate as gl::types::GLuint) }; + }else if bel.desc.rate != 0 { error!("Instanced arrays are not supported"); } } @@ -490,8 +495,8 @@ impl Device { self.bind_target(point, gl::STENCIL_ATTACHMENT, stencil); } }, - Command::BindAttribute(slot, buffer, desc) => { - self.bind_attribute(slot, buffer, desc); + Command::BindAttribute(slot, buffer, bel) => { + self.bind_attribute(slot, buffer, bel); }, Command::BindIndex(buffer) => { let gl = &self.share.context; diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index b3373a585fa..7dabf22e1b0 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -491,13 +491,30 @@ impl core::Factory for Factory { out }; let pipeline = { + let vertex_bindings = desc.vertex_buffers.iter().enumerate().filter_map(|(i, at)| + at.map(|a| vk::VertexInputBindingDescription { + binding: i as u32, + stride: a.stride as u32, + inputRate: a.rate as vk::VertexInputRate, + }) + ).collect::>(); + let vertex_attributes = Vec::new(); + let vertex_input = vk::PipelineVertexInputStateCreateInfo { + sType: vk::STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + vertexBindingDescriptionCount: vertex_bindings.len() as u32, + pVertexBindingDescriptions: vertex_bindings.as_ptr(), + vertexAttributeDescriptionCount: vertex_attributes.len() as u32, + pVertexAttributeDescriptions: vertex_attributes.as_ptr(), + }; let info = vk::GraphicsPipelineCreateInfo { sType: vk::STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, pNext: ptr::null(), flags: 0, stageCount: stages.len() as u32, pStages: stages.as_ptr(), - pVertexInputState: ptr::null(), //TODO + pVertexInputState: &vertex_input, pInputAssemblyState: ptr::null(), //TODO pTessellationState: ptr::null(), pViewportState: ptr::null(), //TODO diff --git a/src/core/src/pso.rs b/src/core/src/pso.rs index 9c32dad9342..e76ff747837 100644 --- a/src/core/src/pso.rs +++ b/src/core/src/pso.rs @@ -28,6 +28,9 @@ use std::error::Error; use std::fmt; +/// Maximum number of vertex buffers used in a PSO definition. +pub const MAX_VERTEX_BUFFERS: usize = 4; + /// An offset inside a vertex buffer, in bytes. pub type BufferOffset = usize; @@ -114,6 +117,8 @@ impl From<(s::Depth, s::Stencil)> for DepthStencilInfo { } } +/// Index of a vertex buffer. +pub type BufferIndex = u8; /// Offset of an attribute from the start of the buffer, in bytes pub type ElemOffset = u32; /// Offset between attribute values, in bytes @@ -128,12 +133,19 @@ pub struct Element { pub format: F, /// Offset from the beginning of the container, in bytes pub offset: ElemOffset, +} + +/// Vertex buffer descriptor +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct BufferDesc { /// Total container size, in bytes pub stride: ElemStride, + /// Rate of the input for the given buffer + pub rate: InstanceRate, } /// PSO vertex attribute descriptor -pub type AttributeDesc = (Element, InstanceRate); +pub type AttributeDesc = (BufferIndex, Element); /// PSO color target descriptor pub type ColorTargetDesc = (format::Format, ColorInfo); /// PSO depth-stencil target descriptor @@ -149,6 +161,8 @@ pub struct Descriptor { pub rasterizer: s::Rasterizer, /// Enable scissor test pub scissor: bool, + /// Vertex buffers + pub vertex_buffers: [Option; MAX_VERTEX_BUFFERS], /// Vertex attributes pub attributes: [Option; MAX_VERTEX_ATTRIBUTES], /// Render target views (RTV) @@ -164,6 +178,7 @@ impl Descriptor { primitive: primitive, rasterizer: rast, scissor: false, + vertex_buffers: [None; MAX_VERTEX_BUFFERS], attributes: [None; MAX_VERTEX_ATTRIBUTES], color_targets: [None; MAX_COLOR_TARGETS], depth_stencil: None, diff --git a/src/render/src/macros/pso.rs b/src/render/src/macros/pso.rs index 0488619818e..e94c09ecb67 100644 --- a/src/render/src/macros/pso.rs +++ b/src/render/src/macros/pso.rs @@ -43,6 +43,14 @@ macro_rules! gfx_pipeline_inner { $( $field: <$ty as DataLink<'a>>::new(), )* }; // v# + let mut _num_vb = 0; + $( + if let Some(vd) = meta.$field.link_vertex_buffer(_num_vb, &self.$field) { + assert!(meta.$field.is_active()); + desc.vertex_buffers[_num_vb as usize] = Some(vd); + _num_vb += 1; + } + )* for at in &info.vertex_attributes { $( match meta.$field.link_input(at, &self.$field) { diff --git a/src/render/src/macros/structure.rs b/src/render/src/macros/structure.rs index 2b35063bc6f..f08c769053c 100644 --- a/src/render/src/macros/structure.rs +++ b/src/render/src/macros/structure.rs @@ -28,9 +28,7 @@ macro_rules! gfx_impl_struct { impl $crate::pso::buffer::Structure<$runtime_format> for $root { fn query(name: &str) -> Option<$crate::pso::buffer::Element<$runtime_format>> { - use std::mem::size_of; - use $crate::pso::buffer::{Element, ElemOffset, ElemStride}; - let stride = size_of::<$root>() as ElemStride; + use $crate::pso::buffer::{Element, ElemOffset}; let tmp: &$root = unsafe{ ::std::mem::uninitialized() }; let base = tmp as *const _ as usize; //HACK: special treatment of array queries @@ -54,7 +52,6 @@ macro_rules! gfx_impl_struct { $name => Some(Element { format: <$ty as $compile_format>::get_format(), offset: ((&tmp.$field as *const _ as usize) - base) as ElemOffset + big_offset, - stride: stride, }), )* _ => None, diff --git a/src/render/src/pso/buffer.rs b/src/render/src/pso/buffer.rs index 3743361e1ba..e70c3e8e5b9 100644 --- a/src/render/src/pso/buffer.rs +++ b/src/render/src/pso/buffer.rs @@ -22,7 +22,7 @@ use gfx_core::format::Format; use shade::{ToUniform, Usage}; use super::{DataLink, DataBind, ElementError, RawDataSet}; -pub use gfx_core::pso::{Element, ElemOffset, ElemStride, InstanceRate}; +pub use gfx_core::pso::{BufferIndex, Element, ElemOffset, ElemStride, InstanceRate}; /// A trait to be implemented by any struct having the layout described /// in the graphics API, like a vertex buffer. @@ -41,9 +41,9 @@ pub type VertexBuffer = VertexBufferCommon; /// Instance buffer component. Same as the vertex buffer but advances per instance. pub type InstanceBuffer = VertexBufferCommon; /// Raw vertex/instance buffer component. -/// - init: ? +/// - init: `(&[&str, element], stride, inst_rate)` /// - data: `RawBuffer` -pub struct RawVertexBuffer(AttributeSlotSet); +pub struct RawVertexBuffer(Option, AttributeSlotSet); /// Constant buffer component. /// - init: `&str` = name of the buffer /// - data: `Buffer` @@ -65,16 +65,25 @@ impl<'a, > DataLink<'a> for VertexBufferCommon { type Init = (); fn new() -> Self { - VertexBufferCommon(RawVertexBuffer(0), PhantomData) + VertexBufferCommon(DataLink::new(), PhantomData) } fn is_active(&self) -> bool { self.0.is_active() } + fn link_vertex_buffer(&mut self, index: BufferIndex, _: &Self::Init) + -> Option { + use std::mem; + (self.0).0 = Some(index); + let rate = ::default().as_ref().len(); + Some(pso::BufferDesc { + stride: mem::size_of::() as ElemStride, + rate: rate as InstanceRate, + }) + } fn link_input(&mut self, at: &shade::AttributeVar, _: &Self::Init) -> Option> { T::query(&at.name).map(|el| { - let rate = ::default().as_ref().len(); - self.0.link(at, el, rate as InstanceRate) + self.0.link(at, el) }) } } @@ -87,11 +96,11 @@ impl DataBind for VertexBufferCommon { } impl RawVertexBuffer { - fn link(&mut self, at: &shade::AttributeVar, el: Element, rate: InstanceRate) + fn link(&mut self, at: &shade::AttributeVar, el: Element) -> Result { - self.0 |= 1 << (at.slot as AttributeSlotSet); + self.1 |= 1 << (at.slot as AttributeSlotSet); if match_attribute(at, el.format) { - Ok((el, rate)) + Ok((self.0.unwrap(), el)) }else { Err(el.format) } @@ -99,17 +108,25 @@ impl RawVertexBuffer { } impl<'a> DataLink<'a> for RawVertexBuffer { - type Init = &'a [(&'a str, Element, InstanceRate)]; + type Init = (&'a [(&'a str, Element)], ElemStride, InstanceRate); fn new() -> Self { - RawVertexBuffer(0) + RawVertexBuffer(None, 0) } fn is_active(&self) -> bool { - self.0 != 0 + self.0.is_some() + } + fn link_vertex_buffer(&mut self, index: BufferIndex, init: &Self::Init) + -> Option { + self.0 = Some(index); + Some(pso::BufferDesc { + stride: init.1, + rate: init.2, + }) } fn link_input(&mut self, at: &shade::AttributeVar, init: &Self::Init) -> Option> { - init.iter().find(|x| x.0 == &at.name) - .map(|x| self.link(at, x.1, x.2)) + init.0.iter().find(|x| x.0 == &at.name) + .map(|x| self.link(at, x.1)) } } @@ -118,7 +135,7 @@ impl DataBind for RawVertexBuffer { fn bind_to(&self, out: &mut RawDataSet, data: &Self::Data, man: &mut handle::Manager) { let value = Some((man.ref_buffer(data).clone(), 0)); for i in 0 .. MAX_VERTEX_ATTRIBUTES { - if (self.0 & (1<: Sized { fn new() -> Self; /// Check if this link is actually used by the shader. fn is_active(&self) -> bool; + /// Attempt to link with a vertex buffer containing multiple attributes. + fn link_vertex_buffer(&mut self, _: d::pso::BufferIndex, _: &Self::Init) -> + Option { None } /// Attempt to link with a vertex attribute. fn link_input(&mut self, _: &d::shade::AttributeVar, _: &Self::Init) -> Option> { None } From ab7ab55f4abef72a25f85c71eaf685f47bd608f8 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Mon, 23 May 2016 00:15:06 -0400 Subject: [PATCH 47/69] [vk] pipeline vertex attributes --- src/backend/vulkan/src/factory.rs | 32 +++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index 7dabf22e1b0..cd2232f54bc 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -491,14 +491,30 @@ impl core::Factory for Factory { out }; let pipeline = { - let vertex_bindings = desc.vertex_buffers.iter().enumerate().filter_map(|(i, at)| - at.map(|a| vk::VertexInputBindingDescription { - binding: i as u32, - stride: a.stride as u32, - inputRate: a.rate as vk::VertexInputRate, - }) - ).collect::>(); - let vertex_attributes = Vec::new(); + let mut vertex_bindings = Vec::new(); + for (i, vbuf) in desc.vertex_buffers.iter().enumerate() { + if let &Some(v) = vbuf { + vertex_bindings.push(vk::VertexInputBindingDescription { + binding: i as u32, + stride: v.stride as u32, + inputRate: v.rate as vk::VertexInputRate, + }); + } + } + let mut vertex_attributes = Vec::new(); + for (i, attr) in desc.attributes.iter().enumerate() { + if let &Some(a) = attr { + vertex_attributes.push(vk::VertexInputAttributeDescription { + location: i as u32, + binding: a.0 as u32, + format: match data::map_format(a.1.format.0, a.1.format.1) { + Some(fm) => fm, + None => return Err(core::pso::CreationError), + }, + offset: a.1.offset as u32, + }); + } + } let vertex_input = vk::PipelineVertexInputStateCreateInfo { sType: vk::STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, pNext: ptr::null(), From b30909586b84624c4d3437abe9ad70f840ef642f Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Mon, 23 May 2016 22:22:55 -0400 Subject: [PATCH 48/69] [vk] pipeline input assembly --- src/backend/vulkan/src/data.rs | 12 +++++++++++- src/backend/vulkan/src/factory.rs | 9 ++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/backend/vulkan/src/data.rs b/src/backend/vulkan/src/data.rs index 50bd0ea66eb..9764f504fe7 100644 --- a/src/backend/vulkan/src/data.rs +++ b/src/backend/vulkan/src/data.rs @@ -15,7 +15,7 @@ use gfx_core::factory::{Bind, MapAccess, Usage, LayerError}; use gfx_core::format::{SurfaceType, ChannelType, Swizzle, ChannelSource}; use gfx_core::tex::{FilterMethod, Kind, Layer, PackedColor, WrapMode}; -use gfx_core::state; +use gfx_core::{state, Primitive}; use vk; @@ -300,3 +300,13 @@ pub fn map_comparison(fun: state::Comparison) -> vk::CompareOp { Always => vk::COMPARE_OP_ALWAYS, } } + +pub fn map_topology(prim: Primitive) -> vk::PrimitiveTopology { + match prim { + Primitive::PointList => vk::PRIMITIVE_TOPOLOGY_POINT_LIST, + Primitive::LineList => vk::PRIMITIVE_TOPOLOGY_LINE_LIST, + Primitive::LineStrip => vk::PRIMITIVE_TOPOLOGY_LINE_STRIP, + Primitive::TriangleList => vk::PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + Primitive::TriangleStrip => vk::PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, + } +} diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index cd2232f54bc..8318524dbef 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -524,6 +524,13 @@ impl core::Factory for Factory { vertexAttributeDescriptionCount: vertex_attributes.len() as u32, pVertexAttributeDescriptions: vertex_attributes.as_ptr(), }; + let input_assembly = vk::PipelineInputAssemblyStateCreateInfo { + sType: vk::STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + topology: data::map_topology(desc.primitive), + primitiveRestartEnable: vk::FALSE, + }; let info = vk::GraphicsPipelineCreateInfo { sType: vk::STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, pNext: ptr::null(), @@ -531,7 +538,7 @@ impl core::Factory for Factory { stageCount: stages.len() as u32, pStages: stages.as_ptr(), pVertexInputState: &vertex_input, - pInputAssemblyState: ptr::null(), //TODO + pInputAssemblyState: &input_assembly, pTessellationState: ptr::null(), pViewportState: ptr::null(), //TODO pRasterizationState: ptr::null(), //TODO From e5c16ba0e7fc52b4b188aa62ad1870c6f1bb68ea Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Mon, 23 May 2016 22:41:21 -0400 Subject: [PATCH 49/69] [vk] pipeline viewport, scissor, and dynamic state --- src/backend/vulkan/src/factory.rs | 92 ++++++++++++++++++++----------- 1 file changed, 59 insertions(+), 33 deletions(-) diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index 8318524dbef..fd323d6f1ef 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -461,18 +461,6 @@ impl core::Factory for Factory { finalLayout: vk::IMAGE_LAYOUT_GENERAL, }); } - let subpass = vk::SubpassDescription { - flags: 0, - pipelineBindPoint: vk::PIPELINE_BIND_POINT_GRAPHICS, - inputAttachmentCount: 0, - pInputAttachments: ptr::null(), - colorAttachmentCount: color_refs.len() as u32, - pColorAttachments: color_refs.as_ptr(), - pResolveAttachments: ptr::null(), - pDepthStencilAttachment: if desc.depth_stencil.is_some() {&ds_ref} else {ptr::null()}, - preserveAttachmentCount: 0, - pPreserveAttachments: ptr::null(), - }; let info = vk::RenderPassCreateInfo { sType: vk::STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, pNext: ptr::null(), @@ -480,7 +468,18 @@ impl core::Factory for Factory { attachmentCount: attachments.len() as u32, pAttachments: attachments.as_ptr(), subpassCount: 1, - pSubpasses: &subpass, + pSubpasses: &vk::SubpassDescription { + flags: 0, + pipelineBindPoint: vk::PIPELINE_BIND_POINT_GRAPHICS, + inputAttachmentCount: 0, + pInputAttachments: ptr::null(), + colorAttachmentCount: color_refs.len() as u32, + pColorAttachments: color_refs.as_ptr(), + pResolveAttachments: ptr::null(), + pDepthStencilAttachment: if desc.depth_stencil.is_some() {&ds_ref} else {ptr::null()}, + preserveAttachmentCount: 0, + pPreserveAttachments: ptr::null(), + }, dependencyCount: 0, pDependencies: ptr::null(), }; @@ -515,37 +514,64 @@ impl core::Factory for Factory { }); } } - let vertex_input = vk::PipelineVertexInputStateCreateInfo { - sType: vk::STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - pNext: ptr::null(), - flags: 0, - vertexBindingDescriptionCount: vertex_bindings.len() as u32, - pVertexBindingDescriptions: vertex_bindings.as_ptr(), - vertexAttributeDescriptionCount: vertex_attributes.len() as u32, - pVertexAttributeDescriptions: vertex_attributes.as_ptr(), - }; - let input_assembly = vk::PipelineInputAssemblyStateCreateInfo { - sType: vk::STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, - pNext: ptr::null(), - flags: 0, - topology: data::map_topology(desc.primitive), - primitiveRestartEnable: vk::FALSE, - }; let info = vk::GraphicsPipelineCreateInfo { sType: vk::STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, pNext: ptr::null(), flags: 0, stageCount: stages.len() as u32, pStages: stages.as_ptr(), - pVertexInputState: &vertex_input, - pInputAssemblyState: &input_assembly, + pVertexInputState: &vk::PipelineVertexInputStateCreateInfo { + sType: vk::STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + vertexBindingDescriptionCount: vertex_bindings.len() as u32, + pVertexBindingDescriptions: vertex_bindings.as_ptr(), + vertexAttributeDescriptionCount: vertex_attributes.len() as u32, + pVertexAttributeDescriptions: vertex_attributes.as_ptr(), + }, + pInputAssemblyState: &vk::PipelineInputAssemblyStateCreateInfo { + sType: vk::STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + topology: data::map_topology(desc.primitive), + primitiveRestartEnable: vk::FALSE, + }, pTessellationState: ptr::null(), - pViewportState: ptr::null(), //TODO + pViewportState: &vk::PipelineViewportStateCreateInfo { + sType: vk::STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + viewportCount: 1, + pViewports: &vk::Viewport { + x: 0.0, + y: 0.0, + width: 1.0, + height: 1.0, + minDepth: 0.0, + maxDepth: 1.0, + }, + scissorCount: 1, + pScissors: &vk::Rect2D { + offset: vk::Offset2D { + x: 0, y: 0, + }, + extent: vk::Extent2D { + width: 1, height: 1, + }, + }, + }, pRasterizationState: ptr::null(), //TODO pMultisampleState: ptr::null(), //TODO pDepthStencilState: ptr::null(), //TODO pColorBlendState: ptr::null(), //TODO - pDynamicState: ptr::null(), + pDynamicState: &vk::PipelineDynamicStateCreateInfo { + sType: vk::STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + dynamicStateCount: 1, + pDynamicStates: [vk::DYNAMIC_STATE_VIEWPORT, vk::DYNAMIC_STATE_SCISSOR, + vk::DYNAMIC_STATE_STENCIL_REFERENCE].as_ptr(), + }, layout: pipe_layout, renderPass: render_pass, subpass: 0, From f3d4c9feef9441cd29beb066f344f571969e17fa Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Mon, 23 May 2016 23:00:46 -0400 Subject: [PATCH 50/69] [vk] pipeline rasterization state --- src/backend/vulkan/src/data.rs | 23 +++++++++++++++++++++++ src/backend/vulkan/src/factory.rs | 17 ++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/backend/vulkan/src/data.rs b/src/backend/vulkan/src/data.rs index 9764f504fe7..600790993b3 100644 --- a/src/backend/vulkan/src/data.rs +++ b/src/backend/vulkan/src/data.rs @@ -310,3 +310,26 @@ pub fn map_topology(prim: Primitive) -> vk::PrimitiveTopology { Primitive::TriangleStrip => vk::PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, } } + +pub fn map_polygon_mode(rm: state::RasterMethod) -> (vk::PolygonMode, f32) { + match rm { + state::RasterMethod::Point => (vk::POLYGON_MODE_POINT, 1.0), + state::RasterMethod::Line(w) => (vk::POLYGON_MODE_LINE, w as f32), + state::RasterMethod::Fill => (vk::POLYGON_MODE_FILL, 1.0), + } +} + +pub fn map_cull_face(cf: state::CullFace) -> vk::CullModeFlagBits { + match cf { + state::CullFace::Nothing => vk::CULL_MODE_NONE, + state::CullFace::Front => vk::CULL_MODE_FRONT_BIT, + state::CullFace::Back => vk::CULL_MODE_BACK_BIT, + } +} + +pub fn map_front_face(ff: state::FrontFace) -> vk::FrontFace { + match ff { + state::FrontFace::Clockwise => vk::FRONT_FACE_CLOCKWISE, + state::FrontFace::CounterClockwise => vk::FRONT_FACE_COUNTER_CLOCKWISE, + } +} diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index fd323d6f1ef..395eeec1083 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -514,6 +514,7 @@ impl core::Factory for Factory { }); } } + let (polygon, line_width) = data::map_polygon_mode(desc.rasterizer.method); let info = vk::GraphicsPipelineCreateInfo { sType: vk::STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, pNext: ptr::null(), @@ -560,7 +561,21 @@ impl core::Factory for Factory { }, }, }, - pRasterizationState: ptr::null(), //TODO + pRasterizationState: &vk::PipelineRasterizationStateCreateInfo { + sType: vk::STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + depthClampEnable: vk::TRUE, + rasterizerDiscardEnable: vk::FALSE, + polygonMode: polygon, + cullMode: data::map_cull_face(desc.rasterizer.cull_face), + frontFace: data::map_front_face(desc.rasterizer.front_face), + depthBiasEnable: if desc.rasterizer.offset.is_some() { vk::TRUE } else { vk::FALSE }, + depthBiasConstantFactor: desc.rasterizer.offset.map_or(0.0, |off| off.1 as f32), + depthBiasClamp: 1.0, + depthBiasSlopeFactor: desc.rasterizer.offset.map_or(0.0, |off| off.0 as f32), + lineWidth: line_width, + }, pMultisampleState: ptr::null(), //TODO pDepthStencilState: ptr::null(), //TODO pColorBlendState: ptr::null(), //TODO From cdb5ac9359eb0c9efbfbebbec4d2fa95fc82a7e9 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Mon, 23 May 2016 23:04:29 -0400 Subject: [PATCH 51/69] [vk] pipeline multisample state (dummy) --- src/backend/vulkan/src/factory.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index 395eeec1083..decca8a0929 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -576,7 +576,17 @@ impl core::Factory for Factory { depthBiasSlopeFactor: desc.rasterizer.offset.map_or(0.0, |off| off.0 as f32), lineWidth: line_width, }, - pMultisampleState: ptr::null(), //TODO + pMultisampleState: &vk::PipelineMultisampleStateCreateInfo { + sType: vk::STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + rasterizationSamples: vk::SAMPLE_COUNT_1_BIT, //TODO + sampleShadingEnable: vk::FALSE, + minSampleShading: 0.0, + pSampleMask: ptr::null(), + alphaToCoverageEnable: vk::FALSE, + alphaToOneEnable: vk::FALSE, + }, pDepthStencilState: ptr::null(), //TODO pColorBlendState: ptr::null(), //TODO pDynamicState: &vk::PipelineDynamicStateCreateInfo { From f44eaa272e103f78ef77879ab31a9a41cc6f9bd8 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Tue, 24 May 2016 22:58:59 -0400 Subject: [PATCH 52/69] Improved LayerError --- src/core/src/factory.rs | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/core/src/factory.rs b/src/core/src/factory.rs index 6dc4af7d7ae..6102fdd1f10 100644 --- a/src/core/src/factory.rs +++ b/src/core/src/factory.rs @@ -182,6 +182,24 @@ pub enum LayerError { OutOfBounds(target::Layer, target::Layer), } +impl fmt::Display for LayerError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + LayerError::NotExpected(kind) => write!(f, "{}: {:?}", self.description(), kind), + LayerError::OutOfBounds(layer, count) => write!(f, "{}: {}/{}", self.description(), layer, count), + } + } +} + +impl Error for LayerError { + fn description(&self) -> &str { + match *self { + LayerError::NotExpected(_) => "The source texture kind doesn't support array slices", + LayerError::OutOfBounds(_, _) => "Selected layer is outside of the provided range", + } + } +} + /// Error creating either a ShaderResourceView, or UnorderedAccessView. #[derive(Clone, PartialEq, Debug)] pub enum ResourceViewError { @@ -197,10 +215,10 @@ pub enum ResourceViewError { impl fmt::Display for ResourceViewError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if let ResourceViewError::Channel(ref channel_type) = *self { - write!(f, "{}: {:?}", self.description(), channel_type) - } else { - write!(f, "{}", self.description()) + match *self { + ResourceViewError::Channel(ref channel_type) => write!(f, "{}: {:?}", self.description(), channel_type), + ResourceViewError::Layer(ref le) => write!(f, "{}: {}", self.description(), le), + _ => write!(f, "{}", self.description()) } } } @@ -210,6 +228,7 @@ impl Error for ResourceViewError { match *self { ResourceViewError::NoBindFlag => "The corresponding bind flag is not present in the texture", ResourceViewError::Channel(_) => "Selected channel type is not supported for this texture", + ResourceViewError::Layer(_) => "Selected layer can not be viewed for this texture", ResourceViewError::Unsupported => "The backend was refused for some reason", } } @@ -221,7 +240,7 @@ pub enum TargetViewError { /// The `RENDER_TARGET`/`DEPTH_STENCIL` flag is not present in the texture. NoBindFlag, /// Selected mip level doesn't exist. - BadLevel(target::Level), + Level(target::Level), /// Selected array layer doesn't exist. Layer(LayerError), /// Selected channel type is not supported for this texture. @@ -234,8 +253,8 @@ impl fmt::Display for TargetViewError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let description = self.description(); match *self { - TargetViewError::BadLevel(ref level) => write!(f, "{}: {}", description, level), - TargetViewError::BadLayer(ref layer) => write!(f, "{}: {}", description, layer), + TargetViewError::Level(ref level) => write!(f, "{}: {}", description, level), + TargetViewError::Layer(ref layer) => write!(f, "{}: {}", description, layer), TargetViewError::Channel(ref channel) => write!(f, "{}: {:?}", description, channel), _ => write!(f, "{}", description) } @@ -247,9 +266,9 @@ impl Error for TargetViewError { match *self { TargetViewError::NoBindFlag => "The `RENDER_TARGET`/`DEPTH_STENCIL` flag is not present in the texture", - TargetViewError::BadLevel(_) => + TargetViewError::Level(_) => "Selected mip level doesn't exist", - TargetViewError::BadLayer(_) => + TargetViewError::Layer(_) => "Selected array layer doesn't exist", TargetViewError::Channel(_) => "Selected channel type is not supported for this texture", From c4b573967a73e310221daa16a418823ade31c1e4 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Tue, 24 May 2016 23:01:02 -0400 Subject: [PATCH 53/69] Updated the tests --- tests/macros.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/macros.rs b/tests/macros.rs index 7e4a8b2c125..eabae307350 100644 --- a/tests/macros.rs +++ b/tests/macros.rs @@ -60,10 +60,9 @@ fn _test_raw(factory: &mut F) -> gfx::PipelineState wher let special = gfx::pso::buffer::Element { format: fm::Format(fm::SurfaceType::R32, fm::ChannelType::Float), offset: 0, - stride: 12, }; let init = testraw::Init { - vertex: &[("a_Special", special, 0)], + vertex: (&[("a_Special", special)], 12, 0), tex: "Specular", target: ("o_Color2", fm::Format(fm::SurfaceType::R8_G8_B8_A8, fm::ChannelType::Unorm), From c47fd22e33601e50eb043a245a4403598069dea7 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Tue, 24 May 2016 23:24:12 -0400 Subject: [PATCH 54/69] [vk] pipeline depth/stencil state --- src/backend/vulkan/src/data.rs | 26 +++++++++++++++++ src/backend/vulkan/src/factory.rs | 46 ++++++++++++++++++++++++++----- 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/src/backend/vulkan/src/data.rs b/src/backend/vulkan/src/data.rs index 600790993b3..d858e9db599 100644 --- a/src/backend/vulkan/src/data.rs +++ b/src/backend/vulkan/src/data.rs @@ -333,3 +333,29 @@ pub fn map_front_face(ff: state::FrontFace) -> vk::FrontFace { state::FrontFace::CounterClockwise => vk::FRONT_FACE_COUNTER_CLOCKWISE, } } + +pub fn map_stencil_op(op: state::StencilOp) -> vk::StencilOp { + use gfx_core::state::StencilOp::*; + match op { + Keep => vk::STENCIL_OP_KEEP, + Zero => vk::STENCIL_OP_ZERO, + Replace => vk::STENCIL_OP_REPLACE, + IncrementClamp => vk::STENCIL_OP_INCREMENT_AND_CLAMP, + IncrementWrap => vk::STENCIL_OP_INCREMENT_AND_WRAP, + DecrementClamp => vk::STENCIL_OP_DECREMENT_AND_CLAMP, + DecrementWrap => vk::STENCIL_OP_DECREMENT_AND_WRAP, + Invert => vk::STENCIL_OP_INVERT, + } +} + +pub fn map_stencil_side(side: &state::StencilSide) -> vk::StencilOpState { + vk::StencilOpState { + failOp: map_stencil_op(side.op_fail), + passOp: map_stencil_op(side.op_pass), + depthFailOp: map_stencil_op(side.op_depth_fail), + compareOp: map_comparison(side.fun), + compareMask: side.mask_read as u32, + writeMask: side.mask_write as u32, + reference: 0, + } +} diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index decca8a0929..e9eeb72b7ef 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -14,7 +14,7 @@ use std::{cell, mem, ptr, slice}; use std::os::raw::c_void; -use gfx_core::{self as core, handle as h, factory as f, state}; +use gfx_core::{self as core, handle as h, factory as f, pso, state}; use vk; use {command, data, native}; use {Resources as R, SharePointer}; @@ -366,8 +366,8 @@ impl core::Factory for Factory { Ok(self.share.handles.borrow_mut().make_program(prog, info)) } - fn create_pipeline_state_raw(&mut self, program: &h::Program, desc: &core::pso::Descriptor) - -> Result, core::pso::CreationError> { + fn create_pipeline_state_raw(&mut self, program: &h::Program, desc: &pso::Descriptor) + -> Result, pso::CreationError> { use gfx_core::handle::Producer; let stages = self.get_shader_stages(program); let (dev, vk) = self.share.get_device(); @@ -430,7 +430,7 @@ impl core::Factory for Factory { flags: 0, format: match data::map_format((col.0).0, (col.0).1) { Some(fm) => fm, - None => return Err(core::pso::CreationError), + None => return Err(pso::CreationError), }, samples: vk::SAMPLE_COUNT_1_BIT, //TODO loadOp: vk::ATTACHMENT_LOAD_OP_LOAD, @@ -450,7 +450,7 @@ impl core::Factory for Factory { flags: 0, format: match data::map_format((ds.0).0, (ds.0).1) { Some(fm) => fm, - None => return Err(core::pso::CreationError), + None => return Err(pso::CreationError), }, samples: vk::SAMPLE_COUNT_1_BIT, //TODO loadOp: vk::ATTACHMENT_LOAD_OP_LOAD, @@ -508,7 +508,7 @@ impl core::Factory for Factory { binding: a.0 as u32, format: match data::map_format(a.1.format.0, a.1.format.1) { Some(fm) => fm, - None => return Err(core::pso::CreationError), + None => return Err(pso::CreationError), }, offset: a.1.offset as u32, }); @@ -587,7 +587,39 @@ impl core::Factory for Factory { alphaToCoverageEnable: vk::FALSE, alphaToOneEnable: vk::FALSE, }, - pDepthStencilState: ptr::null(), //TODO + pDepthStencilState: &vk::PipelineDepthStencilStateCreateInfo { + sType: vk::STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + depthTestEnable: match desc.depth_stencil { + Some((_, pso::DepthStencilInfo { depth: Some(_), ..} )) => vk::TRUE, + _ => vk::FALSE, + }, + depthWriteEnable: match desc.depth_stencil { + Some((_, pso::DepthStencilInfo { depth: Some(state::Depth { write: true, ..}), ..} )) => vk::TRUE, + _ => vk::FALSE, + }, + depthCompareOp: match desc.depth_stencil { + Some((_, pso::DepthStencilInfo { depth: Some(state::Depth { fun, ..}), ..} )) => data::map_comparison(fun), + _ => vk::COMPARE_OP_NEVER, + }, + depthBoundsTestEnable: vk::FALSE, + stencilTestEnable: match desc.depth_stencil { + Some((_, pso::DepthStencilInfo { front: Some(_), ..} )) => vk::TRUE, + Some((_, pso::DepthStencilInfo { back: Some(_), ..} )) => vk::TRUE, + _ => vk::FALSE, + }, + front: match desc.depth_stencil { + Some((_, pso::DepthStencilInfo { front: Some(ref s), ..} )) => data::map_stencil_side(s), + _ => unsafe { mem::zeroed() }, + }, + back: match desc.depth_stencil { + Some((_, pso::DepthStencilInfo { back: Some(ref s), ..} )) => data::map_stencil_side(s), + _ => unsafe { mem::zeroed() }, + }, + minDepthBounds: 0.0, + maxDepthBounds: 1.0, + }, pColorBlendState: ptr::null(), //TODO pDynamicState: &vk::PipelineDynamicStateCreateInfo { sType: vk::STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, From 148a651e0df246391be0b7365a6fcf448d045213 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Wed, 25 May 2016 23:11:21 -0400 Subject: [PATCH 55/69] [vk] pipeline blending --- src/backend/vulkan/src/data.rs | 51 +++++++++++++++++++++++++++++++ src/backend/vulkan/src/factory.rs | 25 +++++++++++++-- 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/src/backend/vulkan/src/data.rs b/src/backend/vulkan/src/data.rs index d858e9db599..a5507b02af3 100644 --- a/src/backend/vulkan/src/data.rs +++ b/src/backend/vulkan/src/data.rs @@ -14,6 +14,7 @@ use gfx_core::factory::{Bind, MapAccess, Usage, LayerError}; use gfx_core::format::{SurfaceType, ChannelType, Swizzle, ChannelSource}; +use gfx_core::pso::ColorInfo; use gfx_core::tex::{FilterMethod, Kind, Layer, PackedColor, WrapMode}; use gfx_core::{state, Primitive}; use vk; @@ -359,3 +360,53 @@ pub fn map_stencil_side(side: &state::StencilSide) -> vk::StencilOpState { reference: 0, } } + +pub fn map_blend_factor(factor: state::Factor) -> vk::BlendFactor { + use gfx_core::state::Factor::*; + use gfx_core::state::BlendValue::*; + match factor { + Zero => vk::BLEND_FACTOR_ZERO, + One => vk::BLEND_FACTOR_ONE, + SourceAlphaSaturated => vk::BLEND_FACTOR_SRC_ALPHA_SATURATE, + ZeroPlus(SourceColor) => vk::BLEND_FACTOR_SRC_COLOR, + ZeroPlus(SourceAlpha) => vk::BLEND_FACTOR_SRC_ALPHA, + ZeroPlus(DestColor) => vk::BLEND_FACTOR_DST_COLOR, + ZeroPlus(DestAlpha) => vk::BLEND_FACTOR_DST_ALPHA, + ZeroPlus(ConstColor) => vk::BLEND_FACTOR_CONSTANT_COLOR, + ZeroPlus(ConstAlpha) => vk::BLEND_FACTOR_CONSTANT_ALPHA, + OneMinus(SourceColor) => vk::BLEND_FACTOR_ONE_MINUS_SRC_COLOR, + OneMinus(SourceAlpha) => vk::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + OneMinus(DestColor) => vk::BLEND_FACTOR_ONE_MINUS_DST_COLOR, + OneMinus(DestAlpha) => vk::BLEND_FACTOR_ONE_MINUS_DST_ALPHA, + OneMinus(ConstColor) => vk::BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, + OneMinus(ConstAlpha) => vk::BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA, + } +} + +pub fn map_blend_op(op: state::Equation) -> vk::BlendOp { + use gfx_core::state::Equation::*; + match op { + Add => vk::BLEND_OP_ADD, + Sub => vk::BLEND_OP_SUBTRACT, + RevSub => vk::BLEND_OP_REVERSE_SUBTRACT, + Min => vk::BLEND_OP_MIN, + Max => vk::BLEND_OP_MAX, + } +} + +pub fn map_blend(ci: &ColorInfo) -> vk::PipelineColorBlendAttachmentState { + vk::PipelineColorBlendAttachmentState { + blendEnable: if ci.color.is_some() || ci.alpha.is_some() { vk::TRUE } else { vk::FALSE }, + srcColorBlendFactor: ci.color.map_or(0, |c| map_blend_factor(c.source)), + dstColorBlendFactor: ci.color.map_or(0, |c| map_blend_factor(c.destination)), + colorBlendOp: ci.color.map_or(0, |c| map_blend_op(c.equation)), + srcAlphaBlendFactor: ci.alpha.map_or(0, |a| map_blend_factor(a.source)), + dstAlphaBlendFactor: ci.alpha.map_or(0, |a| map_blend_factor(a.destination)), + alphaBlendOp: ci.alpha.map_or(0, |a| map_blend_op(a.equation)), + colorWriteMask: + if ci.mask.contains(state::RED) {vk::COLOR_COMPONENT_R_BIT} else {0} | + if ci.mask.contains(state::GREEN) {vk::COLOR_COMPONENT_G_BIT} else {0} | + if ci.mask.contains(state::BLUE) {vk::COLOR_COMPONENT_B_BIT} else {0} | + if ci.mask.contains(state::ALPHA) {vk::COLOR_COMPONENT_A_BIT} else {0}, + } +} diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index e9eeb72b7ef..a15a3a6bc9d 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -514,6 +514,12 @@ impl core::Factory for Factory { }); } } + let mut attachments = Vec::new(); + for ocd in desc.color_targets.iter() { + if let &Some(ref cd) = ocd { + attachments.push(data::map_blend(&cd.1)); + } + } let (polygon, line_width) = data::map_polygon_mode(desc.rasterizer.method); let info = vk::GraphicsPipelineCreateInfo { sType: vk::STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, @@ -620,14 +626,27 @@ impl core::Factory for Factory { minDepthBounds: 0.0, maxDepthBounds: 1.0, }, - pColorBlendState: ptr::null(), //TODO + pColorBlendState: &vk::PipelineColorBlendStateCreateInfo { + sType: vk::STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + logicOpEnable: vk::FALSE, + logicOp: vk::LOGIC_OP_CLEAR, + attachmentCount: attachments.len() as u32, + pAttachments: attachments.as_ptr(), + blendConstants: [0.0; 4], + }, pDynamicState: &vk::PipelineDynamicStateCreateInfo { sType: vk::STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, pNext: ptr::null(), flags: 0, dynamicStateCount: 1, - pDynamicStates: [vk::DYNAMIC_STATE_VIEWPORT, vk::DYNAMIC_STATE_SCISSOR, - vk::DYNAMIC_STATE_STENCIL_REFERENCE].as_ptr(), + pDynamicStates: [ + vk::DYNAMIC_STATE_VIEWPORT, + vk::DYNAMIC_STATE_SCISSOR, + vk::DYNAMIC_STATE_BLEND_CONSTANTS, + vk::DYNAMIC_STATE_STENCIL_REFERENCE, + ].as_ptr(), }, layout: pipe_layout, renderPass: render_pass, From a92099b75da36fd4c0639d58cb4597878476c927 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Wed, 25 May 2016 23:49:39 -0400 Subject: [PATCH 56/69] [vk] application launcher support --- Cargo.toml | 2 ++ src/backend/vulkan/src/lib.rs | 2 +- src/lib.rs | 21 +++++++++++++++---- src/shade.rs | 17 ++++++++++++---- src/window/vulkan/src/lib.rs | 38 +++++++++++++++++++---------------- 5 files changed, 54 insertions(+), 26 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c841f401656..1a6be2fc68a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,8 @@ license = "Apache-2.0" authors = ["The Gfx-rs Developers"] [features] +default = ["vulkan"] +vulkan = [] unstable = [] diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index ab2993e5ff8..8ab2b1cd626 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -23,7 +23,7 @@ use std::cell::RefCell; use std::sync::Arc; use shared_library::dynamic_library::DynamicLibrary; -pub use self::command::GraphicsQueue; +pub use self::command::{GraphicsQueue, Buffer as CommandBuffer}; pub use self::factory::Factory; mod command; diff --git a/src/lib.rs b/src/lib.rs index 702dc821aa2..9bd1ce17fd0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,13 +17,19 @@ extern crate winit; extern crate glutin; extern crate gfx; extern crate gfx_device_gl; -#[cfg(target_os = "windows")] -extern crate gfx_device_dx11; extern crate gfx_window_glutin; //extern crate gfx_window_glfw; + +#[cfg(target_os = "windows")] +extern crate gfx_device_dx11; #[cfg(target_os = "windows")] extern crate gfx_window_dxgi; +#[cfg(feature = "vulkan")] +extern crate gfx_device_vulkan; +#[cfg(feature = "vulkan")] +extern crate gfx_window_vulkan; + #[cfg(target_os = "macos")] extern crate gfx_device_metal; #[cfg(target_os = "macos")] @@ -106,14 +112,18 @@ pub trait ApplicationBase> { pub trait Application: Sized { fn new>(F, Init) -> Self; fn render>(&mut self, &mut gfx::Encoder); - #[cfg(target_os = "windows")] + #[cfg(feature = "vulkan")] + fn launch_default(name: &str) where WrapVulkan: ApplicationVulkan { + WrapVulkan::::launch(name, DEFAULT_CONFIG); + } + /*#[cfg(target_os = "windows")] fn launch_default(name: &str) where WrapD3D11: ApplicationD3D11 { WrapD3D11::::launch(name, DEFAULT_CONFIG); } #[cfg(not(target_os = "windows"))] fn launch_default(name: &str) where WrapGL2: ApplicationGL { WrapGL2::::launch(name, DEFAULT_CONFIG); - } + }*/ /*#[cfg(target_os = "macos")] fn launch_default(name: &str) where WrapMetal: ApplicationMetal { WrapMetal::::launch(name, DEFAULT_CONFIG) @@ -134,6 +144,9 @@ pub type D3D11CommandBufferFake = gfx_device_dx11::CommandBuffer = Wrap; pub type WrapGL2 = Wrap; +#[cfg(feature = "vulkan")] +pub type WrapVulkan = Wrap; + impl ApplicationBase for Wrap where R: gfx::Resources, diff --git a/src/shade.rs b/src/shade.rs index 30109616da7..87591f480fd 100644 --- a/src/shade.rs +++ b/src/shade.rs @@ -27,7 +27,9 @@ pub enum Backend { #[cfg(target_os = "windows")] Hlsl(DxShaderModel), #[cfg(target_os = "macos")] - Msl(MetalShaderModel) + Msl(MetalShaderModel), + #[cfg(feature = "vulkan")] + Vulkan, } pub const EMPTY: &'static [u8] = &[]; @@ -48,7 +50,8 @@ pub struct Source<'a> { pub hlsl_41 : &'a [u8], pub hlsl_50 : &'a [u8], pub msl_10 : &'a [u8], - pub msl_11 : &'a [u8] + pub msl_11 : &'a [u8], + pub vulkan : &'a [u8], } impl<'a> Source<'a> { @@ -69,7 +72,8 @@ impl<'a> Source<'a> { hlsl_41: EMPTY, hlsl_50: EMPTY, msl_10: EMPTY, - msl_11: EMPTY + msl_11: EMPTY, + vulkan: EMPTY, } } @@ -109,7 +113,12 @@ impl<'a> Source<'a> { Source { msl_11: s, .. } if s != EMPTY && revision >= 11 => s, Source { msl_10: s, .. } if s != EMPTY && revision >= 10 => s, _ => return Err(()) - } + }, + #[cfg(feature = "vulkan")] + Backend::Vulkan => match *self { + Source { vulkan: s, .. } if s != EMPTY => s, + _ => return Err(()) + }, }) } } diff --git a/src/window/vulkan/src/lib.rs b/src/window/vulkan/src/lib.rs index 3862fdd0e16..4378df95e5b 100644 --- a/src/window/vulkan/src/lib.rs +++ b/src/window/vulkan/src/lib.rs @@ -31,32 +31,31 @@ pub fn init_winit(builder: winit::WindowBuilder) -> (winit::Window, gfx_device_v (win, device, factory) } -pub type TargetFormat = format::Srgba8; -pub type TargetHandle = gfx_core::handle::RenderTargetView; +pub type TargetHandle = gfx_core::handle::RenderTargetView; -pub struct SwapTarget { +pub struct SwapTarget { _image: vk::Image, - target: TargetHandle, + target: TargetHandle, _fence: vk::Fence, } -pub struct Window { +pub struct Window { connection: xcb::Connection, _foreground: u32, window: u32, _debug_callback: Option, swapchain: vk::SwapchainKHR, - targets: Vec, + targets: Vec>, queue: gfx_device_vulkan::GraphicsQueue, } -pub struct Frame<'a> { - window: &'a mut Window, +pub struct Frame<'a, T: 'a> { + window: &'a mut Window, target_id: u32, } -impl<'a> Frame<'a> { - pub fn get_target(&self) -> TargetHandle { +impl<'a, T: Clone> Frame<'a, T> { + pub fn get_target(&self) -> TargetHandle { self.window.targets[self.target_id as usize].target.clone() } pub fn get_queue(&mut self) -> &mut gfx_device_vulkan::GraphicsQueue { @@ -64,7 +63,7 @@ impl<'a> Frame<'a> { } } -impl<'a> Drop for Frame<'a> { +impl<'a, T> Drop for Frame<'a, T> { fn drop(&mut self) { let mut result = vk::SUCCESS; let info = vk::PresentInfoKHR { @@ -85,8 +84,8 @@ impl<'a> Drop for Frame<'a> { } } -impl Window { - pub fn wait_draw(&mut self) -> Result, ()> { +impl Window { + pub fn wait_draw(&mut self) -> Result>, ()> { let ev = match self.connection.wait_for_event() { Some(ev) => ev, None => return Err(()), @@ -99,7 +98,7 @@ impl Window { } } - pub fn start_frame(&mut self) -> Frame { + pub fn start_frame(&mut self) -> Frame { //TODO: handle window resize let index = unsafe { let (dev, vk) = self.queue.get_share().get_device(); @@ -112,9 +111,13 @@ impl Window { target_id: index, } } + + pub fn get_any_target(&self) -> TargetHandle { + self.targets[0].target.clone() + } } -impl Drop for Window { +impl Drop for Window { fn drop(&mut self) { xcb::unmap_window(&self.connection, self.window); xcb::destroy_window(&self.connection, self.window); @@ -151,7 +154,8 @@ extern "system" fn callback(flags: vk::DebugReportFlagsEXT, vk::FALSE } -pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vulkan::Factory) { +pub fn init_xcb(title: &str, width: u32, height: u32) + -> (Window, gfx_device_vulkan::Factory) { let debug = false; let (mut device, mut factory, backend) = gfx_device_vulkan::create(title, 1, if debug {LAYERS_DEBUG} else {LAYERS}, @@ -230,7 +234,7 @@ pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vul let (dev, vk) = backend.get_device(); let mut images: [vk::Image; 2] = [0; 2]; let mut num = images.len() as u32; - let format = ::get_format(); + let format = ::get_format(); let swapchain_info = vk::SwapchainCreateInfoKHR { sType: vk::STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, From 1a9c64a1a7a29e38b507b093ef75b9e5f7ecdfdf Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Thu, 26 May 2016 00:17:16 -0400 Subject: [PATCH 57/69] [vk] depth-stencil view creation --- src/backend/vulkan/src/command.rs | 2 +- src/backend/vulkan/src/data.rs | 2 +- src/backend/vulkan/src/factory.rs | 49 ++++++++++++++++++++----------- src/backend/vulkan/src/lib.rs | 2 +- 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs index 33cc906deed..c58831983d9 100644 --- a/src/backend/vulkan/src/command.rs +++ b/src/backend/vulkan/src/command.rs @@ -111,7 +111,7 @@ impl draw::CommandBuffer for Buffer { } } - fn clear_depth_stencil(&mut self, _: (), _: Option, + fn clear_depth_stencil(&mut self, _: native::TextureView, _: Option, _: Option) {} fn call_draw(&mut self, _: VertexCount, _: VertexCount, _: draw::InstanceOption) {} diff --git a/src/backend/vulkan/src/data.rs b/src/backend/vulkan/src/data.rs index a5507b02af3..406b72561db 100644 --- a/src/backend/vulkan/src/data.rs +++ b/src/backend/vulkan/src/data.rs @@ -50,7 +50,7 @@ pub fn map_image_aspect(surface: SurfaceType, channel: ChannelType, is_target: b match surface { SurfaceType::D16 | SurfaceType::D24 | SurfaceType::D24_S8 | SurfaceType::D32 => match (is_target, channel) { (true, _) => vk::IMAGE_ASPECT_DEPTH_BIT | vk::IMAGE_ASPECT_STENCIL_BIT, - (false, ChannelType::Float) => vk::IMAGE_ASPECT_DEPTH_BIT, + (false, ChannelType::Float) | (false, ChannelType::Unorm) => vk::IMAGE_ASPECT_DEPTH_BIT, (false, ChannelType::Uint) => vk::IMAGE_ASPECT_STENCIL_BIT, _ => { error!("Unexpected depth/stencil channel {:?}", channel); diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index a15a3a6bc9d..2cd914792f7 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -15,6 +15,8 @@ use std::{cell, mem, ptr, slice}; use std::os::raw::c_void; use gfx_core::{self as core, handle as h, factory as f, pso, state}; +use gfx_core::format::ChannelType; +use gfx_core::target::Layer; use vk; use {command, data, native}; use {Resources as R, SharePointer}; @@ -139,6 +141,24 @@ impl Factory { }) } + fn view_target(&mut self, htex: &h::RawTexture, channel: ChannelType, layer: Option) + -> Result + { + let rdesc = core::tex::ResourceDesc { + channel: channel, + layer: layer, + min: 0, + max: 0, + swizzle: core::format::Swizzle::new(), + }; + self.view_texture(htex, rdesc, true).map_err(|err| match err { + f::ResourceViewError::NoBindFlag => f::TargetViewError::NoBindFlag, + f::ResourceViewError::Channel(ct) => f::TargetViewError::Channel(ct), + f::ResourceViewError::Layer(le) => f::TargetViewError::Layer(le), + f::ResourceViewError::Unsupported => f::TargetViewError::Unsupported, + }) + } + #[doc(hidden)] pub fn view_swapchain_image(&mut self, image: vk::Image, format: core::format::Format, size: (u32, u32)) @@ -751,30 +771,25 @@ impl core::Factory for Factory { -> Result, f::TargetViewError> { use gfx_core::handle::Producer; - let rdesc = core::tex::ResourceDesc { - channel: desc.channel, - layer: desc.layer, - min: 0, - max: 0, - swizzle: core::format::Swizzle::new(), - }; let mut dim = htex.get_info().kind.get_dimensions(); - if rdesc.layer.is_some() { + if desc.layer.is_some() { dim.2 = 1; // slice of the depth/array } - match self.view_texture(htex, rdesc, true) { - Ok(view) => Ok(self.share.handles.borrow_mut().make_rtv(view, htex, dim)), - Err(f::ResourceViewError::NoBindFlag) => Err(f::TargetViewError::NoBindFlag), - Err(f::ResourceViewError::Channel(ct)) => Err(f::TargetViewError::Channel(ct)), - Err(f::ResourceViewError::Layer(le)) => Err(f::TargetViewError::Layer(le)), - Err(f::ResourceViewError::Unsupported) => Err(f::TargetViewError::Unsupported), - } + self.view_target(htex, desc.channel, desc.layer).map(|view| + self.share.handles.borrow_mut().make_rtv(view, htex, dim)) } - fn view_texture_as_depth_stencil_raw(&mut self, _htex: &h::RawTexture, _desc: core::tex::DepthStencilDesc) + fn view_texture_as_depth_stencil_raw(&mut self, htex: &h::RawTexture, desc: core::tex::DepthStencilDesc) -> Result, f::TargetViewError> { - unimplemented!() + use gfx_core::handle::Producer; + let mut dim = htex.get_info().kind.get_dimensions(); + if desc.layer.is_some() { + dim.2 = 1; // slice of the depth/array + } + let channel = ChannelType::Unorm; //TODO + self.view_target(htex, channel, desc.layer).map(|view| + self.share.handles.borrow_mut().make_dsv(view, htex, dim)) } fn create_sampler(&mut self, info: core::tex::SamplerInfo) -> h::Sampler { diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index 8ab2b1cd626..26fe91f179f 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -275,7 +275,7 @@ impl gfx_core::Resources for Resources { type ShaderResourceView = native::TextureView; //TODO: buffer view type UnorderedAccessView = (); type RenderTargetView = native::TextureView; - type DepthStencilView = (); + type DepthStencilView = native::TextureView; type Sampler = vk::Sampler; type Fence = vk::Fence; } From 3290f26a3495bf415a8abd0a2ad29bc4f8591f96 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Thu, 26 May 2016 00:21:21 -0400 Subject: [PATCH 58/69] [vk] depth-stencil clears and view destruction --- src/backend/vulkan/src/command.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs index c58831983d9..50621862c19 100644 --- a/src/backend/vulkan/src/command.rs +++ b/src/backend/vulkan/src/command.rs @@ -111,8 +111,17 @@ impl draw::CommandBuffer for Buffer { } } - fn clear_depth_stencil(&mut self, _: native::TextureView, _: Option, - _: Option) {} + fn clear_depth_stencil(&mut self, tv: native::TextureView, depth: Option, + stencil: Option) { + let (_, vk) = self.share.get_device(); + let value = vk::ClearDepthStencilValue { + depth: depth.unwrap_or(1.0), //TODO + stencil: stencil.unwrap_or(0) as u32, //TODO + }; + unsafe { + vk.CmdClearDepthStencilImage(self.inner, tv.image, tv.layout, &value, 1, &tv.sub_range); + } + } fn call_draw(&mut self, _: VertexCount, _: VertexCount, _: draw::InstanceOption) {} fn call_draw_indexed(&mut self, _: VertexCount, _: VertexCount, @@ -227,7 +236,9 @@ impl core::Device for GraphicsQueue { |vk, v| unsafe { //RTV vk.DestroyImageView(dev, v.view, ptr::null()); }, - |_, _v| (), //DSV + |vk, v| unsafe { //DSV + vk.DestroyImageView(dev, v.view, ptr::null()); + }, |_, _v| (), //sampler |_, _| (), //fence ); From 713c197b912daf02a0be152c8427f257bc532bb0 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Sat, 28 May 2016 00:10:06 -0400 Subject: [PATCH 59/69] [vk] terrain example shaders --- examples/terrain/data/frag.spv | Bin 0 -> 460 bytes examples/terrain/data/vert.spv | Bin 0 -> 1440 bytes examples/terrain/main.rs | 2 ++ src/shade.rs | 13 ++++++++----- 4 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 examples/terrain/data/frag.spv create mode 100644 examples/terrain/data/vert.spv diff --git a/examples/terrain/data/frag.spv b/examples/terrain/data/frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..26fd8b7596589bff837649082d38c01b95b33a24 GIT binary patch literal 460 zcmYk1J4*vm5QWEG^VYlsZ6lUKNTDKxBt?oeDHQEPz#xJeh{4)l;cvAO{J!fdxy#wP zbLPyv9PGsZ}jVPx$o8Qg*Z`+6d#pOUnGx8)<(~3&$6UEE&>D59F z9Dp`Dc@}WXnHup4O0c_nb9?TWo5$65km~loFQ)6~^#)&A>OD2Yexpu+1<4@NqIOpHsUjJQSzk2KX7_-&)So_B1HTVG{y%rh( literal 0 HcmV?d00001 diff --git a/examples/terrain/data/vert.spv b/examples/terrain/data/vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..18a8a3b01c6f6588824f4c96022da0317a1ec6cb GIT binary patch literal 1440 zcmZ9LTTc^F6h@B}3W|b=TvWt?dPl1dYD|o`U{W4xQbWRP)4;@xsU6dc8lU(J`rvQ% z#l*Fyb13mNd-mSnzI|uUv@%tj4dD#Gx$r2A&r+De4`Du33*Bh$H|vApQT@r&$7U>q zN|9*JVmMpa(>yoG*V*ZLEsE5#xo2i%6_<#_2kJ>)s&p zu}1<&E0?OVN6b!(9SpJ zOnv_cV$QgXP7r%KLw^PFtmChu?I|Z`xG%9N&REBHKgOJ)?=Hn+&#R?x{AG2gL8-C8+P>JmQ{T5%qoOza>K+8;D%x zXTF@SBjPdV2DUkJj5!Im_%HfcvxQifAhB*6+dB6d>uT8IvF;|ewc?TQZEWxVf!^Nz zE+XcM*gb49cNDSvCFVX_+}!=_Al932+&%uJudxS+^Uaa7d#xjWA98kI`sV#*(sSe= DS6fe` literal 0 HcmV?d00001 diff --git a/examples/terrain/main.rs b/examples/terrain/main.rs index 641b2485eee..f469f03c506 100644 --- a/examples/terrain/main.rs +++ b/examples/terrain/main.rs @@ -82,6 +82,7 @@ impl gfx_app::Application for App { glsl_150: include_bytes!("shader/terrain_150.glslv"), hlsl_40: include_bytes!("data/vertex.fx"), msl_11: include_bytes!("shader/terrain_vertex.metal"), + vulkan: include_bytes!("data/vert.spv"), .. gfx_app::shade::Source::empty() }; let ps = gfx_app::shade::Source { @@ -89,6 +90,7 @@ impl gfx_app::Application for App { glsl_150: include_bytes!("shader/terrain_150.glslf"), hlsl_40: include_bytes!("data/pixel.fx"), msl_11: include_bytes!("shader/terrain_frag.metal"), + vulkan: include_bytes!("data/frag.spv"), .. gfx_app::shade::Source::empty() }; diff --git a/src/shade.rs b/src/shade.rs index 87591f480fd..80d1c00a575 100644 --- a/src/shade.rs +++ b/src/shade.rs @@ -20,7 +20,7 @@ pub use gfx_device_dx11::ShaderModel as DxShaderModel; pub use gfx_device_metal::ShaderModel as MetalShaderModel; /// Shader backend with version numbers. -#[derive(Copy, Clone, PartialEq, Debug)] +#[derive(Copy, Clone, Debug, PartialEq)] pub enum Backend { Glsl(GlslVersion), GlslEs(GlslVersion), @@ -54,6 +54,9 @@ pub struct Source<'a> { pub vulkan : &'a [u8], } +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct SelectError(Backend); + impl<'a> Source<'a> { /// Create an empty shader source. Useful for specifying the remaining /// structure members upon construction. @@ -78,7 +81,7 @@ impl<'a> Source<'a> { } /// Pick one of the stored versions that is the highest supported by the backend. - pub fn select(&self, backend: Backend) -> Result<&'a [u8], ()> { + pub fn select(&self, backend: Backend) -> Result<&'a [u8], SelectError> { Ok(match backend { Backend::Glsl(version) => { let v = version.major * 100 + version.minor; @@ -88,7 +91,7 @@ impl<'a> Source<'a> { Source { glsl_140: s, .. } if s != EMPTY && v >= 140 => s, Source { glsl_130: s, .. } if s != EMPTY && v >= 130 => s, Source { glsl_120: s, .. } if s != EMPTY && v >= 120 => s, - _ => return Err(()) + _ => return Err(SelectError(backend)) } }, Backend::GlslEs(version) => { @@ -106,7 +109,7 @@ impl<'a> Source<'a> { Source { hlsl_41: s, .. } if s != EMPTY && model >= 41 => s, Source { hlsl_40: s, .. } if s != EMPTY && model >= 40 => s, Source { hlsl_30: s, .. } if s != EMPTY && model >= 30 => s, - _ => return Err(()) + _ => Err(SelectError(backend)) }, #[cfg(target_os = "macos")] Backend::Msl(revision) => match *self { @@ -117,7 +120,7 @@ impl<'a> Source<'a> { #[cfg(feature = "vulkan")] Backend::Vulkan => match *self { Source { vulkan: s, .. } if s != EMPTY => s, - _ => return Err(()) + _ => return Err(SelectError(backend)) }, }) } From 85ecf751f498956e969705a70fd4998dcba15312 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Sat, 28 May 2016 23:14:15 -0400 Subject: [PATCH 60/69] [vk] cube spv shaders --- examples/cube/data/frag.spv | Bin 0 -> 924 bytes examples/cube/data/vert.spv | Bin 0 -> 1216 bytes examples/cube/main.rs | 2 ++ examples/cube/shader/cube_150.glslv | 5 ++++- examples/cube/shader/make_vulkan.sh | 11 +++++++++++ examples/terrain/shader/make_vulkan.sh | 11 +++++++++++ examples/terrain/shader/terrain_150.glslv | 1 + 7 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 examples/cube/data/frag.spv create mode 100644 examples/cube/data/vert.spv create mode 100755 examples/cube/shader/make_vulkan.sh create mode 100755 examples/terrain/shader/make_vulkan.sh diff --git a/examples/cube/data/frag.spv b/examples/cube/data/frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..088196b57a64360037db27c74aa7e6bc7221d22d GIT binary patch literal 924 zcmZ9KOD{uF6oofct#`fOlzI#_jR7JN3=B*RBqWAHG$Nr*su4qp_y^**nn--#b#Kx* zvh1_hUi)$PX|B6ci0I<47@P5TMxz@)Vjy}GdwO*padDFVDx3}Yz>eg5Vo^d+cdnK77lKT|*Ubr%tM(>RJ&Q<1r5i2KV znXVse+;8qYnLkgx0RrmGA52AZ2dVE&9{Y`8t>;|oOIT~ktJimra>ggH*^FEG=1v37 zag`02Hv{B^Ig40d$~(ib~xIDE~vIt-wdT9q-Z4x!sk=dfza4tbN>_ z@0s;=cHc|?khnV;2JS=O*~ft2dqov><3Nr45gn{2m+7attA9_weU`hNJIFM1+&eY% z_;PAK$#aJbz+7YYaZWjFIL9)ux4wFRQ))ia{I!&GH|J!Svkv4tG00YoZGbLN1J-um O>h0~@82>@B4}JlXXezk? literal 0 HcmV?d00001 diff --git a/examples/cube/data/vert.spv b/examples/cube/data/vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..45be2099713fe2567b85fc5b09bf43d7d35973a0 GIT binary patch literal 1216 zcmY+COKTKS5QT4MGLvXD4`Uu`9D6eH83-;^1W^eQCW~1J32uibX{BK@Ej_ISSN;Vz z{#G}F-`5Yt+f>&*=boxtRo(5@U?GG#p2e^qs3c3i(C_btv-`CUhKcp=&jlN{71~UhL14U zevNOiSHA;Z$E%m?)w6DLcxKHTc0F%UhfsFJERNyd4hRv-;GAjzJD{Rm)IY gfx_app::Application for App { glsl_es_100: include_bytes!("shader/cube_100_es.glslv"), hlsl_40: include_bytes!("data/vertex.fx"), msl_11: include_bytes!("shader/cube_vertex.metal"), + vulkan: include_bytes!("data/vert.spv"), .. gfx_app::shade::Source::empty() }; let ps = gfx_app::shade::Source { @@ -80,6 +81,7 @@ impl gfx_app::Application for App { glsl_es_100: include_bytes!("shader/cube_100_es.glslf"), hlsl_40: include_bytes!("data/pixel.fx"), msl_11: include_bytes!("shader/cube_frag.metal"), + vulkan: include_bytes!("data/frag.spv"), .. gfx_app::shade::Source::empty() }; diff --git a/examples/cube/shader/cube_150.glslv b/examples/cube/shader/cube_150.glslv index 36f71abbac8..f8567c42b75 100644 --- a/examples/cube/shader/cube_150.glslv +++ b/examples/cube/shader/cube_150.glslv @@ -4,9 +4,12 @@ in vec4 a_Pos; in vec2 a_TexCoord; out vec2 v_TexCoord; -uniform mat4 u_Transform; +uniform Locals { + mat4 u_Transform; +}; void main() { v_TexCoord = a_TexCoord; gl_Position = u_Transform * a_Pos; + gl_ClipDistance[0] = 1.0; } diff --git a/examples/cube/shader/make_vulkan.sh b/examples/cube/shader/make_vulkan.sh new file mode 100755 index 00000000000..adac1f551c5 --- /dev/null +++ b/examples/cube/shader/make_vulkan.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +echo Compiling... +ln -s cube_150.glslv out.vert +ln -s cube_150.glslf out.frag +glslangValidator -V -o ../data/vert.spv out.vert +glslangValidator -V -o ../data/frag.spv out.frag +rm out.vert out.frag +echo Validating... +spirv-val ../data/vert.spv +spirv-val ../data/frag.spv diff --git a/examples/terrain/shader/make_vulkan.sh b/examples/terrain/shader/make_vulkan.sh new file mode 100755 index 00000000000..311add726d1 --- /dev/null +++ b/examples/terrain/shader/make_vulkan.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +echo Compiling... +ln -s terrain_150.glslv out.vert +ln -s terrain_150.glslf out.frag +glslangValidator -V -o ../data/vert.spv out.vert +glslangValidator -V -o ../data/frag.spv out.frag +rm out.vert out.frag +echo Validating... +spirv-val ../data/vert.spv +spirv-val ../data/frag.spv diff --git a/examples/terrain/shader/terrain_150.glslv b/examples/terrain/shader/terrain_150.glslv index b8927d6041d..4e122ccfd99 100644 --- a/examples/terrain/shader/terrain_150.glslv +++ b/examples/terrain/shader/terrain_150.glslv @@ -13,4 +13,5 @@ uniform Locals { void main() { v_Color = a_Color; gl_Position = u_Proj * u_View * u_Model * vec4(a_Pos, 1.0); + gl_ClipDistance[0] = 1.0; } From b4784c69f1afea9f405fa863000bffe81bdfa8c5 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Mon, 30 May 2016 00:34:29 -0400 Subject: [PATCH 61/69] Added CB, SRV, UAV, and samplers to PSO descriptor --- src/core/src/pso.rs | 27 ++++++++++++++++++++++++--- src/render/src/macros/pso.rs | 16 ++++++++++------ src/render/src/pso/buffer.rs | 12 ++++++------ src/render/src/pso/mod.rs | 11 ++++++----- src/render/src/pso/resource.rs | 19 ++++++++++--------- 5 files changed, 56 insertions(+), 29 deletions(-) diff --git a/src/core/src/pso.rs b/src/core/src/pso.rs index e76ff747837..b98a4c7dbc4 100644 --- a/src/core/src/pso.rs +++ b/src/core/src/pso.rs @@ -18,7 +18,8 @@ //! will want to use the typed and safe `PipelineState`. See the `pso` module inside the `gfx` //! crate. -use {MAX_COLOR_TARGETS, MAX_VERTEX_ATTRIBUTES}; +use {MAX_COLOR_TARGETS, MAX_VERTEX_ATTRIBUTES, MAX_CONSTANT_BUFFERS, + MAX_RESOURCE_VIEWS, MAX_UNORDERED_VIEWS, MAX_SAMPLERS}; use {ConstantBufferSlot, ColorSlot, ResourceViewSlot, UnorderedViewSlot, SamplerSlot, Primitive, Resources}; @@ -137,7 +138,7 @@ pub struct Element { /// Vertex buffer descriptor #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] -pub struct BufferDesc { +pub struct VertexBufferDesc { /// Total container size, in bytes pub stride: ElemStride, /// Rate of the input for the given buffer @@ -146,6 +147,14 @@ pub struct BufferDesc { /// PSO vertex attribute descriptor pub type AttributeDesc = (BufferIndex, Element); +/// PSO constant buffer descriptor +pub type ConstantBufferDesc = Usage; +/// PSO shader resource view descriptor +pub type ResourceViewDesc = Usage; +/// PSO unordered access view descriptor +pub type UnorderedViewDesc = Usage; +/// PSO sampler descriptor +pub type SamplerDesc = Usage; /// PSO color target descriptor pub type ColorTargetDesc = (format::Format, ColorInfo); /// PSO depth-stencil target descriptor @@ -162,9 +171,17 @@ pub struct Descriptor { /// Enable scissor test pub scissor: bool, /// Vertex buffers - pub vertex_buffers: [Option; MAX_VERTEX_BUFFERS], + pub vertex_buffers: [Option; MAX_VERTEX_BUFFERS], /// Vertex attributes pub attributes: [Option; MAX_VERTEX_ATTRIBUTES], + /// Constant buffers + pub constant_buffers: [Option; MAX_CONSTANT_BUFFERS], + /// Shader resource views + pub resource_views: [Option; MAX_RESOURCE_VIEWS], + /// Unordered access views + pub unordered_views: [Option; MAX_UNORDERED_VIEWS], + /// Samplers + pub samplers: [Option; MAX_SAMPLERS], /// Render target views (RTV) pub color_targets: [Option; MAX_COLOR_TARGETS], /// Depth stencil view (DSV) @@ -180,6 +197,10 @@ impl Descriptor { scissor: false, vertex_buffers: [None; MAX_VERTEX_BUFFERS], attributes: [None; MAX_VERTEX_ATTRIBUTES], + constant_buffers: [None; MAX_CONSTANT_BUFFERS], + resource_views: [None; MAX_RESOURCE_VIEWS], + unordered_views: [None; MAX_UNORDERED_VIEWS], + samplers: [None; MAX_SAMPLERS], color_targets: [None; MAX_COLOR_TARGETS], depth_stencil: None, } diff --git a/src/render/src/macros/pso.rs b/src/render/src/macros/pso.rs index e94c09ecb67..6b311867e54 100644 --- a/src/render/src/macros/pso.rs +++ b/src/render/src/macros/pso.rs @@ -45,9 +45,9 @@ macro_rules! gfx_pipeline_inner { // v# let mut _num_vb = 0; $( - if let Some(vd) = meta.$field.link_vertex_buffer(_num_vb, &self.$field) { + if let Some(d) = meta.$field.link_vertex_buffer(_num_vb, &self.$field) { assert!(meta.$field.is_active()); - desc.vertex_buffers[_num_vb as usize] = Some(vd); + desc.vertex_buffers[_num_vb as usize] = Some(d); _num_vb += 1; } )* @@ -71,8 +71,9 @@ macro_rules! gfx_pipeline_inner { for cb in &info.constant_buffers { $( match meta.$field.link_constant_buffer(cb, &self.$field) { - Some(Ok(())) => { + Some(Ok(d)) => { assert!(meta.$field.is_active()); + desc.constant_buffers[cb.slot as usize] = Some(d); continue; }, Some(Err(e)) => return Err( @@ -103,8 +104,9 @@ macro_rules! gfx_pipeline_inner { for srv in &info.textures { $( match meta.$field.link_resource_view(srv, &self.$field) { - Some(Ok(())) => { + Some(Ok(d)) => { assert!(meta.$field.is_active()); + desc.resource_views[srv.slot as usize] = Some(d); continue; }, Some(Err(_)) => return Err( @@ -119,8 +121,9 @@ macro_rules! gfx_pipeline_inner { for uav in &info.unordereds { $( match meta.$field.link_unordered_view(uav, &self.$field) { - Some(Ok(())) => { + Some(Ok(d)) => { assert!(meta.$field.is_active()); + desc.unordered_views[uav.slot as usize] = Some(d); continue; }, Some(Err(_)) => return Err( @@ -135,8 +138,9 @@ macro_rules! gfx_pipeline_inner { for sm in &info.samplers { $( match meta.$field.link_sampler(sm, &self.$field) { - Some(()) => { + Some(d) => { assert!(meta.$field.is_active()); + desc.samplers[sm.slot as usize] = Some(d); continue; }, None => (), diff --git a/src/render/src/pso/buffer.rs b/src/render/src/pso/buffer.rs index e70c3e8e5b9..62824dcf2d6 100644 --- a/src/render/src/pso/buffer.rs +++ b/src/render/src/pso/buffer.rs @@ -71,11 +71,11 @@ impl<'a, self.0.is_active() } fn link_vertex_buffer(&mut self, index: BufferIndex, _: &Self::Init) - -> Option { + -> Option { use std::mem; (self.0).0 = Some(index); let rate = ::default().as_ref().len(); - Some(pso::BufferDesc { + Some(pso::VertexBufferDesc { stride: mem::size_of::() as ElemStride, rate: rate as InstanceRate, }) @@ -116,9 +116,9 @@ impl<'a> DataLink<'a> for RawVertexBuffer { self.0.is_some() } fn link_vertex_buffer(&mut self, index: BufferIndex, init: &Self::Init) - -> Option { + -> Option { self.0 = Some(index); - Some(pso::BufferDesc { + Some(pso::VertexBufferDesc { stride: init.1, rate: init.2, }) @@ -153,7 +153,7 @@ DataLink<'a> for ConstantBuffer { self.0.is_some() } fn link_constant_buffer<'b>(&mut self, cb: &'b shade::ConstantBufferVar, init: &Self::Init) - -> Option>> { + -> Option>> { if &cb.name == *init { for el in cb.elements.iter() { return Some(Err(match T::query(&el.name) { @@ -164,7 +164,7 @@ DataLink<'a> for ConstantBuffer { })) } self.0 = Some((cb.usage, cb.slot)); - Some(Ok(())) + Some(Ok(cb.usage)) }else { None } diff --git a/src/render/src/pso/mod.rs b/src/render/src/pso/mod.rs index b2699464c1e..e4ba3b306bd 100644 --- a/src/render/src/pso/mod.rs +++ b/src/render/src/pso/mod.rs @@ -247,13 +247,13 @@ pub trait DataLink<'a>: Sized { fn is_active(&self) -> bool; /// Attempt to link with a vertex buffer containing multiple attributes. fn link_vertex_buffer(&mut self, _: d::pso::BufferIndex, _: &Self::Init) -> - Option { None } + Option { None } /// Attempt to link with a vertex attribute. fn link_input(&mut self, _: &d::shade::AttributeVar, _: &Self::Init) -> Option> { None } /// Attempt to link with a constant buffer. fn link_constant_buffer<'b>(&mut self, _: &'b d::shade::ConstantBufferVar, _: &Self::Init) -> - Option>> { None } + Option>> { None } /// Attempt to link with a global constant. fn link_global_constant(&mut self, _: &d::shade::ConstVar, _: &Self::Init) -> Option> { None } @@ -265,12 +265,13 @@ pub trait DataLink<'a>: Sized { Option { None } /// Attempt to link with a shader resource (SRV). fn link_resource_view(&mut self, _: &d::shade::TextureVar, _: &Self::Init) -> - Option> { None } + Option> { None } /// Attempt to link with an unordered access (UAV). fn link_unordered_view(&mut self, _: &d::shade::UnorderedVar, _: &Self::Init) -> - Option> { None } + Option> { None } /// Attempt to link with a sampler. - fn link_sampler(&mut self, _: &d::shade::SamplerVar, _: &Self::Init) -> Option<()> { None } + fn link_sampler(&mut self, _: &d::shade::SamplerVar, _: &Self::Init) + -> Option { None } /// Attempt to enable scissor test. fn link_scissor(&mut self) -> bool { false } } diff --git a/src/render/src/pso/resource.rs b/src/render/src/pso/resource.rs index 23a5052fbe3..583a3eff7c2 100644 --- a/src/render/src/pso/resource.rs +++ b/src/render/src/pso/resource.rs @@ -58,7 +58,7 @@ impl<'a, T> DataLink<'a> for ShaderResource { self.0.is_active() } fn link_resource_view(&mut self, var: &shade::TextureVar, init: &Self::Init) - -> Option> { + -> Option> { self.0.link_resource_view(var, init) } } @@ -80,10 +80,10 @@ impl<'a> DataLink<'a> for RawShaderResource { self.0.is_some() } fn link_resource_view(&mut self, var: &shade::TextureVar, init: &Self::Init) - -> Option> { + -> Option> { if *init == var.name { self.0 = Some((var.slot, var.usage)); - Some(Ok(())) //TODO: check format + Some(Ok(var.usage)) //TODO: check format }else { None } @@ -110,10 +110,10 @@ impl<'a, T> DataLink<'a> for UnorderedAccess { self.0.is_some() } fn link_unordered_view(&mut self, var: &shade::UnorderedVar, init: &Self::Init) - -> Option> { + -> Option> { if *init == var.name { self.0 = Some((var.slot, var.usage)); - Some(Ok(())) //TODO: check format + Some(Ok(var.usage)) //TODO: check format }else { None } @@ -139,10 +139,11 @@ impl<'a> DataLink<'a> for Sampler { fn is_active(&self) -> bool { self.0.is_some() } - fn link_sampler(&mut self, var: &shade::SamplerVar, init: &Self::Init) -> Option<()> { + fn link_sampler(&mut self, var: &shade::SamplerVar, init: &Self::Init) + -> Option { if *init == var.name { self.0 = Some((var.slot, var.usage)); - Some(()) + Some(var.usage) }else { None } @@ -169,10 +170,10 @@ impl<'a, T> DataLink<'a> for TextureSampler { self.0.is_active() } fn link_resource_view(&mut self, var: &shade::TextureVar, init: &Self::Init) - -> Option> { + -> Option> { self.0.link_resource_view(var, init) } - fn link_sampler(&mut self, var: &shade::SamplerVar, init: &Self::Init) -> Option<()> { + fn link_sampler(&mut self, var: &shade::SamplerVar, init: &Self::Init) -> Option { self.1.link_sampler(var, init) } } From c3e438e1f5c263bcc00b872469a8257966743833 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Mon, 30 May 2016 00:35:01 -0400 Subject: [PATCH 62/69] [vk] descriptor layout init --- examples/triangle/main.rs | 1 - src/backend/gl/src/lib.rs | 2 +- src/backend/vulkan/src/data.rs | 8 ++++- src/backend/vulkan/src/factory.rs | 49 +++++++++++++++++++++++++++++-- 4 files changed, 55 insertions(+), 5 deletions(-) diff --git a/examples/triangle/main.rs b/examples/triangle/main.rs index c334f12566d..7cbaf1ea51f 100644 --- a/examples/triangle/main.rs +++ b/examples/triangle/main.rs @@ -15,7 +15,6 @@ #[macro_use] extern crate gfx; extern crate gfx_window_glutin; -extern crate gfx_device_gl; extern crate glutin; use gfx::traits::FactoryExt; diff --git a/src/backend/gl/src/lib.rs b/src/backend/gl/src/lib.rs index fc2608bec9b..5dfad509ce0 100644 --- a/src/backend/gl/src/lib.rs +++ b/src/backend/gl/src/lib.rs @@ -77,7 +77,7 @@ impl d::Resources for Resources { #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct BufferElement { - pub desc: d::pso::BufferDesc, + pub desc: d::pso::VertexBufferDesc, pub elem: d::pso::Element, } diff --git a/src/backend/vulkan/src/data.rs b/src/backend/vulkan/src/data.rs index 406b72561db..6bf60003b48 100644 --- a/src/backend/vulkan/src/data.rs +++ b/src/backend/vulkan/src/data.rs @@ -16,7 +16,7 @@ use gfx_core::factory::{Bind, MapAccess, Usage, LayerError}; use gfx_core::format::{SurfaceType, ChannelType, Swizzle, ChannelSource}; use gfx_core::pso::ColorInfo; use gfx_core::tex::{FilterMethod, Kind, Layer, PackedColor, WrapMode}; -use gfx_core::{state, Primitive}; +use gfx_core::{shade, state, Primitive}; use vk; @@ -410,3 +410,9 @@ pub fn map_blend(ci: &ColorInfo) -> vk::PipelineColorBlendAttachmentState { if ci.mask.contains(state::ALPHA) {vk::COLOR_COMPONENT_A_BIT} else {0}, } } + +pub fn map_stage(usage: shade::Usage) -> vk::ShaderStageFlags { + (if usage.contains(shade::VERTEX) { vk::SHADER_STAGE_VERTEX_BIT } else { 0 }) | + (if usage.contains(shade::GEOMETRY) { vk::SHADER_STAGE_GEOMETRY_BIT } else { 0 }) | + (if usage.contains(shade::PIXEL) { vk::SHADER_STAGE_FRAGMENT_BIT } else { 0 }) +} diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index 2cd914792f7..734e2bcf445 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -393,12 +393,57 @@ impl core::Factory for Factory { let (dev, vk) = self.share.get_device(); let set_layout = { + let mut bindings = Vec::new(); + for (i, cb) in desc.constant_buffers.iter().enumerate() { + if let &Some(usage) = cb { + bindings.push(vk::DescriptorSetLayoutBinding { + binding: i as u32, + descriptorType: vk::DESCRIPTOR_TYPE_UNIFORM_BUFFER, + descriptorCount: 1, + stageFlags: data::map_stage(usage), + pImmutableSamplers: ptr::null(), + }); + } + } + for (i, srv) in desc.resource_views.iter().enumerate() { + if let &Some(usage) = srv { + bindings.push(vk::DescriptorSetLayoutBinding { + binding: i as u32, + descriptorType: vk::DESCRIPTOR_TYPE_SAMPLED_IMAGE, + descriptorCount: 1, + stageFlags: data::map_stage(usage), + pImmutableSamplers: ptr::null(), + }); + } + } + for (i, uav) in desc.unordered_views.iter().enumerate() { + if let &Some(usage) = uav { + bindings.push(vk::DescriptorSetLayoutBinding { + binding: i as u32, + descriptorType: vk::DESCRIPTOR_TYPE_STORAGE_IMAGE, //TODO: buffer views + descriptorCount: 1, + stageFlags: data::map_stage(usage), + pImmutableSamplers: ptr::null(), + }); + } + } + for (i, sam) in desc.samplers.iter().enumerate() { + if let &Some(usage) = sam { + bindings.push(vk::DescriptorSetLayoutBinding { + binding: i as u32, + descriptorType: vk::DESCRIPTOR_TYPE_SAMPLER, + descriptorCount: 1, + stageFlags: data::map_stage(usage), + pImmutableSamplers: ptr::null(), + }); + } + } let info = vk::DescriptorSetLayoutCreateInfo { sType: vk::STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, pNext: ptr::null(), flags: 0, - bindingCount: 0, - pBindings: ptr::null(), //TODO + bindingCount: bindings.len() as u32, + pBindings: bindings.as_ptr(), }; let mut out = 0; assert_eq!(vk::SUCCESS, unsafe { From d6e01b4aaa2a45c0e1afca5c6d1be0f21b6d39c0 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Sat, 4 Jun 2016 00:18:51 -0400 Subject: [PATCH 63/69] [vk] FBO creation and hashing. CommandBuffer destruction and reset. --- src/backend/vulkan/src/command.rs | 143 ++++++++++++++++++++++++++++-- src/backend/vulkan/src/factory.rs | 24 +---- src/core/src/pso.rs | 2 +- 3 files changed, 138 insertions(+), 31 deletions(-) diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs index 50621862c19..88664d89529 100644 --- a/src/backend/vulkan/src/command.rs +++ b/src/backend/vulkan/src/command.rs @@ -13,6 +13,7 @@ // limitations under the License. use std::{mem, ptr}; +use std::collections::hash_map::{HashMap, Entry}; use vk; use gfx_core::{self as core, draw, pso, shade, target, tex}; use gfx_core::state::RefValues; @@ -23,24 +24,63 @@ use {Resources, Share, SharePointer}; pub struct Buffer { inner: vk::CommandBuffer, + parent_pool: vk::CommandPool, family: u32, share: SharePointer, + last_render_pass: vk::RenderPass, + fbo_cache: HashMap, vk::Framebuffer>, + temp_attachments: Vec, } impl Buffer { #[doc(hidden)] - pub fn new(b: vk::CommandBuffer, f: u32, s: SharePointer) -> Buffer { + pub fn new(pool: vk::CommandPool, family: u32, share: SharePointer) -> Buffer { + let alloc_info = vk::CommandBufferAllocateInfo { + sType: vk::STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + pNext: ptr::null(), + commandPool: pool, + level: vk::COMMAND_BUFFER_LEVEL_PRIMARY, + commandBufferCount: 1, + }; + let begin_info = vk::CommandBufferBeginInfo { + sType: vk::STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + pNext: ptr::null(), + flags: 0, + pInheritanceInfo: ptr::null(), + }; Buffer { - inner: b, - family: f, - share: s, + inner: { + let (dev, vk) = share.get_device(); + let mut buf = 0; + assert_eq!(vk::SUCCESS, unsafe { + vk.AllocateCommandBuffers(dev, &alloc_info, &mut buf) + }); + assert_eq!(vk::SUCCESS, unsafe { + vk.BeginCommandBuffer(buf, &begin_info) + }); + buf + }, + parent_pool: pool, + family: family, + share: share, + last_render_pass: 0, + fbo_cache: HashMap::new(), + temp_attachments: Vec::new(), } } } impl Drop for Buffer { fn drop(&mut self) { - //TODO + let (dev, vk) = self.share.get_device(); + unsafe { + vk.FreeCommandBuffers(dev, self.parent_pool, 1, &self.inner); + } + for &fbo in self.fbo_cache.values() { + unsafe { + vk.DestroyFramebuffer(dev, fbo, ptr::null()); + } + } } } @@ -82,15 +122,102 @@ impl Buffer { } impl draw::CommandBuffer for Buffer { - fn reset(&mut self) {} - fn bind_pipeline_state(&mut self, _: native::Pipeline) {} + fn reset(&mut self) { + let (_, vk) = self.share.get_device(); + assert_eq!(vk::SUCCESS, unsafe { + vk.ResetCommandBuffer(self.inner, 0) + }); + } + + fn bind_pipeline_state(&mut self, pso: native::Pipeline) { + let (_, vk) = self.share.get_device(); + self.last_render_pass = pso.render_pass; + unsafe { + vk.CmdBindPipeline(self.inner, vk::PIPELINE_BIND_POINT_GRAPHICS, pso.pipeline); + } + } + fn bind_vertex_buffers(&mut self, _: pso::VertexBufferSet) {} fn bind_constant_buffers(&mut self, _: &[pso::ConstantBufferParam]) {} fn bind_global_constant(&mut self, _: shade::Location, _: shade::UniformValue) {} fn bind_resource_views(&mut self, _: &[pso::ResourceViewParam]) {} fn bind_unordered_views(&mut self, _: &[pso::UnorderedViewParam]) {} fn bind_samplers(&mut self, _: &[pso::SamplerParam]) {} - fn bind_pixel_targets(&mut self, _: pso::PixelTargetSet) {} + + fn bind_pixel_targets(&mut self, pts: pso::PixelTargetSet) { + let (dev, vk) = self.share.get_device(); + let vp = vk::Viewport { + x: 0.0, + y: 0.0, + width: pts.size.0 as f32, + height: pts.size.1 as f32, + minDepth: 0.0, + maxDepth: 1.0, + }; + let fbo = match self.fbo_cache.entry(pts) { + Entry::Occupied(oe) => *oe.get(), + Entry::Vacant(ve) => { + let mut ats = &mut self.temp_attachments; + ats.clear(); + for color in pts.colors.iter() { + if let &Some(ref tv) = color { + ats.push(tv.view); + } + } + match (pts.depth, pts.stencil) { + (None, None) => (), + (Some(vd), Some(vs)) => { + if vd != vs { + error!("Different depth and stencil are not supported") + } + ats.push(vd.view); + }, + (Some(vd), None) => ats.push(vd.view), + (None, Some(vs)) => ats.push(vs.view), + } + let info = vk::FramebufferCreateInfo { + sType: vk::STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, + pNext: ptr::null(), + flags: 0, + renderPass: self.last_render_pass, + attachmentCount: ats.len() as u32, + pAttachments: ats.as_ptr(), + width: pts.size.0 as u32, + height: pts.size.1 as u32, + layers: pts.size.2 as u32, + }; + let mut out = 0; + assert_eq!(vk::SUCCESS, unsafe { + vk.CreateFramebuffer(dev, &info, ptr::null(), &mut out) + }); + *ve.insert(out) + }, + }; + let rp_info = vk::RenderPassBeginInfo { + sType: vk::STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + pNext: ptr::null(), + renderPass: self.last_render_pass, + framebuffer: fbo, + renderArea: vk::Rect2D { + offset: vk::Offset2D { + x: 0, + y: 0, + }, + extent: vk::Extent2D { + width: pts.size.0 as u32, + height: pts.size.1 as u32, + }, + }, + clearValueCount: 0, + pClearValues: ptr::null(), + }; + unsafe { + vk.CmdSetViewport(self.inner, 0, 1, &vp); + vk.CmdBeginRenderPass(self.inner, &rp_info, vk::SUBPASS_CONTENTS_INLINE); + } + //TODO: EndRenderPass + } + fn bind_index(&mut self, _: native::Buffer, _: IndexType) {} fn set_scissor(&mut self, _: target::Rect) {} fn set_ref_values(&mut self, _: RefValues) {} diff --git a/src/backend/vulkan/src/factory.rs b/src/backend/vulkan/src/factory.rs index 734e2bcf445..9fee2759916 100644 --- a/src/backend/vulkan/src/factory.rs +++ b/src/backend/vulkan/src/factory.rs @@ -74,28 +74,7 @@ impl Factory { } pub fn create_command_buffer(&mut self) -> command::Buffer { - let alloc_info = vk::CommandBufferAllocateInfo { - sType: vk::STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, - pNext: ptr::null(), - commandPool: self.command_pool, - level: vk::COMMAND_BUFFER_LEVEL_PRIMARY, - commandBufferCount: 1, - }; - let begin_info = vk::CommandBufferBeginInfo { - sType: vk::STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, - pNext: ptr::null(), - flags: 0, - pInheritanceInfo: ptr::null(), - }; - let (dev, vk) = self.share.get_device(); - let mut buf = 0; - assert_eq!(vk::SUCCESS, unsafe { - vk.AllocateCommandBuffers(dev, &alloc_info, &mut buf) - }); - assert_eq!(vk::SUCCESS, unsafe { - vk.BeginCommandBuffer(buf, &begin_info) - }); - command::Buffer::new(buf, self.queue_family_index, self.share.clone()) + command::Buffer::new(self.command_pool, self.queue_family_index, self.share.clone()) } fn view_texture(&mut self, htex: &h::RawTexture, desc: core::tex::ResourceDesc, is_target: bool) @@ -381,6 +360,7 @@ impl core::Factory for Factory { unordereds: Vec::new(), samplers: Vec::new(), outputs: Vec::new(), + output_depth: false, knows_outputs: false, }; Ok(self.share.handles.borrow_mut().make_program(prog, info)) diff --git a/src/core/src/pso.rs b/src/core/src/pso.rs index b98a4c7dbc4..848e8d732f1 100644 --- a/src/core/src/pso.rs +++ b/src/core/src/pso.rs @@ -238,7 +238,7 @@ pub struct UnorderedViewParam(pub R::UnorderedAccessView, pub Usag pub struct SamplerParam(pub R::Sampler, pub Usage, pub SamplerSlot); /// A complete set of render targets to be used for pixel export in PSO. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] pub struct PixelTargetSet { /// Array of color target views pub colors: [Option; MAX_COLOR_TARGETS], From 9e21c41726f5d2cbc064879ede2cafc9534e2599 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Tue, 9 Aug 2016 21:46:33 -0400 Subject: [PATCH 64/69] Merge fixes --- examples/performance/main.rs | 4 - src/backend/vulkan/Cargo.toml | 2 +- src/lib.rs | 125 +++++++++++++++++++---------- src/render/src/macros/structure.rs | 3 +- src/shade.rs | 4 +- src/window/vulkan/Cargo.toml | 2 +- 6 files changed, 90 insertions(+), 50 deletions(-) diff --git a/examples/performance/main.rs b/examples/performance/main.rs index 2a39dec472e..c741a29aae3 100644 --- a/examples/performance/main.rs +++ b/examples/performance/main.rs @@ -150,10 +150,6 @@ impl GFX { } } -fn duration_to_f64(dur: Duration) -> f64 { - dur.as_secs() as f64 + dur.subsec_nanos() as f64 / 1000_000_000.0 -} - impl Renderer for GFX { fn render(&mut self, proj_view: &Matrix4) { let start = Instant::now(); diff --git a/src/backend/vulkan/Cargo.toml b/src/backend/vulkan/Cargo.toml index 8596481a708..85a5f897580 100644 --- a/src/backend/vulkan/Cargo.toml +++ b/src/backend/vulkan/Cargo.toml @@ -17,4 +17,4 @@ vk = "0.0" vk-sys = { path = "../../../../vulkano/vk-sys" } shared_library = "0.1" winit = "0.5" -gfx_core = { path = "../../core", version = "0.3" } +gfx_core = { path = "../../core", version = "0.4" } diff --git a/src/lib.rs b/src/lib.rs index 9bd1ce17fd0..01494978cb9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,16 +25,16 @@ extern crate gfx_device_dx11; #[cfg(target_os = "windows")] extern crate gfx_window_dxgi; -#[cfg(feature = "vulkan")] -extern crate gfx_device_vulkan; -#[cfg(feature = "vulkan")] -extern crate gfx_window_vulkan; - #[cfg(target_os = "macos")] extern crate gfx_device_metal; #[cfg(target_os = "macos")] extern crate gfx_window_metal; +#[cfg(feature = "vulkan")] +extern crate gfx_device_vulkan; +#[cfg(feature = "vulkan")] +extern crate gfx_window_vulkan; + pub mod shade; @@ -175,17 +175,6 @@ pub trait ApplicationGL { fn launch(&str, Config); } -#[cfg(target_os = "macos")] -pub trait ApplicationMetal { - fn launch(&str, Config); -} - -#[cfg(target_os = "windows")] -pub trait ApplicationD3D11 { - fn launch(&str, Config); -} - - impl Factory for gfx_device_gl::Factory { type CommandBuffer = gfx_device_gl::CommandBuffer; fn create_encoder(&mut self) -> gfx::Encoder { @@ -210,10 +199,9 @@ impl ApplicationGL for A where .with_dimensions(config.size.0 as u32, config.size.1 as u32) .with_gl(gl_version) .with_vsync(); - let (window, mut device, mut factory, main_color, main_depth) = + let (window, mut device, factory, main_color, main_depth) = gfx_window_glutin::init::(builder); let (width, height) = window.get_inner_size().unwrap(); - let combuf = factory.create_command_buffer(); let shade_lang = device.get_info().shading_language; let mut app = Self::new(factory, Init { @@ -246,6 +234,58 @@ impl ApplicationGL for A where } } + +#[cfg(target_os = "windows")] +pub trait ApplicationD3D11 { + fn launch(&str, Config); +} + +#[cfg(target_os = "windows")] +impl Factory for gfx_device_dx11::Factory { + type CommandBuffer = D3D11CommandBuffer; + fn create_encoder(&mut self) -> gfx::Encoder { + self.create_command_buffer_native().into() + } +} + +#[cfg(target_os = "windows")] +impl< + A: ApplicationBase +> ApplicationD3D11 for A { + fn launch(title: &str, config: Config) { + use gfx::traits::{Device, Factory}; + + env_logger::init().unwrap(); + let (window, device, factory, main_color) = + gfx_window_dxgi::init::(title, config.size.0, config.size.1) + .unwrap(); + let main_depth = factory.create_depth_stencil_view_only( + window.size.0, window.size.1).unwrap(); + + let mut app = Self::new(factory, Init { + backend: shade::Backend::Hlsl(device.get_shader_model()), + color: main_color, + depth: main_depth, + aspect_ratio: window.size.0 as f32 / window.size.1 as f32, + }); + let mut device: gfx_device_dx11::Deferred = device.into(); + + let mut harness = Harness::new(); + while window.dispatch() { + app.render(&mut device); + window.swap_buffers(1); + device.cleanup(); + harness.bump(); + } + } +} + + +#[cfg(target_os = "macos")] +pub trait ApplicationMetal { + fn launch(&str, Config); +} + #[cfg(target_os = "macos")] impl Factory for gfx_device_metal::Factory { type CommandBuffer = gfx_device_meta::CommandBuffer; @@ -297,42 +337,45 @@ impl< } } -#[cfg(target_os = "windows")] -impl Factory for gfx_device_dx11::Factory { - type CommandBuffer = D3D11CommandBuffer; - fn create_encoder(&mut self) -> gfx::Encoder { - self.create_command_buffer_native().into() + +#[cfg(feature = "vulkan")] +pub trait ApplicationVulkan { + fn launch(&str, Config); +} + +#[cfg(feature = "vulkan")] +impl Factory for gfx_device_vulkan::Factory { + type CommandBuffer = gfx_device_vulkan::CommandBuffer; + fn create_encoder(&mut self) -> gfx::Encoder { + self.create_command_buffer().into() } } -#[cfg(target_os = "windows")] +#[cfg(feature = "vulkan")] impl< - A: ApplicationBase -> ApplicationD3D11 for A { + A: ApplicationBase +> ApplicationVulkan for A { fn launch(title: &str, config: Config) { use gfx::traits::{Device, Factory}; env_logger::init().unwrap(); - let (window, device, factory, main_color) = - gfx_window_dxgi::init::(title, config.size.0, config.size.1) - .unwrap(); - let main_depth = factory.create_depth_stencil_view_only( - window.size.0, window.size.1).unwrap(); + let (mut win, mut factory) = gfx_window_vulkan::init_xcb::(title, config.size.0 as u32, config.size.1 as u32); + let main_depth = factory.create_depth_stencil::(config.size.0, config.size.1).unwrap(); let mut app = Self::new(factory, Init { - backend: shade::Backend::Hlsl(device.get_shader_model()), - color: main_color, - depth: main_depth, - aspect_ratio: window.size.0 as f32 / window.size.1 as f32, + backend: shade::Backend::Vulkan, + color: win.get_any_target(), + depth: main_depth.2, + aspect_ratio: config.size.0 as f32 / config.size.1 as f32, //TODO }); - let mut device: gfx_device_dx11::Deferred = device.into(); let mut harness = Harness::new(); - while window.dispatch() { - app.render(&mut device); - window.swap_buffers(1); - device.cleanup(); - harness.bump(); + while let Ok(frame_opt) = win.wait_draw() { + if let Some(mut frame) = frame_opt { + app.render(frame.get_queue()); + frame.get_queue().cleanup(); + harness.bump(); + } } } } diff --git a/src/render/src/macros/structure.rs b/src/render/src/macros/structure.rs index f08c769053c..d727311c2ed 100644 --- a/src/render/src/macros/structure.rs +++ b/src/render/src/macros/structure.rs @@ -28,6 +28,7 @@ macro_rules! gfx_impl_struct { impl $crate::pso::buffer::Structure<$runtime_format> for $root { fn query(name: &str) -> Option<$crate::pso::buffer::Element<$runtime_format>> { + use std::mem::size_of; use $crate::pso::buffer::{Element, ElemOffset}; let tmp: &$root = unsafe{ ::std::mem::uninitialized() }; let base = tmp as *const _ as usize; @@ -42,7 +43,7 @@ macro_rules! gfx_impl_struct { Some(s) if s.starts_with('.') => &s[1..], _ => name, }; - (sub_name, array_id * (stride as ElemOffset)) + (sub_name, array_id * (size_of::<$root>() as ElemOffset)) }, None => (name, 0), } diff --git a/src/shade.rs b/src/shade.rs index 80d1c00a575..f5190dd9e50 100644 --- a/src/shade.rs +++ b/src/shade.rs @@ -100,7 +100,7 @@ impl<'a> Source<'a> { Source { glsl_es_100: s, .. } if s != EMPTY && v >= 100 => s, Source { glsl_es_200: s, .. } if s != EMPTY && v >= 200 => s, Source { glsl_es_300: s, .. } if s != EMPTY && v >= 300 => s, - _ => return Err(()) + _ => return Err(SelectError(backend)) } }, #[cfg(target_os = "windows")] @@ -115,7 +115,7 @@ impl<'a> Source<'a> { Backend::Msl(revision) => match *self { Source { msl_11: s, .. } if s != EMPTY && revision >= 11 => s, Source { msl_10: s, .. } if s != EMPTY && revision >= 10 => s, - _ => return Err(()) + _ => return Err(SelectError(backend)) }, #[cfg(feature = "vulkan")] Backend::Vulkan => match *self { diff --git a/src/window/vulkan/Cargo.toml b/src/window/vulkan/Cargo.toml index d03fde1e7b2..6697e378305 100644 --- a/src/window/vulkan/Cargo.toml +++ b/src/window/vulkan/Cargo.toml @@ -15,5 +15,5 @@ name = "gfx_window_vulkan" winit = "0.5" xcb = "0.7" vk-sys = { path = "../../../../vulkano/vk-sys" } -gfx_core = { path = "../../core", version = "0.3" } +gfx_core = { path = "../../core", version = "0.4" } gfx_device_vulkan = { path = "../../backend/vulkan", version = "0.1" } From feb5354661a49ed8e9a6e2b1acdcaf79ea0f1666 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Tue, 9 Aug 2016 22:01:11 -0400 Subject: [PATCH 65/69] All around version bumps --- Cargo.toml | 16 ++++++++-------- src/backend/dx11/Cargo.toml | 4 ++-- src/backend/gl/Cargo.toml | 4 ++-- src/backend/metal/Cargo.toml | 2 +- src/backend/vulkan/Cargo.toml | 2 +- src/core/Cargo.toml | 2 +- src/lib.rs | 12 ++++++------ src/render/Cargo.toml | 4 ++-- src/window/dxgi/Cargo.toml | 6 +++--- src/window/glfw/Cargo.toml | 6 +++--- src/window/glutin/Cargo.toml | 6 +++--- src/window/metal/Cargo.toml | 2 +- src/window/sdl/Cargo.toml | 6 +++--- src/window/vulkan/Cargo.toml | 2 +- 14 files changed, 37 insertions(+), 37 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1a6be2fc68a..7cfb3e62654 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,20 +20,20 @@ name = "gfx_app" env_logger = "0.3" glutin = "0.6" winit = "0.5.1" -gfx_core = { path = "src/core", version = "0.4" } -gfx_device_gl = { path = "src/backend/gl", version = "0.11" } +gfx_core = { path = "src/core", version = "0.5" } +gfx = { path = "src/render", version = "0.13" } +gfx_device_gl = { path = "src/backend/gl", version = "0.12" } +gfx_window_glutin = { path = "src/window/glutin", version = "0.13" } gfx_device_vulkan = { path = "src/backend/vulkan", version = "0.1" } -gfx_window_glutin = { path = "src/window/glutin", version = "0.12" } gfx_window_vulkan = { path = "src/window/vulkan", version = "0.1" } -gfx = { path = "src/render", version = "0.12" } [target.'cfg(unix)'.dependencies] -gfx_window_glfw = { path = "src/window/glfw", version = "0.11" } -gfx_window_sdl = { path = "src/window/sdl", version = "0.3" } +gfx_window_glfw = { path = "src/window/glfw", version = "0.12" } +gfx_window_sdl = { path = "src/window/sdl", version = "0.4" } [target.'cfg(windows)'.dependencies] -gfx_device_dx11 = { path = "src/backend/dx11", version = "0.3" } -gfx_window_dxgi = { path = "src/window/dxgi", version = "0.3" } +gfx_device_dx11 = { path = "src/backend/dx11", version = "0.4" } +gfx_window_dxgi = { path = "src/window/dxgi", version = "0.4" } [target.x86_64-apple-darwin.dependencies] gfx_device_metal = { path = "src/backend/metal", version = "0.1" } diff --git a/src/backend/dx11/Cargo.toml b/src/backend/dx11/Cargo.toml index 1d9b3e6ffae..256e3cd8a4d 100644 --- a/src/backend/dx11/Cargo.toml +++ b/src/backend/dx11/Cargo.toml @@ -14,7 +14,7 @@ [package] name = "gfx_device_dx11" -version = "0.3.0" +version = "0.4.0" description = "DirectX-11 backend for gfx-rs" homepage = "https://github.com/gfx-rs/gfx" repository = "https://github.com/gfx-rs/gfx" @@ -27,7 +27,7 @@ name = "gfx_device_dx11" [dependencies] log = "0.3" -gfx_core = { path = "../../core", version = "0.4" } +gfx_core = { path = "../../core", version = "0.5" } d3d11-sys = "0.2" d3dcompiler-sys = "0.2" dxguid-sys = "0.2" diff --git a/src/backend/gl/Cargo.toml b/src/backend/gl/Cargo.toml index 8ccf2038835..0cbd94db13b 100644 --- a/src/backend/gl/Cargo.toml +++ b/src/backend/gl/Cargo.toml @@ -14,7 +14,7 @@ [package] name = "gfx_device_gl" -version = "0.11.2" +version = "0.12.0" description = "OpenGL backend for gfx-rs" homepage = "https://github.com/gfx-rs/gfx" repository = "https://github.com/gfx-rs/gfx" @@ -28,4 +28,4 @@ name = "gfx_device_gl" [dependencies] log = "0.3" gfx_gl = "0.3.1" -gfx_core = { path = "../../core", version = "0.4" } +gfx_core = { path = "../../core", version = "0.5" } diff --git a/src/backend/metal/Cargo.toml b/src/backend/metal/Cargo.toml index 75c860cd09b..2991a10a7f6 100644 --- a/src/backend/metal/Cargo.toml +++ b/src/backend/metal/Cargo.toml @@ -27,7 +27,7 @@ name = "gfx_device_metal" [dependencies] log = "0.3" -gfx_core = { path = "../../core", version = "0.4" } +gfx_core = { path = "../../core", version = "0.5" } cocoa = "0.3" libc = "0.2" objc = "0.1.8" diff --git a/src/backend/vulkan/Cargo.toml b/src/backend/vulkan/Cargo.toml index 85a5f897580..0cc27d3595d 100644 --- a/src/backend/vulkan/Cargo.toml +++ b/src/backend/vulkan/Cargo.toml @@ -17,4 +17,4 @@ vk = "0.0" vk-sys = { path = "../../../../vulkano/vk-sys" } shared_library = "0.1" winit = "0.5" -gfx_core = { path = "../../core", version = "0.4" } +gfx_core = { path = "../../core", version = "0.5" } diff --git a/src/core/Cargo.toml b/src/core/Cargo.toml index b841376ce41..4c315927ddf 100644 --- a/src/core/Cargo.toml +++ b/src/core/Cargo.toml @@ -14,7 +14,7 @@ [package] name = "gfx_core" -version = "0.4.0" +version = "0.5.0" description = "Core library of Gfx-rs" homepage = "https://github.com/gfx-rs/gfx" repository = "https://github.com/gfx-rs/gfx" diff --git a/src/lib.rs b/src/lib.rs index 01494978cb9..25cedf24d98 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -112,22 +112,22 @@ pub trait ApplicationBase> { pub trait Application: Sized { fn new>(F, Init) -> Self; fn render>(&mut self, &mut gfx::Encoder); - #[cfg(feature = "vulkan")] - fn launch_default(name: &str) where WrapVulkan: ApplicationVulkan { - WrapVulkan::::launch(name, DEFAULT_CONFIG); - } - /*#[cfg(target_os = "windows")] + #[cfg(target_os = "windows")] fn launch_default(name: &str) where WrapD3D11: ApplicationD3D11 { WrapD3D11::::launch(name, DEFAULT_CONFIG); } #[cfg(not(target_os = "windows"))] fn launch_default(name: &str) where WrapGL2: ApplicationGL { WrapGL2::::launch(name, DEFAULT_CONFIG); - }*/ + } /*#[cfg(target_os = "macos")] fn launch_default(name: &str) where WrapMetal: ApplicationMetal { WrapMetal::::launch(name, DEFAULT_CONFIG) }*/ + /*#[cfg(feature = "vulkan")] + fn launch_default(name: &str) where WrapVulkan: ApplicationVulkan { + WrapVulkan::::launch(name, DEFAULT_CONFIG); + }*/ } pub struct Wrap, A>{ diff --git a/src/render/Cargo.toml b/src/render/Cargo.toml index 14d98a16457..8ca070185bd 100644 --- a/src/render/Cargo.toml +++ b/src/render/Cargo.toml @@ -14,7 +14,7 @@ [package] name = "gfx" -version = "0.12.0" +version = "0.13.0" description = "A high-performance, bindless graphics API" homepage = "https://github.com/gfx-rs/gfx" repository = "https://github.com/gfx-rs/gfx" @@ -32,4 +32,4 @@ unstable = [] [dependencies] draw_state = "0.6" log = "0.3" -gfx_core = { path = "../core", version = "0.4" } +gfx_core = { path = "../core", version = "0.5" } diff --git a/src/window/dxgi/Cargo.toml b/src/window/dxgi/Cargo.toml index b557bfb9566..3736775e5b3 100644 --- a/src/window/dxgi/Cargo.toml +++ b/src/window/dxgi/Cargo.toml @@ -14,7 +14,7 @@ [package] name = "gfx_window_dxgi" -version = "0.3.0" +version = "0.4.0" description = "DXGI window for gfx-rs" homepage = "https://github.com/gfx-rs/gfx" repository = "https://github.com/gfx-rs/gfx" @@ -30,5 +30,5 @@ log = "0.3" kernel32-sys = "0.2" user32-sys = "0.1" winapi = "0.2" -gfx_core = { path = "../../core", version = "0.4" } -gfx_device_dx11 = { path = "../../backend/dx11", version = "0.3" } +gfx_core = { path = "../../core", version = "0.5" } +gfx_device_dx11 = { path = "../../backend/dx11", version = "0.4" } diff --git a/src/window/glfw/Cargo.toml b/src/window/glfw/Cargo.toml index 72e34c86c2e..3185851d27a 100644 --- a/src/window/glfw/Cargo.toml +++ b/src/window/glfw/Cargo.toml @@ -14,7 +14,7 @@ [package] name = "gfx_window_glfw" -version = "0.11.0" +version = "0.12.0" description = "GLFW window for gfx-rs" homepage = "https://github.com/gfx-rs/gfx" repository = "https://github.com/gfx-rs/gfx" @@ -27,5 +27,5 @@ name = "gfx_window_glfw" [dependencies] glfw = "0.5" -gfx_core = { path = "../../core", version = "0.4" } -gfx_device_gl = { path = "../../backend/gl", version = "0.11" } +gfx_core = { path = "../../core", version = "0.5" } +gfx_device_gl = { path = "../../backend/gl", version = "0.12" } diff --git a/src/window/glutin/Cargo.toml b/src/window/glutin/Cargo.toml index 70405e05722..27d7dc55ee6 100644 --- a/src/window/glutin/Cargo.toml +++ b/src/window/glutin/Cargo.toml @@ -14,7 +14,7 @@ [package] name = "gfx_window_glutin" -version = "0.12.0" +version = "0.13.0" description = "Glutin window for gfx-rs" homepage = "https://github.com/gfx-rs/gfx" repository = "https://github.com/gfx-rs/gfx" @@ -27,5 +27,5 @@ name = "gfx_window_glutin" [dependencies] glutin = "0.6" -gfx_core = { path = "../../core", version = "0.4" } -gfx_device_gl = { path = "../../backend/gl", version = "0.11" } +gfx_core = { path = "../../core", version = "0.5" } +gfx_device_gl = { path = "../../backend/gl", version = "0.12" } diff --git a/src/window/metal/Cargo.toml b/src/window/metal/Cargo.toml index ca1c80c7192..58b0deb5c7b 100644 --- a/src/window/metal/Cargo.toml +++ b/src/window/metal/Cargo.toml @@ -31,5 +31,5 @@ cocoa = "0.2.4" objc = "0.1.8" winit = "0.5.1" metal = { git = "https://github.com/fkaa/metal-rs" } -gfx_core = { path = "../../core", version = "0.4" } +gfx_core = { path = "../../core", version = "0.5" } gfx_device_metal = { path = "../../backend/metal", version = "0.1" } diff --git a/src/window/sdl/Cargo.toml b/src/window/sdl/Cargo.toml index 5fba92fa58b..265a5add087 100644 --- a/src/window/sdl/Cargo.toml +++ b/src/window/sdl/Cargo.toml @@ -14,7 +14,7 @@ [package] name = "gfx_window_sdl" -version = "0.3.0" +version = "0.4.0" description = "SDL2 window for gfx-rs" homepage = "https://github.com/gfx-rs/gfx" repository = "https://github.com/gfx-rs/gfx" @@ -27,5 +27,5 @@ name = "gfx_window_sdl" [dependencies] sdl2 = "0.18" -gfx_core = { path = "../../core", version = "0.4" } -gfx_device_gl = { path = "../../backend/gl", version = "0.11" } +gfx_core = { path = "../../core", version = "0.5" } +gfx_device_gl = { path = "../../backend/gl", version = "0.12" } diff --git a/src/window/vulkan/Cargo.toml b/src/window/vulkan/Cargo.toml index 6697e378305..6db4d39bd75 100644 --- a/src/window/vulkan/Cargo.toml +++ b/src/window/vulkan/Cargo.toml @@ -15,5 +15,5 @@ name = "gfx_window_vulkan" winit = "0.5" xcb = "0.7" vk-sys = { path = "../../../../vulkano/vk-sys" } -gfx_core = { path = "../../core", version = "0.4" } +gfx_core = { path = "../../core", version = "0.5" } gfx_device_vulkan = { path = "../../backend/vulkan", version = "0.1" } From f0f7faabbbf27bf05af01918f29b35eb587eacb1 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Tue, 9 Aug 2016 22:03:29 -0400 Subject: [PATCH 66/69] [GL] Fixed the deferred example u_CamPosAndRadius --- examples/deferred/shader/light.glslf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/deferred/shader/light.glslf b/examples/deferred/shader/light.glslf index ef498266143..fb5c60591e0 100644 --- a/examples/deferred/shader/light.glslf +++ b/examples/deferred/shader/light.glslf @@ -2,7 +2,7 @@ layout(std140) uniform LightLocals { - vec4 u_CameraPosAndRadius; + vec4 u_CamPosAndRadius; }; uniform sampler2D t_Position; uniform sampler2D t_Normal; @@ -18,14 +18,14 @@ void main() { vec3 light = v_LightPos; vec3 to_light = normalize(light - pos); - vec3 to_cam = normalize(u_CameraPosAndRadius.xyz - pos); + vec3 to_cam = normalize(u_CamPosAndRadius.xyz - pos); vec3 n = normalize(normal); float s = pow(max(0.0, dot(to_cam, reflect(-to_light, n))), 20.0); float d = max(0.0, dot(n, to_light)); float dist_sq = dot(light - pos, light - pos); - float scale = max(0.0, 1.0 - dist_sq * u_CameraPosAndRadius.w); + float scale = max(0.0, 1.0 - dist_sq * u_CamPosAndRadius.w); vec3 res_color = d * diffuse + vec3(s); From e58f21e32cc6ca7280f4593cf7d915a8bcb57f9e Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Tue, 9 Aug 2016 22:50:50 -0400 Subject: [PATCH 67/69] [VK] Fixed vk-sys dependency to point to owned git path --- src/backend/vulkan/Cargo.toml | 2 +- src/window/vulkan/Cargo.toml | 2 +- src/window/vulkan/src/lib.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/vulkan/Cargo.toml b/src/backend/vulkan/Cargo.toml index 0cc27d3595d..14aac66182b 100644 --- a/src/backend/vulkan/Cargo.toml +++ b/src/backend/vulkan/Cargo.toml @@ -14,7 +14,7 @@ name = "gfx_device_vulkan" [dependencies] log = "0.3" vk = "0.0" -vk-sys = { path = "../../../../vulkano/vk-sys" } +vk-sys = { git = "https://github.com/sectopod/vulkano", branch = "bind" } shared_library = "0.1" winit = "0.5" gfx_core = { path = "../../core", version = "0.5" } diff --git a/src/window/vulkan/Cargo.toml b/src/window/vulkan/Cargo.toml index 6db4d39bd75..e1e02bbf3e8 100644 --- a/src/window/vulkan/Cargo.toml +++ b/src/window/vulkan/Cargo.toml @@ -14,6 +14,6 @@ name = "gfx_window_vulkan" [dependencies] winit = "0.5" xcb = "0.7" -vk-sys = { path = "../../../../vulkano/vk-sys" } +vk-sys = { git = "https://github.com/sectopod/vulkano", branch = "bind" } gfx_core = { path = "../../core", version = "0.5" } gfx_device_vulkan = { path = "../../backend/vulkan", version = "0.1" } diff --git a/src/window/vulkan/src/lib.rs b/src/window/vulkan/src/lib.rs index 4378df95e5b..4f242638124 100644 --- a/src/window/vulkan/src/lib.rs +++ b/src/window/vulkan/src/lib.rs @@ -243,7 +243,7 @@ pub fn init_xcb(title: &str, width: u32, heig surface: surface, minImageCount: num, imageFormat: gfx_device_vulkan::data::map_format(format.0, format.1).unwrap(), - imageColorSpace: vk::COLORSPACE_SRGB_NONLINEAR_KHR, + imageColorSpace: vk::COLOR_SPACE_SRGB_NONLINEAR_KHR, imageExtent: vk::Extent2D { width: width, height: height }, imageArrayLayers: 1, imageUsage: vk::IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, From 5291dcf33c9f3b58a582e9a03202da0b7cf15589 Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Wed, 10 Aug 2016 21:47:03 -0400 Subject: [PATCH 68/69] [VK] Enabled the feature for Travis CI --- .travis.yml | 4 +++- Cargo.toml | 16 ++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2a33bb8ed84..8cbd2895f07 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,13 +32,15 @@ addons: - libxcursor1 - libsdl2-dev script: - - travis-cargo build + - travis-cargo build -- --features vulkan - travis-cargo test -- -p gfx_core - travis-cargo test -- -p gfx - travis-cargo test -- -p gfx_device_gl - travis-cargo test -- -p gfx_window_glutin - travis-cargo test -- -p gfx_window_glfw - travis-cargo test -- -p gfx_window_sdl +# - travis-cargo test -- -p gfx_device_vulkan +# - travis-cargo test -- -p gfx_window_vulkan - travis-cargo test after_success: - travis-cargo doc -- -j 1 diff --git a/Cargo.toml b/Cargo.toml index 7cfb3e62654..275645aed6a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,8 +8,8 @@ license = "Apache-2.0" authors = ["The Gfx-rs Developers"] [features] -default = ["vulkan"] -vulkan = [] +default = [] +vulkan = ["gfx_device_vulkan", "gfx_window_vulkan"] unstable = [] @@ -24,8 +24,16 @@ gfx_core = { path = "src/core", version = "0.5" } gfx = { path = "src/render", version = "0.13" } gfx_device_gl = { path = "src/backend/gl", version = "0.12" } gfx_window_glutin = { path = "src/window/glutin", version = "0.13" } -gfx_device_vulkan = { path = "src/backend/vulkan", version = "0.1" } -gfx_window_vulkan = { path = "src/window/vulkan", version = "0.1" } + +[dependencies.gfx_device_vulkan] +path = "src/backend/vulkan" +version = "0.1" +optional = true + +[dependencies.gfx_window_vulkan] +path = "src/window/vulkan" +version = "0.1" +optional = true [target.'cfg(unix)'.dependencies] gfx_window_glfw = { path = "src/window/glfw", version = "0.12" } From 7e0767bfdc75ae351232f849a47c0cfb4698ecdb Mon Sep 17 00:00:00 2001 From: Kael Choi Date: Thu, 11 Aug 2016 21:54:14 -0400 Subject: [PATCH 69/69] [DX11] Ported to the new Core API --- appveyor.yml | 2 +- src/backend/dx11/src/command.rs | 25 +++++++++++++++++-------- src/backend/dx11/src/factory.rs | 20 ++++++++++++-------- src/backend/dx11/src/lib.rs | 1 + src/lib.rs | 2 +- src/shade.rs | 2 +- 6 files changed, 33 insertions(+), 19 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 6eecc0146c8..2c1be3bb197 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,7 +7,7 @@ environment: - TARGET: nightly-x86_64-pc-windows COMPILER: msvc install: - - if %COMPILER%==gnu choco install mingw + - if %COMPILER%==gnu choco install -y mingw - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-${env:TARGET}-${env:COMPILER}.exe" -FileName "rust-install.exe" - ps: .\rust-install.exe /VERYSILENT /NORESTART /DIR="C:\rust" | Out-Null - ps: $env:PATH="$env:PATH;C:\rust\bin;C:\tools\mingw64\bin" diff --git a/src/backend/dx11/src/command.rs b/src/backend/dx11/src/command.rs index 042382a56a3..7047d7d63c3 100644 --- a/src/backend/dx11/src/command.rs +++ b/src/backend/dx11/src/command.rs @@ -91,7 +91,7 @@ pub enum Command { unsafe impl Send for Command {} struct Cache { - attributes: [Option; MAX_VERTEX_ATTRIBUTES], + attrib_strides: [Option; MAX_VERTEX_ATTRIBUTES], rasterizer: *const ID3D11RasterizerState, depth_stencil: *const ID3D11DepthStencilState, stencil_ref: UINT, @@ -103,7 +103,7 @@ unsafe impl Send for Cache {} impl Cache { fn new() -> Cache { Cache { - attributes: [None; MAX_VERTEX_ATTRIBUTES], + attrib_strides: [None; MAX_VERTEX_ATTRIBUTES], rasterizer: ptr::null(), depth_stencil: ptr::null(), stencil_ref: 0, @@ -150,7 +150,15 @@ impl draw::CommandBuffer for CommandBuffer

{ fn bind_pipeline_state(&mut self, pso: Pipeline) { self.parser.parse(Command::SetPrimitive(pso.topology)); - self.cache.attributes = pso.attributes; + for (stride, ad_option) in self.cache.attrib_strides.iter_mut().zip(pso.attributes.iter()) { + *stride = ad_option.map(|(buf_id, _)| match pso.vertex_buffers[buf_id as usize] { + Some(ref bdesc) => bdesc.stride, + None => { + error!("Unexpected use of buffer id {}", buf_id); + 0 + }, + }); + } if self.cache.rasterizer != pso.rasterizer { self.cache.rasterizer = pso.rasterizer; self.parser.parse(Command::SetRasterizer(pso.rasterizer)); @@ -162,17 +170,18 @@ impl draw::CommandBuffer for CommandBuffer

{ } fn bind_vertex_buffers(&mut self, vbs: pso::VertexBufferSet) { + //Note: assumes `bind_pipeline_state` is called prior let mut buffers = [native::Buffer(ptr::null_mut()); MAX_VERTEX_ATTRIBUTES]; let mut strides = [0; MAX_VERTEX_ATTRIBUTES]; let mut offsets = [0; MAX_VERTEX_ATTRIBUTES]; for i in 0 .. MAX_VERTEX_ATTRIBUTES { - match (vbs.0[i], self.cache.attributes[i]) { - (None, Some(fm)) => { - error!("No vertex input provided for slot {} of format {:?}", i, fm) + match (vbs.0[i], self.cache.attrib_strides[i]) { + (None, Some(stride)) => { + error!("No vertex input provided for slot {} with stride {}", i, stride) }, - (Some((buffer, offset)), Some(ref format)) => { + (Some((buffer, offset)), Some(stride)) => { buffers[i] = buffer.0; - strides[i] = format.0.stride as UINT; + strides[i] = stride as UINT; offsets[i] = offset as UINT; }, (_, None) => (), diff --git a/src/backend/dx11/src/factory.rs b/src/backend/dx11/src/factory.rs index 1df2a520b9e..8f4a035aac6 100644 --- a/src/backend/dx11/src/factory.rs +++ b/src/backend/dx11/src/factory.rs @@ -446,8 +446,11 @@ impl core::Factory for Factory { let mut charpos = 0; for (attrib, at_desc) in program.get_info().vertex_attributes.iter().zip(desc.attributes.iter()) { use winapi::UINT; - let (elem, irate) = match at_desc { - &Some((ref el, ir)) => (el, ir), + let (bdesc, elem) = match at_desc { + &Some((buf_id, ref el)) => match desc.vertex_buffers[buf_id as usize] { + Some(ref bd) => (bd, el), + None => return Err(core::pso::CreationError), + }, &None => continue, }; if elem.offset & 1 != 0 { @@ -467,12 +470,12 @@ impl core::Factory for Factory { }, InputSlot: attrib.slot as UINT, AlignedByteOffset: elem.offset as UINT, - InputSlotClass: if irate == 0 { + InputSlotClass: if bdesc.rate == 0 { winapi::D3D11_INPUT_PER_VERTEX_DATA }else { winapi::D3D11_INPUT_PER_INSTANCE_DATA }, - InstanceDataStepRate: irate as UINT, + InstanceDataStepRate: bdesc.rate as UINT, }); for (out, inp) in charbuf[charpos..].iter_mut().zip(attrib.name.as_bytes().iter()) { *out = *inp as i8; @@ -513,6 +516,7 @@ impl core::Factory for Factory { TriangleStrip => D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, }, layout: vertex_layout, + vertex_buffers: desc.vertex_buffers, attributes: desc.attributes, program: prog, rasterizer: state::make_rasterizer(dev, &desc.rasterizer, desc.scissor), @@ -704,8 +708,8 @@ impl core::Factory for Factory { (winapi::D3D11_RTV_DIMENSION_TEXTURE2DARRAY, [level, 0, 6 * nlayers as UINT]), (Kind::CubeArray(_, nlayers), Some(lid)) if lid < nlayers => (winapi::D3D11_RTV_DIMENSION_TEXTURE2DARRAY, [level, 6 * lid as UINT, 6 * (1+lid) as UINT]), - (_, None) => return Err(f::TargetViewError::BadLevel(desc.level)), - (_, Some(lid)) => return Err(f::TargetViewError::BadLayer(lid)), + (_, None) => return Err(f::TargetViewError::Level(desc.level)), + (_, Some(lid)) => return Err(f::TargetViewError::Layer(f::LayerError::OutOfBounds(lid, 0))), //TODO }; let format = core::format::Format(htex.get_info().format, desc.channel); let native_desc = winapi::D3D11_RENDER_TARGET_VIEW_DESC { @@ -765,8 +769,8 @@ impl core::Factory for Factory { (winapi::D3D11_DSV_DIMENSION_TEXTURE2DARRAY, [level, 0, 6 * nlayers as UINT]), (Kind::CubeArray(_, nlayers), Some(lid)) if lid < nlayers => (winapi::D3D11_DSV_DIMENSION_TEXTURE2DARRAY, [level, 6 * lid as UINT, 6 * (1+lid) as UINT]), - (_, None) => return Err(f::TargetViewError::BadLevel(desc.level)), - (_, Some(lid)) => return Err(f::TargetViewError::BadLayer(lid)), + (_, None) => return Err(f::TargetViewError::Level(desc.level)), + (_, Some(lid)) => return Err(f::TargetViewError::Layer(f::LayerError::OutOfBounds(lid, 0))), //TODO }; let channel = core::format::ChannelType::Uint; //doesn't matter diff --git a/src/backend/dx11/src/lib.rs b/src/backend/dx11/src/lib.rs index b1554367343..874f0f20c3c 100644 --- a/src/backend/dx11/src/lib.rs +++ b/src/backend/dx11/src/lib.rs @@ -123,6 +123,7 @@ pub type InputLayout = *mut winapi::ID3D11InputLayout; pub struct Pipeline { topology: winapi::D3D11_PRIMITIVE_TOPOLOGY, layout: InputLayout, + vertex_buffers: [Option; gfx_core::pso::MAX_VERTEX_BUFFERS], attributes: [Option; gfx_core::MAX_VERTEX_ATTRIBUTES], program: Program, rasterizer: *const winapi::ID3D11RasterizerState, diff --git a/src/lib.rs b/src/lib.rs index 25cedf24d98..576d9bfa3ef 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -256,7 +256,7 @@ impl< use gfx::traits::{Device, Factory}; env_logger::init().unwrap(); - let (window, device, factory, main_color) = + let (window, device, mut factory, main_color) = gfx_window_dxgi::init::(title, config.size.0, config.size.1) .unwrap(); let main_depth = factory.create_depth_stencil_view_only( diff --git a/src/shade.rs b/src/shade.rs index f5190dd9e50..124bd35f340 100644 --- a/src/shade.rs +++ b/src/shade.rs @@ -109,7 +109,7 @@ impl<'a> Source<'a> { Source { hlsl_41: s, .. } if s != EMPTY && model >= 41 => s, Source { hlsl_40: s, .. } if s != EMPTY && model >= 40 => s, Source { hlsl_30: s, .. } if s != EMPTY && model >= 30 => s, - _ => Err(SelectError(backend)) + _ => return Err(SelectError(backend)) }, #[cfg(target_os = "macos")] Backend::Msl(revision) => match *self {