fix design for wgpu backend

This commit is contained in:
Remmirad 2023-09-25 21:54:50 +02:00 committed by Héctor Ramón Jiménez
parent 4b32a48880
commit e5d3e75d82
No known key found for this signature in database
GPG key ID: 7CC46565708259A7

View file

@ -8,6 +8,7 @@ mod vector;
use atlas::Atlas; use atlas::Atlas;
use iced_graphics::core::image::{FilterMethod, TextureFilter}; use iced_graphics::core::image::{FilterMethod, TextureFilter};
use wgpu::Sampler;
use crate::core::{Rectangle, Size}; use crate::core::{Rectangle, Size};
use crate::graphics::Transformation; use crate::graphics::Transformation;
@ -15,7 +16,6 @@ use crate::layer;
use crate::Buffer; use crate::Buffer;
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::HashMap;
use std::mem; use std::mem;
use bytemuck::{Pod, Zeroable}; use bytemuck::{Pod, Zeroable};
@ -29,6 +29,8 @@ use crate::core::svg;
#[cfg(feature = "tracing")] #[cfg(feature = "tracing")]
use tracing::info_span; use tracing::info_span;
const SAMPLER_COUNT: usize = 4;
#[derive(Debug)] #[derive(Debug)]
pub struct Pipeline { pub struct Pipeline {
#[cfg(feature = "image")] #[cfg(feature = "image")]
@ -39,14 +41,14 @@ pub struct Pipeline {
pipeline: wgpu::RenderPipeline, pipeline: wgpu::RenderPipeline,
vertices: wgpu::Buffer, vertices: wgpu::Buffer,
indices: wgpu::Buffer, indices: wgpu::Buffer,
sampler: HashMap<TextureFilter, wgpu::Sampler>, sampler: [wgpu::Sampler; SAMPLER_COUNT],
texture: wgpu::BindGroup, texture: wgpu::BindGroup,
texture_version: usize, texture_version: usize,
texture_atlas: Atlas, texture_atlas: Atlas,
texture_layout: wgpu::BindGroupLayout, texture_layout: wgpu::BindGroupLayout,
constant_layout: wgpu::BindGroupLayout, constant_layout: wgpu::BindGroupLayout,
layers: Vec<Layer>, layers: Vec<[Option<Layer>; SAMPLER_COUNT]>,
prepare_layer: usize, prepare_layer: usize,
} }
@ -149,17 +151,16 @@ impl Pipeline {
FilterMethod::Nearest => wgpu::FilterMode::Nearest, FilterMethod::Nearest => wgpu::FilterMode::Nearest,
}; };
let mut sampler = HashMap::new(); let mut sampler: [Option<Sampler>; SAMPLER_COUNT] =
[None, None, None, None];
let filter = [FilterMethod::Linear, FilterMethod::Nearest]; let filter = [FilterMethod::Linear, FilterMethod::Nearest];
for min in 0..filter.len() { for min in 0..filter.len() {
for mag in 0..filter.len() { for mag in 0..filter.len() {
let _ = sampler.insert( sampler[to_index(&TextureFilter {
TextureFilter {
min: filter[min], min: filter[min],
mag: filter[mag], mag: filter[mag],
}, })] = Some(device.create_sampler(&wgpu::SamplerDescriptor {
device.create_sampler(&wgpu::SamplerDescriptor {
address_mode_u: wgpu::AddressMode::ClampToEdge, address_mode_u: wgpu::AddressMode::ClampToEdge,
address_mode_v: wgpu::AddressMode::ClampToEdge, address_mode_v: wgpu::AddressMode::ClampToEdge,
address_mode_w: wgpu::AddressMode::ClampToEdge, address_mode_w: wgpu::AddressMode::ClampToEdge,
@ -167,10 +168,15 @@ impl Pipeline {
min_filter: to_wgpu(filter[min]), min_filter: to_wgpu(filter[min]),
mipmap_filter: wgpu::FilterMode::Linear, mipmap_filter: wgpu::FilterMode::Linear,
..Default::default() ..Default::default()
}), }));
);
} }
} }
let sampler = [
sampler[0].take().unwrap(),
sampler[1].take().unwrap(),
sampler[2].take().unwrap(),
sampler[3].take().unwrap(),
];
let constant_layout = let constant_layout =
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
@ -375,8 +381,8 @@ impl Pipeline {
#[cfg(feature = "tracing")] #[cfg(feature = "tracing")]
let _ = info_span!("Wgpu::Image", "DRAW").entered(); let _ = info_span!("Wgpu::Image", "DRAW").entered();
let instances: &mut HashMap<TextureFilter, Vec<Instance>> = let mut instances: [Vec<Instance>; SAMPLER_COUNT] =
&mut HashMap::new(); [Vec::new(), Vec::new(), Vec::new(), Vec::new()];
#[cfg(feature = "image")] #[cfg(feature = "image")]
let mut raster_cache = self.raster_cache.borrow_mut(); let mut raster_cache = self.raster_cache.borrow_mut();
@ -398,9 +404,7 @@ impl Pipeline {
[bounds.x, bounds.y], [bounds.x, bounds.y],
[bounds.width, bounds.height], [bounds.width, bounds.height],
atlas_entry, atlas_entry,
instances &mut instances[to_index(handle.filter())],
.entry(handle.filter().clone())
.or_insert(Vec::new()),
); );
} }
} }
@ -428,9 +432,7 @@ impl Pipeline {
[bounds.x, bounds.y], [bounds.x, bounds.y],
size, size,
atlas_entry, atlas_entry,
instances &mut instances[to_index(&TextureFilter::default())],
.entry(TextureFilter::default())
.or_insert(Vec::new()),
); );
} }
} }
@ -463,21 +465,27 @@ impl Pipeline {
self.texture_version = texture_version; self.texture_version = texture_version;
} }
for (filter, instances) in instances.iter_mut() {
if self.layers.len() <= self.prepare_layer { if self.layers.len() <= self.prepare_layer {
self.layers.push(Layer::new( self.layers.push([None, None, None, None]);
}
for (i, instances) in instances.iter_mut().enumerate() {
let layer = &mut self.layers[self.prepare_layer][i];
if !instances.is_empty() {
if layer.is_none() {
*layer = Some(Layer::new(
device, device,
&self.constant_layout, &self.constant_layout,
self.sampler.get(filter).expect("Sampler is registered"), &self.sampler[i],
)); ))
}
} }
let layer = &mut self.layers[self.prepare_layer]; if let Some(layer) = layer {
layer.prepare(device, queue, instances, transformation); layer.prepare(device, queue, instances, transformation);
self.prepare_layer += 1;
} }
} }
self.prepare_layer += 1;
}
pub fn render<'a>( pub fn render<'a>(
&'a self, &'a self,
@ -485,7 +493,10 @@ impl Pipeline {
bounds: Rectangle<u32>, bounds: Rectangle<u32>,
render_pass: &mut wgpu::RenderPass<'a>, render_pass: &mut wgpu::RenderPass<'a>,
) { ) {
if let Some(layer) = self.layers.get(layer) { if let Some(layer_group) = self.layers.get(layer) {
for (i, layer) in layer_group.iter().enumerate() {
if let Some(layer) = layer {
println!("Render {i}");
render_pass.set_pipeline(&self.pipeline); render_pass.set_pipeline(&self.pipeline);
render_pass.set_scissor_rect( render_pass.set_scissor_rect(
@ -505,6 +516,8 @@ impl Pipeline {
layer.render(render_pass); layer.render(render_pass);
} }
} }
}
}
pub fn end_frame(&mut self) { pub fn end_frame(&mut self) {
#[cfg(feature = "image")] #[cfg(feature = "image")]
@ -517,6 +530,14 @@ impl Pipeline {
} }
} }
fn to_index(filter: &TextureFilter) -> usize {
let to_index = |m| match m {
FilterMethod::Linear => 0,
FilterMethod::Nearest => 1,
};
return (to_index(filter.mag) << 1) | (to_index(filter.min));
}
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Zeroable, Pod)] #[derive(Clone, Copy, Zeroable, Pod)]
pub struct Vertex { pub struct Vertex {