Skip to content

Commit 415ce97

Browse files
committed
Implement anisotropic filtering and extensions/limits
1 parent 1a569eb commit 415ce97

File tree

4 files changed

+89
-4
lines changed

4 files changed

+89
-4
lines changed

wgpu-core/src/conv.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ fn checked_u32_as_u16(value: u32) -> u16 {
429429
value as u16
430430
}
431431

432-
fn is_power_of_two(val: u32) -> bool {
432+
pub fn is_power_of_two(val: u32) -> bool {
433433
val != 0 && (val & (val - 1)) == 0
434434
}
435435

wgpu-core/src/device/mod.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ fn own_label(label: &Label) -> String {
5555
pub const MAX_COLOR_TARGETS: usize = 4;
5656
pub const MAX_MIP_LEVELS: usize = 16;
5757
pub const MAX_VERTEX_BUFFERS: usize = 16;
58+
pub const MAX_ANISOTROPY: u8 = 16;
5859

5960
pub fn all_buffer_stages() -> hal::pso::PipelineStage {
6061
use hal::pso::PipelineStage as Ps;
@@ -541,6 +542,24 @@ impl<B: hal::Backend> Device<B> {
541542
}
542543

543544
impl<G: GlobalIdentityHandlerFactory> Global<G> {
545+
pub fn device_extensions<B: GfxBackend>(&self, device_id: id::DeviceId) -> wgt::Extensions {
546+
let hub = B::hub(self);
547+
let mut token = Token::root();
548+
let (device_guard, _) = hub.devices.read(&mut token);
549+
let device = &device_guard[device_id];
550+
551+
device.extensions.clone()
552+
}
553+
554+
pub fn device_limits<B: GfxBackend>(&self, device_id: id::DeviceId) -> wgt::Limits {
555+
let hub = B::hub(self);
556+
let mut token = Token::root();
557+
let (device_guard, _) = hub.devices.read(&mut token);
558+
let device = &device_guard[device_id];
559+
560+
device.limits.clone()
561+
}
562+
544563
pub fn device_create_buffer<B: GfxBackend>(
545564
&self,
546565
device_id: id::DeviceId,
@@ -977,6 +996,19 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
977996
let (device_guard, mut token) = hub.devices.read(&mut token);
978997
let device = &device_guard[device_id];
979998

999+
if desc.anisotropy_clamp > 1 {
1000+
assert!(
1001+
device.extensions.anisotropic_filtering,
1002+
"Anisotropic clamp may only be used when the anisotropic filtering extension is enabled"
1003+
);
1004+
let valid_clamp = desc.anisotropy_clamp <= MAX_ANISOTROPY
1005+
&& conv::is_power_of_two(desc.anisotropy_clamp as u32);
1006+
assert!(
1007+
valid_clamp,
1008+
"Anisotropic clamp must be one of the values: 0, 1, 2, 4, 8, or 16"
1009+
);
1010+
}
1011+
9801012
let info = hal::image::SamplerDesc {
9811013
min_filter: conv::map_filter(desc.min_filter),
9821014
mag_filter: conv::map_filter(desc.mag_filter),
@@ -991,7 +1023,11 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
9911023
comparison: conv::map_compare_function(desc.compare),
9921024
border: hal::image::PackedColor(0),
9931025
normalized: true,
994-
anisotropy_clamp: None, //TODO
1026+
anisotropy_clamp: if desc.anisotropy_clamp > 1 {
1027+
Some(desc.anisotropy_clamp)
1028+
} else {
1029+
None
1030+
},
9951031
};
9961032

9971033
let sampler = resource::Sampler {

wgpu-core/src/instance.rs

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{
77
device::Device,
88
hub::{GfxBackend, Global, GlobalIdentityHandlerFactory, Input, Token},
99
id::{AdapterId, DeviceId, SurfaceId},
10-
power, LifeGuard, Stored,
10+
power, LifeGuard, Stored, MAX_BIND_GROUPS,
1111
};
1212

1313
use wgt::{Backend, BackendBit, DeviceDescriptor, PowerPreference, BIND_BUFFER_ALIGNMENT};
@@ -527,6 +527,32 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
527527
AdapterInfo::from_gfx(adapter.raw.info.clone(), adapter_id.backend())
528528
}
529529

530+
pub fn adapter_extensions<B: GfxBackend>(&self, adapter_id: AdapterId) -> wgt::Extensions {
531+
let hub = B::hub(self);
532+
let mut token = Token::root();
533+
let (adapter_guard, _) = hub.adapters.read(&mut token);
534+
let adapter = &adapter_guard[adapter_id];
535+
536+
let features = adapter.raw.physical_device.features();
537+
538+
wgt::Extensions {
539+
anisotropic_filtering: features.contains(hal::Features::SAMPLER_ANISOTROPY),
540+
}
541+
}
542+
543+
pub fn adapter_limits<B: GfxBackend>(&self, adapter_id: AdapterId) -> wgt::Limits {
544+
let hub = B::hub(self);
545+
let mut token = Token::root();
546+
let (adapter_guard, _) = hub.adapters.read(&mut token);
547+
let adapter = &adapter_guard[adapter_id];
548+
549+
let limits = adapter.raw.physical_device.limits();
550+
551+
wgt::Limits {
552+
max_bind_groups: (limits.max_bound_descriptor_sets as u32).min(MAX_BIND_GROUPS as u32),
553+
}
554+
}
555+
530556
pub fn adapter_destroy<B: GfxBackend>(&self, adapter_id: AdapterId) {
531557
let hub = B::hub(self);
532558
let mut token = Token::root();
@@ -560,17 +586,30 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
560586
let (adapter_guard, _) = hub.adapters.read(&mut token);
561587
let adapter = &adapter_guard[adapter_id];
562588
let phd = &adapter.raw.physical_device;
589+
590+
let available_features = adapter.raw.physical_device.features();
591+
592+
// Check features that are always needed
563593
let wishful_features = hal::Features::VERTEX_STORES_AND_ATOMICS
564594
| hal::Features::FRAGMENT_STORES_AND_ATOMICS
565595
| hal::Features::NDC_Y_UP;
566-
let enabled_features = adapter.raw.physical_device.features() & wishful_features;
596+
let mut enabled_features = available_features & wishful_features;
567597
if enabled_features != wishful_features {
568598
log::warn!(
569599
"Missing features: {:?}",
570600
wishful_features - enabled_features
571601
);
572602
}
573603

604+
// Check features needed by extensions
605+
if desc.extensions.anisotropic_filtering {
606+
assert!(
607+
available_features.contains(hal::Features::SAMPLER_ANISOTROPY),
608+
"Missing feature SAMPLER_ANISOTROPY for anisotropic filtering extension"
609+
);
610+
enabled_features |= hal::Features::SAMPLER_ANISOTROPY;
611+
}
612+
574613
let family = adapter
575614
.raw
576615
.queue_families

wgpu-types/src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ impl From<Backend> for BackendBit {
8888
#[cfg_attr(feature = "trace", derive(Serialize))]
8989
#[cfg_attr(feature = "replay", derive(Deserialize))]
9090
pub struct Extensions {
91+
/// This is a native only extension. Support is planned to be added to webgpu,
92+
/// but it is not yet implemented.
93+
///
94+
/// https://github.com/gpuweb/gpuweb/issues/696
9195
pub anisotropic_filtering: bool,
9296
}
9397

@@ -926,6 +930,11 @@ pub struct SamplerDescriptor<L> {
926930
pub lod_min_clamp: f32,
927931
pub lod_max_clamp: f32,
928932
pub compare: CompareFunction,
933+
/// Anisotropic filtering extension must be enabled if this value is
934+
/// anything other than 0 and 1.
935+
///
936+
/// Valid values are 0, 1, 2, 4, 8, and 16.
937+
pub anisotropy_clamp: u8,
929938
}
930939

931940
impl<L> SamplerDescriptor<L> {
@@ -941,6 +950,7 @@ impl<L> SamplerDescriptor<L> {
941950
lod_min_clamp: self.lod_min_clamp,
942951
lod_max_clamp: self.lod_max_clamp,
943952
compare: self.compare,
953+
anisotropy_clamp: self.anisotropy_clamp,
944954
}
945955
}
946956
}

0 commit comments

Comments
 (0)