mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
Improve texture caching by allowing weak refs and more formats (#4447)
* Destroy GPU textures when the last reference drops * Request pooled textures synchronously * Pool cached textures by format * Add the owned GPU buffer type * Route the remaining GPU allocations through the executor * Add weak texture parking to the texture cache * Raise the texture cache budget to 1GB for native and 512MB for wasm
This commit is contained in:
@@ -9,8 +9,7 @@ use graph_craft::document::value::{RenderOutput, RenderOutputType};
|
||||
use graphic_types::raster_types::Texture;
|
||||
use rendering::{RenderParams, SvgRender, SvgRenderOutput};
|
||||
use std::fmt::Write;
|
||||
use wgpu::util::DeviceExt;
|
||||
use wgpu_executor::{AsyncWgpuPipeline, WgpuExecutor, WgpuPipelineCache};
|
||||
use wgpu_executor::{AsyncWgpuPipeline, Buffer, WgpuExecutor, WgpuPipelineCache};
|
||||
|
||||
#[node_macro::node(category(""))]
|
||||
async fn render_background<'a: 'n>(
|
||||
@@ -342,7 +341,7 @@ impl AsyncWgpuPipeline for CompositeBackground {
|
||||
} = args;
|
||||
|
||||
let foreground_size = foreground.size();
|
||||
let output = executor.request_texture(UVec2::new(foreground_size.width, foreground_size.height)).await;
|
||||
let output = executor.request_texture(UVec2::new(foreground_size.width, foreground_size.height));
|
||||
|
||||
if zoom <= 0. {
|
||||
return output;
|
||||
@@ -360,10 +359,8 @@ impl AsyncWgpuPipeline for CompositeBackground {
|
||||
let foreground_view = foreground.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
|
||||
let checker_draws = if backgrounds.is_empty() {
|
||||
vec![(
|
||||
3,
|
||||
self.create_checker_bind_group(device, CompositeUniforms::fullscreen(viewport_size, screen_to_document, checker_size_doc)),
|
||||
)]
|
||||
let uniforms = CompositeUniforms::fullscreen(viewport_size, screen_to_document, checker_size_doc).create_buffer(executor);
|
||||
vec![(3, self.create_checker_bind_group(device, &uniforms), uniforms)]
|
||||
} else {
|
||||
backgrounds
|
||||
.iter()
|
||||
@@ -378,8 +375,8 @@ impl AsyncWgpuPipeline for CompositeBackground {
|
||||
return None;
|
||||
}
|
||||
|
||||
let uniforms = CompositeUniforms::rect(min, max, document_to_screen, viewport_size, checker_size_doc);
|
||||
Some((6, self.create_checker_bind_group(device, uniforms)))
|
||||
let uniforms = CompositeUniforms::rect(min, max, document_to_screen, viewport_size, checker_size_doc).create_buffer(executor);
|
||||
Some((6, self.create_checker_bind_group(device, &uniforms), uniforms))
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
@@ -421,13 +418,13 @@ impl AsyncWgpuPipeline for CompositeBackground {
|
||||
|
||||
if backgrounds.is_empty() {
|
||||
pass.set_pipeline(&self.checker_viewport_pipeline);
|
||||
for (vertex_count, bind_group) in &checker_draws {
|
||||
for (vertex_count, bind_group, _uniforms) in &checker_draws {
|
||||
pass.set_bind_group(0, bind_group, &[]);
|
||||
pass.draw(0..*vertex_count, 0..1);
|
||||
}
|
||||
} else {
|
||||
pass.set_pipeline(&self.checker_rect_pipeline);
|
||||
for (vertex_count, bind_group) in &checker_draws {
|
||||
for (vertex_count, bind_group, _uniforms) in &checker_draws {
|
||||
pass.set_bind_group(0, bind_group, &[]);
|
||||
pass.draw(0..*vertex_count, 0..1);
|
||||
}
|
||||
@@ -445,19 +442,13 @@ impl AsyncWgpuPipeline for CompositeBackground {
|
||||
}
|
||||
|
||||
impl CompositeBackground {
|
||||
fn create_checker_bind_group(&self, device: &wgpu::Device, uniforms: CompositeUniforms) -> wgpu::BindGroup {
|
||||
let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("background_checker_uniforms"),
|
||||
contents: bytemuck::bytes_of(&uniforms),
|
||||
usage: wgpu::BufferUsages::UNIFORM,
|
||||
});
|
||||
|
||||
fn create_checker_bind_group(&self, device: &wgpu::Device, uniforms: &Buffer) -> wgpu::BindGroup {
|
||||
device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
label: Some("background_checker_bind_group"),
|
||||
layout: &self.checker_bind_group_layout,
|
||||
entries: &[wgpu::BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: buffer.as_entire_binding(),
|
||||
resource: uniforms.as_entire_binding(),
|
||||
}],
|
||||
})
|
||||
}
|
||||
@@ -499,4 +490,12 @@ impl CompositeUniforms {
|
||||
_pad: 0.,
|
||||
}
|
||||
}
|
||||
|
||||
fn create_buffer(&self, executor: &WgpuExecutor) -> Buffer {
|
||||
executor.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("background_checker_uniforms"),
|
||||
contents: bytemuck::bytes_of(self),
|
||||
usage: wgpu::BufferUsages::UNIFORM,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,7 +391,7 @@ pub async fn render_output_cache<'a: 'n>(
|
||||
}
|
||||
|
||||
let executor = executor.into_element().expect("GPU executor not available");
|
||||
let output_texture = executor.request_texture(physical_resolution).await;
|
||||
let output_texture = executor.request_texture(physical_resolution);
|
||||
|
||||
let combined_metadata = composite_cached_regions(&all_regions, &output_texture, &device_origin_offset, &footprint.transform, executor);
|
||||
|
||||
|
||||
@@ -177,7 +177,7 @@ impl AsyncWgpuPipeline for PixelPreview {
|
||||
let context = &executor.context();
|
||||
let &PixelPreviewArgs { source, transform, size } = args;
|
||||
|
||||
let output = executor.request_texture(size).await;
|
||||
let output = executor.request_texture(size);
|
||||
|
||||
let source_view = source.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
let output_view = output.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
|
||||
Reference in New Issue
Block a user