diff --git a/gb-emu/src/renderer/vulkan/vulkan.rs b/gb-emu/src/renderer/vulkan/vulkan.rs index fc6b19c..14a01d3 100644 --- a/gb-emu/src/renderer/vulkan/vulkan.rs +++ b/gb-emu/src/renderer/vulkan/vulkan.rs @@ -14,8 +14,33 @@ use winit::window::Window; // https://github.com/ash-rs/ash/blob/master/examples/src/bin/texture.rs const SHADER: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/shaders/shader.spv")); +const VERTICES: [Vertex; 3] = [Vertex(-1.0, -1.0), Vertex(3.0, -1.0), Vertex(-1.0, 3.0)]; pub struct WindowData { + inner: VulkanWindowInner, +} + +impl WindowData { + pub fn new(factor: u32, window: &Window) -> Self { + Self { + inner: unsafe { VulkanWindowInner::new(factor, window) }, + } + } + + pub fn resize(&mut self, width: u32, height: u32, factor: u32, window: &Window) { + self.inner.resize(width, height, factor, window); + } + + pub fn new_frame(&mut self, buffer: &[[u8; 4]]) { + self.inner.new_frame(buffer); + } + + pub fn render(&mut self) { + self.inner.render(); + } +} + +struct VulkanWindowInner { instance: Instance, device: Device, surface_loader: Surface, @@ -31,10 +56,6 @@ pub struct WindowData { 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, @@ -49,13 +70,9 @@ pub struct WindowData { graphics_pipelines: Vec, viewports: [vk::Viewport; 1], scissors: [vk::Rect2D; 1], - index_buffer: vk::Buffer, - index_buffer_data: [u32; 6], - shader_module: vk::ShaderModule, vertex_input_buffer_memory: vk::DeviceMemory, texture_memory: vk::DeviceMemory, - index_buffer_memory: vk::DeviceMemory, tex_image_view: vk::ImageView, desc_set_layouts: [vk::DescriptorSetLayout; 1], descriptor_pool: vk::DescriptorPool, @@ -68,8 +85,8 @@ pub struct WindowData { texture_image: vk::Image, } -impl WindowData { - pub unsafe fn new(factor: u32, window: &Window) -> Self { +impl VulkanWindowInner { + unsafe fn new(factor: u32, window: &Window) -> Self { let entry = Entry::linked(); let name = std::ffi::CString::new("gameboy").unwrap(); @@ -265,42 +282,6 @@ impl WindowData { }) .collect(); let device_memory_properties = 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 = device.create_image(&depth_image_create_info, None).unwrap(); - let depth_image_memory_req = 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 = device - .allocate_memory(&depth_image_allocate_info, None) - .unwrap(); - - 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); @@ -312,57 +293,6 @@ impl WindowData { .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), - ); - - 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 = device - .create_image_view(&depth_image_view_info, None) - .unwrap(); - let semaphore_create_info = vk::SemaphoreCreateInfo::default(); let present_complete_semaphore = device @@ -372,32 +302,18 @@ impl WindowData { .create_semaphore(&semaphore_create_info, None) .unwrap(); - let renderpass_attachments = [ - vk::AttachmentDescription { - format: surface_format.format, - samples: vk::SampleCountFlags::TYPE_1, - load_op: vk::AttachmentLoadOp::CLEAR, - store_op: vk::AttachmentStoreOp::STORE, - final_layout: vk::ImageLayout::PRESENT_SRC_KHR, - ..Default::default() - }, - vk::AttachmentDescription { - format: vk::Format::D16_UNORM, - samples: vk::SampleCountFlags::TYPE_1, - load_op: vk::AttachmentLoadOp::CLEAR, - initial_layout: vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - final_layout: vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - ..Default::default() - }, - ]; + let renderpass_attachments = [vk::AttachmentDescription { + format: surface_format.format, + samples: vk::SampleCountFlags::TYPE_1, + load_op: vk::AttachmentLoadOp::CLEAR, + store_op: vk::AttachmentStoreOp::STORE, + final_layout: vk::ImageLayout::PRESENT_SRC_KHR, + ..Default::default() + }]; let color_attachment_refs = [vk::AttachmentReference { attachment: 0, layout: vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL, }]; - let depth_attachment_ref = vk::AttachmentReference { - attachment: 1, - layout: vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - }; let dependencies = [vk::SubpassDependency { src_subpass: vk::SUBPASS_EXTERNAL, src_stage_mask: vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT, @@ -409,7 +325,6 @@ impl WindowData { let subpass = vk::SubpassDescription::default() .color_attachments(&color_attachment_refs) - .depth_stencil_attachment(&depth_attachment_ref) .pipeline_bind_point(vk::PipelineBindPoint::GRAPHICS); let renderpass_create_info = vk::RenderPassCreateInfo::default() @@ -424,7 +339,7 @@ impl WindowData { let framebuffers: Vec = present_image_views .iter() .map(|&present_image_view| { - let framebuffer_attachments = [present_image_view, depth_image_view]; + let framebuffer_attachments = [present_image_view]; let frame_buffer_create_info = vk::FramebufferCreateInfo::default() .render_pass(renderpass) .attachments(&framebuffer_attachments) @@ -437,49 +352,9 @@ impl WindowData { .unwrap() }) .collect(); - let index_buffer_data = [0u32, 1, 2, 2, 3, 0]; - let index_buffer_info = vk::BufferCreateInfo { - size: std::mem::size_of_val(&index_buffer_data) as u64, - usage: vk::BufferUsageFlags::INDEX_BUFFER, - sharing_mode: vk::SharingMode::EXCLUSIVE, - ..Default::default() - }; - let index_buffer = device.create_buffer(&index_buffer_info, None).unwrap(); - let index_buffer_memory_req = device.get_buffer_memory_requirements(index_buffer); - let index_buffer_memory_index = find_memorytype_index( - &index_buffer_memory_req, - &device_memory_properties, - vk::MemoryPropertyFlags::HOST_VISIBLE | vk::MemoryPropertyFlags::HOST_COHERENT, - ) - .expect("Unable to find suitable memorytype for the index buffer."); - let index_allocate_info = vk::MemoryAllocateInfo { - allocation_size: index_buffer_memory_req.size, - memory_type_index: index_buffer_memory_index, - ..Default::default() - }; - let index_buffer_memory = device.allocate_memory(&index_allocate_info, None).unwrap(); - let index_ptr: *mut std::ffi::c_void = device - .map_memory( - index_buffer_memory, - 0, - index_buffer_memory_req.size, - vk::MemoryMapFlags::empty(), - ) - .unwrap(); - let mut index_slice = Align::new( - index_ptr, - std::mem::align_of::() as u64, - index_buffer_memory_req.size, - ); - index_slice.copy_from_slice(&index_buffer_data); - device.unmap_memory(index_buffer_memory); - device - .bind_buffer_memory(index_buffer, index_buffer_memory, 0) - .unwrap(); - let vertices: [Vertex; 3] = [Vertex(-1.0, -1.0), Vertex(3.0, -1.0), Vertex(-1.0, 3.0)]; let vertex_input_buffer_info = vk::BufferCreateInfo { - size: std::mem::size_of_val(&vertices) as u64, + size: std::mem::size_of_val(&VERTICES) as u64, usage: vk::BufferUsageFlags::VERTEX_BUFFER, sharing_mode: vk::SharingMode::EXCLUSIVE, ..Default::default() @@ -518,7 +393,7 @@ impl WindowData { std::mem::align_of::() as u64, vertex_input_buffer_memory_req.size, ); - slice.copy_from_slice(&vertices); + slice.copy_from_slice(&VERTICES); device.unmap_memory(vertex_input_buffer_memory); device .bind_buffer_memory(vertex_input_buffer, vertex_input_buffer_memory, 0) @@ -838,23 +713,6 @@ impl WindowData { let multisample_state_info = vk::PipelineMultisampleStateCreateInfo::default() .rasterization_samples(vk::SampleCountFlags::TYPE_1); - let noop_stencil_state = vk::StencilOpState { - fail_op: vk::StencilOp::KEEP, - pass_op: vk::StencilOp::KEEP, - depth_fail_op: vk::StencilOp::KEEP, - compare_op: vk::CompareOp::ALWAYS, - ..Default::default() - }; - let depth_state_info = vk::PipelineDepthStencilStateCreateInfo { - depth_test_enable: 1, - depth_write_enable: 1, - depth_compare_op: vk::CompareOp::LESS_OR_EQUAL, - front: noop_stencil_state, - back: noop_stencil_state, - max_depth_bounds: 1.0, - ..Default::default() - }; - let color_blend_attachment_states = [vk::PipelineColorBlendAttachmentState { blend_enable: 0, src_color_blend_factor: vk::BlendFactor::SRC_COLOR, @@ -880,7 +738,6 @@ impl WindowData { .viewport_state(&viewport_state_info) .rasterization_state(&rasterization_info) .multisample_state(&multisample_state_info) - .depth_stencil_state(&depth_state_info) .color_blend_state(&color_blend_state) .dynamic_state(&dynamic_state_info) .layout(pipeline_layout) @@ -903,9 +760,6 @@ impl WindowData { 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, @@ -918,12 +772,9 @@ impl WindowData { graphics_pipelines, viewports, scissors, - index_buffer, - index_buffer_data, shader_module, vertex_input_buffer_memory, texture_memory, - index_buffer_memory, tex_image_view, desc_set_layouts, descriptor_pool, @@ -936,11 +787,11 @@ impl WindowData { } } - pub fn resize(&mut self, _width: u32, _height: u32, factor: u32, window: &Window) { + fn resize(&mut self, _width: u32, _height: u32, factor: u32, window: &Window) { *self = unsafe { Self::new(factor, window) }; } - pub fn new_frame(&mut self, buffer: &[[u8; 4]]) { + fn new_frame(&mut self, buffer: &[[u8; 4]]) { unsafe { let image_ptr = self .device @@ -1037,7 +888,7 @@ impl WindowData { } } - pub fn render(&mut self) { + fn render(&mut self) { unsafe { let (present_index, _) = self .swapchain_loader @@ -1048,19 +899,11 @@ impl WindowData { vk::Fence::null(), ) .unwrap(); - let clear_values = [ - vk::ClearValue { - color: vk::ClearColorValue { - float32: [0.0, 0.0, 0.0, 0.0], - }, + let clear_values = [vk::ClearValue { + color: vk::ClearColorValue { + float32: [0.0, 0.0, 0.0, 0.0], }, - vk::ClearValue { - depth_stencil: vk::ClearDepthStencilValue { - depth: 1.0, - stencil: 0, - }, - }, - ]; + }]; let render_pass_begin_info = vk::RenderPassBeginInfo::default() .render_pass(self.renderpass) @@ -1103,20 +946,7 @@ impl WindowData { &[self.vertex_input_buffer], &[0], ); - device.cmd_bind_index_buffer( - draw_command_buffer, - self.index_buffer, - 0, - vk::IndexType::UINT32, - ); - device.cmd_draw_indexed( - draw_command_buffer, - self.index_buffer_data.len() as u32, - 1, - 0, - 0, - 1, - ); + device.cmd_draw(draw_command_buffer, VERTICES.len() as u32, 1, 0, 1); device.cmd_end_render_pass(draw_command_buffer); }, ); @@ -1135,7 +965,7 @@ impl WindowData { } } -impl Drop for WindowData { +impl Drop for VulkanWindowInner { fn drop(&mut self) { unsafe { self.device.device_wait_idle().unwrap(); @@ -1151,8 +981,6 @@ impl Drop for WindowData { self.device.free_memory(self.texture_memory, None); self.device.destroy_image_view(self.tex_image_view, None); self.device.destroy_image(self.texture_image, None); - self.device.free_memory(self.index_buffer_memory, None); - self.device.destroy_buffer(self.index_buffer, None); self.device .free_memory(self.vertex_input_buffer_memory, None); self.device.destroy_buffer(self.vertex_input_buffer, None); @@ -1176,9 +1004,7 @@ impl Drop for WindowData { .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); } diff --git a/gb-emu/src/window.rs b/gb-emu/src/window.rs index e14d797..c465bd8 100644 --- a/gb-emu/src/window.rs +++ b/gb-emu/src/window.rs @@ -114,9 +114,7 @@ impl WindowRenderer { let real_factor = (window.scale_factor() * factor as f64) as usize; - let data = Arc::new(Mutex::new(unsafe { - WindowData::new(real_factor as u32, &window) - })); + let data = Arc::new(Mutex::new(WindowData::new(real_factor as u32, &window))); let info = WindowInfo { id: window.id(), data: data.clone(),