diff options
Diffstat (limited to 'src/graphics_window_dressing.rs')
| -rw-r--r-- | src/graphics_window_dressing.rs | 838 |
1 files changed, 424 insertions, 414 deletions
diff --git a/src/graphics_window_dressing.rs b/src/graphics_window_dressing.rs index 6ffab41..e35332f 100644 --- a/src/graphics_window_dressing.rs +++ b/src/graphics_window_dressing.rs @@ -82,22 +82,22 @@ impl WindowDressing { let surface = &permanent.surface; let device = &permanent.device; - let swapchain = Self::init_swapchain( + let swapchain = init_swapchain( window, instance, surface, &physical_device, device, &indices)?; - let render_pass = Self::init_render_pass(device, &swapchain.format)?; + let render_pass = init_render_pass(device, &swapchain.format)?; let (pipeline_layout, pipeline) - = Self::init_pipeline(device, &swapchain.extent, &render_pass)?; + = init_pipeline(device, &swapchain.extent, &render_pass)?; - let framebuffers = Self::init_framebuffers( + let framebuffers = init_framebuffers( device, &swapchain.extent, &swapchain.image_views, &render_pass)?; let (command_pool, command_buffers) - = Self::init_commands(device, &swapchain.extent, &framebuffers, - &render_pass, &pipeline, &indices)?; + = init_commands(device, &swapchain.extent, &framebuffers, + &render_pass, &pipeline, &indices)?; - let concurrency = Self::init_concurrency(device, &swapchain.images)?; + let concurrency = init_concurrency(device, &swapchain.images)?; Ok(WindowDressing { swapchain, @@ -143,462 +143,472 @@ impl WindowDressing { unsafe { device.destroy_swapchain_khr(self.swapchain.swapchain, None) }; } +} - #[allow(unsafe_code)] - fn init_swapchain(window: &Window, instance: &Instance, - surface: &vk::SurfaceKHR, - physical_device: &vk::PhysicalDevice, device: &Device, - indices: &QueueFamilyIndices) - -> Result<Swapchain> - { - let (capabilities, formats, presentation_modes) - = PermanentGraphicsState::find_device_swapchain_features( - instance, surface, physical_device)?.require()?; - - let format = Self::pick_surface_format(&formats)?; - - let presentation_mode - = Self::pick_presentation_mode(&presentation_modes)?; - let extent = Self::pick_image_extent(window, capabilities)?; - - let mut image_count = capabilities.min_image_count + 1; - if capabilities.max_image_count != 0 { - image_count - = image_count.clamp(0, capabilities.max_image_count); - } - - let mut unique_queue_family_indices = BTreeSet::new(); - unique_queue_family_indices.insert(indices.graphics); - unique_queue_family_indices.insert(indices.presentation); - - // If there's only one queue, we use exclusive sharing mode, which - // will allow things to work without locks. Otherwise we use concurrent - // mode. - let (ordered_indices, sharing_mode) - = if unique_queue_family_indices.len() < 2 - { - (vec![indices.graphics], vk::SharingMode::EXCLUSIVE) - } else { - (vec![indices.graphics, indices.presentation], - vk::SharingMode::CONCURRENT) - }; - let swapchain_info = vk::SwapchainCreateInfoKHR::builder() - .surface(*surface) - .min_image_count(image_count) - .image_format(format.format) - .image_color_space(format.color_space) - .image_extent(extent) - .image_array_layers(1) - .image_usage(vk::ImageUsageFlags::COLOR_ATTACHMENT) - .image_sharing_mode(sharing_mode) - .queue_family_indices(&ordered_indices) - .pre_transform(capabilities.current_transform) - .composite_alpha(vk::CompositeAlphaFlagsKHR::OPAQUE) - .present_mode(presentation_mode) - .clipped(true) - .old_swapchain(vk::SwapchainKHR::null()); - - let swapchain = unsafe { - device.create_swapchain_khr(&swapchain_info, None) - }?; +#[allow(unsafe_code)] +fn init_swapchain(window: &Window, instance: &Instance, + surface: &vk::SurfaceKHR, + physical_device: &vk::PhysicalDevice, device: &Device, + indices: &QueueFamilyIndices) + -> Result<Swapchain> +{ + let (capabilities, formats, presentation_modes) + = PermanentGraphicsState::find_device_swapchain_features( + instance, surface, physical_device)?.require()?; - let images = unsafe { - device.get_swapchain_images_khr(swapchain) - }?; + let format = pick_surface_format(&formats)?; - let mut image_views = Vec::new(); - for image in &images { - let components = vk::ComponentMapping::builder() - .r(vk::ComponentSwizzle::IDENTITY) - .g(vk::ComponentSwizzle::IDENTITY) - .b(vk::ComponentSwizzle::IDENTITY) - .a(vk::ComponentSwizzle::IDENTITY); - - let subresource_range = vk::ImageSubresourceRange::builder() - .aspect_mask(vk::ImageAspectFlags::COLOR) - .base_mip_level(0) - .level_count(1) - .base_array_layer(0) - .layer_count(1); - - let view_info = vk::ImageViewCreateInfo::builder() - .image(*image) - .view_type(vk::ImageViewType::_2D) - .format(format.format) - .components(components) - .subresource_range(subresource_range); - - let view = unsafe { - device.create_image_view(&view_info, None) - }?; - - image_views.push(view); - } + let presentation_mode + = pick_presentation_mode(&presentation_modes)?; + let extent = pick_image_extent(window, capabilities)?; - Ok(Swapchain { - swapchain, images, image_views, - format: format.format, - extent - }) + let mut image_count = capabilities.min_image_count + 1; + if capabilities.max_image_count != 0 { + image_count + = image_count.clamp(0, capabilities.max_image_count); } - #[allow(unsafe_code)] - fn init_render_pass(device: &Device, format: &vk::Format) - -> Result<vk::RenderPass> + let mut unique_queue_family_indices = BTreeSet::new(); + unique_queue_family_indices.insert(indices.graphics); + unique_queue_family_indices.insert(indices.presentation); + + // If there's only one queue, we use exclusive sharing mode, which + // will allow things to work without locks. Otherwise we use concurrent + // mode. + let (ordered_indices, sharing_mode) + = if unique_queue_family_indices.len() < 2 { - let color_attachment - = vk::AttachmentDescription::builder() - .format(*format) - .samples(vk::SampleCountFlags::_1) - .load_op(vk::AttachmentLoadOp::CLEAR) - .store_op(vk::AttachmentStoreOp::STORE) - .stencil_load_op(vk::AttachmentLoadOp::DONT_CARE) - .stencil_store_op(vk::AttachmentStoreOp::DONT_CARE) - .initial_layout(vk::ImageLayout::UNDEFINED) - .final_layout(vk::ImageLayout::PRESENT_SRC_KHR); - - let color_attachment_reference - = vk::AttachmentReference::builder() - .attachment(0) - .layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL); - - let subpass_attachments = [color_attachment_reference]; - let subpass = vk::SubpassDescription::builder() - .pipeline_bind_point(vk::PipelineBindPoint::GRAPHICS) - .color_attachments(&subpass_attachments); - - let dependency - = vk::SubpassDependency::builder() - .src_subpass(vk::SUBPASS_EXTERNAL) - .src_stage_mask( - vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT) - .src_access_mask(vk::AccessFlags::empty()) - .dst_subpass(0) - .dst_stage_mask( - vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT) - .dst_access_mask(vk::AccessFlags::COLOR_ATTACHMENT_WRITE); - - let render_attachments = [color_attachment]; - let subpasses = [subpass]; - let dependencies = [dependency]; - let render_pass_info = vk::RenderPassCreateInfo::builder() - .attachments(&render_attachments) - .subpasses(&subpasses) - .dependencies(&dependencies); - - let render_pass = unsafe { - device.create_render_pass(&render_pass_info, None) + (vec![indices.graphics], vk::SharingMode::EXCLUSIVE) + } else { + (vec![indices.graphics, indices.presentation], + vk::SharingMode::CONCURRENT) + }; + + let swapchain_info = vk::SwapchainCreateInfoKHR::builder() + .surface(*surface) + .min_image_count(image_count) + .image_format(format.format) + .image_color_space(format.color_space) + .image_extent(extent) + .image_array_layers(1) + .image_usage(vk::ImageUsageFlags::COLOR_ATTACHMENT) + .image_sharing_mode(sharing_mode) + .queue_family_indices(&ordered_indices) + .pre_transform(capabilities.current_transform) + .composite_alpha(vk::CompositeAlphaFlagsKHR::OPAQUE) + .present_mode(presentation_mode) + .clipped(true) + .old_swapchain(vk::SwapchainKHR::null()); + + let swapchain = unsafe { + device.create_swapchain_khr(&swapchain_info, None) + }?; + + let images = unsafe { + device.get_swapchain_images_khr(swapchain) + }?; + + let mut image_views = Vec::new(); + for image in &images { + let components = vk::ComponentMapping::builder() + .r(vk::ComponentSwizzle::IDENTITY) + .g(vk::ComponentSwizzle::IDENTITY) + .b(vk::ComponentSwizzle::IDENTITY) + .a(vk::ComponentSwizzle::IDENTITY); + + let subresource_range = vk::ImageSubresourceRange::builder() + .aspect_mask(vk::ImageAspectFlags::COLOR) + .base_mip_level(0) + .level_count(1) + .base_array_layer(0) + .layer_count(1); + + let view_info = vk::ImageViewCreateInfo::builder() + .image(*image) + .view_type(vk::ImageViewType::_2D) + .format(format.format) + .components(components) + .subresource_range(subresource_range); + + let view = unsafe { + device.create_image_view(&view_info, None) }?; - Ok(render_pass) + image_views.push(view); } - #[allow(unsafe_code)] - fn init_pipeline(device: &Device, extent: &vk::Extent2D, - render_pass: &vk::RenderPass) - -> Result<(vk::PipelineLayout, vk::Pipeline)> - { - let vertex_binary = include_bytes!( - concat!(env!("OUT_DIR"), "/shader.vert.spv")); - let fragment_binary = include_bytes!( - concat!(env!("OUT_DIR"), "/shader.frag.spv")); - - let vertex_module = PermanentGraphicsState::load_spirv_shader_module( - device, vertex_binary)?; - let fragment_module = PermanentGraphicsState::load_spirv_shader_module( - device, fragment_binary)?; - - let vertex_stage_info = vk::PipelineShaderStageCreateInfo::builder() - .stage(vk::ShaderStageFlags::VERTEX) - .module(vertex_module) - .name(b"main\0"); + Ok(Swapchain { + swapchain, images, image_views, + format: format.format, + extent + }) +} - let fragment_stage_info = vk::PipelineShaderStageCreateInfo::builder() - .stage(vk::ShaderStageFlags::FRAGMENT) - .module(fragment_module) - .name(b"main\0"); - - let vertex_input_state_info - = vk::PipelineVertexInputStateCreateInfo::builder(); - - let input_assembly_state_info - = vk::PipelineInputAssemblyStateCreateInfo::builder() - .topology(vk::PrimitiveTopology::TRIANGLE_LIST) - .primitive_restart_enable(false); - - let viewport = vk::Viewport::builder() - .x(0.0) - .y(0.0) - .width(extent.width as f32) - .height(extent.height as f32) - .min_depth(0.0) - .max_depth(1.0); - let viewports = [viewport]; - - let scissor = vk::Rect2D::builder() - .offset(vk::Offset2D { x: 0, y: 0 }) - .extent(*extent); - let scissor_list = [scissor]; - - let viewport_state_info = vk::PipelineViewportStateCreateInfo::builder() - .viewports(&viewports) - .scissors(&scissor_list); - - let rasterizer_state_info - = vk::PipelineRasterizationStateCreateInfo::builder() - .depth_clamp_enable(false) - .rasterizer_discard_enable(false) - .polygon_mode(vk::PolygonMode::FILL) - .line_width(1.0) - .cull_mode(vk::CullModeFlags::BACK) - .front_face(vk::FrontFace::CLOCKWISE) - .depth_bias_enable(false); - - let multisample_state_info - = vk::PipelineMultisampleStateCreateInfo::builder() - .sample_shading_enable(false) - .rasterization_samples(vk::SampleCountFlags::_1); - - let blend_attachment_info - = vk::PipelineColorBlendAttachmentState::builder() - .color_write_mask(vk::ColorComponentFlags::all()) - .blend_enable(false) - .src_color_blend_factor(vk::BlendFactor::ONE) - .dst_color_blend_factor(vk::BlendFactor::ZERO) - .color_blend_op(vk::BlendOp::ADD) - .src_alpha_blend_factor(vk::BlendFactor::ONE) - .dst_alpha_blend_factor(vk::BlendFactor::ZERO) - .alpha_blend_op(vk::BlendOp::ADD); - let blend_attachments = [blend_attachment_info]; - - let blend_info = vk::PipelineColorBlendStateCreateInfo::builder() - .logic_op_enable(false) - .logic_op(vk::LogicOp::COPY) - .attachments(&blend_attachments) - .blend_constants([0.0, 0.0, 0.0, 0.0]); - - let pipeline_layout_info = vk::PipelineLayoutCreateInfo::builder(); - - let pipeline_layout = unsafe { - device.create_pipeline_layout(&pipeline_layout_info, None) - }?; - let stages = [vertex_stage_info, fragment_stage_info]; - let pipeline_info - = vk::GraphicsPipelineCreateInfo::builder() - .stages(&stages) - .vertex_input_state(&vertex_input_state_info) - .input_assembly_state(&input_assembly_state_info) - .viewport_state(&viewport_state_info) - .rasterization_state(&rasterizer_state_info) - .multisample_state(&multisample_state_info) - .color_blend_state(&blend_info) - .layout(pipeline_layout) - .render_pass(*render_pass) - .subpass(0); - - let pipeline = unsafe { - device.create_graphics_pipelines(vk::PipelineCache::null(), - &[pipeline_info], None) - }?.0[0]; +#[allow(unsafe_code)] +fn init_render_pass(device: &Device, format: &vk::Format) + -> Result<vk::RenderPass> +{ + let color_attachment + = vk::AttachmentDescription::builder() + .format(*format) + .samples(vk::SampleCountFlags::_1) + .load_op(vk::AttachmentLoadOp::CLEAR) + .store_op(vk::AttachmentStoreOp::STORE) + .stencil_load_op(vk::AttachmentLoadOp::DONT_CARE) + .stencil_store_op(vk::AttachmentStoreOp::DONT_CARE) + .initial_layout(vk::ImageLayout::UNDEFINED) + .final_layout(vk::ImageLayout::PRESENT_SRC_KHR); + + let color_attachment_reference + = vk::AttachmentReference::builder() + .attachment(0) + .layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL); + + let subpass_attachments = [color_attachment_reference]; + let subpass = vk::SubpassDescription::builder() + .pipeline_bind_point(vk::PipelineBindPoint::GRAPHICS) + .color_attachments(&subpass_attachments); + + let dependency + = vk::SubpassDependency::builder() + .src_subpass(vk::SUBPASS_EXTERNAL) + .src_stage_mask( + vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT) + .src_access_mask(vk::AccessFlags::empty()) + .dst_subpass(0) + .dst_stage_mask( + vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT) + .dst_access_mask(vk::AccessFlags::COLOR_ATTACHMENT_WRITE); + + let render_attachments = [color_attachment]; + let subpasses = [subpass]; + let dependencies = [dependency]; + let render_pass_info = vk::RenderPassCreateInfo::builder() + .attachments(&render_attachments) + .subpasses(&subpasses) + .dependencies(&dependencies); + + let render_pass = unsafe { + device.create_render_pass(&render_pass_info, None) + }?; + + Ok(render_pass) +} - unsafe { - device.destroy_shader_module(vertex_module, None); - device.destroy_shader_module(fragment_module, None); - }; - Ok((pipeline_layout, pipeline)) - } +#[allow(unsafe_code)] +fn init_pipeline(device: &Device, extent: &vk::Extent2D, + render_pass: &vk::RenderPass) + -> Result<(vk::PipelineLayout, vk::Pipeline)> +{ + let vertex_binary = include_bytes!( + concat!(env!("OUT_DIR"), "/shader.vert.spv")); + let fragment_binary = include_bytes!( + concat!(env!("OUT_DIR"), "/shader.frag.spv")); + + let vertex_module = PermanentGraphicsState::load_spirv_shader_module( + device, vertex_binary)?; + let fragment_module = PermanentGraphicsState::load_spirv_shader_module( + device, fragment_binary)?; + + let vertex_stage_info = vk::PipelineShaderStageCreateInfo::builder() + .stage(vk::ShaderStageFlags::VERTEX) + .module(vertex_module) + .name(b"main\0"); + + let fragment_stage_info = vk::PipelineShaderStageCreateInfo::builder() + .stage(vk::ShaderStageFlags::FRAGMENT) + .module(fragment_module) + .name(b"main\0"); - #[allow(unsafe_code)] - fn init_framebuffers(device: &Device, extent: &vk::Extent2D, - swapchain_image_views: &Vec<vk::ImageView>, - render_pass: &vk::RenderPass) - -> Result<Vec<vk::Framebuffer>> - { - let mut framebuffers = Vec::new(); + let vertex_input_state_info + = vk::PipelineVertexInputStateCreateInfo::builder(); + + let input_assembly_state_info + = vk::PipelineInputAssemblyStateCreateInfo::builder() + .topology(vk::PrimitiveTopology::TRIANGLE_LIST) + .primitive_restart_enable(false); + + let viewport = vk::Viewport::builder() + .x(0.0) + .y(0.0) + .width(extent.width as f32) + .height(extent.height as f32) + .min_depth(0.0) + .max_depth(1.0); + let viewports = [viewport]; + + let scissor = vk::Rect2D::builder() + .offset(vk::Offset2D { x: 0, y: 0 }) + .extent(*extent); + let scissor_list = [scissor]; + + let viewport_state_info = vk::PipelineViewportStateCreateInfo::builder() + .viewports(&viewports) + .scissors(&scissor_list); + + let rasterizer_state_info + = vk::PipelineRasterizationStateCreateInfo::builder() + .depth_clamp_enable(false) + .rasterizer_discard_enable(false) + .polygon_mode(vk::PolygonMode::FILL) + .line_width(1.0) + .cull_mode(vk::CullModeFlags::BACK) + .front_face(vk::FrontFace::CLOCKWISE) + .depth_bias_enable(false); + + let multisample_state_info + = vk::PipelineMultisampleStateCreateInfo::builder() + .sample_shading_enable(false) + .rasterization_samples(vk::SampleCountFlags::_1); + + let blend_attachment_info + = vk::PipelineColorBlendAttachmentState::builder() + .color_write_mask(vk::ColorComponentFlags::all()) + .blend_enable(false) + .src_color_blend_factor(vk::BlendFactor::ONE) + .dst_color_blend_factor(vk::BlendFactor::ZERO) + .color_blend_op(vk::BlendOp::ADD) + .src_alpha_blend_factor(vk::BlendFactor::ONE) + .dst_alpha_blend_factor(vk::BlendFactor::ZERO) + .alpha_blend_op(vk::BlendOp::ADD); + let blend_attachments = [blend_attachment_info]; + + let blend_info = vk::PipelineColorBlendStateCreateInfo::builder() + .logic_op_enable(false) + .logic_op(vk::LogicOp::COPY) + .attachments(&blend_attachments) + .blend_constants([0.0, 0.0, 0.0, 0.0]); + + let pipeline_layout_info = vk::PipelineLayoutCreateInfo::builder(); + + let pipeline_layout = unsafe { + device.create_pipeline_layout(&pipeline_layout_info, None) + }?; + + let stages = [vertex_stage_info, fragment_stage_info]; + let pipeline_info + = vk::GraphicsPipelineCreateInfo::builder() + .stages(&stages) + .vertex_input_state(&vertex_input_state_info) + .input_assembly_state(&input_assembly_state_info) + .viewport_state(&viewport_state_info) + .rasterization_state(&rasterizer_state_info) + .multisample_state(&multisample_state_info) + .color_blend_state(&blend_info) + .layout(pipeline_layout) + .render_pass(*render_pass) + .subpass(0); + + let pipeline = unsafe { + device.create_graphics_pipelines(vk::PipelineCache::null(), + &[pipeline_info], None) + }?.0[0]; + + unsafe { + device.destroy_shader_module(vertex_module, None); + device.destroy_shader_module(fragment_module, None); + }; + + Ok((pipeline_layout, pipeline)) +} - for image_view in swapchain_image_views { - let attachments = [*image_view]; - let framebuffer_info = vk::FramebufferCreateInfo::builder() - .render_pass(*render_pass) - .attachments(&attachments) - .width(extent.width) - .height(extent.height) - .layers(1); +#[allow(unsafe_code)] +fn init_framebuffers(device: &Device, extent: &vk::Extent2D, + swapchain_image_views: &Vec<vk::ImageView>, + render_pass: &vk::RenderPass) + -> Result<Vec<vk::Framebuffer>> +{ + let mut framebuffers = Vec::new(); - let framebuffer = unsafe { - device.create_framebuffer(&framebuffer_info, None) - }?; + for image_view in swapchain_image_views { + let attachments = [*image_view]; - framebuffers.push(framebuffer); - } + let framebuffer_info = vk::FramebufferCreateInfo::builder() + .render_pass(*render_pass) + .attachments(&attachments) + .width(extent.width) + .height(extent.height) + .layers(1); - Ok(framebuffers) + let framebuffer = unsafe { + device.create_framebuffer(&framebuffer_info, None) + }?; + + framebuffers.push(framebuffer); } - #[allow(unsafe_code)] - fn init_commands(device: &Device, - extent: &vk::Extent2D, - framebuffers: &Vec<vk::Framebuffer>, - render_pass: &vk::RenderPass, - pipeline: &vk::Pipeline, - indices: &QueueFamilyIndices) - -> Result<(vk::CommandPool, Vec<vk::CommandBuffer>)> - { - // We call this one last time. It's kind of a problem. + Ok(framebuffers) +} - let command_pool_info = vk::CommandPoolCreateInfo::builder() - .flags(vk::CommandPoolCreateFlags::empty()) - .queue_family_index(indices.graphics); - let command_pool = unsafe { - device.create_command_pool(&command_pool_info, None) - }?; +#[allow(unsafe_code)] +fn init_commands(device: &Device, + extent: &vk::Extent2D, + framebuffers: &Vec<vk::Framebuffer>, + render_pass: &vk::RenderPass, + pipeline: &vk::Pipeline, + indices: &QueueFamilyIndices) + -> Result<(vk::CommandPool, Vec<vk::CommandBuffer>)> +{ + // We call this one last time. It's kind of a problem. + + let command_pool_info = vk::CommandPoolCreateInfo::builder() + .flags(vk::CommandPoolCreateFlags::empty()) + .queue_family_index(indices.graphics); + + let command_pool = unsafe { + device.create_command_pool(&command_pool_info, None) + }?; + + let command_buffer_allocation_info + = vk::CommandBufferAllocateInfo::builder() + .command_pool(command_pool) + .level(vk::CommandBufferLevel::PRIMARY) + .command_buffer_count(framebuffers.len() as u32); + let command_buffers = unsafe { + device.allocate_command_buffers(&command_buffer_allocation_info) + }?; + + for (index, framebuffer) in framebuffers.iter().enumerate() { + let command_buffer = command_buffers[index]; + + let inheritance_info = vk::CommandBufferInheritanceInfo::builder(); + + let command_buffer_begin_info + = vk::CommandBufferBeginInfo::builder() + .flags(vk::CommandBufferUsageFlags::empty()) + .inheritance_info(&inheritance_info); - let command_buffer_allocation_info - = vk::CommandBufferAllocateInfo::builder() - .command_pool(command_pool) - .level(vk::CommandBufferLevel::PRIMARY) - .command_buffer_count(framebuffers.len() as u32); - let command_buffers = unsafe { - device.allocate_command_buffers(&command_buffer_allocation_info) + unsafe { + device.begin_command_buffer(command_buffer, + &command_buffer_begin_info) }?; - for (index, framebuffer) in framebuffers.iter().enumerate() { - let command_buffer = command_buffers[index]; + let render_area = vk::Rect2D::builder() + .offset(vk::Offset2D::default()) + .extent(*extent); - let inheritance_info = vk::CommandBufferInheritanceInfo::builder(); - - let command_buffer_begin_info - = vk::CommandBufferBeginInfo::builder() - .flags(vk::CommandBufferUsageFlags::empty()) - .inheritance_info(&inheritance_info); + let clear_value = vk::ClearValue { + color: vk::ClearColorValue { + float32: [0.0, 0.0, 0.0, 1.0] + } + }; + let clear_values = [clear_value]; - unsafe { - device.begin_command_buffer(command_buffer, - &command_buffer_begin_info) - }?; + let begin_pass_info = vk::RenderPassBeginInfo::builder() + .render_pass(*render_pass) + .framebuffer(*framebuffer) + .render_area(render_area) + .clear_values(&clear_values); - let render_area = vk::Rect2D::builder() - .offset(vk::Offset2D::default()) - .extent(*extent); + unsafe { + device.cmd_begin_render_pass(command_buffer, &begin_pass_info, + vk::SubpassContents::INLINE) + }; - let clear_value = vk::ClearValue { - color: vk::ClearColorValue { - float32: [0.0, 0.0, 0.0, 1.0] - } - }; - let clear_values = [clear_value]; + unsafe { + device.cmd_bind_pipeline(command_buffer, + vk::PipelineBindPoint::GRAPHICS, + *pipeline) + }; - let begin_pass_info = vk::RenderPassBeginInfo::builder() - .render_pass(*render_pass) - .framebuffer(*framebuffer) - .render_area(render_area) - .clear_values(&clear_values); + unsafe { device.cmd_draw(command_buffer, 3, 1, 0, 0) }; - unsafe { - device.cmd_begin_render_pass(command_buffer, &begin_pass_info, - vk::SubpassContents::INLINE) - }; + unsafe { device.cmd_end_render_pass(command_buffer) }; - unsafe { - device.cmd_bind_pipeline(command_buffer, - vk::PipelineBindPoint::GRAPHICS, - *pipeline) - }; + unsafe { device.end_command_buffer(command_buffer) }?; + } - unsafe { device.cmd_draw(command_buffer, 3, 1, 0, 0) }; + Ok((command_pool, command_buffers)) +} - unsafe { device.cmd_end_render_pass(command_buffer) }; - unsafe { device.end_command_buffer(command_buffer) }?; - } +#[allow(unsafe_code)] +fn init_concurrency(device: &Device, + swapchain_images: &Vec<vk::Image>) + -> Result<Concurrency> +{ + let semaphore_info = vk::SemaphoreCreateInfo::builder(); + let fence_info = vk::FenceCreateInfo::builder() + .flags(vk::FenceCreateFlags::SIGNALED); + + let mut image_available_semaphores = Vec::new(); + let mut rendering_finished_semaphores = Vec::new(); + let mut frame_fences = Vec::new(); + for _ in 0 .. N_SIMULTANEOUS_FRAMES { + image_available_semaphores.push(unsafe { + device.create_semaphore(&semaphore_info, None) + }?); + + rendering_finished_semaphores.push(unsafe { + device.create_semaphore(&semaphore_info, None) + }?); + + frame_fences.push(unsafe { + device.create_fence(&fence_info, None) + }?); + } - Ok((command_pool, command_buffers)) + let mut image_fences = Vec::new(); + for _ in 0 .. swapchain_images.len() { + image_fences.push(vk::Fence::null()); } - #[allow(unsafe_code)] - fn init_concurrency(device: &Device, - swapchain_images: &Vec<vk::Image>) - -> Result<Concurrency> - { - let semaphore_info = vk::SemaphoreCreateInfo::builder(); - let fence_info = vk::FenceCreateInfo::builder() - .flags(vk::FenceCreateFlags::SIGNALED); - - let mut image_available_semaphores = Vec::new(); - let mut rendering_finished_semaphores = Vec::new(); - let mut frame_fences = Vec::new(); - for _ in 0 .. N_SIMULTANEOUS_FRAMES { - image_available_semaphores.push(unsafe { - device.create_semaphore(&semaphore_info, None) - }?); - - rendering_finished_semaphores.push(unsafe { - device.create_semaphore(&semaphore_info, None) - }?); - - frame_fences.push(unsafe { - device.create_fence(&fence_info, None) - }?); - } + Ok(Concurrency { + image_available_semaphores, + rendering_finished_semaphores, + frame_fences, + image_fences: image_fences, + }) +} - let mut image_fences = Vec::new(); - for _ in 0 .. swapchain_images.len() { - image_fences.push(vk::Fence::null()); - } - Ok(Concurrency { - image_available_semaphores, - rendering_finished_semaphores, - frame_fences, - image_fences: image_fences, - }) +fn pick_surface_format(available_formats: &Vec<vk::SurfaceFormatKHR>) + -> Result<vk::SurfaceFormatKHR> +{ + for format in available_formats { + if format.format == vk::Format::B8G8R8A8_SRGB + && format.color_space == vk::ColorSpaceKHR::SRGB_NONLINEAR + { + return Ok(format.clone()); + } } - fn pick_surface_format(available_formats: &Vec<vk::SurfaceFormatKHR>) - -> Result<vk::SurfaceFormatKHR> - { - for format in available_formats { - if format.format == vk::Format::B8G8R8A8_SRGB - && format.color_space == vk::ColorSpaceKHR::SRGB_NONLINEAR - { - return Ok(format.clone()); - } - } + return Ok(available_formats[0].clone()); +} - return Ok(available_formats[0].clone()); - } - fn pick_presentation_mode(_available_modes: &Vec<vk::PresentModeKHR>) - -> Result<vk::PresentModeKHR> - { - // It's guaranteed to have this one. - return Ok(vk::PresentModeKHR::FIFO); - } +fn pick_presentation_mode(_available_modes: &Vec<vk::PresentModeKHR>) + -> Result<vk::PresentModeKHR> +{ + // It's guaranteed to have this one. + return Ok(vk::PresentModeKHR::FIFO); +} - fn pick_image_extent(window: &Window, - capabilities: vk::SurfaceCapabilitiesKHR) - -> Result<vk::Extent2D> + +fn pick_image_extent(window: &Window, + capabilities: vk::SurfaceCapabilitiesKHR) + -> Result<vk::Extent2D> +{ + if capabilities.current_extent.width != u32::MAX + && capabilities.current_extent.height != u32::MAX { - if capabilities.current_extent.width != u32::MAX - && capabilities.current_extent.height != u32::MAX - { - Ok(capabilities.current_extent) - } else { - let window_size = window.inner_size(); - - let width = window_size.width - .clamp(capabilities.min_image_extent.width, - capabilities.max_image_extent.width); - let height = window_size.height - .clamp(capabilities.min_image_extent.height, - capabilities.max_image_extent.height); - - Ok(vk::Extent2D::builder().width(width).height(height).build()) - } + Ok(capabilities.current_extent) + } else { + let window_size = window.inner_size(); + + let width = window_size.width + .clamp(capabilities.min_image_extent.width, + capabilities.max_image_extent.width); + let height = window_size.height + .clamp(capabilities.min_image_extent.height, + capabilities.max_image_extent.height); + + Ok(vk::Extent2D::builder().width(width).height(height).build()) } } + |