use std::{marker::PhantomData, ops::Range, sync::Arc}; use smallvec::smallvec; use vulkano::{ buffer::{BufferContents, Subbuffer}, command_buffer::{ AutoCommandBufferBuilder, CommandBufferInheritanceInfo, CommandBufferInheritanceRenderPassType, CommandBufferInheritanceRenderingInfo, CommandBufferUsage, SecondaryAutoCommandBuffer, }, descriptor_set::{DescriptorSet, WriteDescriptorSet}, image::{ sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo}, view::ImageView, }, pipeline::{ Pipeline, PipelineBindPoint, graphics::{vertex_input::Vertex, viewport::Viewport}, }, }; use super::{WGfx, pipeline::WGfxPipeline}; pub struct WGfxPass { pub command_buffer: Arc, graphics: Arc, descriptor_sets: Vec>, _dummy: PhantomData, } impl WGfxPass where V: BufferContents + Vertex, { pub(super) fn new( pipeline: Arc>, dimensions: [f32; 2], vertex_buffer: Subbuffer<[V]>, vertices: Range, instances: Range, descriptor_sets: Vec>, ) -> anyhow::Result { let viewport = Viewport { offset: [0.0, 0.0], extent: dimensions, depth_range: 0.0..=1.0, }; let pipeline_inner = pipeline.inner(); let mut command_buffer = AutoCommandBufferBuilder::secondary( pipeline.graphics.command_buffer_allocator.clone(), pipeline.graphics.queue_gfx.queue_family_index(), CommandBufferUsage::SimultaneousUse, CommandBufferInheritanceInfo { render_pass: Some(CommandBufferInheritanceRenderPassType::BeginRendering( CommandBufferInheritanceRenderingInfo { color_attachment_formats: vec![Some(pipeline.format)], ..Default::default() }, )), ..Default::default() }, )?; unsafe { command_buffer .set_viewport(0, smallvec![viewport])? .bind_pipeline_graphics(pipeline_inner)? .bind_descriptor_sets( PipelineBindPoint::Graphics, pipeline.inner().layout().clone(), 0, descriptor_sets.clone(), )? .bind_vertex_buffers(0, vertex_buffer)? .draw( vertices.end - vertices.start, instances.end - instances.start, vertices.start, instances.start, )? }; Ok(Self { command_buffer: command_buffer.build()?, graphics: pipeline.graphics.clone(), descriptor_sets, _dummy: PhantomData, }) } pub fn update_sampler( &self, set: usize, texture: Arc, filter: Filter, ) -> anyhow::Result<()> { let sampler = Sampler::new( self.graphics.device.clone(), SamplerCreateInfo { mag_filter: filter, min_filter: filter, address_mode: [SamplerAddressMode::Repeat; 3], ..Default::default() }, )?; unsafe { self.descriptor_sets[set].update_by_ref( [WriteDescriptorSet::image_view_sampler(0, texture, sampler)], [], )?; } Ok(()) } }