Refactor triangle::Pipeline into prepare and render architecture

And get rid of the staging belt! 🎉
This commit is contained in:
Héctor Ramón Jiménez 2023-02-07 23:55:16 +01:00
parent 23ed352e83
commit b8c1809ea1
No known key found for this signature in database
GPG key ID: 140CC052C94F138E
7 changed files with 358 additions and 291 deletions

View file

@ -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,
);
}

View file

@ -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"))]

View file

@ -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
}

View file

@ -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)]

View file

@ -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;
let layer = &mut self.layers[self.render_layer];
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,
);
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(),
},
],
})
}
}
}

View file

@ -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 {