Reorganize layout, pass a new buffer
This commit is contained in:
parent
203435ca72
commit
6d02b3dcc1
@ -63,10 +63,21 @@ pub(crate) fn image_index(pixel_x: usize, pixel_y: usize, image_width: u32) -> u
|
|||||||
pixel_x + pixel_y * image_width as usize
|
pixel_x + pixel_y * image_width as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct Transform {
|
||||||
|
variation_offset: u32,
|
||||||
|
variation_count: u32,
|
||||||
|
weight: f32,
|
||||||
|
color: f32,
|
||||||
|
color_speed: f32,
|
||||||
|
}
|
||||||
|
|
||||||
#[spirv(compute(threads(1)))]
|
#[spirv(compute(threads(1)))]
|
||||||
pub fn main_cs(
|
pub fn main_cs(
|
||||||
#[spirv(push_constant)] constants: &IfsConstants,
|
#[spirv(push_constant)] constants: &IfsConstants,
|
||||||
#[spirv(storage_buffer, descriptor_set = 0, binding = 0)] accum_image: &mut [Vec4],
|
#[spirv(storage_buffer, descriptor_set = 0, binding = 0)] transforms: &[Transform],
|
||||||
|
#[spirv(storage_buffer, descriptor_set = 0, binding = 1)] accum_image: &mut [Vec4],
|
||||||
) {
|
) {
|
||||||
let block_size = 64;
|
let block_size = 64;
|
||||||
for i_width in 0..constants.accum_width as usize {
|
for i_width in 0..constants.accum_width as usize {
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
use flare_shader::{Color, IfsConstants};
|
use flare_shader::{Color, IfsConstants, Transform};
|
||||||
use futures_executor::block_on;
|
use futures_executor::block_on;
|
||||||
use glam::Vec4;
|
use glam::Vec4;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use bytemuck::Zeroable;
|
||||||
|
use wgpu::util::DeviceExt;
|
||||||
use wgpu::{
|
use wgpu::{
|
||||||
Adapter, Device, Features, Instance, Queue, ShaderModule, Surface, SurfaceConfiguration,
|
Adapter, BindGroupLayout, Device, Features, Instance, Queue, ShaderModule, Surface,
|
||||||
|
SurfaceConfiguration,
|
||||||
};
|
};
|
||||||
use winit::event::MouseButton;
|
use winit::event::MouseButton;
|
||||||
use winit::{
|
use winit::{
|
||||||
@ -15,27 +18,74 @@ use winit::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct AccumulatePipeline {
|
struct AccumulatePipeline {
|
||||||
|
device: Device,
|
||||||
|
bind_group_layout: BindGroupLayout,
|
||||||
|
pipeline_layout: wgpu::PipelineLayout,
|
||||||
pipeline: wgpu::ComputePipeline,
|
pipeline: wgpu::ComputePipeline,
|
||||||
|
|
||||||
|
transforms: Option<wgpu::Buffer>,
|
||||||
|
accum_image: Option<wgpu::Buffer>,
|
||||||
|
bind_group: Option<wgpu::BindGroup>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AccumulatePipeline {
|
impl AccumulatePipeline {
|
||||||
pub fn new(device: &Device, module: &ShaderModule) -> Self {
|
const BIND_GROUP_LAYOUT_DESCRIPTOR: wgpu::BindGroupLayoutDescriptor<'static> =
|
||||||
let bindgroup_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
wgpu::BindGroupLayoutDescriptor {
|
||||||
label: Some("accumulate"),
|
label: Some("accumulate"),
|
||||||
entries: &[wgpu::BindGroupLayoutEntry {
|
entries: &[
|
||||||
|
// transforms
|
||||||
|
wgpu::BindGroupLayoutEntry {
|
||||||
binding: 0,
|
binding: 0,
|
||||||
count: None,
|
|
||||||
visibility: wgpu::ShaderStages::COMPUTE,
|
visibility: wgpu::ShaderStages::COMPUTE,
|
||||||
ty: wgpu::BindingType::Buffer {
|
ty: wgpu::BindingType::Buffer {
|
||||||
|
ty: wgpu::BufferBindingType::Storage { read_only: true },
|
||||||
has_dynamic_offset: false,
|
has_dynamic_offset: false,
|
||||||
min_binding_size: None,
|
min_binding_size: None,
|
||||||
ty: wgpu::BufferBindingType::Storage { read_only: false },
|
|
||||||
},
|
},
|
||||||
}],
|
count: None,
|
||||||
});
|
},
|
||||||
|
// accum_image
|
||||||
|
wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 1,
|
||||||
|
visibility: wgpu::ShaderStages::COMPUTE,
|
||||||
|
ty: wgpu::BindingType::Buffer {
|
||||||
|
ty: wgpu::BufferBindingType::Storage { read_only: false },
|
||||||
|
has_dynamic_offset: false,
|
||||||
|
min_binding_size: None,
|
||||||
|
},
|
||||||
|
count: None,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
fn create_bind_group(
|
||||||
|
device: &Device,
|
||||||
|
layout: &wgpu::BindGroupLayout,
|
||||||
|
transforms: &wgpu::Buffer,
|
||||||
|
accum_image: &wgpu::Buffer,
|
||||||
|
) -> wgpu::BindGroup {
|
||||||
|
device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
label: Some("accumulate"),
|
||||||
|
layout,
|
||||||
|
entries: &[
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 0,
|
||||||
|
resource: transforms.as_entire_binding(),
|
||||||
|
},
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 1,
|
||||||
|
resource: accum_image.as_entire_binding(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(device: &Device, module: &ShaderModule) -> Self {
|
||||||
|
let bind_group_layout =
|
||||||
|
device.create_bind_group_layout(&Self::BIND_GROUP_LAYOUT_DESCRIPTOR);
|
||||||
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("accumulate"),
|
label: Some("accumulate"),
|
||||||
bind_group_layouts: &[&bindgroup_layout],
|
bind_group_layouts: &[&bind_group_layout],
|
||||||
push_constant_ranges: &[wgpu::PushConstantRange {
|
push_constant_ranges: &[wgpu::PushConstantRange {
|
||||||
stages: wgpu::ShaderStages::COMPUTE,
|
stages: wgpu::ShaderStages::COMPUTE,
|
||||||
range: 0..size_of::<IfsConstants>() as u32,
|
range: 0..size_of::<IfsConstants>() as u32,
|
||||||
@ -50,62 +100,110 @@ impl AccumulatePipeline {
|
|||||||
cache: None,
|
cache: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
Self { pipeline }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct AccumulatePass {
|
|
||||||
accum_buffer: wgpu::Buffer,
|
|
||||||
bind_group: wgpu::BindGroup,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AccumulatePass {
|
|
||||||
pub fn new(device: &Device, pipeline: &AccumulatePipeline, dimensions: (u32, u32)) -> Self {
|
|
||||||
let pixels = dimensions.0 * dimensions.1;
|
|
||||||
let elements = pixels * 4;
|
|
||||||
let accum_buffer = device.create_buffer(&wgpu::BufferDescriptor {
|
|
||||||
label: Some("accumulate"),
|
|
||||||
size: elements as u64 * size_of::<f32>() as u64,
|
|
||||||
usage: wgpu::BufferUsages::STORAGE,
|
|
||||||
mapped_at_creation: false,
|
|
||||||
});
|
|
||||||
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
|
||||||
label: Some("accumulate"),
|
|
||||||
layout: &pipeline.pipeline.get_bind_group_layout(0),
|
|
||||||
entries: &[wgpu::BindGroupEntry {
|
|
||||||
binding: 0,
|
|
||||||
resource: accum_buffer.as_entire_binding(),
|
|
||||||
}],
|
|
||||||
});
|
|
||||||
Self {
|
Self {
|
||||||
accum_buffer,
|
device: device.clone(),
|
||||||
bind_group,
|
bind_group_layout,
|
||||||
|
pipeline_layout,
|
||||||
|
pipeline,
|
||||||
|
transforms: None,
|
||||||
|
accum_image: None,
|
||||||
|
bind_group: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_transforms(&mut self, transforms: &[Transform]) {
|
||||||
|
// Should be smarter about allocation in the future
|
||||||
|
self.transforms = Some(
|
||||||
|
self.device
|
||||||
|
.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
|
label: Some("accumulate/transforms"),
|
||||||
|
contents: bytemuck::cast_slice(transforms),
|
||||||
|
usage: wgpu::BufferUsages::STORAGE,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Setting a new buffer invalidates the existing bindings
|
||||||
|
self.bind_group.take();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_accum_image(&mut self, accum_image: &wgpu::Buffer) {
|
||||||
|
self.accum_image = Some(accum_image.clone());
|
||||||
|
|
||||||
|
// Setting a new buffer invalidates the existing bindings
|
||||||
|
self.bind_group.take();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fetch_bind_group(&mut self) -> &wgpu::BindGroup {
|
||||||
|
self.bind_group
|
||||||
|
.get_or_insert_with(|| {
|
||||||
|
self.device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
label: Some("accumulate"),
|
||||||
|
layout: &self.bind_group_layout,
|
||||||
|
entries: &[
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 0,
|
||||||
|
resource: self
|
||||||
|
.transforms
|
||||||
|
.as_ref()
|
||||||
|
.expect("transforms missing")
|
||||||
|
.as_entire_binding(),
|
||||||
|
},
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 1,
|
||||||
|
resource: self
|
||||||
|
.accum_image
|
||||||
|
.as_ref()
|
||||||
|
.expect("accum_image missing")
|
||||||
|
.as_entire_binding(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(&mut self, encoder: &mut wgpu::CommandEncoder, constants: &IfsConstants) {
|
||||||
|
let mut pass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor {
|
||||||
|
label: Some("accumulate"),
|
||||||
|
timestamp_writes: None,
|
||||||
|
});
|
||||||
|
pass.set_pipeline(&self.pipeline);
|
||||||
|
pass.set_push_constants(0, bytemuck::cast_slice(&[*constants]));
|
||||||
|
pass.set_bind_group(0, self.fetch_bind_group(), &[]);
|
||||||
|
pass.dispatch_workgroups(1, 1, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RenderPipeline {
|
struct RenderPipeline {
|
||||||
|
device: Device,
|
||||||
|
bind_group_layout: wgpu::BindGroupLayout,
|
||||||
pipeline: wgpu::RenderPipeline,
|
pipeline: wgpu::RenderPipeline,
|
||||||
|
|
||||||
|
accum_image: Option<wgpu::Buffer>,
|
||||||
|
bind_group: Option<wgpu::BindGroup>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderPipeline {
|
impl RenderPipeline {
|
||||||
pub fn new(device: &Device, module: &ShaderModule, format: wgpu::TextureFormat) -> Self {
|
const BIND_GROUP_LAYOUT_DESCRIPTOR: wgpu::BindGroupLayoutDescriptor<'static> =
|
||||||
let bindgroup_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
wgpu::BindGroupLayoutDescriptor {
|
||||||
label: Some("render"),
|
label: Some("render"),
|
||||||
entries: &[wgpu::BindGroupLayoutEntry {
|
entries: &[wgpu::BindGroupLayoutEntry {
|
||||||
binding: 0,
|
binding: 0,
|
||||||
count: None,
|
|
||||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||||
ty: wgpu::BindingType::Buffer {
|
ty: wgpu::BindingType::Buffer {
|
||||||
|
ty: wgpu::BufferBindingType::Storage { read_only: true },
|
||||||
has_dynamic_offset: false,
|
has_dynamic_offset: false,
|
||||||
min_binding_size: None,
|
min_binding_size: None,
|
||||||
ty: wgpu::BufferBindingType::Storage { read_only: true },
|
|
||||||
},
|
},
|
||||||
|
count: None,
|
||||||
}],
|
}],
|
||||||
});
|
};
|
||||||
|
|
||||||
|
pub fn new(device: &Device, module: &ShaderModule, format: wgpu::TextureFormat) -> Self {
|
||||||
|
let bind_group_layout =
|
||||||
|
device.create_bind_group_layout(&Self::BIND_GROUP_LAYOUT_DESCRIPTOR);
|
||||||
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("render"),
|
label: Some("render"),
|
||||||
bind_group_layouts: &[&bindgroup_layout],
|
bind_group_layouts: &[&bind_group_layout],
|
||||||
push_constant_ranges: &[wgpu::PushConstantRange {
|
push_constant_ranges: &[wgpu::PushConstantRange {
|
||||||
stages: wgpu::ShaderStages::FRAGMENT,
|
stages: wgpu::ShaderStages::FRAGMENT,
|
||||||
range: 0..size_of::<IfsConstants>() as u32,
|
range: 0..size_of::<IfsConstants>() as u32,
|
||||||
@ -136,25 +234,63 @@ impl RenderPipeline {
|
|||||||
multiview: None,
|
multiview: None,
|
||||||
cache: None,
|
cache: None,
|
||||||
});
|
});
|
||||||
Self { pipeline }
|
Self {
|
||||||
|
device: device.clone(),
|
||||||
|
bind_group_layout,
|
||||||
|
pipeline,
|
||||||
|
accum_image: None,
|
||||||
|
bind_group: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RenderPass {
|
pub fn set_accum_image(&mut self, accum_image: &wgpu::Buffer) {
|
||||||
bind_group: wgpu::BindGroup,
|
self.accum_image = Some(accum_image.clone());
|
||||||
|
self.bind_group.take();
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderPass {
|
fn fetch_bind_group(&mut self) -> &wgpu::BindGroup {
|
||||||
pub fn new(device: &Device, pipeline: &RenderPipeline, accum_buffer: &wgpu::Buffer) -> Self {
|
self.bind_group
|
||||||
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
.get_or_insert_with(|| {
|
||||||
|
self.device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
label: Some("render"),
|
label: Some("render"),
|
||||||
layout: &pipeline.pipeline.get_bind_group_layout(0),
|
layout: &self.bind_group_layout,
|
||||||
entries: &[wgpu::BindGroupEntry {
|
entries: &[wgpu::BindGroupEntry {
|
||||||
binding: 0,
|
binding: 0,
|
||||||
resource: accum_buffer.as_entire_binding(),
|
resource: self
|
||||||
|
.accum_image
|
||||||
|
.as_ref()
|
||||||
|
.expect("accum_image missing")
|
||||||
|
.as_entire_binding(),
|
||||||
}],
|
}],
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(
|
||||||
|
&mut self,
|
||||||
|
encoder: &mut wgpu::CommandEncoder,
|
||||||
|
output_view: &wgpu::TextureView,
|
||||||
|
constants: &IfsConstants,
|
||||||
|
) {
|
||||||
|
let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
|
label: Some("render"),
|
||||||
|
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||||
|
view: output_view,
|
||||||
|
resolve_target: None,
|
||||||
|
ops: Default::default(),
|
||||||
|
})],
|
||||||
|
depth_stencil_attachment: None,
|
||||||
|
timestamp_writes: None,
|
||||||
|
occlusion_query_set: None,
|
||||||
});
|
});
|
||||||
Self { bind_group }
|
pass.set_pipeline(&self.pipeline);
|
||||||
|
pass.set_push_constants(
|
||||||
|
wgpu::ShaderStages::FRAGMENT,
|
||||||
|
0,
|
||||||
|
bytemuck::cast_slice(&[*constants]),
|
||||||
|
);
|
||||||
|
pass.set_bind_group(0, self.fetch_bind_group(), &[]);
|
||||||
|
pass.draw(0..3, 0..1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,13 +350,24 @@ struct FlareRender<'window> {
|
|||||||
surface: Surface<'window>,
|
surface: Surface<'window>,
|
||||||
surface_configuration: SurfaceConfiguration,
|
surface_configuration: SurfaceConfiguration,
|
||||||
accumulate_pipeline: AccumulatePipeline,
|
accumulate_pipeline: AccumulatePipeline,
|
||||||
accumulate_pass: AccumulatePass,
|
|
||||||
render_pipeline: RenderPipeline,
|
render_pipeline: RenderPipeline,
|
||||||
render_pass: RenderPass,
|
|
||||||
ifs_constants: IfsConstants,
|
ifs_constants: IfsConstants,
|
||||||
|
accum_image: wgpu::Buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FlareRender<'_> {
|
impl FlareRender<'_> {
|
||||||
|
fn create_accum_image(device: &Device, width: u32, height: u32) -> wgpu::Buffer {
|
||||||
|
let pixels = (width * height) as u64;
|
||||||
|
let pixel_size = 4u64 * size_of::<f32>() as u64;
|
||||||
|
let size = pixels * pixel_size;
|
||||||
|
device.create_buffer(&wgpu::BufferDescriptor {
|
||||||
|
label: Some("accum_image"),
|
||||||
|
size,
|
||||||
|
usage: wgpu::BufferUsages::STORAGE,
|
||||||
|
mapped_at_creation: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new(flare: Arc<Flare>, window: Arc<Window>) -> Self {
|
pub fn new(flare: Arc<Flare>, window: Arc<Window>) -> Self {
|
||||||
let window_size = window.inner_size();
|
let window_size = window.inner_size();
|
||||||
|
|
||||||
@ -234,19 +381,10 @@ impl FlareRender<'_> {
|
|||||||
surface_configuration.present_mode = wgpu::PresentMode::AutoVsync;
|
surface_configuration.present_mode = wgpu::PresentMode::AutoVsync;
|
||||||
surface.configure(&flare.device, &surface_configuration);
|
surface.configure(&flare.device, &surface_configuration);
|
||||||
|
|
||||||
let accumulate_pipeline = AccumulatePipeline::new(&flare.device, &flare.module);
|
let mut accumulate_pipeline = AccumulatePipeline::new(&flare.device, &flare.module);
|
||||||
let accumulate_pass = AccumulatePass::new(
|
let mut render_pipeline =
|
||||||
&flare.device,
|
|
||||||
&accumulate_pipeline,
|
|
||||||
(window_size.width, window_size.height),
|
|
||||||
);
|
|
||||||
let render_pipeline =
|
|
||||||
RenderPipeline::new(&flare.device, &flare.module, surface_configuration.format);
|
RenderPipeline::new(&flare.device, &flare.module, surface_configuration.format);
|
||||||
let render_pass = RenderPass::new(
|
|
||||||
&flare.device,
|
|
||||||
&render_pipeline,
|
|
||||||
&accumulate_pass.accum_buffer,
|
|
||||||
);
|
|
||||||
let ifs_constants = IfsConstants::new(
|
let ifs_constants = IfsConstants::new(
|
||||||
window_size.width,
|
window_size.width,
|
||||||
window_size.height,
|
window_size.height,
|
||||||
@ -255,54 +393,24 @@ impl FlareRender<'_> {
|
|||||||
Vec4::BLACK,
|
Vec4::BLACK,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let accum_image = Self::create_accum_image(&flare.device, window_size.width, window_size.height);
|
||||||
|
|
||||||
|
accumulate_pipeline.set_transforms(&[Transform::zeroed()]);
|
||||||
|
accumulate_pipeline.set_accum_image(&accum_image);
|
||||||
|
render_pipeline.set_accum_image(&accum_image);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
flare,
|
flare,
|
||||||
surface,
|
surface,
|
||||||
surface_configuration,
|
surface_configuration,
|
||||||
accumulate_pipeline,
|
accumulate_pipeline,
|
||||||
accumulate_pass,
|
|
||||||
render_pipeline,
|
render_pipeline,
|
||||||
render_pass,
|
|
||||||
ifs_constants,
|
ifs_constants,
|
||||||
|
accum_image,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn begin_accumulate(&self, encoder: &mut wgpu::CommandEncoder) {
|
pub fn render(&mut self, run_accumulate: bool) {
|
||||||
let mut pass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor {
|
|
||||||
label: Some("accumulate"),
|
|
||||||
timestamp_writes: None,
|
|
||||||
});
|
|
||||||
|
|
||||||
pass.set_pipeline(&self.accumulate_pipeline.pipeline);
|
|
||||||
pass.set_push_constants(0, bytemuck::cast_slice(&[self.ifs_constants]));
|
|
||||||
pass.set_bind_group(0, &self.accumulate_pass.bind_group, &[]);
|
|
||||||
pass.dispatch_workgroups(1, 1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn begin_render(&self, encoder: &mut wgpu::CommandEncoder, output_view: &wgpu::TextureView) {
|
|
||||||
let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
|
||||||
label: Some("render"),
|
|
||||||
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
|
||||||
view: output_view,
|
|
||||||
resolve_target: None,
|
|
||||||
ops: Default::default(),
|
|
||||||
})],
|
|
||||||
depth_stencil_attachment: None,
|
|
||||||
timestamp_writes: None,
|
|
||||||
occlusion_query_set: None,
|
|
||||||
});
|
|
||||||
|
|
||||||
pass.set_pipeline(&self.render_pipeline.pipeline);
|
|
||||||
pass.set_push_constants(
|
|
||||||
wgpu::ShaderStages::FRAGMENT,
|
|
||||||
0,
|
|
||||||
bytemuck::cast_slice(&[self.ifs_constants]),
|
|
||||||
);
|
|
||||||
pass.set_bind_group(0, &self.render_pass.bind_group, &[]);
|
|
||||||
pass.draw(0..3, 0..1);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn render(&self, run_accumulate: bool) {
|
|
||||||
let output = self
|
let output = self
|
||||||
.surface
|
.surface
|
||||||
.get_current_texture()
|
.get_current_texture()
|
||||||
@ -314,9 +422,9 @@ impl FlareRender<'_> {
|
|||||||
.create_command_encoder(&Default::default());
|
.create_command_encoder(&Default::default());
|
||||||
|
|
||||||
if run_accumulate {
|
if run_accumulate {
|
||||||
self.begin_accumulate(&mut encoder);
|
self.accumulate_pipeline.run(&mut encoder, &self.ifs_constants);
|
||||||
}
|
}
|
||||||
self.begin_render(&mut encoder, &output_view);
|
self.render_pipeline.run(&mut encoder, &output_view, &self.ifs_constants);
|
||||||
|
|
||||||
self.flare.queue.submit(Some(encoder.finish()));
|
self.flare.queue.submit(Some(encoder.finish()));
|
||||||
output.present();
|
output.present();
|
||||||
@ -324,18 +432,13 @@ impl FlareRender<'_> {
|
|||||||
|
|
||||||
pub fn resize_accumulate(&mut self) {
|
pub fn resize_accumulate(&mut self) {
|
||||||
let vp_dimensions = self.ifs_constants.viewport_dimensions();
|
let vp_dimensions = self.ifs_constants.viewport_dimensions();
|
||||||
self.accumulate_pass = AccumulatePass::new(
|
|
||||||
&self.flare.device,
|
|
||||||
&self.accumulate_pipeline,
|
|
||||||
(vp_dimensions.x, vp_dimensions.y),
|
|
||||||
);
|
|
||||||
self.render_pass = RenderPass::new(
|
|
||||||
&self.flare.device,
|
|
||||||
&self.render_pipeline,
|
|
||||||
&self.accumulate_pass.accum_buffer,
|
|
||||||
);
|
|
||||||
self.ifs_constants
|
self.ifs_constants
|
||||||
.with_accumulate(vp_dimensions.x, vp_dimensions.y);
|
.with_accumulate(vp_dimensions.x, vp_dimensions.y);
|
||||||
|
|
||||||
|
let accum_image = Self::create_accum_image(&self.flare.device, vp_dimensions.x, vp_dimensions.y);
|
||||||
|
self.accumulate_pipeline.set_accum_image(&accum_image);
|
||||||
|
self.render_pipeline.set_accum_image(&accum_image);
|
||||||
|
self.accum_image = accum_image;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resize_viewport(&mut self, width: u32, height: u32) {
|
pub fn resize_viewport(&mut self, width: u32, height: u32) {
|
||||||
@ -377,7 +480,7 @@ impl ApplicationHandler for Application<'_> {
|
|||||||
|
|
||||||
self.window = Some(window.clone());
|
self.window = Some(window.clone());
|
||||||
|
|
||||||
let flare_render = FlareRender::new(self.flare.clone(), window);
|
let mut flare_render = FlareRender::new(self.flare.clone(), window);
|
||||||
flare_render.render(true);
|
flare_render.render(true);
|
||||||
|
|
||||||
self.flare_render = Some(flare_render);
|
self.flare_render = Some(flare_render);
|
||||||
|
Loading…
Reference in New Issue
Block a user