1use super::{
4 AttributeChunkWindow, BondChunkPlacement, ChunkPlacementId, ChunkPlacementStatus,
5 ChunkResidencyError, ChunkResidencyMetrics, Engine, InstanceChunkPlacement,
6 InstanceChunkWindow, PointChunkPlacement, RelationChunkPlacement, ResidentGenericChunk,
7 ResidentStructureChunk, ResidentTrajectoryChunk, StructureChunkPlacement,
8 TrajectoryChunkWindow,
9};
10use molgfx_core::{
11 ChunkData, DeviceLossReport, HostWorkingSet, HostWorkingSetError, PagedSpatialAnchor,
12 ResidencyBudget, ResidencyOutput, ResidencyRequest, ResidencyTicket,
13};
14use molgfx_gpu::Device;
15
16impl<D: Device> Engine<D> {
17 pub fn set_structure_chunk_placements(
23 &mut self,
24 placements: &[StructureChunkPlacement],
25 ) -> Result<(), ChunkResidencyError> {
26 self.chunk_residency.replace_placements(placements)
27 }
28
29 #[must_use]
31 pub fn structure_chunk_placement_status(&self, id: ChunkPlacementId) -> ChunkPlacementStatus {
32 self.chunk_residency.placement_status(id)
33 }
34
35 pub fn set_point_chunk_placements(
41 &mut self,
42 placements: &[PointChunkPlacement],
43 ) -> Result<(), ChunkResidencyError> {
44 self.chunk_residency.replace_point_placements(placements)
45 }
46
47 #[must_use]
49 pub fn point_chunk_placement_status(&self, id: ChunkPlacementId) -> ChunkPlacementStatus {
50 self.chunk_residency.point_placement_status(id)
51 }
52
53 pub fn set_instance_chunk_placements(
59 &mut self,
60 placements: &[InstanceChunkPlacement],
61 ) -> Result<(), ChunkResidencyError> {
62 self.chunk_residency.replace_instance_placements(placements)
63 }
64
65 #[must_use]
67 pub fn instance_chunk_placement_status(&self, id: ChunkPlacementId) -> ChunkPlacementStatus {
68 self.chunk_residency.instance_placement_status(id)
69 }
70
71 pub fn set_instance_chunk_windows(
80 &mut self,
81 windows: &[InstanceChunkWindow],
82 ) -> Result<(), ChunkResidencyError> {
83 self.chunk_residency.replace_instance_windows(windows)
84 }
85
86 pub fn set_attribute_chunk_windows(
92 &mut self,
93 windows: &[AttributeChunkWindow],
94 ) -> Result<(), ChunkResidencyError> {
95 self.chunk_residency.replace_attribute_windows(windows)
96 }
97
98 pub fn set_relation_chunk_placements(
104 &mut self,
105 placements: &[RelationChunkPlacement],
106 ) -> Result<(), ChunkResidencyError> {
107 self.chunk_residency.replace_relation_placements(placements)
108 }
109
110 #[must_use]
112 pub fn relation_chunk_placement_status(&self, id: ChunkPlacementId) -> ChunkPlacementStatus {
113 self.chunk_residency.relation_placement_status(id)
114 }
115
116 #[must_use]
119 pub fn paged_spatial_anchor_is_resident(&self, anchor: PagedSpatialAnchor) -> bool {
120 self.chunk_residency
121 .resolve_spatial_anchor(anchor)
122 .is_some()
123 }
124
125 pub fn set_bond_chunk_placements(
131 &mut self,
132 placements: &[BondChunkPlacement],
133 ) -> Result<(), ChunkResidencyError> {
134 self.chunk_residency.replace_bond_placements(placements)
135 }
136
137 pub fn set_trajectory_chunk_windows(
147 &mut self,
148 windows: &[TrajectoryChunkWindow],
149 ) -> Result<(), ChunkResidencyError> {
150 self.chunk_residency.replace_trajectory_windows(windows)
151 }
152
153 #[must_use]
155 pub fn bond_chunk_placement_status(&self, id: ChunkPlacementId) -> ChunkPlacementStatus {
156 self.chunk_residency.bond_placement_status(id)
157 }
158
159 #[must_use]
161 pub const fn host_working_set(&self) -> &HostWorkingSet {
162 &self.host_working_set
163 }
164
165 pub fn request_chunk_into(
171 &mut self,
172 request: ResidencyRequest,
173 output: &mut ResidencyOutput,
174 ) -> Result<ResidencyTicket, ChunkResidencyError> {
175 let ticket = self.host_working_set.request_into(request, output)?;
176 self.chunk_residency.apply(output)?;
177 Ok(ticket)
178 }
179
180 pub fn deliver_chunk_into(
186 &mut self,
187 ticket: ResidencyTicket,
188 payload: ChunkData,
189 output: &mut ResidencyOutput,
190 ) -> Result<(), ChunkResidencyError> {
191 self.host_working_set
192 .deliver_into(ticket, payload, output)?;
193 self.chunk_residency.apply(output)
194 }
195
196 pub fn upload_chunk_into(
206 &mut self,
207 ticket: ResidencyTicket,
208 output: &mut ResidencyOutput,
209 ) -> Result<(), ChunkResidencyError> {
210 self.host_working_set.begin_upload_into(ticket, output)?;
211 let staged = match self.host_working_set.payload(ticket.key) {
212 Some(payload) => self
213 .chunk_residency
214 .stage(&self.device, &self.queue, ticket, payload),
215 None => Err(ChunkResidencyError::PayloadMissing),
216 };
217 if let Err(error) = staged {
218 self.host_working_set.defer_upload_into(ticket, output)?;
219 self.chunk_residency.apply(output)?;
220 return Err(error);
221 }
222 self.chunk_residency.flush(&self.device, &self.queue)?;
226 Ok(())
227 }
228
229 pub fn poll_chunk_uploads_into(
235 &mut self,
236 output: &mut ResidencyOutput,
237 ) -> Result<(), ChunkResidencyError> {
238 self.chunk_residency.flush(&self.device, &self.queue)?;
241 self.chunk_residency.poll(&self.device, &self.queue)?;
242 let completed = self.chunk_residency.completed().len();
243 for index in 0..completed {
244 let ticket = self.chunk_residency.completed()[index];
245 match self.host_working_set.complete_upload_into(ticket, output) {
246 Ok(()) => self.chunk_residency.apply(output)?,
247 Err(HostWorkingSetError::StaleCompletion(_)) => {
248 self.chunk_residency.discard(ticket)?;
249 }
250 Err(error) => {
251 self.chunk_residency.discard(ticket)?;
252 self.chunk_residency.apply(output)?;
253 return Err(error.into());
254 }
255 }
256 }
257 Ok(())
258 }
259
260 pub fn cancel_chunk_into(
266 &mut self,
267 ticket: ResidencyTicket,
268 output: &mut ResidencyOutput,
269 ) -> Result<(), ChunkResidencyError> {
270 self.host_working_set.cancel_into(ticket, output)?;
271 self.chunk_residency.apply(output)
272 }
273
274 pub fn set_chunk_budget_into(
280 &mut self,
281 budget: ResidencyBudget,
282 output: &mut ResidencyOutput,
283 ) -> Result<(), ChunkResidencyError> {
284 self.host_working_set.set_budget_into(budget, output);
285 self.chunk_residency.apply(output)
286 }
287
288 pub fn chunk_device_lost_into(
294 &mut self,
295 output: &mut ResidencyOutput,
296 ) -> Result<DeviceLossReport, ChunkResidencyError> {
297 let report = self.host_working_set.device_lost_into(output)?;
298 self.chunk_residency.reset(&self.device)?;
299 Ok(report)
300 }
301
302 #[must_use]
304 pub fn resident_structure_chunk(
305 &self,
306 ticket: ResidencyTicket,
307 ) -> Option<ResidentStructureChunk> {
308 self.chunk_residency.resident(ticket)
309 }
310
311 #[must_use]
313 pub fn resident_trajectory_chunk(
314 &self,
315 ticket: ResidencyTicket,
316 ) -> Option<ResidentTrajectoryChunk> {
317 self.chunk_residency.resident_frame(ticket)
318 }
319
320 #[must_use]
322 pub fn resident_generic_chunk(&self, ticket: ResidencyTicket) -> Option<ResidentGenericChunk> {
323 self.chunk_residency.resident_generic(ticket)
324 }
325
326 #[must_use]
328 pub fn chunk_residency_metrics(&self) -> ChunkResidencyMetrics {
329 self.chunk_residency.metrics()
330 }
331}