Skip to main content

spatialrust_gpu/image/kernels/
copy.rs

1//! Device-resident image copy.
2
3use spatialrust_core::SpatialResult;
4
5use crate::image::gpu_image::{create_texture, GpuImage, GpuImageReceipt};
6use crate::WgpuRuntime;
7
8/// Copies `source` into a new GPU image without host transfers.
9pub fn copy_gpu_image(runtime: &WgpuRuntime, source: &GpuImage) -> SpatialResult<GpuImage> {
10    source.validate_runtime(runtime)?;
11    let storage_bytes = source.storage_bytes();
12    let texture = create_texture(runtime, source.width(), source.height(), "gpu-image-copy");
13    let mut encoder = runtime.device().create_command_encoder(&wgpu::CommandEncoderDescriptor {
14        label: Some("gpu-image-copy-encoder"),
15    });
16    encoder.copy_texture_to_texture(
17        wgpu::TexelCopyTextureInfo {
18            texture: source.texture(),
19            mip_level: 0,
20            origin: wgpu::Origin3d::ZERO,
21            aspect: wgpu::TextureAspect::All,
22        },
23        wgpu::TexelCopyTextureInfo {
24            texture: &texture,
25            mip_level: 0,
26            origin: wgpu::Origin3d::ZERO,
27            aspect: wgpu::TextureAspect::All,
28        },
29        wgpu::Extent3d { width: source.width(), height: source.height(), depth_or_array_layers: 1 },
30    );
31    runtime.queue().submit(Some(encoder.finish()));
32    let mut receipt = GpuImageReceipt::default();
33    receipt.merge_from(source.receipt());
34    receipt.record_gpu_to_gpu(storage_bytes, "copy_gpu_image");
35    GpuImage::from_parts(
36        runtime,
37        source.width(),
38        source.height(),
39        source.channels(),
40        texture,
41        source.metadata(),
42        receipt,
43    )
44}