1use super::*;
2use rafx_api::{RafxExtents3D, RafxFormat, RafxResourceType, RafxSampleCount, RafxTextureBindType};
3
4#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
6pub struct RenderGraphImageUsageId(pub(super) usize);
7
8#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
10pub struct VirtualImageId(pub(super) usize);
11
12#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
14pub struct PhysicalImageId(pub(super) usize);
15
16#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
18pub struct PhysicalImageViewId(pub(super) usize);
19
20#[derive(Debug, Copy, Clone)]
22pub struct RenderGraphExternalImageId(pub(super) usize);
23
24#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
27pub struct RenderGraphImageVersionId {
28 pub(super) index: usize,
29 pub(super) version: usize,
30}
31
32#[derive(Debug)]
36pub struct RenderGraphImageResource {
37 pub(super) name: Option<RenderGraphResourceName>,
38
39 pub(super) versions: Vec<RenderGraphImageResourceVersionInfo>,
40}
41
42impl RenderGraphImageResource {
43 pub(super) fn new() -> Self {
44 RenderGraphImageResource {
45 name: None,
46 versions: Default::default(),
47 }
48 }
49}
50
51#[derive(Debug, Clone, PartialEq, Eq, Hash)]
52pub struct RenderGraphImageView {
53 pub(super) physical_image: PhysicalImageId,
54 pub(super) format: RafxFormat,
55 pub(super) view_options: RenderGraphImageViewOptions,
56}
57
58#[derive(Debug, Clone, Copy)]
60pub enum RenderGraphImageUser {
61 Node(RenderGraphNodeId),
62 Input(RenderGraphExternalImageId),
63 Output(RenderGraphExternalImageId),
64}
65
66#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
67pub enum RenderGraphImageExtents {
68 MatchSurface,
69 Custom(RafxExtents3D),
71}
72
73impl RenderGraphImageExtents {
74 pub fn into_rafx_extents(
75 self,
76 swapchain_surface_info: &SwapchainSurfaceInfo,
77 ) -> RafxExtents3D {
78 match self {
79 RenderGraphImageExtents::MatchSurface => RafxExtents3D {
80 width: swapchain_surface_info.extents.width,
81 height: swapchain_surface_info.extents.height,
82 depth: 1,
83 },
84 RenderGraphImageExtents::Custom(extents) => extents,
85 }
86 }
87}
88
89impl Default for RenderGraphImageExtents {
90 fn default() -> Self {
91 RenderGraphImageExtents::MatchSurface
92 }
93}
94
95#[derive(Default, Clone, Debug, PartialEq, Eq, Hash)]
96pub struct RenderGraphImageViewOptions {
97 pub texture_bind_type: Option<RafxTextureBindType>,
98 pub array_slice: Option<u16>,
99 pub mip_slice: Option<u8>,
100}
101
102impl RenderGraphImageViewOptions {
103 pub fn array_slice(array_slice: u16) -> Self {
104 RenderGraphImageViewOptions {
105 texture_bind_type: None,
106 array_slice: Some(array_slice),
107 mip_slice: None,
108 }
109 }
110
111 pub fn mip_slice(mip_slice: u8) -> Self {
112 RenderGraphImageViewOptions {
113 texture_bind_type: None,
114 array_slice: None,
115 mip_slice: Some(mip_slice),
116 }
117 }
118}
119
120#[derive(Debug)]
122pub struct RenderGraphImageUsage {
123 pub(super) user: RenderGraphImageUser,
124 pub(super) usage_type: RenderGraphImageUsageType,
125 pub(super) version: RenderGraphImageVersionId,
126
127 pub(super) view_options: RenderGraphImageViewOptions,
128}
129
130#[derive(Debug, Clone, PartialEq, Eq, Hash)]
133pub struct RenderGraphImageSpecification {
134 pub samples: RafxSampleCount,
136 pub format: RafxFormat,
137 pub resource_type: RafxResourceType,
138 pub extents: RafxExtents3D,
139 pub layer_count: u32,
140 pub mip_count: u32,
141 }
143
144impl RenderGraphImageSpecification {
145 pub fn can_merge(
147 &self,
148 other: &RenderGraphImageSpecification,
149 ) -> bool {
150 if self.samples != other.samples {
151 return false;
152 }
153 if self.format != other.format {
154 return false;
155 }
156 if self.mip_count != other.mip_count {
157 return false;
158 }
159 if self.layer_count != other.layer_count {
160 return false;
161 }
162 if self.extents != other.extents {
163 return false;
164 }
165
166 true
167 }
168
169 pub fn try_merge(
172 &mut self,
173 other: &RenderGraphImageSpecification,
174 ) -> bool {
175 if !self.can_merge(other) {
176 return false;
177 }
178
179 self.resource_type |= other.resource_type;
180
181 true
182 }
183
184 pub fn specifications_are_compatible(
185 written: &RenderGraphImageSpecification,
186 read: &RenderGraphImageSpecification,
187 ) -> bool {
188 if written.samples != read.samples {
189 return false;
190 }
191 if written.format != read.format {
192 return false;
193 }
194 if written.mip_count != read.mip_count {
195 return false;
196 }
197 if written.layer_count != read.layer_count {
198 return false;
199 }
200 if written.extents != read.extents {
201 return false;
202 }
203 if (written.resource_type | read.resource_type) != written.resource_type {
204 return false;
205 }
206 return true;
207 }
208}
209
210#[derive(Default, Clone, Debug)]
213pub struct RenderGraphImageConstraint {
214 pub samples: Option<RafxSampleCount>,
216 pub format: Option<RafxFormat>,
217 pub resource_type: RafxResourceType,
218 pub extents: Option<RenderGraphImageExtents>,
219 pub layer_count: Option<u32>,
220 pub mip_count: Option<u32>,
221}
222
223impl From<RenderGraphImageSpecification> for RenderGraphImageConstraint {
224 fn from(specification: RenderGraphImageSpecification) -> Self {
225 RenderGraphImageConstraint {
226 samples: Some(specification.samples),
227 format: Some(specification.format),
228 resource_type: specification.resource_type,
229 layer_count: Some(specification.layer_count),
230 mip_count: Some(specification.mip_count),
231 extents: Some(RenderGraphImageExtents::Custom(specification.extents)),
232 }
233 }
234}
235
236impl RenderGraphImageConstraint {
237 pub fn try_convert_to_specification(
238 self,
239 swapchain_surface_info: &SwapchainSurfaceInfo,
240 ) -> Option<RenderGraphImageSpecification> {
241 if self.format.is_none() {
243 None
244 } else {
245 Some(RenderGraphImageSpecification {
246 samples: self.samples.unwrap_or(RafxSampleCount::SampleCount1),
247 format: self.format.unwrap(),
248 layer_count: self.layer_count.unwrap_or(1),
249 mip_count: self.mip_count.unwrap_or(1),
250 extents: self
251 .extents
252 .unwrap_or(RenderGraphImageExtents::MatchSurface)
253 .into_rafx_extents(swapchain_surface_info),
254 resource_type: self.resource_type,
255 })
256 }
257 }
258}
259
260impl RenderGraphImageConstraint {
261 pub fn can_merge(
263 &self,
264 other: &RenderGraphImageConstraint,
265 ) -> bool {
266 if self.samples.is_some() && other.samples.is_some() && self.samples != other.samples {
267 return false;
268 }
269 if self.format.is_some() && other.format.is_some() && self.format != other.format {
270 return false;
271 }
272 if self.layer_count.is_some()
273 && other.layer_count.is_some()
274 && self.layer_count != other.layer_count
275 {
276 return false;
277 }
278 if self.mip_count.is_some()
279 && other.mip_count.is_some()
280 && self.mip_count != other.mip_count
281 {
282 return false;
283 }
284 if self.extents.is_some() && other.extents.is_some() && self.extents != other.extents {
285 return false;
286 }
287
288 true
289 }
290
291 pub fn try_merge(
294 &mut self,
295 other: &RenderGraphImageConstraint,
296 ) -> bool {
297 if !self.can_merge(other) {
298 return false;
299 }
300
301 if self.samples.is_none() && other.samples.is_some() {
302 self.samples = other.samples;
303 }
304 if self.format.is_none() && other.format.is_some() {
305 self.format = other.format;
306 }
307 if self.layer_count.is_none() && other.layer_count.is_some() {
308 self.layer_count = other.layer_count;
309 }
310 if self.mip_count.is_none() && other.mip_count.is_some() {
311 self.mip_count = other.mip_count;
312 }
313 if self.extents.is_none() && other.extents.is_some() {
314 self.extents = other.extents;
315 }
316
317 self.resource_type |= other.resource_type;
318
319 true
320 }
321
322 pub fn partial_merge(
325 &mut self,
326 other: &RenderGraphImageConstraint,
327 ) -> bool {
328 let mut complete_merge = true;
329
330 if self.samples.is_some() && other.samples.is_some() && self.samples != other.samples {
331 complete_merge = false;
332 } else if other.samples.is_some() {
333 self.samples = other.samples;
334 }
335
336 if self.format.is_some() && other.format.is_some() && self.format != other.format {
337 complete_merge = false;
338 } else if other.format.is_some() {
339 self.format = other.format;
340 }
341
342 if self.layer_count.is_some()
343 && other.layer_count.is_some()
344 && self.layer_count != other.layer_count
345 {
346 complete_merge = false;
347 } else if other.layer_count.is_some() {
348 self.layer_count = other.layer_count;
349 }
350
351 if self.mip_count.is_some()
352 && other.mip_count.is_some()
353 && self.mip_count != other.mip_count
354 {
355 complete_merge = false;
356 } else if other.mip_count.is_some() {
357 self.mip_count = other.mip_count;
358 }
359
360 if self.extents.is_some() && other.extents.is_some() && self.extents != other.extents {
361 complete_merge = false;
362 } else if other.extents.is_some() {
363 self.extents = other.extents;
364 }
365
366 self.resource_type |= other.resource_type;
367
368 complete_merge
369 }
370
371 pub fn set(
373 &mut self,
374 other: &RenderGraphImageSpecification,
375 ) {
376 *self = other.clone().into();
377 }
378}
379
380#[derive(Copy, Clone, Debug, PartialEq)]
382pub enum RenderGraphImageUsageType {
383 Create,
384 Input,
385 Read,
386 ModifyRead,
387 ModifyWrite,
388 Output,
389}
390
391impl RenderGraphImageUsageType {
392 pub fn is_read_only(&self) -> bool {
394 match self {
395 RenderGraphImageUsageType::Read => true,
396 RenderGraphImageUsageType::Output => true,
397 RenderGraphImageUsageType::ModifyRead => false,
398 RenderGraphImageUsageType::Create => false,
399 RenderGraphImageUsageType::Input => false,
400 RenderGraphImageUsageType::ModifyWrite => false,
401 }
402 }
403}
404
405#[derive(Debug)]
407pub struct RenderGraphImageResourceVersionInfo {
408 pub(super) creator_node: RenderGraphNodeId,
411
412 pub(super) create_usage: RenderGraphImageUsageId,
413 pub(super) read_usages: Vec<RenderGraphImageUsageId>,
414}
415
416impl RenderGraphImageResourceVersionInfo {
417 pub(super) fn new(
418 creator: RenderGraphNodeId,
419 create_usage: RenderGraphImageUsageId,
420 ) -> Self {
421 RenderGraphImageResourceVersionInfo {
422 creator_node: creator,
423 create_usage,
424 read_usages: Default::default(),
425 }
426 }
427
428 pub(super) fn remove_read_usage(
430 &mut self,
431 usage: RenderGraphImageUsageId,
432 ) {
433 if let Some(position) = self.read_usages.iter().position(|x| *x == usage) {
434 self.read_usages.swap_remove(position);
435 }
436 }
437
438 pub(super) fn add_read_usage(
439 &mut self,
440 usage: RenderGraphImageUsageId,
441 ) {
442 self.read_usages.push(usage);
443 }
444}