mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-22 06:44:14 +00:00
Evolve depth clamping into clip control (#2171)
This commit is contained in:
parent
27aae2a2a2
commit
f25a45f4e2
@ -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<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
|
||||
}
|
||||
|
@ -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 {
|
||||
@ -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
|
||||
}
|
||||
|
@ -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)]
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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")]
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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(
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 }>;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)]
|
||||
|
@ -22,6 +22,7 @@ pub struct PhysicalDeviceFeatures {
|
||||
timeline_semaphore: Option<vk::PhysicalDeviceTimelineSemaphoreFeaturesKHR>,
|
||||
image_robustness: Option<vk::PhysicalDeviceImageRobustnessFeaturesEXT>,
|
||||
robustness2: Option<vk::PhysicalDeviceRobustness2FeaturesEXT>,
|
||||
depth_clip_enable: Option<vk::PhysicalDeviceDepthClipEnableFeaturesEXT>,
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
|
@ -1382,7 +1382,6 @@ impl crate::Device<super::Api> 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<super::Api> 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 {
|
||||
|
@ -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<Face>,
|
||||
/// 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.
|
||||
|
@ -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 {
|
||||
|
@ -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),
|
||||
(
|
||||
|
Loading…
Reference in New Issue
Block a user