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
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

View file

@ -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

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.
## 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 <vulkan|dx12>
cargo build --manifest-path libportability/Cargo.toml --features <vulkan|dx12|metal>
```
Build the native example:

View file

@ -1,16 +1,19 @@
[package]
name = "portability-gfx"
publish = false
version = "0.1.0"
authors = ["Dzmitry Malyshau <kvark@mozilla.com>"]
authors = [
"Dzmitry Malyshau <kvark@mozilla.com>",
"Markus Siglreight <m.siglreith@gmail.com>",
]
[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

View file

@ -1,8 +1,6 @@
use VK_NULL_HANDLE;
use std::{borrow, fmt, ops};
static ICD_LOADER_MAGIC: u32 = 0x01CDC0DE;
#[repr(C)]
pub struct Handle<T>(*mut T);
@ -54,52 +52,62 @@ impl<T> fmt::Debug for Handle<T> {
}
}
#[repr(C)]
pub struct DispatchHandle<T>(u32, Handle<T>);
#[cfg(feature = "dispatch")]
pub use self::dispatch::DispatchHandle;
#[cfg(not(feature = "dispatch"))]
pub type DispatchHandle<T> = Handle<T>;
impl<T> DispatchHandle<T> {
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<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> {
self.1.unwrap()
impl<T> Clone for DispatchHandle<T> {
fn clone(&self) -> Self {
DispatchHandle(self.0, self.1)
}
}
pub fn is_null(&self) -> bool {
self.1.is_null()
}
}
impl<T> Clone for DispatchHandle<T> {
fn clone(&self) -> Self {
DispatchHandle(self.0, self.1)
}
}
impl<T> Copy for DispatchHandle<T> {}
impl<T> ops::Deref for DispatchHandle<T> {
type Target = T;
fn deref(&self) -> &T {
self.1.deref()
}
}
impl<T> ops::DerefMut for DispatchHandle<T> {
fn deref_mut(&mut self) -> &mut T {
self.1.deref_mut()
}
}
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)
impl<T> Copy for DispatchHandle<T> {}
impl<T> ops::Deref for DispatchHandle<T> {
type Target = T;
fn deref(&self) -> &T {
self.1.deref()
}
}
impl<T> ops::DerefMut for DispatchHandle<T> {
fn deref_mut(&mut self) -> &mut T {
self.1.deref_mut()
}
}
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();
}
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]

View file

@ -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<back::Instance>;
pub type VkPhysicalDevice = Handle<hal::Adapter<B>>;
pub type VkPhysicalDevice = DispatchHandle<hal::Adapter<B>>;
pub type VkDevice = DispatchHandle<Gpu<B>>;
pub type VkQueue = DispatchHandle<<B as hal::Backend>::CommandQueue>;
pub type VkCommandPool = Handle<<B as hal::Backend>::CommandPool>;

View file

@ -1,7 +1,11 @@
[package]
name = "portability-icd"
publish = false
version = "0.1.0"
authors = ["Dzmitry Malyshau <kvark@mozilla.com>"]
authors = [
"Dzmitry Malyshau <kvark@mozilla.com>",
"Markus Siglreightmaier <m.siglreith@gmail.com>",
]
[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"] }

View file

@ -1,7 +1,11 @@
[package]
name = "portability"
publish = false
version = "0.1.0"
authors = ["Dzmitry Malyshau <kvark@mozilla.com>"]
authors = [
"Dzmitry Malyshau <kvark@mozilla.com>",
"Markus Siglreightmaier <m.siglreith@gmail.com>",
]
[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" }

View file

@ -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;

View file

@ -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);

View file

@ -2,16 +2,21 @@
#include <stdint.h>
#if defined(_WIN32)
#ifdef _WIN32
#include <windows.h>
#else
#elif __APPLE__
//TODO
#elif __unix__
#include <xcb/xcb.h>
#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;