1use std::{
2 fmt::Debug,
3 ops::{BitOr, BitOrAssign},
4};
5
6pub trait AccessFlags: Copy + Debug + BitOr<Output = Self> + BitOrAssign + 'static {
8 fn empty() -> Self;
10
11 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
50pub 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
56pub trait Resource: 'static {
58 type Access: AccessFlags;
60
61 type Usage: UsageFlags;
63
64 type Layout: Copy + Debug + 'static;
66
67 fn no_usage() -> Self::Usage;
69
70 fn layout_for(access: Self::Access) -> Self::Layout;
72}
73
74#[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#[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}