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