dont cache passes

This commit is contained in:
galister 2026-05-27 16:48:25 +09:00
parent 0666bbd668
commit b398880fa9
3 changed files with 62 additions and 95 deletions

View File

@ -14,10 +14,9 @@ use vulkano::{
use crate::{
drawing::{Boundary, ImagePrimitive},
gfx::{
BLEND_ALPHA, WGfx,
cmd::GfxCommandBuffer,
pass::WGfxPass,
pipeline::{WGfxPipeline, WPipelineCreateInfo},
WGfx, BLEND_ALPHA,
},
renderer_vk::{
model_buffer::ModelBuffer,
@ -71,10 +70,10 @@ struct ImageVertexWithContent {
content_key: usize, // identifies an image tag.
}
struct CachedPass {
struct CachedView {
content_id: usize,
vert_buffer: Subbuffer<[ImageVertex]>,
inner: WGfxPass<ImageVertex>,
view: Arc<ImageView>,
res: [u32; 2],
}
@ -82,7 +81,7 @@ pub struct ImageRenderer {
pipeline: ImagePipeline,
image_verts: Vec<ImageVertexWithContent>,
model_buffer: ModelBuffer,
cached_passes: HashMap<usize, CachedPass>,
cached_views: HashMap<usize, CachedView>,
}
impl ImageRenderer {
@ -91,7 +90,7 @@ impl ImageRenderer {
model_buffer: ModelBuffer::new(&pipeline.gfx)?,
pipeline,
image_verts: vec![],
cached_passes: HashMap::new(),
cached_views: HashMap::new(),
})
}
@ -164,17 +163,14 @@ impl ImageRenderer {
self.model_buffer.upload(gfx)?;
for img in &self.image_verts {
let pass = if let Some(x) = self.cached_passes.get_mut(&img.content_key) {
let cached_view = if let Some(x) = self.cached_views.get_mut(&img.content_key) {
if x.content_id != img.content.id || x.res != res {
// image changed
let Some(image_view) = Self::upload_image(&self.pipeline.gfx, res, img)? else {
let Some(view) = Self::upload_image(&self.pipeline.gfx, res, img)? else {
continue;
};
x.inner
.update_sampler(2, image_view, self.pipeline.gfx.texture_filter)?;
x.view = view;
}
x
} else {
let vert_buffer = self.pipeline.gfx.empty_buffer(
@ -182,42 +178,43 @@ impl ImageRenderer {
(std::mem::size_of::<ImageVertex>()) as _,
)?;
let Some(image_view) = Self::upload_image(&self.pipeline.gfx, res, img)? else {
let Some(view) = Self::upload_image(&self.pipeline.gfx, res, img)? else {
continue;
};
let set0 = viewport.get_image_descriptor(&self.pipeline);
let set1 = self.model_buffer.get_image_descriptor(&self.pipeline);
let set2 = self
.pipeline
.inner
.uniform_sampler(2, image_view, self.pipeline.gfx.texture_filter)?;
let pass = self.pipeline.inner.create_pass(
[res[0] as _, res[1] as _],
[0.0, 0.0],
vert_buffer.clone(),
0..4,
0..1,
vec![set0, set1, set2],
vk_scissor,
)?;
self.cached_passes.insert(
self.cached_views.insert(
img.content_key,
CachedPass {
CachedView {
content_id: img.content.id,
vert_buffer,
inner: pass,
view,
res,
},
);
self.cached_passes.get_mut(&img.content_key).unwrap()
self.cached_views.get_mut(&img.content_key).unwrap() // safe
};
pass.vert_buffer.write()?[0..1].clone_from_slice(&[img.vert]);
let set0 = viewport.get_image_descriptor(&self.pipeline);
let set1 = self.model_buffer.get_image_descriptor(&self.pipeline);
let set2 = self
.pipeline
.inner
.uniform_sampler(2, cached_view.view.clone(), self.pipeline.gfx.texture_filter)?;
cmd_buf.run_ref(&pass.inner)?;
let pass = self.pipeline.inner.create_pass(
[res[0] as _, res[1] as _],
[0.0, 0.0],
cached_view.vert_buffer.clone(),
0..4,
0..1,
vec![set0, set1, set2],
vk_scissor,
)?;
cached_view.vert_buffer.write()?[0..1].clone_from_slice(&[img.vert]);
cmd_buf.run_ref(&pass)?;
}
Ok(())

View File

@ -11,7 +11,6 @@ use crate::{
drawing::{Boundary, Rectangle},
gfx::{
cmd::GfxCommandBuffer,
pass::WGfxPass,
pipeline::{WGfxPipeline, WPipelineCreateInfo},
WGfx, BLEND_ALPHA,
},
@ -59,18 +58,12 @@ impl RectPipeline {
}
}
struct CachedPass {
pass: WGfxPass<RectVertex>,
res: [u32; 2],
}
pub struct RectRenderer {
pipeline: RectPipeline,
rect_vertices: Vec<RectVertex>,
vert_buffer: Subbuffer<[RectVertex]>,
vert_buffer_len: usize,
model_buffer: ModelBuffer,
pass: Option<CachedPass>,
}
impl RectRenderer {
@ -88,7 +81,6 @@ impl RectRenderer {
rect_vertices: vec![],
vert_buffer,
vert_buffer_len: BUFFER_SIZE,
pass: None,
})
}
@ -144,27 +136,20 @@ impl RectRenderer {
self.model_buffer.upload(gfx)?;
self.upload_verts()?;
let cache = match self.pass.take() {
Some(p) if p.res == res => p,
_ => {
let set0 = viewport.get_rect_descriptor(&self.pipeline);
let set1 = self.model_buffer.get_rect_descriptor(&self.pipeline);
let pass = self.pipeline.color_rect.create_pass(
[res[0] as _, res[1] as _],
[0.0, 0.0],
self.vert_buffer.clone(),
0..4,
0..self.rect_vertices.len() as _,
vec![set0, set1],
vk_scissor,
)?;
CachedPass { pass, res }
}
};
let set0 = viewport.get_rect_descriptor(&self.pipeline);
let set1 = self.model_buffer.get_rect_descriptor(&self.pipeline);
let pass = self.pipeline.color_rect.create_pass(
[res[0] as _, res[1] as _],
[0.0, 0.0],
self.vert_buffer.clone(),
0..4,
0..self.rect_vertices.len() as _,
vec![set0, set1],
vk_scissor,
)?;
self.rect_vertices.clear();
cmd_buf.run_ref(&cache.pass)?;
self.pass = Some(cache);
cmd_buf.run_ref(&pass)?;
Ok(())
}
}

View File

@ -1,5 +1,5 @@
use crate::{
gfx::{cmd::GfxCommandBuffer, pass::WGfxPass},
gfx::cmd::GfxCommandBuffer,
renderer_vk::{model_buffer::ModelBuffer, text::text_atlas::TEXT_ATLAS_ISLAND_PADDING_PX, viewport::Viewport},
};
@ -17,11 +17,6 @@ use vulkano::{
pipeline::graphics,
};
struct CachedPass {
pass: WGfxPass<GlyphVertex>,
res: [u32; 2],
}
/// A text renderer that uses cached glyphs to render text into an existing render pass.
pub struct TextRenderer {
pipeline: TextPipeline,
@ -29,7 +24,6 @@ pub struct TextRenderer {
vertex_buffer_capacity: usize,
glyph_vertices: Vec<GlyphVertex>,
model_buffer: ModelBuffer,
pass: Option<CachedPass>,
}
impl TextRenderer {
@ -49,14 +43,12 @@ impl TextRenderer {
vertex_buffer,
vertex_buffer_capacity: INITIAL_CAPACITY,
glyph_vertices: Vec::new(),
pass: None,
})
}
pub fn begin(&mut self) {
self.glyph_vertices.clear();
self.model_buffer.begin();
self.pass.take(); // FIXME: this currently makes 0 sense
}
/// Prepares all of the provided text areas for rendering.
@ -265,31 +257,24 @@ impl TextRenderer {
let res = viewport.resolution();
self.model_buffer.upload(&atlas.common.gfx)?;
let cache = match self.pass.take() {
Some(p) if p.res == res => p,
_ => {
let descriptor_sets = vec![
atlas.color_atlas.image_descriptor.clone(),
atlas.mask_atlas.image_descriptor.clone(),
viewport.get_text_descriptor(&self.pipeline),
self.model_buffer.get_text_descriptor(&self.pipeline),
];
let descriptor_sets = vec![
atlas.color_atlas.image_descriptor.clone(),
atlas.mask_atlas.image_descriptor.clone(),
viewport.get_text_descriptor(&self.pipeline),
self.model_buffer.get_text_descriptor(&self.pipeline),
];
let pass = self.pipeline.inner.create_pass(
[res[0] as _, res[1] as _],
[0.0, 0.0],
self.vertex_buffer.clone(),
0..4,
0..self.glyph_vertices.len() as u32,
descriptor_sets,
vk_scissor,
)?;
CachedPass { pass, res }
}
};
let pass = self.pipeline.inner.create_pass(
[res[0] as _, res[1] as _],
[0.0, 0.0],
self.vertex_buffer.clone(),
0..4,
0..self.glyph_vertices.len() as u32,
descriptor_sets,
vk_scissor,
)?;
cmd_buf.run_ref(&cache.pass)?;
self.pass = Some(cache);
cmd_buf.run_ref(&pass)?;
Ok(())
}
}