use std::sync::Arc;
use vulkano::{
command_buffer::{
allocator::StandardCommandBufferAllocator, AutoCommandBufferBuilder, CommandBufferUsage,
RenderPassBeginInfo, SubpassContents,
},
device::{DeviceOwned, Queue},
format::Format,
image::ImageAccess,
memory::allocator::StandardMemoryAllocator,
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
sync::GpuFuture,
};
use vulkano_util::renderer::{DeviceImageView, SwapchainImageView};
use crate::{pixels_draw_pipeline::PixelsDrawPipeline, Resource};
#[derive(Resource)]
pub struct RenderPassPlaceOverFrame {
gfx_queue: Arc<Queue>,
command_buffer_allocator: StandardCommandBufferAllocator,
render_pass: Arc<RenderPass>,
pixels_draw_pipeline: PixelsDrawPipeline,
}
impl RenderPassPlaceOverFrame {
pub fn new(
allocator: Arc<StandardMemoryAllocator>,
gfx_queue: Arc<Queue>,
output_format: Format,
) -> RenderPassPlaceOverFrame {
let render_pass = vulkano::single_pass_renderpass!(gfx_queue.device().clone(),
attachments: {
color: {
load: Clear,
store: Store,
format: output_format,
samples: 1,
}
},
pass: {
color: [color],
depth_stencil: {}
}
)
.unwrap();
let subpass = Subpass::from(render_pass.clone(), 0).unwrap();
let pixels_draw_pipeline =
PixelsDrawPipeline::new(allocator.clone(), gfx_queue.clone(), subpass);
RenderPassPlaceOverFrame {
gfx_queue,
command_buffer_allocator: StandardCommandBufferAllocator::new(
allocator.device().clone(),
Default::default(),
),
render_pass,
pixels_draw_pipeline,
}
}
pub fn render<F>(
&mut self,
before_future: F,
view: DeviceImageView,
target: SwapchainImageView,
) -> Box<dyn GpuFuture>
where
F: GpuFuture + 'static,
{
let img_dims = target.image().dimensions();
let framebuffer = Framebuffer::new(self.render_pass.clone(), FramebufferCreateInfo {
attachments: vec![target],
..Default::default()
})
.unwrap();
let mut command_buffer_builder = AutoCommandBufferBuilder::primary(
&self.command_buffer_allocator,
self.gfx_queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
command_buffer_builder
.begin_render_pass(
RenderPassBeginInfo {
clear_values: vec![Some([0.0; 4].into())],
..RenderPassBeginInfo::framebuffer(framebuffer)
},
SubpassContents::SecondaryCommandBuffers,
)
.unwrap();
let cb = self
.pixels_draw_pipeline
.draw(img_dims.width_height(), view);
command_buffer_builder.execute_commands(cb).unwrap();
command_buffer_builder.end_render_pass().unwrap();
let command_buffer = command_buffer_builder.build().unwrap();
let after_future = before_future
.then_execute(self.gfx_queue.clone(), command_buffer)
.unwrap();
after_future.boxed()
}
}