Metal support, dispatch feature

This commit is contained in:
Dzmitry Malyshau 2018-03-01 22:04:47 -05:00
parent 1c06394db0
commit d308cd7216
12 changed files with 190 additions and 80 deletions

View file

@ -1,15 +1,54 @@
sudo: false sudo: false
language: rust language: rust
rust: matrix:
- stable include:
- nightly - os: linux
os: rust: stable
- linux compiler: gcc
- os: linux
rust: nightly
compiler: gcc
- os: osx
rust: stable
osx_image: xcode9
compiler: clang
branches: branches:
except: except:
- staging.tmp - 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: script:
- if [[ $TRAVIS_RUST_VERSION == "nightly" && $TRAVIS_BRANCH == "staging" ]]; then exit; fi
- export PATH=$PATH:$HOME/deps/bin
- make - make

View file

@ -3,12 +3,35 @@ BINDING=target/vulkan.rs
NATIVE_DIR=target/native NATIVE_DIR=target/native
TARGET=$(NATIVE_DIR)/test TARGET=$(NATIVE_DIR)/test
OBJECTS=$(NATIVE_DIR)/test.o $(NATIVE_DIR)/window.o OBJECTS=$(NATIVE_DIR)/test.o $(NATIVE_DIR)/window.o
LIBRARY=target/debug/libportability.so LIB_EXTENSION=
RUST_BACKTRACE:=1
BACKEND:=gl
CC=g++ CC=g++
CFLAGS=-std=c++11 -ggdb -O0 -I$(VULKAN_DIR) CFLAGS=-std=c++11 -ggdb -O0 -I$(VULKAN_DIR)
DEPS= 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 .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) 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) $(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 mkdir -p target/native
$(NATIVE_DIR)/%.o: native/%.cpp $(DEPS) Makefile $(NATIVE_DIR)/%.o: native/%.cpp $(DEPS) Makefile

View file

@ -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. 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 ## Build
### Makefile (Unix) ### Makefile (Unix)
@ -15,7 +20,7 @@ make
Build the Rust library (portability implementation): Build the Rust library (portability implementation):
``` ```
cargo build --manifest-path libportability/Cargo.toml --features <vulkan|dx12> cargo build --manifest-path libportability/Cargo.toml --features <vulkan|dx12|metal>
``` ```
Build the native example: Build the native example:

View file

@ -1,16 +1,19 @@
[package] [package]
name = "portability-gfx" name = "portability-gfx"
publish = false
version = "0.1.0" version = "0.1.0"
authors = ["Dzmitry Malyshau <kvark@mozilla.com>"] authors = [
"Dzmitry Malyshau <kvark@mozilla.com>",
"Markus Siglreight <m.siglreith@gmail.com>",
]
[lib] [lib]
name = "portability_gfx" name = "portability_gfx"
[features] [features]
default = [] default = []
dispatch = []
#default = ["env_logger"] # uncomment for debugging #default = ["env_logger"] # uncomment for debugging
dx12 = ["gfx-backend-dx12"]
vulkan = ["gfx-backend-vulkan"]
[dependencies] [dependencies]
lazy_static = "1.0" lazy_static = "1.0"
@ -24,7 +27,7 @@ optional = true
git = "https://github.com/gfx-rs/gfx" git = "https://github.com/gfx-rs/gfx"
rev = "070e0cee47ae6f0c395a3402fd6f889c1315ef3e" rev = "070e0cee47ae6f0c395a3402fd6f889c1315ef3e"
[dependencies.gfx-backend-vulkan] [target.'cfg(not(target_os = "macos"))'.dependencies.gfx-backend-vulkan]
git = "https://github.com/gfx-rs/gfx" git = "https://github.com/gfx-rs/gfx"
rev = "070e0cee47ae6f0c395a3402fd6f889c1315ef3e" rev = "070e0cee47ae6f0c395a3402fd6f889c1315ef3e"
optional = true optional = true
@ -33,3 +36,8 @@ optional = true
git = "https://github.com/gfx-rs/gfx" git = "https://github.com/gfx-rs/gfx"
rev = "070e0cee47ae6f0c395a3402fd6f889c1315ef3e" rev = "070e0cee47ae6f0c395a3402fd6f889c1315ef3e"
optional = true optional = true
[target.'cfg(target_os = "macos")'.dependencies.gfx-backend-metal]
git = "https://github.com/gfx-rs/gfx"
rev = "070e0cee47ae6f0c395a3402fd6f889c1315ef3e"
optional = true

View file

@ -1,8 +1,6 @@
use VK_NULL_HANDLE; use VK_NULL_HANDLE;
use std::{borrow, fmt, ops}; use std::{borrow, fmt, ops};
static ICD_LOADER_MAGIC: u32 = 0x01CDC0DE;
#[repr(C)] #[repr(C)]
pub struct Handle<T>(*mut T); pub struct Handle<T>(*mut T);
@ -54,52 +52,62 @@ impl<T> fmt::Debug for Handle<T> {
} }
} }
#[repr(C)] #[cfg(feature = "dispatch")]
pub struct DispatchHandle<T>(u32, Handle<T>); pub use self::dispatch::DispatchHandle;
#[cfg(not(feature = "dispatch"))]
pub type DispatchHandle<T> = Handle<T>;
impl<T> DispatchHandle<T> { #[cfg(feature = "dispatch")]
pub fn new(value: T) -> Self { mod dispatch {
DispatchHandle(ICD_LOADER_MAGIC, Handle::new(value)) const ICD_LOADER_MAGIC: u32 = 0x01CDC0DE;
#[repr(C)]
pub struct DispatchHandle<T>(u32, super::Handle<T>);
impl<T> DispatchHandle<T> {
pub fn new(value: T) -> Self {
DispatchHandle(ICD_LOADER_MAGIC, super::Handle::new(value))
}
pub fn unwrap(self) -> Box<T> {
self.1.unwrap()
}
pub fn is_null(&self) -> bool {
self.1.is_null()
}
} }
pub fn unwrap(self) -> Box<T> { impl<T> Clone for DispatchHandle<T> {
self.1.unwrap() fn clone(&self) -> Self {
DispatchHandle(self.0, self.1)
}
} }
pub fn is_null(&self) -> bool { impl<T> Copy for DispatchHandle<T> {}
self.1.is_null()
} impl<T> ops::Deref for DispatchHandle<T> {
} type Target = T;
fn deref(&self) -> &T {
impl<T> Clone for DispatchHandle<T> { self.1.deref()
fn clone(&self) -> Self { }
DispatchHandle(self.0, self.1) }
}
} impl<T> ops::DerefMut for DispatchHandle<T> {
fn deref_mut(&mut self) -> &mut T {
impl<T> Copy for DispatchHandle<T> {} self.1.deref_mut()
}
impl<T> ops::Deref for DispatchHandle<T> { }
type Target = T;
fn deref(&self) -> &T { impl<T> borrow::Borrow<T> for DispatchHandle<T> {
self.1.deref() fn borrow(&self) -> &T {
} self.1.borrow()
} }
}
impl<T> ops::DerefMut for DispatchHandle<T> {
fn deref_mut(&mut self) -> &mut T { impl<T> fmt::Debug for DispatchHandle<T> {
self.1.deref_mut() fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
} write!(formatter, "DispatchHandle({:p})", (self.1).0)
} }
impl<T> borrow::Borrow<T> for DispatchHandle<T> {
fn borrow(&self) -> &T {
self.1.borrow()
}
}
impl<T> fmt::Debug for DispatchHandle<T> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "DispatchHandle({:p})", (self.1).0)
} }
} }

