vulkan initialisation

This commit is contained in:
Alex Janka 2023-10-01 10:01:17 +11:00
parent 92dc4e3885
commit bd7d03c98b
5 changed files with 613 additions and 9 deletions

134
Cargo.lock generated
View file

@ -187,6 +187,14 @@ version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" 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]] [[package]]
name = "ash" name = "ash"
version = "0.37.3+1.3.251" version = "0.37.3+1.3.251"
@ -196,6 +204,16 @@ dependencies = [
"libloading 0.7.4", "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]] [[package]]
name = "async-ringbuf" name = "async-ringbuf"
version = "0.1.3" version = "0.1.3"
@ -326,6 +344,16 @@ version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" 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]] [[package]]
name = "block-sys" name = "block-sys"
version = "0.1.0-beta.1" version = "0.1.0-beta.1"
@ -351,6 +379,12 @@ version = "3.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
[[package]]
name = "byte-tools"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
[[package]] [[package]]
name = "bytemuck" name = "bytemuck"
version = "1.13.1" version = "1.13.1"
@ -502,6 +536,15 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b"
[[package]]
name = "cmake"
version = "0.1.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130"
dependencies = [
"cc",
]
[[package]] [[package]]
name = "cocoa" name = "cocoa"
version = "0.20.2" version = "0.20.2"
@ -888,6 +931,15 @@ version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f" 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]] [[package]]
name = "dispatch" name = "dispatch"
version = "0.2.0" version = "0.2.0"
@ -948,6 +1000,18 @@ dependencies = [
"libc", "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]] [[package]]
name = "fdeflate" name = "fdeflate"
version = "0.3.0" version = "0.3.0"
@ -1103,7 +1167,8 @@ dependencies = [
name = "gb-emu" name = "gb-emu"
version = "0.3.3" version = "0.3.3"
dependencies = [ dependencies = [
"ash", "ash 0.37.0+1.3.260",
"ash-window",
"bytemuck", "bytemuck",
"clap", "clap",
"cpal", "cpal",
@ -1111,8 +1176,10 @@ dependencies = [
"futures", "futures",
"gb-emu-lib", "gb-emu-lib",
"gilrs", "gilrs",
"glsl-to-spirv",
"nokhwa", "nokhwa",
"pixels", "pixels",
"raw-window-handle",
"send_wrapper", "send_wrapper",
"winit", "winit",
"winit_input_helper", "winit_input_helper",
@ -1133,6 +1200,15 @@ dependencies = [
"serde_with", "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]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.10" version = "0.2.10"
@ -1203,6 +1279,17 @@ dependencies = [
"web-sys", "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]] [[package]]
name = "goblin" name = "goblin"
version = "0.6.1" version = "0.6.1"
@ -2411,6 +2498,18 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" 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]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.3.5" version = "0.3.5"
@ -2673,6 +2772,18 @@ dependencies = [
"syn 2.0.26", "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]] [[package]]
name = "shlex" name = "shlex"
version = "1.1.0" version = "1.1.0"
@ -2787,6 +2898,19 @@ dependencies = [
"unicode-ident", "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]] [[package]]
name = "termcolor" name = "termcolor"
version = "1.2.0" version = "1.2.0"
@ -2920,6 +3044,12 @@ version = "0.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a464a4b34948a5f67fddd2b823c62d9d92e44be75058b99939eae6c5b6960b33" checksum = "a464a4b34948a5f67fddd2b823c62d9d92e44be75058b99939eae6c5b6960b33"
[[package]]
name = "typenum"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]] [[package]]
name = "ultraviolet" name = "ultraviolet"
version = "0.9.1" version = "0.9.1"
@ -3256,7 +3386,7 @@ checksum = "bdcf61a283adc744bb5453dd88ea91f3f86d5ca6b027661c6c73c7734ae0288b"
dependencies = [ dependencies = [
"android_system_properties", "android_system_properties",
"arrayvec", "arrayvec",
"ash", "ash 0.37.3+1.3.251",
"bit-set", "bit-set",
"bitflags 1.3.2", "bitflags 1.3.2",
"block", "block",

View file

@ -4,10 +4,14 @@ version = "0.3.3"
edition = "2021" edition = "2021"
[features] [features]
# default = ["vulkan"] default = ["vulkan"]
default = ["pixels"] pixels = ["dep:pixels", "dep:bytemuck"]
pixels = ["dep:pixels"] vulkan = [
vulkan = ["dep:ash"] "dep:ash",
"dep:ash-window",
"dep:raw-window-handle",
"dep:glsl-to-spirv",
]
camera = ["dep:nokhwa", "dep:send_wrapper"] camera = ["dep:nokhwa", "dep:send_wrapper"]
[dependencies] [dependencies]
@ -23,6 +27,13 @@ nokhwa = { version = "0.10.3", features = [
send_wrapper = { version = "0.6.0", optional = true } send_wrapper = { version = "0.6.0", optional = true }
winit = "0.28" winit = "0.28"
winit_input_helper = "0.14" winit_input_helper = "0.14"
bytemuck = "1.13" bytemuck = { version = "1.13", optional = true }
pixels = { version = "0.12", 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 }

View 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.");
}
}

View file

@ -18,7 +18,7 @@ use winit::{
use winit_input_helper::WinitInputHelper; use winit_input_helper::WinitInputHelper;
#[cfg_attr(feature = "pixels", path = "renderer/pixels.rs")] #[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; mod renderer;
use renderer::WindowData; use renderer::WindowData;