Skip to content

Commit

Permalink
add AddressMode::ClampToZero (#2364)
Browse files Browse the repository at this point in the history
* add AddressMode::ClampToZero

* add feature checks

* oops

* rustfmt

* fix dx12

* change to use SamplerBorderColor

* fix metal

* update to use new config

* update dx12 + docs

* address nits

* cargo fmt

* fix dx12
  • Loading branch information
laptou authored Jan 15, 2022
1 parent 4612cdf commit 0183e7d
Show file tree
Hide file tree
Showing 13 changed files with 63 additions and 12 deletions.
4 changes: 4 additions & 0 deletions wgpu-core/src/device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -994,6 +994,10 @@ impl<A: HalApi> Device<A> {
self.require_features(wgt::Features::ADDRESS_MODE_CLAMP_TO_BORDER)?;
}

if desc.border_color == Some(wgt::SamplerBorderColor::Zero) {
self.require_features(wgt::Features::ADDRESS_MODE_CLAMP_TO_ZERO)?;
}

let lod_clamp = if desc.lod_min_clamp > 0.0 || desc.lod_max_clamp < 32.0 {
Some(desc.lod_min_clamp..desc.lod_max_clamp)
} else {
Expand Down
1 change: 1 addition & 0 deletions wgpu-hal/src/dx12/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ impl super::Adapter {
| wgt::Features::MULTI_DRAW_INDIRECT
| wgt::Features::MULTI_DRAW_INDIRECT_COUNT
| wgt::Features::ADDRESS_MODE_CLAMP_TO_BORDER
| wgt::Features::ADDRESS_MODE_CLAMP_TO_ZERO
| wgt::Features::POLYGON_MODE_LINE
| wgt::Features::POLYGON_MODE_POINT
| wgt::Features::VERTEX_WRITABLE_STORAGE
Expand Down
2 changes: 1 addition & 1 deletion wgpu-hal/src/dx12/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ pub fn map_comparison(func: wgt::CompareFunction) -> d3d12::D3D12_COMPARISON_FUN
pub fn map_border_color(border_color: Option<wgt::SamplerBorderColor>) -> [f32; 4] {
use wgt::SamplerBorderColor as Sbc;
match border_color {
Some(Sbc::TransparentBlack) | None => [0.0; 4],
Some(Sbc::TransparentBlack) | Some(Sbc::Zero) | None => [0.0; 4],
Some(Sbc::OpaqueBlack) => [0.0, 0.0, 0.0, 1.0],
Some(Sbc::OpaqueWhite) => [1.0; 4],
}
Expand Down
4 changes: 3 additions & 1 deletion wgpu-hal/src/dx12/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,8 @@ impl crate::Device<super::Api> for super::Device {
.anisotropy_clamp
.map_or(0, |_| d3d12::D3D12_FILTER_ANISOTROPIC);

let border_color = conv::map_border_color(desc.border_color);

self.raw.create_sampler(
handle.raw,
filter,
Expand All @@ -631,7 +633,7 @@ impl crate::Device<super::Api> for super::Device {
0.0,
desc.anisotropy_clamp.map_or(0, |aniso| aniso.get() as u32),
conv::map_comparison(desc.compare.unwrap_or(wgt::CompareFunction::Always)),
conv::map_border_color(desc.border_color),
border_color,
desc.lod_clamp.clone().unwrap_or(0.0..16.0),
);

Expand Down
2 changes: 1 addition & 1 deletion wgpu-hal/src/gles/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ impl super::Adapter {
| wgt::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES
| wgt::Features::CLEAR_TEXTURE;
features.set(
wgt::Features::ADDRESS_MODE_CLAMP_TO_BORDER,
wgt::Features::ADDRESS_MODE_CLAMP_TO_BORDER | wgt::Features::ADDRESS_MODE_CLAMP_TO_ZERO,
extensions.contains("GL_EXT_texture_border_clamp"),
);
features.set(
Expand Down
4 changes: 3 additions & 1 deletion wgpu-hal/src/gles/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,9 @@ impl crate::Device<super::Api> for super::Device {

if let Some(border_color) = desc.border_color {
let border = match border_color {
wgt::SamplerBorderColor::TransparentBlack => [0.0; 4],
wgt::SamplerBorderColor::TransparentBlack | wgt::SamplerBorderColor::Zero => {
[0.0; 4]
}
wgt::SamplerBorderColor::OpaqueBlack => [0.0, 0.0, 0.0, 1.0],
wgt::SamplerBorderColor::OpaqueWhite => [1.0; 4],
};
Expand Down
2 changes: 2 additions & 0 deletions wgpu-hal/src/metal/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1018,10 +1018,12 @@ impl super::PrivateCapabilities {
{
features.insert(F::STORAGE_RESOURCE_BINDING_ARRAY);
}

features.set(
F::ADDRESS_MODE_CLAMP_TO_BORDER,
self.sampler_clamp_to_border,
);
features.set(F::ADDRESS_MODE_CLAMP_TO_ZERO, true);

features
}
Expand Down
1 change: 1 addition & 0 deletions wgpu-hal/src/metal/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ pub fn map_border_color(border_color: wgt::SamplerBorderColor) -> mtl::MTLSample
wgt::SamplerBorderColor::TransparentBlack => TransparentBlack,
wgt::SamplerBorderColor::OpaqueBlack => OpaqueBlack,
wgt::SamplerBorderColor::OpaqueWhite => OpaqueWhite,
wgt::SamplerBorderColor::Zero => unreachable!(),
}
}

Expand Down
25 changes: 20 additions & 5 deletions wgpu-hal/src/metal/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,15 +392,15 @@ impl crate::Device<super::Api> for super::Device {
wgt::FilterMode::Linear => mtl::MTLSamplerMipFilter::Linear,
});

if let Some(aniso) = desc.anisotropy_clamp {
descriptor.set_max_anisotropy(aniso.get() as _);
}

let [s, t, r] = desc.address_modes;
descriptor.set_address_mode_s(conv::map_address_mode(s));
descriptor.set_address_mode_t(conv::map_address_mode(t));
descriptor.set_address_mode_r(conv::map_address_mode(r));

if let Some(aniso) = desc.anisotropy_clamp {
descriptor.set_max_anisotropy(aniso.get() as _);
}

if let Some(ref range) = desc.lod_clamp {
descriptor.set_lod_min_clamp(range.start);
descriptor.set_lod_max_clamp(range.end);
Expand All @@ -413,8 +413,23 @@ impl crate::Device<super::Api> for super::Device {
if let Some(fun) = desc.compare {
descriptor.set_compare_function(conv::map_compare_function(fun));
}

if let Some(border_color) = desc.border_color {
descriptor.set_border_color(conv::map_border_color(border_color));
if let wgt::SamplerBorderColor::Zero = border_color {
if s == wgt::AddressMode::ClampToBorder {
descriptor.set_address_mode_s(mtl::MTLSamplerAddressMode::ClampToZero);
}

if t == wgt::AddressMode::ClampToBorder {
descriptor.set_address_mode_t(mtl::MTLSamplerAddressMode::ClampToZero);
}

if r == wgt::AddressMode::ClampToBorder {
descriptor.set_address_mode_r(mtl::MTLSamplerAddressMode::ClampToZero);
}
} else {
descriptor.set_border_color(conv::map_border_color(border_color));
}
}

if let Some(label) = desc.label {
Expand Down
1 change: 1 addition & 0 deletions wgpu-hal/src/vulkan/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ impl PhysicalDeviceFeatures {
| F::MAPPABLE_PRIMARY_BUFFERS
| F::PUSH_CONSTANTS
| F::ADDRESS_MODE_CLAMP_TO_BORDER
| F::ADDRESS_MODE_CLAMP_TO_ZERO
| F::TIMESTAMP_QUERY
| F::PIPELINE_STATISTICS_QUERY
| F::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES
Expand Down
6 changes: 4 additions & 2 deletions wgpu-hal/src/vulkan/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -589,13 +589,15 @@ pub fn map_address_mode(mode: wgt::AddressMode) -> vk::SamplerAddressMode {
wgt::AddressMode::Repeat => vk::SamplerAddressMode::REPEAT,
wgt::AddressMode::MirrorRepeat => vk::SamplerAddressMode::MIRRORED_REPEAT,
wgt::AddressMode::ClampToBorder => vk::SamplerAddressMode::CLAMP_TO_BORDER,
//wgt::AddressMode::MirrorClamp => vk::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE,
// wgt::AddressMode::MirrorClamp => vk::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE,
}
}

pub fn map_border_color(border_color: wgt::SamplerBorderColor) -> vk::BorderColor {
match border_color {
wgt::SamplerBorderColor::TransparentBlack => vk::BorderColor::FLOAT_TRANSPARENT_BLACK,
wgt::SamplerBorderColor::TransparentBlack | wgt::SamplerBorderColor::Zero => {
vk::BorderColor::FLOAT_TRANSPARENT_BLACK
}
wgt::SamplerBorderColor::OpaqueBlack => vk::BorderColor::FLOAT_OPAQUE_BLACK,
wgt::SamplerBorderColor::OpaqueWhite => vk::BorderColor::FLOAT_OPAQUE_WHITE,
}
Expand Down
1 change: 1 addition & 0 deletions wgpu-hal/src/vulkan/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,7 @@ impl crate::Device<super::Api> for super::Device {
.max_anisotropy(aniso.get() as f32);
}
}

if let Some(color) = desc.border_color {
vk_info = vk_info.border_color(conv::map_border_color(color));
}
Expand Down
22 changes: 21 additions & 1 deletion wgpu-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,8 @@ bitflags::bitflags! {
///
/// This is a native only feature.
const PUSH_CONSTANTS = 1 << 26;
/// Allows the use of [`AddressMode::ClampToBorder`].
/// Allows the use of [`AddressMode::ClampToBorder`] with a border color
/// other than [`SamplerBorderColor::Zero`].
///
/// Supported platforms:
/// - DX12
Expand Down Expand Up @@ -551,6 +552,18 @@ bitflags::bitflags! {
///
/// This is a native only feature.
const TEXTURE_FORMAT_16BIT_NORM = 1 << 41;
/// Allows the use of [`AddressMode::ClampToBorder`] with a border color
/// of [`SamplerBorderColor::Zero`].
///
/// Supported platforms:
/// - DX12
/// - Vulkan
/// - Metal
/// - DX11
/// - OpenGL
///
/// This is a native only feature.
const ADDRESS_MODE_CLAMP_TO_ZERO = 1 << 42;
}
}

Expand Down Expand Up @@ -3727,6 +3740,13 @@ pub enum SamplerBorderColor {
OpaqueBlack,
/// [1, 1, 1, 1]
OpaqueWhite,

/// On the Metal backend, this is equivalent to `TransparentBlack` for
/// textures that have an alpha component, and equivalent to `OpaqueBlack`
/// for textures that do not have an alpha component. On other backends,
/// this is equivalent to `TransparentBlack`. Requires
/// [`Features::ADDRESS_MODE_CLAMP_TO_ZERO`]. Not supported on the web.
Zero,
}

/// Describes how to create a QuerySet.
Expand Down

0 comments on commit 0183e7d

Please sign in to comment.