Skip to content

Commit

Permalink
Evolve depth clamping into clip control (#2171)
Browse files Browse the repository at this point in the history
  • Loading branch information
kvark authored Nov 10, 2021
1 parent 27aae2a commit f25a45f
Show file tree
Hide file tree
Showing 19 changed files with 126 additions and 148 deletions.
123 changes: 34 additions & 89 deletions deno_webgpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -309,105 +309,50 @@ pub struct GpuRequiredFeatures(HashSet<String>);
impl From<GpuRequiredFeatures> 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
}
Expand Down
4 changes: 2 additions & 2 deletions deno_webgpu/src/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ struct GpuPrimitiveState {
strip_index_format: Option<wgpu_types::IndexFormat>,
front_face: wgpu_types::FrontFace,
cull_mode: GpuCullMode,
clamp_depth: bool,
unclipped_depth: bool,
}

impl From<GpuPrimitiveState> for wgpu_types::PrimitiveState {
Expand All @@ -181,7 +181,7 @@ impl From<GpuPrimitiveState> 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
}
Expand Down
44 changes: 22 additions & 22 deletions wgpu-core/src/command/bundle.rs
Original file line number Diff line number Diff line change
@@ -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<RenderCommand>`. 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<RenderCommand>`. 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)]

Expand Down
4 changes: 2 additions & 2 deletions wgpu-core/src/device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2211,8 +2211,8 @@ impl<A: HalApi> Device<A> {
);
}

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 {
Expand Down
12 changes: 6 additions & 6 deletions wgpu-core/src/present.rs
Original file line number Diff line number Diff line change
@@ -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")]
Expand Down
2 changes: 1 addition & 1 deletion wgpu-hal/src/dx12/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion wgpu-hal/src/dx12/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1275,7 +1275,7 @@ impl crate::Device<super::Api> 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,
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 @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion wgpu-hal/src/gles/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}

Expand Down
2 changes: 1 addition & 1 deletion wgpu-hal/src/gles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ struct StencilState {
struct PrimitiveState {
front_face: u32,
cull_face: u32,
clamp_depth: bool,
unclipped_depth: bool,
}

type InvalidatedAttachments = ArrayVec<u32, { crate::MAX_COLOR_TARGETS + 2 }>;
Expand Down
7 changes: 4 additions & 3 deletions wgpu-hal/src/gles/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down Expand Up @@ -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);
Expand Down
5 changes: 3 additions & 2 deletions wgpu-hal/src/metal/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}
Expand All @@ -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
Expand Down
4 changes: 2 additions & 2 deletions wgpu-hal/src/metal/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -906,8 +906,8 @@ impl crate::Device<super::Api> 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
Expand Down
2 changes: 1 addition & 1 deletion wgpu-hal/src/metal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
Loading

0 comments on commit f25a45f

Please sign in to comment.