Add option to reuse renderpass in rendertarget
This commit is contained in:
parent
dca9ab20be
commit
358c3c5182
5 changed files with 217 additions and 246 deletions
|
@ -9,6 +9,7 @@ pub mod sub_pass;
|
||||||
use sub_pass::{AttachmentInfo, AttachmentInfoUsage, SubPass};
|
use sub_pass::{AttachmentInfo, AttachmentInfoUsage, SubPass};
|
||||||
|
|
||||||
pub struct RenderTargetBuilder {
|
pub struct RenderTargetBuilder {
|
||||||
|
old_render_target: Option<RenderTarget>,
|
||||||
sub_passes: Vec<SubPass>,
|
sub_passes: Vec<SubPass>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +20,12 @@ impl RenderTargetBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn preserve_old_render_pass(mut self, render_target: RenderTarget) -> Self {
|
||||||
|
self.old_render_target = Some(render_target);
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn build(self, device: &Arc<Device>) -> Result<RenderTarget> {
|
pub fn build(self, device: &Arc<Device>) -> Result<RenderTarget> {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
{
|
{
|
||||||
|
@ -33,8 +40,24 @@ impl RenderTargetBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create render pass
|
let mut clear_values = Vec::new();
|
||||||
|
|
||||||
|
self.map_attachment(|attachment| {
|
||||||
|
clear_values.push(attachment.clear_value.clone());
|
||||||
|
});
|
||||||
|
|
||||||
|
// create render pass
|
||||||
|
let render_pass = match self.old_render_target {
|
||||||
|
Some(old_render_target) => {
|
||||||
|
if !Self::verify_setups(&old_render_target.sub_passes, &self.sub_passes) {
|
||||||
|
return Err(anyhow::anyhow!(
|
||||||
|
"Can't preserve old RenderPass if subpasses don't match!"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
old_render_target.render_pass
|
||||||
|
}
|
||||||
|
None => {
|
||||||
// gather attachment descriptions
|
// gather attachment descriptions
|
||||||
let mut attachments = Vec::new();
|
let mut attachments = Vec::new();
|
||||||
|
|
||||||
|
@ -82,7 +105,8 @@ impl RenderTargetBuilder {
|
||||||
if let Some(input_info) = sub_pass.inputs() {
|
if let Some(input_info) = sub_pass.inputs() {
|
||||||
debug_assert!(input_info.sub_pass_index < attachment_references.len());
|
debug_assert!(input_info.sub_pass_index < attachment_references.len());
|
||||||
|
|
||||||
let input_pass_references = &attachment_references[input_info.sub_pass_index];
|
let input_pass_references =
|
||||||
|
&attachment_references[input_info.sub_pass_index];
|
||||||
|
|
||||||
for input_index in input_info.input_indices.iter() {
|
for input_index in input_info.input_indices.iter() {
|
||||||
references.input_attachments.push(VkAttachmentReference {
|
references.input_attachments.push(VkAttachmentReference {
|
||||||
|
@ -140,53 +164,19 @@ impl RenderTargetBuilder {
|
||||||
last_dependency.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT.into();
|
last_dependency.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
// dependencies.push(VkSubpassDependency::new(
|
RenderPass::new(device.clone(), &descriptions, &attachments, &dependencies)?
|
||||||
// self.sub_passes.len() as u32 - 1,
|
}
|
||||||
// VK_SUBPASS_EXTERNAL,
|
};
|
||||||
// VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
|
||||||
// VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
|
||||||
// VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
|
||||||
// VK_ACCESS_MEMORY_READ_BIT,
|
|
||||||
// VK_DEPENDENCY_BY_REGION_BIT,
|
|
||||||
// ));
|
|
||||||
|
|
||||||
let render_pass =
|
|
||||||
RenderPass::new(device.clone(), &descriptions, &attachments, &dependencies)?;
|
|
||||||
|
|
||||||
// create frame buffers
|
// create frame buffers
|
||||||
let max_images = self.max_images();
|
let framebuffers = Self::create_framebuffers(&render_pass, &self.sub_passes)?;
|
||||||
let extent = self.sub_passes[0].extent();
|
|
||||||
|
|
||||||
let framebuffers: Result<Vec<Arc<Framebuffer>>> = (0..max_images)
|
|
||||||
.map(|i| {
|
|
||||||
let mut framebuffer_builder = Framebuffer::builder()
|
|
||||||
.set_render_pass(&render_pass)
|
|
||||||
.set_width(extent.width)
|
|
||||||
.set_height(extent.height);
|
|
||||||
|
|
||||||
for sub_pass in self.sub_passes.iter() {
|
|
||||||
for attachment in sub_pass.attachments().iter() {
|
|
||||||
framebuffer_builder =
|
|
||||||
framebuffer_builder.add_attachment(attachment.image(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
framebuffer_builder.build(render_pass.device().clone())
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let mut clear_values = Vec::new();
|
|
||||||
|
|
||||||
self.map_attachment(|attachment| {
|
|
||||||
clear_values.push(attachment.clear_value.clone());
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(RenderTarget {
|
Ok(RenderTarget {
|
||||||
render_pass,
|
render_pass,
|
||||||
framebuffers: framebuffers?,
|
framebuffers,
|
||||||
clear_values,
|
clear_values,
|
||||||
|
|
||||||
extent,
|
extent: self.sub_passes[0].extent(),
|
||||||
|
|
||||||
sub_passes: self.sub_passes,
|
sub_passes: self.sub_passes,
|
||||||
|
|
||||||
|
@ -195,17 +185,56 @@ impl RenderTargetBuilder {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_framebuffers(
|
||||||
|
render_pass: &Arc<RenderPass>,
|
||||||
|
sub_passes: &[SubPass],
|
||||||
|
) -> Result<Vec<Arc<Framebuffer>>> {
|
||||||
|
let extent = sub_passes[0].extent();
|
||||||
|
|
||||||
|
(0..Self::max_images(sub_passes))
|
||||||
|
.map(|i| {
|
||||||
|
let mut framebuffer_builder = Framebuffer::builder()
|
||||||
|
.set_render_pass(render_pass)
|
||||||
|
.set_width(extent.width)
|
||||||
|
.set_height(extent.height);
|
||||||
|
|
||||||
|
for sub_pass in sub_passes.iter() {
|
||||||
|
for attachment in sub_pass.attachments().iter() {
|
||||||
|
framebuffer_builder =
|
||||||
|
framebuffer_builder.add_attachment(attachment.image(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
framebuffer_builder.build(render_pass.device().clone())
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn max_images(&self) -> usize {
|
fn max_images(sub_passes: &[SubPass]) -> usize {
|
||||||
let mut max_images = 0;
|
let mut max_images = 0;
|
||||||
|
|
||||||
for sub_pass in self.sub_passes.iter() {
|
for sub_pass in sub_passes.iter() {
|
||||||
max_images = max_images.max(sub_pass.max_images_per_attachment());
|
max_images = max_images.max(sub_pass.max_images_per_attachment());
|
||||||
}
|
}
|
||||||
|
|
||||||
max_images
|
max_images
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn verify_setups(old_sub_passes: &[SubPass], new_sub_passes: &[SubPass]) -> bool {
|
||||||
|
if old_sub_passes.len() != new_sub_passes.len() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (new_sub_pass, old_sub_pass) in old_sub_passes.iter().zip(new_sub_passes.iter()) {
|
||||||
|
if !new_sub_pass.verify_setup(old_sub_pass) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn map_attachment<'a, F>(&'a self, mut f: F)
|
fn map_attachment<'a, F>(&'a self, mut f: F)
|
||||||
where
|
where
|
||||||
|
@ -247,6 +276,7 @@ pub struct RenderTarget {
|
||||||
impl RenderTarget {
|
impl RenderTarget {
|
||||||
pub fn builder() -> RenderTargetBuilder {
|
pub fn builder() -> RenderTargetBuilder {
|
||||||
RenderTargetBuilder {
|
RenderTargetBuilder {
|
||||||
|
old_render_target: None,
|
||||||
sub_passes: Vec::new(),
|
sub_passes: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -315,99 +345,3 @@ impl RenderTarget {
|
||||||
buffer_recorder.end_render_pass();
|
buffer_recorder.end_render_pass();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl<'a> RenderTargetBuilder<'a> {
|
|
||||||
// fn create_images_and_renderpass(&self, device: &Arc<Device>) -> Result<Arc<RenderPass>> {
|
|
||||||
// let subpass_descriptions = [match resolve_reference {
|
|
||||||
// Some(resvole_ref) => VkSubpassDescription::new(
|
|
||||||
// 0,
|
|
||||||
// &[],
|
|
||||||
// color_references.as_slice(),
|
|
||||||
// &[resvole_ref],
|
|
||||||
// match depth_reference {
|
|
||||||
// Some(ref depth_ref) => Some(depth_ref),
|
|
||||||
// None => None,
|
|
||||||
// },
|
|
||||||
// &[],
|
|
||||||
// ),
|
|
||||||
// None => VkSubpassDescription::new(
|
|
||||||
// 0,
|
|
||||||
// &[],
|
|
||||||
// color_references.as_slice(),
|
|
||||||
// &[],
|
|
||||||
// match depth_reference {
|
|
||||||
// Some(ref depth_ref) => Some(depth_ref),
|
|
||||||
// None => None,
|
|
||||||
// },
|
|
||||||
// &[],
|
|
||||||
// ),
|
|
||||||
// }];
|
|
||||||
|
|
||||||
// let dependencies = if color_references.is_empty() {
|
|
||||||
// // assume, that when no color references are given,
|
|
||||||
// // we want to store the depth information for later
|
|
||||||
// if depth_reference.is_some() {
|
|
||||||
// for attachment in &mut attachments {
|
|
||||||
// if attachment.format == VK_FORMAT_D16_UNORM {
|
|
||||||
// attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
|
||||||
// attachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// [
|
|
||||||
// VkSubpassDependency::new(
|
|
||||||
// VK_SUBPASS_EXTERNAL,
|
|
||||||
// 0,
|
|
||||||
// VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
|
||||||
// VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
|
||||||
// 0,
|
|
||||||
// VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
|
|
||||||
// | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
|
||||||
// VK_DEPENDENCY_BY_REGION_BIT,
|
|
||||||
// ),
|
|
||||||
// VkSubpassDependency::new(
|
|
||||||
// 0,
|
|
||||||
// VK_SUBPASS_EXTERNAL,
|
|
||||||
// VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
|
||||||
// VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
|
||||||
// VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
|
|
||||||
// | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
|
||||||
// VK_ACCESS_SHADER_READ_BIT,
|
|
||||||
// VK_DEPENDENCY_BY_REGION_BIT,
|
|
||||||
// ),
|
|
||||||
// ]
|
|
||||||
// } else {
|
|
||||||
// [
|
|
||||||
// VkSubpassDependency::new(
|
|
||||||
// VK_SUBPASS_EXTERNAL,
|
|
||||||
// 0,
|
|
||||||
// VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
|
||||||
// VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
|
||||||
// VK_ACCESS_MEMORY_READ_BIT,
|
|
||||||
// VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
|
||||||
// VK_DEPENDENCY_BY_REGION_BIT,
|
|
||||||
// ),
|
|
||||||
// VkSubpassDependency::new(
|
|
||||||
// 0,
|
|
||||||
// VK_SUBPASS_EXTERNAL,
|
|
||||||
// VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
|
||||||
// VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
|
||||||
// VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
|
||||||
// VK_ACCESS_MEMORY_READ_BIT,
|
|
||||||
// VK_DEPENDENCY_BY_REGION_BIT,
|
|
||||||
// ),
|
|
||||||
// ]
|
|
||||||
// };
|
|
||||||
|
|
||||||
// let renderpass = RenderPass::new(
|
|
||||||
// device.clone(),
|
|
||||||
// &subpass_descriptions,
|
|
||||||
// attachments.as_slice(),
|
|
||||||
// &dependencies,
|
|
||||||
// )?;
|
|
||||||
|
|
||||||
// Ok(renderpass)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
|
@ -157,7 +157,7 @@ impl<'a> From<&'a Vec<Arc<Image>>> for ResolveTarget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct InputAttachmentInfo {
|
pub struct InputAttachmentInfo {
|
||||||
pub sub_pass_index: usize,
|
pub sub_pass_index: usize,
|
||||||
pub input_indices: Vec<usize>,
|
pub input_indices: Vec<usize>,
|
||||||
|
@ -383,6 +383,13 @@ impl AttachmentInfo {
|
||||||
|
|
||||||
&self.images[index]
|
&self.images[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn verify_setup(&self, other: &Self) -> bool {
|
||||||
|
self.clear_value == other.clear_value
|
||||||
|
&& self.layout == other.layout
|
||||||
|
&& self.description == other.description
|
||||||
|
&& self.usage == other.usage
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -439,4 +446,34 @@ impl SubPass {
|
||||||
|
|
||||||
max_images
|
max_images
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn verify_setup(&self, other: &Self) -> bool {
|
||||||
|
if self.output_usage != other.output_usage {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
match (&self.input_info, &other.input_info) {
|
||||||
|
(None, None) => (),
|
||||||
|
(Some(self_input_info), Some(other_input_info)) => {
|
||||||
|
if self_input_info != other_input_info {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(None, Some(_)) | (Some(_), None) => return false,
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.attachments.len() != other.attachments.len() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (self_attachment, other_attachment) in
|
||||||
|
self.attachments.iter().zip(other.attachments.iter())
|
||||||
|
{
|
||||||
|
if !self_attachment.verify_setup(other_attachment) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct VkAttachmentDescription {
|
pub struct VkAttachmentDescription {
|
||||||
pub flags: VkAttachmentDescriptionFlagBits,
|
pub flags: VkAttachmentDescriptionFlagBits,
|
||||||
pub format: VkFormat,
|
pub format: VkFormat,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct VkClearColorValue([u32; 4]);
|
pub struct VkClearColorValue([u32; 4]);
|
||||||
|
|
||||||
impl VkClearColorValue {
|
impl VkClearColorValue {
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::prelude::*;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct VkClearValue(VkClearColorValue);
|
pub struct VkClearValue(VkClearColorValue);
|
||||||
|
|
||||||
impl VkClearValue {
|
impl VkClearValue {
|
||||||
|
|
Loading…
Reference in a new issue