13: dx12 support, finish depth image sample and more.. r=kvark a=msiglreith

(The PR is a bit messy, my apologies 😅 )

* Add dx12 backend support, including switching to dylibs over static lib due to linking issues with windows libraries
* Finish API sample 06 (depth image) by implementing vkBindImageMemory
* Start with sample 07 with adding a simple math lib (copied from an older C++ engine of mine..)
* Update `portable` branch to latest version

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/gfx-rs/portability/13)
<!-- Reviewable:end -->
This commit is contained in:
bors[bot] 2018-01-02 18:33:30 +00:00
commit 092c522b8e
10 changed files with 434 additions and 123 deletions

View file

@ -4,11 +4,21 @@ project (portability)
include_directories("modules/vulkan-docs/src") include_directories("modules/vulkan-docs/src")
add_executable(native_test native/test.cpp native/window.cpp) add_executable(native_test native/test.cpp native/window.cpp)
find_library(PORTABILITY_LIB portability "target/debug") # That's quite a mess, cleanup if possible..
target_link_libraries(native_test ${PORTABILITY_LIB})
if (WIN32) if (WIN32)
# TODO: can we use `find_library`? It seemed to search for `portability.lib` always..
target_link_libraries(native_test "../target/debug/portability.dll")
target_link_libraries(native_test Dwmapi Userenv ws2_32) target_link_libraries(native_test Dwmapi Userenv ws2_32)
# Copy dll over to build directory
add_custom_command(TARGET native_test POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${PROJECT_SOURCE_DIR}/target/debug/portability.dll"
$<TARGET_FILE_DIR:native_test>)
else (WIN32) else (WIN32)
find_library(PORTABILITY_LIB portability "target/debug")
target_link_libraries(native_test ${PORTABILITY_LIB})
target_link_libraries(native_test pthread dl m X11 xcb) target_link_libraries(native_test pthread dl m X11 xcb)
endif (WIN32) endif (WIN32)

View file

@ -3,7 +3,7 @@ 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.a LIBRARY=target/debug/libportability.so
CC=g++ CC=g++
CFLAGS=-std=c++11 -ggdb -O0 -I$(VULKAN_DIR) CFLAGS=-std=c++11 -ggdb -O0 -I$(VULKAN_DIR)
@ -20,7 +20,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 -p portability cargo build --manifest-path libportability/Cargo.toml --features vulkan
mkdir -p target/native mkdir -p target/native
$(NATIVE_DIR)/%.o: native/%.cpp $(DEPS) Makefile $(NATIVE_DIR)/%.o: native/%.cpp $(DEPS) Makefile

View file

@ -14,7 +14,7 @@ make
Build the Rust library (portability implementation): Build the Rust library (portability implementation):
``` ```
cargo build -p portability cargo build --manifest-path libportability/Cargo.toml --features <vulkan|dx12>
``` ```
Build the native example: Build the native example:

View file

@ -6,6 +6,11 @@ authors = ["Dzmitry Malyshau <kvark@mozilla.com>"]
[lib] [lib]
name = "portability_gfx" name = "portability_gfx"
[features]
default = []
dx12 = ["gfx-backend-dx12"]
vulkan = ["gfx-backend-vulkan"]
[dependencies] [dependencies]
lazy_static = "1.0" lazy_static = "1.0"
@ -17,3 +22,9 @@ branch = "portable"
git = "https://github.com/gfx-rs/gfx" git = "https://github.com/gfx-rs/gfx"
branch = "portable" branch = "portable"
features = ["portable"] features = ["portable"]
optional = true
[target.'cfg(windows)'.dependencies.gfx-backend-dx12]
git = "https://github.com/gfx-rs/gfx"
branch = "portable"
optional = true

View file

