1use crate::resource::{BufferUsageIntent, ComputePipelineId, TextureId};
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
27pub enum ColorAttachmentLoad {
28 Clear,
29 Load,
30}
31
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
33pub enum DepthAttachmentLoad {
34 Clear,
35 Load,
36 None,
37}
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
40pub enum PassColorTarget {
41 Swapchain,
42 Texture(TextureId),
43}
44
45#[derive(Debug, Clone)]
46pub struct PassDescriptor {
47 pub name: String,
48 pub color_target: PassColorTarget,
49 pub color_load: ColorAttachmentLoad,
50 pub clear_color: [f32; 4],
51 pub depth_load: DepthAttachmentLoad,
52 pub clear_depth: f32,
53 pub instance_indices: Vec<usize>,
54 pub buffer_intents: Vec<BufferUsageIntent>,
55}
56
57impl PassDescriptor {
58 pub fn new(name: impl Into<String>) -> Self {
59 Self {
60 name: name.into(),
61 color_target: PassColorTarget::Swapchain,
62 color_load: ColorAttachmentLoad::Clear,
63 clear_color: [0.04, 0.05, 0.08, 1.0],
64 depth_load: DepthAttachmentLoad::None,
65 clear_depth: 1.0,
66 instance_indices: Vec::new(),
67 buffer_intents: Vec::new(),
68 }
69 }
70
71 pub fn uses_depth_attachment(&self) -> bool {
72 !matches!(self.depth_load, DepthAttachmentLoad::None)
73 }
74
75 pub fn with_clear_color(mut self, clear_color: [f32; 4]) -> Self {
76 self.clear_color = clear_color;
77 self.color_load = ColorAttachmentLoad::Clear;
78 self
79 }
80
81 pub fn with_clear_depth(mut self, clear_depth: Option<f32>) -> Self {
82 match clear_depth {
83 Some(depth) => {
84 self.depth_load = DepthAttachmentLoad::Clear;
85 self.clear_depth = depth;
86 }
87 None => {
88 self.depth_load = DepthAttachmentLoad::None;
89 }
90 }
91 self
92 }
93
94 pub fn with_color_load(mut self, color_load: ColorAttachmentLoad) -> Self {
95 self.color_load = color_load;
96 self
97 }
98
99 pub fn with_depth_load(mut self, depth_load: DepthAttachmentLoad) -> Self {
100 self.depth_load = depth_load;
101 self
102 }
103
104 pub fn with_color_target(mut self, color_target: PassColorTarget) -> Self {
105 self.color_target = color_target;
106 self
107 }
108
109 pub fn with_instance_indices(mut self, instance_indices: Vec<usize>) -> Self {
110 self.instance_indices = instance_indices;
111 self
112 }
113
114 pub fn with_buffer_intents(mut self, buffer_intents: Vec<BufferUsageIntent>) -> Self {
115 self.buffer_intents = buffer_intents;
116 self
117 }
118
119 pub fn into_frame_pass(self) -> FramePass {
120 FramePass::Graphics(self)
121 }
122}
123
124#[derive(Debug, Clone)]
125pub struct ComputePassDescriptor {
126 pub name: String,
127 pub pipeline: ComputePipelineId,
128 pub workgroup_count: [u32; 3],
129 pub buffer_intents: Vec<BufferUsageIntent>,
130}
131
132impl ComputePassDescriptor {
133 pub fn new(
134 name: impl Into<String>,
135 pipeline: ComputePipelineId,
136 workgroup_count: [u32; 3],
137 ) -> Self {
138 Self {
139 name: name.into(),
140 pipeline,
141 workgroup_count,
142 buffer_intents: Vec::new(),
143 }
144 }
145
146 pub fn with_buffer_intents(mut self, buffer_intents: Vec<BufferUsageIntent>) -> Self {
147 self.buffer_intents = buffer_intents;
148 self
149 }
150
151 pub fn into_frame_pass(self) -> FramePass {
152 FramePass::Compute(self)
153 }
154}
155
156#[derive(Debug, Clone)]
157pub enum FramePass {
158 Graphics(PassDescriptor),
159 Compute(ComputePassDescriptor),
160}
161
162#[derive(Debug, Clone)]
163pub struct FrameDescriptor {
164 pub passes: Vec<FramePass>,
165}
166
167impl FrameDescriptor {
168 pub fn new(passes: Vec<FramePass>) -> Self {
169 Self { passes }
170 }
171
172 pub fn new_graphics(passes: Vec<PassDescriptor>) -> Self {
173 Self {
174 passes: passes.into_iter().map(FramePass::Graphics).collect(),
175 }
176 }
177
178 pub fn single_pass(clear_color: [f32; 4], clear_depth: Option<f32>) -> Self {
179 Self::new_graphics(vec![
180 PassDescriptor::new("main")
181 .with_clear_color(clear_color)
182 .with_clear_depth(clear_depth),
183 ])
184 }
185}