diff --git a/ash/src/instance.rs b/ash/src/instance.rs index 78e1c9e..239c1c9 100644 --- a/ash/src/instance.rs +++ b/ash/src/instance.rs @@ -183,6 +183,82 @@ impl Device { } } + pub fn destroy_render_pass(&self, renderpass: vk::RenderPass) { + unsafe { + self.device_fn.destroy_render_pass(self.handle, renderpass, ptr::null()); + } + } + + pub fn destroy_framebuffer(&self, framebuffer: vk::Framebuffer) { + unsafe { + self.device_fn.destroy_framebuffer(self.handle, framebuffer, ptr::null()); + } + } + + pub fn destroy_buffer(&self, buffer: vk::Buffer) { + unsafe { + self.device_fn.destroy_buffer(self.handle, buffer, ptr::null()); + } + } + + pub fn destroy_shader_module(&self, shader: vk::ShaderModule) { + unsafe { + self.device_fn.destroy_shader_module(self.handle, shader, ptr::null()); + } + } + pub fn create_buffer(&self, create_info: &vk::BufferCreateInfo) -> VkResult { + unsafe { + let mut buffer = mem::uninitialized(); + let err_code = self.device_fn + .create_buffer(self.handle, create_info, ptr::null(), &mut buffer); + match err_code { + vk::Result::Success => Ok(buffer), + _ => Err(err_code), + } + } + } + + pub fn map_memory(&self, + memory: vk::DeviceMemory, + offset: vk::DeviceSize, + size: vk::DeviceSize, + flags: vk::MemoryMapFlags) + -> VkResult<&mut [T]> { + + unsafe { + let mut data: *mut () = mem::uninitialized(); + let err_code = self.device_fn + .map_memory(self.handle, memory, offset, size, flags, &mut data); + let x: *mut T = data as *mut T; + match err_code { + vk::Result::Success => { + Ok(::std::slice::from_raw_parts_mut(x, size as usize / mem::size_of::())) + } + _ => Err(err_code), + } + } + } + + pub fn unmap_memory(&self, memory: vk::DeviceMemory) { + unsafe { + self.device_fn.unmap_memory(self.handle, memory); + } + } + + pub fn create_framebuffer(&self, + create_info: &vk::FramebufferCreateInfo) + -> VkResult { + unsafe { + let mut framebuffer = mem::uninitialized(); + let err_code = self.device_fn + .create_framebuffer(self.handle, create_info, ptr::null(), &mut framebuffer); + match err_code { + vk::Result::Success => Ok(framebuffer), + _ => Err(err_code), + } + } + } + pub fn get_device_queue(&self, queue_family_index: u32, queue_index: u32) -> vk::Queue { unsafe { let mut queue = mem::uninitialized(); @@ -197,25 +273,37 @@ impl Device { src_stage_mask: vk::PipelineStageFlags, dst_stage_mask: vk::PipelineStageFlags, dependency_flags: vk::DependencyFlags, - memory_barrier_count: u32, - p_memory_barriers: *const vk::MemoryBarrier, - buffer_memory_barrier_count: u32, - p_buffer_memory_barriers: *const vk::BufferMemoryBarrier, - image_memory_barrier_count: u32, - p_image_memory_barriers: *const vk::ImageMemoryBarrier) { + memory_barriers: &[vk::MemoryBarrier], + buffer_memory_barriers: &[vk::BufferMemoryBarrier], + image_memory_barriers: &[vk::ImageMemoryBarrier]) { unsafe { self.device_fn.cmd_pipeline_barrier(command_buffer, src_stage_mask, dst_stage_mask, dependency_flags, - memory_barrier_count, - p_memory_barriers, - buffer_memory_barrier_count, - p_buffer_memory_barriers, - image_memory_barrier_count, - p_image_memory_barriers); + memory_barriers.len() as u32, + memory_barriers.as_ptr(), + buffer_memory_barriers.len() as u32, + buffer_memory_barriers.as_ptr(), + image_memory_barriers.len() as u32, + image_memory_barriers.as_ptr()); } } + + pub fn create_render_pass(&self, + create_info: &vk::RenderPassCreateInfo) + -> VkResult { + unsafe { + let mut renderpass = mem::uninitialized(); + let err_code = self.device_fn + .create_render_pass(self.handle, create_info, ptr::null(), &mut renderpass); + match err_code { + vk::Result::Success => Ok(renderpass), + _ => Err(err_code), + } + } + } + pub fn begin_command_buffer(&self, command_buffer: vk::CommandBuffer, create_info: &vk::CommandBufferBeginInfo) @@ -241,6 +329,24 @@ impl Device { } } + pub fn wait_for_fences(&self, + fences: &[vk::Fence], + wait_all: bool, + timeout: u64) + -> VkResult<()> { + unsafe { + let err_code = self.device_fn + .wait_for_fences(self.handle, + fences.len() as u32, + fences.as_ptr(), + wait_all as u32, + timeout); + match err_code { + vk::Result::Success => Ok(()), + _ => Err(err_code), + } + } + } pub fn queue_submit(&self, queue: vk::Queue, submit_count: u32, @@ -355,6 +461,15 @@ impl Device { } } + pub fn get_buffer_memory_requirements(&self, buffer: vk::Buffer) -> vk::MemoryRequirements { + unsafe { + let mut mem_req = mem::uninitialized(); + self.device_fn + .get_buffer_memory_requirements(self.handle, buffer, &mut mem_req); + mem_req + } + } + pub fn allocate_memory(&self, create_info: &vk::MemoryAllocateInfo) -> VkResult { @@ -369,6 +484,20 @@ impl Device { } } + pub fn create_shader_module(&self, + create_info: &vk::ShaderModuleCreateInfo) + -> VkResult { + unsafe { + let mut shader = mem::uninitialized(); + let err_code = self.device_fn + .create_shader_module(self.handle, create_info, ptr::null(), &mut shader); + match err_code { + vk::Result::Success => Ok(shader), + _ => Err(err_code), + } + } + } + pub fn create_fence(&self, create_info: &vk::FenceCreateInfo) -> VkResult { unsafe { let mut fence = mem::uninitialized(); @@ -381,6 +510,20 @@ impl Device { } } + pub fn bind_buffer_memory(&self, + buffer: vk::Buffer, + device_memory: vk::DeviceMemory, + offset: vk::DeviceSize) + -> VkResult<()> { + unsafe { + let err_code = self.device_fn + .bind_buffer_memory(self.handle, buffer, device_memory, offset); + match err_code { + vk::Result::Success => Ok(()), + _ => Err(err_code), + } + } + } pub fn bind_image_memory(&self, image: vk::Image, device_memory: vk::DeviceMemory, diff --git a/examples/.idea/compiler.xml b/examples/.idea/compiler.xml deleted file mode 100644 index 96cc43e..0000000 --- a/examples/.idea/compiler.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/.idea/copyright/profiles_settings.xml b/examples/.idea/copyright/profiles_settings.xml deleted file mode 100644 index e7bedf3..0000000 --- a/examples/.idea/copyright/profiles_settings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/examples/.idea/examples.iml b/examples/.idea/examples.iml deleted file mode 100644 index 28d4ea4..0000000 --- a/examples/.idea/examples.iml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/examples/.idea/libraries/Cargo__examples_.xml b/examples/.idea/libraries/Cargo__examples_.xml deleted file mode 100644 index 8b8a58e..0000000 --- a/examples/.idea/libraries/Cargo__examples_.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/.idea/libraries/Rust__examples_.xml b/examples/.idea/libraries/Rust__examples_.xml deleted file mode 100644 index 38bbbf5..0000000 --- a/examples/.idea/libraries/Rust__examples_.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/.idea/misc.xml b/examples/.idea/misc.xml deleted file mode 100644 index fa3af68..0000000 --- a/examples/.idea/misc.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/.idea/modules.xml b/examples/.idea/modules.xml deleted file mode 100644 index 704ff0e..0000000 --- a/examples/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/examples/.idea/workspace.xml b/examples/.idea/workspace.xml deleted file mode 100644 index 7bf56ff..0000000 --- a/examples/.idea/workspace.xml +++ /dev/null @@ -1,427 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1471360642395 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/frag.spv b/examples/frag.spv new file mode 100644 index 0000000..7daf2ce Binary files /dev/null and b/examples/frag.spv differ diff --git a/examples/src/main.rs b/examples/src/main.rs index 7ddce5e..9a7d3e3 100644 --- a/examples/src/main.rs +++ b/examples/src/main.rs @@ -11,6 +11,8 @@ use std::ptr; use std::ffi::{CStr, CString}; use std::mem; use std::path::Path; +use std::fs::File; +use std::io::Read; use std::os::raw::c_void; macro_rules! printlndb{ ($arg: tt) => { @@ -36,6 +38,13 @@ pub fn find_memorytype_index(memory_req: &vk::MemoryRequirements, } None } +#[derive(Clone, Debug, Copy)] +struct Vertex { + x: f32, + y: f32, + z: f32, + w: f32, +} fn main() { let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap(); @@ -207,7 +216,7 @@ fn main() { composite_alpha: vk::COMPOSITE_ALPHA_OPAQUE_BIT_KHR, present_mode: present_mode, clipped: 1, - old_swapchain: unsafe { mem::transmute(0u64) }, + old_swapchain: vk::SwapchainKHR::null(), // FIX ME: What is this? image_array_layers: 1, p_queue_family_indices: ptr::null(), @@ -262,7 +271,7 @@ fn main() { }) .collect(); let device_memory_properties = instance.get_physical_device_memory_properties(pdevice); - let image_create_info = vk::ImageCreateInfo { + let depth_image_create_info = vk::ImageCreateInfo { s_type: vk::StructureType::ImageCreateInfo, p_next: ptr::null(), flags: vk::IMAGE_CREATE_SPARSE_BINDING_BIT, @@ -283,7 +292,7 @@ fn main() { p_queue_family_indices: ptr::null(), initial_layout: vk::ImageLayout::Undefined, }; - let depth_image = device.create_image(&image_create_info).unwrap(); + let depth_image = device.create_image(&depth_image_create_info).unwrap(); let depth_image_memory_req = device.get_image_memory_requirements(depth_image); let depth_image_memory_index = find_memorytype_index(&depth_image_memory_req, &device_memory_properties, @@ -311,7 +320,7 @@ fn main() { s_type: vk::StructureType::ImageMemoryBarrier, p_next: ptr::null(), // TODO Is this correct? - src_access_mask: vk::ACCESS_HOST_WRITE_BIT, + src_access_mask: vk::AccessFlags::empty(), dst_access_mask: vk::ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | vk::ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, old_layout: vk::ImageLayout::Undefined, @@ -331,17 +340,14 @@ fn main() { vk::PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::DEPENDENCY_BY_REGION_BIT, - 0, - ptr::null(), - 0, - ptr::null(), - 1, - &layout_transition_barrier); + &[], + &[], + &[layout_transition_barrier]); let wait_stage_mask = [vk::PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT]; let fence_create_info = vk::FenceCreateInfo { s_type: vk::StructureType::FenceCreateInfo, p_next: ptr::null(), - flags: vk::FENCE_CREATE_SIGNALED_BIT, + flags: vk::FenceCreateFlags::empty(), }; let submit_fence = device.create_fence(&fence_create_info).unwrap(); let submit_info = vk::SubmitInfo { @@ -355,9 +361,193 @@ fn main() { command_buffer_count: 1, p_command_buffers: &setup_command_buffer, }; - device.queue_submit(present_queue, 1, &submit_info, submit_fence); - device.destroy_fence(submit_fence); device.end_command_buffer(setup_command_buffer).unwrap(); + device.queue_submit(present_queue, 1, &submit_info, submit_fence).unwrap(); + device.wait_for_fences(&[submit_fence], true, std::u64::MAX).unwrap(); + let depth_image_view_info = vk::ImageViewCreateInfo { + s_type: vk::StructureType::ImageViewCreateInfo, + p_next: ptr::null(), + flags: 0, + view_type: vk::ImageViewType::Type2d, + format: depth_image_create_info.format, + components: vk::ComponentMapping { + r: vk::ComponentSwizzle::Identity, + g: vk::ComponentSwizzle::Identity, + b: vk::ComponentSwizzle::Identity, + a: vk::ComponentSwizzle::Identity, + }, + subresource_range: vk::ImageSubresourceRange { + aspect_mask: vk::IMAGE_ASPECT_DEPTH_BIT, + base_mip_level: 0, + level_count: 1, + base_array_layer: 0, + layer_count: 1, + }, + image: depth_image, + }; + let depth_image_view = device.create_image_view(&depth_image_view_info).unwrap(); + let renderpass_attachments = [vk::AttachmentDescription { + format: surface_format.format, + flags: vk::AttachmentDescriptionFlags::empty(), + samples: vk::SAMPLE_COUNT_1_BIT, + load_op: vk::AttachmentLoadOp::Clear, + store_op: vk::AttachmentStoreOp::Store, + stencil_load_op: vk::AttachmentLoadOp::DontCare, + stencil_store_op: vk::AttachmentStoreOp::DontCare, + initial_layout: vk::ImageLayout::ColorAttachmentOptimal, + final_layout: vk::ImageLayout::ColorAttachmentOptimal, + }, + vk::AttachmentDescription { + format: depth_image_create_info.format, + flags: vk::AttachmentDescriptionFlags::empty(), + samples: vk::SAMPLE_COUNT_1_BIT, + load_op: vk::AttachmentLoadOp::Clear, + store_op: vk::AttachmentStoreOp::DontCare, + stencil_load_op: vk::AttachmentLoadOp::DontCare, + stencil_store_op: vk::AttachmentStoreOp::DontCare, + initial_layout: + vk::ImageLayout::DepthStencilAttachmentOptimal, + final_layout: vk::ImageLayout::DepthStencilAttachmentOptimal, + }]; + let color_attachment_ref = vk::AttachmentReference { + attachment: 0, + layout: vk::ImageLayout::ColorAttachmentOptimal, + }; + let depth_attachment_ref = vk::AttachmentReference { + attachment: 1, + layout: vk::ImageLayout::DepthStencilAttachmentOptimal, + }; + let subpass = vk::SubpassDescription { + color_attachment_count: 1, + p_color_attachments: &color_attachment_ref, + p_depth_stencil_attachment: &depth_attachment_ref, + // TODO: Why is there no wrapper? + flags: 0, + pipeline_bind_point: vk::PipelineBindPoint::Graphics, + input_attachment_count: 0, + p_input_attachments: ptr::null(), + p_resolve_attachments: ptr::null(), + preserve_attachment_count: 0, + p_preserve_attachments: ptr::null(), + }; + let renderpass_create_info = vk::RenderPassCreateInfo { + s_type: vk::StructureType::RenderPassCreateInfo, + flags: 0, + p_next: ptr::null(), + attachment_count: renderpass_attachments.len() as u32, + p_attachments: renderpass_attachments.as_ptr(), + subpass_count: 1, + p_subpasses: &subpass, + dependency_count: 0, + p_dependencies: ptr::null(), + }; + let renderpass = device.create_render_pass(&renderpass_create_info).unwrap(); + let framebuffers: Vec = present_image_views.iter() + .map(|&present_image_view| { + let framebuffer_attachments = [present_image_view, depth_image_view]; + let frame_buffer_create_info = vk::FramebufferCreateInfo { + s_type: vk::StructureType::FramebufferCreateInfo, + p_next: ptr::null(), + flags: 0, + render_pass: renderpass, + attachment_count: framebuffer_attachments.len() as u32, + p_attachments: framebuffer_attachments.as_ptr(), + width: surface_resoultion.width, + height: surface_resoultion.height, + layers: 1, + }; + device.create_framebuffer(&frame_buffer_create_info).unwrap() + }) + .collect(); + let vertex_input_buffer_info = vk::BufferCreateInfo { + s_type: vk::StructureType::BufferCreateInfo, + p_next: ptr::null(), + flags: vk::BufferCreateFlags::empty(), + size: 3 * std::mem::size_of::() as u64, + usage: vk::BUFFER_USAGE_VERTEX_BUFFER_BIT, + sharing_mode: vk::SharingMode::Exclusive, + queue_family_index_count: 0, + p_queue_family_indices: ptr::null(), + }; + let vertex_input_buffer = device.create_buffer(&vertex_input_buffer_info).unwrap(); + let vertex_input_buffer_memory_req = device.get_buffer_memory_requirements(vertex_input_buffer); + let vertex_input_buffer_memory_index = + find_memorytype_index(&vertex_input_buffer_memory_req, + &device_memory_properties, + vk::MEMORY_PROPERTY_HOST_VISIBLE_BIT) + .expect("Unable to find suitable memorytype for the vertex buffer."); + + let vertex_buffer_allocate_info = vk::MemoryAllocateInfo { + s_type: vk::StructureType::MemoryAllocateInfo, + p_next: ptr::null(), + allocation_size: vertex_input_buffer_memory_req.size, + memory_type_index: vertex_input_buffer_memory_index, + }; + let vertex_input_buffer_memory = device.allocate_memory(&vertex_buffer_allocate_info).unwrap(); + let slice = device.map_memory::(vertex_input_buffer_memory, + 0, + vertex_input_buffer_info.size, + 0) + .unwrap(); + let vertices = [Vertex { + x: -1.0, + y: 1.0, + z: 0.0, + w: 1.0, + }, + Vertex { + x: 1.0, + y: 1.0, + z: 0.0, + w: 1.0, + }, + Vertex { + x: 0.0, + y: -1.0, + z: 0.0, + w: 1.0, + }]; + + slice.copy_from_slice(&vertices); + printlndb!((slice)); + device.unmap_memory(vertex_input_buffer_memory); + device.bind_buffer_memory(vertex_input_buffer, vertex_input_buffer_memory, 0).unwrap(); + let vertex_spv_file = File::open(Path::new("vert.spv")).expect("Could not find vert.spv."); + let frag_spv_file = File::open(Path::new("frag.spv")).expect("Could not find frag.spv."); + + let vertex_bytes: Vec = vertex_spv_file.bytes().filter_map(|byte| byte.ok()).collect(); + let vertex_shader_info = vk::ShaderModuleCreateInfo { + s_type: vk::StructureType::ShaderModuleCreateInfo, + p_next: ptr::null(), + flags: 0, + code_size: vertex_bytes.len(), + p_code: vertex_bytes.as_ptr() as *const u32, + }; + let frag_bytes: Vec = frag_spv_file.bytes().filter_map(|byte| byte.ok()).collect(); + let frag_shader_info = vk::ShaderModuleCreateInfo { + s_type: vk::StructureType::ShaderModuleCreateInfo, + p_next: ptr::null(), + flags: 0, + code_size: frag_bytes.len(), + p_code: frag_bytes.as_ptr() as *const u32, + }; + let vertex_shader_module = device.create_shader_module(&vertex_shader_info) + .expect("Vertex shader module error"); + let frag_shader_module = device.create_shader_module(&frag_shader_info) + .expect("Fragment shader module error"); + + + + device.destroy_shader_module(vertex_shader_module); + device.destroy_shader_module(frag_shader_module); + device.free_memory(vertex_input_buffer_memory); + device.destroy_buffer(vertex_input_buffer); + for framebuffer in framebuffers { + device.destroy_framebuffer(framebuffer); + } + device.destroy_render_pass(renderpass); + device.destroy_image_view(depth_image_view); + device.destroy_fence(submit_fence); device.free_memory(depth_image_memory); device.destroy_image(depth_image); for image_view in present_image_views { diff --git a/examples/vert.spv b/examples/vert.spv new file mode 100644 index 0000000..0e38601 Binary files /dev/null and b/examples/vert.spv differ diff --git a/vk_loader2/src/lib.rs b/vk_loader2/src/lib.rs index 542e80e..e5a5635 100644 --- a/vk_loader2/src/lib.rs +++ b/vk_loader2/src/lib.rs @@ -14,6 +14,11 @@ macro_rules! handle_nondispatchable { #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash)] pub struct $name (uint64_t); + impl $name{ + pub fn null() -> $name{ + $name(0) + } + } impl fmt::Pointer for $name { fn fmt(&self, f: &mut fmt::Formatter) -> ::std::result::Result<(), fmt::Error> { write!(f, "0x{:x}", self.0)