mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Implement anisotropic filtering and extensions/limits
This commit is contained in:
@@ -429,7 +429,7 @@ fn checked_u32_as_u16(value: u32) -> u16 {
|
||||
value as u16
|
||||
}
|
||||
|
||||
fn is_power_of_two(val: u32) -> bool {
|
||||
pub fn is_power_of_two(val: u32) -> bool {
|
||||
val != 0 && (val & (val - 1)) == 0
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ fn own_label(label: &Label) -> String {
|
||||
pub const MAX_COLOR_TARGETS: usize = 4;
|
||||
pub const MAX_MIP_LEVELS: usize = 16;
|
||||
pub const MAX_VERTEX_BUFFERS: usize = 16;
|
||||
pub const MAX_ANISOTROPY: u8 = 16;
|
||||
|
||||
pub fn all_buffer_stages() -> hal::pso::PipelineStage {
|
||||
use hal::pso::PipelineStage as Ps;
|
||||
@@ -541,6 +542,24 @@ impl<B: hal::Backend> Device<B> {
|
||||
}
|
||||
|
||||
impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
pub fn device_extensions<B: GfxBackend>(&self, device_id: id::DeviceId) -> wgt::Extensions {
|
||||
let hub = B::hub(self);
|
||||
let mut token = Token::root();
|
||||
let (device_guard, _) = hub.devices.read(&mut token);
|
||||
let device = &device_guard[device_id];
|
||||
|
||||
device.extensions.clone()
|
||||
}
|
||||
|
||||
pub fn device_limits<B: GfxBackend>(&self, device_id: id::DeviceId) -> wgt::Limits {
|
||||
let hub = B::hub(self);
|
||||
let mut token = Token::root();
|
||||
let (device_guard, _) = hub.devices.read(&mut token);
|
||||
let device = &device_guard[device_id];
|
||||
|
||||
device.limits.clone()
|
||||
}
|
||||
|
||||
pub fn device_create_buffer<B: GfxBackend>(
|
||||
&self,
|
||||
device_id: id::DeviceId,
|
||||
@@ -977,6 +996,19 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||
let device = &device_guard[device_id];
|
||||
|
||||
if desc.anisotropy_clamp > 1 {
|
||||
assert!(
|
||||
device.extensions.anisotropic_filtering,
|
||||
"Anisotropic clamp may only be used when the anisotropic filtering extension is enabled"
|
||||
);
|
||||
let valid_clamp = desc.anisotropy_clamp <= MAX_ANISOTROPY
|
||||
&& conv::is_power_of_two(desc.anisotropy_clamp as u32);
|
||||
assert!(
|
||||
valid_clamp,
|
||||
"Anisotropic clamp must be one of the values: 0, 1, 2, 4, 8, or 16"
|
||||
);
|
||||
}
|
||||
|
||||
let info = hal::image::SamplerDesc {
|
||||
min_filter: conv::map_filter(desc.min_filter),
|
||||
mag_filter: conv::map_filter(desc.mag_filter),
|
||||
@@ -991,7 +1023,11 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
comparison: conv::map_compare_function(desc.compare),
|
||||
border: hal::image::PackedColor(0),
|
||||
normalized: true,
|
||||
anisotropy_clamp: None, //TODO
|
||||
anisotropy_clamp: if desc.anisotropy_clamp > 1 {
|
||||
Some(desc.anisotropy_clamp)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
};
|
||||
|
||||
let sampler = resource::Sampler {
|
||||
|
||||
@@ -7,7 +7,7 @@ use crate::{
|
||||
device::Device,
|
||||
hub::{GfxBackend, Global, GlobalIdentityHandlerFactory, Input, Token},
|
||||
id::{AdapterId, DeviceId, SurfaceId},
|
||||
power, LifeGuard, Stored,
|
||||
power, LifeGuard, Stored, MAX_BIND_GROUPS,
|
||||
};
|
||||
|
||||
use wgt::{Backend, BackendBit, DeviceDescriptor, PowerPreference, BIND_BUFFER_ALIGNMENT};
|
||||
@@ -527,6 +527,32 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
AdapterInfo::from_gfx(adapter.raw.info.clone(), adapter_id.backend())
|
||||
}
|
||||
|
||||
pub fn adapter_extensions<B: GfxBackend>(&self, adapter_id: AdapterId) -> wgt::Extensions {
|
||||
let hub = B::hub(self);
|
||||
let mut token = Token::root();
|
||||
let (adapter_guard, _) = hub.adapters.read(&mut token);
|
||||
let adapter = &adapter_guard[adapter_id];
|
||||
|
||||
let features = adapter.raw.physical_device.features();
|
||||
|
||||
wgt::Extensions {
|
||||
anisotropic_filtering: features.contains(hal::Features::SAMPLER_ANISOTROPY),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn adapter_limits<B: GfxBackend>(&self, adapter_id: AdapterId) -> wgt::Limits {
|
||||
let hub = B::hub(self);
|
||||
let mut token = Token::root();
|
||||
let (adapter_guard, _) = hub.adapters.read(&mut token);
|
||||
let adapter = &adapter_guard[adapter_id];
|
||||
|
||||
let limits = adapter.raw.physical_device.limits();
|
||||
|
||||
wgt::Limits {
|
||||
max_bind_groups: (limits.max_bound_descriptor_sets as u32).min(MAX_BIND_GROUPS as u32),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn adapter_destroy<B: GfxBackend>(&self, adapter_id: AdapterId) {
|
||||
let hub = B::hub(self);
|
||||
let mut token = Token::root();
|
||||
@@ -560,10 +586,14 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
let (adapter_guard, _) = hub.adapters.read(&mut token);
|
||||
let adapter = &adapter_guard[adapter_id];
|
||||
let phd = &adapter.raw.physical_device;
|
||||
|
||||
let available_features = adapter.raw.physical_device.features();
|
||||
|
||||
// Check features that are always needed
|
||||
let wishful_features = hal::Features::VERTEX_STORES_AND_ATOMICS
|
||||
| hal::Features::FRAGMENT_STORES_AND_ATOMICS
|
||||
| hal::Features::NDC_Y_UP;
|
||||
let enabled_features = adapter.raw.physical_device.features() & wishful_features;
|
||||
let mut enabled_features = available_features & wishful_features;
|
||||
if enabled_features != wishful_features {
|
||||
log::warn!(
|
||||
"Missing features: {:?}",
|
||||
@@ -571,6 +601,15 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
);
|
||||
}
|
||||
|
||||
// Check features needed by extensions
|
||||
if desc.extensions.anisotropic_filtering {
|
||||
assert!(
|
||||
available_features.contains(hal::Features::SAMPLER_ANISOTROPY),
|
||||
"Missing feature SAMPLER_ANISOTROPY for anisotropic filtering extension"
|
||||
);
|
||||
enabled_features |= hal::Features::SAMPLER_ANISOTROPY;
|
||||
}
|
||||
|
||||
let family = adapter
|
||||
.raw
|
||||
.queue_families
|
||||
|
||||
@@ -88,6 +88,10 @@ impl From<Backend> for BackendBit {
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct Extensions {
|
||||
/// This is a native only extension. Support is planned to be added to webgpu,
|
||||
/// but it is not yet implemented.
|
||||
///
|
||||
/// https://github.com/gpuweb/gpuweb/issues/696
|
||||
pub anisotropic_filtering: bool,
|
||||
}
|
||||
|
||||
@@ -926,6 +930,11 @@ pub struct SamplerDescriptor<L> {
|
||||
pub lod_min_clamp: f32,
|
||||
pub lod_max_clamp: f32,
|
||||
pub compare: CompareFunction,
|
||||
/// Anisotropic filtering extension must be enabled if this value is
|
||||
/// anything other than 0 and 1.
|
||||
///
|
||||
/// Valid values are 0, 1, 2, 4, 8, and 16.
|
||||
pub anisotropy_clamp: u8,
|
||||
}
|
||||
|
||||
impl<L> SamplerDescriptor<L> {
|
||||
@@ -941,6 +950,7 @@ impl<L> SamplerDescriptor<L> {
|
||||
lod_min_clamp: self.lod_min_clamp,
|
||||
lod_max_clamp: self.lod_max_clamp,
|
||||
compare: self.compare,
|
||||
anisotropy_clamp: self.anisotropy_clamp,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user