From 19eeee27ee89ec4c9a4b8c699d57325c7802d5d7 Mon Sep 17 00:00:00 2001 From: Justin Shrake Date: Sat, 22 Aug 2020 08:58:35 -0700 Subject: [PATCH] Add AddressMode::ClampToBorder behind a feature --- wgpu-core/src/conv.rs | 1 + wgpu-core/src/device/mod.rs | 25 ++++++++++++++++++++++++- wgpu-core/src/instance.rs | 3 +++ wgpu-core/src/resource.rs | 6 ++++++ wgpu-types/src/lib.rs | 28 ++++++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 1 deletion(-) diff --git a/wgpu-core/src/conv.rs b/wgpu-core/src/conv.rs index d8cff595e..9b58bb18f 100644 --- a/wgpu-core/src/conv.rs +++ b/wgpu-core/src/conv.rs @@ -759,6 +759,7 @@ pub fn map_wrap(address: wgt::AddressMode) -> hal::image::WrapMode { Am::ClampToEdge => W::Clamp, Am::Repeat => W::Tile, Am::MirrorRepeat => W::Mirror, + Am::ClampToBorder => W::Border, } } diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 86716bad1..50b7c96d3 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -1490,6 +1490,19 @@ impl Global { .get(device_id) .map_err(|_| DeviceError::Invalid)?; + let clamp_to_border_enabled = device + .features + .contains(wgt::Features::ADDRESS_MODE_CLAMP_TO_BORDER); + let clamp_to_border_found = desc + .address_modes + .iter() + .any(|am| am == &wgt::AddressMode::ClampToBorder); + if clamp_to_border_found && !clamp_to_border_enabled { + return Err(resource::CreateSamplerError::MissingFeature( + wgt::Features::ADDRESS_MODE_CLAMP_TO_BORDER, + )); + } + let actual_clamp = if let Some(clamp) = desc.anisotropy_clamp { let clamp = clamp.get(); let valid_clamp = clamp <= MAX_ANISOTROPY && conv::is_power_of_two(clamp as u32); @@ -1505,6 +1518,16 @@ impl Global { None }; + let actual_border = desc + .border_color + .map(|c| match c { + wgt::SamplerBorderColor::TransparentBlack => [0.0, 0.0, 0.0, 0.0], + wgt::SamplerBorderColor::OpaqueBlack => [0.0, 0.0, 0.0, 1.0], + wgt::SamplerBorderColor::OpaqueWhite => [1.0, 1.0, 1.0, 1.0], + }) + .map(hal::image::PackedColor::from) + .unwrap_or(hal::image::PackedColor(0)); + let info = hal::image::SamplerDesc { min_filter: conv::map_filter(desc.min_filter), mag_filter: conv::map_filter(desc.mag_filter), @@ -1517,7 +1540,7 @@ impl Global { lod_bias: hal::image::Lod(0.0), lod_range: hal::image::Lod(desc.lod_min_clamp)..hal::image::Lod(desc.lod_max_clamp), comparison: desc.compare.map(conv::map_compare_function), - border: hal::image::PackedColor(0), + border: actual_border, normalized: true, anisotropy_clamp: actual_clamp, }; diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index da7b9779b..932fbbc30 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -154,6 +154,9 @@ impl Adapter { wgt::Features::MULTI_DRAW_INDIRECT_COUNT, adapter_features.contains(hal::Features::DRAW_INDIRECT_COUNT), ); + #[cfg(not(target_os = "ios"))] + //TODO: https://github.com/gfx-rs/gfx/issues/3346 + features.set(wgt::Features::ADDRESS_MODE_CLAMP_TO_BORDER, true); let adapter_limits = raw.physical_device.limits(); diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 7d7154ec9..f0afbd7c4 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -362,6 +362,8 @@ pub struct SamplerDescriptor<'a> { pub compare: Option, /// Valid values: 1, 2, 4, 8, and 16. pub anisotropy_clamp: Option, + /// Border color to use when address_mode is [`AddressMode::ClampToBorder`] + pub border_color: Option, } impl Default for SamplerDescriptor<'_> { @@ -376,6 +378,7 @@ impl Default for SamplerDescriptor<'_> { lod_max_clamp: std::f32::MAX, compare: None, anisotropy_clamp: None, + border_color: None, } } } @@ -397,6 +400,9 @@ pub enum CreateSamplerError { InvalidClamp(u8), #[error("cannot create any more samplers")] TooManyObjects, + /// AddressMode::ClampToBorder requires feature ADDRESS_MODE_CLAMP_TO_BORDER + #[error("Feature {0:?} must be enabled")] + MissingFeature(wgt::Features), } impl Borrow for Sampler { diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index b6370bbe2..9d5a57e8d 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -279,6 +279,17 @@ bitflags::bitflags! { /// /// This is a native only feature. const PUSH_CONSTANTS = 0x0000_0000_0080_0000; + /// Allows the use of [`AddressMode::ClampToBorder`]. + /// + /// Supported platforms: + /// - DX12 + /// - Vulkan + /// - Metal (macOS 10.12+ only) + /// - DX11 + /// - OpenGL + /// + /// This is a web and native feature. + const ADDRESS_MODE_CLAMP_TO_BORDER = 0x0000_0000_0100_0000; /// Features which are part of the upstream WebGPU standard. const ALL_WEBGPU = 0x0000_0000_0000_FFFF; /// Features that are only available when targeting native (not web). @@ -1476,6 +1487,12 @@ pub enum AddressMode { /// -0.25 -> 0.25 /// 1.25 -> 0.75 MirrorRepeat = 2, + /// Clamp the value to the border of the texture + /// Requires feature [`Features::ADDRESS_MODE_CLAMP_TO_BORDER`] + /// + /// -0.25 -> border + /// 1.25 -> border + ClampToBorder = 3, } impl Default for AddressMode { @@ -1821,3 +1838,14 @@ pub struct TextureCopyView { /// The base texel of the texture in the selected `mip_level`. pub origin: Origin3d, } + +/// Color variation to use when sampler addressing mode is [`AddressMode::ClampToBorder`] +#[repr(C)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +#[cfg_attr(feature = "trace", derive(serde::Serialize))] +#[cfg_attr(feature = "replay", derive(serde::Deserialize))] +pub enum SamplerBorderColor { + TransparentBlack, + OpaqueBlack, + OpaqueWhite, +}