// ================================================================================
//  Pipeline Helper Methods
// ================================================================================
// TODO(issue#35) make custom story related to issue 2 for custom render passes,
// but not needed for basic single pass pipelines.
/// Creates a simple forward render pass with one subpass.
Pipeline Helper Methods
TODO(issue#35) make custom story related to issue 2 for custom render passes,
but not needed for basic single pass pipelines.
Creates a simple forward render pass with one subpass.
Pipeline Helper Methods TODO ( issue#35 ) make custom story related to issue 2 for custom render passes but not needed for basic single pass pipelines . Creates a simple forward render pass with one subpass .
fn create_forward_render_pass(
    logical_device: &Device, format: vk::Format, depth_buffer: &DepthAttachment,
    num_msaa_samples: NumSamples,
  ) -> SarektResult<vk::RenderPass> {
    // TODO(issue#9) OFFSCREEN only make swapchain optimal if this is going to
    // present. Otherwise TransferDST optimal would be good.
    // Used to reference attachments in render passes.
    // This is the non MSAA sampled color attachment.
    let color_attachment_final_layout = if !matches!(num_msaa_samples, NumSamples::One) {
      vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL
    } else {
      vk::ImageLayout::PRESENT_SRC_KHR
    };
    let color_attachment = vk::AttachmentDescription::builder()
      .format(format)
      .samples(num_msaa_samples.into())
      .load_op(vk::AttachmentLoadOp::CLEAR) // Clear on loading the color attachment, since we're writing over it.
      .store_op(vk::AttachmentStoreOp::STORE) // Want to save to this attachment in the pass.
      .stencil_load_op(vk::AttachmentLoadOp::DONT_CARE) // Not using stencil.
      .stencil_store_op(vk::AttachmentStoreOp::DONT_CARE) // Not using stencil.
      .initial_layout(vk::ImageLayout::UNDEFINED) // Don't know the layout coming in.
      .final_layout(color_attachment_final_layout)
      .build();
    // Used to reference attachments in subpasses.
    let color_attachment_ref = vk::AttachmentReference::builder()
      .attachment(0u32) // Only using 1 (indexed from 0) attachment.
      .layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL) // We're drawing color so optimize the pass to draw color to this attachment.
      .build();
    let color_attachment_refs = [color_attachment_ref];
    // This is the non sampled depth attachment
    let depth_attachment = vk::AttachmentDescription::builder()
      .format(depth_buffer.format)
      .samples(num_msaa_samples.into())
      .load_op(vk::AttachmentLoadOp::CLEAR)
      .store_op(vk::AttachmentStoreOp::DONT_CARE)
      .stencil_load_op(vk::AttachmentLoadOp::DONT_CARE)
      .stencil_store_op(vk::AttachmentStoreOp::DONT_CARE)
      .initial_layout(vk::ImageLayout::UNDEFINED)
      .final_layout(vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
      .build();
    let depth_attachment_ref = vk::AttachmentReference::builder()
      .attachment(1)
      .layout(vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
      .build();
    // This is the resolved MSAA (and presented) color attachment. Unused if MSAA
    // disabled.
    let resolve_attachment = vk::AttachmentDescription::builder()
      .format(format)
      .samples(vk::SampleCountFlags::TYPE_1)
      .load_op(vk::AttachmentLoadOp::DONT_CARE)
      .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)
      .build();
    let resolve_attachment_refs = [vk::AttachmentReference::builder()
      .attachment(2)
      .layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL)
      .build()];
    let attachments = if !matches!(num_msaa_samples, NumSamples::One) {
      vec![color_attachment, depth_attachment, resolve_attachment]
    } else {
      vec![color_attachment, depth_attachment]
    };
    // Subpasses could also reference previous subpasses as input, depth/stencil
    // data, or preserve attachments to send them to the next subpass.
    let mut subpass_description = vk::SubpassDescription::builder()
      .pipeline_bind_point(vk::PipelineBindPoint::GRAPHICS) // This is a graphics subpass
      // index of this attachment here is a reference to the output of the shader in the form of layout(location = 0).
      .color_attachments(&color_attachment_refs)
      .depth_stencil_attachment(&depth_attachment_ref);
    if !matches!(num_msaa_samples, NumSamples::One) {
      subpass_description = subpass_description.resolve_attachments(&resolve_attachment_refs);
    }
    let subpass_descriptions = [subpass_description.build()];
    let dependency = vk::SubpassDependency::builder()
      .src_subpass(vk::SUBPASS_EXTERNAL)
      .dst_subpass(0u32)
      .src_stage_mask(vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT) // We need to wait until the image is not in use (by the swapchain for example).
      .src_access_mask(vk::AccessFlags::empty()) // We're not going to access the swapchain as a source.
      .dst_stage_mask(vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT) // Anyone waiting on this should wait in the color attachment stage.
      .dst_access_mask(vk::AccessFlags::COLOR_ATTACHMENT_READ | vk::AccessFlags::COLOR_ATTACHMENT_WRITE) // Dependents should wait if they read or write the color attachment.
      .build();
    let dependencies = [dependency];
    let render_pass_ci = vk::RenderPassCreateInfo::builder()
      .attachments(&attachments)
      .subpasses(&subpass_descriptions) // Only one subpass in this case.
      .dependencies(&dependencies) // Only one dep.
      .build();
    Ok(unsafe { logical_device.create_render_pass(&render_pass_ci, None)? })
  }
fn create_forward_render_pass ( logical_device : & Device , format : vk :: Format , depth_buffer : & DepthAttachment , num_msaa_samples : NumSamples , ) -> SarektResult < vk :: RenderPass > { // TODO(issue#9) OFFSCREEN only make swapchain optimal if this is going to // present. Otherwise TransferDST optimal would be good. // Used to reference attachments in render passes. // This is the non MSAA sampled color attachment. let color_attachment_final_layout = if ! matches ! ( num_msaa_samples NumSamples One ) { vk :: ImageLayout :: COLOR_ATTACHMENT_OPTIMAL } else { vk :: ImageLayout :: PRESENT_SRC_KHR } ; let color_attachment = vk :: AttachmentDescription :: builder ( ) . format ( format ) . samples ( num_msaa_samples . into ( ) ) . load_op ( vk :: AttachmentLoadOp :: CLEAR ) // Clear on loading the color attachment, since we're writing over it. . store_op ( vk :: AttachmentStoreOp :: STORE ) // Want to save to this attachment in the pass. . stencil_load_op ( vk :: AttachmentLoadOp :: DONT_CARE ) // Not using stencil. . stencil_store_op ( vk :: AttachmentStoreOp :: DONT_CARE ) // Not using stencil. . initial_layout ( vk :: ImageLayout :: UNDEFINED ) // Don't know the layout coming in. . final_layout ( color_attachment_final_layout ) . build ( ) ; // Used to reference attachments in subpasses. let color_attachment_ref = vk :: AttachmentReference :: builder ( ) . attachment ( 0u32 ) // Only using 1 (indexed from 0) attachment. . layout ( vk :: ImageLayout :: COLOR_ATTACHMENT_OPTIMAL ) // We're drawing color so optimize the pass to draw color to this attachment. . build ( ) ; let color_attachment_refs = [ color_attachment_ref ] ; // This is the non sampled depth attachment let depth_attachment = vk :: AttachmentDescription :: builder ( ) . format ( depth_buffer . format ) . samples ( num_msaa_samples . into ( ) ) . load_op ( vk :: AttachmentLoadOp :: CLEAR ) . store_op ( vk :: AttachmentStoreOp :: DONT_CARE ) . stencil_load_op ( vk :: AttachmentLoadOp :: DONT_CARE ) . stencil_store_op ( vk :: AttachmentStoreOp :: DONT_CARE ) . initial_layout ( vk :: ImageLayout :: UNDEFINED ) . final_layout ( vk :: ImageLayout :: DEPTH_STENCIL_ATTACHMENT_OPTIMAL ) . build ( ) ; let depth_attachment_ref = vk :: AttachmentReference :: builder ( ) . attachment ( 1 ) . layout ( vk :: ImageLayout :: DEPTH_STENCIL_ATTACHMENT_OPTIMAL ) . build ( ) ; // This is the resolved MSAA (and presented) color attachment. Unused if MSAA // disabled. let resolve_attachment = vk :: AttachmentDescription :: builder ( ) . format ( format ) . samples ( vk :: SampleCountFlags :: TYPE_1 ) . load_op ( vk :: AttachmentLoadOp :: DONT_CARE ) . 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 ) . build ( ) ; let resolve_attachment_refs = [ vk :: AttachmentReference :: builder ( ) . attachment ( 2 ) . layout ( vk :: ImageLayout :: COLOR_ATTACHMENT_OPTIMAL ) . build ( ) ] ; let attachments = if ! matches ! ( num_msaa_samples NumSamples One ) { vec ! [ color_attachment depth_attachment resolve_attachment ] } else { vec ! [ color_attachment depth_attachment ] } ; // Subpasses could also reference previous subpasses as input, depth/stencil // data, or preserve attachments to send them to the next subpass. let mut subpass_description = vk :: SubpassDescription :: builder ( ) . pipeline_bind_point ( vk :: PipelineBindPoint :: GRAPHICS ) // This is a graphics subpass // index of this attachment here is a reference to the output of the shader in the form of layout(location = 0). . color_attachments ( & color_attachment_refs ) . depth_stencil_attachment ( & depth_attachment_ref ) ; if ! matches ! ( num_msaa_samples NumSamples One ) { subpass_description = subpass_description . resolve_attachments ( & resolve_attachment_refs ) ; } let subpass_descriptions = [ subpass_description . build ( ) ] ; let dependency = vk :: SubpassDependency :: builder ( ) . src_subpass ( vk :: SUBPASS_EXTERNAL ) . dst_subpass ( 0u32 ) . src_stage_mask ( vk :: PipelineStageFlags :: COLOR_ATTACHMENT_OUTPUT ) // We need to wait until the image is not in use (by the swapchain for example). . src_access_mask ( vk :: AccessFlags :: empty ( ) ) // We're not going to access the swapchain as a source. . dst_stage_mask ( vk :: PipelineStageFlags :: COLOR_ATTACHMENT_OUTPUT ) // Anyone waiting on this should wait in the color attachment stage. . dst_access_mask ( vk :: AccessFlags :: COLOR_ATTACHMENT_READ | vk :: AccessFlags :: COLOR_ATTACHMENT_WRITE ) // Dependents should wait if they read or write the color attachment. . build ( ) ; let dependencies = [ dependency ] ; let render_pass_ci = vk :: RenderPassCreateInfo :: builder ( ) . attachments ( & attachments ) . subpasses ( & subpass_descriptions ) // Only one subpass in this case. . dependencies ( & dependencies ) // Only one dep. . build ( ) ; Ok ( unsafe { logical_device . create_render_pass ( & render_pass_ci , None ) ? } ) }
Pipeline Helper Methods
TODO(issue#35) make custom story related to issue 2 for custom render passes,
but not needed for basic single pass pipelines.
Pipeline Helper Methods TODO ( issue#35 ) make custom story related to issue 2 for custom render passes but not needed for basic single pass pipelines .
logical_device
&Device
format
vk::Format
depth_buffer
&DepthAttachment
num_msaa_samples
NumSamples