wgpu renderer no longer creates a sampler with every texture (#2198)
This commit is contained in:
parent
f7a15a34f9
commit
53b800502a
3 changed files with 25 additions and 15 deletions
|
@ -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))
|
* `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))
|
* `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)).
|
* 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
|
## 0.19.0 - 2022-08-20
|
||||||
* Enables deferred render + surface state initialization for Android ([#1634](https://github.com/emilk/egui/pull/1634)).
|
* Enables deferred render + surface state initialization for Android ([#1634](https://github.com/emilk/egui/pull/1634)).
|
||||||
|
|
|
@ -130,11 +130,14 @@ pub struct Renderer {
|
||||||
uniform_buffer: wgpu::Buffer,
|
uniform_buffer: wgpu::Buffer,
|
||||||
uniform_bind_group: wgpu::BindGroup,
|
uniform_bind_group: wgpu::BindGroup,
|
||||||
texture_bind_group_layout: wgpu::BindGroupLayout,
|
texture_bind_group_layout: wgpu::BindGroupLayout,
|
||||||
|
|
||||||
/// Map of egui texture IDs to textures and their associated bindgroups (texture view +
|
/// 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). The texture may be None if the TextureId is just a handle to a user-provided
|
||||||
/// sampler.
|
/// sampler.
|
||||||
textures: HashMap<egui::TextureId, (Option<wgpu::Texture>, wgpu::BindGroup)>,
|
textures: HashMap<egui::TextureId, (Option<wgpu::Texture>, wgpu::BindGroup)>,
|
||||||
next_user_texture_id: u64,
|
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
|
/// Storage for use by [`egui::PaintCallback`]'s that need to store resources such as render
|
||||||
/// pipelines that must have the lifetime of the renderpass.
|
/// pipelines that must have the lifetime of the renderpass.
|
||||||
pub paint_callback_resources: TypeMap,
|
pub paint_callback_resources: TypeMap,
|
||||||
|
@ -312,6 +315,7 @@ impl Renderer {
|
||||||
texture_bind_group_layout,
|
texture_bind_group_layout,
|
||||||
textures: HashMap::new(),
|
textures: HashMap::new(),
|
||||||
next_user_texture_id: 0,
|
next_user_texture_id: 0,
|
||||||
|
samplers: HashMap::new(),
|
||||||
paint_callback_resources: TypeMap::default(),
|
paint_callback_resources: TypeMap::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -511,7 +515,6 @@ impl Renderer {
|
||||||
origin,
|
origin,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// TODO(Wumpf): Create only a new texture if we need to
|
|
||||||
// allocate a new texture
|
// allocate a new texture
|
||||||
// Use same label for all resources associated with this texture id (no point in retyping the type)
|
// Use same label for all resources associated with this texture id (no point in retyping the type)
|
||||||
let label_str = format!("egui_texid_{:?}", id);
|
let label_str = format!("egui_texid_{:?}", id);
|
||||||
|
@ -522,20 +525,13 @@ impl Renderer {
|
||||||
mip_level_count: 1,
|
mip_level_count: 1,
|
||||||
sample_count: 1,
|
sample_count: 1,
|
||||||
dimension: wgpu::TextureDimension::D2,
|
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,
|
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
|
||||||
});
|
});
|
||||||
let filter = match image_delta.filter {
|
let sampler = self
|
||||||
egui::TextureFilter::Nearest => wgpu::FilterMode::Nearest,
|
.samplers
|
||||||
egui::TextureFilter::Linear => wgpu::FilterMode::Linear,
|
.entry(image_delta.filter)
|
||||||
};
|
.or_insert_with(|| create_sampler(image_delta.filter, device));
|
||||||
// TODO(Wumpf): Reuse this sampler.
|
|
||||||
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
|
|
||||||
label,
|
|
||||||
mag_filter: filter,
|
|
||||||
min_filter: filter,
|
|
||||||
..Default::default()
|
|
||||||
});
|
|
||||||
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
label,
|
label,
|
||||||
layout: &self.texture_bind_group_layout,
|
layout: &self.texture_bind_group_layout,
|
||||||
|
@ -548,7 +544,7 @@ impl Renderer {
|
||||||
},
|
},
|
||||||
wgpu::BindGroupEntry {
|
wgpu::BindGroupEntry {
|
||||||
binding: 1,
|
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 {
|
fn create_vertex_buffer(device: &wgpu::Device, size: u64) -> wgpu::Buffer {
|
||||||
device.create_buffer(&wgpu::BufferDescriptor {
|
device.create_buffer(&wgpu::BufferDescriptor {
|
||||||
label: Some("egui_vertex_buffer"),
|
label: Some("egui_vertex_buffer"),
|
||||||
|
|
|
@ -136,7 +136,7 @@ pub struct TextureMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// How the texture texels are filtered.
|
/// 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))]
|
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
pub enum TextureFilter {
|
pub enum TextureFilter {
|
||||||
/// Show the nearest pixel value.
|
/// Show the nearest pixel value.
|
||||||
|
|
Loading…
Reference in a new issue