summaryrefslogtreecommitdiffstats
path: root/wgpu
diff options
context:
space:
mode:
authorLibravatar Billy Messenger <BillyDM@tutamail.com>2021-07-22 12:37:39 -0500
committerLibravatar Billy Messenger <BillyDM@tutamail.com>2021-07-22 12:37:39 -0500
commite822f654e44d2d7375b7fda966bb772055f377d4 (patch)
tree8707561f1bb09c9e58cc9d9884bfb16d956f9f65 /wgpu
parent1c06920158e1a47977b2762bf8b34e56fd1a935a (diff)
parentdc0b96ce407283f2ffd9add5ad339f89097555d3 (diff)
downloadiced-e822f654e44d2d7375b7fda966bb772055f377d4.tar.gz
iced-e822f654e44d2d7375b7fda966bb772055f377d4.tar.bz2
iced-e822f654e44d2d7375b7fda966bb772055f377d4.zip
Merge branch 'master' of https://github.com/hecrj/iced into wgpu_outdatedframe
Diffstat (limited to 'wgpu')
-rw-r--r--wgpu/Cargo.toml35
-rw-r--r--wgpu/README.md2
-rw-r--r--wgpu/src/backend.rs23
-rw-r--r--wgpu/src/image.rs195
-rw-r--r--wgpu/src/image/atlas.rs24
-rw-r--r--wgpu/src/image/atlas/entry.rs2
-rw-r--r--wgpu/src/image/raster.rs8
-rw-r--r--wgpu/src/image/vector.rs42
-rw-r--r--wgpu/src/lib.rs2
-rw-r--r--wgpu/src/quad.rs178
-rw-r--r--wgpu/src/settings.rs52
-rw-r--r--wgpu/src/shader/blit.frag12
-rw-r--r--wgpu/src/shader/blit.frag.spvbin684 -> 0 bytes
-rw-r--r--wgpu/src/shader/blit.vert26
-rw-r--r--wgpu/src/shader/blit.vert.spvbin1384 -> 0 bytes
-rw-r--r--wgpu/src/shader/blit.wgsl43
-rw-r--r--wgpu/src/shader/image.frag12
-rw-r--r--wgpu/src/shader/image.frag.spvbin684 -> 0 bytes
-rw-r--r--wgpu/src/shader/image.vert27
-rw-r--r--wgpu/src/shader/image.vert.spvbin2504 -> 0 bytes
-rw-r--r--wgpu/src/shader/image.wgsl47
-rw-r--r--wgpu/src/shader/quad.frag66
-rw-r--r--wgpu/src/shader/quad.frag.spvbin4212 -> 0 bytes
-rw-r--r--wgpu/src/shader/quad.vert47
-rw-r--r--wgpu/src/shader/quad.vert.spvbin3604 -> 0 bytes
-rw-r--r--wgpu/src/shader/quad.wgsl122
-rw-r--r--wgpu/src/shader/triangle.frag8
-rw-r--r--wgpu/src/shader/triangle.frag.spvbin372 -> 0 bytes
-rw-r--r--wgpu/src/shader/triangle.vert15
-rw-r--r--wgpu/src/shader/triangle.vert.spvbin1256 -> 0 bytes
-rw-r--r--wgpu/src/shader/triangle.wgsl31
-rw-r--r--wgpu/src/text.rs4
-rw-r--r--wgpu/src/triangle.rs146
-rw-r--r--wgpu/src/triangle/msaa.rs119
-rw-r--r--wgpu/src/widget.rs6
-rw-r--r--wgpu/src/widget/pane_grid.rs8
-rw-r--r--wgpu/src/widget/toggler.rs9
-rw-r--r--wgpu/src/widget/tooltip.rs6
-rw-r--r--wgpu/src/window/compositor.rs94
39 files changed, 772 insertions, 639 deletions
diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml
index 5f4699a8..9675797d 100644
--- a/wgpu/Cargo.toml
+++ b/wgpu/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "iced_wgpu"
-version = "0.3.0"
+version = "0.4.0"
authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]
edition = "2018"
description = "A wgpu renderer for Iced"
@@ -8,14 +8,26 @@ license = "MIT AND OFL-1.1"
repository = "https://github.com/hecrj/iced"
[features]
-svg = ["resvg"]
+svg = ["resvg", "usvg"]
+image = ["png", "jpeg", "jpeg_rayon", "gif", "webp", "bmp"]
+png = ["image_rs/png"]
+jpeg = ["image_rs/jpeg"]
+jpeg_rayon = ["image_rs/jpeg_rayon"]
+gif = ["image_rs/gif"]
+webp = ["image_rs/webp"]
+pnm = ["image_rs/pnm"]
+ico = ["image_rs/ico"]
+bmp = ["image_rs/bmp"]
+hdr = ["image_rs/hdr"]
+dds = ["image_rs/dds"]
+farbfeld = ["image_rs/farbfeld"]
canvas = ["iced_graphics/canvas"]
qr_code = ["iced_graphics/qr_code"]
default_system_font = ["iced_graphics/font-source"]
[dependencies]
-wgpu = "0.6"
-wgpu_glyph = "0.10"
+wgpu = "0.9"
+wgpu_glyph = "0.13"
glyph_brush = "0.7"
raw-window-handle = "0.3"
log = "0.4"
@@ -27,21 +39,26 @@ version = "1.4"
features = ["derive"]
[dependencies.iced_native]
-version = "0.3"
+version = "0.4"
path = "../native"
[dependencies.iced_graphics]
-version = "0.1"
+version = "0.2"
path = "../graphics"
features = ["font-fallback", "font-icons"]
-[dependencies.image]
+[dependencies.image_rs]
version = "0.23"
+package = "image"
+default-features = false
optional = true
[dependencies.resvg]
-version = "0.9"
-features = ["raqote-backend"]
+version = "0.12"
+optional = true
+
+[dependencies.usvg]
+version = "0.12"
optional = true
[package.metadata.docs.rs]
diff --git a/wgpu/README.md b/wgpu/README.md
index e8cb0a43..a9d95ea7 100644
--- a/wgpu/README.md
+++ b/wgpu/README.md
@@ -29,7 +29,7 @@ Currently, `iced_wgpu` supports the following primitives:
Add `iced_wgpu` as a dependency in your `Cargo.toml`:
```toml
-iced_wgpu = "0.3"
+iced_wgpu = "0.4"
```
__Iced moves fast and the `master` branch can contain breaking changes!__ If
diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs
index fccb5ac7..783079f3 100644
--- a/wgpu/src/backend.rs
+++ b/wgpu/src/backend.rs
@@ -9,7 +9,7 @@ use iced_graphics::{Primitive, Viewport};
use iced_native::mouse;
use iced_native::{Font, HorizontalAlignment, Size, VerticalAlignment};
-#[cfg(any(feature = "image", feature = "svg"))]
+#[cfg(any(feature = "image_rs", feature = "svg"))]
use crate::image;
/// A [`wgpu`] graphics backend for [`iced`].
@@ -22,7 +22,7 @@ pub struct Backend {
text_pipeline: text::Pipeline,
triangle_pipeline: triangle::Pipeline,
- #[cfg(any(feature = "image", feature = "svg"))]
+ #[cfg(any(feature = "image_rs", feature = "svg"))]
image_pipeline: image::Pipeline,
default_text_size: u16,
@@ -31,8 +31,13 @@ pub struct Backend {
impl Backend {
/// Creates a new [`Backend`].
pub fn new(device: &wgpu::Device, settings: Settings) -> Self {
- let text_pipeline =
- text::Pipeline::new(device, settings.format, settings.default_font);
+ let text_pipeline = text::Pipeline::new(
+ device,
+ settings.format,
+ settings.default_font,
+ settings.text_multithreading,
+ );
+
let quad_pipeline = quad::Pipeline::new(device, settings.format);
let triangle_pipeline = triangle::Pipeline::new(
device,
@@ -40,7 +45,7 @@ impl Backend {
settings.antialiasing,
);
- #[cfg(any(feature = "image", feature = "svg"))]
+ #[cfg(any(feature = "image_rs", feature = "svg"))]
let image_pipeline = image::Pipeline::new(device, settings.format);
Self {
@@ -48,7 +53,7 @@ impl Backend {
text_pipeline,
triangle_pipeline,
- #[cfg(any(feature = "image", feature = "svg"))]
+ #[cfg(any(feature = "image_rs", feature = "svg"))]
image_pipeline,
default_text_size: settings.default_text_size,
@@ -92,7 +97,7 @@ impl Backend {
);
}
- #[cfg(any(feature = "image", feature = "svg"))]
+ #[cfg(any(feature = "image_rs", feature = "svg"))]
self.image_pipeline.trim_cache();
*mouse_interaction
@@ -142,7 +147,7 @@ impl Backend {
);
}
- #[cfg(any(feature = "image", feature = "svg"))]
+ #[cfg(any(feature = "image_rs", feature = "svg"))]
{
if !layer.images.is_empty() {
let scaled = transformation
@@ -270,7 +275,7 @@ impl backend::Text for Backend {
}
}
-#[cfg(feature = "image")]
+#[cfg(feature = "image_rs")]
impl backend::Image for Backend {
fn dimensions(&self, handle: &iced_native::image::Handle) -> (u32, u32) {
self.image_pipeline.dimensions(handle)
diff --git a/wgpu/src/image.rs b/wgpu/src/image.rs
index c256ca7e..85663bf5 100644
--- a/wgpu/src/image.rs
+++ b/wgpu/src/image.rs
@@ -1,6 +1,6 @@
mod atlas;
-#[cfg(feature = "image")]
+#[cfg(feature = "image_rs")]
mod raster;
#[cfg(feature = "svg")]
@@ -16,7 +16,7 @@ use std::mem;
use bytemuck::{Pod, Zeroable};
-#[cfg(feature = "image")]
+#[cfg(feature = "image_rs")]
use iced_native::image;
#[cfg(feature = "svg")]
@@ -24,7 +24,7 @@ use iced_native::svg;
#[derive(Debug)]
pub struct Pipeline {
- #[cfg(feature = "image")]
+ #[cfg(feature = "image_rs")]
raster_cache: RefCell<raster::Cache>,
#[cfg(feature = "svg")]
vector_cache: RefCell<vector::Cache>,
@@ -62,8 +62,9 @@ impl Pipeline {
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX,
- ty: wgpu::BindingType::UniformBuffer {
- dynamic: false,
+ ty: wgpu::BindingType::Buffer {
+ ty: wgpu::BufferBindingType::Uniform,
+ has_dynamic_offset: false,
min_binding_size: wgpu::BufferSize::new(
mem::size_of::<Uniforms>() as u64,
),
@@ -73,7 +74,10 @@ impl Pipeline {
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStage::FRAGMENT,
- ty: wgpu::BindingType::Sampler { comparison: false },
+ ty: wgpu::BindingType::Sampler {
+ comparison: false,
+ filtering: true,
+ },
count: None,
},
],
@@ -94,7 +98,11 @@ impl Pipeline {
wgpu::BindGroupEntry {
binding: 0,
resource: wgpu::BindingResource::Buffer(
- uniforms_buffer.slice(..),
+ wgpu::BufferBinding {
+ buffer: &uniforms_buffer,
+ offset: 0,
+ size: None,
+ },
),
},
wgpu::BindGroupEntry {
@@ -110,9 +118,11 @@ impl Pipeline {
entries: &[wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::FRAGMENT,
- ty: wgpu::BindingType::SampledTexture {
- dimension: wgpu::TextureViewDimension::D2,
- component_type: wgpu::TextureComponentType::Float,
+ ty: wgpu::BindingType::Texture {
+ sample_type: wgpu::TextureSampleType::Float {
+ filterable: true,
+ },
+ view_dimension: wgpu::TextureViewDimension::D2Array,
multisampled: false,
},
count: None,
@@ -126,95 +136,76 @@ impl Pipeline {
bind_group_layouts: &[&constant_layout, &texture_layout],
});
- let vs_module = device.create_shader_module(wgpu::include_spirv!(
- "shader/image.vert.spv"
- ));
-
- let fs_module = device.create_shader_module(wgpu::include_spirv!(
- "shader/image.frag.spv"
- ));
+ let shader =
+ device.create_shader_module(&wgpu::ShaderModuleDescriptor {
+ label: Some("iced_wgpu::image::shader"),
+ source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed(
+ include_str!("shader/image.wgsl"),
+ )),
+ flags: wgpu::ShaderFlags::all(),
+ });
let pipeline =
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("iced_wgpu::image pipeline"),
layout: Some(&layout),
- vertex_stage: wgpu::ProgrammableStageDescriptor {
- module: &vs_module,
- entry_point: "main",
- },
- fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
- module: &fs_module,
- entry_point: "main",
- }),
- rasterization_state: Some(wgpu::RasterizationStateDescriptor {
- front_face: wgpu::FrontFace::Cw,
- cull_mode: wgpu::CullMode::None,
- ..Default::default()
- }),
- primitive_topology: wgpu::PrimitiveTopology::TriangleList,
- color_states: &[wgpu::ColorStateDescriptor {
- format,
- color_blend: wgpu::BlendDescriptor {
- src_factor: wgpu::BlendFactor::SrcAlpha,
- dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
- operation: wgpu::BlendOperation::Add,
- },
- alpha_blend: wgpu::BlendDescriptor {
- src_factor: wgpu::BlendFactor::One,
- dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
- operation: wgpu::BlendOperation::Add,
- },
- write_mask: wgpu::ColorWrite::ALL,
- }],
- depth_stencil_state: None,
- vertex_state: wgpu::VertexStateDescriptor {
- index_format: wgpu::IndexFormat::Uint16,
- vertex_buffers: &[
- wgpu::VertexBufferDescriptor {
- stride: mem::size_of::<Vertex>() as u64,
+ vertex: wgpu::VertexState {
+ module: &shader,
+ entry_point: "vs_main",
+ buffers: &[
+ wgpu::VertexBufferLayout {
+ array_stride: mem::size_of::<Vertex>() as u64,
step_mode: wgpu::InputStepMode::Vertex,
- attributes: &[wgpu::VertexAttributeDescriptor {
+ attributes: &[wgpu::VertexAttribute {
shader_location: 0,
- format: wgpu::VertexFormat::Float2,
+ format: wgpu::VertexFormat::Float32x2,
offset: 0,
}],
},
- wgpu::VertexBufferDescriptor {
- stride: mem::size_of::<Instance>() as u64,
+ wgpu::VertexBufferLayout {
+ array_stride: mem::size_of::<Instance>() as u64,
step_mode: wgpu::InputStepMode::Instance,
- attributes: &[
- wgpu::VertexAttributeDescriptor {
- shader_location: 1,
- format: wgpu::VertexFormat::Float2,
- offset: 0,
- },
- wgpu::VertexAttributeDescriptor {
- shader_location: 2,
- format: wgpu::VertexFormat::Float2,
- offset: 4 * 2,
- },
- wgpu::VertexAttributeDescriptor {
- shader_location: 3,
- format: wgpu::VertexFormat::Float2,
- offset: 4 * 4,
- },
- wgpu::VertexAttributeDescriptor {
- shader_location: 4,
- format: wgpu::VertexFormat::Float2,
- offset: 4 * 6,
- },
- wgpu::VertexAttributeDescriptor {
- shader_location: 5,
- format: wgpu::VertexFormat::Uint,
- offset: 4 * 8,
- },
- ],
+ attributes: &wgpu::vertex_attr_array!(
+ 1 => Float32x2,
+ 2 => Float32x2,
+ 3 => Float32x2,
+ 4 => Float32x2,
+ 5 => Sint32,
+ ),
},
],
},
- sample_count: 1,
- sample_mask: !0,
- alpha_to_coverage_enabled: false,
+ fragment: Some(wgpu::FragmentState {
+ module: &shader,
+ entry_point: "fs_main",
+ targets: &[wgpu::ColorTargetState {
+ format,
+ blend: Some(wgpu::BlendState {
+ color: wgpu::BlendComponent {
+ src_factor: wgpu::BlendFactor::SrcAlpha,
+ dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
+ operation: wgpu::BlendOperation::Add,
+ },
+ alpha: wgpu::BlendComponent {
+ src_factor: wgpu::BlendFactor::One,
+ dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
+ operation: wgpu::BlendOperation::Add,
+ },
+ }),
+ write_mask: wgpu::ColorWrite::ALL,
+ }],
+ }),
+ primitive: wgpu::PrimitiveState {
+ topology: wgpu::PrimitiveTopology::TriangleList,
+ front_face: wgpu::FrontFace::Cw,
+ ..Default::default()
+ },
+ depth_stencil: None,
+ multisample: wgpu::MultisampleState {
+ count: 1,
+ mask: !0,
+ alpha_to_coverage_enabled: false,
+ },
});
let vertices =
@@ -252,7 +243,7 @@ impl Pipeline {
});
Pipeline {
- #[cfg(feature = "image")]
+ #[cfg(feature = "image_rs")]
raster_cache: RefCell::new(raster::Cache::new()),
#[cfg(feature = "svg")]
@@ -271,7 +262,7 @@ impl Pipeline {
}
}
- #[cfg(feature = "image")]
+ #[cfg(feature = "image_rs")]
pub fn dimensions(&self, handle: &image::Handle) -> (u32, u32) {
let mut cache = self.raster_cache.borrow_mut();
let memory = cache.load(&handle);
@@ -300,7 +291,7 @@ impl Pipeline {
) {
let instances: &mut Vec<Instance> = &mut Vec::new();
- #[cfg(feature = "image")]
+ #[cfg(feature = "image_rs")]
let mut raster_cache = self.raster_cache.borrow_mut();
#[cfg(feature = "svg")]
@@ -308,7 +299,7 @@ impl Pipeline {
for image in images {
match &image {
- #[cfg(feature = "image")]
+ #[cfg(feature = "image_rs")]
layer::Image::Raster { handle, bounds } => {
if let Some(atlas_entry) = raster_cache.upload(
handle,
@@ -324,7 +315,7 @@ impl Pipeline {
);
}
}
- #[cfg(not(feature = "image"))]
+ #[cfg(not(feature = "image_rs"))]
layer::Image::Raster { .. } => {}
#[cfg(feature = "svg")]
@@ -415,23 +406,25 @@ impl Pipeline {
let mut render_pass =
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
- color_attachments: &[
- wgpu::RenderPassColorAttachmentDescriptor {
- attachment: target,
- resolve_target: None,
- ops: wgpu::Operations {
- load: wgpu::LoadOp::Load,
- store: true,
- },
+ label: Some("iced_wgpu::image render pass"),
+ color_attachments: &[wgpu::RenderPassColorAttachment {
+ view: target,
+ resolve_target: None,
+ ops: wgpu::Operations {
+ load: wgpu::LoadOp::Load,
+ store: true,
},
- ],
+ }],
depth_stencil_attachment: None,
});
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.slice(..));
+ render_pass.set_index_buffer(
+ self.indices.slice(..),
+ wgpu::IndexFormat::Uint16,
+ );
render_pass.set_vertex_buffer(0, self.vertices.slice(..));
render_pass.set_vertex_buffer(1, self.instances.slice(..));
@@ -453,7 +446,7 @@ impl Pipeline {
}
pub fn trim_cache(&mut self) {
- #[cfg(feature = "image")]
+ #[cfg(feature = "image_rs")]
self.raster_cache.borrow_mut().trim(&mut self.texture_atlas);
#[cfg(feature = "svg")]
diff --git a/wgpu/src/image/atlas.rs b/wgpu/src/image/atlas.rs
index 660ebe44..4855fa4a 100644
--- a/wgpu/src/image/atlas.rs
+++ b/wgpu/src/image/atlas.rs
@@ -4,6 +4,8 @@ mod allocation;
mod allocator;
mod layer;
+use std::num::NonZeroU32;
+
pub use allocation::Allocation;
pub use entry::Entry;
pub use layer::Layer;
@@ -24,7 +26,7 @@ impl Atlas {
let extent = wgpu::Extent3d {
width: SIZE,
height: SIZE,
- depth: 1,
+ depth_or_array_layers: 1,
};
let texture = device.create_texture(&wgpu::TextureDescriptor {
@@ -294,19 +296,19 @@ impl Atlas {
let extent = wgpu::Extent3d {
width,
height,
- depth: 1,
+ depth_or_array_layers: 1,
};
encoder.copy_buffer_to_texture(
- wgpu::BufferCopyView {
+ wgpu::ImageCopyBuffer {
buffer,
- layout: wgpu::TextureDataLayout {
+ layout: wgpu::ImageDataLayout {
offset: offset as u64,
- bytes_per_row: 4 * image_width + padding,
- rows_per_image: image_height,
+ bytes_per_row: NonZeroU32::new(4 * image_width + padding),
+ rows_per_image: NonZeroU32::new(image_height),
},
},
- wgpu::TextureCopyView {
+ wgpu::ImageCopyTexture {
texture: &self.texture,
mip_level: 0,
origin: wgpu::Origin3d {
@@ -334,7 +336,7 @@ impl Atlas {
size: wgpu::Extent3d {
width: SIZE,
height: SIZE,
- depth: self.layers.len() as u32,
+ depth_or_array_layers: self.layers.len() as u32,
},
mip_level_count: 1,
sample_count: 1,
@@ -355,7 +357,7 @@ impl Atlas {
}
encoder.copy_texture_to_texture(
- wgpu::TextureCopyView {
+ wgpu::ImageCopyTexture {
texture: &self.texture,
mip_level: 0,
origin: wgpu::Origin3d {
@@ -364,7 +366,7 @@ impl Atlas {
z: i as u32,
},
},
- wgpu::TextureCopyView {
+ wgpu::ImageCopyTexture {
texture: &new_texture,
mip_level: 0,
origin: wgpu::Origin3d {
@@ -376,7 +378,7 @@ impl Atlas {
wgpu::Extent3d {
width: SIZE,
height: SIZE,
- depth: 1,
+ depth_or_array_layers: 1,
},
);
}
diff --git a/wgpu/src/image/atlas/entry.rs b/wgpu/src/image/atlas/entry.rs
index 0310fc54..9b3f16df 100644
--- a/wgpu/src/image/atlas/entry.rs
+++ b/wgpu/src/image/atlas/entry.rs
@@ -10,7 +10,7 @@ pub enum Entry {
}
impl Entry {
- #[cfg(feature = "image")]
+ #[cfg(feature = "image_rs")]
pub fn size(&self) -> (u32, u32) {
match self {
Entry::Contiguous(allocation) => allocation.size(),
diff --git a/wgpu/src/image/raster.rs b/wgpu/src/image/raster.rs
index 25607dab..d5c62545 100644
--- a/wgpu/src/image/raster.rs
+++ b/wgpu/src/image/raster.rs
@@ -4,7 +4,7 @@ use std::collections::{HashMap, HashSet};
#[derive(Debug)]
pub enum Memory {
- Host(::image::ImageBuffer<::image::Bgra<u8>, Vec<u8>>),
+ Host(::image_rs::ImageBuffer<::image_rs::Bgra<u8>, Vec<u8>>),
Device(atlas::Entry),
NotFound,
Invalid,
@@ -42,14 +42,14 @@ impl Cache {
let memory = match handle.data() {
image::Data::Path(path) => {
- if let Ok(image) = ::image::open(path) {
+ if let Ok(image) = ::image_rs::open(path) {
Memory::Host(image.to_bgra8())
} else {
Memory::NotFound
}
}
image::Data::Bytes(bytes) => {
- if let Ok(image) = ::image::load_from_memory(&bytes) {
+ if let Ok(image) = ::image_rs::load_from_memory(&bytes) {
Memory::Host(image.to_bgra8())
} else {
Memory::Invalid
@@ -60,7 +60,7 @@ impl Cache {
height,
pixels,
} => {
- if let Some(image) = ::image::ImageBuffer::from_vec(
+ if let Some(image) = ::image_rs::ImageBuffer::from_vec(
*width,
*height,
pixels.to_vec(),
diff --git a/wgpu/src/image/vector.rs b/wgpu/src/image/vector.rs
index 95df2e99..cd511a45 100644
--- a/wgpu/src/image/vector.rs
+++ b/wgpu/src/image/vector.rs
@@ -1,9 +1,10 @@
-use crate::image::atlas::{self, Atlas};
use iced_native::svg;
use std::collections::{HashMap, HashSet};
+use crate::image::atlas::{self, Atlas};
+
pub enum Svg {
- Loaded(resvg::usvg::Tree),
+ Loaded(usvg::Tree),
NotFound,
}
@@ -43,17 +44,15 @@ impl Cache {
return self.svgs.get(&handle.id()).unwrap();
}
- let opt = resvg::Options::default();
-
let svg = match handle.data() {
svg::Data::Path(path) => {
- match resvg::usvg::Tree::from_file(path, &opt.usvg) {
+ match usvg::Tree::from_file(path, &Default::default()) {
Ok(tree) => Svg::Loaded(tree),
Err(_) => Svg::NotFound,
}
}
svg::Data::Bytes(bytes) => {
- match resvg::usvg::Tree::from_data(&bytes, &opt.usvg) {
+ match usvg::Tree::from_data(&bytes, &Default::default()) {
Ok(tree) => Svg::Loaded(tree),
Err(_) => Svg::NotFound,
}
@@ -76,8 +75,8 @@ impl Cache {
let id = handle.id();
let (width, height) = (
- (scale * width).round() as u32,
- (scale * height).round() as u32,
+ (scale * width).ceil() as u32,
+ (scale * height).ceil() as u32,
);
// TODO: Optimize!
@@ -101,26 +100,29 @@ impl Cache {
// We currently rerasterize the SVG when its size changes. This is slow
// as heck. A GPU rasterizer like `pathfinder` may perform better.
// It would be cool to be able to smooth resize the `svg` example.
- let screen_size =
- resvg::ScreenSize::new(width, height).unwrap();
-
- let mut canvas =
- resvg::raqote::DrawTarget::new(width as i32, height as i32);
-
- resvg::backend_raqote::render_to_canvas(
+ let img = resvg::render(
tree,
- &resvg::Options::default(),
- screen_size,
- &mut canvas,
- );
+ if width > height {
+ usvg::FitTo::Width(width)
+ } else {
+ usvg::FitTo::Height(height)
+ },
+ None,
+ )?;
+ let width = img.width();
+ let height = img.height();
+
+ let mut rgba = img.take();
+ rgba.chunks_exact_mut(4).for_each(|rgba| rgba.swap(0, 2));
let allocation = texture_atlas.upload(
width,
height,
- bytemuck::cast_slice(canvas.get_data()),
+ bytemuck::cast_slice(rgba.as_slice()),
device,
encoder,
)?;
+ log::debug!("allocating {} {}x{}", id, width, height);
let _ = self.svg_hits.insert(id);
let _ = self.rasterized_hits.insert((id, width, height));
diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs
index a4c2ac0e..e868a655 100644
--- a/wgpu/src/lib.rs
+++ b/wgpu/src/lib.rs
@@ -49,7 +49,7 @@ pub use widget::*;
pub(crate) use iced_graphics::Transformation;
-#[cfg(any(feature = "image", feature = "svg"))]
+#[cfg(any(feature = "image_rs", feature = "svg"))]
mod image;
/// A [`wgpu`] graphics renderer for [`iced`].
diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs
index 24d20cfa..93942fba 100644
--- a/wgpu/src/quad.rs
+++ b/wgpu/src/quad.rs
@@ -24,10 +24,11 @@ impl Pipeline {
entries: &[wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX,
- ty: wgpu::BindingType::UniformBuffer {
- dynamic: false,
+ ty: wgpu::BindingType::Buffer {
+ ty: wgpu::BufferBindingType::Uniform,
+ has_dynamic_offset: false,
min_binding_size: wgpu::BufferSize::new(
- mem::size_of::<Uniforms>() as u64,
+ mem::size_of::<Uniforms>() as wgpu::BufferAddress,
),
},
count: None,
@@ -36,7 +37,7 @@ impl Pipeline {
let constants_buffer = device.create_buffer(&wgpu::BufferDescriptor {
label: Some("iced_wgpu::quad uniforms buffer"),
- size: mem::size_of::<Uniforms>() as u64,
+ size: mem::size_of::<Uniforms>() as wgpu::BufferAddress,
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
mapped_at_creation: false,
});
@@ -46,9 +47,7 @@ impl Pipeline {
layout: &constant_layout,
entries: &[wgpu::BindGroupEntry {
binding: 0,
- resource: wgpu::BindingResource::Buffer(
- constants_buffer.slice(..),
- ),
+ resource: constants_buffer.as_entire_binding(),
}],
});
@@ -59,98 +58,77 @@ impl Pipeline {
bind_group_layouts: &[&constant_layout],
});
- let vs_module = device
- .create_shader_module(wgpu::include_spirv!("shader/quad.vert.spv"));
-
- let fs_module = device
- .create_shader_module(wgpu::include_spirv!("shader/quad.frag.spv"));
+ let shader =
+ device.create_shader_module(&wgpu::ShaderModuleDescriptor {
+ label: Some("iced_wgpu::quad::shader"),
+ source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed(
+ include_str!("shader/quad.wgsl"),
+ )),
+ flags: wgpu::ShaderFlags::all(),
+ });
let pipeline =
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("iced_wgpu::quad pipeline"),
layout: Some(&layout),
- vertex_stage: wgpu::ProgrammableStageDescriptor {
- module: &vs_module,
- entry_point: "main",
- },
- fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
- module: &fs_module,
- entry_point: "main",
- }),
- rasterization_state: Some(wgpu::RasterizationStateDescriptor {
- front_face: wgpu::FrontFace::Cw,
- cull_mode: wgpu::CullMode::None,
- ..Default::default()
- }),
- primitive_topology: wgpu::PrimitiveTopology::TriangleList,
- color_states: &[wgpu::ColorStateDescriptor {
- format,
- color_blend: wgpu::BlendDescriptor {
- src_factor: wgpu::BlendFactor::SrcAlpha,
- dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
- operation: wgpu::BlendOperation::Add,
- },
- alpha_blend: wgpu::BlendDescriptor {
- src_factor: wgpu::BlendFactor::One,
- dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
- operation: wgpu::BlendOperation::Add,
- },
- write_mask: wgpu::ColorWrite::ALL,
- }],
- depth_stencil_state: None,
- vertex_state: wgpu::VertexStateDescriptor {
- index_format: wgpu::IndexFormat::Uint16,
- vertex_buffers: &[
- wgpu::VertexBufferDescriptor {
- stride: mem::size_of::<Vertex>() as u64,
+ vertex: wgpu::VertexState {
+ module: &shader,
+ entry_point: "vs_main",
+ buffers: &[
+ wgpu::VertexBufferLayout {
+ array_stride: mem::size_of::<Vertex>() as u64,
step_mode: wgpu::InputStepMode::Vertex,
- attributes: &[wgpu::VertexAttributeDescriptor {
+ attributes: &[wgpu::VertexAttribute {
shader_location: 0,
- format: wgpu::VertexFormat::Float2,
+ format: wgpu::VertexFormat::Float32x2,
offset: 0,
}],
},
- wgpu::VertexBufferDescriptor {
- stride: mem::size_of::<layer::Quad>() as u64,
+ wgpu::VertexBufferLayout {
+ array_stride: mem::size_of::<layer::Quad>() as u64,
step_mode: wgpu::InputStepMode::Instance,
- attributes: &[
- wgpu::VertexAttributeDescriptor {
- shader_location: 1,
- format: wgpu::VertexFormat::Float2,
- offset: 0,
- },
- wgpu::VertexAttributeDescriptor {
- shader_location: 2,
- format: wgpu::VertexFormat::Float2,
- offset: 4 * 2,
- },
- wgpu::VertexAttributeDescriptor {
- shader_location: 3,
- format: wgpu::VertexFormat::Float4,
- offset: 4 * (2 + 2),
- },
- wgpu::VertexAttributeDescriptor {
- shader_location: 4,
- format: wgpu::VertexFormat::Float4,
- offset: 4 * (2 + 2 + 4),
- },
- wgpu::VertexAttributeDescriptor {
- shader_location: 5,
- format: wgpu::VertexFormat::Float,
- offset: 4 * (2 + 2 + 4 + 4),
- },
- wgpu::VertexAttributeDescriptor {
- shader_location: 6,
- format: wgpu::VertexFormat::Float,
- offset: 4 * (2 + 2 + 4 + 4 + 1),
- },
- ],
+ attributes: &wgpu::vertex_attr_array!(
+ 1 => Float32x2,
+ 2 => Float32x2,
+ 3 => Float32x4,
+ 4 => Float32x4,
+ 5 => Float32,
+ 6 => Float32,
+ ),
},
],
},
- sample_count: 1,
- sample_mask: !0,
- alpha_to_coverage_enabled: false,
+ fragment: Some(wgpu::FragmentState {
+ module: &shader,
+ entry_point: "fs_main",
+ targets: &[wgpu::ColorTargetState {
+ format,
+ blend: Some(wgpu::BlendState {
+ color: wgpu::BlendComponent {
+ src_factor: wgpu::BlendFactor::SrcAlpha,
+ dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
+ operation: wgpu::BlendOperation::Add,
+ },
+ alpha: wgpu::BlendComponent {
+ src_factor: wgpu::BlendFactor::One,
+ dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
+ operation: wgpu::BlendOperation::Add,
+ },
+ }),
+ write_mask: wgpu::ColorWrite::ALL,
+ }],
+ }),
+ primitive: wgpu::PrimitiveState {
+ topology: wgpu::PrimitiveTopology::TriangleList,
+ front_face: wgpu::FrontFace::Cw,
+ ..Default::default()
+ },
+ depth_stencil: None,
+ multisample: wgpu::MultisampleState {
+ count: 1,
+ mask: !0,
+ alpha_to_coverage_enabled: false,
+ },
});
let vertices =
@@ -232,30 +210,33 @@ impl Pipeline {
{
let mut render_pass =
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
- color_attachments: &[
- wgpu::RenderPassColorAttachmentDescriptor {
- attachment: target,
- resolve_target: None,
- ops: wgpu::Operations {
- load: wgpu::LoadOp::Load,
- store: true,
- },
+ label: Some("iced_wgpu::quad render pass"),
+ color_attachments: &[wgpu::RenderPassColorAttachment {
+ view: target,
+ resolve_target: None,
+ ops: wgpu::Operations {
+ load: wgpu::LoadOp::Load,
+ store: true,
},
- ],
+ }],
depth_stencil_attachment: None,
});
render_pass.set_pipeline(&self.pipeline);
render_pass.set_bind_group(0, &self.constants, &[]);
- render_pass.set_index_buffer(self.indices.slice(..));
+ render_pass.set_index_buffer(
+ self.indices.slice(..),
+ wgpu::IndexFormat::Uint16,
+ );
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,
bounds.width,
// TODO: Address anti-aliasing adjustments properly
- bounds.height + 1,
+ bounds.height,
);
render_pass.draw_indexed(
@@ -300,6 +281,9 @@ const MAX_INSTANCES: usize = 100_000;
struct Uniforms {
transform: [f32; 16],
scale: f32,
+ // Uniforms must be aligned to their largest member,
+ // this uses a mat4x4<f32> which aligns to 16, so align to that
+ _padding: [f32; 3],
}
impl Uniforms {
@@ -307,6 +291,7 @@ impl Uniforms {
Self {
transform: *transformation.as_ref(),
scale,
+ _padding: [0.0; 3],
}
}
}
@@ -316,6 +301,7 @@ impl Default for Uniforms {
Self {
transform: *Transformation::identity().as_ref(),
scale: 1.0,
+ _padding: [0.0; 3],
}
}
}
diff --git a/wgpu/src/settings.rs b/wgpu/src/settings.rs
index 26763e22..9a7eed34 100644
--- a/wgpu/src/settings.rs
+++ b/wgpu/src/settings.rs
@@ -16,6 +16,9 @@ pub struct Settings {
/// [`Backend`]: crate::Backend
pub present_mode: wgpu::PresentMode,
+ /// The internal graphics backend to use.
+ pub internal_backend: wgpu::BackendBit,
+
/// The bytes of the font that will be used by default.
///
/// If `None` is provided, a default system font will be chosen.
@@ -26,18 +29,67 @@ pub struct Settings {
/// By default, it will be set to 20.
pub default_text_size: u16,
+ /// If enabled, spread text workload in multiple threads when multiple cores
+ /// are available.
+ ///
+ /// By default, it is disabled.
+ pub text_multithreading: bool,
+
/// The antialiasing strategy that will be used for triangle primitives.
+ ///
+ /// By default, it is `None`.
pub antialiasing: Option<Antialiasing>,
}
+impl Settings {
+ /// Creates new [`Settings`] using environment configuration.
+ ///
+ /// Specifically:
+ ///
+ /// - The `internal_backend` can be configured using the `WGPU_BACKEND`
+ /// environment variable. If the variable is not set, the primary backend
+ /// will be used. The following values are allowed:
+ /// - `vulkan`
+ /// - `metal`
+ /// - `dx12`
+ /// - `dx11`
+ /// - `gl`
+ /// - `webgpu`
+ /// - `primary`
+ pub fn from_env() -> Self {
+ Settings {
+ internal_backend: backend_from_env()
+ .unwrap_or(wgpu::BackendBit::PRIMARY),
+ ..Self::default()
+ }
+ }
+}
+
impl Default for Settings {
fn default() -> Settings {
Settings {
format: wgpu::TextureFormat::Bgra8UnormSrgb,
present_mode: wgpu::PresentMode::Mailbox,
+ internal_backend: wgpu::BackendBit::PRIMARY,
default_font: None,
default_text_size: 20,
+ text_multithreading: false,
antialiasing: None,
}
}
}
+
+fn backend_from_env() -> Option<wgpu::BackendBit> {
+ std::env::var("WGPU_BACKEND").ok().map(|backend| {
+ match backend.to_lowercase().as_str() {
+ "vulkan" => wgpu::BackendBit::VULKAN,
+ "metal" => wgpu::BackendBit::METAL,
+ "dx12" => wgpu::BackendBit::DX12,
+ "dx11" => wgpu::BackendBit::DX11,
+ "gl" => wgpu::BackendBit::GL,
+ "webgpu" => wgpu::BackendBit::BROWSER_WEBGPU,
+ "primary" => wgpu::BackendBit::PRIMARY,
+ other => panic!("Unknown backend: {}", other),
+ }
+ })
+}
diff --git a/wgpu/src/shader/blit.frag b/wgpu/src/shader/blit.frag
deleted file mode 100644
index dfed960f..00000000
--- a/wgpu/src/shader/blit.frag
+++ /dev/null
@@ -1,12 +0,0 @@
-#version 450
-
-layout(location = 0) in vec2 v_Uv;
-
-layout(set = 0, binding = 0) uniform sampler u_Sampler;
-layout(set = 1, binding = 0) uniform texture2D u_Texture;
-
-layout(location = 0) out vec4 o_Color;
-
-void main() {
- o_Color = texture(sampler2D(u_Texture, u_Sampler), v_Uv);
-}
diff --git a/wgpu/src/shader/blit.frag.spv b/wgpu/src/shader/blit.frag.spv
deleted file mode 100644
index 2c5638b5..00000000
--- a/wgpu/src/shader/blit.frag.spv
+++ /dev/null
Binary files differ
diff --git a/wgpu/src/shader/blit.vert b/wgpu/src/shader/blit.vert
deleted file mode 100644
index 899cd39d..00000000
--- a/wgpu/src/shader/blit.vert
+++ /dev/null
@@ -1,26 +0,0 @@
-#version 450
-
-layout(location = 0) out vec2 o_Uv;
-
-const vec2 positions[6] = vec2[6](
- vec2(-1.0, 1.0),
- vec2(-1.0, -1.0),
- vec2(1.0, -1.0),
- vec2(-1.0, 1.0),
- vec2(1.0, 1.0),
- vec2(1.0, -1.0)
-);
-
-const vec2 uvs[6] = vec2[6](
- vec2(0.0, 0.0),
- vec2(0.0, 1.0),
- vec2(1.0, 1.0),
- vec2(0.0, 0.0),
- vec2(1.0, 0.0),
- vec2(1.0, 1.0)
-);
-
-void main() {
- o_Uv = uvs[gl_VertexIndex];
- gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
-}
diff --git a/wgpu/src/shader/blit.vert.spv b/wgpu/src/shader/blit.vert.spv
deleted file mode 100644
index e0b436ce..00000000
--- a/wgpu/src/shader/blit.vert.spv
+++ /dev/null
Binary files differ
diff --git a/wgpu/src/shader/blit.wgsl b/wgpu/src/shader/blit.wgsl
new file mode 100644
index 00000000..694f192e
--- /dev/null
+++ b/wgpu/src/shader/blit.wgsl
@@ -0,0 +1,43 @@
+var positions: array<vec2<f32>, 6> = array<vec2<f32>, 6>(
+ vec2<f32>(-1.0, 1.0),
+ vec2<f32>(-1.0, -1.0),
+ vec2<f32>(1.0, -1.0),
+ vec2<f32>(-1.0, 1.0),
+ vec2<f32>(1.0, 1.0),
+ vec2<f32>(1.0, -1.0)
+);
+
+var uvs: array<vec2<f32>, 6> = array<vec2<f32>, 6>(
+ vec2<f32>(0.0, 0.0),
+ vec2<f32>(0.0, 1.0),
+ vec2<f32>(1.0, 1.0),
+ vec2<f32>(0.0, 0.0),
+ vec2<f32>(1.0, 0.0),
+ vec2<f32>(1.0, 1.0)
+);
+
+[[group(0), binding(0)]] var u_sampler: sampler;
+[[group(1), binding(0)]] var u_texture: texture_2d<f32>;
+
+struct VertexInput {
+ [[builtin(vertex_index)]] vertex_index: u32;
+};
+
+struct VertexOutput {
+ [[builtin(position)]] position: vec4<f32>;
+ [[location(0)]] uv: vec2<f32>;
+};
+
+[[stage(vertex)]]
+fn vs_main(input: VertexInput) -> VertexOutput {
+ var out: VertexOutput;
+ out.uv = uvs[input.vertex_index];
+ out.position = vec4<f32>(positions[input.vertex_index], 0.0, 1.0);
+
+ return out;
+}
+
+[[stage(fragment)]]
+fn fs_main(input: VertexOutput) -> [[location(0)]] vec4<f32> {
+ return textureSample(u_texture, u_sampler, input.uv);
+}
diff --git a/wgpu/src/shader/image.frag b/wgpu/src/shader/image.frag
deleted file mode 100644
index 2809e9e6..00000000
--- a/wgpu/src/shader/image.frag
+++ /dev/null
@@ -1,12 +0,0 @@
-#version 450
-
-layout(location = 0) in vec3 v_Uv;
-
-layout(set = 0, binding = 1) uniform sampler u_Sampler;
-layout(set = 1, binding = 0) uniform texture2DArray u_Texture;
-
-layout(location = 0) out vec4 o_Color;
-
-void main() {
- o_Color = texture(sampler2DArray(u_Texture, u_Sampler), v_Uv);
-}
diff --git a/wgpu/src/shader/image.frag.spv b/wgpu/src/shader/image.frag.spv
deleted file mode 100644
index 65b08aa3..00000000
--- a/wgpu/src/shader/image.frag.spv
+++ /dev/null
Binary files differ
diff --git a/wgpu/src/shader/image.vert b/wgpu/src/shader/image.vert
deleted file mode 100644
index dab53cfe..00000000
--- a/wgpu/src/shader/image.vert
+++ /dev/null
@@ -1,27 +0,0 @@
-#version 450
-
-layout(location = 0) in vec2 v_Pos;
-layout(location = 1) in vec2 i_Pos;
-layout(location = 2) in vec2 i_Scale;
-layout(location = 3) in vec2 i_Atlas_Pos;
-layout(location = 4) in vec2 i_Atlas_Scale;
-layout(location = 5) in uint i_Layer;
-
-layout (set = 0, binding = 0) uniform Globals {
- mat4 u_Transform;
-};
-
-layout(location = 0) out vec3 o_Uv;
-
-void main() {
- o_Uv = vec3(v_Pos * i_Atlas_Scale + i_Atlas_Pos, i_Layer);
-
- mat4 i_Transform = mat4(
- vec4(i_Scale.x, 0.0, 0.0, 0.0),
- vec4(0.0, i_Scale.y, 0.0, 0.0),
- vec4(0.0, 0.0, 1.0, 0.0),
- vec4(i_Pos, 0.0, 1.0)
- );
-
- gl_Position = u_Transform * i_Transform * vec4(v_Pos, 0.0, 1.0);
-}
diff --git a/wgpu/src/shader/image.vert.spv b/wgpu/src/shader/image.vert.spv
deleted file mode 100644
index 21f5db2d..00000000
--- a/wgpu/src/shader/image.vert.spv
+++ /dev/null
Binary files differ
diff --git a/wgpu/src/shader/image.wgsl b/wgpu/src/shader/image.wgsl
new file mode 100644
index 00000000..a63ee8f6
--- /dev/null
+++ b/wgpu/src/shader/image.wgsl
@@ -0,0 +1,47 @@
+[[block]]
+struct Globals {
+ transform: mat4x4<f32>;
+};
+
+[[group(0), binding(0)]] var<uniform> globals: Globals;
+[[group(0), binding(1)]] var u_sampler: sampler;
+[[group(1), binding(0)]] var u_texture: texture_2d_array<f32>;
+
+struct VertexInput {
+ [[location(0)]] v_pos: vec2<f32>;
+ [[location(1)]] pos: vec2<f32>;
+ [[location(2)]] scale: vec2<f32>;
+ [[location(3)]] atlas_pos: vec2<f32>;
+ [[location(4)]] atlas_scale: vec2<f32>;
+ [[location(5)]] layer: i32;
+};
+
+struct VertexOutput {
+ [[builtin(position)]] position: vec4<f32>;
+ [[location(0)]] uv: vec2<f32>;
+ [[location(1)]] layer: f32; // this should be an i32, but naga currently reads that as requiring interpolation.
+};
+
+[[stage(vertex)]]
+fn vs_main(input: VertexInput) -> VertexOutput {
+ var out: VertexOutput;
+
+ out.uv = vec2<f32>(input.v_pos * input.atlas_scale + input.atlas_pos);
+ out.layer = f32(input.layer);
+
+ var transform: mat4x4<f32> = mat4x4<f32>(
+ vec4<f32>(input.scale.x, 0.0, 0.0, 0.0),
+ vec4<f32>(0.0, input.scale.y, 0.0, 0.0),
+ vec4<f32>(0.0, 0.0, 1.0, 0.0),
+ vec4<f32>(input.pos, 0.0, 1.0)
+ );
+
+ out.position = globals.transform * transform * vec4<f32>(input.v_pos, 0.0, 1.0);
+
+ return out;
+}
+
+[[stage(fragment)]]
+fn fs_main(input: VertexOutput) -> [[location(0)]] vec4<f32> {
+ return textureSample(u_texture, u_sampler, input.uv, i32(input.layer));
+}
diff --git a/wgpu/src/shader/quad.frag b/wgpu/src/shader/quad.frag
deleted file mode 100644
index ad1af1ad..00000000
--- a/wgpu/src/shader/quad.frag
+++ /dev/null
@@ -1,66 +0,0 @@
-#version 450
-
-layout(location = 0) in vec4 v_Color;
-layout(location = 1) in vec4 v_BorderColor;
-layout(location = 2) in vec2 v_Pos;
-layout(location = 3) in vec2 v_Scale;
-layout(location = 4) in float v_BorderRadius;
-layout(location = 5) in float v_BorderWidth;
-
-layout(location = 0) out vec4 o_Color;
-
-float distance(in vec2 frag_coord, in vec2 position, in vec2 size, float radius)
-{
- // TODO: Try SDF approach: https://www.shadertoy.com/view/wd3XRN
- vec2 inner_size = size - vec2(radius, radius) * 2.0;
- vec2 top_left = position + vec2(radius, radius);
- vec2 bottom_right = top_left + inner_size;
-
- vec2 top_left_distance = top_left - frag_coord;
- vec2 bottom_right_distance = frag_coord - bottom_right;
-
- vec2 distance = vec2(
- max(max(top_left_distance.x, bottom_right_distance.x), 0),
- max(max(top_left_distance.y, bottom_right_distance.y), 0)
- );
-
- return sqrt(distance.x * distance.x + distance.y * distance.y);
-}
-
-void main() {
- vec4 mixed_color;
-
- // TODO: Remove branching (?)
- if(v_BorderWidth > 0) {
- float internal_border = max(v_BorderRadius - v_BorderWidth, 0);
-
- float internal_distance = distance(
- gl_FragCoord.xy,
- v_Pos + vec2(v_BorderWidth),
- v_Scale - vec2(v_BorderWidth * 2.0),
- internal_border
- );
-
- float border_mix = smoothstep(
- max(internal_border - 0.5, 0.0),
- internal_border + 0.5,
- internal_distance
- );
-
- mixed_color = mix(v_Color, v_BorderColor, border_mix);
- } else {
- mixed_color = v_Color;
- }
-
- float d = distance(
- gl_FragCoord.xy,
- v_Pos,
- v_Scale,
- v_BorderRadius
- );
-
- float radius_alpha =
- 1.0 - smoothstep(max(v_BorderRadius - 0.5, 0), v_BorderRadius + 0.5, d);
-
- o_Color = vec4(mixed_color.xyz, mixed_color.w * radius_alpha);
-}
diff --git a/wgpu/src/shader/quad.frag.spv b/wgpu/src/shader/quad.frag.spv
deleted file mode 100644
index 519f5f01..00000000
--- a/wgpu/src/shader/quad.frag.spv
+++ /dev/null
Binary files differ
diff --git a/wgpu/src/shader/quad.vert b/wgpu/src/shader/quad.vert
deleted file mode 100644
index 09a278b1..00000000
--- a/wgpu/src/shader/quad.vert
+++ /dev/null
@@ -1,47 +0,0 @@
-#version 450
-
-layout(location = 0) in vec2 v_Pos;
-layout(location = 1) in vec2 i_Pos;
-layout(location = 2) in vec2 i_Scale;
-layout(location = 3) in vec4 i_Color;
-layout(location = 4) in vec4 i_BorderColor;
-layout(location = 5) in float i_BorderRadius;
-layout(location = 6) in float i_BorderWidth;
-
-layout (set = 0, binding = 0) uniform Globals {
- mat4 u_Transform;
- float u_Scale;
-};
-
-layout(location = 0) out vec4 o_Color;
-layout(location = 1) out vec4 o_BorderColor;
-layout(location = 2) out vec2 o_Pos;
-layout(location = 3) out vec2 o_Scale;
-layout(location = 4) out float o_BorderRadius;
-layout(location = 5) out float o_BorderWidth;
-
-void main() {
- vec2 p_Pos = i_Pos * u_Scale;
- vec2 p_Scale = i_Scale * u_Scale;
-
- float i_BorderRadius = min(
- i_BorderRadius,
- min(i_Scale.x, i_Scale.y) / 2.0
- );
-
- mat4 i_Transform = mat4(
- vec4(p_Scale.x + 1.0, 0.0, 0.0, 0.0),
- vec4(0.0, p_Scale.y + 1.0, 0.0, 0.0),
- vec4(0.0, 0.0, 1.0, 0.0),
- vec4(p_Pos - vec2(0.5, 0.5), 0.0, 1.0)
- );
-
- o_Color = i_Color;
- o_BorderColor = i_BorderColor;
- o_Pos = p_Pos;
- o_Scale = p_Scale;
- o_BorderRadius = i_BorderRadius * u_Scale;
- o_BorderWidth = i_BorderWidth * u_Scale;
-
- gl_Position = u_Transform * i_Transform * vec4(v_Pos, 0.0, 1.0);
-}
diff --git a/wgpu/src/shader/quad.vert.spv b/wgpu/src/shader/quad.vert.spv
deleted file mode 100644
index fa71ba1e..00000000
--- a/wgpu/src/shader/quad.vert.spv
+++ /dev/null
Binary files differ
diff --git a/wgpu/src/shader/quad.wgsl b/wgpu/src/shader/quad.wgsl
new file mode 100644
index 00000000..80d733ab
--- /dev/null
+++ b/wgpu/src/shader/quad.wgsl
@@ -0,0 +1,122 @@
+[[block]]
+struct Globals {
+ transform: mat4x4<f32>;
+ scale: f32;
+};
+
+[[group(0), binding(0)]] var<uniform> globals: Globals;
+
+struct VertexInput {
+ [[location(0)]] v_pos: vec2<f32>;
+ [[location(1)]] pos: vec2<f32>;
+ [[location(2)]] scale: vec2<f32>;
+ [[location(3)]] color: vec4<f32>;
+ [[location(4)]] border_color: vec4<f32>;
+ [[location(5)]] border_radius: f32;
+ [[location(6)]] border_width: f32;
+};
+
+struct VertexOutput {
+ [[builtin(position)]] position: vec4<f32>;
+ [[location(0)]] color: vec4<f32>;
+ [[location(1)]] border_color: vec4<f32>;
+ [[location(2)]] pos: vec2<f32>;
+ [[location(3)]] scale: vec2<f32>;
+ [[location(4)]] border_radius: f32;
+ [[location(5)]] border_width: f32;
+};
+
+[[stage(vertex)]]
+fn vs_main(input: VertexInput) -> VertexOutput {
+ var out: VertexOutput;
+
+ var pos: vec2<f32> = input.pos * globals.scale;
+ var scale: vec2<f32> = input.scale * globals.scale;
+
+ var border_radius: f32 = min(
+ input.border_radius,
+ min(input.scale.x, input.scale.y) / 2.0
+ );
+
+ var transform: mat4x4<f32> = mat4x4<f32>(
+ vec4<f32>(scale.x + 1.0, 0.0, 0.0, 0.0),
+ vec4<f32>(0.0, scale.y + 1.0, 0.0, 0.0),
+ vec4<f32>(0.0, 0.0, 1.0, 0.0),
+ vec4<f32>(pos - vec2<f32>(0.5, 0.5), 0.0, 1.0)
+ );
+
+ out.color = input.color;
+ out.border_color = input.border_color;
+ out.pos = pos;
+ out.scale = scale;
+ out.border_radius = border_radius * globals.scale;
+ out.border_width = input.border_width * globals.scale;
+ out.position = globals.transform * transform * vec4<f32>(input.v_pos, 0.0, 1.0);
+
+ return out;
+}
+
+fn distance_alg(
+ frag_coord: vec2<f32>,
+ position: vec2<f32>,
+ size: vec2<f32>,
+ radius: f32
+) -> f32 {
+ var inner_size: vec2<f32> = size - vec2<f32>(radius, radius) * 2.0;
+ var top_left: vec2<f32> = position + vec2<f32>(radius, radius);
+ var bottom_right: vec2<f32> = top_left + inner_size;
+
+ var top_left_distance: vec2<f32> = top_left - frag_coord;
+ var bottom_right_distance: vec2<f32> = frag_coord - bottom_right;
+
+ var dist: vec2<f32> = vec2<f32>(
+ max(max(top_left_distance.x, bottom_right_distance.x), 0.0),
+ max(max(top_left_distance.y, bottom_right_distance.y), 0.0)
+ );
+
+ return sqrt(dist.x * dist.x + dist.y * dist.y);
+}
+
+
+[[stage(fragment)]]
+fn fs_main(
+ input: VertexOutput
+) -> [[location(0)]] vec4<f32> {
+ var mixed_color: vec4<f32> = input.color;
+
+ if (input.border_width > 0.0) {
+ var internal_border: f32 = max(
+ input.border_radius - input.border_width,
+ 0.0
+ );
+
+ var internal_distance: f32 = distance_alg(
+ vec2<f32>(input.position.x, input.position.y),
+ input.pos + vec2<f32>(input.border_width, input.border_width),
+ input.scale - vec2<f32>(input.border_width * 2.0, input.border_width * 2.0),
+ internal_border
+ );
+
+ var border_mix: f32 = smoothStep(
+ max(internal_border - 0.5, 0.0),
+ internal_border + 0.5,
+ internal_distance
+ );
+
+ mixed_color = mix(input.color, input.border_color, vec4<f32>(border_mix, border_mix, border_mix, border_mix));
+ }
+
+ var dist: f32 = distance_alg(
+ vec2<f32>(input.position.x, input.position.y),
+ input.pos,
+ input.scale,
+ input.border_radius
+ );
+
+ var radius_alpha: f32 = 1.0 - smoothStep(
+ max(input.border_radius - 0.5, 0.0),
+ input.border_radius + 0.5,
+ dist);
+
+ return vec4<f32>(mixed_color.x, mixed_color.y, mixed_color.z, mixed_color.w * radius_alpha);
+}
diff --git a/wgpu/src/shader/triangle.frag b/wgpu/src/shader/triangle.frag
deleted file mode 100644
index e39c45e7..00000000
--- a/wgpu/src/shader/triangle.frag
+++ /dev/null
@@ -1,8 +0,0 @@
-#version 450
-
-layout(location = 0) in vec4 i_Color;
-layout(location = 0) out vec4 o_Color;
-
-void main() {
- o_Color = i_Color;
-}
diff --git a/wgpu/src/shader/triangle.frag.spv b/wgpu/src/shader/triangle.frag.spv
deleted file mode 100644
index 11201872..00000000
--- a/wgpu/src/shader/triangle.frag.spv
+++ /dev/null
Binary files differ
diff --git a/wgpu/src/shader/triangle.vert b/wgpu/src/shader/triangle.vert
deleted file mode 100644
index 1f2c009b..00000000
--- a/wgpu/src/shader/triangle.vert
+++ /dev/null
@@ -1,15 +0,0 @@
-#version 450
-
-layout(location = 0) in vec2 i_Position;
-layout(location = 1) in vec4 i_Color;
-
-layout(location = 0) out vec4 o_Color;
-
-layout (set = 0, binding = 0) uniform Globals {
- mat4 u_Transform;
-};
-
-void main() {
- gl_Position = u_Transform * vec4(i_Position, 0.0, 1.0);
- o_Color = i_Color;
-}
diff --git a/wgpu/src/shader/triangle.vert.spv b/wgpu/src/shader/triangle.vert.spv
deleted file mode 100644
index 871f4f55..00000000
--- a/wgpu/src/shader/triangle.vert.spv
+++ /dev/null
Binary files differ
diff --git a/wgpu/src/shader/triangle.wgsl b/wgpu/src/shader/triangle.wgsl
new file mode 100644
index 00000000..96eaabcc
--- /dev/null
+++ b/wgpu/src/shader/triangle.wgsl
@@ -0,0 +1,31 @@
+[[block]]
+struct Globals {
+ transform: mat4x4<f32>;
+};
+
+[[group(0), binding(0)]] var<uniform> globals: Globals;
+
+struct VertexInput {
+ [[location(0)]] position: vec2<f32>;
+ [[location(1)]] color: vec4<f32>;
+};
+
+struct VertexOutput {
+ [[builtin(position)]] position: vec4<f32>;
+ [[location(0)]] color: vec4<f32>;
+};
+
+[[stage(vertex)]]
+fn vs_main(input: VertexInput) -> VertexOutput {
+ var out: VertexOutput;
+
+ out.color = input.color;
+ out.position = globals.transform * vec4<f32>(input.position, 0.0, 1.0);
+
+ return out;
+}
+
+[[stage(fragment)]]
+fn fs_main(input: VertexOutput) -> [[location(0)]] vec4<f32> {
+ return input.color;
+}
diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs
index 78999cf8..2b5b94c9 100644
--- a/wgpu/src/text.rs
+++ b/wgpu/src/text.rs
@@ -15,10 +15,12 @@ impl Pipeline {
device: &wgpu::Device,
format: wgpu::TextureFormat,
default_font: Option<&[u8]>,
+ multithreading: bool,
) -> Self {
let default_font = default_font.map(|slice| slice.to_vec());
// TODO: Font customization
+ #[cfg(not(target_os = "ios"))]
#[cfg(feature = "default_system_font")]
let default_font = {
default_font.or_else(|| {
@@ -45,7 +47,7 @@ impl Pipeline {
let draw_brush =
wgpu_glyph::GlyphBrushBuilder::using_font(font.clone())
.initial_cache_size((2048, 2048))
- .draw_cache_multithread(false) // TODO: Expose as a configuration flag
+ .draw_cache_multithread(multithreading)
.build(device, format);
let measure_brush =
diff --git a/wgpu/src/triangle.rs b/wgpu/src/triangle.rs
index 61a771d8..65b2b7b0 100644
--- a/wgpu/src/triangle.rs
+++ b/wgpu/src/triangle.rs
@@ -86,8 +86,9 @@ impl Pipeline {
entries: &[wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX,
- ty: wgpu::BindingType::UniformBuffer {
- dynamic: true,
+ ty: wgpu::BindingType::Buffer {
+ ty: wgpu::BufferBindingType::Uniform,
+ has_dynamic_offset: true,
min_binding_size: wgpu::BufferSize::new(
mem::size_of::<Uniforms>() as u64,
),
@@ -110,9 +111,15 @@ impl Pipeline {
entries: &[wgpu::BindGroupEntry {
binding: 0,
resource: wgpu::BindingResource::Buffer(
- constants_buffer
- .raw
- .slice(0..std::mem::size_of::<Uniforms>() as u64),
+ wgpu::BufferBinding {
+ buffer: &constants_buffer.raw,
+ offset: 0,
+ size: wgpu::BufferSize::new(std::mem::size_of::<
+ Uniforms,
+ >(
+ )
+ as u64),
+ },
),
}],
});
@@ -124,73 +131,66 @@ impl Pipeline {
bind_group_layouts: &[&constants_layout],
});
- let vs_module = device.create_shader_module(wgpu::include_spirv!(
- "shader/triangle.vert.spv"
- ));
-
- let fs_module = device.create_shader_module(wgpu::include_spirv!(
- "shader/triangle.frag.spv"
- ));
+ let shader =
+ device.create_shader_module(&wgpu::ShaderModuleDescriptor {
+ label: Some("iced_wgpu::triangle::shader"),
+ source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed(
+ include_str!("shader/triangle.wgsl"),
+ )),
+ flags: wgpu::ShaderFlags::all(),
+ });
let pipeline =
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("iced_wgpu::triangle pipeline"),
layout: Some(&layout),
- vertex_stage: wgpu::ProgrammableStageDescriptor {
- module: &vs_module,
- entry_point: "main",
- },
- fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
- module: &fs_module,
- entry_point: "main",
- }),
- rasterization_state: Some(wgpu::RasterizationStateDescriptor {
- front_face: wgpu::FrontFace::Cw,
- cull_mode: wgpu::CullMode::None,
- ..Default::default()
- }),
- primitive_topology: wgpu::PrimitiveTopology::TriangleList,
- color_states: &[wgpu::ColorStateDescriptor {
- format,
- color_blend: wgpu::BlendDescriptor {
- src_factor: wgpu::BlendFactor::SrcAlpha,
- dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
- operation: wgpu::BlendOperation::Add,
- },
- alpha_blend: wgpu::BlendDescriptor {
- src_factor: wgpu::BlendFactor::One,
- dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
- operation: wgpu::BlendOperation::Add,
- },
- write_mask: wgpu::ColorWrite::ALL,
- }],
- depth_stencil_state: None,
- vertex_state: wgpu::VertexStateDescriptor {
- index_format: wgpu::IndexFormat::Uint32,
- vertex_buffers: &[wgpu::VertexBufferDescriptor {
- stride: mem::size_of::<Vertex2D>() as u64,
+ vertex: wgpu::VertexState {
+ module: &shader,
+ entry_point: "vs_main",
+ buffers: &[wgpu::VertexBufferLayout {
+ array_stride: mem::size_of::<Vertex2D>() as u64,
step_mode: wgpu::InputStepMode::Vertex,
- attributes: &[
+ attributes: &wgpu::vertex_attr_array!(
// Position
- wgpu::VertexAttributeDescriptor {
- shader_location: 0,
- format: wgpu::VertexFormat::Float2,
- offset: 0,
- },
+ 0 => Float32x2,
// Color
- wgpu::VertexAttributeDescriptor {
- shader_location: 1,
- format: wgpu::VertexFormat::Float4,
- offset: 4 * 2,
+ 1 => Float32x4,
+ ),
+ }],
+ },
+ fragment: Some(wgpu::FragmentState {
+ module: &shader,
+ entry_point: "fs_main",
+ targets: &[wgpu::ColorTargetState {
+ format,
+ blend: Some(wgpu::BlendState {
+ color: wgpu::BlendComponent {
+ src_factor: wgpu::BlendFactor::SrcAlpha,
+ dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
+ operation: wgpu::BlendOperation::Add,
+ },
+ alpha: wgpu::BlendComponent {
+ src_factor: wgpu::BlendFactor::One,
+ dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
+ operation: wgpu::BlendOperation::Add,
},
- ],
+ }),
+ write_mask: wgpu::ColorWrite::ALL,
}],
+ }),
+ primitive: wgpu::PrimitiveState {
+ topology: wgpu::PrimitiveTopology::TriangleList,
+ front_face: wgpu::FrontFace::Cw,
+ ..Default::default()
+ },
+ depth_stencil: None,
+ multisample: wgpu::MultisampleState {
+ count: u32::from(
+ antialiasing.map(|a| a.sample_count()).unwrap_or(1),
+ ),
+ mask: !0,
+ alpha_to_coverage_enabled: false,
},
- sample_count: u32::from(
- antialiasing.map(|a| a.sample_count()).unwrap_or(1),
- ),
- sample_mask: !0,
- alpha_to_coverage_enabled: false,
});
Pipeline {
@@ -253,9 +253,13 @@ impl Pipeline {
entries: &[wgpu::BindGroupEntry {
binding: 0,
resource: wgpu::BindingResource::Buffer(
- self.uniforms_buffer.raw.slice(
- 0..std::mem::size_of::<Uniforms>() as u64,
- ),
+ wgpu::BufferBinding {
+ buffer: &self.uniforms_buffer.raw,
+ offset: 0,
+ size: wgpu::BufferSize::new(
+ std::mem::size_of::<Uniforms>() as u64,
+ ),
+ },
),
}],
});
@@ -356,13 +360,12 @@ impl Pipeline {
let mut render_pass =
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
- color_attachments: &[
- wgpu::RenderPassColorAttachmentDescriptor {
- attachment,
- resolve_target,
- ops: wgpu::Operations { load, store: true },
- },
- ],
+ label: Some("iced_wgpu::triangle render pass"),
+ color_attachments: &[wgpu::RenderPassColorAttachment {
+ view: attachment,
+ resolve_target,
+ ops: wgpu::Operations { load, store: true },
+ }],
depth_stencil_attachment: None,
});
@@ -390,6 +393,7 @@ impl Pipeline {
self.index_buffer
.raw
.slice(index_offset * mem::size_of::<u32>() as u64..),
+ wgpu::IndexFormat::Uint32,
);
render_pass.set_vertex_buffer(
diff --git a/wgpu/src/triangle/msaa.rs b/wgpu/src/triangle/msaa.rs
index db86f748..c099d518 100644
--- a/wgpu/src/triangle/msaa.rs
+++ b/wgpu/src/triangle/msaa.rs
@@ -20,9 +20,9 @@ impl Blit {
address_mode_u: wgpu::AddressMode::ClampToEdge,
address_mode_v: wgpu::AddressMode::ClampToEdge,
address_mode_w: wgpu::AddressMode::ClampToEdge,
- mag_filter: wgpu::FilterMode::Linear,
- min_filter: wgpu::FilterMode::Linear,
- mipmap_filter: wgpu::FilterMode::Linear,
+ mag_filter: wgpu::FilterMode::Nearest,
+ min_filter: wgpu::FilterMode::Nearest,
+ mipmap_filter: wgpu::FilterMode::Nearest,
..Default::default()
});
@@ -32,7 +32,10 @@ impl Blit {
entries: &[wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::FRAGMENT,
- ty: wgpu::BindingType::Sampler { comparison: false },
+ ty: wgpu::BindingType::Sampler {
+ comparison: false,
+ filtering: false,
+ },
count: None,
}],
});
@@ -53,9 +56,11 @@ impl Blit {
entries: &[wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::FRAGMENT,
- ty: wgpu::BindingType::SampledTexture {
- dimension: wgpu::TextureViewDimension::D2,
- component_type: wgpu::TextureComponentType::Float,
+ ty: wgpu::BindingType::Texture {
+ sample_type: wgpu::TextureSampleType::Float {
+ filterable: false,
+ },
+ view_dimension: wgpu::TextureViewDimension::D2,
multisampled: false,
},
count: None,
@@ -69,54 +74,55 @@ impl Blit {
bind_group_layouts: &[&constant_layout, &texture_layout],
});
- let vs_module = device.create_shader_module(wgpu::include_spirv!(
- "../shader/blit.vert.spv"
- ));
-
- let fs_module = device.create_shader_module(wgpu::include_spirv!(
- "../shader/blit.frag.spv"
- ));
+ let shader =
+ device.create_shader_module(&wgpu::ShaderModuleDescriptor {
+ label: Some("iced_wgpu::triangle::blit_shader"),
+ source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed(
+ include_str!("../shader/blit.wgsl"),
+ )),
+ flags: wgpu::ShaderFlags::all(),
+ });
let pipeline =
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("iced_wgpu::triangle::msaa pipeline"),
layout: Some(&layout),
- vertex_stage: wgpu::ProgrammableStageDescriptor {
- module: &vs_module,
- entry_point: "main",
+ vertex: wgpu::VertexState {
+ module: &shader,
+ entry_point: "vs_main",
+ buffers: &[],
},
- fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
- module: &fs_module,
- entry_point: "main",
+ fragment: Some(wgpu::FragmentState {
+ module: &shader,
+ entry_point: "fs_main",
+ targets: &[wgpu::ColorTargetState {
+ format,
+ blend: Some(wgpu::BlendState {
+ color: wgpu::BlendComponent {
+ src_factor: wgpu::BlendFactor::SrcAlpha,
+ dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
+ operation: wgpu::BlendOperation::Add,
+ },
+ alpha: wgpu::BlendComponent {
+ src_factor: wgpu::BlendFactor::One,
+ dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
+ operation: wgpu::BlendOperation::Add,
+ },
+ }),
+ write_mask: wgpu::ColorWrite::ALL,
+ }],
}),
- rasterization_state: Some(wgpu::RasterizationStateDescriptor {
+ primitive: wgpu::PrimitiveState {
+ topology: wgpu::PrimitiveTopology::TriangleList,
front_face: wgpu::FrontFace::Cw,
- cull_mode: wgpu::CullMode::None,
..Default::default()
- }),
- primitive_topology: wgpu::PrimitiveTopology::TriangleList,
- color_states: &[wgpu::ColorStateDescriptor {
- format,
- color_blend: wgpu::BlendDescriptor {
- src_factor: wgpu::BlendFactor::SrcAlpha,
- dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
- operation: wgpu::BlendOperation::Add,
- },
- alpha_blend: wgpu::BlendDescriptor {
- src_factor: wgpu::BlendFactor::One,
- dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
- operation: wgpu::BlendOperation::Add,
- },
- write_mask: wgpu::ColorWrite::ALL,
- }],
- depth_stencil_state: None,
- vertex_state: wgpu::VertexStateDescriptor {
- index_format: wgpu::IndexFormat::Uint16,
- vertex_buffers: &[],
},
- sample_count: 1,
- sample_mask: !0,
- alpha_to_coverage_enabled: false,
+ depth_stencil: None,
+ multisample: wgpu::MultisampleState {
+ count: 1,
+ mask: !0,
+ alpha_to_coverage_enabled: false,
+ },
});
Blit {
@@ -172,16 +178,15 @@ impl Blit {
) {
let mut render_pass =
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
- color_attachments: &[
- wgpu::RenderPassColorAttachmentDescriptor {
- attachment: target,
- resolve_target: None,
- ops: wgpu::Operations {
- load: wgpu::LoadOp::Load,
- store: true,
- },
+ label: Some("iced_wgpu::triangle::msaa render pass"),
+ color_attachments: &[wgpu::RenderPassColorAttachment {
+ view: target,
+ resolve_target: None,
+ ops: wgpu::Operations {
+ load: wgpu::LoadOp::Load,
+ store: true,
},
- ],
+ }],
depth_stencil_attachment: None,
});
@@ -217,7 +222,7 @@ impl Targets {
let extent = wgpu::Extent3d {
width,
height,
- depth: 1,
+ depth_or_array_layers: 1,
};
let attachment = device.create_texture(&wgpu::TextureDescriptor {
@@ -227,7 +232,7 @@ impl Targets {
sample_count,
dimension: wgpu::TextureDimension::D2,
format,
- usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
+ usage: wgpu::TextureUsage::RENDER_ATTACHMENT,
});
let resolve = device.create_texture(&wgpu::TextureDescriptor {
@@ -237,7 +242,7 @@ impl Targets {
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format,
- usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT
+ usage: wgpu::TextureUsage::RENDER_ATTACHMENT
| wgpu::TextureUsage::SAMPLED,
});
diff --git a/wgpu/src/widget.rs b/wgpu/src/widget.rs
index 177ae1b6..a575d036 100644
--- a/wgpu/src/widget.rs
+++ b/wgpu/src/widget.rs
@@ -20,6 +20,8 @@ pub mod rule;
pub mod scrollable;
pub mod slider;
pub mod text_input;
+pub mod toggler;
+pub mod tooltip;
#[doc(no_inline)]
pub use button::Button;
@@ -43,6 +45,10 @@ pub use scrollable::Scrollable;
pub use slider::Slider;
#[doc(no_inline)]
pub use text_input::TextInput;
+#[doc(no_inline)]
+pub use toggler::Toggler;
+#[doc(no_inline)]
+pub use tooltip::Tooltip;
#[cfg(feature = "canvas")]
#[cfg_attr(docsrs, doc(cfg(feature = "canvas")))]
diff --git a/wgpu/src/widget/pane_grid.rs b/wgpu/src/widget/pane_grid.rs
index c26dde48..fc36862c 100644
--- a/wgpu/src/widget/pane_grid.rs
+++ b/wgpu/src/widget/pane_grid.rs
@@ -6,12 +6,12 @@
//! The [`pane_grid` example] showcases how to use a [`PaneGrid`] with resizing,
//! drag and drop, and hotkey support.
//!
-//! [`pane_grid` example]: https://github.com/hecrj/iced/tree/0.2/examples/pane_grid
+//! [`pane_grid` example]: https://github.com/hecrj/iced/tree/0.3/examples/pane_grid
use crate::Renderer;
-pub use iced_native::pane_grid::{
- Axis, Configuration, Direction, DragEvent, Node, Pane, ResizeEvent, Split,
- State,
+pub use iced_graphics::pane_grid::{
+ Axis, Configuration, Direction, DragEvent, Line, Node, Pane, ResizeEvent,
+ Split, State, StyleSheet,
};
/// A collection of panes distributed using either vertical or horizontal splits
diff --git a/wgpu/src/widget/toggler.rs b/wgpu/src/widget/toggler.rs
new file mode 100644
index 00000000..dfcf759b
--- /dev/null
+++ b/wgpu/src/widget/toggler.rs
@@ -0,0 +1,9 @@
+//! Show toggle controls using togglers.
+use crate::Renderer;
+
+pub use iced_graphics::toggler::{Style, StyleSheet};
+
+/// A toggler that can be toggled
+///
+/// This is an alias of an `iced_native` toggler with an `iced_wgpu::Renderer`.
+pub type Toggler<Message> = iced_native::Toggler<Message, Renderer>;
diff --git a/wgpu/src/widget/tooltip.rs b/wgpu/src/widget/tooltip.rs
new file mode 100644
index 00000000..89ab3a15
--- /dev/null
+++ b/wgpu/src/widget/tooltip.rs
@@ -0,0 +1,6 @@
+//! Display a widget over another.
+/// A widget allowing the selection of a single value from a list of options.
+pub type Tooltip<'a, Message> =
+ iced_native::Tooltip<'a, Message, crate::Renderer>;
+
+pub use iced_native::tooltip::Position;
diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs
index 072521ef..c21b0868 100644
--- a/wgpu/src/window/compositor.rs
+++ b/wgpu/src/window/compositor.rs
@@ -21,29 +21,38 @@ impl Compositor {
/// Requests a new [`Compositor`] with the given [`Settings`].
///
/// Returns `None` if no compatible graphics adapter could be found.
- pub async fn request(settings: Settings) -> Option<Self> {
- let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY);
+ pub async fn request<W: HasRawWindowHandle>(
+ settings: Settings,
+ compatible_window: Option<&W>,
+ ) -> Option<Self> {
+ let instance = wgpu::Instance::new(settings.internal_backend);
+
+ #[allow(unsafe_code)]
+ let compatible_surface = compatible_window
+ .map(|window| unsafe { instance.create_surface(window) });
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
power_preference: if settings.antialiasing.is_none() {
- wgpu::PowerPreference::Default
+ wgpu::PowerPreference::LowPower
} else {
wgpu::PowerPreference::HighPerformance
},
- compatible_surface: None,
+ compatible_surface: compatible_surface.as_ref(),
})
.await?;
let (device, queue) = adapter
.request_device(
&wgpu::DeviceDescriptor {
+ label: Some(
+ "iced_wgpu::window::compositor device descriptor",
+ ),
features: wgpu::Features::empty(),
limits: wgpu::Limits {
max_bind_groups: 2,
..wgpu::Limits::default()
},
- shader_validation: false,
},
None,
)
@@ -75,9 +84,15 @@ impl iced_graphics::window::Compositor for Compositor {
type Surface = wgpu::Surface;
type SwapChain = wgpu::SwapChain;
- fn new(settings: Self::Settings) -> Result<(Self, Renderer), Error> {
- let compositor = futures::executor::block_on(Self::request(settings))
- .ok_or(Error::AdapterNotFound)?;
+ fn new<W: HasRawWindowHandle>(
+ settings: Self::Settings,
+ compatible_window: Option<&W>,
+ ) -> Result<(Self, Renderer), Error> {
+ let compositor = futures::executor::block_on(Self::request(
+ settings,
+ compatible_window,
+ ))
+ .ok_or(Error::AdapterNotFound)?;
let backend = compositor.create_backend();
@@ -103,7 +118,7 @@ impl iced_graphics::window::Compositor for Compositor {
self.device.create_swap_chain(
surface,
&wgpu::SwapChainDescriptor {
- usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
+ usage: wgpu::TextureUsage::RENDER_ATTACHMENT,
format: self.settings.format,
present_mode: self.settings.present_mode,
width,
@@ -129,31 +144,28 @@ impl iced_graphics::window::Compositor for Compositor {
},
);
- let _ =
- encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
- color_attachments: &[
- wgpu::RenderPassColorAttachmentDescriptor {
- attachment: &frame.output.view,
- resolve_target: None,
- 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,
- });
-
+ let _ = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
+ label: Some("iced_wgpu::window::Compositor render pass"),
+ color_attachments: &[wgpu::RenderPassColorAttachment {
+ view: &frame.output.view,
+ resolve_target: None,
+ 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,
+ });
+
let mouse_interaction = renderer.backend_mut().draw(
&mut self.device,
&mut self.staging_belt,
@@ -163,27 +175,29 @@ impl iced_graphics::window::Compositor for Compositor {
output,
overlay,
);
-
+
// 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();
-
+
Ok(mouse_interaction)
}
Err(error) => match error {
- wgpu::SwapChainError::Outdated => {
+ wgpu::SwapChainError::OutOfMemory => {
+ panic!("Swapchain error: {:?}", error);
+ }
+ _ => {
// Try again next frame.
Err(())
}
- _ => panic!("Swapchain error: {:?}", error),
},
}
}