Skip to content
Open
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
130 changes: 51 additions & 79 deletions vello_gpu/src/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ impl LayerTextureRegion {
}

/// Number of external textures that can be sampled by one strip draw.
pub(crate) const EXTERNAL_TEXTURE_SLOT_COUNT: usize = 4;
pub(crate) const EXTERNAL_TEXTURE_SLOT_COUNT: usize = 1;

/// External texture bindings for one strip draw.
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
Expand All @@ -461,7 +461,7 @@ impl ExternalTextureBindings {
};

/// Return the existing slot for `texture_source`, or insert it into the first empty slot.
/// Returns `None` when all four slots are occupied by other textures.
/// Returns `None` when the slot is occupied by another texture.
#[inline]
fn get_or_insert(&mut self, texture_source: TextureSourceId) -> Option<u8> {
// This iteration order assumes slots are assigned without leaving "holes" in-between,
Expand Down Expand Up @@ -684,7 +684,12 @@ mod tests {
texture_ids().map(TextureSourceId::External)
}

fn run_states(runs: &[ExternalTextureRun]) -> Vec<([Option<TextureSourceId>; 4], usize)> {
fn run_states(
runs: &[ExternalTextureRun],
) -> Vec<(
[Option<TextureSourceId>; super::EXTERNAL_TEXTURE_SLOT_COUNT],
usize,
)> {
runs.iter()
.map(|run| (run.bindings.as_array(), run.strips_start))
.collect()
Expand Down Expand Up @@ -754,15 +759,11 @@ mod tests {

assert_eq!(
run_states(&draw.external_texture_runs),
[(
[
Some(TextureSourceId::External(texture_a)),
Some(TextureSourceId::External(texture_b)),
None,
None,
],
0,
)]
[
([Some(TextureSourceId::External(texture_a))], 0),
([Some(TextureSourceId::External(texture_b))], 2),
([Some(TextureSourceId::External(texture_a))], 4),
]
);
}

Expand All @@ -787,24 +788,12 @@ mod tests {
assert_eq!(
run_states(&draw.external_texture_runs),
[
(
[
Some(TextureSourceId::External(textures[0])),
Some(TextureSourceId::External(textures[1])),
Some(TextureSourceId::External(textures[2])),
Some(TextureSourceId::External(textures[3]))
],
0
),
(
[
Some(TextureSourceId::External(textures[4])),
Some(TextureSourceId::External(textures[0])),
None,
None,
],
4,
),
([Some(TextureSourceId::External(textures[0]))], 0),
([Some(TextureSourceId::External(textures[1]))], 1),
([Some(TextureSourceId::External(textures[2]))], 2),
([Some(TextureSourceId::External(textures[3]))], 3),
([Some(TextureSourceId::External(textures[4]))], 4),
([Some(TextureSourceId::External(textures[0]))], 5),
]
);
assert_eq!(
Expand All @@ -813,7 +802,7 @@ mod tests {
.iter()
.map(|strip| (strip.paint_and_rect_flag >> EXTERNAL_TEXTURE_SLOT_SHIFT) & 0x3)
.collect::<Vec<_>>(),
[0, 1, 2, 3, 0, 1]
[0, 0, 0, 0, 0, 0]
);
}

Expand All @@ -830,10 +819,7 @@ mod tests {

assert_eq!(
run_states(&draw.external_texture_runs),
[(
[Some(TextureSourceId::External(texture)), None, None, None],
0,
)]
[([Some(TextureSourceId::External(texture))], 0)]
);
}

Expand All @@ -853,15 +839,13 @@ mod tests {

assert_eq!(draw.strip_ranges.len(), 3);
assert_eq!(
draw.external_texture_runs[0].bindings.as_array(),
run_states(&draw.external_texture_runs),
[
Some(TextureSourceId::External(texture)),
Some(TextureSourceId::Atlas(AtlasId::new(0))),
None,
None,
([Some(TextureSourceId::External(texture))], 0),
([Some(TextureSourceId::Atlas(AtlasId::new(0)))], 1),
([Some(TextureSourceId::External(texture))], 2),
]
);
assert_eq!(draw.external_texture_runs[0].strips_start, 0);
}

#[test]
Expand Down Expand Up @@ -908,25 +892,19 @@ mod tests {
assert_eq!(
run_states(draw.external_texture_runs()),
[
(
[
Some(textures[0]),
Some(textures[1]),
Some(textures[2]),
Some(textures[3]),
],
0,
),
(
[
Some(textures[4]),
Some(textures[0]),
Some(textures[5]),
Some(textures[6]),
],
19,
),
([Some(textures[7]), Some(textures[1]), None, None], 28,),
([Some(textures[0])], 0),
([Some(textures[1])], 6),
([Some(textures[2])], 8),
([Some(textures[0])], 13),
([Some(textures[1])], 15),
([Some(textures[3])], 16),
([Some(textures[0])], 18),
([Some(textures[4])], 19),
([Some(textures[0])], 22),
([Some(textures[5])], 23),
([Some(textures[6])], 26),
([Some(textures[7])], 28),
([Some(textures[1])], 30),
]
);
let original_slots = external_texture_slots(&draw);
Expand All @@ -941,25 +919,19 @@ mod tests {
assert_eq!(
run_states(draw.external_texture_runs()),
[
([Some(textures[7]), Some(textures[1]), None, None], 0,),
(
[
Some(textures[4]),
Some(textures[0]),
Some(textures[5]),
Some(textures[6]),
],
4,
),
(
[
Some(textures[0]),
Some(textures[1]),
Some(textures[2]),
Some(textures[3]),
],
13,
),
([Some(textures[1])], 0),
([Some(textures[7])], 2),
([Some(textures[6])], 4),
([Some(textures[5])], 6),
([Some(textures[0])], 9),
([Some(textures[4])], 10),
([Some(textures[0])], 13),
([Some(textures[3])], 14),
([Some(textures[1])], 16),
([Some(textures[0])], 17),
([Some(textures[2])], 19),
([Some(textures[1])], 24),
([Some(textures[0])], 26),
]
);
}
Expand Down
18 changes: 6 additions & 12 deletions vello_gpu/src/render/webgl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2128,12 +2128,7 @@ fn get_strip_uniforms(
let encoded_paints_texture_vs_name = render::vertex::ENCODED_PAINTS_TEXTURE;
let gradient_texture_name = render::fragment::GRADIENT_TEXTURE;
// TODO: Change it so this is based on `EXTERNAL_TEXTURE_SLOT_COUNT`.
let external_texture_names = [
render::fragment::EXTERNAL_TEXTURE_0,
render::fragment::EXTERNAL_TEXTURE_1,
render::fragment::EXTERNAL_TEXTURE_2,
render::fragment::EXTERNAL_TEXTURE_3,
];
let external_texture_names = [render::fragment::EXTERNAL_TEXTURE_0];

Ok(StripUniforms {
config_vs_block_index,
Expand All @@ -2151,12 +2146,11 @@ fn get_strip_uniforms(
encoded_paints_texture_vs_name,
)?,
gradient_texture: required_uniform_location(gl, program, gradient_texture_name)?,
external_textures: [
required_uniform_location(gl, program, external_texture_names[0])?,
required_uniform_location(gl, program, external_texture_names[1])?,
required_uniform_location(gl, program, external_texture_names[2])?,
required_uniform_location(gl, program, external_texture_names[3])?,
],
external_textures: [required_uniform_location(
gl,
program,
external_texture_names[0],
)?],
})
}

Expand Down
29 changes: 5 additions & 24 deletions vello_gpu/src/render/wgpu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1138,12 +1138,7 @@ impl Programs {
},
count: None,
};
let external_texture_layout_entries = [
external_texture_layout_entry(0),
external_texture_layout_entry(1),
external_texture_layout_entry(2),
external_texture_layout_entry(3),
];
let external_texture_layout_entries = [external_texture_layout_entry(0)];
let external_texture_bind_group_layout =
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
label: Some("External Texture Bind Group Layout"),
Expand Down Expand Up @@ -2033,24 +2028,10 @@ impl Programs {
external_texture_bind_group_layout: &BindGroupLayout,
texture_views: [&TextureView; EXTERNAL_TEXTURE_SLOT_COUNT],
) -> BindGroup {
let entries = [
wgpu::BindGroupEntry {
binding: 0,
resource: wgpu::BindingResource::TextureView(texture_views[0]),
},
wgpu::BindGroupEntry {
binding: 1,
resource: wgpu::BindingResource::TextureView(texture_views[1]),
},
wgpu::BindGroupEntry {
binding: 2,
resource: wgpu::BindingResource::TextureView(texture_views[2]),
},
wgpu::BindGroupEntry {
binding: 3,
resource: wgpu::BindingResource::TextureView(texture_views[3]),
},
];
let entries = [wgpu::BindGroupEntry {
binding: 0,
resource: wgpu::BindingResource::TextureView(texture_views[0]),
}];
device.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("External Texture Bind Group"),
layout: external_texture_bind_group_layout,
Expand Down
54 changes: 8 additions & 46 deletions vello_gpu_shaders/shaders/render.wesl
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ struct Config {
// - Bits 0-25:
// - If paint_type = 0: unused
// - Bits 0-23: `paint_texture_idx` for every non-solid paint
// - Bits 24-25: external texture slot for external images; unused otherwise
// - Bits 24-25: reserved
//
// When color_source = 1 (COLOR_SOURCE_LAYER):
// - Bits 0-7: opacity (0-255)
Expand Down Expand Up @@ -216,15 +216,6 @@ var<uniform> config: Config;
@group(1) @binding(0)
var external_texture_0: texture_2d<f32>;

@group(1) @binding(1)
var external_texture_1: texture_2d<f32>;

@group(1) @binding(2)
var external_texture_2: texture_2d<f32>;

@group(1) @binding(3)
var external_texture_3: texture_2d<f32>;

@group(2) @binding(0)
var encoded_paints_texture: texture_2d<u32>;

Expand Down Expand Up @@ -412,43 +403,14 @@ fn fs_main(
// TODO: add a fast path for images where we are using bilinear sampling and want transparent pixels,
// using GPU-native bilinear sampling

var sample_color: vec4<f32>;
let external_texture_slot =
(paint_and_rect_flag >> EXTERNAL_TEXTURE_SLOT_SHIFT) & 0x3u;
let final_xy = image_offset + extended_xy;
if external_texture_slot == 0u {
sample_color = sample_external_image(
external_texture_0,
image_quality,
final_xy,
image_offset,
image_size,
);
} else if external_texture_slot == 1u {
sample_color = sample_external_image(
external_texture_1,
image_quality,
final_xy,
image_offset,
image_size,
);
} else if external_texture_slot == 2u {
sample_color = sample_external_image(
external_texture_2,
image_quality,
final_xy,
image_offset,
image_size,
);
} else {
sample_color = sample_external_image(
external_texture_3,
image_quality,
final_xy,
image_offset,
image_size,
);
}
let sample_color = sample_external_image(
external_texture_0,
image_quality,
final_xy,
image_offset,
image_size,
);

final_color = alpha * select(
image_tint * sample_color.a,
Expand Down
Loading