From 67d90e394678eba94975a19ef51821135373b634 Mon Sep 17 00:00:00 2001
From: Héctor Ramón Jiménez <hector0193@gmail.com>
Date: Thu, 27 Aug 2020 13:03:42 +0200
Subject: Update `wgpu` to `0.6` in `iced_wgpu`

---
 wgpu/Cargo.toml               |   8 +-
 wgpu/src/backend.rs           |   6 ++
 wgpu/src/lib.rs               |   2 +-
 wgpu/src/quad.rs              | 125 +++++++++++++-------------
 wgpu/src/text.rs              |   2 +
 wgpu/src/triangle.rs          | 201 +++++++++++++++++++++++-------------------
 wgpu/src/triangle/msaa.rs     |  55 ++++++------
 wgpu/src/window/compositor.rs |  91 +++++++++++++------
 8 files changed, 277 insertions(+), 213 deletions(-)

(limited to 'wgpu')

diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml
index 6d9a1830..05088bbd 100644
--- a/wgpu/Cargo.toml
+++ b/wgpu/Cargo.toml
@@ -13,17 +13,15 @@ canvas = ["iced_graphics/canvas"]
 default_system_font = ["iced_graphics/font-source"]
 
 [dependencies]
-wgpu = "0.5"
-wgpu_glyph = "0.9"
+wgpu = "0.6"
+wgpu_glyph = "0.10"
 glyph_brush = "0.7"
 zerocopy = "0.3"
 bytemuck = "1.2"
 raw-window-handle = "0.3"
 log = "0.4"
 guillotiere = "0.5"
-# Pin `gfx-memory` until https://github.com/gfx-rs/wgpu-rs/issues/261 is
-# resolved
-gfx-memory = "=0.1.1"
+futures = "0.3"
 
 [dependencies.iced_native]
 version = "0.2"
diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs
index c71a6a77..80c982d7 100644
--- a/wgpu/src/backend.rs
+++ b/wgpu/src/backend.rs
@@ -64,6 +64,7 @@ impl Backend {
     pub fn draw<T: AsRef<str>>(
         &mut self,
         device: &wgpu::Device,
+        staging_belt: &mut wgpu::util::StagingBelt,
         encoder: &mut wgpu::CommandEncoder,
         frame: &wgpu::TextureView,
         viewport: &Viewport,
@@ -85,6 +86,7 @@ impl Backend {
                 scale_factor,
                 transformation,
                 &layer,
+                staging_belt,
                 encoder,
                 &frame,
                 target_size.width,
@@ -104,6 +106,7 @@ impl Backend {
         scale_factor: f32,
         transformation: Transformation,
         layer: &Layer<'_>,
+        staging_belt: &mut wgpu::util::StagingBelt,
         encoder: &mut wgpu::CommandEncoder,
         target: &wgpu::TextureView,
         target_width: u32,
@@ -114,6 +117,7 @@ impl Backend {
         if !layer.quads.is_empty() {
             self.quad_pipeline.draw(
                 device,
+                staging_belt,
                 encoder,
                 &layer.quads,
                 transformation,
@@ -129,6 +133,7 @@ impl Backend {
 
             self.triangle_pipeline.draw(
                 device,
+                staging_belt,
                 encoder,
                 target,
                 target_width,
@@ -225,6 +230,7 @@ impl Backend {
 
             self.text_pipeline.draw_queued(
                 device,
+                staging_belt,
                 encoder,
                 target,
                 transformation,
diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs
index e51a225c..570e8a94 100644
--- a/wgpu/src/lib.rs
+++ b/wgpu/src/lib.rs
@@ -23,7 +23,7 @@
 #![deny(missing_docs)]
 #![deny(missing_debug_implementations)]
 #![deny(unused_results)]
-#![forbid(unsafe_code)]
+#![deny(unsafe_code)]
 #![forbid(rust_2018_idioms)]
 #![cfg_attr(docsrs, feature(doc_cfg))]
 
diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs
index 0b62f44f..f8d6c509 100644
--- a/wgpu/src/quad.rs
+++ b/wgpu/src/quad.rs
@@ -3,6 +3,7 @@ use iced_graphics::layer;
 use iced_native::Rectangle;
 
 use std::mem;
+use wgpu::util::DeviceExt;
 use zerocopy::AsBytes;
 
 #[derive(Debug)]
@@ -20,50 +21,54 @@ impl Pipeline {
         let constant_layout =
             device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
                 label: None,
-                bindings: &[wgpu::BindGroupLayoutEntry {
+                entries: &[wgpu::BindGroupLayoutEntry {
                     binding: 0,
                     visibility: wgpu::ShaderStage::VERTEX,
-                    ty: wgpu::BindingType::UniformBuffer { dynamic: false },
+                    ty: wgpu::BindingType::UniformBuffer {
+                        dynamic: false,
+                        min_binding_size: wgpu::BufferSize::new(
+                            mem::size_of::<Uniforms>() as u64,
+                        ),
+                    },
+                    count: None,
                 }],
             });
 
-        let constants_buffer = device.create_buffer_with_data(
-            Uniforms::default().as_bytes(),
-            wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
-        );
+        let constants_buffer =
+            device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
+                label: None,
+                contents: Uniforms::default().as_bytes(),
+                usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
+            });
 
         let constants = device.create_bind_group(&wgpu::BindGroupDescriptor {
             label: None,
             layout: &constant_layout,
-            bindings: &[wgpu::Binding {
+            entries: &[wgpu::BindGroupEntry {
                 binding: 0,
-                resource: wgpu::BindingResource::Buffer {
-                    buffer: &constants_buffer,
-                    range: 0..std::mem::size_of::<Uniforms>() as u64,
-                },
+                resource: wgpu::BindingResource::Buffer(
+                    constants_buffer.slice(..),
+                ),
             }],
         });
 
         let layout =
             device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
+                label: None,
+                push_constant_ranges: &[],
                 bind_group_layouts: &[&constant_layout],
             });
 
-        let vs = include_bytes!("shader/quad.vert.spv");
-        let vs_module = device.create_shader_module(
-            &wgpu::read_spirv(std::io::Cursor::new(&vs[..]))
-                .expect("Read quad vertex shader as SPIR-V"),
-        );
+        let vs_module = device
+            .create_shader_module(wgpu::include_spirv!("shader/quad.vert.spv"));
 
-        let fs = include_bytes!("shader/quad.frag.spv");
-        let fs_module = device.create_shader_module(
-            &wgpu::read_spirv(std::io::Cursor::new(&fs[..]))
-                .expect("Read quad fragment shader as SPIR-V"),
-        );
+        let fs_module = device
+            .create_shader_module(wgpu::include_spirv!("shader/quad.frag.spv"));
 
         let pipeline =
             device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
-                layout: &layout,
+                label: None,
+                layout: Some(&layout),
                 vertex_stage: wgpu::ProgrammableStageDescriptor {
                     module: &vs_module,
                     entry_point: "main",
@@ -78,6 +83,7 @@ impl Pipeline {
                     depth_bias: 0,
                     depth_bias_slope_scale: 0.0,
                     depth_bias_clamp: 0.0,
+                    ..Default::default()
                 }),
                 primitive_topology: wgpu::PrimitiveTopology::TriangleList,
                 color_states: &[wgpu::ColorStateDescriptor {
@@ -150,20 +156,25 @@ impl Pipeline {
                 alpha_to_coverage_enabled: false,
             });
 
-        let vertices = device.create_buffer_with_data(
-            QUAD_VERTS.as_bytes(),
-            wgpu::BufferUsage::VERTEX,
-        );
+        let vertices =
+            device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
+                label: None,
+                contents: QUAD_VERTS.as_bytes(),
+                usage: wgpu::BufferUsage::VERTEX,
+            });
 
-        let indices = device.create_buffer_with_data(
-            QUAD_INDICES.as_bytes(),
-            wgpu::BufferUsage::INDEX,
-        );
+        let indices =
+            device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
+                label: None,
+                contents: QUAD_INDICES.as_bytes(),
+                usage: wgpu::BufferUsage::INDEX,
+            });
 
         let instances = device.create_buffer(&wgpu::BufferDescriptor {
             label: None,
             size: mem::size_of::<layer::Quad>() as u64 * MAX_INSTANCES as u64,
             usage: wgpu::BufferUsage::VERTEX | wgpu::BufferUsage::COPY_DST,
+            mapped_at_creation: false,
         });
 
         Pipeline {
@@ -179,6 +190,7 @@ impl Pipeline {
     pub fn draw(
         &mut self,
         device: &wgpu::Device,
+        staging_belt: &mut wgpu::util::StagingBelt,
         encoder: &mut wgpu::CommandEncoder,
         instances: &[layer::Quad],
         transformation: Transformation,
@@ -188,18 +200,18 @@ impl Pipeline {
     ) {
         let uniforms = Uniforms::new(transformation, scale);
 
-        let constants_buffer = device.create_buffer_with_data(
-            uniforms.as_bytes(),
-            wgpu::BufferUsage::COPY_SRC,
-        );
+        {
+            let mut constants_buffer = staging_belt.write_buffer(
+                encoder,
+                &self.constants_buffer,
+                0,
+                wgpu::BufferSize::new(mem::size_of::<Uniforms>() as u64)
+                    .unwrap(),
+                device,
+            );
 
-        encoder.copy_buffer_to_buffer(
-            &constants_buffer,
-            0,
-            &self.constants_buffer,
-            0,
-            std::mem::size_of::<Uniforms>() as u64,
-        );
+            constants_buffer.copy_from_slice(uniforms.as_bytes());
+        }
 
         let mut i = 0;
         let total = instances.len();
@@ -208,19 +220,18 @@ impl Pipeline {
             let end = (i + MAX_INSTANCES).min(total);
             let amount = end - i;
 
-            let instance_buffer = device.create_buffer_with_data(
-                bytemuck::cast_slice(&instances[i..end]),
-                wgpu::BufferUsage::COPY_SRC,
-            );
+            let instance_bytes = bytemuck::cast_slice(&instances[i..end]);
 
-            encoder.copy_buffer_to_buffer(
-                &instance_buffer,
-                0,
+            let mut instance_buffer = staging_belt.write_buffer(
+                encoder,
                 &self.instances,
                 0,
-                (mem::size_of::<layer::Quad>() * amount) as u64,
+                wgpu::BufferSize::new(instance_bytes.len() as u64).unwrap(),
+                device,
             );
 
+            instance_buffer.copy_from_slice(instance_bytes);
+
             {
                 let mut render_pass =
                     encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
@@ -228,13 +239,9 @@ impl Pipeline {
                             wgpu::RenderPassColorAttachmentDescriptor {
                                 attachment: target,
                                 resolve_target: None,
-                                load_op: wgpu::LoadOp::Load,
-                                store_op: wgpu::StoreOp::Store,
-                                clear_color: wgpu::Color {
-                                    r: 0.0,
-                                    g: 0.0,
-                                    b: 0.0,
-                                    a: 0.0,
+                                ops: wgpu::Operations {
+                                    load: wgpu::LoadOp::Load,
+                                    store: true,
                                 },
                             },
                         ],
@@ -243,9 +250,9 @@ impl Pipeline {
 
                 render_pass.set_pipeline(&self.pipeline);
                 render_pass.set_bind_group(0, &self.constants, &[]);
-                render_pass.set_index_buffer(&self.indices, 0, 0);
-                render_pass.set_vertex_buffer(0, &self.vertices, 0, 0);
-                render_pass.set_vertex_buffer(1, &self.instances, 0, 0);
+                render_pass.set_index_buffer(self.indices.slice(..));
+                render_pass.set_vertex_buffer(0, self.vertices.slice(..));
+                render_pass.set_vertex_buffer(1, self.instances.slice(..));
                 render_pass.set_scissor_rect(
                     bounds.x,
                     bounds.y,
diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs
index a7123d39..78999cf8 100644
--- a/wgpu/src/text.rs
+++ b/wgpu/src/text.rs
@@ -65,6 +65,7 @@ impl Pipeline {
     pub fn draw_queued(
         &mut self,
         device: &wgpu::Device,
+        staging_belt: &mut wgpu::util::StagingBelt,
         encoder: &mut wgpu::CommandEncoder,
         target: &wgpu::TextureView,
         transformation: Transformation,
@@ -74,6 +75,7 @@ impl Pipeline {
             .borrow_mut()
             .draw_queued_with_transform_and_scissoring(
                 device,
+                staging_belt,
                 encoder,
                 target,
                 transformation.into(),
diff --git a/wgpu/src/triangle.rs b/wgpu/src/triangle.rs
index 2744c67a..fcab5e3d 100644
--- a/wgpu/src/triangle.rs
+++ b/wgpu/src/triangle.rs
@@ -8,7 +8,7 @@ pub use iced_graphics::triangle::{Mesh2D, Vertex2D};
 
 mod msaa;
 
-const UNIFORM_BUFFER_SIZE: usize = 100;
+const UNIFORM_BUFFER_SIZE: usize = 50;
 const VERTEX_BUFFER_SIZE: usize = 10_000;
 const INDEX_BUFFER_SIZE: usize = 10_000;
 
@@ -41,6 +41,7 @@ impl<T> Buffer<T> {
             label: None,
             size: (std::mem::size_of::<T>() * size) as u64,
             usage,
+            mapped_at_creation: false,
         });
 
         Buffer {
@@ -59,6 +60,7 @@ impl<T> Buffer<T> {
                 label: None,
                 size: (std::mem::size_of::<T>() * size) as u64,
                 usage: self.usage,
+                mapped_at_creation: false,
             });
 
             self.size = size;
@@ -77,10 +79,16 @@ impl Pipeline {
         let constants_layout =
             device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
                 label: None,
-                bindings: &[wgpu::BindGroupLayoutEntry {
+                entries: &[wgpu::BindGroupLayoutEntry {
                     binding: 0,
                     visibility: wgpu::ShaderStage::VERTEX,
-                    ty: wgpu::BindingType::UniformBuffer { dynamic: true },
+                    ty: wgpu::BindingType::UniformBuffer {
+                        dynamic: true,
+                        min_binding_size: wgpu::BufferSize::new(
+                            mem::size_of::<Uniforms>() as u64,
+                        ),
+                    },
+                    count: None,
                 }],
             });
 
@@ -94,35 +102,35 @@ impl Pipeline {
             device.create_bind_group(&wgpu::BindGroupDescriptor {
                 label: None,
                 layout: &constants_layout,
-                bindings: &[wgpu::Binding {
+                entries: &[wgpu::BindGroupEntry {
                     binding: 0,
-                    resource: wgpu::BindingResource::Buffer {
-                        buffer: &constants_buffer.raw,
-                        range: 0..std::mem::size_of::<Uniforms>() as u64,
-                    },
+                    resource: wgpu::BindingResource::Buffer(
+                        constants_buffer
+                            .raw
+                            .slice(0..std::mem::size_of::<Uniforms>() as u64),
+                    ),
                 }],
             });
 
         let layout =
             device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
+                label: None,
+                push_constant_ranges: &[],
                 bind_group_layouts: &[&constants_layout],
             });
 
-        let vs = include_bytes!("shader/triangle.vert.spv");
-        let vs_module = device.create_shader_module(
-            &wgpu::read_spirv(std::io::Cursor::new(&vs[..]))
-                .expect("Read triangle vertex shader as SPIR-V"),
-        );
+        let vs_module = device.create_shader_module(wgpu::include_spirv!(
+            "shader/triangle.vert.spv"
+        ));
 
-        let fs = include_bytes!("shader/triangle.frag.spv");
-        let fs_module = device.create_shader_module(
-            &wgpu::read_spirv(std::io::Cursor::new(&fs[..]))
-                .expect("Read triangle fragment shader as SPIR-V"),
-        );
+        let fs_module = device.create_shader_module(wgpu::include_spirv!(
+            "shader/triangle.frag.spv"
+        ));
 
         let pipeline =
             device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
-                layout: &layout,
+                label: None,
+                layout: Some(&layout),
                 vertex_stage: wgpu::ProgrammableStageDescriptor {
                     module: &vs_module,
                     entry_point: "main",
@@ -137,6 +145,7 @@ impl Pipeline {
                     depth_bias: 0,
                     depth_bias_slope_scale: 0.0,
                     depth_bias_clamp: 0.0,
+                    ..Default::default()
                 }),
                 primitive_topology: wgpu::PrimitiveTopology::TriangleList,
                 color_states: &[wgpu::ColorStateDescriptor {
@@ -204,6 +213,7 @@ impl Pipeline {
     pub fn draw(
         &mut self,
         device: &wgpu::Device,
+        staging_belt: &mut wgpu::util::StagingBelt,
         encoder: &mut wgpu::CommandEncoder,
         target: &wgpu::TextureView,
         target_width: u32,
@@ -236,12 +246,13 @@ impl Pipeline {
                 device.create_bind_group(&wgpu::BindGroupDescriptor {
                     label: None,
                     layout: &self.constants_layout,
-                    bindings: &[wgpu::Binding {
+                    entries: &[wgpu::BindGroupEntry {
                         binding: 0,
-                        resource: wgpu::BindingResource::Buffer {
-                            buffer: &self.uniforms_buffer.raw,
-                            range: 0..std::mem::size_of::<Uniforms>() as u64,
-                        },
+                        resource: wgpu::BindingResource::Buffer(
+                            self.uniforms_buffer.raw.slice(
+                                0..std::mem::size_of::<Uniforms>() as u64,
+                            ),
+                        ),
                     }],
                 });
         }
@@ -261,65 +272,85 @@ impl Pipeline {
                 * Transformation::translate(mesh.origin.x, mesh.origin.y))
             .into();
 
-            let vertex_buffer = device.create_buffer_with_data(
-                bytemuck::cast_slice(&mesh.buffers.vertices),
-                wgpu::BufferUsage::COPY_SRC,
-            );
+            let vertices = bytemuck::cast_slice(&mesh.buffers.vertices);
+            let indices = bytemuck::cast_slice(&mesh.buffers.indices);
 
-            let index_buffer = device.create_buffer_with_data(
-                mesh.buffers.indices.as_bytes(),
-                wgpu::BufferUsage::COPY_SRC,
-            );
+            if let Some(vertices_size) =
+                wgpu::BufferSize::new(vertices.len() as u64)
+            {
+                if let Some(indices_size) =
+                    wgpu::BufferSize::new(indices.len() as u64)
+                {
+                    {
+                        let mut vertex_buffer = staging_belt.write_buffer(
+                            encoder,
+                            &self.vertex_buffer.raw,
+                            (std::mem::size_of::<Vertex2D>() * last_vertex)
+                                as u64,
+                            vertices_size,
+                            device,
+                        );
+
+                        vertex_buffer.copy_from_slice(vertices);
+                    }
+
+                    {
+                        let mut index_buffer = staging_belt.write_buffer(
+                            encoder,
+                            &self.index_buffer.raw,
+                            (std::mem::size_of::<u32>() * last_index) as u64,
+                            indices_size,
+                            device,
+                        );
+
+                        index_buffer.copy_from_slice(indices);
+                    }
+
+                    uniforms.push(transform);
+                    offsets.push((
+                        last_vertex as u64,
+                        last_index as u64,
+                        mesh.buffers.indices.len(),
+                    ));
+
+                    last_vertex += mesh.buffers.vertices.len();
+                    last_index += mesh.buffers.indices.len();
+                }
+            }
+        }
 
-            encoder.copy_buffer_to_buffer(
-                &vertex_buffer,
-                0,
-                &self.vertex_buffer.raw,
-                (std::mem::size_of::<Vertex2D>() * last_vertex) as u64,
-                (std::mem::size_of::<Vertex2D>() * mesh.buffers.vertices.len())
-                    as u64,
-            );
+        let uniforms = uniforms.as_bytes();
 
-            encoder.copy_buffer_to_buffer(
-                &index_buffer,
+        if let Some(uniforms_size) =
+            wgpu::BufferSize::new(uniforms.len() as u64)
+        {
+            let mut uniforms_buffer = staging_belt.write_buffer(
+                encoder,
+                &self.uniforms_buffer.raw,
                 0,
-                &self.index_buffer.raw,
-                (std::mem::size_of::<u32>() * last_index) as u64,
-                (std::mem::size_of::<u32>() * mesh.buffers.indices.len())
-                    as u64,
+                uniforms_size,
+                device,
             );
 
-            uniforms.push(transform);
-            offsets.push((
-                last_vertex as u64,
-                last_index as u64,
-                mesh.buffers.indices.len(),
-            ));
-
-            last_vertex += mesh.buffers.vertices.len();
-            last_index += mesh.buffers.indices.len();
+            uniforms_buffer.copy_from_slice(uniforms);
         }
 
-        let uniforms_buffer = device.create_buffer_with_data(
-            uniforms.as_bytes(),
-            wgpu::BufferUsage::COPY_SRC,
-        );
-
-        encoder.copy_buffer_to_buffer(
-            &uniforms_buffer,
-            0,
-            &self.uniforms_buffer.raw,
-            0,
-            (std::mem::size_of::<Uniforms>() * uniforms.len()) as u64,
-        );
-
         {
-            let (attachment, resolve_target, load_op) =
+            let (attachment, resolve_target, load) =
                 if let Some(blit) = &mut self.blit {
                     let (attachment, resolve_target) =
                         blit.targets(device, target_width, target_height);
 
-                    (attachment, Some(resolve_target), wgpu::LoadOp::Clear)
+                    (
+                        attachment,
+                        Some(resolve_target),
+                        wgpu::LoadOp::Clear(wgpu::Color {
+                            r: 0.0,
+                            g: 0.0,
+                            b: 0.0,
+                            a: 0.0,
+                        }),
+                    )
                 } else {
                     (target, None, wgpu::LoadOp::Load)
                 };
@@ -330,14 +361,7 @@ impl Pipeline {
                         wgpu::RenderPassColorAttachmentDescriptor {
                             attachment,
                             resolve_target,
-                            load_op,
-                            store_op: wgpu::StoreOp::Store,
-                            clear_color: wgpu::Color {
-                                r: 0.0,
-                                g: 0.0,
-                                b: 0.0,
-                                a: 0.0,
-                            },
+                            ops: wgpu::Operations { load, store: true },
                         },
                     ],
                     depth_stencil_attachment: None,
@@ -363,20 +387,17 @@ impl Pipeline {
                     &[(std::mem::size_of::<Uniforms>() * i) as u32],
                 );
 
-                render_pass.set_index_buffer(
-                    &self.index_buffer.raw,
-                    index_offset * std::mem::size_of::<u32>() as u64,
-                    0,
-                );
+                render_pass.set_index_buffer(self.index_buffer.raw.slice(..));
 
-                render_pass.set_vertex_buffer(
-                    0,
-                    &self.vertex_buffer.raw,
-                    vertex_offset * std::mem::size_of::<Vertex2D>() as u64,
-                    0,
-                );
+                render_pass
+                    .set_vertex_buffer(0, self.vertex_buffer.raw.slice(..));
 
-                render_pass.draw_indexed(0..indices as u32, 0, 0..1);
+                render_pass.draw_indexed(
+                    index_offset as u32
+                        ..(index_offset as usize + indices) as u32,
+                    vertex_offset as i32,
+                    0..1,
+                );
             }
         }
 
diff --git a/wgpu/src/triangle/msaa.rs b/wgpu/src/triangle/msaa.rs
index f52c888b..f25667a5 100644
--- a/wgpu/src/triangle/msaa.rs
+++ b/wgpu/src/triangle/msaa.rs
@@ -23,18 +23,17 @@ impl Blit {
             mag_filter: wgpu::FilterMode::Linear,
             min_filter: wgpu::FilterMode::Linear,
             mipmap_filter: wgpu::FilterMode::Linear,
-            lod_min_clamp: -100.0,
-            lod_max_clamp: 100.0,
-            compare: wgpu::CompareFunction::Always,
+            ..Default::default()
         });
 
         let constant_layout =
             device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
                 label: None,
-                bindings: &[wgpu::BindGroupLayoutEntry {
+                entries: &[wgpu::BindGroupLayoutEntry {
                     binding: 0,
                     visibility: wgpu::ShaderStage::FRAGMENT,
                     ty: wgpu::BindingType::Sampler { comparison: false },
+                    count: None,
                 }],
             });
 
@@ -42,7 +41,7 @@ impl Blit {
             device.create_bind_group(&wgpu::BindGroupDescriptor {
                 label: None,
                 layout: &constant_layout,
-                bindings: &[wgpu::Binding {
+                entries: &[wgpu::BindGroupEntry {
                     binding: 0,
                     resource: wgpu::BindingResource::Sampler(&sampler),
                 }],
@@ -51,7 +50,7 @@ impl Blit {
         let texture_layout =
             device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
                 label: None,
-                bindings: &[wgpu::BindGroupLayoutEntry {
+                entries: &[wgpu::BindGroupLayoutEntry {
                     binding: 0,
                     visibility: wgpu::ShaderStage::FRAGMENT,
                     ty: wgpu::BindingType::SampledTexture {
@@ -59,29 +58,29 @@ impl Blit {
                         component_type: wgpu::TextureComponentType::Float,
                         multisampled: false,
                     },
+                    count: None,
                 }],
             });
 
         let layout =
             device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
+                label: None,
+                push_constant_ranges: &[],
                 bind_group_layouts: &[&constant_layout, &texture_layout],
             });
 
-        let vs = include_bytes!("../shader/blit.vert.spv");
-        let vs_module = device.create_shader_module(
-            &wgpu::read_spirv(std::io::Cursor::new(&vs[..]))
-                .expect("Read blit vertex shader as SPIR-V"),
-        );
+        let vs_module = device.create_shader_module(wgpu::include_spirv!(
+            "../shader/blit.vert.spv"
+        ));
 
-        let fs = include_bytes!("../shader/blit.frag.spv");
-        let fs_module = device.create_shader_module(
-            &wgpu::read_spirv(std::io::Cursor::new(&fs[..]))
-                .expect("Read blit fragment shader as SPIR-V"),
-        );
+        let fs_module = device.create_shader_module(wgpu::include_spirv!(
+            "../shader/blit.frag.spv"
+        ));
 
         let pipeline =
             device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
-                layout: &layout,
+                label: None,
+                layout: Some(&layout),
                 vertex_stage: wgpu::ProgrammableStageDescriptor {
                     module: &vs_module,
                     entry_point: "main",
@@ -96,6 +95,7 @@ impl Blit {
                     depth_bias: 0,
                     depth_bias_slope_scale: 0.0,
                     depth_bias_clamp: 0.0,
+                    ..Default::default()
                 }),
                 primitive_topology: wgpu::PrimitiveTopology::TriangleList,
                 color_states: &[wgpu::ColorStateDescriptor {
@@ -179,13 +179,9 @@ impl Blit {
                     wgpu::RenderPassColorAttachmentDescriptor {
                         attachment: target,
                         resolve_target: None,
-                        load_op: wgpu::LoadOp::Load,
-                        store_op: wgpu::StoreOp::Store,
-                        clear_color: wgpu::Color {
-                            r: 0.0,
-                            g: 0.0,
-                            b: 0.0,
-                            a: 0.0,
+                        ops: wgpu::Operations {
+                            load: wgpu::LoadOp::Load,
+                            store: true,
                         },
                     },
                 ],
@@ -230,7 +226,6 @@ impl Targets {
         let attachment = device.create_texture(&wgpu::TextureDescriptor {
             label: None,
             size: extent,
-            array_layer_count: 1,
             mip_level_count: 1,
             sample_count,
             dimension: wgpu::TextureDimension::D2,
@@ -241,7 +236,6 @@ impl Targets {
         let resolve = device.create_texture(&wgpu::TextureDescriptor {
             label: None,
             size: extent,
-            array_layer_count: 1,
             mip_level_count: 1,
             sample_count: 1,
             dimension: wgpu::TextureDimension::D2,
@@ -250,13 +244,16 @@ impl Targets {
                 | wgpu::TextureUsage::SAMPLED,
         });
 
-        let attachment = attachment.create_default_view();
-        let resolve = resolve.create_default_view();
+        let attachment =
+            attachment.create_view(&wgpu::TextureViewDescriptor::default());
+
+        let resolve =
+            resolve.create_view(&wgpu::TextureViewDescriptor::default());
 
         let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
             label: None,
             layout: texture_layout,
-            bindings: &[wgpu::Binding {
+            entries: &[wgpu::BindGroupEntry {
                 binding: 0,
                 resource: wgpu::BindingResource::TextureView(&resolve),
             }],
diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs
index 5bdd34bc..0c94c281 100644
--- a/wgpu/src/window/compositor.rs
+++ b/wgpu/src/window/compositor.rs
@@ -1,18 +1,24 @@
 use crate::{Backend, Color, Renderer, Settings};
 
+use futures::task::SpawnExt;
 use iced_graphics::Viewport;
 use iced_native::{futures, mouse};
 use raw_window_handle::HasRawWindowHandle;
 
 /// A window graphics backend for iced powered by `wgpu`.
-#[derive(Debug)]
+#[allow(missing_debug_implementations)]
 pub struct Compositor {
     settings: Settings,
+    instance: wgpu::Instance,
     device: wgpu::Device,
     queue: wgpu::Queue,
+    staging_belt: wgpu::util::StagingBelt,
+    local_pool: futures::executor::LocalPool,
 }
 
 impl Compositor {
+    const CHUNK_SIZE: u64 = 10 * 1024;
+
     /// Requests a new [`Compositor`] with the given [`Settings`].
     ///
     /// Returns `None` if no compatible graphics adapter could be found.
@@ -20,32 +26,44 @@ impl Compositor {
     /// [`Compositor`]: struct.Compositor.html
     /// [`Settings`]: struct.Settings.html
     pub async fn request(settings: Settings) -> Option<Self> {
-        let adapter = wgpu::Adapter::request(
-            &wgpu::RequestAdapterOptions {
+        let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY);
+
+        let adapter = instance
+            .request_adapter(&wgpu::RequestAdapterOptions {
                 power_preference: if settings.antialiasing.is_none() {
                     wgpu::PowerPreference::Default
                 } else {
                     wgpu::PowerPreference::HighPerformance
                 },
                 compatible_surface: None,
-            },
-            wgpu::BackendBit::PRIMARY,
-        )
-        .await?;
+            })
+            .await?;
 
         let (device, queue) = adapter
-            .request_device(&wgpu::DeviceDescriptor {
-                extensions: wgpu::Extensions {
-                    anisotropic_filtering: false,
+            .request_device(
+                &wgpu::DeviceDescriptor {
+                    features: wgpu::Features::empty(),
+                    limits: wgpu::Limits {
+                        max_bind_groups: 2,
+                        ..wgpu::Limits::default()
+                    },
+                    shader_validation: false,
                 },
-                limits: wgpu::Limits { max_bind_groups: 2 },
-            })
-            .await;
+                None,
+            )
+            .await
+            .ok()?;
+
+        let staging_belt = wgpu::util::StagingBelt::new(Self::CHUNK_SIZE);
+        let local_pool = futures::executor::LocalPool::new();
 
         Some(Compositor {
+            instance,
             settings,
             device,
             queue,
+            staging_belt,
+            local_pool,
         })
     }
 
@@ -77,7 +95,10 @@ impl iced_graphics::window::Compositor for Compositor {
         &mut self,
         window: &W,
     ) -> wgpu::Surface {
-        wgpu::Surface::create(window)
+        #[allow(unsafe_code)]
+        unsafe {
+            self.instance.create_surface(window)
+        }
     }
 
     fn create_swap_chain(
@@ -107,7 +128,7 @@ impl iced_graphics::window::Compositor for Compositor {
         output: &<Self::Renderer as iced_native::Renderer>::Output,
         overlay: &[T],
     ) -> mouse::Interaction {
-        let frame = swap_chain.get_next_texture().expect("Next frame");
+        let frame = swap_chain.get_current_frame().expect("Next frame");
 
         let mut encoder = self.device.create_command_encoder(
             &wgpu::CommandEncoderDescriptor { label: None },
@@ -115,19 +136,20 @@ impl iced_graphics::window::Compositor for Compositor {
 
         let _ = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
             color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
-                attachment: &frame.view,
+                attachment: &frame.output.view,
                 resolve_target: None,
-                load_op: wgpu::LoadOp::Clear,
-                store_op: wgpu::StoreOp::Store,
-                clear_color: {
-                    let [r, g, b, a] = background_color.into_linear();
-
-                    wgpu::Color {
-                        r: f64::from(r),
-                        g: f64::from(g),
-                        b: f64::from(b),
-                        a: f64::from(a),
-                    }
+                ops: wgpu::Operations {
+                    load: wgpu::LoadOp::Clear({
+                        let [r, g, b, a] = background_color.into_linear();
+
+                        wgpu::Color {
+                            r: f64::from(r),
+                            g: f64::from(g),
+                            b: f64::from(b),
+                            a: f64::from(a),
+                        }
+                    }),
+                    store: true,
                 },
             }],
             depth_stencil_attachment: None,
@@ -135,14 +157,25 @@ impl iced_graphics::window::Compositor for Compositor {
 
         let mouse_interaction = renderer.backend_mut().draw(
             &mut self.device,
+            &mut self.staging_belt,
             &mut encoder,
-            &frame.view,
+            &frame.output.view,
             viewport,
             output,
             overlay,
         );
 
-        self.queue.submit(&[encoder.finish()]);
+        // Submit work
+        self.staging_belt.finish();
+        self.queue.submit(Some(encoder.finish()));
+
+        // Recall staging buffers
+        self.local_pool
+            .spawner()
+            .spawn(self.staging_belt.recall())
+            .expect("Recall staging belt");
+
+        self.local_pool.run_until_stalled();
 
         mouse_interaction
     }
-- 
cgit 


From 83e037829c67d010afa1f3318252f2e40535352e Mon Sep 17 00:00:00 2001
From: Héctor Ramón Jiménez <hector0193@gmail.com>
Date: Thu, 27 Aug 2020 13:41:00 +0200
Subject: Update `image` pipeline in `iced_wgpu`

---
 wgpu/src/backend.rs     |   1 +
 wgpu/src/image.rs       | 158 ++++++++++++++++++++++++++----------------------
 wgpu/src/image/atlas.rs |  76 ++++++++++++++++++-----
 3 files changed, 147 insertions(+), 88 deletions(-)

(limited to 'wgpu')

diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs
index 80c982d7..819d65c7 100644
--- a/wgpu/src/backend.rs
+++ b/wgpu/src/backend.rs
@@ -152,6 +152,7 @@ impl Backend {
 
                 self.image_pipeline.draw(
                     device,
+                    staging_belt,
                     encoder,
                     &layer.images,
                     scaled,
diff --git a/wgpu/src/image.rs b/wgpu/src/image.rs
index 49f1d29c..cd756c1e 100644
--- a/wgpu/src/image.rs
+++ b/wgpu/src/image.rs
@@ -42,6 +42,8 @@ pub struct Pipeline {
 
 impl Pipeline {
     pub fn new(device: &wgpu::Device, format: wgpu::TextureFormat) -> Self {
+        use wgpu::util::DeviceExt;
+
         let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
             address_mode_u: wgpu::AddressMode::ClampToEdge,
             address_mode_v: wgpu::AddressMode::ClampToEdge,
@@ -49,24 +51,29 @@ impl Pipeline {
             mag_filter: wgpu::FilterMode::Linear,
             min_filter: wgpu::FilterMode::Linear,
             mipmap_filter: wgpu::FilterMode::Linear,
-            lod_min_clamp: -100.0,
-            lod_max_clamp: 100.0,
-            compare: wgpu::CompareFunction::Always,
+            ..Default::default()
         });
 
         let constant_layout =
             device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
                 label: None,
-                bindings: &[
+                entries: &[
                     wgpu::BindGroupLayoutEntry {
                         binding: 0,
                         visibility: wgpu::ShaderStage::VERTEX,
-                        ty: wgpu::BindingType::UniformBuffer { dynamic: false },
+                        ty: wgpu::BindingType::UniformBuffer {
+                            dynamic: false,
+                            min_binding_size: wgpu::BufferSize::new(
+                                mem::size_of::<Uniforms>() as u64,
+                            ),
+                        },
+                        count: None,
                     },
                     wgpu::BindGroupLayoutEntry {
                         binding: 1,
                         visibility: wgpu::ShaderStage::FRAGMENT,
                         ty: wgpu::BindingType::Sampler { comparison: false },
+                        count: None,
                     },
                 ],
             });
@@ -75,24 +82,25 @@ impl Pipeline {
             transform: Transformation::identity().into(),
         };
 
-        let uniforms_buffer = device.create_buffer_with_data(
-            uniforms.as_bytes(),
-            wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
-        );
+        let uniforms_buffer =
+            device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
+                label: None,
+                contents: uniforms.as_bytes(),
+                usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
+            });
 
         let constant_bind_group =
             device.create_bind_group(&wgpu::BindGroupDescriptor {
                 label: None,
                 layout: &constant_layout,
-                bindings: &[
-                    wgpu::Binding {
+                entries: &[
+                    wgpu::BindGroupEntry {
                         binding: 0,
-                        resource: wgpu::BindingResource::Buffer {
-                            buffer: &uniforms_buffer,
-                            range: 0..std::mem::size_of::<Uniforms>() as u64,
-                        },
+                        resource: wgpu::BindingResource::Buffer(
+                            uniforms_buffer.slice(..),
+                        ),
                     },
-                    wgpu::Binding {
+                    wgpu::BindGroupEntry {
                         binding: 1,
                         resource: wgpu::BindingResource::Sampler(&sampler),
                     },
@@ -102,7 +110,7 @@ impl Pipeline {
         let texture_layout =
             device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
                 label: None,
-                bindings: &[wgpu::BindGroupLayoutEntry {
+                entries: &[wgpu::BindGroupLayoutEntry {
                     binding: 0,
                     visibility: wgpu::ShaderStage::FRAGMENT,
                     ty: wgpu::BindingType::SampledTexture {
@@ -110,29 +118,29 @@ impl Pipeline {
                         component_type: wgpu::TextureComponentType::Float,
                         multisampled: false,
                     },
+                    count: None,
                 }],
             });
 
         let layout =
             device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
+                label: None,
+                push_constant_ranges: &[],
                 bind_group_layouts: &[&constant_layout, &texture_layout],
             });
 
-        let vs = include_bytes!("shader/image.vert.spv");
-        let vs_module = device.create_shader_module(
-            &wgpu::read_spirv(std::io::Cursor::new(&vs[..]))
-                .expect("Read image vertex shader as SPIR-V"),
-        );
+        let vs_module = device.create_shader_module(wgpu::include_spirv!(
+            "shader/image.vert.spv"
+        ));
 
-        let fs = include_bytes!("shader/image.frag.spv");
-        let fs_module = device.create_shader_module(
-            &wgpu::read_spirv(std::io::Cursor::new(&fs[..]))
-                .expect("Read image fragment shader as SPIR-V"),
-        );
+        let fs_module = device.create_shader_module(wgpu::include_spirv!(
+            "shader/image.frag.spv"
+        ));
 
         let pipeline =
             device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
-                layout: &layout,
+                label: None,
+                layout: Some(&layout),
                 vertex_stage: wgpu::ProgrammableStageDescriptor {
                     module: &vs_module,
                     entry_point: "main",
@@ -147,6 +155,7 @@ impl Pipeline {
                     depth_bias: 0,
                     depth_bias_slope_scale: 0.0,
                     depth_bias_clamp: 0.0,
+                    ..Default::default()
                 }),
                 primitive_topology: wgpu::PrimitiveTopology::TriangleList,
                 color_states: &[wgpu::ColorStateDescriptor {
@@ -214,20 +223,25 @@ impl Pipeline {
                 alpha_to_coverage_enabled: false,
             });
 
-        let vertices = device.create_buffer_with_data(
-            QUAD_VERTS.as_bytes(),
-            wgpu::BufferUsage::VERTEX,
-        );
+        let vertices =
+            device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
+                label: None,
+                contents: QUAD_VERTS.as_bytes(),
+                usage: wgpu::BufferUsage::VERTEX,
+            });
 
-        let indices = device.create_buffer_with_data(
-            QUAD_INDICES.as_bytes(),
-            wgpu::BufferUsage::INDEX,
-        );
+        let indices =
+            device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
+                label: None,
+                contents: QUAD_INDICES.as_bytes(),
+                usage: wgpu::BufferUsage::INDEX,
+            });
 
         let instances = device.create_buffer(&wgpu::BufferDescriptor {
             label: None,
             size: mem::size_of::<Instance>() as u64 * Instance::MAX as u64,
             usage: wgpu::BufferUsage::VERTEX | wgpu::BufferUsage::COPY_DST,
+            mapped_at_creation: false,
         });
 
         let texture_atlas = Atlas::new(device);
@@ -235,7 +249,7 @@ impl Pipeline {
         let texture = device.create_bind_group(&wgpu::BindGroupDescriptor {
             label: None,
             layout: &texture_layout,
-            bindings: &[wgpu::Binding {
+            entries: &[wgpu::BindGroupEntry {
                 binding: 0,
                 resource: wgpu::BindingResource::TextureView(
                     &texture_atlas.view(),
@@ -282,6 +296,7 @@ impl Pipeline {
     pub fn draw(
         &mut self,
         device: &wgpu::Device,
+        staging_belt: &mut wgpu::util::StagingBelt,
         encoder: &mut wgpu::CommandEncoder,
         images: &[layer::Image],
         transformation: Transformation,
@@ -356,7 +371,7 @@ impl Pipeline {
                 device.create_bind_group(&wgpu::BindGroupDescriptor {
                     label: None,
                     layout: &self.texture_layout,
-                    bindings: &[wgpu::Binding {
+                    entries: &[wgpu::BindGroupEntry {
                         binding: 0,
                         resource: wgpu::BindingResource::TextureView(
                             &self.texture_atlas.view(),
@@ -367,26 +382,23 @@ impl Pipeline {
             self.texture_version = texture_version;
         }
 
-        let uniforms_buffer = device.create_buffer_with_data(
-            Uniforms {
-                transform: transformation.into(),
-            }
-            .as_bytes(),
-            wgpu::BufferUsage::COPY_SRC,
-        );
-
-        encoder.copy_buffer_to_buffer(
-            &uniforms_buffer,
-            0,
-            &self.uniforms,
-            0,
-            std::mem::size_of::<Uniforms>() as u64,
-        );
-
-        let instances_buffer = device.create_buffer_with_data(
-            instances.as_bytes(),
-            wgpu::BufferUsage::COPY_SRC,
-        );
+        {
+            let mut uniforms_buffer = staging_belt.write_buffer(
+                encoder,
+                &self.uniforms,
+                0,
+                wgpu::BufferSize::new(mem::size_of::<Uniforms>() as u64)
+                    .unwrap(),
+                device,
+            );
+
+            uniforms_buffer.copy_from_slice(
+                Uniforms {
+                    transform: transformation.into(),
+                }
+                .as_bytes(),
+            );
+        }
 
         let mut i = 0;
         let total = instances.len();
@@ -395,27 +407,29 @@ impl Pipeline {
             let end = (i + Instance::MAX).min(total);
             let amount = end - i;
 
-            encoder.copy_buffer_to_buffer(
-                &instances_buffer,
-                (i * std::mem::size_of::<Instance>()) as u64,
+            let mut instances_buffer = staging_belt.write_buffer(
+                encoder,
                 &self.instances,
                 0,
-                (amount * std::mem::size_of::<Instance>()) as u64,
+                wgpu::BufferSize::new(
+                    (amount * std::mem::size_of::<Instance>()) as u64,
+                )
+                .unwrap(),
+                device,
             );
 
+            instances_buffer
+                .copy_from_slice(instances[i..i + amount].as_bytes());
+
             let mut render_pass =
                 encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
                     color_attachments: &[
                         wgpu::RenderPassColorAttachmentDescriptor {
                             attachment: target,
                             resolve_target: None,
-                            load_op: wgpu::LoadOp::Load,
-                            store_op: wgpu::StoreOp::Store,
-                            clear_color: wgpu::Color {
-                                r: 0.0,
-                                g: 0.0,
-                                b: 0.0,
-                                a: 0.0,
+                            ops: wgpu::Operations {
+                                load: wgpu::LoadOp::Load,
+                                store: true,
                             },
                         },
                     ],
@@ -425,9 +439,9 @@ impl Pipeline {
             render_pass.set_pipeline(&self.pipeline);
             render_pass.set_bind_group(0, &self.constants, &[]);
             render_pass.set_bind_group(1, &self.texture, &[]);
-            render_pass.set_index_buffer(&self.indices, 0, 0);
-            render_pass.set_vertex_buffer(0, &self.vertices, 0, 0);
-            render_pass.set_vertex_buffer(1, &self.instances, 0, 0);
+            render_pass.set_index_buffer(self.indices.slice(..));
+            render_pass.set_vertex_buffer(0, self.vertices.slice(..));
+            render_pass.set_vertex_buffer(1, self.instances.slice(..));
 
             render_pass.set_scissor_rect(
                 bounds.x,
diff --git a/wgpu/src/image/atlas.rs b/wgpu/src/image/atlas.rs
index 3ce3ce8b..99e9995f 100644
--- a/wgpu/src/image/atlas.rs
+++ b/wgpu/src/image/atlas.rs
@@ -30,7 +30,6 @@ impl Atlas {
         let texture = device.create_texture(&wgpu::TextureDescriptor {
             label: None,
             size: extent,
-            array_layer_count: 2,
             mip_level_count: 1,
             sample_count: 1,
             dimension: wgpu::TextureDimension::D2,
@@ -40,7 +39,10 @@ impl Atlas {
                 | wgpu::TextureUsage::SAMPLED,
         });
 
-        let texture_view = texture.create_default_view();
+        let texture_view = texture.create_view(&wgpu::TextureViewDescriptor {
+            dimension: Some(wgpu::TextureViewDimension::D2Array),
+            ..Default::default()
+        });
 
         Atlas {
             texture,
@@ -65,6 +67,8 @@ impl Atlas {
         device: &wgpu::Device,
         encoder: &mut wgpu::CommandEncoder,
     ) -> Option<Entry> {
+        use wgpu::util::DeviceExt;
+
         let entry = {
             let current_size = self.layers.len();
             let entry = self.allocate(width, height)?;
@@ -78,8 +82,31 @@ impl Atlas {
 
         log::info!("Allocated atlas entry: {:?}", entry);
 
+        // It is a webgpu requirement that:
+        //   BufferCopyView.layout.bytes_per_row % wgpu::COPY_BYTES_PER_ROW_ALIGNMENT == 0
+        // So we calculate padded_width by rounding width up to the next
+        // multiple of wgpu::COPY_BYTES_PER_ROW_ALIGNMENT.
+        let align = wgpu::COPY_BYTES_PER_ROW_ALIGNMENT;
+        let padding = (align - (4 * width) % align) % align;
+        let padded_width = (4 * width + padding) as usize;
+        let padded_data_size = padded_width * height as usize;
+
+        let mut padded_data = vec![0; padded_data_size];
+
+        for row in 0..height as usize {
+            let offset = row * padded_width;
+
+            padded_data[offset..offset + 4 * width as usize].copy_from_slice(
+                &data[row * 4 * width as usize..(row + 1) * 4 * width as usize],
+            )
+        }
+
         let buffer =
-            device.create_buffer_with_data(data, wgpu::BufferUsage::COPY_SRC);
+            device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
+                label: None,
+                contents: &padded_data,
+                usage: wgpu::BufferUsage::COPY_SRC,
+            });
 
         match &entry {
             Entry::Contiguous(allocation) => {
@@ -87,6 +114,7 @@ impl Atlas {
                     &buffer,
                     width,
                     height,
+                    padding,
                     0,
                     &allocation,
                     encoder,
@@ -95,12 +123,13 @@ impl Atlas {
             Entry::Fragmented { fragments, .. } => {
                 for fragment in fragments {
                     let (x, y) = fragment.position;
-                    let offset = (y * width + x) as usize * 4;
+                    let offset = (y * padded_width as u32 + x) as usize * 4;
 
                     self.upload_allocation(
                         &buffer,
                         width,
                         height,
+                        padding,
                         offset,
                         &fragment.allocation,
                         encoder,
@@ -253,6 +282,7 @@ impl Atlas {
         buffer: &wgpu::Buffer,
         image_width: u32,
         image_height: u32,
+        padding: u32,
         offset: usize,
         allocation: &Allocation,
         encoder: &mut wgpu::CommandEncoder,
@@ -270,15 +300,20 @@ impl Atlas {
         encoder.copy_buffer_to_texture(
             wgpu::BufferCopyView {
                 buffer,
-                offset: offset as u64,
-                bytes_per_row: 4 * image_width,
-                rows_per_image: image_height,
+                layout: wgpu::TextureDataLayout {
+                    offset: offset as u64,
+                    bytes_per_row: 4 * image_width + padding,
+                    rows_per_image: image_height,
+                },
             },
             wgpu::TextureCopyView {
                 texture: &self.texture,
-                array_layer: layer as u32,
                 mip_level: 0,
-                origin: wgpu::Origin3d { x, y, z: 0 },
+                origin: wgpu::Origin3d {
+                    x,
+                    y,
+                    z: layer as u32,
+                },
             },
             extent,
         );
@@ -299,9 +334,8 @@ impl Atlas {
             size: wgpu::Extent3d {
                 width: SIZE,
                 height: SIZE,
-                depth: 1,
+                depth: self.layers.len() as u32,
             },
-            array_layer_count: self.layers.len() as u32,
             mip_level_count: 1,
             sample_count: 1,
             dimension: wgpu::TextureDimension::D2,
@@ -323,15 +357,21 @@ impl Atlas {
             encoder.copy_texture_to_texture(
                 wgpu::TextureCopyView {
                     texture: &self.texture,
-                    array_layer: i as u32,
                     mip_level: 0,
-                    origin: wgpu::Origin3d { x: 0, y: 0, z: 0 },
+                    origin: wgpu::Origin3d {
+                        x: 0,
+                        y: 0,
+                        z: i as u32,
+                    },
                 },
                 wgpu::TextureCopyView {
                     texture: &new_texture,
-                    array_layer: i as u32,
                     mip_level: 0,
-                    origin: wgpu::Origin3d { x: 0, y: 0, z: 0 },
+                    origin: wgpu::Origin3d {
+                        x: 0,
+                        y: 0,
+                        z: i as u32,
+                    },
                 },
                 wgpu::Extent3d {
                     width: SIZE,
@@ -342,6 +382,10 @@ impl Atlas {
         }
 
         self.texture = new_texture;
-        self.texture_view = self.texture.create_default_view();
+        self.texture_view =
+            self.texture.create_view(&wgpu::TextureViewDescriptor {
+                dimension: Some(wgpu::TextureViewDimension::D2Array),
+                ..Default::default()
+            });
     }
 }
-- 
cgit 


From ecbee66bd652228204568c17dd5e8a97b0a59ee0 Mon Sep 17 00:00:00 2001
From: Héctor Ramón Jiménez <hector0193@gmail.com>
Date: Thu, 27 Aug 2020 14:44:51 +0200
Subject: Fix `layers` initialization in `image::Atlas`

---
 wgpu/src/image/atlas.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'wgpu')

diff --git a/wgpu/src/image/atlas.rs b/wgpu/src/image/atlas.rs
index 99e9995f..8d110fc4 100644
--- a/wgpu/src/image/atlas.rs
+++ b/wgpu/src/image/atlas.rs
@@ -47,7 +47,7 @@ impl Atlas {
         Atlas {
             texture,
             texture_view,
-            layers: vec![Layer::Empty, Layer::Empty],
+            layers: vec![Layer::Empty],
         }
     }
 
-- 
cgit 


From bb5f034e08c46e5ce46ed0e38a684c5ca710cb11 Mon Sep 17 00:00:00 2001
From: Héctor Ramón Jiménez <hector0193@gmail.com>
Date: Thu, 27 Aug 2020 14:45:08 +0200
Subject: Fix `offset` calculation in `image::Atlas`

---
 wgpu/src/image/atlas.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'wgpu')

diff --git a/wgpu/src/image/atlas.rs b/wgpu/src/image/atlas.rs
index 8d110fc4..69f872e8 100644
--- a/wgpu/src/image/atlas.rs
+++ b/wgpu/src/image/atlas.rs
@@ -123,7 +123,7 @@ impl Atlas {
             Entry::Fragmented { fragments, .. } => {
                 for fragment in fragments {
                     let (x, y) = fragment.position;
-                    let offset = (y * padded_width as u32 + x) as usize * 4;
+                    let offset = (y * padded_width as u32 + 4 * x) as usize;
 
                     self.upload_allocation(
                         &buffer,
-- 
cgit 


From b689778ed94b34706bf97e5994a721a8648386a5 Mon Sep 17 00:00:00 2001
From: Héctor Ramón Jiménez <hector0193@gmail.com>
Date: Thu, 27 Aug 2020 19:15:05 +0200
Subject: Remove redundant depth bias fields in `iced_wgpu`

---
 wgpu/src/image.rs         | 3 ---
 wgpu/src/quad.rs          | 3 ---
 wgpu/src/triangle.rs      | 3 ---
 wgpu/src/triangle/msaa.rs | 3 ---
 4 files changed, 12 deletions(-)

(limited to 'wgpu')

diff --git a/wgpu/src/image.rs b/wgpu/src/image.rs
index cd756c1e..3a08662a 100644
--- a/wgpu/src/image.rs
+++ b/wgpu/src/image.rs
@@ -152,9 +152,6 @@ impl Pipeline {
                 rasterization_state: Some(wgpu::RasterizationStateDescriptor {
                     front_face: wgpu::FrontFace::Cw,
                     cull_mode: wgpu::CullMode::None,
-                    depth_bias: 0,
-                    depth_bias_slope_scale: 0.0,
-                    depth_bias_clamp: 0.0,
                     ..Default::default()
                 }),
                 primitive_topology: wgpu::PrimitiveTopology::TriangleList,
diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs
index f8d6c509..a115fa73 100644
--- a/wgpu/src/quad.rs
+++ b/wgpu/src/quad.rs
@@ -80,9 +80,6 @@ impl Pipeline {
                 rasterization_state: Some(wgpu::RasterizationStateDescriptor {
                     front_face: wgpu::FrontFace::Cw,
                     cull_mode: wgpu::CullMode::None,
-                    depth_bias: 0,
-                    depth_bias_slope_scale: 0.0,
-                    depth_bias_clamp: 0.0,
                     ..Default::default()
                 }),
                 primitive_topology: wgpu::PrimitiveTopology::TriangleList,
diff --git a/wgpu/src/triangle.rs b/wgpu/src/triangle.rs
index fcab5e3d..d06e29c0 100644
--- a/wgpu/src/triangle.rs
+++ b/wgpu/src/triangle.rs
@@ -142,9 +142,6 @@ impl Pipeline {
                 rasterization_state: Some(wgpu::RasterizationStateDescriptor {
                     front_face: wgpu::FrontFace::Cw,
                     cull_mode: wgpu::CullMode::None,
-                    depth_bias: 0,
-                    depth_bias_slope_scale: 0.0,
-                    depth_bias_clamp: 0.0,
                     ..Default::default()
                 }),
                 primitive_topology: wgpu::PrimitiveTopology::TriangleList,
diff --git a/wgpu/src/triangle/msaa.rs b/wgpu/src/triangle/msaa.rs
index f25667a5..14560281 100644
--- a/wgpu/src/triangle/msaa.rs
+++ b/wgpu/src/triangle/msaa.rs
@@ -92,9 +92,6 @@ impl Blit {
                 rasterization_state: Some(wgpu::RasterizationStateDescriptor {
                     front_face: wgpu::FrontFace::Cw,
                     cull_mode: wgpu::CullMode::None,
-                    depth_bias: 0,
-                    depth_bias_slope_scale: 0.0,
-                    depth_bias_clamp: 0.0,
                     ..Default::default()
                 }),
                 primitive_topology: wgpu::PrimitiveTopology::TriangleList,
-- 
cgit 


From 3eb63762c72ccd91717d4feb98128aa12cc1b126 Mon Sep 17 00:00:00 2001
From: Héctor Ramón Jiménez <hector0193@gmail.com>
Date: Thu, 27 Aug 2020 19:28:03 +0200
Subject: Remove unnecessary `create_buffer_init` for uniforms

---
 wgpu/src/image.rs | 16 ++++++----------
 wgpu/src/quad.rs  | 12 ++++++------
 2 files changed, 12 insertions(+), 16 deletions(-)

(limited to 'wgpu')

diff --git a/wgpu/src/image.rs b/wgpu/src/image.rs
index 3a08662a..814eefea 100644
--- a/wgpu/src/image.rs
+++ b/wgpu/src/image.rs
@@ -78,16 +78,12 @@ impl Pipeline {
                 ],
             });
 
-        let uniforms = Uniforms {
-            transform: Transformation::identity().into(),
-        };
-
-        let uniforms_buffer =
-            device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
-                label: None,
-                contents: uniforms.as_bytes(),
-                usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
-            });
+        let uniforms_buffer = device.create_buffer(&wgpu::BufferDescriptor {
+            label: None,
+            size: mem::size_of::<Uniforms>() as u64,
+            usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
+            mapped_at_creation: false,
+        });
 
         let constant_bind_group =
             device.create_bind_group(&wgpu::BindGroupDescriptor {
diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs
index a115fa73..0c54db15 100644
--- a/wgpu/src/quad.rs
+++ b/wgpu/src/quad.rs
@@ -34,12 +34,12 @@ impl Pipeline {
                 }],
             });
 
-        let constants_buffer =
-            device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
-                label: None,
-                contents: Uniforms::default().as_bytes(),
-                usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
-            });
+        let constants_buffer = device.create_buffer(&wgpu::BufferDescriptor {
+            label: None,
+            size: mem::size_of::<Uniforms>() as u64,
+            usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
+            mapped_at_creation: false,
+        });
 
         let constants = device.create_bind_group(&wgpu::BindGroupDescriptor {
             label: None,
-- 
cgit 


From 8d605be4e3e0b678c7563708ea941d6188f45678 Mon Sep 17 00:00:00 2001
From: Héctor Ramón Jiménez <hector0193@gmail.com>
Date: Thu, 27 Aug 2020 19:30:56 +0200
Subject: Use `wgpu::Color::TRANSPARENT`

---
 wgpu/src/triangle.rs | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

(limited to 'wgpu')

diff --git a/wgpu/src/triangle.rs b/wgpu/src/triangle.rs
index d06e29c0..a5789a61 100644
--- a/wgpu/src/triangle.rs
+++ b/wgpu/src/triangle.rs
@@ -341,12 +341,7 @@ impl Pipeline {
                     (
                         attachment,
                         Some(resolve_target),
-                        wgpu::LoadOp::Clear(wgpu::Color {
-                            r: 0.0,
-                            g: 0.0,
-                            b: 0.0,
-                            a: 0.0,
-                        }),
+                        wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT),
                     )
                 } else {
                     (target, None, wgpu::LoadOp::Load)
-- 
cgit 


From 7559e4fb30a282271717f700cb6e420cdf6123f0 Mon Sep 17 00:00:00 2001
From: Héctor Ramón Jiménez <hector0193@gmail.com>
Date: Thu, 27 Aug 2020 19:35:24 +0200
Subject: Set offsets in buffer slices in `iced_wgpu`

---
 wgpu/src/triangle.rs | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

(limited to 'wgpu')

diff --git a/wgpu/src/triangle.rs b/wgpu/src/triangle.rs
index a5789a61..6ae46cba 100644
--- a/wgpu/src/triangle.rs
+++ b/wgpu/src/triangle.rs
@@ -379,17 +379,20 @@ impl Pipeline {
                     &[(std::mem::size_of::<Uniforms>() * i) as u32],
                 );
 
-                render_pass.set_index_buffer(self.index_buffer.raw.slice(..));
-
-                render_pass
-                    .set_vertex_buffer(0, self.vertex_buffer.raw.slice(..));
+                render_pass.set_index_buffer(
+                    self.index_buffer
+                        .raw
+                        .slice(index_offset * mem::size_of::<u32>() as u64..),
+                );
 
-                render_pass.draw_indexed(
-                    index_offset as u32
-                        ..(index_offset as usize + indices) as u32,
-                    vertex_offset as i32,
-                    0..1,
+                render_pass.set_vertex_buffer(
+                    0,
+                    self.vertex_buffer.raw.slice(
+                        vertex_offset * mem::size_of::<Vertex2D>() as u64..,
+                    ),
                 );
+
+                render_pass.draw_indexed(0..indices as u32, 0, 0..1);
             }
         }
 
-- 
cgit 


From 07880c392c865d700cbaff7601c1fffd3354dd4f Mon Sep 17 00:00:00 2001
From: Héctor Ramón Jiménez <hector0193@gmail.com>
Date: Thu, 27 Aug 2020 19:40:42 +0200
Subject: Turn consecutive if-lets into pattern match

---
 wgpu/src/triangle.rs | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

(limited to 'wgpu')

diff --git a/wgpu/src/triangle.rs b/wgpu/src/triangle.rs
index 6ae46cba..ed6af0ff 100644
--- a/wgpu/src/triangle.rs
+++ b/wgpu/src/triangle.rs
@@ -272,12 +272,11 @@ impl Pipeline {
             let vertices = bytemuck::cast_slice(&mesh.buffers.vertices);
             let indices = bytemuck::cast_slice(&mesh.buffers.indices);
 
-            if let Some(vertices_size) =
-                wgpu::BufferSize::new(vertices.len() as u64)
-            {
-                if let Some(indices_size) =
-                    wgpu::BufferSize::new(indices.len() as u64)
-                {
+            match (
+                wgpu::BufferSize::new(vertices.len() as u64),
+                wgpu::BufferSize::new(indices.len() as u64),
+            ) {
+                (Some(vertices_size), Some(indices_size)) => {
                     {
                         let mut vertex_buffer = staging_belt.write_buffer(
                             encoder,
@@ -313,6 +312,7 @@ impl Pipeline {
                     last_vertex += mesh.buffers.vertices.len();
                     last_index += mesh.buffers.indices.len();
                 }
+                _ => {}
             }
         }
 
-- 
cgit 


From 44118263b5de7bc32f6280ee3d1dc170a9b034d3 Mon Sep 17 00:00:00 2001
From: Héctor Ramón Jiménez <hector0193@gmail.com>
Date: Mon, 31 Aug 2020 14:41:41 +0200
Subject: Add labels to `iced_wgpu` internals

---
 wgpu/src/image.rs             | 22 +++++++++++-----------
 wgpu/src/image/atlas.rs       |  6 +++---
 wgpu/src/quad.rs              | 16 ++++++++--------
 wgpu/src/triangle.rs          | 20 +++++++++++++-------
 wgpu/src/triangle/msaa.rs     | 16 ++++++++--------
 wgpu/src/window/compositor.rs |  4 +++-
 6 files changed, 46 insertions(+), 38 deletions(-)

(limited to 'wgpu')

diff --git a/wgpu/src/image.rs b/wgpu/src/image.rs
index 814eefea..891dba1e 100644
--- a/wgpu/src/image.rs
+++ b/wgpu/src/image.rs
@@ -56,7 +56,7 @@ impl Pipeline {
 
         let constant_layout =
             device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
-                label: None,
+                label: Some("iced_wgpu::image constants layout"),
                 entries: &[
                     wgpu::BindGroupLayoutEntry {
                         binding: 0,
@@ -79,7 +79,7 @@ impl Pipeline {
             });
 
         let uniforms_buffer = device.create_buffer(&wgpu::BufferDescriptor {
-            label: None,
+            label: Some("iced_wgpu::image uniforms buffer"),
             size: mem::size_of::<Uniforms>() as u64,
             usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
             mapped_at_creation: false,
@@ -87,7 +87,7 @@ impl Pipeline {
 
         let constant_bind_group =
             device.create_bind_group(&wgpu::BindGroupDescriptor {
-                label: None,
+                label: Some("iced_wgpu::image constants bind group"),
                 layout: &constant_layout,
                 entries: &[
                     wgpu::BindGroupEntry {
@@ -105,7 +105,7 @@ impl Pipeline {
 
         let texture_layout =
             device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
-                label: None,
+                label: Some("iced_wgpu::image texture atlas layout"),
                 entries: &[wgpu::BindGroupLayoutEntry {
                     binding: 0,
                     visibility: wgpu::ShaderStage::FRAGMENT,
@@ -120,7 +120,7 @@ impl Pipeline {
 
         let layout =
             device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
-                label: None,
+                label: Some("iced_wgpu::image pipeline layout"),
                 push_constant_ranges: &[],
                 bind_group_layouts: &[&constant_layout, &texture_layout],
             });
@@ -135,7 +135,7 @@ impl Pipeline {
 
         let pipeline =
             device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
-                label: None,
+                label: Some("iced_wgpu::image pipeline"),
                 layout: Some(&layout),
                 vertex_stage: wgpu::ProgrammableStageDescriptor {
                     module: &vs_module,
@@ -218,20 +218,20 @@ impl Pipeline {
 
         let vertices =
             device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
-                label: None,
+                label: Some("iced_wgpu::image vertex buffer"),
                 contents: QUAD_VERTS.as_bytes(),
                 usage: wgpu::BufferUsage::VERTEX,
             });
 
         let indices =
             device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
-                label: None,
+                label: Some("iced_wgpu::image index buffer"),
                 contents: QUAD_INDICES.as_bytes(),
                 usage: wgpu::BufferUsage::INDEX,
             });
 
         let instances = device.create_buffer(&wgpu::BufferDescriptor {
-            label: None,
+            label: Some("iced_wgpu::image instance buffer"),
             size: mem::size_of::<Instance>() as u64 * Instance::MAX as u64,
             usage: wgpu::BufferUsage::VERTEX | wgpu::BufferUsage::COPY_DST,
             mapped_at_creation: false,
@@ -240,7 +240,7 @@ impl Pipeline {
         let texture_atlas = Atlas::new(device);
 
         let texture = device.create_bind_group(&wgpu::BindGroupDescriptor {
-            label: None,
+            label: Some("iced_wgpu::image texture atlas bind group"),
             layout: &texture_layout,
             entries: &[wgpu::BindGroupEntry {
                 binding: 0,
@@ -362,7 +362,7 @@ impl Pipeline {
 
             self.texture =
                 device.create_bind_group(&wgpu::BindGroupDescriptor {
-                    label: None,
+                    label: Some("iced_wgpu::image texture atlas bind group"),
                     layout: &self.texture_layout,
                     entries: &[wgpu::BindGroupEntry {
                         binding: 0,
diff --git a/wgpu/src/image/atlas.rs b/wgpu/src/image/atlas.rs
index 69f872e8..660ebe44 100644
--- a/wgpu/src/image/atlas.rs
+++ b/wgpu/src/image/atlas.rs
@@ -28,7 +28,7 @@ impl Atlas {
         };
 
         let texture = device.create_texture(&wgpu::TextureDescriptor {
-            label: None,
+            label: Some("iced_wgpu::image texture atlas"),
             size: extent,
             mip_level_count: 1,
             sample_count: 1,
@@ -103,7 +103,7 @@ impl Atlas {
 
         let buffer =
             device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
-                label: None,
+                label: Some("iced_wgpu::image staging buffer"),
                 contents: &padded_data,
                 usage: wgpu::BufferUsage::COPY_SRC,
             });
@@ -330,7 +330,7 @@ impl Atlas {
         }
 
         let new_texture = device.create_texture(&wgpu::TextureDescriptor {
-            label: None,
+            label: Some("iced_wgpu::image texture atlas"),
             size: wgpu::Extent3d {
                 width: SIZE,
                 height: SIZE,
diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs
index 0c54db15..d54f2577 100644
--- a/wgpu/src/quad.rs
+++ b/wgpu/src/quad.rs
@@ -20,7 +20,7 @@ impl Pipeline {
     pub fn new(device: &wgpu::Device, format: wgpu::TextureFormat) -> Pipeline {
         let constant_layout =
             device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
-                label: None,
+                label: Some("iced_wgpu::quad uniforms layout"),
                 entries: &[wgpu::BindGroupLayoutEntry {
                     binding: 0,
                     visibility: wgpu::ShaderStage::VERTEX,
@@ -35,14 +35,14 @@ impl Pipeline {
             });
 
         let constants_buffer = device.create_buffer(&wgpu::BufferDescriptor {
-            label: None,
+            label: Some("iced_wgpu::quad uniforms buffer"),
             size: mem::size_of::<Uniforms>() as u64,
             usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
             mapped_at_creation: false,
         });
 
         let constants = device.create_bind_group(&wgpu::BindGroupDescriptor {
-            label: None,
+            label: Some("iced_wgpu::quad uniforms bind group"),
             layout: &constant_layout,
             entries: &[wgpu::BindGroupEntry {
                 binding: 0,
@@ -54,7 +54,7 @@ impl Pipeline {
 
         let layout =
             device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
-                label: None,
+                label: Some("iced_wgpu::quad pipeline layout"),
                 push_constant_ranges: &[],
                 bind_group_layouts: &[&constant_layout],
             });
@@ -67,7 +67,7 @@ impl Pipeline {
 
         let pipeline =
             device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
-                label: None,
+                label: Some("iced_wgpu::quad pipeline"),
                 layout: Some(&layout),
                 vertex_stage: wgpu::ProgrammableStageDescriptor {
                     module: &vs_module,
@@ -155,20 +155,20 @@ impl Pipeline {
 
         let vertices =
             device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
-                label: None,
+                label: Some("iced_wgpu::quad vertex buffer"),
                 contents: QUAD_VERTS.as_bytes(),
                 usage: wgpu::BufferUsage::VERTEX,
             });
 
         let indices =
             device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
-                label: None,
+                label: Some("iced_wgpu::quad index buffer"),
                 contents: QUAD_INDICES.as_bytes(),
                 usage: wgpu::BufferUsage::INDEX,
             });
 
         let instances = device.create_buffer(&wgpu::BufferDescriptor {
-            label: None,
+            label: Some("iced_wgpu::quad instance buffer"),
             size: mem::size_of::<layer::Quad>() as u64 * MAX_INSTANCES as u64,
             usage: wgpu::BufferUsage::VERTEX | wgpu::BufferUsage::COPY_DST,
             mapped_at_creation: false,
diff --git a/wgpu/src/triangle.rs b/wgpu/src/triangle.rs
index ed6af0ff..53ce454b 100644
--- a/wgpu/src/triangle.rs
+++ b/wgpu/src/triangle.rs
@@ -25,6 +25,7 @@ pub(crate) struct Pipeline {
 
 #[derive(Debug)]
 struct Buffer<T> {
+    label: &'static str,
     raw: wgpu::Buffer,
     size: usize,
     usage: wgpu::BufferUsage,
@@ -33,18 +34,20 @@ struct Buffer<T> {
 
 impl<T> Buffer<T> {
     pub fn new(
+        label: &'static str,
         device: &wgpu::Device,
         size: usize,
         usage: wgpu::BufferUsage,
     ) -> Self {
         let raw = device.create_buffer(&wgpu::BufferDescriptor {
-            label: None,
+            label: Some(label),
             size: (std::mem::size_of::<T>() * size) as u64,
             usage,
             mapped_at_creation: false,
         });
 
         Buffer {
+            label,
             raw,
             size,
             usage,
@@ -57,7 +60,7 @@ impl<T> Buffer<T> {
 
         if needs_resize {
             self.raw = device.create_buffer(&wgpu::BufferDescriptor {
-                label: None,
+                label: Some(self.label),
                 size: (std::mem::size_of::<T>() * size) as u64,
                 usage: self.usage,
                 mapped_at_creation: false,
@@ -78,7 +81,7 @@ impl Pipeline {
     ) -> Pipeline {
         let constants_layout =
             device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
-                label: None,
+                label: Some("iced_wgpu::triangle uniforms layout"),
                 entries: &[wgpu::BindGroupLayoutEntry {
                     binding: 0,
                     visibility: wgpu::ShaderStage::VERTEX,
@@ -93,6 +96,7 @@ impl Pipeline {
             });
 
         let constants_buffer = Buffer::new(
+            "iced_wgpu::triangle uniforms buffer",
             device,
             UNIFORM_BUFFER_SIZE,
             wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
@@ -100,7 +104,7 @@ impl Pipeline {
 
         let constant_bind_group =
             device.create_bind_group(&wgpu::BindGroupDescriptor {
-                label: None,
+                label: Some("iced_wgpu::triangle uniforms bind group"),
                 layout: &constants_layout,
                 entries: &[wgpu::BindGroupEntry {
                     binding: 0,
@@ -114,7 +118,7 @@ impl Pipeline {
 
         let layout =
             device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
-                label: None,
+                label: Some("iced_wgpu::triangle pipeline layout"),
                 push_constant_ranges: &[],
                 bind_group_layouts: &[&constants_layout],
             });
@@ -129,7 +133,7 @@ impl Pipeline {
 
         let pipeline =
             device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
-                label: None,
+                label: Some("iced_wgpu::triangle pipeline"),
                 layout: Some(&layout),
                 vertex_stage: wgpu::ProgrammableStageDescriptor {
                     module: &vs_module,
@@ -195,11 +199,13 @@ impl Pipeline {
             constants: constant_bind_group,
             uniforms_buffer: constants_buffer,
             vertex_buffer: Buffer::new(
+                "iced_wgpu::triangle vertex buffer",
                 device,
                 VERTEX_BUFFER_SIZE,
                 wgpu::BufferUsage::VERTEX | wgpu::BufferUsage::COPY_DST,
             ),
             index_buffer: Buffer::new(
+                "iced_wgpu::triangle index buffer",
                 device,
                 INDEX_BUFFER_SIZE,
                 wgpu::BufferUsage::INDEX | wgpu::BufferUsage::COPY_DST,
@@ -241,7 +247,7 @@ impl Pipeline {
         if self.uniforms_buffer.expand(device, meshes.len()) {
             self.constants =
                 device.create_bind_group(&wgpu::BindGroupDescriptor {
-                    label: None,
+                    label: Some("iced_wgpu::triangle uniforms buffer"),
                     layout: &self.constants_layout,
                     entries: &[wgpu::BindGroupEntry {
                         binding: 0,
diff --git a/wgpu/src/triangle/msaa.rs b/wgpu/src/triangle/msaa.rs
index 14560281..db86f748 100644
--- a/wgpu/src/triangle/msaa.rs
+++ b/wgpu/src/triangle/msaa.rs
@@ -28,7 +28,7 @@ impl Blit {
 
         let constant_layout =
             device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
-                label: None,
+                label: Some("iced_wgpu::triangle:msaa uniforms layout"),
                 entries: &[wgpu::BindGroupLayoutEntry {
                     binding: 0,
                     visibility: wgpu::ShaderStage::FRAGMENT,
@@ -39,7 +39,7 @@ impl Blit {
 
         let constant_bind_group =
             device.create_bind_group(&wgpu::BindGroupDescriptor {
-                label: None,
+                label: Some("iced_wgpu::triangle::msaa uniforms bind group"),
                 layout: &constant_layout,
                 entries: &[wgpu::BindGroupEntry {
                     binding: 0,
@@ -49,7 +49,7 @@ impl Blit {
 
         let texture_layout =
             device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
-                label: None,
+                label: Some("iced_wgpu::triangle::msaa texture layout"),
                 entries: &[wgpu::BindGroupLayoutEntry {
                     binding: 0,
                     visibility: wgpu::ShaderStage::FRAGMENT,
@@ -64,7 +64,7 @@ impl Blit {
 
         let layout =
             device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
-                label: None,
+                label: Some("iced_wgpu::triangle::msaa pipeline layout"),
                 push_constant_ranges: &[],
                 bind_group_layouts: &[&constant_layout, &texture_layout],
             });
@@ -79,7 +79,7 @@ impl Blit {
 
         let pipeline =
             device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
-                label: None,
+                label: Some("iced_wgpu::triangle::msaa pipeline"),
                 layout: Some(&layout),
                 vertex_stage: wgpu::ProgrammableStageDescriptor {
                     module: &vs_module,
@@ -221,7 +221,7 @@ impl Targets {
         };
 
         let attachment = device.create_texture(&wgpu::TextureDescriptor {
-            label: None,
+            label: Some("iced_wgpu::triangle::msaa attachment"),
             size: extent,
             mip_level_count: 1,
             sample_count,
@@ -231,7 +231,7 @@ impl Targets {
         });
 
         let resolve = device.create_texture(&wgpu::TextureDescriptor {
-            label: None,
+            label: Some("iced_wgpu::triangle::msaa resolve target"),
             size: extent,
             mip_level_count: 1,
             sample_count: 1,
@@ -248,7 +248,7 @@ impl Targets {
             resolve.create_view(&wgpu::TextureViewDescriptor::default());
 
         let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
-            label: None,
+            label: Some("iced_wgpu::triangle::msaa texture bind group"),
             layout: texture_layout,
             entries: &[wgpu::BindGroupEntry {
                 binding: 0,
diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs
index 0c94c281..c790f35f 100644
--- a/wgpu/src/window/compositor.rs
+++ b/wgpu/src/window/compositor.rs
@@ -131,7 +131,9 @@ impl iced_graphics::window::Compositor for Compositor {
         let frame = swap_chain.get_current_frame().expect("Next frame");
 
         let mut encoder = self.device.create_command_encoder(
-            &wgpu::CommandEncoderDescriptor { label: None },
+            &wgpu::CommandEncoderDescriptor {
+                label: Some("iced_wgpu encoder"),
+            },
         );
 
         let _ = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
-- 
cgit