Zip the layer's lists against their pipelines, and stop explaining wgpu wrongly
The update loop zips all three and asserts up front that no list is left without a pipeline, instead of indexing the pipelines to get that guarantee. The comment on the data layout claimed a `None` minimum takes its value from the first pipeline built against the layout. That is not documented and does not reproduce -- one shared layout with `None` renders the tabs example correctly today. What is documented is that a stated size is checked when the bind group and pipeline are created, and `None` is checked on every draw, so that is what the comment says now. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
23fb71ee56
commit
444a2cd138
2 files changed
+11
-14
No files matched your search
+10
-14
@@ -117,24 +117,22 @@ impl UiRenderNode {
|
|||||||
}
|
}
|
||||||
let rlayer = self.layers.entry(i).or_insert_with(RenderLayer::new);
|
let rlayer = self.layers.entry(i).or_insert_with(RenderLayer::new);
|
||||||
if draws.updated {
|
if draws.updated {
|
||||||
rlayer
|
let lists = draws.primitives();
|
||||||
.primitives
|
// The zip would otherwise skip a list with no pipeline.
|
||||||
.resize_with(draws.primitives().len(), || None);
|
assert!(lists.len() <= self.primitives.len());
|
||||||
for (id, (buffers, list)) in rlayer
|
rlayer.primitives.resize_with(lists.len(), || None);
|
||||||
|
for ((buffers, list), primitive) in rlayer
|
||||||
.primitives
|
.primitives
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.zip(draws.primitives())
|
.zip(lists)
|
||||||
.enumerate()
|
.zip(&self.primitives)
|
||||||
{
|
{
|
||||||
let Some(list) = list else {
|
let Some(list) = list else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
// Indexed, not zipped: a missing pipeline should say so
|
|
||||||
// rather than quietly leave the list unbuilt.
|
|
||||||
let layout = &self.primitives[id].data_layout;
|
|
||||||
buffers
|
buffers
|
||||||
.get_or_insert_with(|| ListBuffers::new(device))
|
.get_or_insert_with(|| ListBuffers::new(device))
|
||||||
.update(device, queue, layout, list);
|
.update(device, queue, &primitive.data_layout, list);
|
||||||
}
|
}
|
||||||
draws.updated = false;
|
draws.updated = false;
|
||||||
}
|
}
|
||||||
@@ -364,9 +362,8 @@ impl UiRenderNode {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// One list's per-instance data. Each primitive needs its own, stating its
|
/// Layout for a list of one primitive's data. Stating the size rather than
|
||||||
/// own `stride`: a `None` minimum takes its value from the first pipeline
|
/// leaving it `None` is what moves the check off every draw.
|
||||||
/// built against the layout, and then holds every later one to that.
|
|
||||||
fn data_layout(device: &Device, stride: u64) -> BindGroupLayout {
|
fn data_layout(device: &Device, stride: u64) -> BindGroupLayout {
|
||||||
device.create_bind_group_layout(&BindGroupLayoutDescriptor {
|
device.create_bind_group_layout(&BindGroupLayoutDescriptor {
|
||||||
entries: &[BindGroupLayoutEntry {
|
entries: &[BindGroupLayoutEntry {
|
||||||
@@ -442,7 +439,6 @@ impl ListBuffers {
|
|||||||
self.slots.extend_from_slice(list.slots());
|
self.slots.extend_from_slice(list.slots());
|
||||||
self.instance.update(device, queue, list.instances());
|
self.instance.update(device, queue, list.instances());
|
||||||
let resized = self.data.update(device, queue, list.data());
|
let resized = self.data.update(device, queue, list.data());
|
||||||
// An empty list has no buffer big enough to bind, and nothing to draw.
|
|
||||||
if list.instances().is_empty() {
|
if list.instances().is_empty() {
|
||||||
self.group = None;
|
self.group = None;
|
||||||
} else if resized || self.group.is_none() {
|
} else if resized || self.group.is_none() {
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ impl<'a> Painter<'a> {
|
|||||||
ui.text.render(buffer, attrs, width)
|
ui.text.render(buffer, attrs, width)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: merge the text methods into the primitive ones.
|
||||||
pub fn glyphs(&mut self, text: &RenderedText, origin: UiRegion) {
|
pub fn glyphs(&mut self, text: &RenderedText, origin: UiRegion) {
|
||||||
let kind = self.rsc.ui_mut().primitives.kind::<GlyphPrimitive>();
|
let kind = self.rsc.ui_mut().primitives.kind::<GlyphPrimitive>();
|
||||||
for glyph in text.glyphs.iter() {
|
for glyph in text.glyphs.iter() {
|
||||||
|
|||||||
Reference in new issue
Block a user