1use crate::{
2 AccelerationStructureBuildSizes, AccelerationStructureDescriptor, Api, BindGroupDescriptor,
3 BindGroupLayoutDescriptor, BufferDescriptor, BufferMapping, CommandEncoderDescriptor,
4 ComputePipelineDescriptor, Device, DeviceError, FenceValue,
5 GetAccelerationStructureBuildSizesDescriptor, Label, MemoryRange, PipelineCacheDescriptor,
6 PipelineCacheError, PipelineError, PipelineLayoutDescriptor, RenderPipelineDescriptor,
7 SamplerDescriptor, ShaderError, ShaderInput, ShaderModuleDescriptor, TextureDescriptor,
8 TextureViewDescriptor,
9};
10
11use super::{
12 DynAccelerationStructure, DynBindGroup, DynBindGroupLayout, DynBuffer, DynCommandEncoder,
13 DynComputePipeline, DynFence, DynPipelineCache, DynPipelineLayout, DynQuerySet, DynQueue,
14 DynRenderPipeline, DynResource, DynResourceExt as _, DynSampler, DynShaderModule, DynTexture,
15 DynTextureView,
16};
17
18pub trait DynDevice: DynResource {
19 unsafe fn exit(self: Box<Self>, queue: Box<dyn DynQueue>);
20
21 unsafe fn create_buffer(
22 &self,
23 desc: &BufferDescriptor,
24 ) -> Result<Box<dyn DynBuffer>, DeviceError>;
25
26 unsafe fn destroy_buffer(&self, buffer: Box<dyn DynBuffer>);
27 unsafe fn add_raw_buffer(&self, buffer: &dyn DynBuffer);
28
29 unsafe fn map_buffer(
30 &self,
31 buffer: &dyn DynBuffer,
32 range: MemoryRange,
33 ) -> Result<BufferMapping, DeviceError>;
34
35 unsafe fn unmap_buffer(&self, buffer: &dyn DynBuffer);
36
37 unsafe fn flush_mapped_ranges(&self, buffer: &dyn DynBuffer, ranges: &[MemoryRange]);
38 unsafe fn invalidate_mapped_ranges(&self, buffer: &dyn DynBuffer, ranges: &[MemoryRange]);
39
40 unsafe fn create_texture(
41 &self,
42 desc: &TextureDescriptor,
43 ) -> Result<Box<dyn DynTexture>, DeviceError>;
44 unsafe fn destroy_texture(&self, texture: Box<dyn DynTexture>);
45 unsafe fn add_raw_texture(&self, texture: &dyn DynTexture);
46
47 unsafe fn create_texture_view(
48 &self,
49 texture: &dyn DynTexture,
50 desc: &TextureViewDescriptor,
51 ) -> Result<Box<dyn DynTextureView>, DeviceError>;
52 unsafe fn destroy_texture_view(&self, view: Box<dyn DynTextureView>);
53 unsafe fn create_sampler(
54 &self,
55 desc: &SamplerDescriptor,
56 ) -> Result<Box<dyn DynSampler>, DeviceError>;
57 unsafe fn destroy_sampler(&self, sampler: Box<dyn DynSampler>);
58
59 unsafe fn create_command_encoder(
60 &self,
61 desc: &CommandEncoderDescriptor<dyn DynQueue>,
62 ) -> Result<Box<dyn DynCommandEncoder>, DeviceError>;
63 unsafe fn destroy_command_encoder(&self, pool: Box<dyn DynCommandEncoder>);
64
65 unsafe fn create_bind_group_layout(
66 &self,
67 desc: &BindGroupLayoutDescriptor,
68 ) -> Result<Box<dyn DynBindGroupLayout>, DeviceError>;
69 unsafe fn destroy_bind_group_layout(&self, bg_layout: Box<dyn DynBindGroupLayout>);
70
71 unsafe fn create_pipeline_layout(
72 &self,
73 desc: &PipelineLayoutDescriptor<dyn DynBindGroupLayout>,
74 ) -> Result<Box<dyn DynPipelineLayout>, DeviceError>;
75 unsafe fn destroy_pipeline_layout(&self, pipeline_layout: Box<dyn DynPipelineLayout>);
76
77 unsafe fn create_bind_group(
78 &self,
79 desc: &BindGroupDescriptor<
80 dyn DynBindGroupLayout,
81 dyn DynBuffer,
82 dyn DynSampler,
83 dyn DynTextureView,
84 dyn DynAccelerationStructure,
85 >,
86 ) -> Result<Box<dyn DynBindGroup>, DeviceError>;
87 unsafe fn destroy_bind_group(&self, group: Box<dyn DynBindGroup>);
88
89 unsafe fn create_shader_module(
90 &self,
91 desc: &ShaderModuleDescriptor,
92 shader: ShaderInput,
93 ) -> Result<Box<dyn DynShaderModule>, ShaderError>;
94 unsafe fn destroy_shader_module(&self, module: Box<dyn DynShaderModule>);
95
96 unsafe fn create_render_pipeline(
97 &self,
98 desc: &RenderPipelineDescriptor<
99 dyn DynPipelineLayout,
100 dyn DynShaderModule,
101 dyn DynPipelineCache,
102 >,
103 ) -> Result<Box<dyn DynRenderPipeline>, PipelineError>;
104 unsafe fn destroy_render_pipeline(&self, pipeline: Box<dyn DynRenderPipeline>);
105
106 unsafe fn create_compute_pipeline(
107 &self,
108 desc: &ComputePipelineDescriptor<
109 dyn DynPipelineLayout,
110 dyn DynShaderModule,
111 dyn DynPipelineCache,
112 >,
113 ) -> Result<Box<dyn DynComputePipeline>, PipelineError>;
114 unsafe fn destroy_compute_pipeline(&self, pipeline: Box<dyn DynComputePipeline>);
115
116 unsafe fn create_pipeline_cache(
117 &self,
118 desc: &PipelineCacheDescriptor<'_>,
119 ) -> Result<Box<dyn DynPipelineCache>, PipelineCacheError>;
120 fn pipeline_cache_validation_key(&self) -> Option<[u8; 16]> {
121 None
122 }
123 unsafe fn destroy_pipeline_cache(&self, cache: Box<dyn DynPipelineCache>);
124
125 unsafe fn create_query_set(
126 &self,
127 desc: &wgt::QuerySetDescriptor<Label>,
128 ) -> Result<Box<dyn DynQuerySet>, DeviceError>;
129 unsafe fn destroy_query_set(&self, set: Box<dyn DynQuerySet>);
130
131 unsafe fn create_fence(&self) -> Result<Box<dyn DynFence>, DeviceError>;
132 unsafe fn destroy_fence(&self, fence: Box<dyn DynFence>);
133 unsafe fn get_fence_value(&self, fence: &dyn DynFence) -> Result<FenceValue, DeviceError>;
134
135 unsafe fn wait(
136 &self,
137 fence: &dyn DynFence,
138 value: FenceValue,
139 timeout_ms: u32,
140 ) -> Result<bool, DeviceError>;
141
142 unsafe fn start_capture(&self) -> bool;
143 unsafe fn stop_capture(&self);
144
145 unsafe fn pipeline_cache_get_data(&self, cache: &dyn DynPipelineCache) -> Option<Vec<u8>>;
146
147 unsafe fn create_acceleration_structure(
148 &self,
149 desc: &AccelerationStructureDescriptor,
150 ) -> Result<Box<dyn DynAccelerationStructure>, DeviceError>;
151 unsafe fn get_acceleration_structure_build_sizes(
152 &self,
153 desc: &GetAccelerationStructureBuildSizesDescriptor<dyn DynBuffer>,
154 ) -> AccelerationStructureBuildSizes;
155 unsafe fn get_acceleration_structure_device_address(
156 &self,
157 acceleration_structure: &dyn DynAccelerationStructure,
158 ) -> wgt::BufferAddress;
159 unsafe fn destroy_acceleration_structure(
160 &self,
161 acceleration_structure: Box<dyn DynAccelerationStructure>,
162 );
163
164 fn get_internal_counters(&self) -> wgt::HalCounters;
165 fn generate_allocator_report(&self) -> Option<wgt::AllocatorReport>;
166}
167
168impl<D: Device + DynResource> DynDevice for D {
169 unsafe fn exit(self: Box<Self>, queue: Box<dyn DynQueue>) {
170 unsafe { D::exit(*self, queue.unbox()) }
171 }
172
173 unsafe fn create_buffer(
174 &self,
175 desc: &BufferDescriptor,
176 ) -> Result<Box<dyn DynBuffer>, DeviceError> {
177 unsafe { D::create_buffer(self, desc) }.map(|b| -> Box<dyn DynBuffer> { Box::new(b) })
178 }
179
180 unsafe fn destroy_buffer(&self, buffer: Box<dyn DynBuffer>) {
181 unsafe { D::destroy_buffer(self, buffer.unbox()) };
182 }
183 unsafe fn add_raw_buffer(&self, buffer: &dyn DynBuffer) {
184 let buffer = buffer.expect_downcast_ref();
185 unsafe { D::add_raw_buffer(self, buffer) };
186 }
187
188 unsafe fn map_buffer(
189 &self,
190 buffer: &dyn DynBuffer,
191 range: MemoryRange,
192 ) -> Result<BufferMapping, DeviceError> {
193 let buffer = buffer.expect_downcast_ref();
194 unsafe { D::map_buffer(self, buffer, range) }
195 }
196
197 unsafe fn unmap_buffer(&self, buffer: &dyn DynBuffer) {
198 let buffer = buffer.expect_downcast_ref();
199 unsafe { D::unmap_buffer(self, buffer) }
200 }
201
202 unsafe fn flush_mapped_ranges(&self, buffer: &dyn DynBuffer, ranges: &[MemoryRange]) {
203 let buffer = buffer.expect_downcast_ref();
204 unsafe { D::flush_mapped_ranges(self, buffer, ranges.iter().cloned()) }
205 }
206
207 unsafe fn invalidate_mapped_ranges(&self, buffer: &dyn DynBuffer, ranges: &[MemoryRange]) {
208 let buffer = buffer.expect_downcast_ref();
209 unsafe { D::invalidate_mapped_ranges(self, buffer, ranges.iter().cloned()) }
210 }
211
212 unsafe fn create_texture(
213 &self,
214 desc: &TextureDescriptor,
215 ) -> Result<Box<dyn DynTexture>, DeviceError> {
216 unsafe { D::create_texture(self, desc) }.map(|b| {
217 let boxed_texture: Box<<D::A as Api>::Texture> = Box::new(b);
218 let boxed_texture: Box<dyn DynTexture> = boxed_texture;
219 boxed_texture
220 })
221 }
222
223 unsafe fn destroy_texture(&self, texture: Box<dyn DynTexture>) {
224 unsafe { D::destroy_texture(self, texture.unbox()) };
225 }
226
227 unsafe fn add_raw_texture(&self, texture: &dyn DynTexture) {
228 let texture = texture.expect_downcast_ref();
229 unsafe { D::add_raw_texture(self, texture) };
230 }
231
232 unsafe fn create_texture_view(
233 &self,
234 texture: &dyn DynTexture,
235 desc: &TextureViewDescriptor,
236 ) -> Result<Box<dyn DynTextureView>, DeviceError> {
237 let texture = texture.expect_downcast_ref();
238 unsafe { D::create_texture_view(self, texture, desc) }.map(|b| {
239 let boxed_texture_view: Box<<D::A as Api>::TextureView> = Box::new(b);
240 let boxed_texture_view: Box<dyn DynTextureView> = boxed_texture_view;
241 boxed_texture_view
242 })
243 }
244
245 unsafe fn destroy_texture_view(&self, view: Box<dyn DynTextureView>) {
246 unsafe { D::destroy_texture_view(self, view.unbox()) };
247 }
248
249 unsafe fn create_sampler(
250 &self,
251 desc: &SamplerDescriptor,
252 ) -> Result<Box<dyn DynSampler>, DeviceError> {
253 unsafe { D::create_sampler(self, desc) }.map(|b| {
254 let boxed_sampler: Box<<D::A as Api>::Sampler> = Box::new(b);
255 let boxed_sampler: Box<dyn DynSampler> = boxed_sampler;
256 boxed_sampler
257 })
258 }
259
260 unsafe fn destroy_sampler(&self, sampler: Box<dyn DynSampler>) {
261 unsafe { D::destroy_sampler(self, sampler.unbox()) };
262 }
263
264 unsafe fn create_command_encoder(
265 &self,
266 desc: &CommandEncoderDescriptor<'_, dyn DynQueue>,
267 ) -> Result<Box<dyn DynCommandEncoder>, DeviceError> {
268 let desc = CommandEncoderDescriptor {
269 label: desc.label,
270 queue: desc.queue.expect_downcast_ref(),
271 };
272 unsafe { D::create_command_encoder(self, &desc) }
273 .map(|b| -> Box<dyn DynCommandEncoder> { Box::new(b) })
274 }
275
276 unsafe fn destroy_command_encoder(&self, encoder: Box<dyn DynCommandEncoder>) {
277 unsafe { D::destroy_command_encoder(self, encoder.unbox()) };
278 }
279
280 unsafe fn create_bind_group_layout(
281 &self,
282 desc: &BindGroupLayoutDescriptor,
283 ) -> Result<Box<dyn DynBindGroupLayout>, DeviceError> {
284 unsafe { D::create_bind_group_layout(self, desc) }
285 .map(|b| -> Box<dyn DynBindGroupLayout> { Box::new(b) })
286 }
287
288 unsafe fn destroy_bind_group_layout(&self, bg_layout: Box<dyn DynBindGroupLayout>) {
289 unsafe { D::destroy_bind_group_layout(self, bg_layout.unbox()) };
290 }
291
292 unsafe fn create_pipeline_layout(
293 &self,
294 desc: &PipelineLayoutDescriptor<dyn DynBindGroupLayout>,
295 ) -> Result<Box<dyn DynPipelineLayout>, DeviceError> {
296 let bind_group_layouts: Vec<_> = desc
297 .bind_group_layouts
298 .iter()
299 .map(|bgl| bgl.expect_downcast_ref())
300 .collect();
301 let desc = PipelineLayoutDescriptor {
302 label: desc.label,
303 bind_group_layouts: &bind_group_layouts,
304 push_constant_ranges: desc.push_constant_ranges,
305 flags: desc.flags,
306 };
307
308 unsafe { D::create_pipeline_layout(self, &desc) }
309 .map(|b| -> Box<dyn DynPipelineLayout> { Box::new(b) })
310 }
311
312 unsafe fn destroy_pipeline_layout(&self, pipeline_layout: Box<dyn DynPipelineLayout>) {
313 unsafe { D::destroy_pipeline_layout(self, pipeline_layout.unbox()) };
314 }
315
316 unsafe fn create_bind_group(
317 &self,
318 desc: &BindGroupDescriptor<
319 dyn DynBindGroupLayout,
320 dyn DynBuffer,
321 dyn DynSampler,
322 dyn DynTextureView,
323 dyn DynAccelerationStructure,
324 >,
325 ) -> Result<Box<dyn DynBindGroup>, DeviceError> {
326 let buffers: Vec<_> = desc
327 .buffers
328 .iter()
329 .map(|b| b.clone().expect_downcast())
330 .collect();
331 let samplers: Vec<_> = desc
332 .samplers
333 .iter()
334 .map(|s| s.expect_downcast_ref())
335 .collect();
336 let textures: Vec<_> = desc
337 .textures
338 .iter()
339 .map(|t| t.clone().expect_downcast())
340 .collect();
341 let acceleration_structures: Vec<_> = desc
342 .acceleration_structures
343 .iter()
344 .map(|a| a.expect_downcast_ref())
345 .collect();
346
347 let desc = BindGroupDescriptor {
348 label: desc.label.to_owned(),
349 layout: desc.layout.expect_downcast_ref(),
350 buffers: &buffers,
351 samplers: &samplers,
352 textures: &textures,
353 entries: desc.entries,
354 acceleration_structures: &acceleration_structures,
355 };
356
357 unsafe { D::create_bind_group(self, &desc) }
358 .map(|b| -> Box<dyn DynBindGroup> { Box::new(b) })
359 }
360
361 unsafe fn destroy_bind_group(&self, group: Box<dyn DynBindGroup>) {
362 unsafe { D::destroy_bind_group(self, group.unbox()) };
363 }
364
365 unsafe fn create_shader_module(
366 &self,
367 desc: &ShaderModuleDescriptor,
368 shader: ShaderInput,
369 ) -> Result<Box<dyn DynShaderModule>, ShaderError> {
370 unsafe { D::create_shader_module(self, desc, shader) }
371 .map(|b| -> Box<dyn DynShaderModule> { Box::new(b) })
372 }
373
374 unsafe fn destroy_shader_module(&self, module: Box<dyn DynShaderModule>) {
375 unsafe { D::destroy_shader_module(self, module.unbox()) };
376 }
377
378 unsafe fn create_render_pipeline(
379 &self,
380 desc: &RenderPipelineDescriptor<
381 dyn DynPipelineLayout,
382 dyn DynShaderModule,
383 dyn DynPipelineCache,
384 >,
385 ) -> Result<Box<dyn DynRenderPipeline>, PipelineError> {
386 let desc = RenderPipelineDescriptor {
387 label: desc.label,
388 layout: desc.layout.expect_downcast_ref(),
389 vertex_buffers: desc.vertex_buffers,
390 vertex_stage: desc.vertex_stage.clone().expect_downcast(),
391 primitive: desc.primitive,
392 depth_stencil: desc.depth_stencil.clone(),
393 multisample: desc.multisample,
394 fragment_stage: desc.fragment_stage.clone().map(|f| f.expect_downcast()),
395 color_targets: desc.color_targets,
396 multiview: desc.multiview,
397 cache: desc.cache.map(|c| c.expect_downcast_ref()),
398 };
399
400 unsafe { D::create_render_pipeline(self, &desc) }
401 .map(|b| -> Box<dyn DynRenderPipeline> { Box::new(b) })
402 }
403
404 unsafe fn destroy_render_pipeline(&self, pipeline: Box<dyn DynRenderPipeline>) {
405 unsafe { D::destroy_render_pipeline(self, pipeline.unbox()) };
406 }
407
408 unsafe fn create_compute_pipeline(
409 &self,
410 desc: &ComputePipelineDescriptor<
411 dyn DynPipelineLayout,
412 dyn DynShaderModule,
413 dyn DynPipelineCache,
414 >,
415 ) -> Result<Box<dyn DynComputePipeline>, PipelineError> {
416 let desc = ComputePipelineDescriptor {
417 label: desc.label,
418 layout: desc.layout.expect_downcast_ref(),
419 stage: desc.stage.clone().expect_downcast(),
420 cache: desc.cache.as_ref().map(|c| c.expect_downcast_ref()),
421 };
422
423 unsafe { D::create_compute_pipeline(self, &desc) }
424 .map(|b| -> Box<dyn DynComputePipeline> { Box::new(b) })
425 }
426
427 unsafe fn destroy_compute_pipeline(&self, pipeline: Box<dyn DynComputePipeline>) {
428 unsafe { D::destroy_compute_pipeline(self, pipeline.unbox()) };
429 }
430
431 unsafe fn create_pipeline_cache(
432 &self,
433 desc: &PipelineCacheDescriptor<'_>,
434 ) -> Result<Box<dyn DynPipelineCache>, PipelineCacheError> {
435 unsafe { D::create_pipeline_cache(self, desc) }
436 .map(|b| -> Box<dyn DynPipelineCache> { Box::new(b) })
437 }
438
439 fn pipeline_cache_validation_key(&self) -> Option<[u8; 16]> {
440 D::pipeline_cache_validation_key(self)
441 }
442
443 unsafe fn destroy_pipeline_cache(&self, pipeline_cache: Box<dyn DynPipelineCache>) {
444 unsafe { D::destroy_pipeline_cache(self, pipeline_cache.unbox()) };
445 }
446
447 unsafe fn create_query_set(
448 &self,
449 desc: &wgt::QuerySetDescriptor<Label>,
450 ) -> Result<Box<dyn DynQuerySet>, DeviceError> {
451 unsafe { D::create_query_set(self, desc) }.map(|b| -> Box<dyn DynQuerySet> { Box::new(b) })
452 }
453
454 unsafe fn destroy_query_set(&self, query_set: Box<dyn DynQuerySet>) {
455 unsafe { D::destroy_query_set(self, query_set.unbox()) };
456 }
457
458 unsafe fn create_fence(&self) -> Result<Box<dyn DynFence>, DeviceError> {
459 unsafe { D::create_fence(self) }.map(|b| -> Box<dyn DynFence> { Box::new(b) })
460 }
461
462 unsafe fn destroy_fence(&self, fence: Box<dyn DynFence>) {
463 unsafe { D::destroy_fence(self, fence.unbox()) };
464 }
465
466 unsafe fn get_fence_value(&self, fence: &dyn DynFence) -> Result<FenceValue, DeviceError> {
467 let fence = fence.expect_downcast_ref();
468 unsafe { D::get_fence_value(self, fence) }
469 }
470
471 unsafe fn wait(
472 &self,
473 fence: &dyn DynFence,
474 value: FenceValue,
475 timeout_ms: u32,
476 ) -> Result<bool, DeviceError> {
477 let fence = fence.expect_downcast_ref();
478 unsafe { D::wait(self, fence, value, timeout_ms) }
479 }
480
481 unsafe fn start_capture(&self) -> bool {
482 unsafe { D::start_capture(self) }
483 }
484
485 unsafe fn stop_capture(&self) {
486 unsafe { D::stop_capture(self) }
487 }
488
489 unsafe fn pipeline_cache_get_data(&self, cache: &dyn DynPipelineCache) -> Option<Vec<u8>> {
490 let cache = cache.expect_downcast_ref();
491 unsafe { D::pipeline_cache_get_data(self, cache) }
492 }
493
494 unsafe fn create_acceleration_structure(
495 &self,
496 desc: &AccelerationStructureDescriptor,
497 ) -> Result<Box<dyn DynAccelerationStructure>, DeviceError> {
498 unsafe { D::create_acceleration_structure(self, desc) }
499 .map(|b| -> Box<dyn DynAccelerationStructure> { Box::new(b) })
500 }
501
502 unsafe fn get_acceleration_structure_build_sizes(
503 &self,
504 desc: &GetAccelerationStructureBuildSizesDescriptor<dyn DynBuffer>,
505 ) -> AccelerationStructureBuildSizes {
506 let entries = desc.entries.expect_downcast();
507 let desc = GetAccelerationStructureBuildSizesDescriptor {
508 entries: &entries,
509 flags: desc.flags,
510 };
511 unsafe { D::get_acceleration_structure_build_sizes(self, &desc) }
512 }
513
514 unsafe fn get_acceleration_structure_device_address(
515 &self,
516 acceleration_structure: &dyn DynAccelerationStructure,
517 ) -> wgt::BufferAddress {
518 let acceleration_structure = acceleration_structure.expect_downcast_ref();
519 unsafe { D::get_acceleration_structure_device_address(self, acceleration_structure) }
520 }
521
522 unsafe fn destroy_acceleration_structure(
523 &self,
524 acceleration_structure: Box<dyn DynAccelerationStructure>,
525 ) {
526 unsafe { D::destroy_acceleration_structure(self, acceleration_structure.unbox()) }
527 }
528
529 fn get_internal_counters(&self) -> wgt::HalCounters {
530 D::get_internal_counters(self)
531 }
532
533 fn generate_allocator_report(&self) -> Option<wgt::AllocatorReport> {
534 D::generate_allocator_report(self)
535 }
536}