Browse Source

wgpu renderer no longer creates a sampler with every texture (#2198)

pull/2200/head
Andreas Reich 2 years ago
committed by GitHub
parent
commit
53b800502a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      crates/egui-wgpu/CHANGELOG.md
  2. 37
      crates/egui-wgpu/src/renderer.rs
  3. 2
      crates/epaint/src/textures.rs

1
crates/egui-wgpu/CHANGELOG.md

@ -10,6 +10,7 @@ All notable changes to the `egui-wgpu` integration will be noted in this file.
* `Renderer` no longer handles pass creation and depth buffer creation ([#2136](https://github.com/emilk/egui/pull/2136))
* `PrepareCallback` now passes `wgpu::CommandEncoder` ([#2136](https://github.com/emilk/egui/pull/2136))
* Only a single vertex & index buffer is now created and resized when necessary (previously, vertex/index buffers were allocated for every mesh) ([#2148](https://github.com/emilk/egui/pull/2148)).
* `Renderer::update_texture` no longer creates a new `wgpu::Sampler` with every new texture ([#2198](https://github.com/emilk/egui/pull/2198))
## 0.19.0 - 2022-08-20
* Enables deferred render + surface state initialization for Android ([#1634](https://github.com/emilk/egui/pull/1634)).

37
crates/egui-wgpu/src/renderer.rs

@ -130,11 +130,14 @@ pub struct Renderer {
uniform_buffer: wgpu::Buffer,
uniform_bind_group: wgpu::BindGroup,
texture_bind_group_layout: wgpu::BindGroupLayout,
/// Map of egui texture IDs to textures and their associated bindgroups (texture view +
/// sampler). The texture may be None if the TextureId is just a handle to a user-provided
/// sampler.
textures: HashMap<egui::TextureId, (Option<wgpu::Texture>, wgpu::BindGroup)>,
next_user_texture_id: u64,
samplers: HashMap<egui::TextureFilter, wgpu::Sampler>,
/// Storage for use by [`egui::PaintCallback`]'s that need to store resources such as render
/// pipelines that must have the lifetime of the renderpass.
pub paint_callback_resources: TypeMap,
@ -312,6 +315,7 @@ impl Renderer {
texture_bind_group_layout,
textures: HashMap::new(),
next_user_texture_id: 0,
samplers: HashMap::new(),
paint_callback_resources: TypeMap::default(),
}
}
@ -511,7 +515,6 @@ impl Renderer {
origin,
);
} else {
// TODO(Wumpf): Create only a new texture if we need to
// allocate a new texture
// Use same label for all resources associated with this texture id (no point in retyping the type)
let label_str = format!("egui_texid_{:?}", id);
@ -522,20 +525,13 @@ impl Renderer {
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Rgba8UnormSrgb, // TODO(emilk): handle WebGL1 where this is not always supported!
format: wgpu::TextureFormat::Rgba8UnormSrgb, // Minspec for wgpu WebGL emulation is WebGL2, so this should always be supported.
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
});
let filter = match image_delta.filter {
egui::TextureFilter::Nearest => wgpu::FilterMode::Nearest,
egui::TextureFilter::Linear => wgpu::FilterMode::Linear,
};
// TODO(Wumpf): Reuse this sampler.
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
label,
mag_filter: filter,
min_filter: filter,
..Default::default()
});
let sampler = self
.samplers
.entry(image_delta.filter)
.or_insert_with(|| create_sampler(image_delta.filter, device));
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
label,
layout: &self.texture_bind_group_layout,
@ -548,7 +544,7 @@ impl Renderer {
},
wgpu::BindGroupEntry {
binding: 1,
resource: wgpu::BindingResource::Sampler(&sampler),
resource: wgpu::BindingResource::Sampler(sampler),
},
],
});
@ -794,6 +790,19 @@ impl Renderer {
}
}
fn create_sampler(filter: egui::TextureFilter, device: &wgpu::Device) -> wgpu::Sampler {
let wgpu_filter = match filter {
egui::TextureFilter::Nearest => wgpu::FilterMode::Nearest,
egui::TextureFilter::Linear => wgpu::FilterMode::Linear,
};
device.create_sampler(&wgpu::SamplerDescriptor {
label: Some(&format!("egui sampler ({:?})", filter)),
mag_filter: wgpu_filter,
min_filter: wgpu_filter,
..Default::default()
})
}
fn create_vertex_buffer(device: &wgpu::Device, size: u64) -> wgpu::Buffer {
device.create_buffer(&wgpu::BufferDescriptor {
label: Some("egui_vertex_buffer"),

2
crates/epaint/src/textures.rs

@ -136,7 +136,7 @@ pub struct TextureMeta {
}
/// How the texture texels are filtered.
#[derive(Copy, Clone, Debug, PartialEq)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum TextureFilter {
/// Show the nearest pixel value.

Loading…
Cancel
Save