diff --git a/render/wgpu/src/filters.rs b/render/wgpu/src/filters.rs index 17556648c..8d7750a9b 100644 --- a/render/wgpu/src/filters.rs +++ b/render/wgpu/src/filters.rs @@ -67,67 +67,59 @@ impl<'a> FilterSource<'a> { ] } - pub fn vertices_with_blur_offset( - &self, - device: &wgpu::Device, - blur_offset: (f32, f32), - ) -> wgpu::Buffer { + pub fn vertices_with_blur_offset(&self, blur_offset: (f32, f32)) -> [FilterVertexWithBlur; 4] { let source_width = self.texture.width() as f32; let source_height = self.texture.height() as f32; let source_left = self.point.0; let source_top = self.point.1; let source_right = source_left + self.size.0; let source_bottom = source_top + self.size.1; - device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: create_debug_label!("Filter vertices").as_deref(), - contents: bytemuck::cast_slice(&[ - FilterVertexWithBlur { - position: [0.0, 0.0], - source_uv: [ - source_left as f32 / source_width, - source_top as f32 / source_height, - ], - blur_uv: [ - (source_left as f32 + blur_offset.0) / source_width, - (source_top as f32 + blur_offset.1) / source_height, - ], - }, - FilterVertexWithBlur { - position: [1.0, 0.0], - source_uv: [ - source_right as f32 / source_width, - source_top as f32 / source_height, - ], - blur_uv: [ - (source_right as f32 + blur_offset.0) / source_width, - (source_top as f32 + blur_offset.1) / source_height, - ], - }, - FilterVertexWithBlur { - position: [1.0, 1.0], - source_uv: [ - source_right as f32 / source_width, - source_bottom as f32 / source_height, - ], - blur_uv: [ - (source_right as f32 + blur_offset.0) / source_width, - (source_bottom as f32 + blur_offset.1) / source_height, - ], - }, - FilterVertexWithBlur { - position: [0.0, 1.0], - source_uv: [ - source_left as f32 / source_width, - source_bottom as f32 / source_height, - ], - blur_uv: [ - (source_left as f32 + blur_offset.0) / source_width, - (source_bottom as f32 + blur_offset.1) / source_height, - ], - }, - ]), - usage: wgpu::BufferUsages::VERTEX, - }) + [ + FilterVertexWithBlur { + position: [0.0, 0.0], + source_uv: [ + source_left as f32 / source_width, + source_top as f32 / source_height, + ], + blur_uv: [ + (source_left as f32 + blur_offset.0) / source_width, + (source_top as f32 + blur_offset.1) / source_height, + ], + }, + FilterVertexWithBlur { + position: [1.0, 0.0], + source_uv: [ + source_right as f32 / source_width, + source_top as f32 / source_height, + ], + blur_uv: [ + (source_right as f32 + blur_offset.0) / source_width, + (source_top as f32 + blur_offset.1) / source_height, + ], + }, + FilterVertexWithBlur { + position: [1.0, 1.0], + source_uv: [ + source_right as f32 / source_width, + source_bottom as f32 / source_height, + ], + blur_uv: [ + (source_right as f32 + blur_offset.0) / source_width, + (source_bottom as f32 + blur_offset.1) / source_height, + ], + }, + FilterVertexWithBlur { + position: [0.0, 1.0], + source_uv: [ + source_left as f32 / source_width, + source_bottom as f32 / source_height, + ], + blur_uv: [ + (source_left as f32 + blur_offset.0) / source_width, + (source_bottom as f32 + blur_offset.1) / source_height, + ], + }, + ] } pub fn vertices_with_highlight_and_shadow( diff --git a/render/wgpu/src/filters/glow.rs b/render/wgpu/src/filters/glow.rs index 35a048b99..8e5ccf307 100644 --- a/render/wgpu/src/filters/glow.rs +++ b/render/wgpu/src/filters/glow.rs @@ -2,7 +2,9 @@ use crate::backend::RenderTargetMode; use crate::buffer_pool::TexturePool; use crate::descriptors::Descriptors; use crate::filters::blur::BlurFilter; -use crate::filters::{FilterSource, VERTEX_BUFFERS_DESCRIPTION_FILTERS_WITH_BLUR}; +use crate::filters::{ + FilterSource, FilterVertexWithBlur, VERTEX_BUFFERS_DESCRIPTION_FILTERS_WITH_BLUR, +}; use crate::surface::target::CommandTarget; use crate::utils::SampleCountMap; use bytemuck::{Pod, Zeroable}; @@ -23,14 +25,16 @@ struct GlowUniform { pub struct GlowFilter { bind_group_layout: wgpu::BindGroupLayout, pipeline_layout: wgpu::PipelineLayout, - buffer: wgpu::Buffer, - buffer_size: wgpu::BufferSize, + vertex_buffer: wgpu::Buffer, + uniform_buffer: wgpu::Buffer, + vertices_size: wgpu::BufferSize, + uniform_size: wgpu::BufferSize, pipeline: SampleCountMap>, } impl GlowFilter { pub fn new(device: &wgpu::Device) -> Self { - let buffer_size = std::mem::size_of::() as u64; + let uniform_size = std::mem::size_of::() as u64; let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { entries: &[ wgpu::BindGroupLayoutEntry { @@ -55,7 +59,7 @@ impl GlowFilter { ty: wgpu::BindingType::Buffer { ty: wgpu::BufferBindingType::Uniform, has_dynamic_offset: false, - min_binding_size: wgpu::BufferSize::new(buffer_size), + min_binding_size: wgpu::BufferSize::new(uniform_size), }, count: None, }, @@ -73,9 +77,17 @@ impl GlowFilter { label: create_debug_label!("Blur filter binds").as_deref(), }); - let buffer = device.create_buffer(&wgpu::BufferDescriptor { + let vertices_size = std::mem::size_of::<[FilterVertexWithBlur; 4]>() as u64; + let vertex_buffer = device.create_buffer(&wgpu::BufferDescriptor { label: None, - size: buffer_size, + size: vertices_size, + usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST, + mapped_at_creation: false, + }); + + let uniform_buffer = device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: uniform_size, usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, mapped_at_creation: false, }); @@ -89,9 +101,11 @@ impl GlowFilter { Self { pipeline: Default::default(), pipeline_layout, - buffer, + vertex_buffer, + uniform_buffer, bind_group_layout, - buffer_size: wgpu::BufferSize::new(buffer_size).expect("Definitely not zero."), + uniform_size: wgpu::BufferSize::new(uniform_size).expect("Definitely not zero."), + vertices_size: wgpu::BufferSize::new(vertices_size).expect("Definitely not zero."), } } @@ -181,9 +195,9 @@ impl GlowFilter { staging_belt .write_buffer( draw_encoder, - &self.buffer, + &self.uniform_buffer, 0, - self.buffer_size, + self.uniform_size, &descriptors.device, ) .copy_from_slice(bytemuck::cast_slice(&[GlowUniform { @@ -198,7 +212,17 @@ impl GlowFilter { knockout: if filter.is_knockout() { 1 } else { 0 }, composite_source: if filter.composite_source() { 1 } else { 0 }, }])); - let vertices = source.vertices_with_blur_offset(&descriptors.device, blur_offset); + staging_belt + .write_buffer( + draw_encoder, + &self.vertex_buffer, + 0, + self.vertices_size, + &descriptors.device, + ) + .copy_from_slice(bytemuck::cast_slice(&[ + source.vertices_with_blur_offset(blur_offset) + ])); let filter_group = descriptors .device .create_bind_group(&wgpu::BindGroupDescriptor { @@ -217,7 +241,7 @@ impl GlowFilter { }, wgpu::BindGroupEntry { binding: 2, - resource: self.buffer.as_entire_binding(), + resource: self.uniform_buffer.as_entire_binding(), }, wgpu::BindGroupEntry { binding: 3, @@ -234,7 +258,7 @@ impl GlowFilter { render_pass.set_bind_group(0, &filter_group, &[]); - render_pass.set_vertex_buffer(0, vertices.slice(..)); + render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..)); render_pass.set_index_buffer( descriptors.quad.indices.slice(..), wgpu::IndexFormat::Uint32,