@ -1,42 +1,13 @@
use hal::{adapter, format, image, memory, window};
use std::mem;
use super::*; use super::*;
use hal::{self, format, image, memory, window};
pub fn format_from_hal(format: format::Format) -> VkFormat { pub fn format_from_hal(format: format::Format) -> VkFormat {
use VkFormat::*; // HAL formats have the same numeric representation as Vulkan formats
use hal::format::ChannelType::*; unsafe { mem::transmute(format) }
use hal::format::SurfaceType::*;
match format.0 {
R5_G6_B5 => match format.1 {
Unorm => VK_FORMAT_R5G6B5_UNORM_PACK16,
_ => unreachable!(),
},
R4_G4_B4_A4 => match format.1 {
Unorm => VK_FORMAT_R4G4B4A4_UNORM_PACK16,
_ => unreachable!(),
},
R8_G8_B8_A8 => match format.1 {
Unorm => VK_FORMAT_R8G8B8A8_UNORM,
Inorm => VK_FORMAT_R8G8B8A8_SNORM,
Srgb => VK_FORMAT_R8G8B8A8_SRGB,
_ => panic!("format {:?}", format),
},
B8_G8_R8_A8 => match format.1 {
Unorm => VK_FORMAT_B8G8R8A8_UNORM,
Inorm => VK_FORMAT_B8G8R8A8_SNORM,
Srgb => VK_FORMAT_B8G8R8A8_SRGB,
_ => panic!("format {:?}", format),
},
R16_G16_B16_A16 => match format.1 {
Unorm => VK_FORMAT_R16G16B16A16_UNORM,
Inorm => VK_FORMAT_R16G16B16A16_SNORM,
Float => VK_FORMAT_R16G16B16A16_SFLOAT,
_ => panic!("format {:?}", format),
},
_ => {
panic!("format {:?}", format);
}
}
} }
pub fn format_properties_from_hal(properties: format::Properties) -> VkFormatProperties { pub fn format_properties_from_hal(properties: format::Properties) -> VkFormatProperties {
@ -101,19 +72,12 @@ fn buffer_features_from_hal(features: format::BufferFeature) -> VkFormatFeatureF
} }
pub fn map_format(format: VkFormat) -> format::Format { pub fn map_format(format: VkFormat) -> format::Format {
use VkFormat::*; if (format as usize) < format::NUM_FORMATS {
use hal::format::ChannelType::*; // HAL formats have the same numeric representation as Vulkan formats
use hal::format::SurfaceType::*; unsafe { mem::transmute(format) }
} else {
let (sf, cf) = match format { unimplemented!("Unknown format {:?}", format);
VK_FORMAT_B8G8R8A8_UNORM => (B8_G8_R8_A8, Unorm), }
VK_FORMAT_D16_UNORM => (D16, Unorm),
_ => {
panic!("format {:?}", format);
}
};
format::Format(sf, cf)
} }
pub fn extent2d_from_hal(extent: window::Extent2d) -> VkExtent2D { pub fn extent2d_from_hal(extent: window::Extent2d) -> VkExtent2D {
@ -158,16 +122,16 @@ pub fn map_subresource_range(subresource: VkImageSubresourceRange) -> image::Sub
} }
} }
fn map_aspect(aspects: VkImageAspectFlags) -> image::AspectFlags { fn map_aspect(aspects: VkImageAspectFlags) -> format::AspectFlags {
let mut flags = image::AspectFlags::empty(); let mut flags = format::AspectFlags::empty();
if aspects & VkImageAspectFlagBits::VK_IMAGE_ASPECT_COLOR_BIT as u32 != 0 { if aspects & VkImageAspectFlagBits::VK_IMAGE_ASPECT_COLOR_BIT as u32 != 0 {
flags |= image::AspectFlags::COLOR; flags |= format::AspectFlags::COLOR;
} }
if aspects & VkImageAspectFlagBits::VK_IMAGE_ASPECT_DEPTH_BIT as u32 != 0 { if aspects & VkImageAspectFlagBits::VK_IMAGE_ASPECT_DEPTH_BIT as u32 != 0 {
flags |= image::AspectFlags::DEPTH; flags |= format::AspectFlags::DEPTH;
} }
if aspects & VkImageAspectFlagBits::VK_IMAGE_ASPECT_STENCIL_BIT as u32 != 0 { if aspects & VkImageAspectFlagBits::VK_IMAGE_ASPECT_STENCIL_BIT as u32 != 0 {
flags |= image::AspectFlags::DEPTH; flags |= format::AspectFlags::DEPTH;
} }
if aspects & VkImageAspectFlagBits::VK_IMAGE_ASPECT_METADATA_BIT as u32 != 0 { if aspects & VkImageAspectFlagBits::VK_IMAGE_ASPECT_METADATA_BIT as u32 != 0 {
unimplemented!() unimplemented!()
@ -278,3 +242,17 @@ pub fn memory_properties_from_hal(properties: memory::Properties) -> VkMemoryPro
flags flags
} }
pub fn map_err_device_creation(err: adapter::DeviceCreationError) -> VkResult {
use hal::adapter::DeviceCreationError::*;
match err {
OutOfHostMemory => VkResult::VK_ERROR_OUT_OF_HOST_MEMORY,
OutOfDeviceMemory => VkResult::VK_ERROR_OUT_OF_DEVICE_MEMORY,
InitializationFailed => VkResult::VK_ERROR_INITIALIZATION_FAILED,
MissingExtension => VkResult::VK_ERROR_EXTENSION_NOT_PRESENT,
MissingFeature => VkResult::VK_ERROR_FEATURE_NOT_PRESENT,
TooManyObjects => VkResult::VK_ERROR_TOO_MANY_OBJECTS,
DeviceLost => VkResult::VK_ERROR_DEVICE_LOST,
}
}

View file

@ -1,8 +1,11 @@
use super::*; use hal::{Device, Instance, PhysicalDevice, QueueFamily, Surface};
use std::mem; use std::mem;
use std::ops::Deref; use std::ops::Deref;
use super::*;
#[inline] #[inline]
pub extern fn gfxCreateInstance( pub extern fn gfxCreateInstance(
_pCreateInfo: *const VkInstanceCreateInfo, _pCreateInfo: *const VkInstanceCreateInfo,
@ -80,7 +83,12 @@ pub extern fn gfxGetPhysicalDeviceFormatProperties(
format: VkFormat, format: VkFormat,
pFormatProperties: *mut VkFormatProperties, pFormatProperties: *mut VkFormatProperties,
) { ) {
let properties = adapter.physical_device.format_properties(conv::map_format(format)); let format = match format {
VkFormat::VK_FORMAT_UNDEFINED => None,
format => Some(conv::map_format(format)),
};
let properties = adapter.physical_device.format_properties(format);
unsafe { *pFormatProperties = conv::format_properties_from_hal(properties); } unsafe { *pFormatProperties = conv::format_properties_from_hal(properties); }
} }
extern "C" { extern "C" {
@ -156,10 +164,15 @@ pub extern fn gfxCreateDevice(
(family, vec![1.0; info.queueCount as usize]) (family, vec![1.0; info.queueCount as usize])
}).collect::<Vec<_>>(); }).collect::<Vec<_>>();
let gpu = adapter.physical_device.clone().open(request_infos); let gpu = adapter.physical_device.open(request_infos);
unsafe { *pDevice = Handle::new(gpu) };
VkResult::VK_SUCCESS match gpu {
Ok(device) => {
unsafe { *pDevice = Handle::new(device); }
VkResult::VK_SUCCESS
}
Err(err) => conv::map_err_device_creation(err),
}
} }
#[inline] #[inline]
@ -317,12 +330,26 @@ extern "C" {
} }
#[inline] #[inline]
pub extern fn gfxBindImageMemory( pub extern fn gfxBindImageMemory(
device: VkDevice, gpu: VkDevice,
image: VkImage, mut image: VkImage,
memory: VkDeviceMemory, memory: VkDeviceMemory,
memoryOffset: VkDeviceSize, memoryOffset: VkDeviceSize,
) -> VkResult { ) -> VkResult {
unimplemented!() let new_img = match *image.unwrap() {
Image::Image(_) => panic!("An Image can only be bound once!"),
Image::Unbound(unbound) => {
gpu.device.bind_image_memory(
&memory,
memoryOffset,
unbound,
).unwrap() // TODO
}
};
// Replace the unbound image with an actual image under the hood.
*image = Image::Image(new_img);
VkResult::VK_SUCCESS
} }
extern "C" { extern "C" {
pub fn vkGetBufferMemoryRequirements(device: VkDevice, buffer: VkBuffer, pub fn vkGetBufferMemoryRequirements(device: VkDevice, buffer: VkBuffer,
@ -1118,17 +1145,31 @@ pub extern fn gfxGetPhysicalDeviceSurfaceFormatsKHR(
pSurfaceFormatCount: *mut u32, pSurfaceFormatCount: *mut u32,
pSurfaceFormats: *mut VkSurfaceFormatKHR, pSurfaceFormats: *mut VkSurfaceFormatKHR,
) -> VkResult { ) -> VkResult {
let (_, formats) = surface.capabilities_and_formats(&adapter.physical_device); let formats = surface
let output = unsafe { slice::from_raw_parts_mut(pSurfaceFormats, *pSurfaceFormatCount as usize) }; .capabilities_and_formats(&adapter.physical_device)
.1
.map(|formats|
formats
.into_iter()
.map(conv::format_from_hal)
.collect()
)
.unwrap_or(vec![VkFormat::VK_FORMAT_UNDEFINED]);
if output.len() > formats.len() { if pSurfaceFormats.is_null() {
// Return only the number of formats
unsafe { *pSurfaceFormatCount = formats.len() as u32 }; unsafe { *pSurfaceFormatCount = formats.len() as u32 };
} } else {
for (out, format) in output.iter_mut().zip(formats) { let output = unsafe { slice::from_raw_parts_mut(pSurfaceFormats, *pSurfaceFormatCount as usize) };
*out = VkSurfaceFormatKHR { if output.len() > formats.len() {
format: conv::format_from_hal(format), unsafe { *pSurfaceFormatCount = formats.len() as u32 };
colorSpace: VkColorSpaceKHR::VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, //TODO }
}; for (out, format) in output.iter_mut().zip(formats) {
*out = VkSurfaceFormatKHR {
format,
colorSpace: VkColorSpaceKHR::VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, //TODO
};
}
} }
VkResult::VK_SUCCESS VkResult::VK_SUCCESS
@ -1348,3 +1389,40 @@ extern "C" {
discardRectangleCount: u32, discardRectangleCount: u32,
pDiscardRectangles: *const VkRect2D); pDiscardRectangles: *const VkRect2D);
} }
pub fn gfxCreateWin32SurfaceKHR(
instance: VkInstance,
pCreateInfos: *const VkWin32SurfaceCreateInfoKHR,
pAllocator: *const VkAllocationCallbacks,
pSurface: *mut VkSurfaceKHR,
) -> VkResult {
#[cfg(all(feature = "vulkan", target_os = "windows"))]
{
unsafe {
assert_eq!((*pCreateInfos).flags, 0);
assert!(pAllocator.is_null());
*pSurface = Handle::new(
instance.create_surface_from_hwnd(
(*pCreateInfos).hinstance,
(*pCreateInfos).hwnd,
)
);
VkResult::VK_SUCCESS
}
}
#[cfg(feature = "dx12")]
{
unsafe {
assert_eq!((*pCreateInfos).flags, 0);
assert!(pAllocator.is_null());
*pSurface = Handle::new(
instance.create_surface_from_hwnd(
(*pCreateInfos).hwnd,
)
);
VkResult::VK_SUCCESS
}
}
#[cfg(not(target_os = "windows"))]
unreachable!()
}

View file

@ -4,7 +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")]
extern crate gfx_backend_dx12 as back;
#[cfg(feature = "vulkan")]
extern crate gfx_backend_vulkan as back; extern crate gfx_backend_vulkan as back;
#[macro_use] #[macro_use]
extern crate lazy_static; extern crate lazy_static;
@ -13,7 +17,6 @@ mod handle;
mod impls; mod impls;
use std::{cmp, slice}; use std::{cmp, slice};
use hal::{Device, Instance, PhysicalDevice, QueueFamily, Surface}; // traits only
use hal::pool::RawCommandPool; use hal::pool::RawCommandPool;
use back::Backend as B; use back::Backend as B;
use handle::Handle; use handle::Handle;
@ -4806,30 +4809,6 @@ pub struct VkWin32SurfaceCreateInfoKHR {
impl Clone for VkWin32SurfaceCreateInfoKHR { impl Clone for VkWin32SurfaceCreateInfoKHR {
fn clone(&self) -> Self { *self } fn clone(&self) -> Self { *self }
} }
pub fn gfxCreateWin32SurfaceKHR(
instance: VkInstance,
pCreateInfos: *const VkWin32SurfaceCreateInfoKHR,
pAllocator: *const VkAllocationCallbacks,
pSurface: *mut VkSurfaceKHR,
) -> VkResult {
#[cfg(target_os = "windows")]
{
unsafe {
assert_eq!((*pCreateInfos).flags, 0);
assert!(pAllocator.is_null());
// TODO: handle HINSTANCE
*pSurface = Handle::new(
instance.create_surface_from_hwnd(
(*pCreateInfos).hinstance,
(*pCreateInfos).hwnd,
)
);
VkResult::VK_SUCCESS
}
}
#[cfg(not(target_os = "windows"))]
unreachable!()
}
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy)] #[derive(Debug, Copy)]
pub struct VkPhysicalDeviceFeatures2KHR { pub struct VkPhysicalDeviceFeatures2KHR {

View file

@ -5,7 +5,12 @@ authors = ["Dzmitry Malyshau <kvark@mozilla.com>"]
[lib] [lib]
name = "portability" name = "portability"
crate-type = ["staticlib"] crate-type = ["cdylib"]
[features]
default = []
dx12 = ["portability-gfx/dx12"]
vulkan = ["portability-gfx/vulkan"]
[dependencies] [dependencies]
portability-gfx = { path = "../libportability-gfx" } portability-gfx = { path = "../libportability-gfx" }

219
native/math.hpp Normal file
View file

@ -0,0 +1,219 @@
#pragma once
#include <cmath>
const float pi = 3.1415926535897932;
template<typename T>
class mat4_tl
{
public:
typedef T value_type;
typedef mat4_tl<T> type;
public:
union {
struct { value_type m00, m01, m02, m03;
value_type m10, m11, m12, m13;
value_type m20, m21, m22, m23;
value_type m30, m31, m32, m33; };
value_type data[4*4];
};
public:
mat4_tl()
: mat4_tl(
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0)
{ }
///
mat4_tl(
T const& v00, T const& v01, T const& v02, T const& v03,
T const& v10, T const& v11, T const& v12, T const& v13,
T const& v20, T const& v21, T const& v22, T const& v23,
T const& v30, T const& v31, T const& v32, T const& v33)
: m00(v00), m01(v01), m02(v02), m03(v03),
m10(v10), m11(v11), m12(v12), m13(v13),
m20(v20), m21(v21), m22(v22), m23(v23),
m30(v30), m31(v31), m32(v32), m33(v33)
{ }
///
static
auto identity() -> mat4_tl {
return mat4_tl<T>(
1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1);
}
};
template<typename T>
auto operator *(mat4_tl<T> const& m1, mat4_tl<T> const& m2) -> mat4_tl<T> {
return mul(m1, m2);
}
template<typename T>
auto mul(mat4_tl<T> const& m1, mat4_tl<T> const& m2) -> mat4_tl<T> {
mat4_tl<T> m;
m.m00 = m1.m00*m2.m00 + m1.m01*m2.m10 + m1.m02*m2.m20 + m1.m03*m2.m30;
m.m01 = m1.m00*m2.m01 + m1.m01*m2.m11 + m1.m02*m2.m21 + m1.m03*m2.m31;
m.m02 = m1.m00*m2.m02 + m1.m01*m2.m12 + m1.m02*m2.m22 + m1.m03*m2.m32;
m.m03 = m1.m00*m2.m03 + m1.m01*m2.m13 + m1.m02*m2.m23 + m1.m03*m2.m33;
m.m10 = m1.m10*m2.m00 + m1.m11*m2.m10 + m1.m12*m2.m20 + m1.m13*m2.m30;
m.m11 = m1.m10*m2.m01 + m1.m11*m2.m11 + m1.m12*m2.m21 + m1.m13*m2.m31;
m.m12 = m1.m10*m2.m02 + m1.m11*m2.m12 + m1.m12*m2.m22 + m1.m13*m2.m32;
m.m13 = m1.m10*m2.m03 + m1.m11*m2.m13 + m1.m12*m2.m23 + m1.m13*m2.m33;
m.m20 = m1.m20*m2.m00 + m1.m21*m2.m10 + m1.m22*m2.m20 + m1.m23*m2.m30;
m.m21 = m1.m20*m2.m01 + m1.m21*m2.m11 + m1.m22*m2.m21 + m1.m23*m2.m31;
m.m22 = m1.m20*m2.m02 + m1.m21*m2.m12 + m1.m22*m2.m22 + m1.m23*m2.m32;
m.m23 = m1.m20*m2.m03 + m1.m21*m2.m13 + m1.m22*m2.m23 + m1.m23*m2.m33;
m.m30 = m1.m30*m2.m00 + m1.m31*m2.m10 + m1.m32*m2.m20 + m1.m33*m2.m30;
m.m31 = m1.m30*m2.m01 + m1.m31*m2.m11 + m1.m32*m2.m21 + m1.m33*m2.m31;
m.m32 = m1.m30*m2.m02 + m1.m31*m2.m12 + m1.m32*m2.m22 + m1.m33*m2.m32;
m.m33 = m1.m30*m2.m03 + m1.m31*m2.m13 + m1.m32*m2.m23 + m1.m33*m2.m33;
return m;
}
template<typename T>
auto perspective(T fov, T aspect, T n, T f) -> mat4_tl<T> {
assert(fov > 0); assert(aspect > 0);
const T rad = fov*T(pi)/T(180);
const T a = T(1)/(std::tan(rad/T(2)));
return mat4_tl<T>(
a/aspect, 0, 0, 0,
0, a, 0, 0,
0, 0, (n+f)/(n-f), 2*n*f/(n-f),
0, 0, -1, 0);
}
template<typename T>
class vec3_tl
{
public:
union {
struct { T x, y, z; };
struct { T s, t, u; };
struct { T r, g, b; };
T data[3];
};
public:
/// Constructors
vec3_tl()
: x(0), y(0), z(0) {}
vec3_tl(T const& v)
: x(v), y(v), z(v) {}
vec3_tl(T const& v1, T const& v2, T const& v3)
: x(v1), y(v2), z(v3) {}
vec3_tl(vec3_tl const& v)
: x(v.x), y(v.y), z(v.z) {}
/// Operators
auto operator [](size_t pos) -> T & {
assert(0<=pos && pos<3); return data[pos];
}
auto operator [](size_t pos) const -> T const& {
assert(0<=pos && pos<3); return data[pos];
}
auto operator ==(vec3_tl const& v) const -> bool {
return x==v.x && y==v.y && z==v.z;
}
auto operator +=(vec3_tl const& v) -> vec3_tl & {
x+=v.x; y+=v.y; z+=v.z; return *this;
}
auto operator -=(vec3_tl const& v) -> vec3_tl & {
x-=v.x; y-=v.y; z-=v.z; return *this;
}
auto operator *=(T const& v) -> vec3_tl & {
x*=v; y*=v; z*=v; return *this;
}
auto operator /=(T const& v) -> vec3_tl & {
x/=v; y/=v; z/=v; return *this;
}
auto operator -() const -> vec3_tl {
return vec3_tl(-x, -y, -z);
}
friend
auto operator +(vec3_tl const& v1, vec3_tl const& v2) -> vec3_tl {
return vec3_tl(v1.x+v2.x, v1.y+v2.y, v1.z+v2.z);
}
friend
auto operator -(vec3_tl const& v1, vec3_tl const& v2) -> vec3_tl {
return vec3_tl(v1.x-v2.x, v1.y-v2.y, v1.z-v2.z);
}
friend
auto operator *(vec3_tl const& v, T const& s) -> vec3_tl {
return vec3_tl(v.x*s, v.y*s, v.z*s);
}
friend
auto operator /(vec3_tl const& v, T const& s) -> vec3_tl {
return vec3_tl(v.x/s, v.y/s, v.z/s);
}
};
template<typename T>
auto dot(vec3_tl<T> const& v1, vec3_tl<T> const& v2) -> T {
return (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
}
template<typename T>
auto length(vec3_tl<T> const& v) -> T {
return std::sqrt(dot(v, v));
}
template<typename T>
auto normalize(vec3_tl<T> const& v) -> vec3_tl<T> {
return v/length(v);
}
template<typename T>
auto cross(vec3_tl<T> const& v1, vec3_tl<T> const& v2) -> vec3_tl<T> {
return vec3_tl<T>(
v1.y*v2.z - v1.z*v2.y,
v1.z*v2.x - v1.x*v2.z,
v1.x*v2.y - v1.y*v2.x
);
}
template<typename T>
auto look_at(vec3_tl<T> const& eye, vec3_tl<T> const& target, vec3_tl<T> const& up) -> mat4_tl<T> {
vec3_tl<T> axis_z = normalize(target-eye);
vec3_tl<T> axis_x = normalize(cross(axis_z, up));
vec3_tl<T> axis_y = cross(axis_x, axis_z);
return mat4_tl<T>(
axis_x.x, axis_x.y, axis_x.z, -dot(axis_x, eye),
axis_y.x, axis_y.y, axis_y.z, -dot(axis_y, eye),
-axis_z.x, -axis_z.y, -axis_z.z, dot(axis_z, eye),
0, 0, 0, 1
);
}
typedef vec3_tl<float> vec3;
typedef mat4_tl<float> mat4;

View file

@ -28,6 +28,8 @@
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <vector> #include <vector>
#include "math.hpp"
#include "window.hpp" #include "window.hpp"
bool memory_type_from_properties( bool memory_type_from_properties(
@ -191,12 +193,12 @@ int main() {
uint32_t image_count = 0; uint32_t image_count = 0;
res = vkGetSwapchainImagesKHR(device, swapchain, &image_count, NULL); res = vkGetSwapchainImagesKHR(device, swapchain, &image_count, NULL);
printf("\tvkCreateSwapchainKHR (query): res=%d image_count=%d\n", res, image_count); printf("\tvkGetSwapchainImagesKHR (query): res=%d image_count=%d\n", res, image_count);
assert(!res); assert(!res);
std::vector<VkImage> swapchain_images(image_count); std::vector<VkImage> swapchain_images(image_count);
res = vkGetSwapchainImagesKHR(device, swapchain, &image_count, &swapchain_images[0]); res = vkGetSwapchainImagesKHR(device, swapchain, &image_count, &swapchain_images[0]);
printf("\tvkCreateSwapchainKHR: res=%d\n", res); printf("\tvkGetSwapchainImagesKHR: res=%d\n", res);
assert(!res); assert(!res);
std::vector<VkImageView> swapchain_views(image_count); std::vector<VkImageView> swapchain_views(image_count);
@ -268,26 +270,8 @@ int main() {
mem_alloc.allocationSize = 0; mem_alloc.allocationSize = 0;
mem_alloc.memoryTypeIndex = 0; mem_alloc.memoryTypeIndex = 0;
VkImageViewCreateInfo view_info = {};
view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
view_info.pNext = NULL;
view_info.image = VK_NULL_HANDLE;
view_info.format = depth_format;
view_info.components.r = VK_COMPONENT_SWIZZLE_R;
view_info.components.g = VK_COMPONENT_SWIZZLE_G;
view_info.components.b = VK_COMPONENT_SWIZZLE_B;
view_info.components.a = VK_COMPONENT_SWIZZLE_A;
view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
view_info.subresourceRange.baseMipLevel = 0;
view_info.subresourceRange.levelCount = 1;
view_info.subresourceRange.baseArrayLayer = 0;
view_info.subresourceRange.layerCount = 1;
view_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
view_info.flags = 0;
VkMemoryRequirements mem_reqs; VkMemoryRequirements mem_reqs;
/* Create image */
VkImage depth_image = 0; VkImage depth_image = 0;
res = vkCreateImage(device, &image_info, NULL, &depth_image); res = vkCreateImage(device, &image_info, NULL, &depth_image);
printf("\tvkCreateImage: res=%d\n", res); printf("\tvkCreateImage: res=%d\n", res);
@ -316,6 +300,48 @@ int main() {
printf("\tvkAllocateMemory: res=%d\n", res); printf("\tvkAllocateMemory: res=%d\n", res);
assert(!res); assert(!res);
res = vkBindImageMemory(device, depth_image, depth_memory, 0);
printf("\tvkBindImageMemory: res=%d\n", res);
assert(!res);
VkImageViewCreateInfo view_info = {};
view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
view_info.pNext = NULL;
view_info.image = depth_image;
view_info.format = depth_format;
view_info.components.r = VK_COMPONENT_SWIZZLE_R;
view_info.components.g = VK_COMPONENT_SWIZZLE_G;
view_info.components.b = VK_COMPONENT_SWIZZLE_B;
view_info.components.a = VK_COMPONENT_SWIZZLE_A;
view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
view_info.subresourceRange.baseMipLevel = 0;
view_info.subresourceRange.levelCount = 1;
view_info.subresourceRange.baseArrayLayer = 0;
view_info.subresourceRange.layerCount = 1;
view_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
view_info.flags = 0;
VkImageView depth_view = 0;
res = vkCreateImageView(device, &view_info, NULL, &depth_view);
printf("\tvkCreateImageView: res=%d\n", res);
assert(!res);
auto projection = perspective(45.0f, 1.0f, 0.1f, 100.0f);
auto view = look_at(
vec3(-5.0f, 3.0f, -10.0f),
vec3(0, 0, 0),
vec3(0, -1, 0)
);
auto model = mat4::identity();
auto clip = mat4(
1.0f, 0.0f, 0.0f, 0.0f,
0.0f,-1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
0.0f, 0.0f, 0.5f, 1.0f);
auto mvp = clip * projection * view * model;
VkCommandPool cmd_pool = 0; VkCommandPool cmd_pool = 0;
VkCommandPoolCreateInfo cmd_pool_info = {}; VkCommandPoolCreateInfo cmd_pool_info = {};
cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
@ -344,8 +370,13 @@ int main() {
} }
// TODO: destroy depth image
vkFreeMemory(device, depth_memory, NULL); vkFreeMemory(device, depth_memory, NULL);
printf("\tvkFreeMemory\n"); printf("\tvkFreeMemory\n");
vkDestroyImageView(device, depth_view, NULL);
printf("\tvkDestroyImageView\n");
for(auto view : swapchain_views) { for(auto view : swapchain_views) {
vkDestroyImageView(device, view, NULL); vkDestroyImageView(device, view, NULL);
printf("\tvkDestroyImageView\n"); printf("\tvkDestroyImageView\n");