Skip to content

Commit

Permalink
yakui-wgpu: add mipmap filtering for custom textures (#138)
Browse files Browse the repository at this point in the history
  • Loading branch information
Uriopass authored Jan 25, 2024
1 parent b5ae11d commit 836a695
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 18 deletions.
1 change: 1 addition & 0 deletions crates/bootstrap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ async fn run(body: impl ExampleBody) {
custom_texture::generate(&app.device, &app.queue),
wgpu::FilterMode::Nearest,
wgpu::FilterMode::Nearest,
wgpu::FilterMode::Nearest,
);

// Add a custom font for some of the examples.
Expand Down
21 changes: 17 additions & 4 deletions crates/yakui-wgpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,13 @@ impl YakuiWgpu {
view: impl Into<Arc<wgpu::TextureView>>,
min_filter: wgpu::FilterMode,
mag_filter: wgpu::FilterMode,
mipmap_filter: wgpu::FilterMode,
) -> TextureId {
let index = self.textures.insert(GpuTexture {
view: view.into(),
min_filter,
mag_filter,
mipmap_filter,
});
TextureId::User(index.to_bits())
}
Expand Down Expand Up @@ -310,26 +312,37 @@ impl YakuiWgpu {
self.vertices.extend(vertices);
self.indices.extend(indices);

let (view, min_filter, mag_filter) = call
let (view, min_filter, mag_filter, mipmap_filter) = call
.texture
.and_then(|id| match id {
TextureId::Managed(managed) => {
let texture = self.managed_textures.get(&managed)?;
Some((&texture.view, texture.min_filter, texture.mag_filter))
Some((
&texture.view,
texture.min_filter,
texture.mag_filter,
wgpu::FilterMode::Nearest,
))
}
TextureId::User(bits) => {
let index = Index::from_bits(bits)?;
let texture = self.textures.get(index)?;
Some((&texture.view, texture.min_filter, texture.mag_filter))
Some((
&texture.view,
texture.min_filter,
texture.mag_filter,
texture.mipmap_filter,
))
}
})
.unwrap_or((
&self.default_texture.view,
self.default_texture.min_filter,
self.default_texture.mag_filter,
wgpu::FilterMode::Nearest,
));

let sampler = self.samplers.get(min_filter, mag_filter);
let sampler = self.samplers.get(min_filter, mag_filter, mipmap_filter);

let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("yakui Bind Group"),
Expand Down
47 changes: 33 additions & 14 deletions crates/yakui-wgpu/src/samplers.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,47 @@
pub(crate) struct Samplers {
nearest: wgpu::Sampler,
linear: wgpu::Sampler,
nearest_linear: wgpu::Sampler,
linear_nearest: wgpu::Sampler,
nearest_nearest_nearest: wgpu::Sampler,
linear_linear_nearest: wgpu::Sampler,
nearest_linear_nearest: wgpu::Sampler,
linear_nearest_nearest: wgpu::Sampler,
nearest_nearest_linear: wgpu::Sampler,
linear_linear_linear: wgpu::Sampler,
nearest_linear_linear: wgpu::Sampler,
linear_nearest_linear: wgpu::Sampler,
}

impl Samplers {
pub fn new(device: &wgpu::Device) -> Self {
use wgpu::FilterMode::{Linear, Nearest};

Self {
nearest: sampler(device, Nearest, Nearest),
linear: sampler(device, Linear, Linear),
nearest_linear: sampler(device, Nearest, Linear),
linear_nearest: sampler(device, Linear, Nearest),
nearest_nearest_nearest: sampler(device, Nearest, Nearest, Nearest),
linear_linear_nearest: sampler(device, Linear, Linear, Nearest),
nearest_linear_nearest: sampler(device, Nearest, Linear, Nearest),
linear_nearest_nearest: sampler(device, Linear, Nearest, Nearest),
nearest_nearest_linear: sampler(device, Nearest, Nearest, Linear),
linear_linear_linear: sampler(device, Linear, Linear, Linear),
nearest_linear_linear: sampler(device, Nearest, Linear, Linear),
linear_nearest_linear: sampler(device, Linear, Nearest, Linear),
}
}

pub fn get(&self, min: wgpu::FilterMode, max: wgpu::FilterMode) -> &wgpu::Sampler {
pub fn get(
&self,
min: wgpu::FilterMode,
max: wgpu::FilterMode,
mipmap: wgpu::FilterMode,
) -> &wgpu::Sampler {
use wgpu::FilterMode::{Linear, Nearest};

match (min, max) {
(Nearest, Nearest) => &self.nearest,
(Linear, Linear) => &self.linear,
(Nearest, Linear) => &self.nearest_linear,
(Linear, Nearest) => &self.linear_nearest,
match (min, max, mipmap) {
(Nearest, Nearest, Nearest) => &self.nearest_nearest_nearest,
(Linear, Linear, Nearest) => &self.linear_linear_nearest,
(Nearest, Linear, Nearest) => &self.nearest_linear_nearest,
(Linear, Nearest, Nearest) => &self.linear_nearest_nearest,
(Nearest, Nearest, Linear) => &self.nearest_nearest_linear,
(Linear, Linear, Linear) => &self.linear_linear_linear,
(Nearest, Linear, Linear) => &self.nearest_linear_linear,
(Linear, Nearest, Linear) => &self.linear_nearest_linear,
}
}
}
Expand All @@ -33,10 +50,12 @@ fn sampler(
device: &wgpu::Device,
min_filter: wgpu::FilterMode,
mag_filter: wgpu::FilterMode,
mipmap_filter: wgpu::FilterMode,
) -> wgpu::Sampler {
device.create_sampler(&wgpu::SamplerDescriptor {
mag_filter,
min_filter,
mipmap_filter,
..Default::default()
})
}
1 change: 1 addition & 0 deletions crates/yakui-wgpu/src/texture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub(crate) struct GpuTexture {
pub view: Arc<wgpu::TextureView>,
pub min_filter: wgpu::FilterMode,
pub mag_filter: wgpu::FilterMode,
pub mipmap_filter: wgpu::FilterMode,
}

impl GpuManagedTexture {
Expand Down

0 comments on commit 836a695

Please sign in to comment.