|  |  |  | @ -13,6 +13,8 @@ use std::ffi::CString; | 
			
		
	
		
			
				
					|  |  |  |  | use raw_window_handle::HasDisplayHandle; | 
			
		
	
		
			
				
					|  |  |  |  | use raw_window_handle::HasWindowHandle; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | use sdl2::event::Event; | 
			
		
	
		
			
				
					|  |  |  |  | use sdl2::keyboard::Keycode; | 
			
		
	
		
			
				
					|  |  |  |  | use sdl2::video::Window; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | const APP_NAME: &str = "MineClone"; | 
			
		
	
	
		
			
				
					|  |  |  | @ -411,10 +413,10 @@ fn setup_pipe_layout(dev: &Device) -> vk::PipelineLayout { | 
			
		
	
		
			
				
					|  |  |  |  |         vk::PushConstantRange::default() | 
			
		
	
		
			
				
					|  |  |  |  |             .stage_flags(vk::ShaderStageFlags::VERTEX) | 
			
		
	
		
			
				
					|  |  |  |  |             .offset(0) | 
			
		
	
		
			
				
					|  |  |  |  |             .size(32), // vec4 camera_orig, camera_rot
 | 
			
		
	
		
			
				
					|  |  |  |  |             .size(48), // vec4 camera_orig, camera_rot
 | 
			
		
	
		
			
				
					|  |  |  |  |         vk::PushConstantRange::default() | 
			
		
	
		
			
				
					|  |  |  |  |             .stage_flags(vk::ShaderStageFlags::FRAGMENT) | 
			
		
	
		
			
				
					|  |  |  |  |             .offset(32) | 
			
		
	
		
			
				
					|  |  |  |  |             .offset(48) | 
			
		
	
		
			
				
					|  |  |  |  |             .size(16), // vec4 base_color
 | 
			
		
	
		
			
				
					|  |  |  |  |     ]; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -450,9 +452,9 @@ fn setup_pipeline( | 
			
		
	
		
			
				
					|  |  |  |  |     dev: &Device, | 
			
		
	
		
			
				
					|  |  |  |  |     vert_shader: &vk::ShaderModule, | 
			
		
	
		
			
				
					|  |  |  |  |     frag_shader: &vk::ShaderModule, | 
			
		
	
		
			
				
					|  |  |  |  |     pass: &vk::RenderPass, | 
			
		
	
		
			
				
					|  |  |  |  |     pipe_layout: &vk::PipelineLayout, | 
			
		
	
		
			
				
					|  |  |  |  | ) -> 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() | 
			
		
	
	
		
			
				
					|  |  |  | @ -508,9 +510,9 @@ fn setup_pipeline( | 
			
		
	
		
			
				
					|  |  |  |  |         .multisample_state(&multisample) | 
			
		
	
		
			
				
					|  |  |  |  |         .depth_stencil_state(&depth_stencil) | 
			
		
	
		
			
				
					|  |  |  |  |         .color_blend_state(&color_blend) | 
			
		
	
		
			
				
					|  |  |  |  |         .layout(pipe_layout) | 
			
		
	
		
			
				
					|  |  |  |  |         .layout(*pipe_layout) | 
			
		
	
		
			
				
					|  |  |  |  |         .dynamic_state(&dynamic) | 
			
		
	
		
			
				
					|  |  |  |  |         .render_pass(pass) | 
			
		
	
		
			
				
					|  |  |  |  |         .render_pass(*pass) | 
			
		
	
		
			
				
					|  |  |  |  |         .subpass(0); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     let pipe = unsafe { | 
			
		
	
	
		
			
				
					|  |  |  | @ -633,6 +635,355 @@ fn make_swap_views( | 
			
		
	
		
			
				
					|  |  |  |  |     views | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | fn make_depth_view(dev: &Device, depth_img: &vk::Image, format: vk::Format) -> vk::ImageView { | 
			
		
	
		
			
				
					|  |  |  |  |     let view_info = vk::ImageViewCreateInfo::default() | 
			
		
	
		
			
				
					|  |  |  |  |         .image(*depth_img) | 
			
		
	
		
			
				
					|  |  |  |  |         .view_type(vk::ImageViewType::TYPE_2D) | 
			
		
	
		
			
				
					|  |  |  |  |         .format(format) | 
			
		
	
		
			
				
					|  |  |  |  |         .components(vk::ComponentMapping::default()) | 
			
		
	
		
			
				
					|  |  |  |  |         .subresource_range( | 
			
		
	
		
			
				
					|  |  |  |  |             vk::ImageSubresourceRange::default() | 
			
		
	
		
			
				
					|  |  |  |  |                 .aspect_mask(vk::ImageAspectFlags::DEPTH) | 
			
		
	
		
			
				
					|  |  |  |  |                 .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") | 
			
		
	
		
			
				
					|  |  |  |  |     }; | 
			
		
	
		
			
				
					|  |  |  |  |     view | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | fn make_framebufs( | 
			
		
	
		
			
				
					|  |  |  |  |     dev: &Device, | 
			
		
	
		
			
				
					|  |  |  |  |     swap_views: &Vec<vk::ImageView>, | 
			
		
	
		
			
				
					|  |  |  |  |     depth_view: &vk::ImageView, | 
			
		
	
		
			
				
					|  |  |  |  |     pass: &vk::RenderPass, | 
			
		
	
		
			
				
					|  |  |  |  |     width: u32, | 
			
		
	
		
			
				
					|  |  |  |  |     height: u32, | 
			
		
	
		
			
				
					|  |  |  |  | ) -> Vec<vk::Framebuffer> { | 
			
		
	
		
			
				
					|  |  |  |  |     let mut framebufs = Vec::new(); | 
			
		
	
		
			
				
					|  |  |  |  |     for view in swap_views.iter() { | 
			
		
	
		
			
				
					|  |  |  |  |         let attachments = [*view, *depth_view]; | 
			
		
	
		
			
				
					|  |  |  |  |         let framebuf_info = vk::FramebufferCreateInfo::default() | 
			
		
	
		
			
				
					|  |  |  |  |             .render_pass(*pass) | 
			
		
	
		
			
				
					|  |  |  |  |             .attachments(attachments.as_ref()) | 
			
		
	
		
			
				
					|  |  |  |  |             .width(width) | 
			
		
	
		
			
				
					|  |  |  |  |             .height(height) | 
			
		
	
		
			
				
					|  |  |  |  |             .layers(1); | 
			
		
	
		
			
				
					|  |  |  |  |         let framebuf = unsafe { | 
			
		
	
		
			
				
					|  |  |  |  |             dev.create_framebuffer(&framebuf_info, None) | 
			
		
	
		
			
				
					|  |  |  |  |                 .expect("Failed to create framebuffer") | 
			
		
	
		
			
				
					|  |  |  |  |         }; | 
			
		
	
		
			
				
					|  |  |  |  |         framebufs.push(framebuf); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     framebufs | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | fn make_desc_sets(dev: &Device, desc_pool: &vk::DescriptorPool) -> Vec<vk::DescriptorSet> { | 
			
		
	
		
			
				
					|  |  |  |  |     let layout = setup_desc_layout(&dev); | 
			
		
	
		
			
				
					|  |  |  |  |     let layouts = [layout]; | 
			
		
	
		
			
				
					|  |  |  |  |     let alloc_info = vk::DescriptorSetAllocateInfo::default() | 
			
		
	
		
			
				
					|  |  |  |  |         .descriptor_pool(*desc_pool) | 
			
		
	
		
			
				
					|  |  |  |  |         .set_layouts(&layouts); | 
			
		
	
		
			
				
					|  |  |  |  |     let sets = unsafe { | 
			
		
	
		
			
				
					|  |  |  |  |         dev.allocate_descriptor_sets(&alloc_info) | 
			
		
	
		
			
				
					|  |  |  |  |             .expect("Failed to allocate descriptor sets") | 
			
		
	
		
			
				
					|  |  |  |  |     }; | 
			
		
	
		
			
				
					|  |  |  |  |     sets | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | fn write_desc_sets(dev: &Device, desc_sets: &Vec<vk::DescriptorSet>, mesh_buf: &vk::Buffer) { | 
			
		
	
		
			
				
					|  |  |  |  |     let buf_info = vk::DescriptorBufferInfo::default() | 
			
		
	
		
			
				
					|  |  |  |  |         .buffer(*mesh_buf) | 
			
		
	
		
			
				
					|  |  |  |  |         .offset(0) | 
			
		
	
		
			
				
					|  |  |  |  |         .range(vk::WHOLE_SIZE); | 
			
		
	
		
			
				
					|  |  |  |  |     let buf_infos = [buf_info]; | 
			
		
	
		
			
				
					|  |  |  |  |     let buf_desc = vk::WriteDescriptorSet::default() | 
			
		
	
		
			
				
					|  |  |  |  |         .dst_set(desc_sets[0]) | 
			
		
	
		
			
				
					|  |  |  |  |         .dst_binding(0) | 
			
		
	
		
			
				
					|  |  |  |  |         .dst_array_element(0) | 
			
		
	
		
			
				
					|  |  |  |  |         .descriptor_type(vk::DescriptorType::STORAGE_BUFFER) | 
			
		
	
		
			
				
					|  |  |  |  |         .buffer_info(&buf_infos); | 
			
		
	
		
			
				
					|  |  |  |  |     unsafe { | 
			
		
	
		
			
				
					|  |  |  |  |         dev.update_descriptor_sets(&[buf_desc], &[]); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | fn make_sem(dev: &Device) -> vk::Semaphore { | 
			
		
	
		
			
				
					|  |  |  |  |     let sem_info = vk::SemaphoreCreateInfo::default(); | 
			
		
	
		
			
				
					|  |  |  |  |     let sem = unsafe { | 
			
		
	
		
			
				
					|  |  |  |  |         dev.create_semaphore(&sem_info, None) | 
			
		
	
		
			
				
					|  |  |  |  |             .expect("Failed to create semaphore") | 
			
		
	
		
			
				
					|  |  |  |  |     }; | 
			
		
	
		
			
				
					|  |  |  |  |     sem | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | fn make_fence(dev: &Device) -> vk::Fence { | 
			
		
	
		
			
				
					|  |  |  |  |     let fence_info = vk::FenceCreateInfo::default().flags(vk::FenceCreateFlags::SIGNALED); | 
			
		
	
		
			
				
					|  |  |  |  |     let fence = unsafe { | 
			
		
	
		
			
				
					|  |  |  |  |         dev.create_fence(&fence_info, None) | 
			
		
	
		
			
				
					|  |  |  |  |             .expect("Failed to create fence") | 
			
		
	
		
			
				
					|  |  |  |  |     }; | 
			
		
	
		
			
				
					|  |  |  |  |     fence | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | fn wait_for_fence(dev: &Device, fence: &vk::Fence) { | 
			
		
	
		
			
				
					|  |  |  |  |     unsafe { | 
			
		
	
		
			
				
					|  |  |  |  |         let fence = [*fence]; | 
			
		
	
		
			
				
					|  |  |  |  |         dev.wait_for_fences(&fence, true, u64::MAX) | 
			
		
	
		
			
				
					|  |  |  |  |             .expect("Failed to wait for fence"); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | fn reset_fence(dev: &Device, fence: &vk::Fence) { | 
			
		
	
		
			
				
					|  |  |  |  |     unsafe { | 
			
		
	
		
			
				
					|  |  |  |  |         let fence = [*fence]; | 
			
		
	
		
			
				
					|  |  |  |  |         dev.reset_fences(&fence).expect("Failed to reset fence"); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | fn ack_next_img( | 
			
		
	
		
			
				
					|  |  |  |  |     dev: &Device, | 
			
		
	
		
			
				
					|  |  |  |  |     swapchain_loader: &swapchain::Device, | 
			
		
	
		
			
				
					|  |  |  |  |     swapchain: &vk::SwapchainKHR, | 
			
		
	
		
			
				
					|  |  |  |  |     sem_avail: &vk::Semaphore, | 
			
		
	
		
			
				
					|  |  |  |  |     fence: &vk::Fence, | 
			
		
	
		
			
				
					|  |  |  |  | ) -> u32 { | 
			
		
	
		
			
				
					|  |  |  |  |     unsafe { | 
			
		
	
		
			
				
					|  |  |  |  |         let (img_inx, _) = swapchain_loader | 
			
		
	
		
			
				
					|  |  |  |  |             .acquire_next_image(*swapchain, u64::MAX, *sem_avail, vk::Fence::null()) | 
			
		
	
		
			
				
					|  |  |  |  |             .expect("Failed to acquire next image"); | 
			
		
	
		
			
				
					|  |  |  |  |         img_inx | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | fn record_commands( | 
			
		
	
		
			
				
					|  |  |  |  |     dev: &Device, | 
			
		
	
		
			
				
					|  |  |  |  |     cmd_buf: &vk::CommandBuffer, | 
			
		
	
		
			
				
					|  |  |  |  |     framebuf: &vk::Framebuffer, | 
			
		
	
		
			
				
					|  |  |  |  |     pass: &vk::RenderPass, | 
			
		
	
		
			
				
					|  |  |  |  |     layout: &vk::PipelineLayout, | 
			
		
	
		
			
				
					|  |  |  |  |     width: u32, | 
			
		
	
		
			
				
					|  |  |  |  |     height: u32, | 
			
		
	
		
			
				
					|  |  |  |  |     pipe: &vk::Pipeline, | 
			
		
	
		
			
				
					|  |  |  |  |     desc_sets: &Vec<vk::DescriptorSet>, | 
			
		
	
		
			
				
					|  |  |  |  |     camera: &Camera, | 
			
		
	
		
			
				
					|  |  |  |  | ) { | 
			
		
	
		
			
				
					|  |  |  |  |     let clear_vals = [ | 
			
		
	
		
			
				
					|  |  |  |  |         vk::ClearValue { | 
			
		
	
		
			
				
					|  |  |  |  |             color: vk::ClearColorValue { | 
			
		
	
		
			
				
					|  |  |  |  |                 float32: [0.0, 0.0, 0.0, 1.0], | 
			
		
	
		
			
				
					|  |  |  |  |             }, | 
			
		
	
		
			
				
					|  |  |  |  |         }, | 
			
		
	
		
			
				
					|  |  |  |  |         vk::ClearValue { | 
			
		
	
		
			
				
					|  |  |  |  |             depth_stencil: vk::ClearDepthStencilValue { | 
			
		
	
		
			
				
					|  |  |  |  |                 depth: 1.0, | 
			
		
	
		
			
				
					|  |  |  |  |                 stencil: 0, | 
			
		
	
		
			
				
					|  |  |  |  |             }, | 
			
		
	
		
			
				
					|  |  |  |  |         }, | 
			
		
	
		
			
				
					|  |  |  |  |     ]; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     let render_pass_info = vk::RenderPassBeginInfo::default() | 
			
		
	
		
			
				
					|  |  |  |  |         .render_pass(*pass) | 
			
		
	
		
			
				
					|  |  |  |  |         .framebuffer(*framebuf) | 
			
		
	
		
			
				
					|  |  |  |  |         .render_area( | 
			
		
	
		
			
				
					|  |  |  |  |             vk::Rect2D::default() | 
			
		
	
		
			
				
					|  |  |  |  |                 .offset(vk::Offset2D::default()) | 
			
		
	
		
			
				
					|  |  |  |  |                 .extent(vk::Extent2D { width, height }), | 
			
		
	
		
			
				
					|  |  |  |  |         ) | 
			
		
	
		
			
				
					|  |  |  |  |         .clear_values(&clear_vals); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     unsafe { | 
			
		
	
		
			
				
					|  |  |  |  |         dev.cmd_begin_render_pass(*cmd_buf, &render_pass_info, vk::SubpassContents::INLINE); | 
			
		
	
		
			
				
					|  |  |  |  |         dev.cmd_bind_pipeline(*cmd_buf, vk::PipelineBindPoint::GRAPHICS, *pipe); | 
			
		
	
		
			
				
					|  |  |  |  |         dev.cmd_bind_descriptor_sets( | 
			
		
	
		
			
				
					|  |  |  |  |             *cmd_buf, | 
			
		
	
		
			
				
					|  |  |  |  |             vk::PipelineBindPoint::GRAPHICS, | 
			
		
	
		
			
				
					|  |  |  |  |             *layout, | 
			
		
	
		
			
				
					|  |  |  |  |             0, | 
			
		
	
		
			
				
					|  |  |  |  |             desc_sets.as_ref(), | 
			
		
	
		
			
				
					|  |  |  |  |             &[], | 
			
		
	
		
			
				
					|  |  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |  |         dev.cmd_set_viewport_with_count( | 
			
		
	
		
			
				
					|  |  |  |  |             *cmd_buf, | 
			
		
	
		
			
				
					|  |  |  |  |             &[vk::Viewport::default() | 
			
		
	
		
			
				
					|  |  |  |  |                 .width(width as f32) | 
			
		
	
		
			
				
					|  |  |  |  |                 .height(height as f32)], | 
			
		
	
		
			
				
					|  |  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |  |         dev.cmd_set_scissor_with_count( | 
			
		
	
		
			
				
					|  |  |  |  |             *cmd_buf, | 
			
		
	
		
			
				
					|  |  |  |  |             &[vk::Rect2D::default().extent(vk::Extent2D { width, height })], | 
			
		
	
		
			
				
					|  |  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |  |         let cam_data: Vec<u8> = (Vec::<f32>::from([ | 
			
		
	
		
			
				
					|  |  |  |  |             camera.origin.x, | 
			
		
	
		
			
				
					|  |  |  |  |             camera.origin.y, | 
			
		
	
		
			
				
					|  |  |  |  |             camera.origin.z, | 
			
		
	
		
			
				
					|  |  |  |  |             0.0, | 
			
		
	
		
			
				
					|  |  |  |  |             camera.rotation.x, | 
			
		
	
		
			
				
					|  |  |  |  |             camera.rotation.y, | 
			
		
	
		
			
				
					|  |  |  |  |             camera.rotation.z, | 
			
		
	
		
			
				
					|  |  |  |  |         ])) | 
			
		
	
		
			
				
					|  |  |  |  |         .iter() | 
			
		
	
		
			
				
					|  |  |  |  |         .map(|f| f.to_ne_bytes()) | 
			
		
	
		
			
				
					|  |  |  |  |         .collect::<Vec<_>>() | 
			
		
	
		
			
				
					|  |  |  |  |         .into_flattened(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         let screen_res: Vec<u8> = (Vec::<u32>::from([width, height])) | 
			
		
	
		
			
				
					|  |  |  |  |             .iter() | 
			
		
	
		
			
				
					|  |  |  |  |             .map(|f| f.to_ne_bytes()) | 
			
		
	
		
			
				
					|  |  |  |  |             .collect::<Vec<_>>() | 
			
		
	
		
			
				
					|  |  |  |  |             .into_flattened(); | 
			
		
	
		
			
				
					|  |  |  |  |         let base_color: Vec<u8> = (Vec::<f32>::from([0.0, 1.0, 1.0, 1.0])) | 
			
		
	
		
			
				
					|  |  |  |  |             .iter() | 
			
		
	
		
			
				
					|  |  |  |  |             .map(|f| f.to_ne_bytes()) | 
			
		
	
		
			
				
					|  |  |  |  |             .collect::<Vec<_>>() | 
			
		
	
		
			
				
					|  |  |  |  |             .into_flattened(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         dev.cmd_push_constants( | 
			
		
	
		
			
				
					|  |  |  |  |             *cmd_buf, | 
			
		
	
		
			
				
					|  |  |  |  |             *layout, | 
			
		
	
		
			
				
					|  |  |  |  |             vk::ShaderStageFlags::VERTEX, | 
			
		
	
		
			
				
					|  |  |  |  |             0, | 
			
		
	
		
			
				
					|  |  |  |  |             cam_data.as_ref(), | 
			
		
	
		
			
				
					|  |  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |  |         dev.cmd_push_constants( | 
			
		
	
		
			
				
					|  |  |  |  |             *cmd_buf, | 
			
		
	
		
			
				
					|  |  |  |  |             *layout, | 
			
		
	
		
			
				
					|  |  |  |  |             vk::ShaderStageFlags::VERTEX, | 
			
		
	
		
			
				
					|  |  |  |  |             32, | 
			
		
	
		
			
				
					|  |  |  |  |             screen_res.as_ref(), | 
			
		
	
		
			
				
					|  |  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |  |         dev.cmd_push_constants( | 
			
		
	
		
			
				
					|  |  |  |  |             *cmd_buf, | 
			
		
	
		
			
				
					|  |  |  |  |             *layout, | 
			
		
	
		
			
				
					|  |  |  |  |             vk::ShaderStageFlags::FRAGMENT, | 
			
		
	
		
			
				
					|  |  |  |  |             48, | 
			
		
	
		
			
				
					|  |  |  |  |             base_color.as_ref(), | 
			
		
	
		
			
				
					|  |  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |  |         dev.cmd_draw(*cmd_buf, 36, 1, 0, 0); | 
			
		
	
		
			
				
					|  |  |  |  |         dev.cmd_end_render_pass(*cmd_buf); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | fn start_cmd_buf(dev: &Device, cmd_buf: &vk::CommandBuffer) { | 
			
		
	
		
			
				
					|  |  |  |  |     unsafe { | 
			
		
	
		
			
				
					|  |  |  |  |         dev.reset_command_buffer(*cmd_buf, vk::CommandBufferResetFlags::empty()) | 
			
		
	
		
			
				
					|  |  |  |  |             .expect("Failed to reset command buffer"); | 
			
		
	
		
			
				
					|  |  |  |  |         let begin_info = | 
			
		
	
		
			
				
					|  |  |  |  |             vk::CommandBufferBeginInfo::default().flags(vk::CommandBufferUsageFlags::empty()); | 
			
		
	
		
			
				
					|  |  |  |  |         dev.begin_command_buffer(*cmd_buf, &begin_info) | 
			
		
	
		
			
				
					|  |  |  |  |             .expect("Failed to begin command buffer"); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | fn end_cmd_buf(dev: &Device, cmd_buf: &vk::CommandBuffer) { | 
			
		
	
		
			
				
					|  |  |  |  |     unsafe { | 
			
		
	
		
			
				
					|  |  |  |  |         dev.end_command_buffer(*cmd_buf) | 
			
		
	
		
			
				
					|  |  |  |  |             .expect("Failed to end command buffer"); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | fn submit_queue( | 
			
		
	
		
			
				
					|  |  |  |  |     dev: &Device, | 
			
		
	
		
			
				
					|  |  |  |  |     queue: &vk::Queue, | 
			
		
	
		
			
				
					|  |  |  |  |     cmd_buf: &vk::CommandBuffer, | 
			
		
	
		
			
				
					|  |  |  |  |     sem_avail: &vk::Semaphore, | 
			
		
	
		
			
				
					|  |  |  |  |     sem_finish: &vk::Semaphore, | 
			
		
	
		
			
				
					|  |  |  |  |     fence: &vk::Fence, | 
			
		
	
		
			
				
					|  |  |  |  | ) { | 
			
		
	
		
			
				
					|  |  |  |  |     let cmd_bufs = [*cmd_buf]; | 
			
		
	
		
			
				
					|  |  |  |  |     let wait_sems = [*sem_avail]; | 
			
		
	
		
			
				
					|  |  |  |  |     let signal_sems = [*sem_finish]; | 
			
		
	
		
			
				
					|  |  |  |  |     let submit_info = vk::SubmitInfo::default() | 
			
		
	
		
			
				
					|  |  |  |  |         .command_buffers(&cmd_bufs) | 
			
		
	
		
			
				
					|  |  |  |  |         .wait_semaphores(&wait_sems) | 
			
		
	
		
			
				
					|  |  |  |  |         .wait_dst_stage_mask(&[vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT]) | 
			
		
	
		
			
				
					|  |  |  |  |         .signal_semaphores(&signal_sems); | 
			
		
	
		
			
				
					|  |  |  |  |     unsafe { | 
			
		
	
		
			
				
					|  |  |  |  |         dev.queue_submit(*queue, &[submit_info], *fence) | 
			
		
	
		
			
				
					|  |  |  |  |             .expect("Failed to submit queue"); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | fn queue_present( | 
			
		
	
		
			
				
					|  |  |  |  |     swapchain_loader: &swapchain::Device, | 
			
		
	
		
			
				
					|  |  |  |  |     queue: &vk::Queue, | 
			
		
	
		
			
				
					|  |  |  |  |     swapchain: &vk::SwapchainKHR, | 
			
		
	
		
			
				
					|  |  |  |  |     img_inx: u32, | 
			
		
	
		
			
				
					|  |  |  |  |     sem_finish: &vk::Semaphore, | 
			
		
	
		
			
				
					|  |  |  |  | ) { | 
			
		
	
		
			
				
					|  |  |  |  |     let swapchains = [*swapchain]; | 
			
		
	
		
			
				
					|  |  |  |  |     let img_inxs = [img_inx]; | 
			
		
	
		
			
				
					|  |  |  |  |     let wait_sems = [*sem_finish]; | 
			
		
	
		
			
				
					|  |  |  |  |     let present_info = vk::PresentInfoKHR::default() | 
			
		
	
		
			
				
					|  |  |  |  |         .swapchains(&swapchains) | 
			
		
	
		
			
				
					|  |  |  |  |         .image_indices(&img_inxs) | 
			
		
	
		
			
				
					|  |  |  |  |         .wait_semaphores(&wait_sems); | 
			
		
	
		
			
				
					|  |  |  |  |     unsafe { | 
			
		
	
		
			
				
					|  |  |  |  |         swapchain_loader | 
			
		
	
		
			
				
					|  |  |  |  |             .queue_present(*queue, &present_info) | 
			
		
	
		
			
				
					|  |  |  |  |             .expect("Failed to present queue"); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #[derive(Debug)] | 
			
		
	
		
			
				
					|  |  |  |  | struct Vector3 { | 
			
		
	
		
			
				
					|  |  |  |  |     x: f32, | 
			
		
	
		
			
				
					|  |  |  |  |     y: f32, | 
			
		
	
		
			
				
					|  |  |  |  |     z: f32, | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #[derive(Debug)] | 
			
		
	
		
			
				
					|  |  |  |  | struct Camera { | 
			
		
	
		
			
				
					|  |  |  |  |     origin: Vector3, | 
			
		
	
		
			
				
					|  |  |  |  |     rotation: Vector3, | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | fn handle_key(keycode: Keycode, camera: &mut Camera) { | 
			
		
	
		
			
				
					|  |  |  |  |     let mov_scale = 0.01; | 
			
		
	
		
			
				
					|  |  |  |  |     let rot_scale = 0.01; | 
			
		
	
		
			
				
					|  |  |  |  |     match keycode { | 
			
		
	
		
			
				
					|  |  |  |  |         Keycode::W => { | 
			
		
	
		
			
				
					|  |  |  |  |             camera.origin.x -= -camera.rotation.y.sin() * mov_scale; | 
			
		
	
		
			
				
					|  |  |  |  |             camera.origin.z -= camera.rotation.y.cos() * mov_scale; | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         Keycode::S => { | 
			
		
	
		
			
				
					|  |  |  |  |             camera.origin.x += -camera.rotation.y.sin() * mov_scale; | 
			
		
	
		
			
				
					|  |  |  |  |             camera.origin.z += camera.rotation.y.cos() * mov_scale; | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         Keycode::A => { | 
			
		
	
		
			
				
					|  |  |  |  |             camera.origin.x += camera.rotation.y.cos() * mov_scale; | 
			
		
	
		
			
				
					|  |  |  |  |             camera.origin.z += camera.rotation.y.sin() * mov_scale; | 
			
		
	
		
			
				
					|  |  |  |  |         }        
 | 
			
		
	
		
			
				
					|  |  |  |  |         Keycode::D => { | 
			
		
	
		
			
				
					|  |  |  |  |             camera.origin.z -= camera.rotation.y.sin() * mov_scale; | 
			
		
	
		
			
				
					|  |  |  |  |             camera.origin.x -= camera.rotation.y.cos() * mov_scale; | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         Keycode::R => { | 
			
		
	
		
			
				
					|  |  |  |  |             camera.rotation.x += rot_scale; | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         Keycode::F => { | 
			
		
	
		
			
				
					|  |  |  |  |             camera.rotation.x -= rot_scale; | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         Keycode::Q => { | 
			
		
	
		
			
				
					|  |  |  |  |             camera.rotation.y += rot_scale; | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         Keycode::E => { | 
			
		
	
		
			
				
					|  |  |  |  |             camera.rotation.y -= rot_scale; | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         Keycode::Space => { | 
			
		
	
		
			
				
					|  |  |  |  |             camera.origin.y += mov_scale; | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         Keycode::LShift => { | 
			
		
	
		
			
				
					|  |  |  |  |             camera.origin.y -= mov_scale; | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         _ => {} | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | fn main() { | 
			
		
	
		
			
				
					|  |  |  |  |     let sdl_context = sdl2::init().unwrap(); | 
			
		
	
		
			
				
					|  |  |  |  |     let video_subsystem = sdl_context.video().unwrap(); | 
			
		
	
	
		
			
				
					|  |  |  | @ -659,7 +1010,12 @@ fn main() { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     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 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) }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -725,7 +1081,10 @@ fn main() { | 
			
		
	
		
			
				
					|  |  |  |  |         .expect("Failed to create fragment shader module") | 
			
		
	
		
			
				
					|  |  |  |  |     }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     let pipe = setup_pipeline(&dev, &vert_shader, &frag_shader); | 
			
		
	
		
			
				
					|  |  |  |  |     let pass = setup_render_pass(&dev); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     let pipe_layout = setup_pipe_layout(&dev); | 
			
		
	
		
			
				
					|  |  |  |  |     let pipe = setup_pipeline(&dev, &vert_shader, &frag_shader, &pass, &pipe_layout); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     let surface_loader = surface::Instance::new(&entry, &instance); | 
			
		
	
		
			
				
					|  |  |  |  |     let swapchain_loader = swapchain::Device::new(&instance, &dev); | 
			
		
	
	
		
			
				
					|  |  |  | @ -744,4 +1103,81 @@ fn main() { | 
			
		
	
		
			
				
					|  |  |  |  |     let swap_images = make_swap_images(&dev, &swapchain, &swapchain_loader); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     let swap_views = make_swap_views(&dev, &swap_images, vk::Format::B8G8R8A8_UNORM); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     let depth_view = make_depth_view(&dev, &depth_img, vk::Format::D32_SFLOAT); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     let framebufs = make_framebufs(&dev, &swap_views, &depth_view, &pass, width, height); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     let desc_sets = make_desc_sets(&dev, &desc_pool); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     write_desc_sets(&dev, &desc_sets, &mesh_buf); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     let sem_avail = make_sem(&dev); | 
			
		
	
		
			
				
					|  |  |  |  |     let sem_finish = make_sem(&dev); | 
			
		
	
		
			
				
					|  |  |  |  |     let fence_flight = make_fence(&dev); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     let mut event_pump = sdl_context.event_pump().expect("Failed to get event pump"); | 
			
		
	
		
			
				
					|  |  |  |  |     let mut camera = Camera { | 
			
		
	
		
			
				
					|  |  |  |  |         origin: Vector3 { | 
			
		
	
		
			
				
					|  |  |  |  |             x: 0.0, | 
			
		
	
		
			
				
					|  |  |  |  |             y: 0.0, | 
			
		
	
		
			
				
					|  |  |  |  |             z: 0.0, | 
			
		
	
		
			
				
					|  |  |  |  |         }, | 
			
		
	
		
			
				
					|  |  |  |  |         rotation: Vector3 { | 
			
		
	
		
			
				
					|  |  |  |  |             x: 0.0, | 
			
		
	
		
			
				
					|  |  |  |  |             y: 0.0, | 
			
		
	
		
			
				
					|  |  |  |  |             z: 0.0, | 
			
		
	
		
			
				
					|  |  |  |  |         }, | 
			
		
	
		
			
				
					|  |  |  |  |     }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     let mut running = true; | 
			
		
	
		
			
				
					|  |  |  |  |     while running { | 
			
		
	
		
			
				
					|  |  |  |  |         for event in event_pump.poll_iter() { | 
			
		
	
		
			
				
					|  |  |  |  |             match event { | 
			
		
	
		
			
				
					|  |  |  |  |                 Event::Quit { .. } => running = false, | 
			
		
	
		
			
				
					|  |  |  |  |                 Event::KeyDown { | 
			
		
	
		
			
				
					|  |  |  |  |                     keycode: Some(keycode), | 
			
		
	
		
			
				
					|  |  |  |  |                     .. | 
			
		
	
		
			
				
					|  |  |  |  |                 } => handle_key(keycode, &mut camera), | 
			
		
	
		
			
				
					|  |  |  |  |                 _ => {} | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         wait_for_fence(&dev, &fence_flight); | 
			
		
	
		
			
				
					|  |  |  |  |         reset_fence(&dev, &fence_flight); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         let img_inx = ack_next_img( | 
			
		
	
		
			
				
					|  |  |  |  |             &dev, | 
			
		
	
		
			
				
					|  |  |  |  |             &swapchain_loader, | 
			
		
	
		
			
				
					|  |  |  |  |             &swapchain, | 
			
		
	
		
			
				
					|  |  |  |  |             &sem_avail, | 
			
		
	
		
			
				
					|  |  |  |  |             &fence_flight, | 
			
		
	
		
			
				
					|  |  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         start_cmd_buf(&dev, &cmd_buf); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         record_commands( | 
			
		
	
		
			
				
					|  |  |  |  |             &dev, | 
			
		
	
		
			
				
					|  |  |  |  |             &cmd_buf, | 
			
		
	
		
			
				
					|  |  |  |  |             &framebufs[img_inx as usize], | 
			
		
	
		
			
				
					|  |  |  |  |             &pass, | 
			
		
	
		
			
				
					|  |  |  |  |             &pipe_layout, | 
			
		
	
		
			
				
					|  |  |  |  |             width, | 
			
		
	
		
			
				
					|  |  |  |  |             height, | 
			
		
	
		
			
				
					|  |  |  |  |             &pipe, | 
			
		
	
		
			
				
					|  |  |  |  |             &desc_sets, | 
			
		
	
		
			
				
					|  |  |  |  |             &camera, | 
			
		
	
		
			
				
					|  |  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |  |         end_cmd_buf(&dev, &cmd_buf); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         submit_queue( | 
			
		
	
		
			
				
					|  |  |  |  |             &dev, | 
			
		
	
		
			
				
					|  |  |  |  |             &queue, | 
			
		
	
		
			
				
					|  |  |  |  |             &cmd_buf, | 
			
		
	
		
			
				
					|  |  |  |  |             &sem_avail, | 
			
		
	
		
			
				
					|  |  |  |  |             &sem_finish, | 
			
		
	
		
			
				
					|  |  |  |  |             &fence_flight, | 
			
		
	
		
			
				
					|  |  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         queue_present(&swapchain_loader, &queue, &swapchain, img_inx, &sem_finish); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
	
		
			
				
					|  |  |  | 
 |