vulkan initialisation
This commit is contained in:
parent
92dc4e3885
commit
bd7d03c98b
5 changed files with 613 additions and 9 deletions
134
Cargo.lock
generated
134
Cargo.lock
generated
|
@ -187,6 +187,14 @@ version = "0.7.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
|
||||
|
||||
[[package]]
|
||||
name = "ash"
|
||||
version = "0.37.0+1.3.260"
|
||||
source = "git+https://github.com/ash-rs/ash#3f5b96b3638a9ff341584e82188c3ba3aa5cb996"
|
||||
dependencies = [
|
||||
"libloading 0.7.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ash"
|
||||
version = "0.37.3+1.3.251"
|
||||
|
@ -196,6 +204,16 @@ dependencies = [
|
|||
"libloading 0.7.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ash-window"
|
||||
version = "0.12.0"
|
||||
source = "git+https://github.com/ash-rs/ash#3f5b96b3638a9ff341584e82188c3ba3aa5cb996"
|
||||
dependencies = [
|
||||
"ash 0.37.0+1.3.260",
|
||||
"raw-window-handle",
|
||||
"raw-window-metal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-ringbuf"
|
||||
version = "0.1.3"
|
||||
|
@ -326,6 +344,16 @@ version = "0.1.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"byte-tools",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-sys"
|
||||
version = "0.1.0-beta.1"
|
||||
|
@ -351,6 +379,12 @@ version = "3.13.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.13.1"
|
||||
|
@ -502,6 +536,15 @@ version = "0.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b"
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cocoa"
|
||||
version = "0.20.2"
|
||||
|
@ -888,6 +931,15 @@ version = "0.11.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dispatch"
|
||||
version = "0.2.0"
|
||||
|
@ -948,6 +1000,18 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fake-simd"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
|
||||
|
||||
[[package]]
|
||||
name = "fdeflate"
|
||||
version = "0.3.0"
|
||||
|
@ -1103,7 +1167,8 @@ dependencies = [
|
|||
name = "gb-emu"
|
||||
version = "0.3.3"
|
||||
dependencies = [
|
||||
"ash",
|
||||
"ash 0.37.0+1.3.260",
|
||||
"ash-window",
|
||||
"bytemuck",
|
||||
"clap",
|
||||
"cpal",
|
||||
|
@ -1111,8 +1176,10 @@ dependencies = [
|
|||
"futures",
|
||||
"gb-emu-lib",
|
||||
"gilrs",
|
||||
"glsl-to-spirv",
|
||||
"nokhwa",
|
||||
"pixels",
|
||||
"raw-window-handle",
|
||||
"send_wrapper",
|
||||
"winit",
|
||||
"winit_input_helper",
|
||||
|
@ -1133,6 +1200,15 @@ dependencies = [
|
|||
"serde_with",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d00328cedcac5e81c683e5620ca6a30756fc23027ebf9bff405c0e8da1fbb7e"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.10"
|
||||
|
@ -1203,6 +1279,17 @@ dependencies = [
|
|||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glsl-to-spirv"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28caebc98746d507603a2d3df66dcbe04e41d4febad0320f3eec1ef72b6bbef1"
|
||||
dependencies = [
|
||||
"cmake",
|
||||
"sha2",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "goblin"
|
||||
version = "0.6.1"
|
||||
|
@ -2411,6 +2498,18 @@ version = "0.5.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9"
|
||||
|
||||
[[package]]
|
||||
name = "raw-window-metal"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed91094d30089fc273de843cfef783f8c04cc75828277a64e0e8dc2a0cebd4dc"
|
||||
dependencies = [
|
||||
"cocoa 0.24.1",
|
||||
"core-graphics 0.22.3",
|
||||
"objc",
|
||||
"raw-window-handle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.3.5"
|
||||
|
@ -2673,6 +2772,18 @@ dependencies = [
|
|||
"syn 2.0.26",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"byte-tools",
|
||||
"digest",
|
||||
"fake-simd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.1.0"
|
||||
|
@ -2787,6 +2898,19 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"fastrand",
|
||||
"redox_syscall",
|
||||
"rustix 0.38.4",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.2.0"
|
||||
|
@ -2920,6 +3044,12 @@ version = "0.19.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a464a4b34948a5f67fddd2b823c62d9d92e44be75058b99939eae6c5b6960b33"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||
|
||||
[[package]]
|
||||
name = "ultraviolet"
|
||||
version = "0.9.1"
|
||||
|
@ -3256,7 +3386,7 @@ checksum = "bdcf61a283adc744bb5453dd88ea91f3f86d5ca6b027661c6c73c7734ae0288b"
|
|||
dependencies = [
|
||||
"android_system_properties",
|
||||
"arrayvec",
|
||||
"ash",
|
||||
"ash 0.37.3+1.3.251",
|
||||
"bit-set",
|
||||
"bitflags 1.3.2",
|
||||
"block",
|
||||
|
|
|
@ -4,10 +4,14 @@ version = "0.3.3"
|
|||
edition = "2021"
|
||||
|
||||
[features]
|
||||
# default = ["vulkan"]
|
||||
default = ["pixels"]
|
||||
pixels = ["dep:pixels"]
|
||||
vulkan = ["dep:ash"]
|
||||
default = ["vulkan"]
|
||||
pixels = ["dep:pixels", "dep:bytemuck"]
|
||||
vulkan = [
|
||||
"dep:ash",
|
||||
"dep:ash-window",
|
||||
"dep:raw-window-handle",
|
||||
"dep:glsl-to-spirv",
|
||||
]
|
||||
camera = ["dep:nokhwa", "dep:send_wrapper"]
|
||||
|
||||
[dependencies]
|
||||
|
@ -23,6 +27,13 @@ nokhwa = { version = "0.10.3", features = [
|
|||
send_wrapper = { version = "0.6.0", optional = true }
|
||||
winit = "0.28"
|
||||
winit_input_helper = "0.14"
|
||||
bytemuck = "1.13"
|
||||
bytemuck = { version = "1.13", optional = true }
|
||||
pixels = { version = "0.12", optional = true }
|
||||
ash = { version = "0.37", optional = true }
|
||||
ash = { git = "https://github.com/ash-rs/ash", features = [
|
||||
"linked",
|
||||
], optional = true }
|
||||
ash-window = { git = "https://github.com/ash-rs/ash", optional = true }
|
||||
raw-window-handle = { version = "0.5", optional = true }
|
||||
|
||||
[build-dependencies]
|
||||
glsl-to-spirv = { version = "0.1.7", optional = true }
|
||||
|
|
463
gb-emu/src/renderer/vulkan/vulkan.rs
Normal file
463
gb-emu/src/renderer/vulkan/vulkan.rs
Normal file
|
@ -0,0 +1,463 @@
|
|||
use ash::{
|
||||
extensions::khr::{Surface, Swapchain},
|
||||
vk, Device, Entry, Instance,
|
||||
};
|
||||
use ash_window::enumerate_required_extensions;
|
||||
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
|
||||
use winit::window::Window;
|
||||
|
||||
// much of this is lifted from the Ash examples
|
||||
// https://github.com/ash-rs/ash/blob/master/examples/src/lib.rs
|
||||
// https://github.com/ash-rs/ash/blob/master/examples/src/bin/texture.rs
|
||||
|
||||
pub struct WindowData {
|
||||
scale_factor: u32,
|
||||
|
||||
entry: Entry,
|
||||
instance: Instance,
|
||||
device: Device,
|
||||
surface_loader: Surface,
|
||||
swapchain_loader: Swapchain,
|
||||
pdevice: vk::PhysicalDevice,
|
||||
device_memory_properties: vk::PhysicalDeviceMemoryProperties,
|
||||
queue_family_index: u32,
|
||||
present_queue: vk::Queue,
|
||||
|
||||
surface: vk::SurfaceKHR,
|
||||
surface_format: vk::SurfaceFormatKHR,
|
||||
surface_resolution: vk::Extent2D,
|
||||
swapchain: vk::SwapchainKHR,
|
||||
present_images: Vec<vk::Image>,
|
||||
present_image_views: Vec<vk::ImageView>,
|
||||
|
||||
pool: vk::CommandPool,
|
||||
draw_command_buffer: vk::CommandBuffer,
|
||||
setup_command_buffer: vk::CommandBuffer,
|
||||
|
||||
depth_image: vk::Image,
|
||||
depth_image_view: vk::ImageView,
|
||||
depth_image_memory: vk::DeviceMemory,
|
||||
|
||||
present_complete_semaphore: vk::Semaphore,
|
||||
rendering_complete_semaphore: vk::Semaphore,
|
||||
|
||||
draw_commands_reuse_fence: vk::Fence,
|
||||
setup_commands_reuse_fence: vk::Fence,
|
||||
}
|
||||
|
||||
impl WindowData {
|
||||
pub fn new(factor: u32, window: &Window) -> Self {
|
||||
let entry = Entry::linked();
|
||||
let name = std::ffi::CString::new("gameboy").unwrap();
|
||||
|
||||
let mut extension_names = enumerate_required_extensions(window.raw_display_handle())
|
||||
.unwrap()
|
||||
.to_vec();
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
{
|
||||
extension_names.push(vk::KhrPortabilityEnumerationFn::NAME.as_ptr());
|
||||
extension_names.push(vk::KhrGetPhysicalDeviceProperties2Fn::NAME.as_ptr());
|
||||
}
|
||||
|
||||
let appinfo = vk::ApplicationInfo::default()
|
||||
.application_name(&name)
|
||||
.engine_name(&name)
|
||||
.application_version(0)
|
||||
.engine_version(0)
|
||||
.api_version(vk::make_api_version(0, 1, 0, 0));
|
||||
|
||||
let create_flags = if cfg!(any(target_os = "macos", target_os = "ios")) {
|
||||
vk::InstanceCreateFlags::ENUMERATE_PORTABILITY_KHR
|
||||
} else {
|
||||
vk::InstanceCreateFlags::default()
|
||||
};
|
||||
|
||||
let create_info = vk::InstanceCreateInfo::default()
|
||||
.application_info(&appinfo)
|
||||
.enabled_extension_names(&extension_names)
|
||||
.flags(create_flags);
|
||||
|
||||
let instance = unsafe { entry.create_instance(&create_info, None) }.unwrap();
|
||||
|
||||
let surface = unsafe {
|
||||
ash_window::create_surface(
|
||||
&entry,
|
||||
&instance,
|
||||
window.raw_display_handle(),
|
||||
window.raw_window_handle(),
|
||||
None,
|
||||
)
|
||||
}
|
||||
.unwrap();
|
||||
let pdevices =
|
||||
unsafe { instance.enumerate_physical_devices() }.expect("Physical device error");
|
||||
let surface_loader = Surface::new(&entry, &instance);
|
||||
let (pdevice, queue_family_index) = pdevices
|
||||
.iter()
|
||||
.find_map(|pdevice| {
|
||||
unsafe { instance.get_physical_device_queue_family_properties(*pdevice) }
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(index, info)| {
|
||||
let supports_graphic_and_surface =
|
||||
info.queue_flags.contains(vk::QueueFlags::GRAPHICS)
|
||||
&& unsafe {
|
||||
surface_loader.get_physical_device_surface_support(
|
||||
*pdevice,
|
||||
index as u32,
|
||||
surface,
|
||||
)
|
||||
}
|
||||
.unwrap();
|
||||
if supports_graphic_and_surface {
|
||||
Some((*pdevice, index))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
})
|
||||
.expect("Couldn't find suitable device.");
|
||||
let queue_family_index = queue_family_index as u32;
|
||||
let device_extension_names_raw = [
|
||||
Swapchain::NAME.as_ptr(),
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
vk::KhrPortabilitySubsetFn::NAME.as_ptr(),
|
||||
];
|
||||
let features = vk::PhysicalDeviceFeatures {
|
||||
shader_clip_distance: 1,
|
||||
..Default::default()
|
||||
};
|
||||
let priorities = [1.0];
|
||||
|
||||
let queue_info = vk::DeviceQueueCreateInfo::default()
|
||||
.queue_family_index(queue_family_index)
|
||||
.queue_priorities(&priorities);
|
||||
|
||||
let device_create_info = vk::DeviceCreateInfo::default()
|
||||
.queue_create_infos(std::slice::from_ref(&queue_info))
|
||||
.enabled_extension_names(&device_extension_names_raw)
|
||||
.enabled_features(&features);
|
||||
|
||||
let device = unsafe { instance.create_device(pdevice, &device_create_info, None) }.unwrap();
|
||||
|
||||
let present_queue = unsafe { device.get_device_queue(queue_family_index, 0) };
|
||||
|
||||
let surface_format =
|
||||
unsafe { surface_loader.get_physical_device_surface_formats(pdevice, surface) }
|
||||
.unwrap()[0];
|
||||
|
||||
let surface_capabilities =
|
||||
unsafe { surface_loader.get_physical_device_surface_capabilities(pdevice, surface) }
|
||||
.unwrap();
|
||||
let mut desired_image_count = surface_capabilities.min_image_count + 1;
|
||||
if surface_capabilities.max_image_count > 0
|
||||
&& desired_image_count > surface_capabilities.max_image_count
|
||||
{
|
||||
desired_image_count = surface_capabilities.max_image_count;
|
||||
}
|
||||
let surface_resolution = match surface_capabilities.current_extent.width {
|
||||
std::u32::MAX => vk::Extent2D {
|
||||
width: window.inner_size().width,
|
||||
height: window.inner_size().height,
|
||||
},
|
||||
_ => surface_capabilities.current_extent,
|
||||
};
|
||||
let pre_transform = if surface_capabilities
|
||||
.supported_transforms
|
||||
.contains(vk::SurfaceTransformFlagsKHR::IDENTITY)
|
||||
{
|
||||
vk::SurfaceTransformFlagsKHR::IDENTITY
|
||||
} else {
|
||||
surface_capabilities.current_transform
|
||||
};
|
||||
let present_modes =
|
||||
unsafe { surface_loader.get_physical_device_surface_present_modes(pdevice, surface) }
|
||||
.unwrap();
|
||||
let present_mode = present_modes
|
||||
.iter()
|
||||
.cloned()
|
||||
.find(|&mode| mode == vk::PresentModeKHR::MAILBOX)
|
||||
.unwrap_or(vk::PresentModeKHR::FIFO);
|
||||
let swapchain_loader = Swapchain::new(&instance, &device);
|
||||
|
||||
let swapchain_create_info = vk::SwapchainCreateInfoKHR::default()
|
||||
.surface(surface)
|
||||
.min_image_count(desired_image_count)
|
||||
.image_color_space(surface_format.color_space)
|
||||
.image_format(surface_format.format)
|
||||
.image_extent(surface_resolution)
|
||||
.image_usage(vk::ImageUsageFlags::COLOR_ATTACHMENT)
|
||||
.image_sharing_mode(vk::SharingMode::EXCLUSIVE)
|
||||
.pre_transform(pre_transform)
|
||||
.composite_alpha(vk::CompositeAlphaFlagsKHR::OPAQUE)
|
||||
.present_mode(present_mode)
|
||||
.clipped(true)
|
||||
.image_array_layers(1);
|
||||
|
||||
let swapchain =
|
||||
unsafe { swapchain_loader.create_swapchain(&swapchain_create_info, None) }.unwrap();
|
||||
|
||||
let pool_create_info = vk::CommandPoolCreateInfo::default()
|
||||
.flags(vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER)
|
||||
.queue_family_index(queue_family_index);
|
||||
|
||||
let pool = unsafe { device.create_command_pool(&pool_create_info, None).unwrap() };
|
||||
|
||||
let command_buffer_allocate_info = vk::CommandBufferAllocateInfo::default()
|
||||
.command_buffer_count(2)
|
||||
.command_pool(pool)
|
||||
.level(vk::CommandBufferLevel::PRIMARY);
|
||||
|
||||
let command_buffers =
|
||||
unsafe { device.allocate_command_buffers(&command_buffer_allocate_info) }.unwrap();
|
||||
let setup_command_buffer = command_buffers[0];
|
||||
let draw_command_buffer = command_buffers[1];
|
||||
|
||||
let present_images = unsafe { swapchain_loader.get_swapchain_images(swapchain) }.unwrap();
|
||||
let present_image_views: Vec<vk::ImageView> = present_images
|
||||
.iter()
|
||||
.map(|&image| {
|
||||
let create_view_info = vk::ImageViewCreateInfo::default()
|
||||
.view_type(vk::ImageViewType::TYPE_2D)
|
||||
.format(surface_format.format)
|
||||
.components(vk::ComponentMapping {
|
||||
r: vk::ComponentSwizzle::R,
|
||||
g: vk::ComponentSwizzle::G,
|
||||
b: vk::ComponentSwizzle::B,
|
||||
a: vk::ComponentSwizzle::A,
|
||||
})
|
||||
.subresource_range(vk::ImageSubresourceRange {
|
||||
aspect_mask: vk::ImageAspectFlags::COLOR,
|
||||
base_mip_level: 0,
|
||||
level_count: 1,
|
||||
base_array_layer: 0,
|
||||
layer_count: 1,
|
||||
})
|
||||
.image(image);
|
||||
unsafe { device.create_image_view(&create_view_info, None) }.unwrap()
|
||||
})
|
||||
.collect();
|
||||
let device_memory_properties =
|
||||
unsafe { instance.get_physical_device_memory_properties(pdevice) };
|
||||
let depth_image_create_info = vk::ImageCreateInfo::default()
|
||||
.image_type(vk::ImageType::TYPE_2D)
|
||||
.format(vk::Format::D16_UNORM)
|
||||
.extent(surface_resolution.into())
|
||||
.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);
|
||||
|
||||
let depth_image = unsafe { device.create_image(&depth_image_create_info, None) }.unwrap();
|
||||
let depth_image_memory_req = unsafe { device.get_image_memory_requirements(depth_image) };
|
||||
let depth_image_memory_index = device_memory_properties.memory_types
|
||||
[..device_memory_properties.memory_type_count as _]
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(index, memory_type)| {
|
||||
(1 << index) & depth_image_memory_req.memory_type_bits != 0
|
||||
&& memory_type.property_flags & vk::MemoryPropertyFlags::DEVICE_LOCAL
|
||||
== vk::MemoryPropertyFlags::DEVICE_LOCAL
|
||||
})
|
||||
.map(|(index, _memory_type)| index as _)
|
||||
.expect("Unable to find suitable memory index for depth image.");
|
||||
|
||||
let depth_image_allocate_info = vk::MemoryAllocateInfo::default()
|
||||
.allocation_size(depth_image_memory_req.size)
|
||||
.memory_type_index(depth_image_memory_index);
|
||||
|
||||
let depth_image_memory =
|
||||
unsafe { device.allocate_memory(&depth_image_allocate_info, None) }.unwrap();
|
||||
|
||||
unsafe { device.bind_image_memory(depth_image, depth_image_memory, 0) }
|
||||
.expect("Unable to bind depth image memory");
|
||||
|
||||
let fence_create_info =
|
||||
vk::FenceCreateInfo::default().flags(vk::FenceCreateFlags::SIGNALED);
|
||||
|
||||
let draw_commands_reuse_fence =
|
||||
unsafe { device.create_fence(&fence_create_info, None) }.expect("Create fence failed.");
|
||||
let setup_commands_reuse_fence =
|
||||
unsafe { device.create_fence(&fence_create_info, None) }.expect("Create fence failed.");
|
||||
|
||||
record_submit_commandbuffer(
|
||||
&device,
|
||||
setup_command_buffer,
|
||||
setup_commands_reuse_fence,
|
||||
present_queue,
|
||||
&[],
|
||||
&[],
|
||||
&[],
|
||||
|device, setup_command_buffer| {
|
||||
let layout_transition_barriers = vk::ImageMemoryBarrier::default()
|
||||
.image(depth_image)
|
||||
.dst_access_mask(
|
||||
vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ
|
||||
| vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_WRITE,
|
||||
)
|
||||
.new_layout(vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
|
||||
.old_layout(vk::ImageLayout::UNDEFINED)
|
||||
.subresource_range(
|
||||
vk::ImageSubresourceRange::default()
|
||||
.aspect_mask(vk::ImageAspectFlags::DEPTH)
|
||||
.layer_count(1)
|
||||
.level_count(1),
|
||||
);
|
||||
|
||||
unsafe {
|
||||
device.cmd_pipeline_barrier(
|
||||
setup_command_buffer,
|
||||
vk::PipelineStageFlags::BOTTOM_OF_PIPE,
|
||||
vk::PipelineStageFlags::LATE_FRAGMENT_TESTS,
|
||||
vk::DependencyFlags::empty(),
|
||||
&[],
|
||||
&[],
|
||||
&[layout_transition_barriers],
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
let depth_image_view_info = vk::ImageViewCreateInfo::default()
|
||||
.subresource_range(
|
||||
vk::ImageSubresourceRange::default()
|
||||
.aspect_mask(vk::ImageAspectFlags::DEPTH)
|
||||
.level_count(1)
|
||||
.layer_count(1),
|
||||
)
|
||||
.image(depth_image)
|
||||
.format(depth_image_create_info.format)
|
||||
.view_type(vk::ImageViewType::TYPE_2D);
|
||||
|
||||
let depth_image_view =
|
||||
unsafe { device.create_image_view(&depth_image_view_info, None) }.unwrap();
|
||||
|
||||
let semaphore_create_info = vk::SemaphoreCreateInfo::default();
|
||||
|
||||
let present_complete_semaphore =
|
||||
unsafe { device.create_semaphore(&semaphore_create_info, None) }.unwrap();
|
||||
let rendering_complete_semaphore =
|
||||
unsafe { device.create_semaphore(&semaphore_create_info, None) }.unwrap();
|
||||
|
||||
Self {
|
||||
scale_factor: factor,
|
||||
entry,
|
||||
instance,
|
||||
device,
|
||||
surface_loader,
|
||||
swapchain_loader,
|
||||
pdevice,
|
||||
device_memory_properties,
|
||||
queue_family_index,
|
||||
present_queue,
|
||||
surface,
|
||||
surface_format,
|
||||
surface_resolution,
|
||||
swapchain,
|
||||
present_images,
|
||||
present_image_views,
|
||||
pool,
|
||||
draw_command_buffer,
|
||||
setup_command_buffer,
|
||||
depth_image,
|
||||
depth_image_view,
|
||||
depth_image_memory,
|
||||
present_complete_semaphore,
|
||||
rendering_complete_semaphore,
|
||||
draw_commands_reuse_fence,
|
||||
setup_commands_reuse_fence,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resize(&mut self, _width: u32, _height: u32, factor: u32, window: &Window) {
|
||||
*self = Self::new(factor, window);
|
||||
}
|
||||
|
||||
pub fn new_frame(&mut self, buffer: &[[u8; 4]]) {}
|
||||
|
||||
pub fn render(&mut self) {}
|
||||
}
|
||||
|
||||
impl Drop for WindowData {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
self.device.device_wait_idle().unwrap();
|
||||
self.device
|
||||
.destroy_semaphore(self.present_complete_semaphore, None);
|
||||
self.device
|
||||
.destroy_semaphore(self.rendering_complete_semaphore, None);
|
||||
self.device
|
||||
.destroy_fence(self.draw_commands_reuse_fence, None);
|
||||
self.device
|
||||
.destroy_fence(self.setup_commands_reuse_fence, None);
|
||||
self.device.free_memory(self.depth_image_memory, None);
|
||||
self.device.destroy_image_view(self.depth_image_view, None);
|
||||
self.device.destroy_image(self.depth_image, None);
|
||||
for &image_view in self.present_image_views.iter() {
|
||||
self.device.destroy_image_view(image_view, None);
|
||||
}
|
||||
self.device.destroy_command_pool(self.pool, None);
|
||||
self.swapchain_loader
|
||||
.destroy_swapchain(self.swapchain, None);
|
||||
self.device.destroy_device(None);
|
||||
self.surface_loader.destroy_surface(self.surface, None);
|
||||
self.instance.destroy_instance(None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn record_submit_commandbuffer<F: FnOnce(&Device, vk::CommandBuffer)>(
|
||||
device: &Device,
|
||||
command_buffer: vk::CommandBuffer,
|
||||
command_buffer_reuse_fence: vk::Fence,
|
||||
submit_queue: vk::Queue,
|
||||
wait_mask: &[vk::PipelineStageFlags],
|
||||
wait_semaphores: &[vk::Semaphore],
|
||||
signal_semaphores: &[vk::Semaphore],
|
||||
f: F,
|
||||
) {
|
||||
|
||||
unsafe {
|
||||
device
|
||||
.wait_for_fences(&[command_buffer_reuse_fence], true, std::u64::MAX)
|
||||
.expect("Wait for fence failed.");
|
||||
|
||||
device
|
||||
.reset_fences(&[command_buffer_reuse_fence])
|
||||
.expect("Reset fences failed.");
|
||||
|
||||
device
|
||||
.reset_command_buffer(
|
||||
command_buffer,
|
||||
vk::CommandBufferResetFlags::RELEASE_RESOURCES,
|
||||
)
|
||||
.expect("Reset command buffer failed.");
|
||||
|
||||
let command_buffer_begin_info = vk::CommandBufferBeginInfo::default()
|
||||
.flags(vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT);
|
||||
|
||||
device
|
||||
.begin_command_buffer(command_buffer, &command_buffer_begin_info)
|
||||
.expect("Begin commandbuffer");
|
||||
f(device, command_buffer);
|
||||
device
|
||||
.end_command_buffer(command_buffer)
|
||||
.expect("End commandbuffer");
|
||||
|
||||
let command_buffers = vec![command_buffer];
|
||||
|
||||
let submit_info = vk::SubmitInfo::default()
|
||||
.wait_semaphores(wait_semaphores)
|
||||
.wait_dst_stage_mask(wait_mask)
|
||||
.command_buffers(&command_buffers)
|
||||
.signal_semaphores(signal_semaphores);
|
||||
|
||||
device
|
||||
.queue_submit(submit_queue, &[submit_info], command_buffer_reuse_fence)
|
||||
.expect("queue submit failed.");
|
||||
}
|
||||
}
|
|
@ -18,7 +18,7 @@ use winit::{
|
|||
use winit_input_helper::WinitInputHelper;
|
||||
|
||||
#[cfg_attr(feature = "pixels", path = "renderer/pixels.rs")]
|
||||
#[cfg_attr(feature = "vulkan", path = "renderer/vulkan.rs")]
|
||||
#[cfg_attr(feature = "vulkan", path = "renderer/vulkan/vulkan.rs")]
|
||||
mod renderer;
|
||||
|
||||
use renderer::WindowData;
|
||||
|
|
Loading…
Add table
Reference in a new issue