From d308cd7216af9dcc8ec736a9d39ea44297556b5b Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Thu, 1 Mar 2018 22:04:47 -0500 Subject: [PATCH] Metal support, dispatch feature --- .travis.yml | 49 ++++++++++++++-- Makefile | 29 +++++++++- README.md | 7 ++- libportability-gfx/Cargo.toml | 16 ++++-- libportability-gfx/src/handle.rs | 96 +++++++++++++++++--------------- libportability-gfx/src/impls.rs | 12 ++-- libportability-gfx/src/lib.rs | 8 ++- libportability-icd/Cargo.toml | 13 +++-- libportability/Cargo.toml | 11 +++- native/test.cpp | 6 +- native/window.cpp | 12 +++- native/window.hpp | 11 +++- 12 files changed, 190 insertions(+), 80 deletions(-) diff --git a/.travis.yml b/.travis.yml index 025636a..855552a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,54 @@ sudo: false language: rust -rust: - - stable - - nightly -os: - - linux +matrix: + include: + - os: linux + rust: stable + compiler: gcc + - os: linux + rust: nightly + compiler: gcc + - os: osx + rust: stable + osx_image: xcode9 + compiler: clang branches: except: - staging.tmp +before_install: + # Do not run bors builds against the nightly compiler. + # We want to find out about nightly bugs, so they're done in master, but we don't block on them. + - if [[ $TRAVIS_RUST_VERSION == "nightly" && $TRAVIS_BRANCH == "staging" ]]; then exit; fi + - if [[ $TRAVIS_OS_NAME == "osx" ]]; then brew update && brew install sdl2 && brew upgrade cmake && export CXX=clang++ && export MACOSX_DEPLOYMENT_TARGET=10.9; fi + +addons: + apt: + sources: + # install a newer cmake since at this time Travis only has version 2.8.7 + - george-edison55-precise-backports + - llvm-toolchain-precise-3.8 + - ubuntu-toolchain-r-test + #- ppa:xorg-edgers/ppa # for libosmesa6-dev + packages: + - xdotool + - cmake + - cmake-data + - libxxf86vm-dev + - libxinerama-dev + - libxinerama1 + - libxcursor-dev + - libxcursor1 + - libglfw-dev + - libosmesa6-dev + - libxi-dev + - libxrandr-dev + - g++-5 + - gcc + script: + - if [[ $TRAVIS_RUST_VERSION == "nightly" && $TRAVIS_BRANCH == "staging" ]]; then exit; fi + - export PATH=$PATH:$HOME/deps/bin - make diff --git a/Makefile b/Makefile index 11ab14b..aaab833 100644 --- a/Makefile +++ b/Makefile @@ -3,12 +3,35 @@ BINDING=target/vulkan.rs NATIVE_DIR=target/native TARGET=$(NATIVE_DIR)/test OBJECTS=$(NATIVE_DIR)/test.o $(NATIVE_DIR)/window.o -LIBRARY=target/debug/libportability.so +LIB_EXTENSION= + +RUST_BACKTRACE:=1 +BACKEND:=gl CC=g++ CFLAGS=-std=c++11 -ggdb -O0 -I$(VULKAN_DIR) DEPS= -LDFLAGS=-lpthread -ldl -lm -lX11 -lxcb +LDFLAGS= + +ifeq ($(OS),Windows_NT) + LDFLAGS= + BACKEND=dx12 + LIB_EXTENSION=dll +else + UNAME_S:=$(shell uname -s) + ifeq ($(UNAME_S),Linux) + LDFLAGS=-lpthread -ldl -lm -lX11 -lxcb + BACKEND=vulkan + LIB_EXTENSION=so + endif + ifeq ($(UNAME_S),Darwin) + LDFLAGS=-lpthread -ldl -lm + BACKEND=metal + LIB_EXTENSION=dylib + endif +endif + +LIBRARY=target/debug/libportability.$(LIB_EXTENSION) .PHONY: all binding run @@ -20,7 +43,7 @@ $(BINDING): $(VULKAN_DIR)/vulkan/*.h bindgen --no-layout-tests --rustfmt-bindings $(VULKAN_DIR)/vulkan/vulkan.h -o $(BINDING) $(LIBRARY): libportability/src/*.rs libportability-gfx/src/*.rs Cargo.toml $(wildcard Cargo.lock) - cargo build --manifest-path libportability/Cargo.toml --features vulkan + cargo build --manifest-path libportability/Cargo.toml --features $(BACKEND) mkdir -p target/native $(NATIVE_DIR)/%.o: native/%.cpp $(DEPS) Makefile diff --git a/README.md b/README.md index f2d038c..032dbee 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,11 @@ This is a prototype library implementing [Vulkan Portability Initiative](https://www.khronos.org/blog/khronos-announces-the-vulkan-portability-initiative) using gfx-rs [low-level core](http://gfx-rs.github.io/2017/07/24/low-level.html). See gfx-rs [meta issue](https://github.com/gfx-rs/gfx/issues/1354) for backend limitations and further details. +## Check out +``` +git clone --recursive https://github.com/gfx-rs/portability && cd portability +``` + ## Build ### Makefile (Unix) @@ -15,7 +20,7 @@ make Build the Rust library (portability implementation): ``` -cargo build --manifest-path libportability/Cargo.toml --features +cargo build --manifest-path libportability/Cargo.toml --features ``` Build the native example: diff --git a/libportability-gfx/Cargo.toml b/libportability-gfx/Cargo.toml index ccc99c6..bba8d00 100644 --- a/libportability-gfx/Cargo.toml +++ b/libportability-gfx/Cargo.toml @@ -1,16 +1,19 @@ [package] name = "portability-gfx" +publish = false version = "0.1.0" -authors = ["Dzmitry Malyshau "] +authors = [ + "Dzmitry Malyshau ", + "Markus Siglreight ", +] [lib] name = "portability_gfx" [features] default = [] +dispatch = [] #default = ["env_logger"] # uncomment for debugging -dx12 = ["gfx-backend-dx12"] -vulkan = ["gfx-backend-vulkan"] [dependencies] lazy_static = "1.0" @@ -24,7 +27,7 @@ optional = true git = "https://github.com/gfx-rs/gfx" rev = "070e0cee47ae6f0c395a3402fd6f889c1315ef3e" -[dependencies.gfx-backend-vulkan] +[target.'cfg(not(target_os = "macos"))'.dependencies.gfx-backend-vulkan] git = "https://github.com/gfx-rs/gfx" rev = "070e0cee47ae6f0c395a3402fd6f889c1315ef3e" optional = true @@ -33,3 +36,8 @@ optional = true git = "https://github.com/gfx-rs/gfx" rev = "070e0cee47ae6f0c395a3402fd6f889c1315ef3e" optional = true + +[target.'cfg(target_os = "macos")'.dependencies.gfx-backend-metal] +git = "https://github.com/gfx-rs/gfx" +rev = "070e0cee47ae6f0c395a3402fd6f889c1315ef3e" +optional = true diff --git a/libportability-gfx/src/handle.rs b/libportability-gfx/src/handle.rs index 6fdbaa9..760448f 100644 --- a/libportability-gfx/src/handle.rs +++ b/libportability-gfx/src/handle.rs @@ -1,8 +1,6 @@ use VK_NULL_HANDLE; use std::{borrow, fmt, ops}; -static ICD_LOADER_MAGIC: u32 = 0x01CDC0DE; - #[repr(C)] pub struct Handle(*mut T); @@ -54,52 +52,62 @@ impl fmt::Debug for Handle { } } -#[repr(C)] -pub struct DispatchHandle(u32, Handle); +#[cfg(feature = "dispatch")] +pub use self::dispatch::DispatchHandle; +#[cfg(not(feature = "dispatch"))] +pub type DispatchHandle = Handle; -impl DispatchHandle { - pub fn new(value: T) -> Self { - DispatchHandle(ICD_LOADER_MAGIC, Handle::new(value)) +#[cfg(feature = "dispatch")] +mod dispatch { + const ICD_LOADER_MAGIC: u32 = 0x01CDC0DE; + + #[repr(C)] + pub struct DispatchHandle(u32, super::Handle); + + impl DispatchHandle { + pub fn new(value: T) -> Self { + DispatchHandle(ICD_LOADER_MAGIC, super::Handle::new(value)) + } + + pub fn unwrap(self) -> Box { + self.1.unwrap() + } + + pub fn is_null(&self) -> bool { + self.1.is_null() + } } - pub fn unwrap(self) -> Box { - self.1.unwrap() + impl Clone for DispatchHandle { + fn clone(&self) -> Self { + DispatchHandle(self.0, self.1) + } } - pub fn is_null(&self) -> bool { - self.1.is_null() - } -} - -impl Clone for DispatchHandle { - fn clone(&self) -> Self { - DispatchHandle(self.0, self.1) - } -} - -impl Copy for DispatchHandle {} - -impl ops::Deref for DispatchHandle { - type Target = T; - fn deref(&self) -> &T { - self.1.deref() - } -} - -impl ops::DerefMut for DispatchHandle { - fn deref_mut(&mut self) -> &mut T { - self.1.deref_mut() - } -} - -impl borrow::Borrow for DispatchHandle { - fn borrow(&self) -> &T { - self.1.borrow() - } -} - -impl fmt::Debug for DispatchHandle { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - write!(formatter, "DispatchHandle({:p})", (self.1).0) + impl Copy for DispatchHandle {} + + impl ops::Deref for DispatchHandle { + type Target = T; + fn deref(&self) -> &T { + self.1.deref() + } + } + + impl ops::DerefMut for DispatchHandle { + fn deref_mut(&mut self) -> &mut T { + self.1.deref_mut() + } + } + + impl borrow::Borrow for DispatchHandle { + fn borrow(&self) -> &T { + self.1.borrow() + } + } + + impl fmt::Debug for DispatchHandle { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "DispatchHandle({:p})", (self.1).0) + } } } diff --git a/libportability-gfx/src/impls.rs b/libportability-gfx/src/impls.rs index 4c899fa..e0d2c23 100644 --- a/libportability-gfx/src/impls.rs +++ b/libportability-gfx/src/impls.rs @@ -44,7 +44,7 @@ pub extern "C" fn gfxCreateInstance( env_logger::init(); } let instance = back::Instance::create("portability", 1); - unsafe { *pInstance = Handle::new(instance) }; + unsafe { *pInstance = DispatchHandle::new(instance) }; VkResult::VK_SUCCESS } @@ -75,7 +75,7 @@ pub extern "C" fn gfxEnumeratePhysicalDevices( let count = cmp::min(adapters.len(), output.len()); for (out, adapter) in output.iter_mut().zip(adapters.into_iter()) { - *out = Handle::new(adapter); + *out = DispatchHandle::new(adapter); } unsafe { *pPhysicalDeviceCount = count as _ }; @@ -3205,7 +3205,7 @@ pub extern "C" fn gfxCreateWin32SurfaceKHR( pSurface: *mut VkSurfaceKHR, ) -> VkResult { let info = unsafe { &*pCreateInfo }; - #[cfg(all(feature = "vulkan", target_os = "windows"))] + #[cfg(all(feature = "gfx-backend-vulkan", target_os = "windows"))] { unsafe { assert_eq!(info.flags, 0); @@ -3216,7 +3216,7 @@ pub extern "C" fn gfxCreateWin32SurfaceKHR( VkResult::VK_SUCCESS } } - #[cfg(feature = "dx12")] + #[cfg(feature = "gfx-backend-dx12")] { unsafe { assert_eq!(info.flags, 0); @@ -3235,7 +3235,7 @@ pub extern "C" fn gfxCreateXcbSurfaceKHR( pSurface: *mut VkSurfaceKHR, ) -> VkResult { let info = unsafe { &*pCreateInfo }; - #[cfg(all(feature = "vulkan", target_os = "linux"))] + #[cfg(all(feature = "gfx-backend-vulkan", target_os = "linux"))] { unsafe { assert_eq!(info.flags, 0); @@ -3246,7 +3246,7 @@ pub extern "C" fn gfxCreateXcbSurfaceKHR( VkResult::VK_SUCCESS } } - #[cfg(not(all(feature = "vulkan", target_os = "linux")))] + #[cfg(not(all(feature = "gfx-backend-vulkan", target_os = "linux")))] unreachable!() } #[inline] diff --git a/libportability-gfx/src/lib.rs b/libportability-gfx/src/lib.rs index ec746b6..e696f45 100644 --- a/libportability-gfx/src/lib.rs +++ b/libportability-gfx/src/lib.rs @@ -4,9 +4,11 @@ #![allow(improper_ctypes)] //TEMP: buggy Rustc FFI analysis extern crate gfx_hal as hal; -#[cfg(feature = "dx12")] +#[cfg(feature = "gfx-backend-dx12")] extern crate gfx_backend_dx12 as back; -#[cfg(feature = "vulkan")] +#[cfg(feature = "gfx-backend-metal")] +extern crate gfx_backend_metal as back; +#[cfg(feature = "gfx-backend-vulkan")] extern crate gfx_backend_vulkan as back; #[macro_use] @@ -30,7 +32,7 @@ pub use impls::*; // Vulkan objects pub type VkInstance = Handle; -pub type VkPhysicalDevice = Handle>; +pub type VkPhysicalDevice = DispatchHandle>; pub type VkDevice = DispatchHandle>; pub type VkQueue = DispatchHandle<::CommandQueue>; pub type VkCommandPool = Handle<::CommandPool>; diff --git a/libportability-icd/Cargo.toml b/libportability-icd/Cargo.toml index 5125b4e..3368940 100644 --- a/libportability-icd/Cargo.toml +++ b/libportability-icd/Cargo.toml @@ -1,7 +1,11 @@ [package] name = "portability-icd" +publish = false version = "0.1.0" -authors = ["Dzmitry Malyshau "] +authors = [ + "Dzmitry Malyshau ", + "Markus Siglreightmaier ", +] [lib] name = "portability_icd" @@ -9,8 +13,9 @@ crate-type = ["cdylib"] [features] default = [] -dx12 = ["portability-gfx/dx12"] -vulkan = ["portability-gfx/vulkan"] +dx12 = ["portability-gfx/gfx-backend-dx12"] +metal = ["portability-gfx/gfx-backend-metal"] +vulkan = ["portability-gfx/gfx-backend-vulkan"] [dependencies] -portability-gfx = { path = "../libportability-gfx" } +portability-gfx = { path = "../libportability-gfx", features = ["dispatch"] } diff --git a/libportability/Cargo.toml b/libportability/Cargo.toml index 27f998e..d3f819a 100644 --- a/libportability/Cargo.toml +++ b/libportability/Cargo.toml @@ -1,7 +1,11 @@ [package] name = "portability" +publish = false version = "0.1.0" -authors = ["Dzmitry Malyshau "] +authors = [ + "Dzmitry Malyshau ", + "Markus Siglreightmaier ", +] [lib] name = "portability" @@ -9,8 +13,9 @@ crate-type = ["cdylib"] [features] default = [] -dx12 = ["portability-gfx/dx12"] -vulkan = ["portability-gfx/vulkan"] +dx12 = ["portability-gfx/gfx-backend-dx12"] +metal = ["portability-gfx/gfx-backend-metal"] +vulkan = ["portability-gfx/gfx-backend-vulkan"] [dependencies] portability-gfx = { path = "../libportability-gfx" } diff --git a/native/test.cpp b/native/test.cpp index 95bb1a5..3f00276 100644 --- a/native/test.cpp +++ b/native/test.cpp @@ -20,7 +20,7 @@ */ -#if defined(_WIN32) +#ifdef _WIN32 #define VK_USE_PLATFORM_WIN32_KHR #endif @@ -79,9 +79,9 @@ int main() { Config config = { 10, 10, width, height }; Window window = new_window(config); - VkSurfaceKHR surface; + VkSurfaceKHR surface = 0; -#if defined(_WIN32) +#ifdef _WIN32 VkWin32SurfaceCreateInfoKHR surface_info = {}; surface_info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; surface_info.hinstance = window.instance; diff --git a/native/window.cpp b/native/window.cpp index 41ffad8..d106233 100644 --- a/native/window.cpp +++ b/native/window.cpp @@ -3,7 +3,7 @@ #include "window.hpp" -#if defined(_WIN32) +#ifdef _WIN32 const char *CLASS_NAME = "PortabilityClass"; auto WINAPI window_func(HWND hwnd, UINT u_msg, WPARAM w_param, LPARAM l_param) -> LRESULT { @@ -78,6 +78,16 @@ auto poll_events() -> bool { return true; } +#elif __APPLE__ +auto new_window(Config config) -> Window { + Window window = Window {}; + return window; +} + +auto poll_events() -> bool { + return true; +} + #else auto new_window(Config config) -> Window { auto connection = xcb_connect(NULL, NULL); diff --git a/native/window.hpp b/native/window.hpp index 373e500..68f60c0 100644 --- a/native/window.hpp +++ b/native/window.hpp @@ -2,16 +2,21 @@ #include -#if defined(_WIN32) +#ifdef _WIN32 #include -#else +#elif __APPLE__ +//TODO +#elif __unix__ #include +#else +#error "unknown platform" #endif struct Window { -#if defined(_WIN32) +#ifdef _WIN32 HINSTANCE instance; HWND window; +#elif __APPLE__ #else xcb_connection_t *connection; xcb_drawable_t window;