mirror of
https://github.com/italicsjenga/portability.git
synced 2024-11-22 15:01:31 +11:00
Merge #13
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:
commit
092c522b8e
|
@ -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"
|
||||
$<TARGET_FILE_DIR:native_test>)
|
||||
|
||||
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)
|
||||
|
|
4
Makefile
4
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
|
||||
|
|
|
@ -14,7 +14,7 @@ make
|
|||
Build the Rust library (portability implementation):
|
||||
|
||||
```
|
||||
cargo build -p portability
|
||||
cargo build --manifest-path libportability/Cargo.toml --features <vulkan|dx12>
|
||||
```
|
||||
|
||||
Build the native example:
|
||||
|
|
|
@ -6,6 +6,11 @@ authors = ["Dzmitry Malyshau <kvark@mozilla.com>"]
|
|||
[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
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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::<Vec<_>>();
|
||||
|
||||
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!()
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -5,7 +5,12 @@ authors = ["Dzmitry Malyshau <kvark@mozilla.com>"]
|
|||
|
||||
[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" }
|
||||
|
|
219
native/math.hpp
Normal file
219
native/math.hpp
Normal 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;
|
|
@ -28,6 +28,8 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
|
||||
#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<VkImage> 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<VkImageView> 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");
|
||||
|
|
Loading…
Reference in a new issue