rafx_framework/upload/
gpu_image_data.rs1use rafx_api::RafxFormat;
2
3#[derive(Copy, Clone, Debug, PartialEq)]
4pub enum GpuImageDataColorSpace {
5 Srgb,
6 Linear,
7}
8
9impl GpuImageDataColorSpace {
10 pub fn rgba8(self) -> RafxFormat {
11 match self {
12 GpuImageDataColorSpace::Srgb => RafxFormat::R8G8B8A8_SRGB,
13 GpuImageDataColorSpace::Linear => RafxFormat::R8G8B8A8_UNORM,
14 }
15 }
16
17 pub fn astc4x4(self) -> RafxFormat {
18 match self {
19 GpuImageDataColorSpace::Srgb => RafxFormat::ASTC_4X4_SRGB_BLOCK,
20 GpuImageDataColorSpace::Linear => RafxFormat::ASTC_4X4_UNORM_BLOCK,
21 }
22 }
23
24 pub fn bc7(self) -> RafxFormat {
25 match self {
26 GpuImageDataColorSpace::Srgb => RafxFormat::BC7_SRGB_BLOCK,
27 GpuImageDataColorSpace::Linear => RafxFormat::BC7_UNORM_BLOCK,
28 }
29 }
30}
31
32#[derive(Debug)]
33pub struct GpuImageData {
34 pub width: u32,
35 pub height: u32,
36 pub format: RafxFormat,
37 pub layers: Vec<GpuImageDataLayer>,
38}
39
40impl GpuImageData {
41 pub fn new(
42 layers: Vec<GpuImageDataLayer>,
43 format: RafxFormat,
44 ) -> Self {
45 #[cfg(debug_assertions)]
46 {
47 for i in 1..layers.len() {
48 debug_assert_eq!(layers[0].mip_levels.len(), layers[i].mip_levels.len());
49 for j in 1..layers[0].mip_levels.len() {
50 debug_assert_eq!(layers[0].mip_levels[j].width, layers[i].mip_levels[j].width);
51 debug_assert_eq!(
52 layers[0].mip_levels[j].height,
53 layers[i].mip_levels[j].height
54 );
55 debug_assert_eq!(layers[0].mip_levels[j].width, layers[i].mip_levels[j].width);
56 }
57 }
58 }
59
60 GpuImageData {
61 width: layers[0].mip_levels[0].width,
62 height: layers[0].mip_levels[0].height,
63 format,
64 layers,
65 }
66 }
67
68 pub fn new_simple_image_from_bytes(
69 width: u32,
70 height: u32,
71 format: RafxFormat,
72 data: Vec<u8>,
73 ) -> Self {
74 GpuImageData {
75 width,
76 height,
77 format,
78 layers: vec![GpuImageDataLayer::new_single_level(width, height, data)],
79 }
80 }
81
82 pub fn total_size(
83 &self,
84 required_image_alignment: u32,
85 required_row_alignment: u32,
86 ) -> u64 {
87 let mut bytes_required = 0;
88 for layer in &self.layers {
89 for level in &layer.mip_levels {
90 bytes_required += required_image_alignment as u64;
92
93 let row_size = level.data.len() as u64 / level.height as u64;
96 bytes_required += rafx_base::memory::round_size_up_to_alignment_u64(
97 row_size,
98 required_row_alignment as u64,
99 ) * (level.height as u64 - 1);
100 }
101 }
102
103 bytes_required
104 }
105
106 #[cfg(debug_assertions)]
107 pub fn verify_state(&self) {
108 let first_layer = &self.layers[0];
109 let first_level = &first_layer.mip_levels[0];
110 assert_eq!(first_level.width, self.width);
111 assert_eq!(first_level.height, self.height);
112
113 for layer in &self.layers {
114 assert_eq!(first_layer.mip_levels.len(), layer.mip_levels.len());
115 for (i, level) in layer.mip_levels.iter().enumerate() {
116 assert_eq!(first_layer.mip_levels[i].width, level.width);
117 assert_eq!(first_layer.mip_levels[i].height, level.height);
118 }
119 }
120 }
121}
122
123#[derive(Debug)]
124pub struct GpuImageDataLayer {
125 pub mip_levels: Vec<GpuImageDataMipLevel>,
126}
127
128impl GpuImageDataLayer {
129 pub fn new(mip_levels: Vec<GpuImageDataMipLevel>) -> Self {
130 GpuImageDataLayer { mip_levels }
131 }
132
133 pub fn new_single_level(
134 width: u32,
135 height: u32,
136 data: Vec<u8>,
137 ) -> Self {
138 GpuImageDataLayer {
139 mip_levels: vec![GpuImageDataMipLevel {
140 width,
141 height,
142 data,
143 }],
144 }
145 }
146}
147
148pub struct GpuImageDataMipLevel {
149 pub width: u32,
150 pub height: u32,
151 pub data: Vec<u8>,
152}
153
154impl std::fmt::Debug for GpuImageDataMipLevel {
155 fn fmt(
156 &self,
157 f: &mut std::fmt::Formatter,
158 ) -> std::fmt::Result {
159 f.debug_struct("GpuImageDataMipLevel")
160 .field("width", &self.width)
161 .field("height", &self.height)
162 .field("data_length", &self.data.len())
163 .finish()
164 }
165}
166
167impl GpuImageData {
168 pub fn new_1x1_rgba8(
169 r: u8,
170 g: u8,
171 b: u8,
172 a: u8,
173 color_space: GpuImageDataColorSpace,
174 ) -> Self {
175 GpuImageData::new_simple_image_from_bytes(1, 1, color_space.rgba8(), vec![r, g, b, a])
176 }
177
178 pub fn new_1x1_d32(d: f32) -> Self {
179 let bytes = d.to_bits().to_ne_bytes().to_vec();
180 GpuImageData::new_simple_image_from_bytes(1, 1, RafxFormat::D32_SFLOAT, bytes)
181 }
182}