forked from itycodes/MineClone
parent
45ebc4a807
commit
380476549c
@ -0,0 +1 @@
|
||||
/target
|
@ -0,0 +1,335 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "ash"
|
||||
version = "0.38.0+1.3.281"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f"
|
||||
dependencies = [
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ash-window"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52bca67b61cb81e5553babde81b8211f713cb6db79766f80168f3e5f40ea6c82"
|
||||
dependencies = [
|
||||
"ash",
|
||||
"raw-window-handle",
|
||||
"raw-window-metal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "block"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cocoa"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"block",
|
||||
"cocoa-foundation",
|
||||
"core-foundation",
|
||||
"core-graphics",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"objc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cocoa-foundation"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"block",
|
||||
"core-foundation",
|
||||
"core-graphics-types",
|
||||
"libc",
|
||||
"objc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||
|
||||
[[package]]
|
||||
name = "core-graphics"
|
||||
version = "0.23.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"core-foundation",
|
||||
"core-graphics-types",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-graphics-types"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"core-foundation",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965"
|
||||
dependencies = [
|
||||
"foreign-types-macros",
|
||||
"foreign-types-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-macros"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.171"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "malloc_buf"
|
||||
version = "0.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mineclone"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ash",
|
||||
"ash-window",
|
||||
"raw-window-handle",
|
||||
"sdl2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
|
||||
dependencies = [
|
||||
"malloc_buf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "raw-window-handle"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539"
|
||||
|
||||
[[package]]
|
||||
name = "raw-window-metal"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76e8caa82e31bb98fee12fa8f051c94a6aa36b07cddb03f0d4fc558988360ff1"
|
||||
dependencies = [
|
||||
"cocoa",
|
||||
"core-graphics",
|
||||
"objc",
|
||||
"raw-window-handle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sdl2"
|
||||
version = "0.37.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b498da7d14d1ad6c839729bd4ad6fc11d90a57583605f3b4df2cd709a9cd380"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"raw-window-handle",
|
||||
"sdl2-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sdl2-sys"
|
||||
version = "0.37.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "951deab27af08ed9c6068b7b0d05a93c91f0a8eb16b6b816a5e73452a43521d3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"version-compare",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||
|
||||
[[package]]
|
||||
name = "version-compare"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29"
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
@ -0,0 +1,18 @@
|
||||
BIN = target/debug/mineclone
|
||||
|
||||
SHADERS = shaders/vert.spv shaders/frag.spv
|
||||
SOURCES = $(shell find src -name '*.rs')
|
||||
|
||||
all: $(SHADERS) $(BIN)
|
||||
|
||||
run: all
|
||||
cargo run
|
||||
|
||||
$(BIN): $(SOURCES)
|
||||
cargo build
|
||||
|
||||
%.spv: %.vert
|
||||
glslc $< -o $@
|
||||
|
||||
%.spv: %.frag
|
||||
glslc $< -o $@
|
@ -0,0 +1,19 @@
|
||||
#version 450
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
layout(location = 0) in vec4 normal;
|
||||
layout(location = 1) in vec4 pos_pre;
|
||||
|
||||
layout(push_constant, std430) uniform pc {
|
||||
layout(offset=32) vec4 data;
|
||||
};
|
||||
|
||||
void main() {
|
||||
outColor = vec4(data.rgb*(1.0+dot(normal.xyz, normalize(vec3(-0.7, -0.5, -0.1))))/2.0, 1.0);
|
||||
//if(pos_post.z <= 0.0) {
|
||||
// outColor = vec4(1.0);
|
||||
//}
|
||||
//outColor = normal.xyz;
|
||||
//outColor = vec4(vec3(1.0-gl_FragCoord.z), 1.0);
|
||||
}
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,109 @@
|
||||
#version 450
|
||||
// vim: ft=c
|
||||
|
||||
layout(std430, set = 0, binding = 0) buffer positions_buffer {
|
||||
mat2x4 posnrm[];
|
||||
} pos;
|
||||
|
||||
layout(push_constant, std430) uniform pc {
|
||||
layout(offset=0) vec4 cam_orig;
|
||||
layout(offset=16) vec4 cam_rot;
|
||||
};
|
||||
|
||||
layout (location = 0) out vec4 normal;
|
||||
layout (location = 1) out vec4 pos_pre;
|
||||
|
||||
const float PI = 3.14159;
|
||||
// Forgive me for I have sinned
|
||||
const float TAU = PI*2.0;
|
||||
|
||||
void main() {
|
||||
// assign outs
|
||||
normal = pos.posnrm[gl_VertexIndex][1];
|
||||
pos_pre = pos.posnrm[gl_VertexIndex][0];
|
||||
|
||||
// define constants
|
||||
const float zFar = 100.0;
|
||||
const float zNear = 0.1;
|
||||
|
||||
// assign the transformee
|
||||
gl_Position = pos.posnrm[gl_VertexIndex][0];
|
||||
|
||||
mat4 view_orig = mat4(
|
||||
1.0, 0.0, 0.0, cam_orig.x,
|
||||
0.0, 1.0, 0.0, cam_orig.y,
|
||||
0.0, 0.0, 1.0, cam_orig.z,
|
||||
0.0, 0.0, 0.0, 1.0
|
||||
);
|
||||
mat4 view_rot_xz = mat4(
|
||||
cos(cam_rot.y), 0.0, sin(cam_rot.y), 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
-sin(cam_rot.y), 0.0, cos(cam_rot.y), 0.0,
|
||||
0.0, 0.0, 0.0, 1.0
|
||||
);
|
||||
mat4 view_rot_yz = mat4(
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
0.0, cos(cam_rot.x), sin(cam_rot.x), 0.0,
|
||||
0.0, -sin(cam_rot.x), cos(cam_rot.x), 0.0,
|
||||
0.0, 0.0, 0.0, 1.0
|
||||
);
|
||||
mat4 project_aspect = mat4(
|
||||
(1080.0/1920.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 project_znear = mat4(
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, -zNear,
|
||||
0.0, 0.0, 0.0, 1.0
|
||||
);
|
||||
mat4 project_div = mat4(
|
||||
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, tan((70.0/2.0)/360.0*TAU), 0.0
|
||||
);
|
||||
mat4 project_normal = mat4(
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0/zFar, 0.0,
|
||||
0.0, 0.0, 0.0, 1.0
|
||||
);
|
||||
|
||||
// apply view's origin transformation
|
||||
//gl_Position.xyz += cam_orig.xyz;
|
||||
gl_Position *= view_orig;
|
||||
|
||||
// apply view's xz rotation
|
||||
//mat2 xz_rot;
|
||||
//xz_rot[0] = vec2(cos(cam_rot.y), -sin(cam_rot.y));
|
||||
//xz_rot[1] = vec2(sin(cam_rot.y), cos(cam_rot.y));
|
||||
//gl_Position.xz *= inverse(xz_rot);
|
||||
gl_Position *= view_rot_xz;
|
||||
|
||||
// apply view's yz rotation
|
||||
//mat2 yz_rot;
|
||||
//yz_rot[0] = vec2(cos(cam_rot.x), -sin(cam_rot.x));
|
||||
//yz_rot[1] = vec2(sin(cam_rot.x), cos(cam_rot.x));
|
||||
//gl_Position.yz *= inverse(yz_rot);
|
||||
gl_Position *= view_rot_yz;
|
||||
|
||||
// aspect correction
|
||||
//gl_Position.x *= (1080.0/1920.0);
|
||||
gl_Position *= project_aspect;
|
||||
|
||||
// z near correction
|
||||
//gl_Position.z -= zNear;
|
||||
gl_Position *= project_znear;
|
||||
|
||||
// division by z
|
||||
// has to be assigned by w so that the hardware performs the division AFTER clipping.
|
||||
//gl_Position.w = (gl_Position.z*sin(140.0/360.0*TAU));
|
||||
gl_Position *= project_div;
|
||||
|
||||
// z normalization
|
||||
//gl_Position.z /= zFar;
|
||||
gl_Position *= project_normal;
|
||||
}
|
@ -1,3 +1,747 @@
|
||||
#![feature(inherent_str_constructors)]
|
||||
#![allow(unused_variables, unused_mut)]
|
||||
|
||||
use ash::Device;
|
||||
use ash::Entry;
|
||||
use ash::Instance;
|
||||
use ash::khr::{surface, swapchain};
|
||||
use ash::vk;
|
||||
|
||||
use std::ffi::CStr;
|
||||
use std::ffi::CString;
|
||||
|
||||
use raw_window_handle::HasDisplayHandle;
|
||||
use raw_window_handle::HasWindowHandle;
|
||||
|
||||
use sdl2::video::Window;
|
||||
|
||||
const APP_NAME: &str = "MineClone";
|
||||
|
||||
const MESH_SIZE: u64 = 36 * 2 * 4 * 4;
|
||||
|
||||
const POSITIONS: [f32; 36 * 2 * 4] = [
|
||||
// BOTTOM
|
||||
-0.5, 0.5, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.5, 0.5, 2.0, 1.0, 0.0, 1.0, 0.0, 0.0, -0.5, 0.5, 2.0,
|
||||
1.0, 0.0, 1.0, 0.0, 0.0, 0.5, 0.5, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.5, 0.5, 2.0, 1.0, 0.0, 1.0,
|
||||
0.0, 0.0, -0.5, 0.5, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, // TOP
|
||||
0.5, -0.5, 2.0, 1.0, 0.0, -1.0, 0.0, 0.0, -0.5, -0.5, 1.0, 1.0, 0.0, -1.0, 0.0, 0.0, -0.5,
|
||||
-0.5, 2.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.5, -0.5, 2.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.5, -0.5, 1.0,
|
||||
1.0, 0.0, -1.0, 0.0, 0.0, -0.5, -0.5, 1.0, 1.0, 0.0, -1.0, 0.0, 0.0, // FRONT
|
||||
-0.5, -0.5, 1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.5, 0.5, 1.0, 1.0, 0.0, 0.0, -1.0, 0.0, -0.5, 0.5,
|
||||
1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.5, -0.5, 1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.5, 0.5, 1.0, 1.0,
|
||||
0.0, 0.0, -1.0, 0.0, -0.5, -0.5, 1.0, 1.0, 0.0, 0.0, -1.0, 0.0, // BACK
|
||||
0.5, 0.5, 2.0, 1.0, 0.0, 0.0, 1.0, 0.0, -0.5, -0.5, 2.0, 1.0, 0.0, 0.0, 1.0, 0.0, -0.5, 0.5,
|
||||
2.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.5, 0.5, 2.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.5, -0.5, 2.0, 1.0, 0.0,
|
||||
0.0, 1.0, 0.0, -0.5, -0.5, 2.0, 1.0, 0.0, 0.0, 1.0, 0.0, // LEFT
|
||||
-0.5, -0.5, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, -0.5, 0.5, 2.0, 1.0, -1.0, 0.0, 0.0, 0.0, -0.5,
|
||||
-0.5, 2.0, 1.0, -1.0, 0.0, 0.0, 0.0, -0.5, 0.5, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, -0.5, 0.5, 2.0,
|
||||
1.0, -1.0, 0.0, 0.0, 0.0, -0.5, -0.5, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, // RIGHT
|
||||
0.5, 0.5, 2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, -0.5, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, -0.5,
|
||||
2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 1.0, 1.0, 1.0,
|
||||
0.0, 0.0, 0.0, 0.5, -0.5, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0,
|
||||
];
|
||||
|
||||
fn create_instance(window: &Window, entry: &Entry) -> Instance {
|
||||
unsafe {
|
||||
let n_app_name = CString::new(APP_NAME).unwrap();
|
||||
let n_engine_name = CString::new(format!("{} Engine", APP_NAME)).unwrap();
|
||||
|
||||
let appinfo = vk::ApplicationInfo::default()
|
||||
.application_name(n_app_name.as_c_str())
|
||||
.application_version(0)
|
||||
.engine_name(n_engine_name.as_c_str())
|
||||
.engine_version(0)
|
||||
.api_version(vk::make_api_version(0, 1, 3, 0));
|
||||
|
||||
let default_exts = window
|
||||
.vulkan_instance_extensions()
|
||||
.expect("Failed to get list of required extensions from SDL2");
|
||||
|
||||
let mut exts = vec![];
|
||||
exts.extend(default_exts);
|
||||
|
||||
let exts: Vec<*const i8> = exts
|
||||
.iter()
|
||||
.map(|s| s.as_ptr() as *const i8)
|
||||
.collect::<Vec<_>>();
|
||||
let exts: &[*const i8] = exts.as_slice();
|
||||
|
||||
let insinfo = vk::InstanceCreateInfo::default()
|
||||
.application_info(&appinfo)
|
||||
.enabled_extension_names(exts);
|
||||
|
||||
let instance = entry
|
||||
.create_instance(&insinfo, None)
|
||||
.expect("Failed to create instance");
|
||||
println!("Created instance");
|
||||
instance
|
||||
}
|
||||
}
|
||||
|
||||
fn find_pdev_dgpu(instance: &Instance) -> vk::PhysicalDevice {
|
||||
unsafe {
|
||||
let mut pdevs = instance
|
||||
.enumerate_physical_devices()
|
||||
.expect("Failed to enumerate devices");
|
||||
for (i, d) in pdevs.iter().enumerate() {
|
||||
let props = instance.get_physical_device_properties(*d);
|
||||
if props.device_type == vk::PhysicalDeviceType::DISCRETE_GPU {
|
||||
// TODO this assumes that the first discrete GPU will have an RCS queue family
|
||||
// This is not guaranteed by the spec (example, a compute-only GPU)
|
||||
// Fix.
|
||||
println!(
|
||||
"Found discrete GPU: {}",
|
||||
str::from_utf8(std::mem::transmute(props.device_name.as_slice())).unwrap()
|
||||
);
|
||||
return pdevs.remove(i);
|
||||
}
|
||||
}
|
||||
println!("No discrete GPU found");
|
||||
assert!(pdevs.len() > 0, "No GPU found");
|
||||
return pdevs.remove(0);
|
||||
}
|
||||
}
|
||||
|
||||
fn make_surface(entry: &Entry, instance: &Instance, window: &Window) -> vk::SurfaceKHR {
|
||||
unsafe {
|
||||
let surface = ash_window::create_surface(
|
||||
&entry,
|
||||
&instance,
|
||||
(&window).display_handle().unwrap().as_raw(),
|
||||
(&window).window_handle().unwrap().as_raw(),
|
||||
None,
|
||||
)
|
||||
.expect("Failed to create surface");
|
||||
println!("Created surface");
|
||||
surface
|
||||
}
|
||||
}
|
||||
|
||||
// Using Intel GPU hardware terminology 🥴
|
||||
fn find_rcs_queue_inx(instance: &Instance, pdev: &vk::PhysicalDevice) -> Option<u32> {
|
||||
unsafe {
|
||||
let qfams = instance.get_physical_device_queue_family_properties(*pdev);
|
||||
for (inx, qfam) in qfams.iter().enumerate() {
|
||||
if qfam
|
||||
.queue_flags
|
||||
.contains(vk::QueueFlags::GRAPHICS | vk::QueueFlags::COMPUTE)
|
||||
{
|
||||
println!("Found RCS queue at index {}", inx);
|
||||
return Some(inx as u32);
|
||||
}
|
||||
}
|
||||
println!("No RCS queue found");
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
fn make_dev(
|
||||
instance: &Instance,
|
||||
pdev: &vk::PhysicalDevice,
|
||||
rcs_queue_inx: u32,
|
||||
exts: Vec<&CStr>,
|
||||
) -> Device {
|
||||
unsafe {
|
||||
let dev_queue = vec![
|
||||
vk::DeviceQueueCreateInfo::default()
|
||||
.queue_family_index(rcs_queue_inx)
|
||||
.queue_priorities(&[1.0]),
|
||||
];
|
||||
|
||||
let exts = exts.iter().map(|&s| s.as_ptr()).collect::<Vec<_>>();
|
||||
let exts = exts.as_slice();
|
||||
|
||||
// Enable all features
|
||||
let features = instance.get_physical_device_features(*pdev);
|
||||
|
||||
let dev_info = vk::DeviceCreateInfo::default()
|
||||
.queue_create_infos(&dev_queue)
|
||||
.enabled_extension_names(exts)
|
||||
.enabled_features(&features);
|
||||
|
||||
let dev = instance
|
||||
.create_device(*pdev, &dev_info, None)
|
||||
.expect("Failed to create device");
|
||||
println!("Created device");
|
||||
dev
|
||||
}
|
||||
}
|
||||
|
||||
fn make_command_pool(dev: &Device, rcs_queue_inx: u32) -> vk::CommandPool {
|
||||
unsafe {
|
||||
let pool_info = vk::CommandPoolCreateInfo::default()
|
||||
.queue_family_index(rcs_queue_inx)
|
||||
.flags(vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER);
|
||||
let pool = dev
|
||||
.create_command_pool(&pool_info, None)
|
||||
.expect("Failed to create command pool");
|
||||
println!("Created command pool");
|
||||
pool
|
||||
}
|
||||
}
|
||||
|
||||
fn alloc_cmd_buf(dev: &Device, pool: vk::CommandPool) -> vk::CommandBuffer {
|
||||
unsafe {
|
||||
let alloc_info = vk::CommandBufferAllocateInfo::default()
|
||||
.command_pool(pool)
|
||||
.level(vk::CommandBufferLevel::PRIMARY)
|
||||
.command_buffer_count(1);
|
||||
let cmd_buf = dev
|
||||
.allocate_command_buffers(&alloc_info)
|
||||
.expect("Failed to allocate command buffer")
|
||||
.remove(0);
|
||||
println!("Allocated command buffer");
|
||||
cmd_buf
|
||||
}
|
||||
}
|
||||
|
||||
fn find_host_visible(instance: &Instance, pdev: &vk::PhysicalDevice) -> Option<u32> {
|
||||
unsafe {
|
||||
let mem_props = instance.get_physical_device_memory_properties(*pdev);
|
||||
for (i, mem_type) in mem_props.memory_types.iter().enumerate() {
|
||||
if mem_type.property_flags.contains(
|
||||
vk::MemoryPropertyFlags::DEVICE_LOCAL
|
||||
| vk::MemoryPropertyFlags::HOST_VISIBLE
|
||||
| vk::MemoryPropertyFlags::HOST_COHERENT,
|
||||
) {
|
||||
println!("Found host visible memory at index {}", i);
|
||||
return Some(i as u32);
|
||||
}
|
||||
}
|
||||
println!("No host visible memory found");
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
fn find_host_invisible(instance: &Instance, pdev: &vk::PhysicalDevice) -> Option<u32> {
|
||||
unsafe {
|
||||
let mem_props = instance.get_physical_device_memory_properties(*pdev);
|
||||
for (i, mem_type) in mem_props.memory_types.iter().enumerate() {
|
||||
if mem_type
|
||||
.property_flags
|
||||
.contains(vk::MemoryPropertyFlags::DEVICE_LOCAL)
|
||||
&& !mem_type.property_flags.contains(
|
||||
vk::MemoryPropertyFlags::HOST_VISIBLE | vk::MemoryPropertyFlags::HOST_COHERENT,
|
||||
)
|
||||
{
|
||||
println!("Found host invisible memory at index {}", i);
|
||||
return Some(i as u32);
|
||||
}
|
||||
}
|
||||
println!("No host invisible memory found");
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
fn mem_alloc(dev: &Device, mem_type_inx: u32, size: u64) -> vk::DeviceMemory {
|
||||
unsafe {
|
||||
let mem_info = vk::MemoryAllocateInfo::default()
|
||||
.allocation_size(size)
|
||||
.memory_type_index(mem_type_inx);
|
||||
let mem = dev
|
||||
.allocate_memory(&mem_info, None)
|
||||
.expect("Failed to allocate memory");
|
||||
println!("Allocated memory");
|
||||
mem
|
||||
}
|
||||
}
|
||||
|
||||
fn make_depth_img(
|
||||
dev: &Device,
|
||||
host_invisible_inx: u32,
|
||||
width: u32,
|
||||
height: u32,
|
||||
mem: vk::DeviceMemory,
|
||||
qfam: u32,
|
||||
) -> vk::Image {
|
||||
unsafe {
|
||||
let queue_fams = [qfam];
|
||||
let img_info = vk::ImageCreateInfo::default()
|
||||
.flags(vk::ImageCreateFlags::empty())
|
||||
.image_type(vk::ImageType::TYPE_2D)
|
||||
.format(vk::Format::D32_SFLOAT)
|
||||
.extent(vk::Extent3D {
|
||||
width,
|
||||
height,
|
||||
depth: 1,
|
||||
})
|
||||
.mip_levels(1)
|
||||
.array_layers(1)
|
||||
.samples(vk::SampleCountFlags::TYPE_1)
|
||||
.tiling(vk::ImageTiling::OPTIMAL)
|
||||
.usage(vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT)
|
||||
.sharing_mode(vk::SharingMode::EXCLUSIVE)
|
||||
.queue_family_indices(&queue_fams)
|
||||
.initial_layout(vk::ImageLayout::UNDEFINED);
|
||||
|
||||
let img = dev
|
||||
.create_image(&img_info, None)
|
||||
.expect("Failed to create image");
|
||||
println!("Created image");
|
||||
|
||||
dev.bind_image_memory(img, mem, 0)
|
||||
.expect("Failed to bind image memory");
|
||||
|
||||
img
|
||||
}
|
||||
}
|
||||
|
||||
fn alloc_buf(
|
||||
dev: &Device,
|
||||
mem: &vk::DeviceMemory,
|
||||
size: u64,
|
||||
usage: vk::BufferUsageFlags,
|
||||
) -> vk::Buffer {
|
||||
unsafe {
|
||||
let buf_info = vk::BufferCreateInfo::default()
|
||||
.size(size)
|
||||
.usage(usage)
|
||||
.sharing_mode(vk::SharingMode::EXCLUSIVE);
|
||||
let buf = dev
|
||||
.create_buffer(&buf_info, None)
|
||||
.expect("Failed to create buffer");
|
||||
|
||||
dev.bind_buffer_memory(buf, *mem, 0)
|
||||
.expect("Failed to bind buffer memory");
|
||||
println!("Created buffer");
|
||||
buf
|
||||
}
|
||||
}
|
||||
|
||||
fn buf_to_ptr(dev: &Device, mem: &vk::DeviceMemory, buf: &vk::Buffer) -> *mut std::ffi::c_void {
|
||||
unsafe {
|
||||
let ptr = dev
|
||||
.map_memory(*mem, 0, vk::WHOLE_SIZE, vk::MemoryMapFlags::empty())
|
||||
.expect("Failed to map memory");
|
||||
println!("Mapped memory");
|
||||
ptr
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_desc_layout(dev: &Device) -> vk::DescriptorSetLayout {
|
||||
let storage_binding = vk::DescriptorSetLayoutBinding::default()
|
||||
.binding(0)
|
||||
.descriptor_type(vk::DescriptorType::STORAGE_BUFFER)
|
||||
.descriptor_count(1)
|
||||
.stage_flags(vk::ShaderStageFlags::VERTEX);
|
||||
let layouts = [storage_binding];
|
||||
|
||||
let layout_info = vk::DescriptorSetLayoutCreateInfo::default().bindings(&layouts);
|
||||
let layout = unsafe {
|
||||
dev.create_descriptor_set_layout(&layout_info, None)
|
||||
.expect("Failed to create descriptor set layout")
|
||||
};
|
||||
layout
|
||||
}
|
||||
|
||||
fn setup_render_pass(dev: &Device) -> vk::RenderPass {
|
||||
let color_attach = vk::AttachmentDescription::default()
|
||||
.format(vk::Format::B8G8R8A8_UNORM)
|
||||
.samples(vk::SampleCountFlags::TYPE_1)
|
||||
.load_op(vk::AttachmentLoadOp::CLEAR)
|
||||
.store_op(vk::AttachmentStoreOp::STORE)
|
||||
.stencil_load_op(vk::AttachmentLoadOp::DONT_CARE)
|
||||
.stencil_store_op(vk::AttachmentStoreOp::DONT_CARE)
|
||||
.initial_layout(vk::ImageLayout::UNDEFINED)
|
||||
.final_layout(vk::ImageLayout::PRESENT_SRC_KHR);
|
||||
let depth_attach = vk::AttachmentDescription::default()
|
||||
.format(vk::Format::D32_SFLOAT)
|
||||
.samples(vk::SampleCountFlags::TYPE_1)
|
||||
.load_op(vk::AttachmentLoadOp::CLEAR)
|
||||
.store_op(vk::AttachmentStoreOp::DONT_CARE)
|
||||
.stencil_load_op(vk::AttachmentLoadOp::DONT_CARE)
|
||||
.stencil_store_op(vk::AttachmentStoreOp::DONT_CARE)
|
||||
.initial_layout(vk::ImageLayout::UNDEFINED)
|
||||
.final_layout(vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
|
||||
let color_ref = vk::AttachmentReference::default()
|
||||
.attachment(0)
|
||||
.layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
let depth_ref = vk::AttachmentReference::default()
|
||||
.attachment(1)
|
||||
.layout(vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
|
||||
let color_refs = [color_ref];
|
||||
let depth_refs = [depth_ref];
|
||||
|
||||
let subpass = vk::SubpassDescription::default()
|
||||
.pipeline_bind_point(vk::PipelineBindPoint::GRAPHICS)
|
||||
.color_attachments(color_refs.as_ref())
|
||||
.depth_stencil_attachment(&depth_ref);
|
||||
|
||||
let subpass_dep = vk::SubpassDependency::default()
|
||||
.src_subpass(vk::SUBPASS_EXTERNAL)
|
||||
.dst_subpass(0)
|
||||
.src_stage_mask(
|
||||
vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT
|
||||
| vk::PipelineStageFlags::EARLY_FRAGMENT_TESTS,
|
||||
)
|
||||
.dst_stage_mask(
|
||||
vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT
|
||||
| vk::PipelineStageFlags::EARLY_FRAGMENT_TESTS,
|
||||
)
|
||||
.src_access_mask(vk::AccessFlags::empty())
|
||||
.dst_access_mask(
|
||||
vk::AccessFlags::COLOR_ATTACHMENT_WRITE
|
||||
| vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_WRITE,
|
||||
);
|
||||
|
||||
let attach_desc = [color_attach, depth_attach];
|
||||
|
||||
let subpasses = [subpass];
|
||||
|
||||
let deps = [subpass_dep];
|
||||
|
||||
let pass_info = vk::RenderPassCreateInfo::default()
|
||||
.attachments(&attach_desc)
|
||||
.subpasses(subpasses.as_ref())
|
||||
.dependencies(deps.as_ref());
|
||||
|
||||
let pass = unsafe {
|
||||
dev.create_render_pass(&pass_info, None)
|
||||
.expect("Failed to create render pass")
|
||||
};
|
||||
pass
|
||||
}
|
||||
|
||||
fn setup_pipe_layout(dev: &Device) -> vk::PipelineLayout {
|
||||
let layout = setup_desc_layout(&dev);
|
||||
let push_range: [vk::PushConstantRange; 2] = [
|
||||
vk::PushConstantRange::default()
|
||||
.stage_flags(vk::ShaderStageFlags::VERTEX)
|
||||
.offset(0)
|
||||
.size(32), // vec4 camera_orig, camera_rot
|
||||
vk::PushConstantRange::default()
|
||||
.stage_flags(vk::ShaderStageFlags::FRAGMENT)
|
||||
.offset(32)
|
||||
.size(16), // vec4 base_color
|
||||
];
|
||||
|
||||
let layouts = &[layout];
|
||||
|
||||
let pipe_layout = vk::PipelineLayoutCreateInfo::default()
|
||||
.set_layouts(layouts.as_ref())
|
||||
.push_constant_ranges(&push_range);
|
||||
let pipe_layout = unsafe {
|
||||
dev.create_pipeline_layout(&pipe_layout, None)
|
||||
.expect("Failed to create pipeline layout")
|
||||
};
|
||||
pipe_layout
|
||||
}
|
||||
|
||||
fn setup_shader_stage(
|
||||
dev: &Device,
|
||||
vert_shader: vk::ShaderModule,
|
||||
frag_shader: vk::ShaderModule,
|
||||
) -> [vk::PipelineShaderStageCreateInfo; 2] {
|
||||
let vert_stage = vk::PipelineShaderStageCreateInfo::default()
|
||||
.stage(vk::ShaderStageFlags::VERTEX)
|
||||
.module(vert_shader)
|
||||
.name(CStr::from_bytes_with_nul(b"main\0").unwrap());
|
||||
let frag_stage = vk::PipelineShaderStageCreateInfo::default()
|
||||
.stage(vk::ShaderStageFlags::FRAGMENT)
|
||||
.module(frag_shader)
|
||||
.name(CStr::from_bytes_with_nul(b"main\0").unwrap());
|
||||
[vert_stage, frag_stage]
|
||||
}
|
||||
|
||||
fn setup_pipeline(
|
||||
dev: &Device,
|
||||
vert_shader: &vk::ShaderModule,
|
||||
frag_shader: &vk::ShaderModule,
|
||||
) -> vk::Pipeline {
|
||||
let pipe_layout = setup_pipe_layout(&dev);
|
||||
let pass = setup_render_pass(&dev);
|
||||
let shader_stages = setup_shader_stage(&dev, *vert_shader, *frag_shader);
|
||||
let vert_input = vk::PipelineVertexInputStateCreateInfo::default();
|
||||
let input_assembly = vk::PipelineInputAssemblyStateCreateInfo::default()
|
||||
.topology(vk::PrimitiveTopology::TRIANGLE_LIST);
|
||||
let rasterization = vk::PipelineRasterizationStateCreateInfo::default()
|
||||
.polygon_mode(vk::PolygonMode::FILL)
|
||||
.cull_mode(vk::CullModeFlags::BACK)
|
||||
.front_face(vk::FrontFace::CLOCKWISE)
|
||||
.line_width(1.0);
|
||||
let multisample = vk::PipelineMultisampleStateCreateInfo::default()
|
||||
.rasterization_samples(vk::SampleCountFlags::TYPE_1);
|
||||
let depth_stencil = vk::PipelineDepthStencilStateCreateInfo::default()
|
||||
.depth_test_enable(true)
|
||||
.depth_write_enable(true)
|
||||
.depth_compare_op(vk::CompareOp::LESS)
|
||||
.depth_bounds_test_enable(true)
|
||||
.stencil_test_enable(false)
|
||||
.min_depth_bounds(0.0)
|
||||
.max_depth_bounds(1.0);
|
||||
|
||||
let blend = vk::PipelineColorBlendAttachmentState::default()
|
||||
.src_color_blend_factor(vk::BlendFactor::SRC_COLOR)
|
||||
.dst_color_blend_factor(vk::BlendFactor::SRC_COLOR)
|
||||
.color_blend_op(vk::BlendOp::ADD)
|
||||
.src_alpha_blend_factor(vk::BlendFactor::SRC_COLOR)
|
||||
.dst_alpha_blend_factor(vk::BlendFactor::SRC_COLOR)
|
||||
.alpha_blend_op(vk::BlendOp::ADD)
|
||||
.color_write_mask(
|
||||
vk::ColorComponentFlags::R
|
||||
| vk::ColorComponentFlags::G
|
||||
| vk::ColorComponentFlags::B
|
||||
| vk::ColorComponentFlags::A,
|
||||
);
|
||||
|
||||
let blend_attachments = [blend];
|
||||
|
||||
let color_blend = vk::PipelineColorBlendStateCreateInfo::default()
|
||||
.attachments(blend_attachments.as_ref())
|
||||
.logic_op_enable(false)
|
||||
.logic_op(vk::LogicOp::COPY)
|
||||
.blend_constants([1.0, 1.0, 1.0, 1.0]);
|
||||
|
||||
let dynamic = vk::PipelineDynamicStateCreateInfo::default().dynamic_states(&[
|
||||
vk::DynamicState::VIEWPORT_WITH_COUNT,
|
||||
vk::DynamicState::SCISSOR_WITH_COUNT,
|
||||
]);
|
||||
|
||||
let pipe_info = vk::GraphicsPipelineCreateInfo::default()
|
||||
.stages(&shader_stages)
|
||||
.vertex_input_state(&vert_input)
|
||||
.input_assembly_state(&input_assembly)
|
||||
.rasterization_state(&rasterization)
|
||||
.multisample_state(&multisample)
|
||||
.depth_stencil_state(&depth_stencil)
|
||||
.color_blend_state(&color_blend)
|
||||
.layout(pipe_layout)
|
||||
.dynamic_state(&dynamic)
|
||||
.render_pass(pass)
|
||||
.subpass(0);
|
||||
|
||||
let pipe = unsafe {
|
||||
dev.create_graphics_pipelines(vk::PipelineCache::null(), &[pipe_info], None)
|
||||
.expect("Failed to create graphics pipeline")
|
||||
.remove(0)
|
||||
};
|
||||
println!("Created pipeline");
|
||||
pipe
|
||||
}
|
||||
|
||||
// TODO dynamic state for resizing
|
||||
fn setup_swapchain(
|
||||
pdev: &vk::PhysicalDevice,
|
||||
dev: &Device,
|
||||
surface: &vk::SurfaceKHR,
|
||||
surface_loader: &surface::Instance,
|
||||
swapchain_loader: &ash::khr::swapchain::Device,
|
||||
instance: &Instance,
|
||||
) -> vk::SwapchainKHR {
|
||||
let caps = unsafe {
|
||||
surface_loader
|
||||
.get_physical_device_surface_capabilities(*pdev, *surface)
|
||||
.expect("Failed to get surface capabilities")
|
||||
};
|
||||
|
||||
let formats = unsafe {
|
||||
surface_loader
|
||||
.get_physical_device_surface_formats(*pdev, *surface)
|
||||
.expect("Failed to get surface formats")
|
||||
};
|
||||
|
||||
let format = (formats)
|
||||
.iter()
|
||||
.filter(|f| {
|
||||
f.format == vk::Format::B8G8R8A8_UNORM
|
||||
&& f.color_space == vk::ColorSpaceKHR::SRGB_NONLINEAR
|
||||
})
|
||||
.next()
|
||||
.expect("No suitable format found");
|
||||
|
||||
let swap_create = vk::SwapchainCreateInfoKHR::default()
|
||||
.surface(*surface)
|
||||
.min_image_count(caps.min_image_count)
|
||||
.image_format(format.format)
|
||||
.image_color_space(format.color_space)
|
||||
.image_extent(caps.current_extent)
|
||||
.image_array_layers(1)
|
||||
.image_usage(vk::ImageUsageFlags::COLOR_ATTACHMENT)
|
||||
.image_sharing_mode(vk::SharingMode::EXCLUSIVE)
|
||||
.pre_transform(vk::SurfaceTransformFlagsKHR::IDENTITY)
|
||||
.composite_alpha(vk::CompositeAlphaFlagsKHR::OPAQUE)
|
||||
.present_mode(vk::PresentModeKHR::MAILBOX)
|
||||
.clipped(true);
|
||||
|
||||
let swapchain = unsafe {
|
||||
swapchain_loader
|
||||
.create_swapchain(&swap_create, None)
|
||||
.expect("Failed to create swapchain")
|
||||
};
|
||||
println!("Created swapchain");
|
||||
swapchain
|
||||
}
|
||||
|
||||
fn setup_desc_pool(dev: &Device) -> vk::DescriptorPool {
|
||||
let pool_size = vk::DescriptorPoolSize::default()
|
||||
.ty(vk::DescriptorType::STORAGE_BUFFER)
|
||||
.descriptor_count(1);
|
||||
let pool_sizes = [pool_size];
|
||||
let pool_info = vk::DescriptorPoolCreateInfo::default()
|
||||
.max_sets(1)
|
||||
.pool_sizes(&pool_sizes);
|
||||
let pool = unsafe {
|
||||
dev.create_descriptor_pool(&pool_info, None)
|
||||
.expect("Failed to create descriptor pool")
|
||||
};
|
||||
pool
|
||||
}
|
||||
|
||||
fn make_swap_images(
|
||||
dev: &Device,
|
||||
swapchain: &vk::SwapchainKHR,
|
||||
swapchain_loader: &swapchain::Device,
|
||||
) -> Vec<vk::Image> {
|
||||
unsafe {
|
||||
let images = swapchain_loader
|
||||
.get_swapchain_images(*swapchain)
|
||||
.expect("Failed to get swapchain images");
|
||||
println!("Fetched swapchain images");
|
||||
images
|
||||
}
|
||||
}
|
||||
|
||||
fn make_swap_views(
|
||||
dev: &Device,
|
||||
swap_images: &Vec<vk::Image>,
|
||||
format: vk::Format,
|
||||
) -> Vec<vk::ImageView> {
|
||||
let mut views = Vec::new();
|
||||
for img in swap_images.iter() {
|
||||
let view_info = vk::ImageViewCreateInfo::default()
|
||||
.image(*img)
|
||||
.view_type(vk::ImageViewType::TYPE_2D)
|
||||
.format(format)
|
||||
.components(vk::ComponentMapping::default())
|
||||
.subresource_range(
|
||||
vk::ImageSubresourceRange::default()
|
||||
.aspect_mask(vk::ImageAspectFlags::COLOR)
|
||||
.base_mip_level(0)
|
||||
.level_count(1)
|
||||
.base_array_layer(0)
|
||||
.layer_count(1),
|
||||
);
|
||||
let view = unsafe {
|
||||
dev.create_image_view(&view_info, None)
|
||||
.expect("Failed to create image view")
|
||||
};
|
||||
views.push(view);
|
||||
}
|
||||
views
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
let sdl_context = sdl2::init().unwrap();
|
||||
let video_subsystem = sdl_context.video().unwrap();
|
||||
|
||||
let mut width = 1024;
|
||||
let mut height = 768;
|
||||
|
||||
let max_width = 3440;
|
||||
let max_height = 1440;
|
||||
|
||||
let window = video_subsystem
|
||||
.window(APP_NAME, width, height)
|
||||
.vulkan()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let entry = Entry::linked();
|
||||
|
||||
let instance = create_instance(&window, &entry);
|
||||
|
||||
let surface = make_surface(&entry, &instance, &window);
|
||||
|
||||
let pdev = find_pdev_dgpu(&instance);
|
||||
|
||||
let rcs_queue_inx = find_rcs_queue_inx(&instance, &pdev).expect("No RCS queue found");
|
||||
|
||||
let dev = make_dev(&instance, &pdev, rcs_queue_inx, vec![c"VK_KHR_swapchain", c"VK_EXT_extended_dynamic_state3"]);
|
||||
|
||||
let queue = unsafe { dev.get_device_queue(rcs_queue_inx, 0) };
|
||||
|
||||
let cmd_pool = make_command_pool(&dev, rcs_queue_inx);
|
||||
|
||||
let cmd_buf = alloc_cmd_buf(&dev, cmd_pool);
|
||||
|
||||
let host_visible_inx =
|
||||
find_host_visible(&instance, &pdev).expect("No host visible memory found");
|
||||
|
||||
let host_invisible_inx =
|
||||
find_host_invisible(&instance, &pdev).expect("No host invisible memory found");
|
||||
|
||||
let mesh_mem = mem_alloc(&dev, host_visible_inx, MESH_SIZE);
|
||||
// Max viewport size is 3440x1440
|
||||
let depth_mem = mem_alloc(&dev, host_invisible_inx, max_width * max_height * 8);
|
||||
|
||||
let depth_img = make_depth_img(
|
||||
&dev,
|
||||
host_invisible_inx,
|
||||
width,
|
||||
height,
|
||||
depth_mem,
|
||||
rcs_queue_inx,
|
||||
);
|
||||
|
||||
let mesh_buf = alloc_buf(
|
||||
&dev,
|
||||
&mesh_mem,
|
||||
MESH_SIZE,
|
||||
vk::BufferUsageFlags::TRANSFER_SRC | vk::BufferUsageFlags::STORAGE_BUFFER,
|
||||
);
|
||||
|
||||
let mesh_mem = buf_to_ptr(&dev, &mesh_mem, &mesh_buf);
|
||||
unsafe {
|
||||
std::ptr::copy(POSITIONS.as_ptr(), mesh_mem as *mut f32, POSITIONS.len());
|
||||
}
|
||||
|
||||
let vert_shader_bin = std::fs::read("shaders/vert.spv").unwrap();
|
||||
let frag_shader_bin = std::fs::read("shaders/frag.spv").unwrap();
|
||||
|
||||
let vert_shader = unsafe {
|
||||
dev.create_shader_module(
|
||||
&vk::ShaderModuleCreateInfo {
|
||||
code_size: vert_shader_bin.len(),
|
||||
p_code: vert_shader_bin.as_ptr() as *const u32,
|
||||
..Default::default()
|
||||
},
|
||||
None,
|
||||
)
|
||||
.expect("Failed to create vertex shader module")
|
||||
};
|
||||
|
||||
let frag_shader = unsafe {
|
||||
dev.create_shader_module(
|
||||
&vk::ShaderModuleCreateInfo {
|
||||
code_size: frag_shader_bin.len(),
|
||||
p_code: frag_shader_bin.as_ptr() as *const u32,
|
||||
..Default::default()
|
||||
},
|
||||
None,
|
||||
)
|
||||
.expect("Failed to create fragment shader module")
|
||||
};
|
||||
|
||||
let pipe = setup_pipeline(&dev, &vert_shader, &frag_shader);
|
||||
|
||||
let surface_loader = surface::Instance::new(&entry, &instance);
|
||||
let swapchain_loader = swapchain::Device::new(&instance, &dev);
|
||||
|
||||
let swapchain = setup_swapchain(
|
||||
&pdev,
|
||||
&dev,
|
||||
&surface,
|
||||
&surface_loader,
|
||||
&swapchain_loader,
|
||||
&instance,
|
||||
);
|
||||
|
||||
let desc_pool = setup_desc_pool(&dev);
|
||||
|
||||
let swap_images = make_swap_images(&dev, &swapchain, &swapchain_loader);
|
||||
|
||||
let swap_views = make_swap_views(&dev, &swap_images, vk::Format::B8G8R8A8_UNORM);
|
||||
}
|
||||
|
Loading…
Reference in new issue