Re-add upload texture (#2915)

* vello: code cleanup of resource overwrites

* upload_texture: upload cpu textures as SRGBA8

* vello: fix wgpu::Texture leak within vello's `context.resource_overrides` HashMap

* fix missing feature gate
This commit is contained in:
Firestar99
2025-07-24 12:51:03 +02:00
committed by GitHub
parent 0d43ad2ea0
commit 2d11d96b4a
6 changed files with 161 additions and 24 deletions

View File

@@ -25,3 +25,4 @@ futures = { workspace = true }
web-sys = { workspace = true }
winit = { workspace = true }
vello = { workspace = true }
bytemuck = { workspace = true }

View File

@@ -1,4 +1,5 @@
mod context;
pub mod texture_upload;
use anyhow::Result;
pub use context::Context;
@@ -111,20 +112,19 @@ impl WgpuExecutor {
{
let mut renderer = self.vello_renderer.lock().await;
for (id, texture) in context.resource_overrides.iter() {
let texture = texture.clone();
for (image, texture) in context.resource_overrides.iter() {
let texture_view = wgpu::TexelCopyTextureInfoBase {
texture,
texture: texture.clone(),
mip_level: 0,
origin: Origin3d::ZERO,
aspect: TextureAspect::All,
};
renderer.override_image(
&vello::peniko::Image::new(vello::peniko::Blob::from_raw_parts(Arc::new(vec![]), *id), vello::peniko::ImageFormat::Rgba8, 0, 0),
Some(texture_view),
);
renderer.override_image(image, Some(texture_view));
}
renderer.render_to_texture(&self.context.device, &self.context.queue, scene, &target_texture.view, &render_params)?;
for (image, _) in context.resource_overrides.iter() {
renderer.override_image(image, None);
}
}
let surface_texture = surface_inner.get_current_texture()?;

View File

@@ -0,0 +1,51 @@
use crate::WgpuExecutor;
use graphene_core::color::SRGBA8;
use graphene_core::instances::Instance;
use graphene_core::raster_types::{CPU, GPU, Raster, RasterDataTable};
use graphene_core::{Ctx, ExtractFootprint};
use wgpu::util::{DeviceExt, TextureDataOrder};
use wgpu::{Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages};
#[node_macro::node(category(""))]
pub async fn upload_texture<'a: 'n>(_: impl ExtractFootprint + Ctx, input: RasterDataTable<CPU>, executor: &'a WgpuExecutor) -> RasterDataTable<GPU> {
let device = &executor.context.device;
let queue = &executor.context.queue;
let instances = input
.instance_ref_iter()
.map(|instance| {
let image = instance.instance;
let rgba8_data: Vec<SRGBA8> = image.data.iter().map(|x| (*x).into()).collect();
let texture = device.create_texture_with_data(
queue,
&TextureDescriptor {
label: Some("upload_texture node texture"),
size: Extent3d {
width: image.width,
height: image.height,
depth_or_array_layers: 1,
},
mip_level_count: 1,
sample_count: 1,
dimension: TextureDimension::D2,
format: TextureFormat::Rgba8UnormSrgb,
// I don't know what usages are actually necessary
usage: TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST | TextureUsages::COPY_SRC,
view_formats: &[],
},
TextureDataOrder::LayerMajor,
bytemuck::cast_slice(rgba8_data.as_slice()),
);
Instance {
instance: Raster::new_gpu(texture.into()),
transform: *instance.transform,
alpha_blending: *instance.alpha_blending,
source_node_id: *instance.source_node_id,
}
})
.collect();
queue.submit([]);
instances
}