From f25a45f4e2588ed39183dc068b69f2aebfa6aa66 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Wed, 10 Nov 2021 16:55:27 -0500 Subject: [PATCH] Evolve depth clamping into clip control (#2171) --- deno_webgpu/src/lib.rs | 123 +++++++++----------------------- deno_webgpu/src/pipeline.rs | 4 +- wgpu-core/src/command/bundle.rs | 44 ++++++------ wgpu-core/src/device/mod.rs | 4 +- wgpu-core/src/present.rs | 12 ++-- wgpu-hal/src/dx12/adapter.rs | 2 +- wgpu-hal/src/dx12/device.rs | 2 +- wgpu-hal/src/gles/adapter.rs | 2 +- wgpu-hal/src/gles/conv.rs | 2 +- wgpu-hal/src/gles/mod.rs | 2 +- wgpu-hal/src/gles/queue.rs | 7 +- wgpu-hal/src/metal/adapter.rs | 5 +- wgpu-hal/src/metal/device.rs | 4 +- wgpu-hal/src/metal/mod.rs | 2 +- wgpu-hal/src/vulkan/adapter.rs | 25 ++++++- wgpu-hal/src/vulkan/device.rs | 8 ++- wgpu-types/src/lib.rs | 14 ++-- wgpu/examples/shadow/main.rs | 6 +- wgpu/src/backend/web.rs | 6 +- 19 files changed, 126 insertions(+), 148 deletions(-) diff --git a/deno_webgpu/src/lib.rs b/deno_webgpu/src/lib.rs index 66b514cd3a..3dfb15000a 100644 --- a/deno_webgpu/src/lib.rs +++ b/deno_webgpu/src/lib.rs @@ -127,8 +127,8 @@ pub fn init(unstable: bool) -> Extension { fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> { let mut return_features: Vec<&'static str> = vec![]; - if features.contains(wgpu_types::Features::DEPTH_CLAMPING) { - return_features.push("depth-clamping"); + if features.contains(wgpu_types::Features::DEPTH_CLIP_CONTROL) { + return_features.push("depth-clip-control"); } if features.contains(wgpu_types::Features::PIPELINE_STATISTICS_QUERY) { return_features.push("pipeline-statistics-query"); @@ -309,105 +309,50 @@ pub struct GpuRequiredFeatures(HashSet); impl From for wgpu_types::Features { fn from(required_features: GpuRequiredFeatures) -> wgpu_types::Features { let mut features: wgpu_types::Features = wgpu_types::Features::empty(); - - if required_features.0.contains("depth-clamping") { - features.set(wgpu_types::Features::DEPTH_CLAMPING, true); - } - if required_features.0.contains("pipeline-statistics-query") { - features.set(wgpu_types::Features::PIPELINE_STATISTICS_QUERY, true); - } - if required_features.0.contains("texture-compression-bc") { - features.set(wgpu_types::Features::TEXTURE_COMPRESSION_BC, true); - } - if required_features.0.contains("timestamp-query") { - features.set(wgpu_types::Features::TIMESTAMP_QUERY, true); - } + features.set(wgpu_types::Features::DEPTH_CLIP_CONTROL, required_features.0.contains("depth-clip-control")); + features.set(wgpu_types::Features::PIPELINE_STATISTICS_QUERY, required_features.0.contains("pipeline-statistics-query")); + features.set(wgpu_types::Features::TEXTURE_COMPRESSION_BC, required_features.0.contains("texture-compression-bc")); + features.set(wgpu_types::Features::TIMESTAMP_QUERY, required_features.0.contains("timestamp-query")); // extended from spec - if required_features.0.contains("mappable-primary-buffers") { - features.set(wgpu_types::Features::MAPPABLE_PRIMARY_BUFFERS, true); - } - if required_features.0.contains("texture-binding-array") { - features.set(wgpu_types::Features::TEXTURE_BINDING_ARRAY, true); - } - if required_features.0.contains("buffer-binding-array") { - features.set(wgpu_types::Features::BUFFER_BINDING_ARRAY, true); - } - if required_features + features.set(wgpu_types::Features::MAPPABLE_PRIMARY_BUFFERS, required_features.0.contains("mappable-primary-buffers")); + features.set(wgpu_types::Features::TEXTURE_BINDING_ARRAY, required_features.0.contains("texture-binding-array")); + features.set(wgpu_types::Features::BUFFER_BINDING_ARRAY, required_features.0.contains("buffer-binding-array")); + features.set(wgpu_types::Features::STORAGE_RESOURCE_BINDING_ARRAY, required_features .0 - .contains("storage-resource-binding-array") - { - features.set(wgpu_types::Features::STORAGE_RESOURCE_BINDING_ARRAY, true); - } - if required_features - .0 - .contains("sampled-texture-and-storage-buffer-array-non-uniform-indexing") - { + .contains("storage-resource-binding-array")); features.set( wgpu_types::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, - true, - ); - } - if required_features + required_features .0 - .contains("uniform-buffer-and-storage-buffer-texture-non-uniform-indexing") - { + .contains("sampled-texture-and-storage-buffer-array-non-uniform-indexing"), + ); features.set( wgpu_types::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, - true, - ); - } - if required_features.0.contains("unsized-binding-array") { - features.set(wgpu_types::Features::UNSIZED_BINDING_ARRAY, true); - } - if required_features.0.contains("multi-draw-indirect") { - features.set(wgpu_types::Features::MULTI_DRAW_INDIRECT, true); - } - if required_features.0.contains("multi-draw-indirect-count") { - features.set(wgpu_types::Features::MULTI_DRAW_INDIRECT_COUNT, true); - } - if required_features.0.contains("push-constants") { - features.set(wgpu_types::Features::PUSH_CONSTANTS, true); - } - if required_features.0.contains("address-mode-clamp-to-border") { - features.set(wgpu_types::Features::ADDRESS_MODE_CLAMP_TO_BORDER, true); - } - if required_features.0.contains("texture-compression-etc2") { - features.set(wgpu_types::Features::TEXTURE_COMPRESSION_ETC2, true); - } - if required_features.0.contains("texture-compression-astc-ldr") { - features.set(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC_LDR, true); - } - if required_features + required_features .0 - .contains("texture-adapter-specific-format-features") - { + .contains("uniform-buffer-and-storage-buffer-texture-non-uniform-indexing"), + ); + features.set(wgpu_types::Features::UNSIZED_BINDING_ARRAY, required_features.0.contains("unsized-binding-array")); + features.set(wgpu_types::Features::MULTI_DRAW_INDIRECT, required_features.0.contains("multi-draw-indirect")); + features.set(wgpu_types::Features::MULTI_DRAW_INDIRECT_COUNT, required_features.0.contains("multi-draw-indirect-count")); + features.set(wgpu_types::Features::PUSH_CONSTANTS, required_features.0.contains("push-constants")); + features.set(wgpu_types::Features::ADDRESS_MODE_CLAMP_TO_BORDER, required_features.0.contains("address-mode-clamp-to-border")); + features.set(wgpu_types::Features::TEXTURE_COMPRESSION_ETC2, required_features.0.contains("texture-compression-etc2")); + features.set(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC_LDR, required_features.0.contains("texture-compression-astc-ldr")); features.set( wgpu_types::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES, - true, + required_features + .0 + .contains("texture-adapter-specific-format-features"), ); - } - if required_features.0.contains("shader-float64") { - features.set(wgpu_types::Features::SHADER_FLOAT64, true); - } - if required_features.0.contains("vertex-attribute-64bit") { - features.set(wgpu_types::Features::VERTEX_ATTRIBUTE_64BIT, true); - } - if required_features.0.contains("conservative-rasterization") { - features.set(wgpu_types::Features::CONSERVATIVE_RASTERIZATION, true); - } - if required_features.0.contains("vertex-writable-storage") { - features.set(wgpu_types::Features::VERTEX_WRITABLE_STORAGE, true); - } - if required_features.0.contains("clear-commands") { - features.set(wgpu_types::Features::CLEAR_COMMANDS, true); - } - if required_features.0.contains("spirv-shader-passthrough") { - features.set(wgpu_types::Features::SPIRV_SHADER_PASSTHROUGH, true); - } - if required_features.0.contains("shader-primitive-index") { - features.set(wgpu_types::Features::SHADER_PRIMITIVE_INDEX, true); - } + features.set(wgpu_types::Features::SHADER_FLOAT64, required_features.0.contains("shader-float64")); + features.set(wgpu_types::Features::VERTEX_ATTRIBUTE_64BIT, required_features.0.contains("vertex-attribute-64bit")); + features.set(wgpu_types::Features::CONSERVATIVE_RASTERIZATION, required_features.0.contains("conservative-rasterization")); + features.set(wgpu_types::Features::VERTEX_WRITABLE_STORAGE, required_features.0.contains("vertex-writable-storage")); + features.set(wgpu_types::Features::CLEAR_COMMANDS, required_features.0.contains("clear-commands")); + features.set(wgpu_types::Features::SPIRV_SHADER_PASSTHROUGH, required_features.0.contains("spirv-shader-passthrough")); + features.set(wgpu_types::Features::SHADER_PRIMITIVE_INDEX, required_features.0.contains("shader-primitive-index")); features } diff --git a/deno_webgpu/src/pipeline.rs b/deno_webgpu/src/pipeline.rs index c784ea35f1..248732074b 100644 --- a/deno_webgpu/src/pipeline.rs +++ b/deno_webgpu/src/pipeline.rs @@ -171,7 +171,7 @@ struct GpuPrimitiveState { strip_index_format: Option, front_face: wgpu_types::FrontFace, cull_mode: GpuCullMode, - clamp_depth: bool, + unclipped_depth: bool, } impl From for wgpu_types::PrimitiveState { @@ -181,7 +181,7 @@ impl From for wgpu_types::PrimitiveState { strip_index_format: value.strip_index_format, front_face: value.front_face, cull_mode: value.cull_mode.into(), - clamp_depth: value.clamp_depth, + unclipped_depth: value.unclipped_depth, polygon_mode: Default::default(), // native-only conservative: false, // native-only } diff --git a/wgpu-core/src/command/bundle.rs b/wgpu-core/src/command/bundle.rs index 01c710eabd..e35d390970 100644 --- a/wgpu-core/src/command/bundle.rs +++ b/wgpu-core/src/command/bundle.rs @@ -1,35 +1,35 @@ /*! Render Bundles - ## Software implementation +## Software implementation - The path from nothing to using a render bundle consists of 3 phases. +The path from nothing to using a render bundle consists of 3 phases. - ### Initial command encoding +### Initial command encoding - User creates a `RenderBundleEncoder` and populates it by issuing commands - from `bundle_ffi` module, just like with `RenderPass`, except that the - set of available commands is reduced. Everything is written into a `RawPass`. +User creates a `RenderBundleEncoder` and populates it by issuing commands +from `bundle_ffi` module, just like with `RenderPass`, except that the +set of available commands is reduced. Everything is written into a `RawPass`. - ### Bundle baking +### Bundle baking - Once the commands are encoded, user calls `render_bundle_encoder_finish`. - This is perhaps the most complex part of the logic. It consumes the - commands stored in `RawPass`, while validating everything, tracking the state, - and re-recording the commands into a separate `Vec`. It - doesn't actually execute any commands. +Once the commands are encoded, user calls `render_bundle_encoder_finish`. +This is perhaps the most complex part of the logic. It consumes the +commands stored in `RawPass`, while validating everything, tracking the state, +and re-recording the commands into a separate `Vec`. It +doesn't actually execute any commands. - What's more important, is that the produced vector of commands is "normalized", - which means it can be executed verbatim without any state tracking. More - formally, "normalized" command stream guarantees that any state required by - a draw call is set explicitly by one of the commands between the draw call - and the last changing of the pipeline. +What's more important, is that the produced vector of commands is "normalized", +which means it can be executed verbatim without any state tracking. More +formally, "normalized" command stream guarantees that any state required by +a draw call is set explicitly by one of the commands between the draw call +and the last changing of the pipeline. - ### Execution +### Execution - When the bundle is used in an actual render pass, `RenderBundle::execute` is - called. It goes through the commands and issues them into the native command - buffer. Thanks to the "normalized" property, it doesn't track any bind group - invalidations or index format changes. +When the bundle is used in an actual render pass, `RenderBundle::execute` is +called. It goes through the commands and issues them into the native command +buffer. Thanks to the "normalized" property, it doesn't track any bind group +invalidations or index format changes. !*/ #![allow(clippy::reversed_empty_ranges)] diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index f0d9237457..d153515357 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -2211,8 +2211,8 @@ impl Device { ); } - if desc.primitive.clamp_depth { - self.require_features(wgt::Features::DEPTH_CLAMPING)?; + if desc.primitive.unclipped_depth { + self.require_features(wgt::Features::DEPTH_CLIP_CONTROL)?; } if desc.primitive.polygon_mode == wgt::PolygonMode::Line { diff --git a/wgpu-core/src/present.rs b/wgpu-core/src/present.rs index 56304dae2d..dabd9bd642 100644 --- a/wgpu-core/src/present.rs +++ b/wgpu-core/src/present.rs @@ -1,12 +1,12 @@ /*! Presentation. - ## Lifecycle +## Lifecycle - Whenever a submission detects the use of any surface texture, it adds it to the device - tracker for the duration of the submission (temporarily, while recording). - It's added with `UNINITIALIZED` state and transitioned into `empty()` state. - When this texture is presented, we remove it from the device tracker as well as - extract it from the hub. +Whenever a submission detects the use of any surface texture, it adds it to the device +tracker for the duration of the submission (temporarily, while recording). +It's added with `UNINITIALIZED` state and transitioned into `empty()` state. +When this texture is presented, we remove it from the device tracker as well as +extract it from the hub. !*/ #[cfg(feature = "trace")] diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index d5e195d511..f114b89b4a 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -169,7 +169,7 @@ impl super::Adapter { }; let mut features = wgt::Features::empty() - | wgt::Features::DEPTH_CLAMPING + | wgt::Features::DEPTH_CLIP_CONTROL | wgt::Features::MAPPABLE_PRIMARY_BUFFERS //TODO: Naga part //| wgt::Features::TEXTURE_BINDING_ARRAY diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 95eccb3b9b..25423ed5f5 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -1275,7 +1275,7 @@ impl crate::Device for super::Device { DepthBias: bias.constant, DepthBiasClamp: bias.clamp, SlopeScaledDepthBias: bias.slope_scale, - DepthClipEnable: if desc.primitive.clamp_depth { 0 } else { 1 }, + DepthClipEnable: if desc.primitive.unclipped_depth { 0 } else { 1 }, MultisampleEnable: if desc.multisample.count > 1 { 1 } else { 0 }, ForcedSampleCount: 0, AntialiasedLineEnable: 0, diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index 30a46a4d55..d42e09b5c4 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -280,7 +280,7 @@ impl super::Adapter { | wgt::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES | wgt::Features::CLEAR_COMMANDS; features.set( - wgt::Features::DEPTH_CLAMPING, + wgt::Features::DEPTH_CLIP_CONTROL, extensions.contains("GL_EXT_depth_clamp"), ); features.set( diff --git a/wgpu-hal/src/gles/conv.rs b/wgpu-hal/src/gles/conv.rs index e82f829331..9a1739b534 100644 --- a/wgpu-hal/src/gles/conv.rs +++ b/wgpu-hal/src/gles/conv.rs @@ -254,7 +254,7 @@ pub(super) fn map_primitive_state(state: &wgt::PrimitiveState) -> super::Primiti Some(wgt::Face::Back) => glow::BACK, None => 0, }, - clamp_depth: state.clamp_depth, + unclipped_depth: state.unclipped_depth, } } diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 054475676e..9330c1822c 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -546,7 +546,7 @@ struct StencilState { struct PrimitiveState { front_face: u32, cull_face: u32, - clamp_depth: bool, + unclipped_depth: bool, } type InvalidatedAttachments = ArrayVec; diff --git a/wgpu-hal/src/gles/queue.rs b/wgpu-hal/src/gles/queue.rs index 9652a33325..2bb3c61f04 100644 --- a/wgpu-hal/src/gles/queue.rs +++ b/wgpu-hal/src/gles/queue.rs @@ -66,7 +66,7 @@ impl super::Queue { gl.disable(glow::BLEND); gl.disable(glow::CULL_FACE); gl.disable(glow::POLYGON_OFFSET_FILL); - if self.features.contains(wgt::Features::DEPTH_CLAMPING) { + if self.features.contains(wgt::Features::DEPTH_CLIP_CONTROL) { gl.disable(glow::DEPTH_CLAMP); } } @@ -927,8 +927,9 @@ impl super::Queue { } else { gl.disable(glow::CULL_FACE); } - if self.features.contains(wgt::Features::DEPTH_CLAMPING) { - if state.clamp_depth { + if self.features.contains(wgt::Features::DEPTH_CLIP_CONTROL) { + //Note: this is a bit tricky, since we are controlling the clip, not the clamp. + if state.unclipped_depth { gl.enable(glow::DEPTH_CLAMP); } else { gl.disable(glow::DEPTH_CLAMP); diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index 77f4b9135b..64ecaa2430 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -861,7 +861,8 @@ impl super::PrivateCapabilities { Self::version_at_least(major, minor, 11, 0) }, //Depth clipping is supported on all macOS GPU families and iOS family 4 and later - supports_depth_clamping: device.supports_feature_set(MTLFeatureSet::iOS_GPUFamily4_v1) + supports_depth_clip_control: device + .supports_feature_set(MTLFeatureSet::iOS_GPUFamily4_v1) || os_is_mac, } } @@ -877,7 +878,7 @@ impl super::PrivateCapabilities { | F::POLYGON_MODE_LINE | F::CLEAR_COMMANDS; - features.set(F::DEPTH_CLAMPING, self.supports_depth_clamping); + features.set(F::DEPTH_CLIP_CONTROL, self.supports_depth_clip_control); features.set( F::TEXTURE_BINDING_ARRAY diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index da3a73ed10..172d5eb5d7 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -906,8 +906,8 @@ impl crate::Device for super::Device { raw_triangle_fill_mode, raw_front_winding: conv::map_winding(desc.primitive.front_face), raw_cull_mode: conv::map_cull_mode(desc.primitive.cull_mode), - raw_depth_clip_mode: if self.features.contains(wgt::Features::DEPTH_CLAMPING) { - Some(if desc.primitive.clamp_depth { + raw_depth_clip_mode: if self.features.contains(wgt::Features::DEPTH_CLIP_CONTROL) { + Some(if desc.primitive.unclipped_depth { mtl::MTLDepthClipMode::Clamp } else { mtl::MTLDepthClipMode::Clip diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index 8ed744babe..fb3f41dc4d 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -222,7 +222,7 @@ struct PrivateCapabilities { supports_arrays_of_textures: bool, supports_arrays_of_textures_write: bool, supports_mutability: bool, - supports_depth_clamping: bool, + supports_depth_clip_control: bool, } #[derive(Clone, Debug)] diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index e1580e0b15..a289e52f40 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -22,6 +22,7 @@ pub struct PhysicalDeviceFeatures { timeline_semaphore: Option, image_robustness: Option, robustness2: Option, + depth_clip_enable: Option, } // This is safe because the structs have `p_next: *mut c_void`, which we null out/never read. @@ -53,6 +54,9 @@ impl PhysicalDeviceFeatures { if let Some(ref mut feature) = self.robustness2 { info = info.push_next(feature); } + if let Some(ref mut feature) = self.depth_clip_enable { + info = info.push_next(feature); + } info } @@ -102,7 +106,6 @@ impl PhysicalDeviceFeatures { .multi_draw_indirect( requested_features.contains(wgt::Features::MULTI_DRAW_INDIRECT), ) - .depth_clamp(requested_features.contains(wgt::Features::DEPTH_CLAMPING)) .fill_mode_non_solid(requested_features.intersects( wgt::Features::POLYGON_MODE_LINE | wgt::Features::POLYGON_MODE_POINT, )) @@ -281,6 +284,17 @@ impl PhysicalDeviceFeatures { } else { None }, + depth_clip_enable: if enabled_extensions.contains(&vk::ExtDepthClipEnableFn::name()) { + Some( + vk::PhysicalDeviceDepthClipEnableFeaturesEXT::builder() + .depth_clip_enable( + requested_features.contains(wgt::Features::DEPTH_CLIP_CONTROL), + ) + .build(), + ) + } else { + None + }, } } @@ -307,7 +321,6 @@ impl PhysicalDeviceFeatures { //if self.core.dual_src_blend != 0 features.set(F::MULTI_DRAW_INDIRECT, self.core.multi_draw_indirect != 0); - features.set(F::DEPTH_CLAMPING, self.core.depth_clamp != 0); features.set(F::POLYGON_MODE_LINE, self.core.fill_mode_non_solid != 0); features.set(F::POLYGON_MODE_POINT, self.core.fill_mode_non_solid != 0); //if self.core.depth_bounds != 0 { @@ -462,6 +475,10 @@ impl PhysicalDeviceFeatures { } } + if let Some(ref feature) = self.depth_clip_enable { + features.set(F::DEPTH_CLIP_CONTROL, feature.depth_clip_enable != 0); + } + (features, dl_flags) } @@ -540,6 +557,10 @@ impl PhysicalDeviceCapabilities { extensions.push(vk::ExtConservativeRasterizationFn::name()); } + if requested_features.contains(wgt::Features::DEPTH_CLIP_CONTROL) { + extensions.push(vk::ExtDepthClipEnableFn::name()); + } + extensions } diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 9b9f8677fe..6c896d5354 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -1382,7 +1382,6 @@ impl crate::Device for super::Device { }; let mut vk_rasterization = vk::PipelineRasterizationStateCreateInfo::builder() - .depth_clamp_enable(desc.primitive.clamp_depth) .polygon_mode(conv::map_polygon_mode(desc.primitive.polygon_mode)) .front_face(conv::map_front_face(desc.primitive.front_face)) .line_width(1.0); @@ -1396,6 +1395,13 @@ impl crate::Device for super::Device { if desc.primitive.conservative { vk_rasterization = vk_rasterization.push_next(&mut vk_rasterization_conservative_state); } + let mut vk_depth_clip_state = + vk::PipelineRasterizationDepthClipStateCreateInfoEXT::builder() + .depth_clip_enable(false) + .build(); + if desc.primitive.unclipped_depth { + vk_rasterization = vk_rasterization.push_next(&mut vk_depth_clip_state); + } let mut vk_depth_stencil = vk::PipelineDepthStencilStateCreateInfo::builder(); if let Some(ref ds) = desc.depth_stencil { diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 2f8d4ea464..9f1983a4f4 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -163,10 +163,10 @@ bitflags::bitflags! { #[repr(transparent)] #[derive(Default)] 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. + /// By default, polygon depth is clipped to 0-1 range before/during rasterization. + /// 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 + /// With this extension, we can disabling clipping. That allows /// shadow map occluders to be rendered into a tighter depth range. /// /// Supported platforms: @@ -174,7 +174,7 @@ bitflags::bitflags! { /// - some mobile chips /// /// This is a web and native feature. - const DEPTH_CLAMPING = 1 << 0; + const DEPTH_CLIP_CONTROL = 1 << 0; /// Enables BCn family of compressed textures. All BCn textures use 4x4 pixel blocks /// with 8 or 16 bytes per block. /// @@ -1309,11 +1309,11 @@ pub struct PrimitiveState { /// The face culling mode. #[cfg_attr(feature = "serde", serde(default))] pub cull_mode: Option, - /// If set to true, the polygon depth is clamped to 0-1 range instead of being clipped. + /// If set to true, the polygon depth is not clipped to 0-1 before rasterization. /// - /// Enabling this requires `Features::DEPTH_CLAMPING` to be enabled. + /// Enabling this requires `Features::DEPTH_CLIP_CONTROL` to be enabled. #[cfg_attr(feature = "serde", serde(default))] - pub clamp_depth: bool, + pub unclipped_depth: bool, /// Controls the way each polygon is rasterized. Can be either `Fill` (default), `Line` or `Point` /// /// Setting this to `Line` requires `Features::POLYGON_MODE_LINE` to be enabled. diff --git a/wgpu/examples/shadow/main.rs b/wgpu/examples/shadow/main.rs index 78b88854a8..8a22c8fe99 100644 --- a/wgpu/examples/shadow/main.rs +++ b/wgpu/examples/shadow/main.rs @@ -210,7 +210,7 @@ impl Example { impl framework::Example for Example { fn optional_features() -> wgpu::Features { - wgpu::Features::DEPTH_CLAMPING + wgpu::Features::DEPTH_CLIP_CONTROL } fn init( @@ -510,7 +510,9 @@ impl framework::Example for Example { topology: wgpu::PrimitiveTopology::TriangleList, front_face: wgpu::FrontFace::Ccw, cull_mode: Some(wgpu::Face::Back), - clamp_depth: device.features().contains(wgpu::Features::DEPTH_CLAMPING), + unclipped_depth: device + .features() + .contains(wgpu::Features::DEPTH_CLIP_CONTROL), ..Default::default() }, depth_stencil: Some(wgpu::DepthStencilState { diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index f0d68ec096..744c124c34 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -604,7 +604,8 @@ fn map_primitive_state(primitive: &wgt::PrimitiveState) -> web_sys::GpuPrimitive PrimitiveTopology::TriangleStrip => pt::TriangleStrip, }); - //mapped.clamp_depth(primitive.clamp_depth); + //TODO: + //mapped.unclipped_depth(primitive.unclipped_depth); mapped } @@ -1026,7 +1027,8 @@ impl crate::Context for Context { let mut mapped_desc = web_sys::GpuDeviceDescriptor::new(); let possible_features = [ - (wgt::Features::DEPTH_CLAMPING, Gfn::DepthClamping), + //TODO: update the name + (wgt::Features::DEPTH_CLIP_CONTROL, Gfn::DepthClamping), // TODO (_, Gfn::Depth24unormStencil8), // TODO (_, Gfn::Depth32floatStencil8), (