-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add texture pool to render cache node #3804
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
97fcf76
ed617a4
dee4a04
2572389
ebe119e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -96,6 +96,7 @@ struct TileCacheImpl { | |
| total_memory: usize, | ||
| cache_key: CacheKey, | ||
| current_scale: f64, | ||
| texture_cache: (UVec2, Vec<Arc<wgpu::Texture>>), | ||
| } | ||
|
|
||
| impl Default for TileCacheImpl { | ||
|
|
@@ -106,6 +107,7 @@ impl Default for TileCacheImpl { | |
| total_memory: 0, | ||
| cache_key: CacheKey::default(), | ||
| current_scale: 0.0, | ||
| texture_cache: Default::default(), | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -224,6 +226,36 @@ impl TileCacheImpl { | |
| self.regions.clear(); | ||
| self.total_memory = 0; | ||
| } | ||
|
|
||
| pub fn request_texture(&mut self, size: UVec2, device: &wgpu::Device) -> Arc<wgpu::Texture> { | ||
| if self.texture_cache.0 != size { | ||
| self.texture_cache.0 = size; | ||
| self.texture_cache.1.clear(); | ||
| } | ||
| self.texture_cache.1.truncate(5); | ||
| for texture in &self.texture_cache.1 { | ||
| if Arc::strong_count(&texture) == 1 { | ||
| return Arc::clone(texture); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Reused textures from the pool retain stale pixel data from the previous frame. Unlike a freshly allocated texture, a pooled texture contains actual rendered content. Since Prompt for AI agents |
||
| } | ||
| } | ||
| let texture = Arc::new(device.create_texture(&wgpu::TextureDescriptor { | ||
| label: Some("viewport_output"), | ||
| size: wgpu::Extent3d { | ||
| width: size.x, | ||
| height: size.y, | ||
| depth_or_array_layers: 1, | ||
| }, | ||
| mip_level_count: 1, | ||
| sample_count: 1, | ||
| dimension: wgpu::TextureDimension::D2, | ||
| format: wgpu::TextureFormat::Rgba8Unorm, | ||
| usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::COPY_DST | wgpu::TextureUsages::COPY_SRC | wgpu::TextureUsages::TEXTURE_BINDING, | ||
| view_formats: &[], | ||
| })); | ||
| self.texture_cache.1.push(texture.clone()); | ||
|
|
||
| texture | ||
| } | ||
| } | ||
|
|
||
| impl TileCache { | ||
|
|
@@ -234,6 +266,10 @@ impl TileCache { | |
| pub fn store_regions(&self, regions: Vec<CachedRegion>) { | ||
| self.0.lock().unwrap().store_regions(regions); | ||
| } | ||
|
|
||
| pub fn request_texture(&self, size: UVec2, device: &wgpu::Device) -> Arc<wgpu::Texture> { | ||
| self.0.lock().unwrap().request_texture(size, device) | ||
| } | ||
| } | ||
|
|
||
| fn group_into_regions(tiles: &[TileCoord], scale: f64, max_region_area: u32) -> Vec<RenderRegion> { | ||
|
|
@@ -421,7 +457,11 @@ pub async fn render_output_cache<'a: 'n>( | |
| } | ||
|
|
||
| let exec = editor_api.application_io.as_ref().unwrap().gpu_executor().unwrap(); | ||
| let (output_texture, combined_metadata) = composite_cached_regions(&all_regions, &viewport_bounds, physical_resolution, logical_scale, physical_scale, exec); | ||
|
|
||
| let device = &exec.context.device; | ||
| let output_texture = tile_cache.request_texture(physical_resolution, device); | ||
|
|
||
| let combined_metadata = composite_cached_regions(&all_regions, &viewport_bounds, output_texture.as_ref(), logical_scale, physical_scale, exec); | ||
|
|
||
| RenderOutput { | ||
| data: RenderOutputType::Texture(ImageTexture { texture: output_texture }), | ||
|
|
@@ -475,7 +515,7 @@ where | |
| let memory_size = (region_pixel_size.x * region_pixel_size.y) as usize * BYTES_PER_PIXEL; | ||
|
|
||
| CachedRegion { | ||
| texture: rendered_texture.texture, | ||
| texture: rendered_texture.texture.as_ref().clone(), | ||
| texture_size: region_pixel_size, | ||
| scene_bounds: region.scene_bounds.clone(), | ||
| tiles: region.tiles.clone(), | ||
|
|
@@ -488,29 +528,14 @@ where | |
| fn composite_cached_regions( | ||
| regions: &[CachedRegion], | ||
| viewport_bounds: &AxisAlignedBbox, | ||
| output_resolution: UVec2, | ||
| output_texture: &wgpu::Texture, | ||
| logical_scale: f64, | ||
| physical_scale: f64, | ||
| exec: &wgpu_executor::WgpuExecutor, | ||
| ) -> (wgpu::Texture, rendering::RenderMetadata) { | ||
| ) -> rendering::RenderMetadata { | ||
| let device = &exec.context.device; | ||
| let queue = &exec.context.queue; | ||
|
|
||
| // TODO: Use texture pool to reuse existing unused textures instead of allocating fresh ones every time | ||
| let output_texture = device.create_texture(&wgpu::TextureDescriptor { | ||
| label: Some("viewport_output"), | ||
| size: wgpu::Extent3d { | ||
| width: output_resolution.x, | ||
| height: output_resolution.y, | ||
| depth_or_array_layers: 1, | ||
| }, | ||
| mip_level_count: 1, | ||
| sample_count: 1, | ||
| dimension: wgpu::TextureDimension::D2, | ||
| format: wgpu::TextureFormat::Rgba8Unorm, | ||
| usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::COPY_DST | wgpu::TextureUsages::COPY_SRC | wgpu::TextureUsages::TEXTURE_BINDING, | ||
| view_formats: &[], | ||
| }); | ||
| let output_resolution = UVec2::new(output_texture.width(), output_texture.height()); | ||
|
|
||
| let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: Some("composite") }); | ||
| let mut combined_metadata = rendering::RenderMetadata::default(); | ||
|
|
@@ -570,5 +595,5 @@ fn composite_cached_regions( | |
| } | ||
|
|
||
| queue.submit([encoder.finish()]); | ||
| (output_texture, combined_metadata) | ||
| combined_metadata | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.