825: Add depth clamping support r=cwfitzgerald a=kvark

**Connections**
Implements https://github.com/gpuweb/gpuweb/pull/900

**Description**
Depth clamping is useful for shadow mapping and stuff. We'd want to use it in our `shadow` example.

**Testing**
Untested, should work though :)

Co-authored-by: Dzmitry Malyshau <dmalyshau@mozilla.com>
This commit is contained in:
bors[bot] 2020-07-22 15:16:20 +00:00 committed by GitHub
commit b904d1ee4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 36 additions and 5 deletions

View File

@ -635,7 +635,7 @@ pub fn map_rasterization_state_descriptor(
) -> hal::pso::Rasterizer {
use hal::pso;
pso::Rasterizer {
depth_clamping: false,
depth_clamping: desc.clamp_depth,
polygon_mode: pso::PolygonMode::Fill,
cull_face: match desc.cull_mode {
wgt::CullMode::None => pso::Face::empty(),

View File

@ -2109,10 +2109,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let color_states = &desc.color_states;
let depth_stencil_state = desc.depth_stencil_state.as_ref();
let rasterization_state = desc.rasterization_state.as_ref();
let rasterizer = conv::map_rasterization_state_descriptor(
&rasterization_state.cloned().unwrap_or_default(),
);
let rasterization_state = desc
.rasterization_state
.as_ref()
.cloned()
.unwrap_or_default();
let rasterizer = conv::map_rasterization_state_descriptor(&rasterization_state);
let mut interface = validation::StageInterface::default();
let mut validated_stages = wgt::ShaderStage::empty();
@ -2200,6 +2202,14 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let (device_guard, mut token) = hub.devices.read(&mut token);
let device = &device_guard[device_id];
if rasterization_state.clamp_depth
&& !device.features.contains(wgt::Features::DEPTH_CLAMPING)
{
return Err(pipeline::RenderPipelineError::MissingFeature(
wgt::Features::DEPTH_CLAMPING,
));
}
let (raw_pipeline, layout_ref_count) = {
let (pipeline_layout_guard, mut token) = hub.pipeline_layouts.read(&mut token);
let (bgl_guard, mut token) = hub.bind_group_layouts.read(&mut token);

View File

@ -127,6 +127,10 @@ impl<B: hal::Backend> Adapter<B> {
let mut features = wgt::Features::default()
| wgt::Features::MAPPABLE_PRIMARY_BUFFERS
| wgt::Features::PUSH_CONSTANTS;
features.set(
wgt::Features::DEPTH_CLAMPING,
adapter_features.contains(hal::Features::DEPTH_CLAMP),
);
features.set(
wgt::Features::SAMPLED_TEXTURE_BINDING_ARRAY,
adapter_features.contains(hal::Features::TEXTURE_DESCRIPTOR_ARRAY),

View File

@ -55,6 +55,7 @@ pub type RenderPipelineDescriptor<'a> =
#[derive(Clone, Debug)]
pub enum RenderPipelineError {
MissingFeature(wgt::Features),
InvalidVertexAttributeOffset {
location: wgt::ShaderLocation,
offset: BufferAddress,

View File

@ -131,6 +131,18 @@ bitflags::bitflags! {
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct Features: u64 {
/// By default, polygon depth is clipped to 0-1 range. Anything outside of that range
/// is rejected, and respective fragments are not touched.
///
/// With this extension, we can force clamping of the polygon depth to 0-1. That allows
/// shadow map occluders to be rendered into a tighter depth range.
///
/// Supported platforms:
/// - desktops
/// - some mobile chips
///
/// This is a web and native feature.
const DEPTH_CLAMPING = 0x0000_0000_0000_0001;
/// Webgpu only allows the MAP_READ and MAP_WRITE buffer usage to be matched with
/// COPY_DST and COPY_SRC respectively. This removes this requirement.
///
@ -543,6 +555,10 @@ impl Default for CullMode {
pub struct RasterizationStateDescriptor {
pub front_face: FrontFace,
pub cull_mode: CullMode,
/// If enabled polygon depth is clamped to 0-1 range instead of being clipped.
///
/// Requires `Features::DEPTH_CLAMPING` enabled.
pub clamp_depth: bool,
pub depth_bias: i32,
pub depth_bias_slope_scale: f32,
pub depth_bias_clamp: f32,