summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--examples/integration/src/main.rs9
-rw-r--r--wgpu/src/backend.rs17
-rw-r--r--wgpu/src/buffer/dynamic.rs23
-rw-r--r--wgpu/src/buffer/static.rs21
-rw-r--r--wgpu/src/quad.rs7
-rw-r--r--wgpu/src/triangle.rs561
-rw-r--r--wgpu/src/window/compositor.rs11
7 files changed, 358 insertions, 291 deletions
diff --git a/examples/integration/src/main.rs b/examples/integration/src/main.rs
index 69f6961e..5af30ab1 100644
--- a/examples/integration/src/main.rs
+++ b/examples/integration/src/main.rs
@@ -125,9 +125,6 @@ pub fn main() {
let mut resized = false;
- // Initialize staging belt
- let mut staging_belt = wgpu::util::StagingBelt::new(5 * 1024);
-
// Initialize scene and GUI controls
let scene = Scene::new(&device, format);
let controls = Controls::new();
@@ -252,7 +249,6 @@ pub fn main() {
backend.present(
&device,
&queue,
- &mut staging_belt,
&mut encoder,
&view,
primitive,
@@ -262,7 +258,6 @@ pub fn main() {
});
// Then we submit the work
- staging_belt.finish();
queue.submit(Some(encoder.finish()));
frame.present();
@@ -272,10 +267,6 @@ pub fn main() {
state.mouse_interaction(),
),
);
-
- // And recall staging buffers
- staging_belt.recall();
-
}
Err(error) => match error {
wgpu::SurfaceError::OutOfMemory => {
diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs
index 90a511ef..8c4c0daa 100644
--- a/wgpu/src/backend.rs
+++ b/wgpu/src/backend.rs
@@ -70,7 +70,6 @@ impl Backend {
&mut self,
device: &wgpu::Device,
queue: &wgpu::Queue,
- staging_belt: &mut wgpu::util::StagingBelt,
encoder: &mut wgpu::CommandEncoder,
frame: &wgpu::TextureView,
primitives: &[Primitive],
@@ -95,7 +94,6 @@ impl Backend {
scale_factor,
transformation,
&layer,
- staging_belt,
encoder,
frame,
target_size,
@@ -104,6 +102,7 @@ impl Backend {
self.quad_pipeline.end_frame();
self.text_pipeline.end_frame();
+ self.triangle_pipeline.end_frame();
#[cfg(any(feature = "image", feature = "svg"))]
self.image_pipeline.end_frame(device, queue, encoder);
@@ -116,7 +115,6 @@ impl Backend {
scale_factor: f32,
transformation: Transformation,
layer: &Layer<'_>,
- staging_belt: &mut wgpu::util::StagingBelt,
encoder: &mut wgpu::CommandEncoder,
target: &wgpu::TextureView,
target_size: Size<u32>,
@@ -159,15 +157,20 @@ impl Backend {
let scaled = transformation
* Transformation::scale(scale_factor, scale_factor);
- self.triangle_pipeline.draw(
+ self.triangle_pipeline.prepare(
+ device,
+ queue,
+ &layer.meshes,
+ scaled,
+ );
+
+ self.triangle_pipeline.render(
device,
- staging_belt,
encoder,
target,
target_size,
- scaled,
- scale_factor,
&layer.meshes,
+ scale_factor,
);
}
diff --git a/wgpu/src/buffer/dynamic.rs b/wgpu/src/buffer/dynamic.rs
index 88289b98..43fc47ac 100644
--- a/wgpu/src/buffer/dynamic.rs
+++ b/wgpu/src/buffer/dynamic.rs
@@ -112,25 +112,8 @@ impl<T: ShaderType + WriteInto> Buffer<T> {
}
/// Write the contents of this dynamic buffer to the GPU via staging belt command.
- pub fn write(
- &mut self,
- device: &wgpu::Device,
- staging_belt: &mut wgpu::util::StagingBelt,
- encoder: &mut wgpu::CommandEncoder,
- ) {
- let size = self.cpu.get_ref().len();
-
- if let Some(buffer_size) = wgpu::BufferSize::new(size as u64) {
- let mut buffer = staging_belt.write_buffer(
- encoder,
- &self.gpu,
- 0,
- buffer_size,
- device,
- );
-
- buffer.copy_from_slice(self.cpu.get_ref());
- }
+ pub fn write(&mut self, queue: &wgpu::Queue) {
+ queue.write_buffer(&self.gpu, 0, self.cpu.get_ref());
}
// Gets the aligned offset at the given index from the CPU buffer.
@@ -184,7 +167,7 @@ impl Internal {
}
/// Returns bytearray of aligned CPU buffer.
- pub(super) fn get_ref(&self) -> &Vec<u8> {
+ pub(super) fn get_ref(&self) -> &[u8] {
match self {
Internal::Uniform(buf) => buf.as_ref(),
#[cfg(not(target_arch = "wasm32"))]
diff --git a/wgpu/src/buffer/static.rs b/wgpu/src/buffer/static.rs
index ef87422f..7ae7edd2 100644
--- a/wgpu/src/buffer/static.rs
+++ b/wgpu/src/buffer/static.rs
@@ -3,7 +3,7 @@ use std::marker::PhantomData;
use std::mem;
//128 triangles/indices
-const DEFAULT_STATIC_BUFFER_COUNT: wgpu::BufferAddress = 128;
+const DEFAULT_STATIC_BUFFER_COUNT: wgpu::BufferAddress = 1_000;
/// A generic buffer struct useful for items which have no alignment requirements
/// (e.g. Vertex, Index buffers) & no dynamic offsets.
@@ -71,28 +71,15 @@ impl<T: Pod + Zeroable> Buffer<T> {
/// Returns the size of the written bytes.
pub fn write(
&mut self,
- device: &wgpu::Device,
- staging_belt: &mut wgpu::util::StagingBelt,
- encoder: &mut wgpu::CommandEncoder,
+ queue: &wgpu::Queue,
offset: u64,
content: &[T],
) -> u64 {
let bytes = bytemuck::cast_slice(content);
let bytes_size = bytes.len() as u64;
- if let Some(buffer_size) = wgpu::BufferSize::new(bytes_size) {
- let mut buffer = staging_belt.write_buffer(
- encoder,
- &self.gpu,
- offset,
- buffer_size,
- device,
- );
-
- buffer.copy_from_slice(bytes);
-
- self.offsets.push(offset);
- }
+ queue.write_buffer(&self.gpu, offset, bytes);
+ self.offsets.push(offset);
bytes_size
}
diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs
index 94bcec92..c1aa49c4 100644
--- a/wgpu/src/quad.rs
+++ b/wgpu/src/quad.rs
@@ -1,5 +1,4 @@
-use crate::buffer::Buffer;
-use crate::Transformation;
+use crate::{Buffer, Transformation};
use iced_graphics::layer;
use iced_native::Rectangle;
@@ -228,7 +227,7 @@ impl Layer {
let instances = Buffer::new(
device,
"iced_wgpu::quad instance buffer",
- MAX_INSTANCES,
+ INITIAL_INSTANCES,
wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
);
@@ -302,7 +301,7 @@ const QUAD_VERTS: [Vertex; 4] = [
},
];
-const MAX_INSTANCES: usize = 100_000;
+const INITIAL_INSTANCES: usize = 10_000;
#[repr(C)]
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
diff --git a/wgpu/src/triangle.rs b/wgpu/src/triangle.rs
index efdd214b..572af1e8 100644
--- a/wgpu/src/triangle.rs
+++ b/wgpu/src/triangle.rs
@@ -14,50 +14,56 @@ use tracing::info_span;
#[derive(Debug)]
pub struct Pipeline {
blit: Option<msaa::Blit>,
- index_buffer: Buffer<u32>,
- index_strides: Vec<u32>,
solid: solid::Pipeline,
/// Gradients are currently not supported on WASM targets due to their need of storage buffers.
#[cfg(not(target_arch = "wasm32"))]
gradient: gradient::Pipeline,
+
+ layers: Vec<Layer>,
+ prepare_layer: usize,
+ render_layer: usize,
}
-impl Pipeline {
- pub fn new(
+#[derive(Debug)]
+struct Layer {
+ index_buffer: Buffer<u32>,
+ index_strides: Vec<u32>,
+ solid: solid::Layer,
+
+ #[cfg(not(target_arch = "wasm32"))]
+ gradient: gradient::Layer,
+}
+
+impl Layer {
+ fn new(
device: &wgpu::Device,
- format: wgpu::TextureFormat,
- antialiasing: Option<settings::Antialiasing>,
- ) -> Pipeline {
- Pipeline {
- blit: antialiasing.map(|a| msaa::Blit::new(device, format, a)),
+ solid: &solid::Pipeline,
+ #[cfg(not(target_arch = "wasm32"))] gradient: &gradient::Pipeline,
+ ) -> Self {
+ Self {
index_buffer: Buffer::new(
device,
"iced_wgpu::triangle vertex buffer",
wgpu::BufferUsages::INDEX | wgpu::BufferUsages::COPY_DST,
),
index_strides: Vec::new(),
- solid: solid::Pipeline::new(device, format, antialiasing),
+ solid: solid::Layer::new(device, &solid.constants_layout),
#[cfg(not(target_arch = "wasm32"))]
- gradient: gradient::Pipeline::new(device, format, antialiasing),
+ gradient: gradient::Layer::new(device, &gradient.constants_layout),
}
}
- pub fn draw(
+ fn prepare(
&mut self,
device: &wgpu::Device,
- staging_belt: &mut wgpu::util::StagingBelt,
- encoder: &mut wgpu::CommandEncoder,
- target: &wgpu::TextureView,
- target_size: Size<u32>,
- transformation: Transformation,
- scale_factor: f32,
+ queue: &wgpu::Queue,
+ solid: &solid::Pipeline,
+ #[cfg(not(target_arch = "wasm32"))] gradient: &gradient::Pipeline,
meshes: &[Mesh<'_>],
+ transformation: Transformation,
) {
- #[cfg(feature = "tracing")]
- let _ = info_span!("Wgpu::Triangle", "DRAW").entered();
-
// Count the total amount of vertices & indices we need to handle
let count = mesh::attribute_count_of(meshes);
@@ -75,6 +81,7 @@ impl Pipeline {
.resize(device, count.gradient_vertices);
// Prepare dynamic buffers & data store for writing
+ self.index_buffer.clear();
self.index_strides.clear();
self.solid.vertices.clear();
self.solid.uniforms.clear();
@@ -99,13 +106,8 @@ impl Pipeline {
let transform =
transformation * Transformation::translate(origin.x, origin.y);
- let new_index_offset = self.index_buffer.write(
- device,
- staging_belt,
- encoder,
- index_offset,
- indices,
- );
+ let new_index_offset =
+ self.index_buffer.write(queue, index_offset, indices);
index_offset += new_index_offset;
self.index_strides.push(indices.len() as u32);
@@ -116,9 +118,7 @@ impl Pipeline {
self.solid.uniforms.push(&solid::Uniforms::new(transform));
let written_bytes = self.solid.vertices.write(
- device,
- staging_belt,
- encoder,
+ queue,
solid_vertex_offset,
&buffers.vertices,
);
@@ -130,9 +130,7 @@ impl Pipeline {
buffers, gradient, ..
} => {
let written_bytes = self.gradient.vertices.write(
- device,
- staging_belt,
- encoder,
+ queue,
gradient_vertex_offset,
&buffers.vertices,
);
@@ -196,14 +194,14 @@ impl Pipeline {
let uniforms_resized = self.solid.uniforms.resize(device);
if uniforms_resized {
- self.solid.bind_group = solid::Pipeline::bind_group(
+ self.solid.constants = solid::Layer::bind_group(
device,
self.solid.uniforms.raw(),
- &self.solid.bind_group_layout,
+ &solid.constants_layout,
)
}
- self.solid.uniforms.write(device, staging_belt, encoder);
+ self.solid.uniforms.write(queue);
}
#[cfg(not(target_arch = "wasm32"))]
@@ -218,22 +216,169 @@ impl Pipeline {
let storage_resized = self.gradient.storage.resize(device);
if uniforms_resized || storage_resized {
- self.gradient.bind_group = gradient::Pipeline::bind_group(
+ self.gradient.constants = gradient::Layer::bind_group(
device,
self.gradient.uniforms.raw(),
self.gradient.storage.raw(),
- &self.gradient.bind_group_layout,
+ &gradient.constants_layout,
);
}
// Write to GPU
- self.gradient.uniforms.write(device, staging_belt, encoder);
- self.gradient.storage.write(device, staging_belt, encoder);
+ self.gradient.uniforms.write(queue);
+ self.gradient.storage.write(queue);
// Cleanup
self.gradient.color_stop_offset = 0;
self.gradient.color_stops_pending_write.color_stops.clear();
}
+ }
+
+ fn render<'a>(
+ &'a mut self,
+ solid: &'a solid::Pipeline,
+ #[cfg(not(target_arch = "wasm32"))] gradient: &'a gradient::Pipeline,
+ meshes: &[Mesh<'_>],
+ scale_factor: f32,
+ render_pass: &mut wgpu::RenderPass<'a>,
+ ) {
+ let mut num_solids = 0;
+ #[cfg(not(target_arch = "wasm32"))]
+ let mut num_gradients = 0;
+ let mut last_is_solid = None;
+
+ for (index, mesh) in meshes.iter().enumerate() {
+ let clip_bounds = (mesh.clip_bounds() * scale_factor).snap();
+
+ render_pass.set_scissor_rect(
+ clip_bounds.x,
+ clip_bounds.y,
+ clip_bounds.width,
+ clip_bounds.height,
+ );
+
+ match mesh {
+ Mesh::Solid { .. } => {
+ if !last_is_solid.unwrap_or(false) {
+ render_pass.set_pipeline(&solid.pipeline);
+
+ last_is_solid = Some(true);
+ }
+
+ render_pass.set_bind_group(
+ 0,
+ &self.solid.constants,
+ &[self.solid.uniforms.offset_at_index(num_solids)],
+ );
+
+ render_pass.set_vertex_buffer(
+ 0,
+ self.solid.vertices.slice_from_index(num_solids),
+ );
+
+ num_solids += 1;
+ }
+ #[cfg(not(target_arch = "wasm32"))]
+ Mesh::Gradient { .. } => {
+ if last_is_solid.unwrap_or(true) {
+ render_pass.set_pipeline(&gradient.pipeline);
+
+ last_is_solid = Some(false);
+ }
+
+ render_pass.set_bind_group(
+ 0,
+ &self.gradient.constants,
+ &[self
+ .gradient
+ .uniforms
+ .offset_at_index(num_gradients)],
+ );
+
+ render_pass.set_vertex_buffer(
+ 0,
+ self.gradient.vertices.slice_from_index(num_gradients),
+ );
+
+ num_gradients += 1;
+ }
+ #[cfg(target_arch = "wasm32")]
+ Mesh::Gradient { .. } => {}
+ };
+
+ render_pass.set_index_buffer(
+ self.index_buffer.slice_from_index(index),
+ wgpu::IndexFormat::Uint32,
+ );
+
+ render_pass.draw_indexed(0..self.index_strides[index], 0, 0..1);
+ }
+ }
+}
+
+impl Pipeline {
+ pub fn new(
+ device: &wgpu::Device,
+ format: wgpu::TextureFormat,
+ antialiasing: Option<settings::Antialiasing>,
+ ) -> Pipeline {
+ Pipeline {
+ blit: antialiasing.map(|a| msaa::Blit::new(device, format, a)),
+ solid: solid::Pipeline::new(device, format, antialiasing),
+
+ #[cfg(not(target_arch = "wasm32"))]
+ gradient: gradient::Pipeline::new(device, format, antialiasing),
+
+ layers: Vec::new(),
+ prepare_layer: 0,
+ render_layer: 0,
+ }
+ }
+
+ pub fn prepare(
+ &mut self,
+ device: &wgpu::Device,
+ queue: &wgpu::Queue,
+ meshes: &[Mesh<'_>],
+ transformation: Transformation,
+ ) {
+ #[cfg(feature = "tracing")]
+ let _ = info_span!("Wgpu::Triangle", "PREPARE").entered();
+
+ if self.layers.len() <= self.prepare_layer {
+ self.layers.push(Layer::new(
+ device,
+ &self.solid,
+ #[cfg(not(target_arch = "wasm32"))]
+ &self.gradient,
+ ));
+ }
+
+ let layer = &mut self.layers[self.prepare_layer];
+ layer.prepare(
+ device,
+ queue,
+ &self.solid,
+ #[cfg(not(target_arch = "wasm32"))]
+ &self.gradient,
+ meshes,
+ transformation,
+ );
+
+ self.prepare_layer += 1;
+ }
+
+ pub fn render(
+ &mut self,
+ device: &wgpu::Device,
+ encoder: &mut wgpu::CommandEncoder,
+ target: &wgpu::TextureView,
+ target_size: Size<u32>,
+ meshes: &[Mesh<'_>],
+ scale_factor: f32,
+ ) {
+ #[cfg(feature = "tracing")]
+ let _ = info_span!("Wgpu::Triangle", "DRAW").entered();
// Configure render pass
{
@@ -268,87 +413,29 @@ impl Pipeline {
depth_stencil_attachment: None,
});
- let mut num_solids = 0;
- #[cfg(not(target_arch = "wasm32"))]
- let mut num_gradients = 0;
- let mut last_is_solid = None;
-
- for (index, mesh) in meshes.iter().enumerate() {
- let clip_bounds = (mesh.clip_bounds() * scale_factor).snap();
-
- render_pass.set_scissor_rect(
- clip_bounds.x,
- clip_bounds.y,
- clip_bounds.width,
- clip_bounds.height,
- );
-
- match mesh {
- Mesh::Solid { .. } => {
- if !last_is_solid.unwrap_or(false) {
- render_pass.set_pipeline(&self.solid.pipeline);
-
- last_is_solid = Some(true);
- }
-
- render_pass.set_bind_group(
- 0,
- &self.solid.bind_group,
- &[self.solid.uniforms.offset_at_index(num_solids)],
- );
-
- render_pass.set_vertex_buffer(
- 0,
- self.solid.vertices.slice_from_index(num_solids),
- );
-
- num_solids += 1;
- }
- #[cfg(not(target_arch = "wasm32"))]
- Mesh::Gradient { .. } => {
- if last_is_solid.unwrap_or(true) {
- render_pass.set_pipeline(&self.gradient.pipeline);
-
- last_is_solid = Some(false);
- }
-
- render_pass.set_bind_group(
- 0,
- &self.gradient.bind_group,
- &[self
- .gradient
- .uniforms
- .offset_at_index(num_gradients)],
- );
-
- render_pass.set_vertex_buffer(
- 0,
- self.gradient
- .vertices
- .slice_from_index(num_gradients),
- );
-
- num_gradients += 1;
- }
- #[cfg(target_arch = "wasm32")]
- Mesh::Gradient { .. } => {}
- };
-
- render_pass.set_index_buffer(
- self.index_buffer.slice_from_index(index),
- wgpu::IndexFormat::Uint32,
- );
+ let layer = &mut self.layers[self.render_layer];
- render_pass.draw_indexed(0..self.index_strides[index], 0, 0..1);
- }
+ layer.render(
+ &self.solid,
+ #[cfg(not(target_arch = "wasm32"))]
+ &self.gradient,
+ meshes,
+ scale_factor,
+ &mut render_pass,
+ );
}
- self.index_buffer.clear();
+ self.render_layer += 1;
if let Some(blit) = &mut self.blit {
blit.draw(encoder, target);
}
}
+
+ pub fn end_frame(&mut self) {
+ self.prepare_layer = 0;
+ self.render_layer = 0;
+ }
}
fn fragment_target(
@@ -390,10 +477,62 @@ mod solid {
#[derive(Debug)]
pub struct Pipeline {
pub pipeline: wgpu::RenderPipeline,
+ pub constants_layout: wgpu::BindGroupLayout,
+ }
+
+ #[derive(Debug)]
+ pub struct Layer {
pub vertices: Buffer<triangle::ColoredVertex2D>,
pub uniforms: dynamic::Buffer<Uniforms>,
- pub bind_group_layout: wgpu::BindGroupLayout,
- pub bind_group: wgpu::BindGroup,
+ pub constants: wgpu::BindGroup,
+ }
+
+ impl Layer {
+ pub fn new(
+ device: &wgpu::Device,
+ constants_layout: &wgpu::BindGroupLayout,
+ ) -> Self {
+ let vertices = Buffer::new(
+ device,
+ "iced_wgpu::triangle::solid vertex buffer",
+ wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
+ );
+
+ let uniforms = dynamic::Buffer::uniform(
+ device,
+ "iced_wgpu::triangle::solid uniforms",
+ );
+
+ let constants =
+ Self::bind_group(device, uniforms.raw(), constants_layout);
+
+ Self {
+ vertices,
+ uniforms,
+ constants,
+ }
+ }
+
+ pub fn bind_group(
+ device: &wgpu::Device,
+ buffer: &wgpu::Buffer,
+ layout: &wgpu::BindGroupLayout,
+ ) -> wgpu::BindGroup {
+ device.create_bind_group(&wgpu::BindGroupDescriptor {
+ label: Some("iced_wgpu::triangle::solid bind group"),
+ layout,
+ entries: &[wgpu::BindGroupEntry {
+ binding: 0,
+ resource: wgpu::BindingResource::Buffer(
+ wgpu::BufferBinding {
+ buffer,
+ offset: 0,
+ size: Some(Uniforms::min_size()),
+ },
+ ),
+ }],
+ })
+ }
}
#[derive(Debug, Clone, Copy, ShaderType)]
@@ -416,18 +555,7 @@ mod solid {
format: wgpu::TextureFormat,
antialiasing: Option<settings::Antialiasing>,
) -> Self {
- let vertices = Buffer::new(
- device,
- "iced_wgpu::triangle::solid vertex buffer",
- wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
- );
-
- let uniforms = dynamic::Buffer::uniform(
- device,
- "iced_wgpu::triangle::solid uniforms",
- );
-
- let bind_group_layout = device.create_bind_group_layout(
+ let constants_layout = device.create_bind_group_layout(
&wgpu::BindGroupLayoutDescriptor {
label: Some("iced_wgpu::triangle::solid bind group layout"),
entries: &[wgpu::BindGroupLayoutEntry {
@@ -443,13 +571,10 @@ mod solid {
},
);
- let bind_group =
- Self::bind_group(device, uniforms.raw(), &bind_group_layout);
-
let layout = device.create_pipeline_layout(
&wgpu::PipelineLayoutDescriptor {
label: Some("iced_wgpu::triangle::solid pipeline layout"),
- bind_group_layouts: &[&bind_group_layout],
+ bind_group_layouts: &[&constants_layout],
push_constant_ranges: &[],
},
);
@@ -501,33 +626,9 @@ mod solid {
Self {
pipeline,
- vertices,
- uniforms,
- bind_group_layout,
- bind_group,
+ constants_layout,
}
}
-
- pub fn bind_group(
- device: &wgpu::Device,
- buffer: &wgpu::Buffer,
- layout: &wgpu::BindGroupLayout,
- ) -> wgpu::BindGroup {
- device.create_bind_group(&wgpu::BindGroupDescriptor {
- label: Some("iced_wgpu::triangle::solid bind group"),
- layout,
- entries: &[wgpu::BindGroupEntry {
- binding: 0,
- resource: wgpu::BindingResource::Buffer(
- wgpu::BufferBinding {
- buffer,
- offset: 0,
- size: Some(Uniforms::min_size()),
- },
- ),
- }],
- })
- }
}
}
@@ -545,15 +646,90 @@ mod gradient {
#[derive(Debug)]
pub struct Pipeline {
pub pipeline: wgpu::RenderPipeline,
+ pub constants_layout: wgpu::BindGroupLayout,
+ }
+
+ #[derive(Debug)]
+ pub struct Layer {
pub vertices: Buffer<Vertex2D>,
pub uniforms: dynamic::Buffer<Uniforms>,
pub storage: dynamic::Buffer<Storage>,
+ pub constants: wgpu::BindGroup,
pub color_stop_offset: i32,
//Need to store these and then write them all at once
//or else they will be padded to 256 and cause gaps in the storage buffer
pub color_stops_pending_write: Storage,
- pub bind_group_layout: wgpu::BindGroupLayout,
- pub bind_group: wgpu::BindGroup,
+ }
+
+ impl Layer {
+ pub fn new(
+ device: &wgpu::Device,
+ constants_layout: &wgpu::BindGroupLayout,
+ ) -> Self {
+ let vertices = Buffer::new(
+ device,
+ "iced_wgpu::triangle::gradient vertex buffer",
+ wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
+ );
+
+ let uniforms = dynamic::Buffer::uniform(
+ device,
+ "iced_wgpu::triangle::gradient uniforms",
+ );
+
+ // Note: with a WASM target storage buffers are not supported. Will need to use UBOs & static
+ // sized array (eg like the 32-sized array on OpenGL side right now) to make gradients work
+ let storage = dynamic::Buffer::storage(
+ device,
+ "iced_wgpu::triangle::gradient storage",
+ );
+
+ let constants = Self::bind_group(
+ device,
+ uniforms.raw(),
+ storage.raw(),
+ constants_layout,
+ );
+
+ Self {
+ vertices,
+ uniforms,
+ storage,
+ constants,
+ color_stop_offset: 0,
+ color_stops_pending_write: Storage {
+ color_stops: vec![],
+ },
+ }
+ }
+
+ pub fn bind_group(
+ device: &wgpu::Device,
+ uniform_buffer: &wgpu::Buffer,
+ storage_buffer: &wgpu::Buffer,
+ layout: &wgpu::BindGroupLayout,
+ ) -> wgpu::BindGroup {
+ device.create_bind_group(&wgpu::BindGroupDescriptor {
+ label: Some("iced_wgpu::triangle::gradient bind group"),
+ layout,
+ entries: &[
+ wgpu::BindGroupEntry {
+ binding: 0,
+ resource: wgpu::BindingResource::Buffer(
+ wgpu::BufferBinding {
+ buffer: uniform_buffer,
+ offset: 0,
+ size: Some(Uniforms::min_size()),
+ },
+ ),
+ },
+ wgpu::BindGroupEntry {
+ binding: 1,
+ resource: storage_buffer.as_entire_binding(),
+ },
+ ],
+ })
+ }
}
#[derive(Debug, ShaderType)]
@@ -584,25 +760,7 @@ mod gradient {
format: wgpu::TextureFormat,
antialiasing: Option<settings::Antialiasing>,
) -> Self {
- let vertices = Buffer::new(
- device,
- "iced_wgpu::triangle::gradient vertex buffer",
- wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
- );
-
- let uniforms = dynamic::Buffer::uniform(
- device,
- "iced_wgpu::triangle::gradient uniforms",
- );
-
- //Note: with a WASM target storage buffers are not supported. Will need to use UBOs & static
- // sized array (eg like the 32-sized array on OpenGL side right now) to make gradients work
- let storage = dynamic::Buffer::storage(
- device,
- "iced_wgpu::triangle::gradient storage",
- );
-
- let bind_group_layout = device.create_bind_group_layout(
+ let constants_layout = device.create_bind_group_layout(
&wgpu::BindGroupLayoutDescriptor {
label: Some(
"iced_wgpu::triangle::gradient bind group layout",
@@ -634,19 +792,12 @@ mod gradient {
},
);
- let bind_group = Pipeline::bind_group(
- device,
- uniforms.raw(),
- storage.raw(),
- &bind_group_layout,
- );
-
let layout = device.create_pipeline_layout(
&wgpu::PipelineLayoutDescriptor {
label: Some(
"iced_wgpu::triangle::gradient pipeline layout",
),
- bind_group_layouts: &[&bind_group_layout],
+ bind_group_layouts: &[&constants_layout],
push_constant_ranges: &[],
},
);
@@ -694,44 +845,8 @@ mod gradient {
Self {
pipeline,
- vertices,
- uniforms,
- storage,
- color_stop_offset: 0,
- color_stops_pending_write: Storage {
- color_stops: vec![],
- },
- bind_group_layout,
- bind_group,
+ constants_layout,
}
}
-
- pub fn bind_group(
- device: &wgpu::Device,
- uniform_buffer: &wgpu::Buffer,
- storage_buffer: &wgpu::Buffer,
- layout: &wgpu::BindGroupLayout,
- ) -> wgpu::BindGroup {
- device.create_bind_group(&wgpu::BindGroupDescriptor {
- label: Some("iced_wgpu::triangle::gradient bind group"),
- layout,
- entries: &[
- wgpu::BindGroupEntry {
- binding: 0,
- resource: wgpu::BindingResource::Buffer(
- wgpu::BufferBinding {
- buffer: uniform_buffer,
- offset: 0,
- size: Some(Uniforms::min_size()),
- },
- ),
- },
- wgpu::BindGroupEntry {
- binding: 1,
- resource: storage_buffer.as_entire_binding(),
- },
- ],
- })
- }
}
}
diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs
index 50231f7c..6e1acc06 100644
--- a/wgpu/src/window/compositor.rs
+++ b/wgpu/src/window/compositor.rs
@@ -16,14 +16,11 @@ pub struct Compositor<Theme> {
adapter: wgpu::Adapter,
device: wgpu::Device,
queue: wgpu::Queue,
- staging_belt: wgpu::util::StagingBelt,
format: wgpu::TextureFormat,
theme: PhantomData<Theme>,
}
impl<Theme> Compositor<Theme> {
- const CHUNK_SIZE: u64 = 10 * 1024;
-
/// Requests a new [`Compositor`] with the given [`Settings`].
///
/// Returns `None` if no compatible graphics adapter could be found.
@@ -98,15 +95,12 @@ impl<Theme> Compositor<Theme> {
.next()
.await?;
- let staging_belt = wgpu::util::StagingBelt::new(Self::CHUNK_SIZE);
-
Some(Compositor {
instance,
settings,
adapter,
device,
queue,
- staging_belt,
format,
theme: PhantomData,
})
@@ -228,7 +222,6 @@ impl<Theme> iced_graphics::window::Compositor for Compositor<Theme> {
backend.present(
&self.device,
&self.queue,
- &mut self.staging_belt,
&mut encoder,
view,
primitives,
@@ -238,13 +231,9 @@ impl<Theme> iced_graphics::window::Compositor for Compositor<Theme> {
});
// Submit work
- self.staging_belt.finish();
let _submission = self.queue.submit(Some(encoder.finish()));
frame.present();
- // Recall staging buffers
- self.staging_belt.recall();
-
Ok(())
}
Err(error) => match error {