diff --git a/vulkan-rs/src/prelude.rs b/vulkan-rs/src/prelude.rs index 288c0f4..8df00f3 100644 --- a/vulkan-rs/src/prelude.rs +++ b/vulkan-rs/src/prelude.rs @@ -43,9 +43,6 @@ pub use super::{OutOfDate, VkHandle, VulkanDevice}; pub use image; pub use vulkan_sys::prelude::*; -pub use super::render_target::{ - sub_pass::{ClearValue, CustomTarget, SubPass, SubPassBuilder}, - RenderTarget, -}; +pub use super::render_target::{sub_pass::*, *}; pub use super::single_submit::SingleSubmit; diff --git a/vulkan-rs/src/render_target/mod.rs b/vulkan-rs/src/render_target/mod.rs index b99ce17..bda1675 100644 --- a/vulkan-rs/src/render_target/mod.rs +++ b/vulkan-rs/src/render_target/mod.rs @@ -345,3 +345,109 @@ impl RenderTarget { buffer_recorder.end_render_pass(); } } + +#[cfg(test)] +mod test { + use crate::prelude::*; + use anyhow::Result; + + use std::sync::{Arc, Mutex}; + + fn create_vk_handles() -> Result<(Arc, Arc>)> { + let instance = Instance::new( + VkApplicationInfo::new( + &VkString::new("Test"), + 1, + &VkString::new("no name"), + 1, + VK_MAKE_VERSION(1, 3, 0), + ), + VulkanDebugInfo::default(), + InstanceExtensions::default(), + )?; + + let physical_device = PhysicalDevice::new(instance)?; + + let queue_info = Queue::create_non_presentable_request_info( + &physical_device, + VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_TRANSFER_BIT, + )?; + + let device = Device::new( + physical_device, + DeviceExtensions::default(), + &[queue_info.queue_create_info], + DeviceFeatures::default(), + )?; + + let queue = device.get_queue(queue_info.queue_family_index, queue_info.queue_index); + + Ok((device, queue)) + } + + #[test] + fn test_render_target() { + let (device, queue) = create_vk_handles().unwrap(); + + let target_images: Vec> = (0..2) + .map(|_| { + let image = Image::empty( + 1920, + 1080, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + VK_SAMPLE_COUNT_1_BIT, + ) + .format(VK_FORMAT_R8G8B8A8_UNORM) + .build(&device, &queue)?; + + image.convert_layout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)?; + + Ok(image) + }) + .collect::>>>() + .unwrap(); + + RenderTarget::builder() + .add_sub_pass( + SubPass::builder(target_images[0].width(), target_images[0].height()) + .set_prepared_targets(&target_images, 0, [0.0, 0.0, 0.0, 0.0], false) + .build(&device) + .unwrap(), + ) + .add_sub_pass( + SubPass::builder(target_images[0].width(), target_images[0].height()) + .add_target_info(CustomTarget { + usage: VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT.into(), + format: VK_FORMAT_R8G8B8A8_UNORM, + clear_on_load: true, + store_on_save: true, + attach_sampler: false, + use_as_input: false, + clear_value: ClearValue::Color([0.0, 0.0, 0.0, 0.0]), + }) + .set_sample_count(VK_SAMPLE_COUNT_4_BIT) + .add_resolve_targets(CustomTarget::resolve( + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + VK_FORMAT_R8G8B8A8_UNORM, + None, + false, + true, + )) + .use_queue(queue.clone()) + .build(&device) + .unwrap(), + ) + .add_sub_pass( + SubPass::builder(target_images[0].width(), target_images[0].height()) + .set_input_attachment_info(InputAttachmentInfo { + sub_pass_index: 1, + input_indices: vec![1], + }) + .set_prepared_targets(&target_images, 0, [0.0, 0.0, 0.0, 0.0], false) + .build(&device) + .unwrap(), + ) + .build(&device) + .unwrap(); + } +} diff --git a/vulkan-rs/src/render_target/sub_pass.rs b/vulkan-rs/src/render_target/sub_pass.rs index a13a5f8..38c1095 100644 --- a/vulkan-rs/src/render_target/sub_pass.rs +++ b/vulkan-rs/src/render_target/sub_pass.rs @@ -18,8 +18,8 @@ pub struct CustomTarget { } impl CustomTarget { - pub fn depth() -> CustomTarget { - CustomTarget { + pub fn depth() -> Self { + Self { usage: VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT.into(), format: VK_FORMAT_D16_UNORM, clear_on_load: true, @@ -30,6 +30,30 @@ impl CustomTarget { } } + pub fn resolve( + usage: impl Into, + format: VkFormat, + clear_value: impl Into>, + attach_sampler: bool, + use_as_input: bool, + ) -> Self { + let clear_value = clear_value.into(); + + Self { + usage: usage.into(), + format, + clear_on_load: if use_as_input { + false + } else { + clear_value.is_some() + }, + store_on_save: true, + attach_sampler, + use_as_input, + clear_value: clear_value.unwrap_or(ClearValue::Color([0.0, 0.0, 0.0, 0.0])), + } + } + fn to_attachment_info( &self, device: &Arc, @@ -104,7 +128,13 @@ impl CustomTarget { unimplemented!(); }; - let mut image_builder = Image::empty(width, height, self.usage, sample_count) + let mut vk_usage = self.usage; + + if self.use_as_input { + vk_usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; + } + + let mut image_builder = Image::empty(width, height, vk_usage, sample_count) .format(format) .aspect_mask(aspect); @@ -114,8 +144,6 @@ impl CustomTarget { let image = image_builder.build(device, queue)?; - image.convert_layout(layout)?; - match aspect { VK_IMAGE_ASPECT_DEPTH_BIT => { Image::convert_layout(&image, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL)?