diff --git a/CMakeLists.txt b/CMakeLists.txt index 3046ee6..a6435e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,11 +4,21 @@ project (portability) include_directories("modules/vulkan-docs/src") add_executable(native_test native/test.cpp native/window.cpp) -find_library(PORTABILITY_LIB portability "target/debug") -target_link_libraries(native_test ${PORTABILITY_LIB}) - +# That's quite a mess, cleanup if possible.. 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) + + # 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" + $) + 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) + endif (WIN32) diff --git a/Makefile b/Makefile index a01962f..11ab14b 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ 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.a +LIBRARY=target/debug/libportability.so CC=g++ 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) $(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 $(NATIVE_DIR)/%.o: native/%.cpp $(DEPS) Makefile diff --git a/README.md b/README.md index 153f37b..fbdad59 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ make Build the Rust library (portability implementation): ``` -cargo build -p portability +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 b33a7b1..a98e8bf 100644 --- a/libportability-gfx/Cargo.toml +++ b/libportability-gfx/Cargo.toml @@ -6,6 +6,11 @@ authors = ["Dzmitry Malyshau "] [lib] name = "portability_gfx" +[features] +default = [] +dx12 = ["gfx-backend-dx12"] +vulkan = ["gfx-backend-vulkan"] + [dependencies] lazy_static = "1.0" @@ -17,3 +22,9 @@ branch = "portable" git = "https://github.com/gfx-rs/gfx" branch = "portable" features = ["portable"] +optional = true + +[target.'cfg(windows)'.dependencies.gfx-backend-dx12] +git = "https://github.com/gfx-rs/gfx" +branch = "portable" +optional = true diff --git a/libportability-gfx/src/conv.rs b/libportability-gfx/src/conv.rs index 24d5416..cbe4e5a 100644 --- a/libportability-gfx/src/conv.rs +++ b/libportability-gfx/src/conv.rs @@ -1,42 +1,13 @@ + +use hal::{adapter, format, image, memory, window}; + +use std::mem; + use super::*; -use hal::{self, format, image, memory, window}; pub fn format_from_hal(format: format::Format) -> VkFormat { - use VkFormat::*; - use hal::format::ChannelType::*; - 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); - } - } + // HAL formats have the same numeric representation as Vulkan formats + unsafe { mem::transmute(format) } } 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 { - use VkFormat::*; - use hal::format::ChannelType::*; - use hal::format::SurfaceType::*; - - let (sf, cf) = match format { - VK_FORMAT_B8G8R8A8_UNORM => (B8_G8_R8_A8, Unorm), - VK_FORMAT_D16_UNORM => (D16, Unorm), - _ => { - panic!("format {:?}", format); - } - }; - - format::Format(sf, cf) + if (format as usize) < format::NUM_FORMATS { + // HAL formats have the same numeric representation as Vulkan formats + unsafe { mem::transmute(format) } + } else { + unimplemented!("Unknown format {:?}", format); + } } 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 { - let mut flags = image::AspectFlags::empty(); +fn map_aspect(aspects: VkImageAspectFlags) -> format::AspectFlags { + let mut flags = format::AspectFlags::empty(); 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 { - flags |= image::AspectFlags::DEPTH; + flags |= format::AspectFlags::DEPTH; } 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 { unimplemented!() @@ -278,3 +242,17 @@ pub fn memory_properties_from_hal(properties: memory::Properties) -> VkMemoryPro 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, + } +} diff --git a/libportability-gfx/src/impls.rs b/libportability-gfx/src/impls.rs index 14bd5d4..07dbe3e 100644 --- a/libportability-gfx/src/impls.rs +++ b/libportability-gfx/src/impls.rs @@ -1,8 +1,11 @@ -use super::*; +use hal::{Device, Instance, PhysicalDevice, QueueFamily, Surface}; + use std::mem; use std::ops::Deref; +use super::*; + #[inline] pub extern fn gfxCreateInstance( _pCreateInfo: *const VkInstanceCreateInfo, @@ -80,7 +83,12 @@ pub extern fn gfxGetPhysicalDeviceFormatProperties( format: VkFormat, 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); } } extern "C" { @@ -156,10 +164,15 @@ pub extern fn gfxCreateDevice( (family, vec![1.0; info.queueCount as usize]) }).collect::>(); - let gpu = adapter.physical_device.clone().open(request_infos); - unsafe { *pDevice = Handle::new(gpu) }; + let gpu = adapter.physical_device.open(request_infos); - VkResult::VK_SUCCESS + match gpu { + Ok(device) => { + unsafe { *pDevice = Handle::new(device); } + VkResult::VK_SUCCESS + } + Err(err) => conv::map_err_device_creation(err), + } } #[inline] @@ -317,12 +330,26 @@ extern "C" { } #[inline] pub extern fn gfxBindImageMemory( - device: VkDevice, - image: VkImage, + gpu: VkDevice, + mut image: VkImage, memory: VkDeviceMemory, memoryOffset: VkDeviceSize, ) -> 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" { pub fn vkGetBufferMemoryRequirements(device: VkDevice, buffer: VkBuffer, @@ -1118,17 +1145,31 @@ pub extern fn gfxGetPhysicalDeviceSurfaceFormatsKHR( pSurfaceFormatCount: *mut u32, pSurfaceFormats: *mut VkSurfaceFormatKHR, ) -> VkResult { - let (_, formats) = surface.capabilities_and_formats(&adapter.physical_device); - let output = unsafe { slice::from_raw_parts_mut(pSurfaceFormats, *pSurfaceFormatCount as usize) }; + let formats = surface + .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 }; - } - for (out, format) in output.iter_mut().zip(formats) { - *out = VkSurfaceFormatKHR { - format: conv::format_from_hal(format), - colorSpace: VkColorSpaceKHR::VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, //TODO - }; + } else { + let output = unsafe { slice::from_raw_parts_mut(pSurfaceFormats, *pSurfaceFormatCount as usize) }; + if output.len() > formats.len() { + unsafe { *pSurfaceFormatCount = formats.len() as u32 }; + } + for (out, format) in output.iter_mut().zip(formats) { + *out = VkSurfaceFormatKHR { + format, + colorSpace: VkColorSpaceKHR::VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, //TODO + }; + } } VkResult::VK_SUCCESS @@ -1348,3 +1389,40 @@ extern "C" { discardRectangleCount: u32, 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!() +} diff --git a/libportability-gfx/src/lib.rs b/libportability-gfx/src/lib.rs index 57bd3ea..0bb0f9b 100644 --- a/libportability-gfx/src/lib.rs +++ b/libportability-gfx/src/lib.rs @@ -4,7 +4,11 @@ #![allow(improper_ctypes)] //TEMP: buggy Rustc FFI analysis 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; + #[macro_use] extern crate lazy_static; @@ -13,7 +17,6 @@ mod handle; mod impls; use std::{cmp, slice}; -use hal::{Device, Instance, PhysicalDevice, QueueFamily, Surface}; // traits only use hal::pool::RawCommandPool; use back::Backend as B; use handle::Handle; @@ -4806,30 +4809,6 @@ pub struct VkWin32SurfaceCreateInfoKHR { impl Clone for VkWin32SurfaceCreateInfoKHR { 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)] #[derive(Debug, Copy)] pub struct VkPhysicalDeviceFeatures2KHR { diff --git a/libportability/Cargo.toml b/libportability/Cargo.toml index 622ae02..27f998e 100644 --- a/libportability/Cargo.toml +++ b/libportability/Cargo.toml @@ -5,7 +5,12 @@ authors = ["Dzmitry Malyshau "] [lib] name = "portability" -crate-type = ["staticlib"] +crate-type = ["cdylib"] + +[features] +default = [] +dx12 = ["portability-gfx/dx12"] +vulkan = ["portability-gfx/vulkan"] [dependencies] portability-gfx = { path = "../libportability-gfx" } diff --git a/native/math.hpp b/native/math.hpp new file mode 100644 index 0000000..88ed5ea --- /dev/null +++ b/native/math.hpp @@ -0,0 +1,219 @@ + +#pragma once + +#include + +const float pi = 3.1415926535897932; + +template +class mat4_tl +{ +public: + typedef T value_type; + typedef mat4_tl 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( + 1,0,0,0, + 0,1,0,0, + 0,0,1,0, + 0,0,0,1); + } +}; + +template +auto operator *(mat4_tl const& m1, mat4_tl const& m2) -> mat4_tl { + return mul(m1, m2); +} + +template +auto mul(mat4_tl const& m1, mat4_tl const& m2) -> mat4_tl { + mat4_tl 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 +auto perspective(T fov, T aspect, T n, T f) -> mat4_tl { + 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( + 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 +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 +auto dot(vec3_tl const& v1, vec3_tl const& v2) -> T { + return (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z); +} + +template +auto length(vec3_tl const& v) -> T { + return std::sqrt(dot(v, v)); +} + +template +auto normalize(vec3_tl const& v) -> vec3_tl { + return v/length(v); +} + +template +auto cross(vec3_tl const& v1, vec3_tl const& v2) -> vec3_tl { + return vec3_tl( + 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 +auto look_at(vec3_tl const& eye, vec3_tl const& target, vec3_tl const& up) -> mat4_tl { + vec3_tl axis_z = normalize(target-eye); + vec3_tl axis_x = normalize(cross(axis_z, up)); + vec3_tl axis_y = cross(axis_x, axis_z); + + return mat4_tl( + 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 vec3; +typedef mat4_tl mat4; diff --git a/native/test.cpp b/native/test.cpp index 36230bf..6430ddc 100644 --- a/native/test.cpp +++ b/native/test.cpp @@ -28,6 +28,8 @@ #include #include #include + +#include "math.hpp" #include "window.hpp" bool memory_type_from_properties( @@ -191,12 +193,12 @@ int main() { uint32_t image_count = 0; 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); std::vector swapchain_images(image_count); res = vkGetSwapchainImagesKHR(device, swapchain, &image_count, &swapchain_images[0]); - printf("\tvkCreateSwapchainKHR: res=%d\n", res); + printf("\tvkGetSwapchainImagesKHR: res=%d\n", res); assert(!res); std::vector swapchain_views(image_count); @@ -268,26 +270,8 @@ int main() { mem_alloc.allocationSize = 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; - /* Create image */ VkImage depth_image = 0; res = vkCreateImage(device, &image_info, NULL, &depth_image); printf("\tvkCreateImage: res=%d\n", res); @@ -316,6 +300,48 @@ int main() { printf("\tvkAllocateMemory: res=%d\n", 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; VkCommandPoolCreateInfo cmd_pool_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); printf("\tvkFreeMemory\n"); + vkDestroyImageView(device, depth_view, NULL); + printf("\tvkDestroyImageView\n"); + for(auto view : swapchain_views) { vkDestroyImageView(device, view, NULL); printf("\tvkDestroyImageView\n");