Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions wgpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,13 +293,13 @@ impl Renderer {
for layer in self.layers.iter() {
let clip_bounds = layer.bounds * scale_factor;

if physical_bounds
let Some(layer_bounds) = physical_bounds
.intersection(&clip_bounds)
.and_then(Rectangle::snap)
.is_none()
{
.map(Rectangle::<f32>::from)
else {
continue;
}
};

if !layer.quads.is_empty() {
let prepare_span = debug::prepare(debug::Primitive::Quad);
Expand All @@ -326,6 +326,7 @@ impl Renderer {
&mut self.staging_belt,
encoder,
&layer.triangles,
layer_bounds,
Transformation::scale(scale_factor),
viewport.physical_size(),
);
Expand Down
14 changes: 14 additions & 0 deletions wgpu/src/shader/triangle.wgsl
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
struct Globals {
transform: mat4x4<f32>,
clip_bounds: vec4<f32>,
}

@group(0) @binding(0) var<uniform> globals: Globals;

fn discard_if_clipped(position: vec4<f32>) {
let pixel = position.xy;

if (
pixel.x < globals.clip_bounds.x ||
pixel.y < globals.clip_bounds.y ||
pixel.x >= globals.clip_bounds.z ||
pixel.y >= globals.clip_bounds.w
) {
discard;
}
}
2 changes: 2 additions & 0 deletions wgpu/src/shader/triangle/gradient.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ fn gradient(

@fragment
fn gradient_fs_main(input: GradientVertexOutput) -> @location(0) vec4<f32> {
discard_if_clipped(input.position);

let colors = array<vec4<f32>, 8>(
unpack_color(input.colors_1.xy),
unpack_color(input.colors_1.zw),
Expand Down
2 changes: 2 additions & 0 deletions wgpu/src/shader/triangle/solid.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,7 @@ fn solid_vs_main(input: SolidVertexInput) -> SolidVertexOutput {

@fragment
fn solid_fs_main(input: SolidVertexOutput) -> @location(0) vec4<f32> {
discard_if_clipped(input.position);

return input.color;
}
58 changes: 46 additions & 12 deletions wgpu/src/triangle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub enum Item {
struct Upload {
layer: Layer,
transformation: Transformation,
bounds: Rectangle,
version: usize,
batch: Arc<[Mesh]>,
}
Expand Down Expand Up @@ -62,12 +63,16 @@ impl Storage {
gradient: &gradient::Pipeline,
cache: &mesh::Cache,
new_transformation: Transformation,
new_bounds: Rectangle,
screen_transformation: Transformation,
) {
match self.uploads.entry(cache.id()) {
hash_map::Entry::Occupied(entry) => {
let upload = entry.into_mut();

if upload.version != cache.version() || upload.transformation != new_transformation
if upload.version != cache.version()
|| upload.transformation != new_transformation
|| upload.bounds != new_bounds
{
if !cache.is_empty() {
upload.layer.prepare(
Expand All @@ -78,12 +83,15 @@ impl Storage {
gradient,
cache.batch(),
new_transformation,
new_bounds,
screen_transformation,
);
}

upload.batch = cache.batch().clone();
upload.version = cache.version();
upload.transformation = new_transformation;
upload.bounds = new_bounds;
}
}
hash_map::Entry::Vacant(entry) => {
Expand All @@ -97,12 +105,15 @@ impl Storage {
gradient,
cache.batch(),
new_transformation,
new_bounds,
screen_transformation,
);

let _ = entry.insert(Upload {
layer,
transformation: new_transformation,
version: 0,
bounds: new_bounds,
version: cache.version(),
batch: cache.batch().clone(),
});

Expand Down Expand Up @@ -155,14 +166,15 @@ impl State {
belt: &mut wgpu::util::StagingBelt,
encoder: &mut wgpu::CommandEncoder,
items: &[Item],
bounds: Rectangle,
scale: Transformation,
target_size: Size<u32>,
) {
let projection =
if let Some((state, pipeline)) = self.msaa.as_mut().zip(pipeline.msaa.as_ref()) {
state.prepare(device, encoder, belt, pipeline, target_size) * scale
state.prepare(device, encoder, belt, pipeline, target_size)
} else {
Transformation::orthographic(target_size.width, target_size.height) * scale
Transformation::orthographic(target_size.width, target_size.height)
};

for item in items {
Expand All @@ -171,6 +183,8 @@ impl State {
transformation,
meshes,
} => {
let screen_transformation = scale * *transformation;

if self.layers.len() <= self.prepare_layer {
self.layers
.push(Layer::new(device, &pipeline.solid, &pipeline.gradient));
Expand All @@ -184,7 +198,9 @@ impl State {
&pipeline.solid,
&pipeline.gradient,
meshes,
projection * *transformation,
projection * screen_transformation,
bounds,
screen_transformation,
);

self.prepare_layer += 1;
Expand All @@ -193,14 +209,18 @@ impl State {
transformation,
cache,
} => {
let screen_transformation = scale * *transformation;

self.storage.prepare(
device,
encoder,
belt,
&pipeline.solid,
&pipeline.gradient,
cache,
projection * *transformation,
projection * screen_transformation,
bounds,
screen_transformation,
);
}
}
Expand Down Expand Up @@ -359,6 +379,8 @@ impl Layer {
gradient: &gradient::Pipeline,
meshes: &[Mesh],
transformation: Transformation,
bounds: Rectangle,
screen_transformation: Transformation,
) {
// Count the total amount of vertices & indices we need to handle
let count = mesh::attribute_count_of(meshes);
Expand Down Expand Up @@ -394,19 +416,24 @@ impl Layer {
let mut index_offset = 0;

for mesh in meshes {
let clip_bounds = mesh.clip_bounds() * transformation;
let snap_distance = clip_bounds
let transformed_clip_bounds = mesh.clip_bounds() * transformation;
let snap_distance = transformed_clip_bounds
.snap()
.map(|snapped_bounds| {
Point::new(snapped_bounds.x as f32, snapped_bounds.y as f32)
- clip_bounds.position()
- transformed_clip_bounds.position()
})
.unwrap_or(Vector::ZERO);

let clip_bounds = bounds
.intersection(&(mesh.clip_bounds() * screen_transformation))
.unwrap_or_default();

let uniforms = Uniforms::new(
transformation
* mesh.transformation()
* Transformation::translate(snap_distance.x, snap_distance.y),
clip_bounds,
);

let indices = mesh.indices();
Expand Down Expand Up @@ -579,16 +606,23 @@ fn multisample_state(antialiasing: Option<Antialiasing>) -> wgpu::MultisampleSta
#[repr(C)]
pub struct Uniforms {
transform: [f32; 16],
clip_bounds: [f32; 4],
/// Uniform values must be 256-aligned;
/// see: [`wgpu::Limits`] `min_uniform_buffer_offset_alignment`.
_padding: [f32; 48],
_padding: [f32; 44],
}

impl Uniforms {
pub fn new(transform: Transformation) -> Self {
pub fn new(transform: Transformation, clip_bounds: Rectangle) -> Self {
Self {
transform: transform.into(),
_padding: [0.0; 48],
clip_bounds: [
clip_bounds.x,
clip_bounds.y,
clip_bounds.x + clip_bounds.width,
clip_bounds.y + clip_bounds.height,
],
_padding: [0.0; 44],
}
}

Expand Down
19 changes: 19 additions & 0 deletions wgpu/src/triangle/msaa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,25 @@ impl Pipeline {
let targets = self.targets.read().expect("Read MSAA targets");
let targets = targets.as_ref().unwrap();

{
let _clear_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("iced_wgpu.triangle.resolve.clear_pass"),
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view: &targets.resolve,
depth_slice: None,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT),
store: wgpu::StoreOp::Store,
},
})],
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});
}

encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("iced_wgpu.triangle.render_pass"),
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
Expand Down
11 changes: 5 additions & 6 deletions wgpu/src/window/compositor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,11 @@ impl Compositor {

log::info!("Available alpha modes: {alpha_modes:#?}");

let preferred_alpha =
if alpha_modes.contains(&wgpu::CompositeAlphaMode::PreMultiplied) {
wgpu::CompositeAlphaMode::PreMultiplied
} else {
wgpu::CompositeAlphaMode::Auto
};
let preferred_alpha = if alpha_modes.contains(&wgpu::CompositeAlphaMode::Opaque) {
wgpu::CompositeAlphaMode::Opaque
} else {
wgpu::CompositeAlphaMode::Auto
};

format.zip(Some(preferred_alpha))
})
Expand Down