2022-06-24 15:27:33 +00:00
|
|
|
use crate::pixels_draw_pipeline::PixelsDrawPipeline;
|
2022-10-27 18:59:47 +00:00
|
|
|
use std::sync::Arc;
|
2021-09-13 15:14:54 +00:00
|
|
|
use vulkano::{
|
2022-04-24 01:16:19 +00:00
|
|
|
command_buffer::{
|
2024-10-19 12:13:15 +00:00
|
|
|
allocator::StandardCommandBufferAllocator, AutoCommandBufferBuilder, CommandBufferUsage,
|
2024-10-18 18:00:21 +00:00
|
|
|
RenderPassBeginInfo, SubpassBeginInfo, SubpassContents,
|
2022-04-24 01:16:19 +00:00
|
|
|
},
|
2022-10-05 09:09:26 +00:00
|
|
|
descriptor_set::allocator::StandardDescriptorSetAllocator,
|
2021-09-13 15:14:54 +00:00
|
|
|
device::Queue,
|
|
|
|
format::Format,
|
2023-07-03 20:37:29 +00:00
|
|
|
image::view::ImageView,
|
2022-02-20 00:14:16 +00:00
|
|
|
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
2021-09-13 15:14:54 +00:00
|
|
|
sync::GpuFuture,
|
|
|
|
};
|
|
|
|
|
2023-03-05 18:56:35 +00:00
|
|
|
/// A render pass which places an incoming image over frame filling it.
|
2021-09-13 15:14:54 +00:00
|
|
|
pub struct RenderPassPlaceOverFrame {
|
|
|
|
gfx_queue: Arc<Queue>,
|
|
|
|
render_pass: Arc<RenderPass>,
|
|
|
|
pixels_draw_pipeline: PixelsDrawPipeline,
|
2022-10-27 18:59:47 +00:00
|
|
|
command_buffer_allocator: Arc<StandardCommandBufferAllocator>,
|
2024-02-21 08:08:50 +00:00
|
|
|
framebuffers: Vec<Arc<Framebuffer>>,
|
2021-09-13 15:14:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl RenderPassPlaceOverFrame {
|
2022-10-05 09:09:26 +00:00
|
|
|
pub fn new(
|
|
|
|
gfx_queue: Arc<Queue>,
|
2022-10-27 18:59:47 +00:00
|
|
|
command_buffer_allocator: Arc<StandardCommandBufferAllocator>,
|
|
|
|
descriptor_set_allocator: Arc<StandardDescriptorSetAllocator>,
|
2022-10-05 09:09:26 +00:00
|
|
|
output_format: Format,
|
2024-02-21 08:08:50 +00:00
|
|
|
swapchain_image_views: &[Arc<ImageView>],
|
2022-10-05 09:09:26 +00:00
|
|
|
) -> RenderPassPlaceOverFrame {
|
2023-03-25 09:25:25 +00:00
|
|
|
let render_pass = vulkano::single_pass_renderpass!(
|
|
|
|
gfx_queue.device().clone(),
|
2021-11-02 20:33:58 +00:00
|
|
|
attachments: {
|
|
|
|
color: {
|
|
|
|
format: output_format,
|
|
|
|
samples: 1,
|
2023-06-17 19:01:50 +00:00
|
|
|
load_op: Clear,
|
|
|
|
store_op: Store,
|
2023-03-25 09:25:25 +00:00
|
|
|
},
|
2021-11-02 20:33:58 +00:00
|
|
|
},
|
|
|
|
pass: {
|
2022-10-26 14:25:01 +00:00
|
|
|
color: [color],
|
2023-03-25 09:25:25 +00:00
|
|
|
depth_stencil: {},
|
|
|
|
},
|
2021-11-02 20:33:58 +00:00
|
|
|
)
|
|
|
|
.unwrap();
|
2021-09-13 15:14:54 +00:00
|
|
|
let subpass = Subpass::from(render_pass.clone(), 0).unwrap();
|
2022-10-05 09:09:26 +00:00
|
|
|
let pixels_draw_pipeline = PixelsDrawPipeline::new(
|
|
|
|
gfx_queue.clone(),
|
|
|
|
subpass,
|
|
|
|
command_buffer_allocator.clone(),
|
|
|
|
descriptor_set_allocator,
|
|
|
|
);
|
|
|
|
|
2021-09-13 15:14:54 +00:00
|
|
|
RenderPassPlaceOverFrame {
|
|
|
|
gfx_queue,
|
2024-02-21 08:08:50 +00:00
|
|
|
render_pass: render_pass.clone(),
|
2021-09-13 15:14:54 +00:00
|
|
|
pixels_draw_pipeline,
|
2022-10-05 09:09:26 +00:00
|
|
|
command_buffer_allocator,
|
2024-02-21 08:08:50 +00:00
|
|
|
framebuffers: create_framebuffers(swapchain_image_views, render_pass),
|
2021-09-13 15:14:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-05 18:56:35 +00:00
|
|
|
/// Places the view exactly over the target swapchain image. The texture draw pipeline uses a
|
|
|
|
/// quad onto which it places the view.
|
2021-09-13 15:14:54 +00:00
|
|
|
pub fn render<F>(
|
2022-10-07 06:59:54 +00:00
|
|
|
&self,
|
2021-09-13 15:14:54 +00:00
|
|
|
before_future: F,
|
2023-07-03 20:37:29 +00:00
|
|
|
view: Arc<ImageView>,
|
|
|
|
target: Arc<ImageView>,
|
2024-02-21 08:08:50 +00:00
|
|
|
image_index: u32,
|
2021-09-13 15:14:54 +00:00
|
|
|
) -> Box<dyn GpuFuture>
|
|
|
|
where
|
|
|
|
F: GpuFuture + 'static,
|
|
|
|
{
|
2023-03-05 18:56:35 +00:00
|
|
|
// Get dimensions.
|
2023-07-06 08:52:11 +00:00
|
|
|
let img_dims: [u32; 2] = target.image().extent()[0..2].try_into().unwrap();
|
2023-03-05 18:56:35 +00:00
|
|
|
|
|
|
|
// Create primary command buffer builder.
|
2024-10-19 12:13:15 +00:00
|
|
|
let mut command_buffer_builder = AutoCommandBufferBuilder::primary(
|
2023-11-14 16:57:43 +00:00
|
|
|
self.command_buffer_allocator.clone(),
|
2022-09-10 06:00:08 +00:00
|
|
|
self.gfx_queue.queue_family_index(),
|
2024-10-18 18:00:21 +00:00
|
|
|
CommandBufferUsage::OneTimeSubmit,
|
2021-09-13 15:14:54 +00:00
|
|
|
)
|
|
|
|
.unwrap();
|
2023-03-05 18:56:35 +00:00
|
|
|
|
|
|
|
// Begin render pass.
|
2021-09-13 15:14:54 +00:00
|
|
|
command_buffer_builder
|
|
|
|
.begin_render_pass(
|
2022-04-24 01:16:19 +00:00
|
|
|
RenderPassBeginInfo {
|
|
|
|
clear_values: vec![Some([0.0; 4].into())],
|
2024-02-21 08:08:50 +00:00
|
|
|
..RenderPassBeginInfo::framebuffer(
|
|
|
|
self.framebuffers[image_index as usize].clone(),
|
|
|
|
)
|
2022-04-24 01:16:19 +00:00
|
|
|
},
|
2023-08-04 18:55:16 +00:00
|
|
|
SubpassBeginInfo {
|
|
|
|
contents: SubpassContents::SecondaryCommandBuffers,
|
|
|
|
..Default::default()
|
|
|
|
},
|
2021-09-13 15:14:54 +00:00
|
|
|
)
|
|
|
|
.unwrap();
|
2023-03-05 18:56:35 +00:00
|
|
|
|
|
|
|
// Create secondary command buffer from texture pipeline & send draw commands.
|
2023-07-06 08:52:11 +00:00
|
|
|
let cb = self.pixels_draw_pipeline.draw(img_dims, view);
|
2023-03-05 18:56:35 +00:00
|
|
|
|
|
|
|
// Execute above commands (subpass).
|
2021-09-13 15:14:54 +00:00
|
|
|
command_buffer_builder.execute_commands(cb).unwrap();
|
2023-03-05 18:56:35 +00:00
|
|
|
|
|
|
|
// End render pass.
|
2023-08-04 18:55:16 +00:00
|
|
|
command_buffer_builder
|
|
|
|
.end_render_pass(Default::default())
|
|
|
|
.unwrap();
|
2023-03-05 18:56:35 +00:00
|
|
|
|
|
|
|
// Build command buffer.
|
2024-10-19 12:13:15 +00:00
|
|
|
let command_buffer = command_buffer_builder.build().unwrap();
|
2023-03-05 18:56:35 +00:00
|
|
|
|
|
|
|
// Execute primary command buffer.
|
2021-09-13 15:14:54 +00:00
|
|
|
let after_future = before_future
|
|
|
|
.then_execute(self.gfx_queue.clone(), command_buffer)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
after_future.boxed()
|
|
|
|
}
|
2024-02-21 08:08:50 +00:00
|
|
|
|
|
|
|
pub fn recreate_framebuffers(&mut self, swapchain_image_views: &[Arc<ImageView>]) {
|
|
|
|
self.framebuffers = create_framebuffers(swapchain_image_views, self.render_pass.clone());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn create_framebuffers(
|
|
|
|
swapchain_image_views: &[Arc<ImageView>],
|
|
|
|
render_pass: Arc<RenderPass>,
|
|
|
|
) -> Vec<Arc<Framebuffer>> {
|
|
|
|
swapchain_image_views
|
|
|
|
.iter()
|
|
|
|
.map(|swapchain_image_view| {
|
|
|
|
Framebuffer::new(
|
|
|
|
render_pass.clone(),
|
|
|
|
FramebufferCreateInfo {
|
|
|
|
attachments: vec![swapchain_image_view.clone()],
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
)
|
|
|
|
.unwrap()
|
|
|
|
})
|
|
|
|
.collect::<Vec<_>>()
|
2021-09-13 15:14:54 +00:00
|
|
|
}
|