.
diff --git a/sparse_strips/vello_hybrid/src/render/webgl/mod.rs b/sparse_strips/vello_hybrid/src/render/webgl/mod.rs index a4e3850..484cd21 100644 --- a/sparse_strips/vello_hybrid/src/render/webgl/mod.rs +++ b/sparse_strips/vello_hybrid/src/render/webgl/mod.rs
@@ -594,14 +594,14 @@ root_output_target, ); - // See: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#use_invalidateframebuffer - // We want to indicate to the GPU driver that we won't read the depth buffer again - // until the next clear. This enables the GPU to avoid storing depth tiles back to VRAM. self.gl.bind_framebuffer( WebGl2RenderingContext::FRAMEBUFFER, self.programs.resources.view_framebuffer_override.as_deref(), ); if self.programs.resources.depth_cleared_this_frame { + // See: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#use_invalidateframebuffer + // We want to indicate to the GPU driver that we won't read the depth buffer again + // until the next clear. This enables the GPU to avoid storing depth tiles back to VRAM. self.gl .invalidate_framebuffer( WebGl2RenderingContext::FRAMEBUFFER,
diff --git a/sparse_strips/vello_hybrid/src/render/wgpu/mod.rs b/sparse_strips/vello_hybrid/src/render/wgpu/mod.rs index 0845bb8..36e4189 100644 --- a/sparse_strips/vello_hybrid/src/render/wgpu/mod.rs +++ b/sparse_strips/vello_hybrid/src/render/wgpu/mod.rs
@@ -923,9 +923,7 @@ alpha_strip_pipeline: RenderPipeline, /// Root opaque-strip pipeline. opaque_strip_pipeline: RenderPipeline, - /// Depth texture for early-z rejection on the Output target. - depth_texture: Option<Texture>, - /// View for the depth texture. + /// View of the depth texture used for early-z rejection on the Output target. depth_texture_view: Option<TextureView>, /// Whether the depth buffer has been cleared this frame. depth_cleared_this_frame: bool, @@ -1731,22 +1729,19 @@ view_config_buffer, }; - let depth_texture = use_depth_buffer.then(|| { + let depth_texture_view = use_depth_buffer.then(|| { Self::create_depth_texture( device, render_target_config.width, render_target_config.height, ) + .create_view(&TextureViewDescriptor::default()) }); - let depth_texture_view = depth_texture - .as_ref() - .map(|texture| texture.create_view(&TextureViewDescriptor::default())); Self { intermediate_strip_pipeline, alpha_strip_pipeline, opaque_strip_pipeline, - depth_texture, depth_texture_view, depth_cleared_this_frame: false, strip_bind_group_layout, @@ -2417,15 +2412,15 @@ .expect("Buffer only ever holds `Config`"); buffer.copy_from_slice(bytemuck::bytes_of(&config)); - if self.depth_texture.is_some() { - let depth_texture = Self::create_depth_texture( - device, - new_render_size.width, - new_render_size.height, + if self.depth_texture_view.is_some() { + self.depth_texture_view = Some( + Self::create_depth_texture( + device, + new_render_size.width, + new_render_size.height, + ) + .create_view(&TextureViewDescriptor::default()), ); - self.depth_texture_view = - Some(depth_texture.create_view(&TextureViewDescriptor::default())); - self.depth_texture = Some(depth_texture); } self.render_size = new_render_size.clone();
diff --git a/sparse_strips/vello_hybrid/src/schedule/execute.rs b/sparse_strips/vello_hybrid/src/schedule/execute.rs index 3f7cbec..969431a 100644 --- a/sparse_strips/vello_hybrid/src/schedule/execute.rs +++ b/sparse_strips/vello_hybrid/src/schedule/execute.rs
@@ -259,7 +259,8 @@ let mut case = SceneCase::new(16, 8); case.draw_at(0.0, 1.0); chain(&mut case, depth); - case.schedule(root_target, SizeU16::new(64), 2).unwrap() + case.schedule(root_target, SizeU16::new(64), 2, true) + .unwrap() } fn round_order_case() -> ScheduledCase { @@ -294,7 +295,7 @@ }); }); - case.schedule(RootTarget::UserSurface, SizeU16::new(128), 6) + case.schedule(RootTarget::UserSurface, SizeU16::new(128), 6, true) .unwrap() } @@ -371,7 +372,9 @@ #[test] fn empty_passes_are_skipped() { let mut recorder = Recorder::default(); - SceneCase::new(16, 8).schedule_root().execute(&mut recorder); + SceneCase::new(16, 8) + .schedule_root(true) + .execute(&mut recorder); assert!(recorder.calls.is_empty()); }
diff --git a/sparse_strips/vello_hybrid/src/schedule/schedule_tests.rs b/sparse_strips/vello_hybrid/src/schedule/schedule_tests.rs index 2859e06..824334e 100644 --- a/sparse_strips/vello_hybrid/src/schedule/schedule_tests.rs +++ b/sparse_strips/vello_hybrid/src/schedule/schedule_tests.rs
@@ -75,7 +75,7 @@ |case| case.draw(Rect::new(8.0, 0.0, 16.0, 8.0), 0.5), ); }); - case.schedule_root() + case.schedule_root(true) } fn root_blend_case() -> SceneCase { @@ -130,7 +130,7 @@ let mut case = SceneCase::new(8, 8); add_chain(&mut case, depth); - case.schedule_root() + case.schedule_root(true) } fn binding_case() -> ScheduledCase { @@ -145,7 +145,7 @@ })), |case| case.draw(Rect::new(0.0, 0.0, 60.0, 60.0), 0.5), ); - case.schedule(RootTarget::UserSurface, SizeU16::new(80), 8) + case.schedule(RootTarget::UserSurface, SizeU16::new(80), 8, true) .unwrap() } @@ -167,7 +167,7 @@ #[test] fn empty_scene() { - let scheduled = SceneCase::new(32, 32).schedule_root(); + let scheduled = SceneCase::new(32, 32).schedule_root(true); assert!(scheduled.views().is_empty()); assert_eq!(scheduled.page_counts(), [0, 0]); @@ -181,7 +181,7 @@ case.draw_at(x, 0.5); } - let scheduled = case.schedule_root(); + let scheduled = case.schedule_root(true); let rounds_view = scheduled.views(); assert_eq!(rounds_view.len(), 1); @@ -197,7 +197,7 @@ case.layer(|case| case.draw_at(8.0, 0.5)); case.draw_at(16.0, 0.5); - let scheduled = case.schedule_root(); + let scheduled = case.schedule_root(true); let rounds_view = scheduled.views(); assert_eq!(rounds_view.len(), 1); @@ -213,19 +213,17 @@ } case.draw_at(24.0, 0.5); - let user = case.schedule_root(); + let user = case.schedule_root(true); assert_eq!(user.opaque_x(), [16, 8, 0]); assert_eq!(user.views()[0].root.x, [24]); let atlas = case - .schedule(RootTarget::AtlasLayer, SizeU16::new(64), 8) + .schedule(RootTarget::AtlasLayer, SizeU16::new(64), 8, true) .unwrap(); assert!(atlas.opaque_x().is_empty()); assert_eq!(atlas.views()[0].root.x, [0, 8, 16, 24]); - let without_depth = case - .schedule_with_depth(RootTarget::UserSurface, SizeU16::new(64), 8, false) - .unwrap(); + let without_depth = case.schedule_root(false); assert!(without_depth.opaque_x().is_empty()); assert_eq!(without_depth.views()[0].root.x, [0, 8, 16, 24]); } @@ -237,13 +235,11 @@ case.draw_at(x, opacity); } - let with_depth = case.schedule_root(); + let with_depth = case.schedule_root(true); assert_eq!(with_depth.opaque_x(), [16, 0]); assert_eq!(with_depth.views()[0].root.x, [8, 24]); - let without_depth = case - .schedule_with_depth(RootTarget::UserSurface, SizeU16::new(64), 8, false) - .unwrap(); + let without_depth = case.schedule_root(false); assert!(without_depth.opaque_x().is_empty()); assert_eq!(without_depth.views()[0].root.x, [0, 8, 16, 24]); } @@ -253,7 +249,7 @@ let mut case = SceneCase::new(32, 8); case.layer(|case| case.draw_at(8.0, 0.5)); - let scheduled = case.schedule_root(); + let scheduled = case.schedule_root(true); let rounds_view = scheduled.views(); let round = &rounds_view[0]; @@ -270,7 +266,7 @@ let mut case = SceneCase::new(16, 8); case.layer(|case| case.draw_at(4.0, 0.5)); - let scheduled = case.schedule_root(); + let scheduled = case.schedule_root(true); assert!(scheduled.views()[0].root.has_child_layer); assert!(scheduled.storage.buffers.blend_ops.is_empty()); @@ -301,7 +297,7 @@ ); }); - let scheduled = case.schedule_root(); + let scheduled = case.schedule_root(true); assert_eq!(scheduled.storage.buffers.filter_ops.len(), 1); assert!(scheduled.storage.buffers.blend_ops.is_empty()); @@ -327,7 +323,7 @@ // There is room for exactly one padded filter region per page. Allocating the parent therefore // advances the cursor before the clipped-away child is released. let scheduled = case - .schedule(RootTarget::UserSurface, filter_page_size(), 2) + .schedule(RootTarget::UserSurface, filter_page_size(), 2, true) .unwrap(); assert_eq!(scheduled.storage.buffers.filter_ops.len(), 1); @@ -362,7 +358,7 @@ #[test] fn root_blend_resources() { let scheduled = root_blend_case() - .schedule(RootTarget::UserSurface, SizeU16::new(16), 3) + .schedule(RootTarget::UserSurface, SizeU16::new(16), 3, true) .unwrap(); // Root lands in the first odd layer, its child in the even one. @@ -373,7 +369,7 @@ #[test] fn root_release() { let scheduled = root_blend_case() - .schedule(RootTarget::UserSurface, SizeU16::new(16), 3) + .schedule(RootTarget::UserSurface, SizeU16::new(16), 3, true) .unwrap(); let rounds_view = scheduled.views(); let root_round = rounds_view @@ -389,11 +385,11 @@ let case = root_blend_case(); assert!( - case.schedule(RootTarget::UserSurface, SizeU16::new(16), 3,) + case.schedule(RootTarget::UserSurface, SizeU16::new(16), 3, true) .is_ok() ); assert!(matches!( - case.schedule(RootTarget::UserSurface, SizeU16::new(16), 2,), + case.schedule(RootTarget::UserSurface, SizeU16::new(16), 2, true), Err(RenderError::IntermediateTexture( IntermediateTextureError::LimitReached { required: 3, @@ -410,7 +406,7 @@ case.layer(|case| case.draw_at(4.0, 0.5)); }); - let scheduled = case.schedule_root(); + let scheduled = case.schedule_root(true); let rounds_view = scheduled.views(); let round = &rounds_view[0]; @@ -460,7 +456,7 @@ case.draw_at(24.0, 0.5); }); - let scheduled = case.schedule_root(); + let scheduled = case.schedule_root(true); let rounds_view = scheduled.views(); assert_eq!(rounds_view[0].odd.x.len(), 1); @@ -479,7 +475,7 @@ } let scheduled = case - .schedule(RootTarget::UserSurface, SizeU16::from_wh(16, 8), 1) + .schedule(RootTarget::UserSurface, SizeU16::from_wh(16, 8), 1, true) .unwrap(); let rounds_view = scheduled.views(); let round = &rounds_view[0]; @@ -542,7 +538,7 @@ add_chain(&mut case, DEPTH); let scheduled = case - .schedule(RootTarget::UserSurface, SizeU16::new(8), 2) + .schedule(RootTarget::UserSurface, SizeU16::new(8), 2, true) .unwrap(); let rounds_view = scheduled.views(); let layer_draws = rounds_view @@ -568,7 +564,7 @@ add_chain(&mut case, depth); let scheduled = case - .schedule(RootTarget::UserSurface, SizeU16::new(8), 2) + .schedule(RootTarget::UserSurface, SizeU16::new(8), 2, true) .unwrap(); let textures = scheduled.page_counts().into_iter().sum::<usize>(); @@ -583,7 +579,7 @@ add_blend_chain(&mut case, depth); let scheduled = case - .schedule(RootTarget::UserSurface, SizeU16::new(8), 3) + .schedule(RootTarget::UserSurface, SizeU16::new(8), 3, true) .unwrap(); assert_eq!( @@ -598,7 +594,7 @@ fn wide_layers() { for count in 1..=32 { let scheduled = sibling_case(count) - .schedule(RootTarget::UserSurface, SizeU16::from_wh(64, 8), 1) + .schedule(RootTarget::UserSurface, SizeU16::from_wh(64, 8), 1, true) .unwrap(); let rounds_view = scheduled.views(); @@ -624,7 +620,7 @@ let mut case = SceneCase::new(8, 8); add_tree(&mut case, depth, CHILDREN); let scheduled = case - .schedule(RootTarget::UserSurface, SizeU16::new(256), 2) + .schedule(RootTarget::UserSurface, SizeU16::new(256), 2, true) .unwrap(); let layers = (CHILDREN.pow(depth.try_into().expect("test depth fits in u32")) - 1) / (CHILDREN - 1); @@ -650,7 +646,7 @@ let mut case = SceneCase::new(8, 8); add_tree(&mut case, depth, CHILDREN); let scheduled = case - .schedule(RootTarget::UserSurface, SizeU16::new(8), 16) + .schedule(RootTarget::UserSurface, SizeU16::new(8), 16, true) .unwrap(); let layers = (CHILDREN.pow(depth.try_into().expect("test depth fits in u32")) - 1) / (CHILDREN - 1); @@ -674,7 +670,7 @@ let mut case = SceneCase::new(16, 8); case.layer(|_| {}); - let scheduled = case.schedule_root(); + let scheduled = case.schedule_root(true); assert!(scheduled.views().is_empty()); assert_eq!(scheduled.page_counts(), [0, 0]); @@ -693,7 +689,7 @@ ); }); - let scheduled = case.schedule_root(); + let scheduled = case.schedule_root(true); assert_eq!(scheduled.page_counts(), [1, 1]); assert!(scheduled.scratch_texture()); @@ -707,7 +703,7 @@ clipped.layer_with(Some(clip), None, None, |case| { case.draw(Rect::new(0.0, 0.0, 24.0, 8.0), 0.5); }); - let scheduled = clipped.schedule_root(); + let scheduled = clipped.schedule_root(true); let rounds_view = scheduled.views(); assert_eq!(scheduled.page_counts(), [0, 1]); assert_eq!(rounds_view.len(), 1); @@ -722,7 +718,7 @@ disjoint.layer_with(Some(Rect::new(24.0, 0.0, 32.0, 8.0)), None, None, |case| { case.draw(Rect::new(0.0, 0.0, 8.0, 8.0), 0.5); }); - let scheduled = disjoint.schedule_root(); + let scheduled = disjoint.schedule_root(true); assert!(scheduled.views().is_empty()); assert_eq!(scheduled.page_counts(), [0, 0]); } @@ -737,7 +733,7 @@ }); let scheduled = case - .schedule(RootTarget::UserSurface, SizeU16::new(128), 2) + .schedule(RootTarget::UserSurface, SizeU16::new(128), 2, true) .unwrap(); let rounds_view = scheduled.views(); @@ -764,7 +760,7 @@ }); let scheduled = case - .schedule(RootTarget::UserSurface, SizeU16::new(64), 2) + .schedule(RootTarget::UserSurface, SizeU16::new(64), 2, true) .unwrap(); assert_eq!(scheduled.page_counts(), [1, 1]); @@ -780,7 +776,7 @@ }); let scheduled = case - .schedule(RootTarget::UserSurface, filter_page_size(), 2) + .schedule(RootTarget::UserSurface, filter_page_size(), 2, true) .unwrap(); let rounds_view = scheduled.views(); let filter = scheduled.storage.buffers.filter_ops[0]; @@ -824,7 +820,7 @@ } let scheduled = case - .schedule(RootTarget::UserSurface, filter_page_size(), 2) + .schedule(RootTarget::UserSurface, filter_page_size(), 2, true) .unwrap(); // Sibling filter layers should also reuse pages. @@ -859,7 +855,13 @@ let mut storage = ScheduleStorage::default(); let first_schedule = first - .schedule_into(&mut storage, RootTarget::UserSurface, SizeU16::new(128), 4) + .schedule_into( + &mut storage, + RootTarget::UserSurface, + SizeU16::new(128), + 4, + true, + ) .unwrap(); assert!(!storage.buffers.draw_buffers.strips.is_empty()); @@ -872,7 +874,13 @@ let mut second = SceneCase::new(64, 16); second.draw_at(48.0, 0.5); let second_schedule = second - .schedule_into(&mut storage, RootTarget::UserSurface, SizeU16::new(128), 4) + .schedule_into( + &mut storage, + RootTarget::UserSurface, + SizeU16::new(128), + 4, + true, + ) .unwrap(); assert_eq!(storage.buffers.draw_buffers.strips.len(), 1); @@ -902,7 +910,7 @@ |case| case.draw(Rect::new(4.0, 0.0, 16.0, 8.0), 0.5), ); }); - let scheduled = case.schedule_root(); + let scheduled = case.schedule_root(true); let blend = scheduled.storage.buffers.blend_ops.first().unwrap(); assert_eq!(blend.blend_bbox, blend.parent_region.layer_bbox); // This must not panic.
diff --git a/sparse_strips/vello_hybrid/src/schedule/test_support.rs b/sparse_strips/vello_hybrid/src/schedule/test_support.rs index 013c222..80cc180 100644 --- a/sparse_strips/vello_hybrid/src/schedule/test_support.rs +++ b/sparse_strips/vello_hybrid/src/schedule/test_support.rs
@@ -59,15 +59,6 @@ root_target: RootTarget, texture_size: SizeU16, max_textures: usize, - ) -> Result<ScheduledCase, RenderError> { - self.schedule_with_depth(root_target, texture_size, max_textures, true) - } - - pub(super) fn schedule_with_depth( - &self, - root_target: RootTarget, - texture_size: SizeU16, - max_textures: usize, use_depth_buffer: bool, ) -> Result<ScheduledCase, RenderError> { let mut storage = ScheduleStorage::default(); @@ -97,6 +88,7 @@ root_target: RootTarget, texture_size: SizeU16, max_textures: usize, + use_depth_buffer: bool, ) -> Result<Schedule, RenderError> { let encoded = &self.scene.encoded_paints; let offsets = vec![0; encoded.len()]; @@ -104,7 +96,7 @@ storage, &self.scene, root_target, - true, + use_depth_buffer, PaintResolver::new(encoded, &offsets), texture_size, IntermediateTextureAllocations::default(), @@ -112,9 +104,14 @@ ) } - pub(super) fn schedule_root(&self) -> ScheduledCase { - self.schedule(RootTarget::UserSurface, SizeU16::new(64), 8) - .unwrap() + pub(super) fn schedule_root(&self, use_depth_buffer: bool) -> ScheduledCase { + self.schedule( + RootTarget::UserSurface, + SizeU16::new(64), + 8, + use_depth_buffer, + ) + .unwrap() } }
diff --git a/sparse_strips/vello_sparse_tests/tests/depth.rs b/sparse_strips/vello_sparse_tests/tests/hybrid_depth.rs similarity index 100% rename from sparse_strips/vello_sparse_tests/tests/depth.rs rename to sparse_strips/vello_sparse_tests/tests/hybrid_depth.rs
diff --git a/sparse_strips/vello_sparse_tests/tests/mod.rs b/sparse_strips/vello_sparse_tests/tests/mod.rs index 99a58dc..864ff5d 100644 --- a/sparse_strips/vello_sparse_tests/tests/mod.rs +++ b/sparse_strips/vello_sparse_tests/tests/mod.rs
@@ -34,11 +34,11 @@ mod blurred_rounded_rect; mod clip; mod compose; -mod depth; mod external_texture; mod filter; mod glyph; mod gradient; +mod hybrid_depth; mod hybrid_schedule; mod image; #[cfg(all(target_arch = "wasm32", feature = "webgl"))]