1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
use bevy::{
ecs::system::{lifetimeless::SRes, SystemParamItem},
prelude::*,
render::{
render_asset::{PrepareAssetError, RenderAsset, RenderAssets},
render_resource::{Buffer, BufferDescriptor, BufferUsages, Extent3d, TextureFormat},
renderer::RenderDevice, texture::GpuImage,
},
};
/// Render-world version of HeadlessRenderSource
pub struct GpuHeadlessRenderSource {
pub(crate) buffer: Buffer,
pub(crate) source_handle: Handle<Image>,
pub(crate) source_size: Extent3d,
pub(crate) bytes_per_row: u32,
pub(crate) padded_bytes_per_row: u32,
pub(crate) format: TextureFormat,
}
/// Headless render source. Contains a handle to the render texture which will be copied
/// from.
#[derive(Asset, Reflect, Clone, Default)]
pub struct HeadlessRenderSource(pub Handle<Image>);
impl RenderAsset for GpuHeadlessRenderSource {
type SourceAsset = HeadlessRenderSource;
type Param = (SRes<RenderDevice>, SRes<RenderAssets<GpuImage>>);
fn prepare_asset(
source_asset: Self::SourceAsset,
(device, images): &mut SystemParamItem<Self::Param>,
) -> Result<Self, PrepareAssetError<Self::SourceAsset>> {
let Some(gpu_image) = images.get(source_asset.0.id()) else {
warn!("Failed to get GPU image");
return Err(PrepareAssetError::RetryNextUpdate(source_asset));
};
let size = gpu_image.texture.size();
let format = gpu_image.texture_format;
let bytes_per_row =
(size.width / format.block_dimensions().0) * format.block_copy_size(None).unwrap();
let padded_bytes_per_row =
RenderDevice::align_copy_bytes_per_row(bytes_per_row as usize) as u32;
Ok(GpuHeadlessRenderSource {
buffer: device.create_buffer(&BufferDescriptor {
label: Some("framebuffer_extract_buffer"),
size: (size.height * padded_bytes_per_row) as u64,
usage: BufferUsages::COPY_DST | BufferUsages::MAP_READ,
mapped_at_creation: false,
}),
source_handle: source_asset.0.clone(),
source_size: size,
bytes_per_row,
padded_bytes_per_row,
format,
})
}
}
|