summaryrefslogtreecommitdiffstats
path: root/wgpu/src/image
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2023-11-29 22:28:31 +0100
committerLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2023-11-29 22:28:31 +0100
commite09b4e24dda51b8212d8ece52431dacaa3922a7b (patch)
tree7005e181528134ebdde5bbbe5909273db9f30174 /wgpu/src/image
parent83c7870c569a2976923ee6243a19813094d44673 (diff)
parent7f8b17604a31e00becc43130ec516c1a53552c88 (diff)
downloadiced-e09b4e24dda51b8212d8ece52431dacaa3922a7b.tar.gz
iced-e09b4e24dda51b8212d8ece52431dacaa3922a7b.tar.bz2
iced-e09b4e24dda51b8212d8ece52431dacaa3922a7b.zip
Merge branch 'master' into feat/multi-window-support
Diffstat (limited to '')
-rw-r--r--wgpu/src/image.rs129
-rw-r--r--wgpu/src/image/atlas.rs12
-rw-r--r--wgpu/src/image/vector.rs2
3 files changed, 108 insertions, 35 deletions
diff --git a/wgpu/src/image.rs b/wgpu/src/image.rs
index 553ba330..b78802c7 100644
--- a/wgpu/src/image.rs
+++ b/wgpu/src/image.rs
@@ -37,7 +37,8 @@ pub struct Pipeline {
pipeline: wgpu::RenderPipeline,
vertices: wgpu::Buffer,
indices: wgpu::Buffer,
- sampler: wgpu::Sampler,
+ nearest_sampler: wgpu::Sampler,
+ linear_sampler: wgpu::Sampler,
texture: wgpu::BindGroup,
texture_version: usize,
texture_atlas: Atlas,
@@ -51,16 +52,16 @@ pub struct Pipeline {
#[derive(Debug)]
struct Layer {
uniforms: wgpu::Buffer,
- constants: wgpu::BindGroup,
- instances: Buffer<Instance>,
- instance_count: usize,
+ nearest: Data,
+ linear: Data,
}
impl Layer {
fn new(
device: &wgpu::Device,
constant_layout: &wgpu::BindGroupLayout,
- sampler: &wgpu::Sampler,
+ nearest_sampler: &wgpu::Sampler,
+ linear_sampler: &wgpu::Sampler,
) -> Self {
let uniforms = device.create_buffer(&wgpu::BufferDescriptor {
label: Some("iced_wgpu::image uniforms buffer"),
@@ -69,6 +70,59 @@ impl Layer {
mapped_at_creation: false,
});
+ let nearest =
+ Data::new(device, constant_layout, nearest_sampler, &uniforms);
+
+ let linear =
+ Data::new(device, constant_layout, linear_sampler, &uniforms);
+
+ Self {
+ uniforms,
+ nearest,
+ linear,
+ }
+ }
+
+ fn prepare(
+ &mut self,
+ device: &wgpu::Device,
+ queue: &wgpu::Queue,
+ nearest_instances: &[Instance],
+ linear_instances: &[Instance],
+ transformation: Transformation,
+ ) {
+ queue.write_buffer(
+ &self.uniforms,
+ 0,
+ bytemuck::bytes_of(&Uniforms {
+ transform: transformation.into(),
+ }),
+ );
+
+ self.nearest.upload(device, queue, nearest_instances);
+ self.linear.upload(device, queue, linear_instances);
+ }
+
+ fn render<'a>(&'a self, render_pass: &mut wgpu::RenderPass<'a>) {
+ self.nearest.render(render_pass);
+ self.linear.render(render_pass);
+ }
+}
+
+#[derive(Debug)]
+struct Data {
+ constants: wgpu::BindGroup,
+ instances: Buffer<Instance>,
+ instance_count: usize,
+}
+
+impl Data {
+ pub fn new(
+ device: &wgpu::Device,
+ constant_layout: &wgpu::BindGroupLayout,
+ sampler: &wgpu::Sampler,
+ uniforms: &wgpu::Buffer,
+ ) -> Self {
let constants = device.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("iced_wgpu::image constants bind group"),
layout: constant_layout,
@@ -77,7 +131,7 @@ impl Layer {
binding: 0,
resource: wgpu::BindingResource::Buffer(
wgpu::BufferBinding {
- buffer: &uniforms,
+ buffer: uniforms,
offset: 0,
size: None,
},
@@ -98,28 +152,18 @@ impl Layer {
);
Self {
- uniforms,
constants,
instances,
instance_count: 0,
}
}
- fn prepare(
+ fn upload(
&mut self,
device: &wgpu::Device,
queue: &wgpu::Queue,
instances: &[Instance],
- transformation: Transformation,
) {
- queue.write_buffer(
- &self.uniforms,
- 0,
- bytemuck::bytes_of(&Uniforms {
- transform: transformation.into(),
- }),
- );
-
let _ = self.instances.resize(device, instances.len());
let _ = self.instances.write(queue, 0, instances);
@@ -142,12 +186,22 @@ impl Pipeline {
pub fn new(device: &wgpu::Device, format: wgpu::TextureFormat) -> Self {
use wgpu::util::DeviceExt;
- let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
+ let nearest_sampler = device.create_sampler(&wgpu::SamplerDescriptor {
+ address_mode_u: wgpu::AddressMode::ClampToEdge,
+ address_mode_v: wgpu::AddressMode::ClampToEdge,
+ address_mode_w: wgpu::AddressMode::ClampToEdge,
+ min_filter: wgpu::FilterMode::Nearest,
+ mag_filter: wgpu::FilterMode::Nearest,
+ mipmap_filter: wgpu::FilterMode::Nearest,
+ ..Default::default()
+ });
+
+ let linear_sampler = device.create_sampler(&wgpu::SamplerDescriptor {
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,
+ mag_filter: wgpu::FilterMode::Linear,
mipmap_filter: wgpu::FilterMode::Linear,
..Default::default()
});
@@ -312,7 +366,8 @@ impl Pipeline {
pipeline,
vertices,
indices,
- sampler,
+ nearest_sampler,
+ linear_sampler,
texture,
texture_version: texture_atlas.layer_count(),
texture_atlas,
@@ -355,7 +410,8 @@ impl Pipeline {
#[cfg(feature = "tracing")]
let _ = info_span!("Wgpu::Image", "DRAW").entered();
- let instances: &mut Vec<Instance> = &mut Vec::new();
+ let nearest_instances: &mut Vec<Instance> = &mut Vec::new();
+ let linear_instances: &mut Vec<Instance> = &mut Vec::new();
#[cfg(feature = "image")]
let mut raster_cache = self.raster_cache.borrow_mut();
@@ -366,7 +422,11 @@ impl Pipeline {
for image in images {
match &image {
#[cfg(feature = "image")]
- layer::Image::Raster { handle, bounds } => {
+ layer::Image::Raster {
+ handle,
+ filter_method,
+ bounds,
+ } => {
if let Some(atlas_entry) = raster_cache.upload(
device,
encoder,
@@ -377,7 +437,12 @@ impl Pipeline {
[bounds.x, bounds.y],
[bounds.width, bounds.height],
atlas_entry,
- instances,
+ match filter_method {
+ image::FilterMethod::Nearest => {
+ nearest_instances
+ }
+ image::FilterMethod::Linear => linear_instances,
+ },
);
}
}
@@ -405,7 +470,7 @@ impl Pipeline {
[bounds.x, bounds.y],
size,
atlas_entry,
- instances,
+ nearest_instances,
);
}
}
@@ -414,7 +479,7 @@ impl Pipeline {
}
}
- if instances.is_empty() {
+ if nearest_instances.is_empty() && linear_instances.is_empty() {
return;
}
@@ -442,12 +507,20 @@ impl Pipeline {
self.layers.push(Layer::new(
device,
&self.constant_layout,
- &self.sampler,
+ &self.nearest_sampler,
+ &self.linear_sampler,
));
}
let layer = &mut self.layers[self.prepare_layer];
- layer.prepare(device, queue, instances, transformation);
+
+ layer.prepare(
+ device,
+ queue,
+ nearest_instances,
+ linear_instances,
+ transformation,
+ );
self.prepare_layer += 1;
}
@@ -524,7 +597,7 @@ struct Instance {
}
impl Instance {
- pub const INITIAL: usize = 1_000;
+ pub const INITIAL: usize = 20;
}
#[repr(C)]
diff --git a/wgpu/src/image/atlas.rs b/wgpu/src/image/atlas.rs
index e3de1290..789e35b4 100644
--- a/wgpu/src/image/atlas.rs
+++ b/wgpu/src/image/atlas.rs
@@ -86,7 +86,7 @@ impl Atlas {
entry
};
- log::info!("Allocated atlas entry: {:?}", entry);
+ log::info!("Allocated atlas entry: {entry:?}");
// It is a webgpu requirement that:
// BufferCopyView.layout.bytes_per_row % wgpu::COPY_BYTES_PER_ROW_ALIGNMENT == 0
@@ -104,7 +104,7 @@ impl Atlas {
padded_data[offset..offset + 4 * width as usize].copy_from_slice(
&data[row * 4 * width as usize..(row + 1) * 4 * width as usize],
- )
+ );
}
match &entry {
@@ -139,13 +139,13 @@ impl Atlas {
}
}
- log::info!("Current atlas: {:?}", self);
+ log::info!("Current atlas: {self:?}");
Some(entry)
}
pub fn remove(&mut self, entry: &Entry) {
- log::info!("Removing atlas entry: {:?}", entry);
+ log::info!("Removing atlas entry: {entry:?}");
match entry {
Entry::Contiguous(allocation) => {
@@ -237,7 +237,7 @@ impl Atlas {
}));
}
}
- _ => {}
+ Layer::Full => {}
}
}
@@ -258,7 +258,7 @@ impl Atlas {
}
fn deallocate(&mut self, allocation: &Allocation) {
- log::info!("Deallocating atlas: {:?}", allocation);
+ log::info!("Deallocating atlas: {allocation:?}");
match allocation {
Allocation::Full { layer } => {
diff --git a/wgpu/src/image/vector.rs b/wgpu/src/image/vector.rs
index 2c03d36b..6582bb82 100644
--- a/wgpu/src/image/vector.rs
+++ b/wgpu/src/image/vector.rs
@@ -152,7 +152,7 @@ impl Cache {
let allocation =
atlas.upload(device, encoder, width, height, &rgba)?;
- log::debug!("allocating {} {}x{}", id, width, height);
+ log::debug!("allocating {id} {width}x{height}");
let _ = self.svg_hits.insert(id);
let _ = self.rasterized_hits.insert(key);