rendy_chain/
resource.rs

1use std::{
2    fmt::Debug,
3    ops::{BitOr, BitOrAssign},
4};
5
6/// Trait to abstract of specific access flags.
7pub trait AccessFlags: Copy + Debug + BitOr<Output = Self> + BitOrAssign + 'static {
8    /// Get flags value with no flags set.
9    fn empty() -> Self;
10
11    /// Check if this access must be exclusive.
12    ///
13    /// Basically this checks if all flags are known read flags.
14    fn exclusive(&self) -> bool;
15}
16
17impl AccessFlags for rendy_core::hal::buffer::Access {
18    #[inline]
19    fn empty() -> Self {
20        Self::empty()
21    }
22
23    #[inline]
24    fn exclusive(&self) -> bool {
25        self.intersects(
26            Self::SHADER_WRITE | Self::TRANSFER_WRITE | Self::HOST_WRITE | Self::MEMORY_WRITE,
27        )
28    }
29}
30
31impl AccessFlags for rendy_core::hal::image::Access {
32    #[inline]
33    fn empty() -> Self {
34        Self::empty()
35    }
36
37    #[inline]
38    fn exclusive(&self) -> bool {
39        self.intersects(
40            Self::SHADER_WRITE
41                | Self::COLOR_ATTACHMENT_WRITE
42                | Self::DEPTH_STENCIL_ATTACHMENT_WRITE
43                | Self::TRANSFER_WRITE
44                | Self::HOST_WRITE
45                | Self::MEMORY_WRITE,
46        )
47    }
48}
49
50/// Trait to abstract of specific usage flags.
51pub trait UsageFlags: Copy + Debug + BitOr<Output = Self> + BitOrAssign + 'static {}
52
53impl UsageFlags for rendy_core::hal::buffer::Usage {}
54impl UsageFlags for rendy_core::hal::image::Usage {}
55
56/// Abstracts resource types that uses different usage flags and layouts types.
57pub trait Resource: 'static {
58    /// Access flags for resource type.
59    type Access: AccessFlags;
60
61    /// Usage flags type for the resource.
62    type Usage: UsageFlags;
63
64    /// Layout type for the resource.
65    type Layout: Copy + Debug + 'static;
66
67    /// Empty usage.
68    fn no_usage() -> Self::Usage;
69
70    /// Layout suitable for specified accesses.
71    fn layout_for(access: Self::Access) -> Self::Layout;
72}
73
74/// Buffer resource type.
75#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
76pub struct Buffer;
77
78impl Resource for Buffer {
79    type Access = rendy_core::hal::buffer::Access;
80    type Usage = rendy_core::hal::buffer::Usage;
81    type Layout = ();
82
83    fn no_usage() -> Self::Usage {
84        rendy_core::hal::buffer::Usage::empty()
85    }
86
87    fn layout_for(_access: rendy_core::hal::buffer::Access) {}
88}
89
90/// Image resource type.
91#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
92pub struct Image;
93
94impl Resource for Image {
95    type Access = rendy_core::hal::image::Access;
96
97    type Usage = rendy_core::hal::image::Usage;
98
99    type Layout = rendy_core::hal::image::Layout;
100
101    fn no_usage() -> Self::Usage {
102        rendy_core::hal::image::Usage::empty()
103    }
104
105    fn layout_for(access: rendy_core::hal::image::Access) -> rendy_core::hal::image::Layout {
106        let mut acc = None;
107        if access.contains(rendy_core::hal::image::Access::INPUT_ATTACHMENT_READ) {
108            acc = Some(common_layout(
109                acc,
110                rendy_core::hal::image::Layout::ShaderReadOnlyOptimal,
111            ));
112        }
113        if access.contains(rendy_core::hal::image::Access::COLOR_ATTACHMENT_READ) {
114            acc = Some(common_layout(
115                acc,
116                rendy_core::hal::image::Layout::ColorAttachmentOptimal,
117            ));
118        }
119        if access.contains(rendy_core::hal::image::Access::COLOR_ATTACHMENT_WRITE) {
120            acc = Some(common_layout(
121                acc,
122                rendy_core::hal::image::Layout::ColorAttachmentOptimal,
123            ));
124        }
125        if access.contains(rendy_core::hal::image::Access::DEPTH_STENCIL_ATTACHMENT_READ) {
126            acc = Some(common_layout(
127                acc,
128                rendy_core::hal::image::Layout::DepthStencilReadOnlyOptimal,
129            ));
130        }
131        if access.contains(rendy_core::hal::image::Access::DEPTH_STENCIL_ATTACHMENT_WRITE) {
132            acc = Some(common_layout(
133                acc,
134                rendy_core::hal::image::Layout::DepthStencilAttachmentOptimal,
135            ));
136        }
137        if access.contains(rendy_core::hal::image::Access::TRANSFER_READ) {
138            acc = Some(common_layout(
139                acc,
140                rendy_core::hal::image::Layout::TransferSrcOptimal,
141            ));
142        }
143        if access.contains(rendy_core::hal::image::Access::TRANSFER_WRITE) {
144            acc = Some(common_layout(
145                acc,
146                rendy_core::hal::image::Layout::TransferDstOptimal,
147            ));
148        }
149        acc.unwrap_or(rendy_core::hal::image::Layout::General)
150    }
151}
152
153fn common_layout(
154    acc: Option<rendy_core::hal::image::Layout>,
155    layout: rendy_core::hal::image::Layout,
156) -> rendy_core::hal::image::Layout {
157    match (acc, layout) {
158        (None, layout) => layout,
159        (Some(left), right) if left == right => left,
160        (
161            Some(rendy_core::hal::image::Layout::DepthStencilReadOnlyOptimal),
162            rendy_core::hal::image::Layout::DepthStencilAttachmentOptimal,
163        ) => rendy_core::hal::image::Layout::DepthStencilAttachmentOptimal,
164        (
165            Some(rendy_core::hal::image::Layout::DepthStencilAttachmentOptimal),
166            rendy_core::hal::image::Layout::DepthStencilReadOnlyOptimal,
167        ) => rendy_core::hal::image::Layout::DepthStencilAttachmentOptimal,
168        (Some(_), _) => rendy_core::hal::image::Layout::General,
169    }
170}