View file

@ -44,7 +44,7 @@ pub extern "C" fn gfxCreateInstance(
env_logger::init(); env_logger::init();
} }
let instance = back::Instance::create("portability", 1); let instance = back::Instance::create("portability", 1);
unsafe { *pInstance = Handle::new(instance) }; unsafe { *pInstance = DispatchHandle::new(instance) };
VkResult::VK_SUCCESS VkResult::VK_SUCCESS
} }
@ -75,7 +75,7 @@ pub extern "C" fn gfxEnumeratePhysicalDevices(
let count = cmp::min(adapters.len(), output.len()); let count = cmp::min(adapters.len(), output.len());
for (out, adapter) in output.iter_mut().zip(adapters.into_iter()) { for (out, adapter) in output.iter_mut().zip(adapters.into_iter()) {
*out = Handle::new(adapter); *out = DispatchHandle::new(adapter);
} }
unsafe { *pPhysicalDeviceCount = count as _ }; unsafe { *pPhysicalDeviceCount = count as _ };
@ -3205,7 +3205,7 @@ pub extern "C" fn gfxCreateWin32SurfaceKHR(
pSurface: *mut VkSurfaceKHR, pSurface: *mut VkSurfaceKHR,
) -> VkResult { ) -> VkResult {
let info = unsafe { &*pCreateInfo }; let info = unsafe { &*pCreateInfo };
#[cfg(all(feature = "vulkan", target_os = "windows"))] #[cfg(all(feature = "gfx-backend-vulkan", target_os = "windows"))]
{ {
unsafe { unsafe {
assert_eq!(info.flags, 0); assert_eq!(info.flags, 0);
@ -3216,7 +3216,7 @@ pub extern "C" fn gfxCreateWin32SurfaceKHR(
VkResult::VK_SUCCESS VkResult::VK_SUCCESS
} }
} }
#[cfg(feature = "dx12")] #[cfg(feature = "gfx-backend-dx12")]
{ {
unsafe { unsafe {
assert_eq!(info.flags, 0); assert_eq!(info.flags, 0);
@ -3235,7 +3235,7 @@ pub extern "C" fn gfxCreateXcbSurfaceKHR(
pSurface: *mut VkSurfaceKHR, pSurface: *mut VkSurfaceKHR,
) -> VkResult { ) -> VkResult {
let info = unsafe { &*pCreateInfo }; let info = unsafe { &*pCreateInfo };
#[cfg(all(feature = "vulkan", target_os = "linux"))] #[cfg(all(feature = "gfx-backend-vulkan", target_os = "linux"))]
{ {
unsafe { unsafe {
assert_eq!(info.flags, 0); assert_eq!(info.flags, 0);
@ -3246,7 +3246,7 @@ pub extern "C" fn gfxCreateXcbSurfaceKHR(
VkResult::VK_SUCCESS VkResult::VK_SUCCESS
} }
} }
#[cfg(not(all(feature = "vulkan", target_os = "linux")))] #[cfg(not(all(feature = "gfx-backend-vulkan", target_os = "linux")))]
unreachable!() unreachable!()
} }
#[inline] #[inline]

View file

@ -4,9 +4,11 @@
#![allow(improper_ctypes)] //TEMP: buggy Rustc FFI analysis #![allow(improper_ctypes)] //TEMP: buggy Rustc FFI analysis
extern crate gfx_hal as hal; extern crate gfx_hal as hal;
#[cfg(feature = "dx12")] #[cfg(feature = "gfx-backend-dx12")]
extern crate gfx_backend_dx12 as back; 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; extern crate gfx_backend_vulkan as back;
#[macro_use] #[macro_use]
@ -30,7 +32,7 @@ pub use impls::*;
// Vulkan objects // Vulkan objects
pub type VkInstance = Handle<back::Instance>; pub type VkInstance = Handle<back::Instance>;
pub type VkPhysicalDevice = Handle<hal::Adapter<B>>; pub type VkPhysicalDevice = DispatchHandle<hal::Adapter<B>>;
pub type VkDevice = DispatchHandle<Gpu<B>>; pub type VkDevice = DispatchHandle<Gpu<B>>;
pub type VkQueue = DispatchHandle<<B as hal::Backend>::CommandQueue>; pub type VkQueue = DispatchHandle<<B as hal::Backend>::CommandQueue>;
pub type VkCommandPool = Handle<<B as hal::Backend>::CommandPool>; pub type VkCommandPool = Handle<<B as hal::Backend>::CommandPool>;

View file

@ -1,7 +1,11 @@
[package] [package]
name = "portability-icd" name = "portability-icd"
publish = false
version = "0.1.0" version = "0.1.0"
authors = ["Dzmitry Malyshau <kvark@mozilla.com>"] authors = [
"Dzmitry Malyshau <kvark@mozilla.com>",
"Markus Siglreightmaier <m.siglreith@gmail.com>",
]
[lib] [lib]
name = "portability_icd" name = "portability_icd"
@ -9,8 +13,9 @@ crate-type = ["cdylib"]
[features] [features]
default = [] default = []
dx12 = ["portability-gfx/dx12"] dx12 = ["portability-gfx/gfx-backend-dx12"]
vulkan = ["portability-gfx/vulkan"] metal = ["portability-gfx/gfx-backend-metal"]
vulkan = ["portability-gfx/gfx-backend-vulkan"]
[dependencies] [dependencies]
portability-gfx = { path = "../libportability-gfx" } portability-gfx = { path = "../libportability-gfx", features = ["dispatch"] }

View file

@ -1,7 +1,11 @@
[package] [package]
name = "portability" name = "portability"
publish = false
version = "0.1.0" version = "0.1.0"
authors = ["Dzmitry Malyshau <kvark@mozilla.com>"] authors = [
"Dzmitry Malyshau <kvark@mozilla.com>",
"Markus Siglreightmaier <m.siglreith@gmail.com>",
]
[lib] [lib]
name = "portability" name = "portability"
@ -9,8 +13,9 @@ crate-type = ["cdylib"]
[features] [features]
default = [] default = []
dx12 = ["portability-gfx/dx12"] dx12 = ["portability-gfx/gfx-backend-dx12"]
vulkan = ["portability-gfx/vulkan"] metal = ["portability-gfx/gfx-backend-metal"]
vulkan = ["portability-gfx/gfx-backend-vulkan"]
[dependencies] [dependencies]
portability-gfx = { path = "../libportability-gfx" } portability-gfx = { path = "../libportability-gfx" }

View file

@ -20,7 +20,7 @@
*/ */
#if defined(_WIN32) #ifdef _WIN32
#define VK_USE_PLATFORM_WIN32_KHR #define VK_USE_PLATFORM_WIN32_KHR
#endif #endif
@ -79,9 +79,9 @@ int main() {
Config config = { 10, 10, width, height }; Config config = { 10, 10, width, height };
Window window = new_window(config); Window window = new_window(config);
VkSurfaceKHR surface; VkSurfaceKHR surface = 0;
#if defined(_WIN32) #ifdef _WIN32
VkWin32SurfaceCreateInfoKHR surface_info = {}; VkWin32SurfaceCreateInfoKHR surface_info = {};
surface_info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; surface_info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
surface_info.hinstance = window.instance; surface_info.hinstance = window.instance;

View file

@ -3,7 +3,7 @@
#include "window.hpp" #include "window.hpp"
#if defined(_WIN32) #ifdef _WIN32
const char *CLASS_NAME = "PortabilityClass"; const char *CLASS_NAME = "PortabilityClass";
auto WINAPI window_func(HWND hwnd, UINT u_msg, WPARAM w_param, LPARAM l_param) -> LRESULT { 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; return true;
} }
#elif __APPLE__
auto new_window(Config config) -> Window {
Window window = Window {};
return window;
}
auto poll_events() -> bool {
return true;
}
#else #else
auto new_window(Config config) -> Window { auto new_window(Config config) -> Window {
auto connection = xcb_connect(NULL, NULL); auto connection = xcb_connect(NULL, NULL);

View file

@ -2,16 +2,21 @@
#include <stdint.h> #include <stdint.h>
#if defined(_WIN32) #ifdef _WIN32
#include <windows.h> #include <windows.h>
#else #elif __APPLE__
//TODO
#elif __unix__
#include <xcb/xcb.h> #include <xcb/xcb.h>
#else
#error "unknown platform"
#endif #endif
struct Window { struct Window {
#if defined(_WIN32) #ifdef _WIN32
HINSTANCE instance; HINSTANCE instance;
HWND window; HWND window;
#elif __APPLE__
#else #else
xcb_connection_t *connection; xcb_connection_t *connection;
xcb_drawable_t window; xcb_drawable_t window;