gfx_hal/device.rs
1//! Logical graphics device.
2//!
3//! # Device
4//!
5//! This module exposes the [`Device`][Device] trait, which provides methods for creating
6//! and managing graphics resources such as buffers, images and memory.
7//!
8//! The `Adapter` and `Device` types are very similar to the Vulkan concept of
9//! "physical devices" vs. "logical devices"; an `Adapter` is single GPU
10//! (or CPU) that implements a backend, a `Device` is a
11//! handle to that physical device that has the requested capabilities
12//! and is used to actually do things.
13
14use crate::{
15 buffer, display, external_memory, format, image, memory,
16 memory::{Requirements, Segment},
17 pass,
18 pool::CommandPoolCreateFlags,
19 pso,
20 pso::DescriptorPoolCreateFlags,
21 query,
22 queue::QueueFamilyId,
23 Backend, MemoryTypeId,
24};
25
26use std::{any::Any, fmt, iter, ops::Range};
27
28/// Error occurred caused device to be lost.
29#[derive(Clone, Debug, PartialEq, thiserror::Error)]
30#[error("Device lost")]
31pub struct DeviceLost;
32
33/// Error allocating memory.
34#[derive(Clone, Debug, PartialEq, thiserror::Error)]
35pub enum OutOfMemory {
36 /// Host memory exhausted.
37 #[error("Out of host memory")]
38 Host,
39 /// Device memory exhausted.
40 #[error("Out of device memory")]
41 Device,
42}
43
44/// Error occurring when waiting for fences or events.
45#[derive(Clone, Debug, PartialEq, thiserror::Error)]
46pub enum WaitError {
47 /// Out of either host or device memory.
48 #[error(transparent)]
49 OutOfMemory(#[from] OutOfMemory),
50 /// Device is lost
51 #[error(transparent)]
52 DeviceLost(#[from] DeviceLost),
53}
54
55/// Possible cause of allocation failure.
56#[derive(Clone, Debug, PartialEq, thiserror::Error)]
57pub enum AllocationError {
58 /// Out of either host or device memory.
59 #[error(transparent)]
60 OutOfMemory(#[from] OutOfMemory),
61
62 /// Cannot create any more objects.
63 #[error("Too many objects")]
64 TooManyObjects,
65}
66
67/// Device creation errors during `open`.
68#[derive(Clone, Debug, PartialEq, thiserror::Error)]
69pub enum CreationError {
70 /// Out of either host or device memory.
71 #[error(transparent)]
72 OutOfMemory(#[from] OutOfMemory),
73 /// Device initialization failed due to implementation specific errors.
74 #[error("Implementation specific error occurred")]
75 InitializationFailed,
76 /// At least one of the user requested features if not supported by the
77 /// physical device.
78 ///
79 /// Use [`features`](trait.PhysicalDevice.html#tymethod.features)
80 /// for checking the supported features.
81 #[error("Requested feature is missing")]
82 MissingFeature,
83 /// Too many logical devices have been created from this physical device.
84 ///
85 /// The implementation may only support one logical device for each physical
86 /// device or lacks resources to allocate a new device.
87 #[error("Too many objects")]
88 TooManyObjects,
89 /// The logical or physical device are lost during the device creation
90 /// process.
91 ///
92 /// This may be caused by hardware failure, physical device removal,
93 /// power outage, etc.
94 #[error("Logical or Physical device was lost during creation")]
95 DeviceLost,
96}
97
98/// Error accessing a mapping.
99#[derive(Clone, Debug, PartialEq, thiserror::Error)]
100pub enum MapError {
101 /// Out of either host or device memory.
102 #[error(transparent)]
103 OutOfMemory(#[from] OutOfMemory),
104 /// The requested mapping range is outside of the resource.
105 #[error("Requested range is outside the resource")]
106 OutOfBounds,
107 /// Failed to allocate an appropriately sized contiguous virtual address range.
108 #[error("Unable to allocate an appropriately sized contiguous virtual address range")]
109 MappingFailed,
110 /// Memory is not CPU visible.
111 #[error("Memory is not CPU visible")]
112 Access,
113}
114
115/// Error binding a resource to memory allocation.
116#[derive(Clone, Debug, PartialEq, thiserror::Error)]
117pub enum BindError {
118 /// Out of either host or device memory.
119 #[error(transparent)]
120 OutOfMemory(#[from] OutOfMemory),
121 /// Requested binding to memory that doesn't support the required operations.
122 #[error("Wrong memory")]
123 WrongMemory,
124 /// Requested binding to an invalid memory.
125 #[error("Requested range is outside the resource")]
126 OutOfBounds,
127}
128
129/// Specifies the waiting targets.
130#[derive(Clone, Debug, PartialEq)]
131#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
132pub enum WaitFor {
133 /// Wait for any target.
134 Any,
135 /// Wait for all targets at once.
136 All,
137}
138
139/// An error from creating a shader module.
140#[derive(Clone, Debug, PartialEq, thiserror::Error)]
141pub enum ShaderError {
142 /// Unsupported module.
143 #[error("Shader module is not supported")]
144 Unsupported,
145 /// Compilation failed.
146 #[error("Shader module failed to compile: {0:}")]
147 CompilationFailed(String),
148 /// Device ran out of memory.
149 #[error(transparent)]
150 OutOfMemory(#[from] OutOfMemory),
151}
152
153/// Source shader code for a module.
154#[derive(Debug)]
155#[non_exhaustive]
156pub enum ShaderModuleDesc<'a> {
157 /// SPIR-V word array.
158 SpirV(&'a [u32]),
159}
160
161/// Naga shader module.
162#[allow(missing_debug_implementations)]
163pub struct NagaShader {
164 /// Shader module IR.
165 pub module: naga::Module,
166 /// Analysis information of the module.
167 pub info: naga::valid::ModuleInfo,
168}
169
170/// Logical device handle, responsible for creating and managing resources
171/// for the physical device it was created from.
172///
173/// ## Resource Construction and Handling
174///
175/// This device structure can then be used to create and manage different resources,
176/// like [buffers][Device::create_buffer], [shader modules][Device::create_shader_module]
177/// and [images][Device::create_image]. See the individual methods for more information.
178///
179/// ## Mutability
180///
181/// All the methods get `&self`. Any internal mutability of the `Device` is hidden from the user.
182///
183/// ## Synchronization
184///
185/// `Device` should be usable concurrently from multiple threads. The `Send` and `Sync` bounds
186/// are not enforced at the HAL level due to OpenGL constraint (to be revised). Users can still
187/// benefit from the backends that support synchronization of the `Device`.
188///
189pub trait Device<B: Backend>: fmt::Debug + Any + Send + Sync {
190 /// Allocates a memory segment of a specified type.
191 ///
192 /// There is only a limited amount of allocations allowed depending on the implementation!
193 ///
194 /// # Arguments
195 ///
196 /// * `memory_type` - Index of the memory type in the memory properties of the associated physical device.
197 /// * `size` - Size of the allocation.
198 unsafe fn allocate_memory(
199 &self,
200 memory_type: MemoryTypeId,
201 size: u64,
202 ) -> Result<B::Memory, AllocationError>;
203
204 /// Free device memory
205 unsafe fn free_memory(&self, memory: B::Memory);
206
207 /// Create a new [command pool][crate::pool::CommandPool] for a given queue family.
208 ///
209 /// *Note*: the family has to be associated with one of [the queue groups
210 /// of this device][crate::adapter::Gpu::queue_groups].
211 unsafe fn create_command_pool(
212 &self,
213 family: QueueFamilyId,
214 create_flags: CommandPoolCreateFlags,
215 ) -> Result<B::CommandPool, OutOfMemory>;
216
217 /// Destroy a command pool.
218 unsafe fn destroy_command_pool(&self, pool: B::CommandPool);
219
220 /// Create a [render pass][crate::pass] with the given attachments and subpasses.
221 ///
222 /// The use of a render pass in a command buffer is a *render pass* instance.
223 ///
224 /// # Arguments
225 ///
226 /// * `attachments` - [image attachments][crate::pass::Attachment] to be used in
227 /// this render pass. Usually you need at least one attachment, to be used as output.
228 /// * `subpasses` - [subpasses][crate::pass::SubpassDesc] to use.
229 /// You need to use at least one subpass.
230 /// * `dependencies` - [dependencies between subpasses][crate::pass::SubpassDependency].
231 /// Can be empty.
232 unsafe fn create_render_pass<'a, Ia, Is, Id>(
233 &self,
234 attachments: Ia,
235 subpasses: Is,
236 dependencies: Id,
237 ) -> Result<B::RenderPass, OutOfMemory>
238 where
239 Ia: Iterator<Item = pass::Attachment>,
240 Is: Iterator<Item = pass::SubpassDesc<'a>>,
241 Id: Iterator<Item = pass::SubpassDependency>;
242
243 /// Destroys a *render pass* created by this device.
244 unsafe fn destroy_render_pass(&self, rp: B::RenderPass);
245
246 /// Create a new pipeline layout object.
247 ///
248 /// # Arguments
249 ///
250 /// * `set_layouts` - Descriptor set layouts
251 /// * `push_constants` - Ranges of push constants. A shader stage may only contain one push
252 /// constant block. The range is defined in units of bytes.
253 ///
254 /// # PipelineLayout
255 ///
256 /// Access to descriptor sets from a pipeline is accomplished through a *pipeline layout*.
257 /// Zero or more descriptor set layouts and zero or more push constant ranges are combined to
258 /// form a pipeline layout object which describes the complete set of resources that **can** be
259 /// accessed by a pipeline. The pipeline layout represents a sequence of descriptor sets with
260 /// each having a specific layout. This sequence of layouts is used to determine the interface
261 /// between shader stages and shader resources. Each pipeline is created using a pipeline layout.
262 unsafe fn create_pipeline_layout<'a, Is, Ic>(
263 &self,
264 set_layouts: Is,
265 push_constant: Ic,
266 ) -> Result<B::PipelineLayout, OutOfMemory>
267 where
268 Is: Iterator<Item = &'a B::DescriptorSetLayout>,
269 Ic: Iterator<Item = (pso::ShaderStageFlags, Range<u32>)>;
270
271 /// Destroy a pipeline layout object
272 unsafe fn destroy_pipeline_layout(&self, layout: B::PipelineLayout);
273
274 /// Create a pipeline cache object.
275 unsafe fn create_pipeline_cache(
276 &self,
277 data: Option<&[u8]>,
278 ) -> Result<B::PipelineCache, OutOfMemory>;
279
280 /// Retrieve data from pipeline cache object.
281 unsafe fn get_pipeline_cache_data(
282 &self,
283 cache: &B::PipelineCache,
284 ) -> Result<Vec<u8>, OutOfMemory>;
285
286 /// Merge a number of source pipeline caches into the target one.
287 unsafe fn merge_pipeline_caches<'a, I>(
288 &self,
289 target: &mut B::PipelineCache,
290 sources: I,
291 ) -> Result<(), OutOfMemory>
292 where
293 I: Iterator<Item = &'a B::PipelineCache>;
294
295 /// Destroy a pipeline cache object.
296 unsafe fn destroy_pipeline_cache(&self, cache: B::PipelineCache);
297
298 /// Create a graphics pipeline.
299 ///
300 /// # Arguments
301 ///
302 /// * `desc` - the [description][crate::pso::GraphicsPipelineDesc] of
303 /// the graphics pipeline to create.
304 /// * `cache` - the pipeline cache,
305 /// [obtained from this device][Device::create_pipeline_cache],
306 /// used for faster PSO creation.
307 unsafe fn create_graphics_pipeline<'a>(
308 &self,
309 desc: &pso::GraphicsPipelineDesc<'a, B>,
310 cache: Option<&B::PipelineCache>,
311 ) -> Result<B::GraphicsPipeline, pso::CreationError>;
312
313 /// Destroy a graphics pipeline.
314 ///
315 /// The graphics pipeline shouldn't be destroyed before any submitted command buffer,
316 /// which references the graphics pipeline, has finished execution.
317 unsafe fn destroy_graphics_pipeline(&self, pipeline: B::GraphicsPipeline);
318
319 /// Create a compute pipeline.
320 unsafe fn create_compute_pipeline<'a>(
321 &self,
322 desc: &pso::ComputePipelineDesc<'a, B>,
323 cache: Option<&B::PipelineCache>,
324 ) -> Result<B::ComputePipeline, pso::CreationError>;
325
326 /// Destroy a compute pipeline.
327 ///
328 /// The compute pipeline shouldn't be destroyed before any submitted command buffer,
329 /// which references the compute pipeline, has finished execution.
330 unsafe fn destroy_compute_pipeline(&self, pipeline: B::ComputePipeline);
331
332 /// Create a new framebuffer object.
333 ///
334 /// # Safety
335 /// - `extent.width`, `extent.height` and `extent.depth` **must** be greater than `0`.
336 unsafe fn create_framebuffer<I>(
337 &self,
338 pass: &B::RenderPass,
339 attachments: I,
340 extent: image::Extent,
341 ) -> Result<B::Framebuffer, OutOfMemory>
342 where
343 I: Iterator<Item = image::FramebufferAttachment>;
344
345 /// Destroy a framebuffer.
346 ///
347 /// The framebuffer shouldn't be destroyed before any submitted command buffer,
348 /// which references the framebuffer, has finished execution.
349 unsafe fn destroy_framebuffer(&self, buf: B::Framebuffer);
350
351 /// Create a new shader module object from the SPIR-V binary data.
352 ///
353 /// Once a shader module has been created, any [entry points][crate::pso::EntryPoint]
354 /// it contains can be used in pipeline shader stages of
355 /// [compute pipelines][crate::pso::ComputePipelineDesc] and
356 /// [graphics pipelines][crate::pso::GraphicsPipelineDesc].
357 unsafe fn create_shader_module(&self, spirv: &[u32]) -> Result<B::ShaderModule, ShaderError>;
358
359 /// Create a new shader module from the `naga` module.
360 unsafe fn create_shader_module_from_naga(
361 &self,
362 shader: NagaShader,
363 ) -> Result<B::ShaderModule, (ShaderError, NagaShader)> {
364 Err((ShaderError::Unsupported, shader))
365 }
366
367 /// Destroy a shader module module
368 ///
369 /// A shader module can be destroyed while pipelines created using its shaders are still in use.
370 unsafe fn destroy_shader_module(&self, shader: B::ShaderModule);
371
372 /// Create a new buffer (unbound).
373 ///
374 /// The created buffer won't have associated memory until `bind_buffer_memory` is called.
375 unsafe fn create_buffer(
376 &self,
377 size: u64,
378 usage: buffer::Usage,
379 sparse: memory::SparseFlags,
380 ) -> Result<B::Buffer, buffer::CreationError>;
381
382 /// Get memory requirements for the buffer
383 unsafe fn get_buffer_requirements(&self, buf: &B::Buffer) -> Requirements;
384
385 /// Bind memory to a buffer.
386 ///
387 /// Be sure to check that there is enough memory available for the buffer.
388 /// Use `get_buffer_requirements` to acquire the memory requirements.
389 unsafe fn bind_buffer_memory(
390 &self,
391 memory: &B::Memory,
392 offset: u64,
393 buf: &mut B::Buffer,
394 ) -> Result<(), BindError>;
395
396 /// Destroy a buffer.
397 ///
398 /// The buffer shouldn't be destroyed before any submitted command buffer,
399 /// which references the images, has finished execution.
400 unsafe fn destroy_buffer(&self, buffer: B::Buffer);
401
402 /// Create a new buffer view object
403 unsafe fn create_buffer_view(
404 &self,
405 buf: &B::Buffer,
406 fmt: Option<format::Format>,
407 range: buffer::SubRange,
408 ) -> Result<B::BufferView, buffer::ViewCreationError>;
409
410 /// Destroy a buffer view object
411 unsafe fn destroy_buffer_view(&self, view: B::BufferView);
412
413 //TODO: add a list of supported formats for casting the views
414
415 /// Create a new image object
416 unsafe fn create_image(
417 &self,
418 kind: image::Kind,
419 mip_levels: image::Level,
420 format: format::Format,
421 tiling: image::Tiling,
422 usage: image::Usage,
423 sparse: memory::SparseFlags,
424 view_caps: image::ViewCapabilities,
425 ) -> Result<B::Image, image::CreationError>;
426
427 /// Get memory requirements for the Image
428 unsafe fn get_image_requirements(&self, image: &B::Image) -> Requirements;
429
430 ///
431 unsafe fn get_image_subresource_footprint(
432 &self,
433 image: &B::Image,
434 subresource: image::Subresource,
435 ) -> image::SubresourceFootprint;
436
437 /// Bind device memory to an image object
438 unsafe fn bind_image_memory(
439 &self,
440 memory: &B::Memory,
441 offset: u64,
442 image: &mut B::Image,
443 ) -> Result<(), BindError>;
444
445 /// Destroy an image.
446 ///
447 /// The image shouldn't be destroyed before any submitted command buffer,
448 /// which references the images, has finished execution.
449 unsafe fn destroy_image(&self, image: B::Image);
450
451 /// Create an image view from an existing image
452 unsafe fn create_image_view(
453 &self,
454 image: &B::Image,
455 view_kind: image::ViewKind,
456 format: format::Format,
457 swizzle: format::Swizzle,
458 usage: image::Usage,
459 range: image::SubresourceRange,
460 ) -> Result<B::ImageView, image::ViewCreationError>;
461
462 /// Destroy an image view object
463 unsafe fn destroy_image_view(&self, view: B::ImageView);
464
465 /// Create a new sampler object
466 unsafe fn create_sampler(
467 &self,
468 desc: &image::SamplerDesc,
469 ) -> Result<B::Sampler, AllocationError>;
470
471 /// Destroy a sampler object
472 unsafe fn destroy_sampler(&self, sampler: B::Sampler);
473
474 /// Create a descriptor pool.
475 ///
476 /// Descriptor pools allow allocation of descriptor sets.
477 /// The pool can't be modified directly, only through updating descriptor sets.
478 unsafe fn create_descriptor_pool<I>(
479 &self,
480 max_sets: usize,
481 descriptor_ranges: I,
482 flags: DescriptorPoolCreateFlags,
483 ) -> Result<B::DescriptorPool, OutOfMemory>
484 where
485 I: Iterator<Item = pso::DescriptorRangeDesc>;
486
487 /// Destroy a descriptor pool object
488 ///
489 /// When a pool is destroyed, all descriptor sets allocated from the pool are implicitly freed
490 /// and become invalid. Descriptor sets allocated from a given pool do not need to be freed
491 /// before destroying that descriptor pool.
492 unsafe fn destroy_descriptor_pool(&self, pool: B::DescriptorPool);
493
494 /// Create a descriptor set layout.
495 ///
496 /// A descriptor set layout object is defined by an array of zero or more descriptor bindings.
497 /// Each individual descriptor binding is specified by a descriptor type, a count (array size)
498 /// of the number of descriptors in the binding, a set of shader stages that **can** access the
499 /// binding, and (if using immutable samplers) an array of sampler descriptors.
500 unsafe fn create_descriptor_set_layout<'a, I, J>(
501 &self,
502 bindings: I,
503 immutable_samplers: J,
504 ) -> Result<B::DescriptorSetLayout, OutOfMemory>
505 where
506 I: Iterator<Item = pso::DescriptorSetLayoutBinding>,
507 J: Iterator<Item = &'a B::Sampler>;
508
509 /// Destroy a descriptor set layout object
510 unsafe fn destroy_descriptor_set_layout(&self, layout: B::DescriptorSetLayout);
511
512 /// Specifying the parameters of a descriptor set write operation.
513 unsafe fn write_descriptor_set<'a, I>(&self, op: pso::DescriptorSetWrite<'a, B, I>)
514 where
515 I: Iterator<Item = pso::Descriptor<'a, B>>;
516
517 /// Structure specifying a copy descriptor set operation.
518 unsafe fn copy_descriptor_set<'a>(&self, op: pso::DescriptorSetCopy<'a, B>);
519
520 /// Map a memory object into application address space
521 ///
522 /// Call `map_memory()` to retrieve a host virtual address pointer to a region of a mappable memory object
523 unsafe fn map_memory(
524 &self,
525 memory: &mut B::Memory,
526 segment: Segment,
527 ) -> Result<*mut u8, MapError>;
528
529 /// Flush mapped memory ranges
530 unsafe fn flush_mapped_memory_ranges<'a, I>(&self, ranges: I) -> Result<(), OutOfMemory>
531 where
532 I: Iterator<Item = (&'a B::Memory, Segment)>;
533
534 /// Invalidate ranges of non-coherent memory from the host caches
535 unsafe fn invalidate_mapped_memory_ranges<'a, I>(&self, ranges: I) -> Result<(), OutOfMemory>
536 where
537 I: Iterator<Item = (&'a B::Memory, Segment)>;
538
539 /// Unmap a memory object once host access to it is no longer needed by the application
540 unsafe fn unmap_memory(&self, memory: &mut B::Memory);
541
542 /// Create a new semaphore object.
543 fn create_semaphore(&self) -> Result<B::Semaphore, OutOfMemory>;
544
545 /// Destroy a semaphore object.
546 unsafe fn destroy_semaphore(&self, semaphore: B::Semaphore);
547
548 /// Create a new fence object.
549 ///
550 /// Fences are a synchronization primitive that **can** be used to insert a dependency from
551 /// a queue to the host.
552 /// Fences have two states - signaled and unsignaled.
553 ///
554 /// A fence **can** be signaled as part of the execution of a
555 /// [queue submission][crate::queue::Queue::submit] command.
556 ///
557 /// Fences **can** be unsignaled on the host with
558 /// [`reset_fence`][Device::reset_fence].
559 ///
560 /// Fences **can** be waited on by the host with the
561 /// [`wait_for_fences`][Device::wait_for_fences] command.
562 ///
563 /// A fence's current state **can** be queried with
564 /// [`get_fence_status`][Device::get_fence_status].
565 ///
566 /// # Arguments
567 ///
568 /// * `signaled` - the fence will be in its signaled state.
569 fn create_fence(&self, signaled: bool) -> Result<B::Fence, OutOfMemory>;
570
571 /// Resets a given fence to its original, unsignaled state.
572 unsafe fn reset_fence(&self, fence: &mut B::Fence) -> Result<(), OutOfMemory>;
573
574 /// Blocks until the given fence is signaled.
575 /// Returns true if the fence was signaled before the timeout.
576 unsafe fn wait_for_fence(&self, fence: &B::Fence, timeout_ns: u64) -> Result<bool, WaitError> {
577 self.wait_for_fences(iter::once(fence), WaitFor::All, timeout_ns)
578 }
579
580 /// Blocks until all or one of the given fences are signaled.
581 /// Returns true if fences were signaled before the timeout.
582 unsafe fn wait_for_fences<'a, I>(
583 &self,
584 fences: I,
585 wait: WaitFor,
586 timeout_ns: u64,
587 ) -> Result<bool, WaitError>
588 where
589 I: Iterator<Item = &'a B::Fence>,
590 {
591 use std::{thread, time};
592 fn to_ns(duration: time::Duration) -> u64 {
593 duration.as_secs() * 1_000_000_000 + duration.subsec_nanos() as u64
594 }
595
596 let start = time::Instant::now();
597 match wait {
598 WaitFor::All => {
599 for fence in fences {
600 if !self.wait_for_fence(fence, 0)? {
601 let elapsed_ns = to_ns(start.elapsed());
602 if elapsed_ns > timeout_ns {
603 return Ok(false);
604 }
605 if !self.wait_for_fence(fence, timeout_ns - elapsed_ns)? {
606 return Ok(false);
607 }
608 }
609 }
610 Ok(true)
611 }
612 WaitFor::Any => {
613 let fences: Vec<_> = fences.collect();
614 loop {
615 for &fence in &fences {
616 if self.wait_for_fence(fence, 0)? {
617 return Ok(true);
618 }
619 }
620 if to_ns(start.elapsed()) >= timeout_ns {
621 return Ok(false);
622 }
623 thread::sleep(time::Duration::from_millis(1));
624 }
625 }
626 }
627 }
628
629 /// true for signaled, false for not ready
630 unsafe fn get_fence_status(&self, fence: &B::Fence) -> Result<bool, DeviceLost>;
631
632 /// Destroy a fence object
633 unsafe fn destroy_fence(&self, fence: B::Fence);
634
635 /// Create an event object.
636 fn create_event(&self) -> Result<B::Event, OutOfMemory>;
637
638 /// Destroy an event object.
639 unsafe fn destroy_event(&self, event: B::Event);
640
641 /// Query the status of an event.
642 ///
643 /// Returns `true` if the event is set, or `false` if it is reset.
644 unsafe fn get_event_status(&self, event: &B::Event) -> Result<bool, WaitError>;
645
646 /// Sets an event.
647 unsafe fn set_event(&self, event: &mut B::Event) -> Result<(), OutOfMemory>;
648
649 /// Resets an event.
650 unsafe fn reset_event(&self, event: &mut B::Event) -> Result<(), OutOfMemory>;
651
652 /// Create a new query pool object
653 ///
654 /// Queries are managed using query pool objects. Each query pool is a collection of a specific
655 /// number of queries of a particular type.
656 unsafe fn create_query_pool(
657 &self,
658 ty: query::Type,
659 count: query::Id,
660 ) -> Result<B::QueryPool, query::CreationError>;
661
662 /// Destroy a query pool object
663 unsafe fn destroy_query_pool(&self, pool: B::QueryPool);
664
665 /// Get query pool results into the specified CPU memory.
666 /// Returns `Ok(false)` if the results are not ready yet and neither of `WAIT` or `PARTIAL` flags are set.
667 unsafe fn get_query_pool_results(
668 &self,
669 pool: &B::QueryPool,
670 queries: Range<query::Id>,
671 data: &mut [u8],
672 stride: buffer::Stride,
673 flags: query::ResultFlags,
674 ) -> Result<bool, WaitError>;
675
676 /// Wait for all queues associated with this device to idle.
677 ///
678 /// Host access to all queues needs to be **externally** sycnhronized!
679 fn wait_idle(&self) -> Result<(), OutOfMemory>;
680
681 /// Associate a name with an image, for easier debugging in external tools or with validation
682 /// layers that can print a friendly name when referring to objects in error messages
683 unsafe fn set_image_name(&self, image: &mut B::Image, name: &str);
684 /// Associate a name with a buffer, for easier debugging in external tools or with validation
685 /// layers that can print a friendly name when referring to objects in error messages
686 unsafe fn set_buffer_name(&self, buffer: &mut B::Buffer, name: &str);
687 /// Associate a name with a command buffer, for easier debugging in external tools or with
688 /// validation layers that can print a friendly name when referring to objects in error messages
689 unsafe fn set_command_buffer_name(&self, command_buffer: &mut B::CommandBuffer, name: &str);
690 /// Associate a name with a semaphore, for easier debugging in external tools or with validation
691 /// layers that can print a friendly name when referring to objects in error messages
692 unsafe fn set_semaphore_name(&self, semaphore: &mut B::Semaphore, name: &str);
693 /// Associate a name with a fence, for easier debugging in external tools or with validation
694 /// layers that can print a friendly name when referring to objects in error messages
695 unsafe fn set_fence_name(&self, fence: &mut B::Fence, name: &str);
696 /// Associate a name with a framebuffer, for easier debugging in external tools or with
697 /// validation layers that can print a friendly name when referring to objects in error messages
698 unsafe fn set_framebuffer_name(&self, framebuffer: &mut B::Framebuffer, name: &str);
699 /// Associate a name with a render pass, for easier debugging in external tools or with
700 /// validation layers that can print a friendly name when referring to objects in error messages
701 unsafe fn set_render_pass_name(&self, render_pass: &mut B::RenderPass, name: &str);
702 /// Associate a name with a descriptor set, for easier debugging in external tools or with
703 /// validation layers that can print a friendly name when referring to objects in error messages
704 unsafe fn set_descriptor_set_name(&self, descriptor_set: &mut B::DescriptorSet, name: &str);
705 /// Associate a name with a descriptor set layout, for easier debugging in external tools or
706 /// with validation layers that can print a friendly name when referring to objects in error
707 /// messages
708 unsafe fn set_descriptor_set_layout_name(
709 &self,
710 descriptor_set_layout: &mut B::DescriptorSetLayout,
711 name: &str,
712 );
713 /// Associate a name with a pipeline layout, for easier debugging in external tools or with
714 /// validation layers that can print a friendly name when referring to objects in error messages
715 unsafe fn set_pipeline_layout_name(&self, pipeline_layout: &mut B::PipelineLayout, name: &str);
716
717 /// Control the power state of the provided display
718 unsafe fn set_display_power_state(
719 &self,
720 display: &display::Display<B>,
721 power_state: &display::control::PowerState,
722 ) -> Result<(), display::control::DisplayControlError>;
723
724 /// Register device event
725 unsafe fn register_device_event(
726 &self,
727 device_event: &display::control::DeviceEvent,
728 fence: &mut B::Fence,
729 ) -> Result<(), display::control::DisplayControlError>;
730
731 /// Register display event
732 unsafe fn register_display_event(
733 &self,
734 display: &display::Display<B>,
735 display_event: &display::control::DisplayEvent,
736 fence: &mut B::Fence,
737 ) -> Result<(), display::control::DisplayControlError>;
738
739 /// Create, allocate and bind a buffer that can be exported.
740 /// # Arguments
741 ///
742 /// * `external_memory_type_flags` - the external memory types the buffer will be valid to be used.
743 /// * `usage` - the usage of the buffer.
744 /// * `sparse` - the sparse flags of the buffer.
745 /// * `type_mask` - a memory type mask containing all the desired memory type ids.
746 /// * `size` - the size of the buffer.
747 /// # Errors
748 ///
749 /// - Returns `OutOfMemory` if the implementation goes out of memory during the operation.
750 /// - Returns `TooManyObjects` if the implementation can allocate buffers no more.
751 /// - Returns `NoValidMemoryTypeId` if the no one of the desired memory type id is valid for the implementation.
752 /// - Returns `InvalidExternalHandle` if the requested external memory type is invalid for the implementation.
753 ///
754 unsafe fn create_allocate_external_buffer(
755 &self,
756 external_memory_type_flags: external_memory::ExternalBufferMemoryType,
757 usage: buffer::Usage,
758 sparse: memory::SparseFlags,
759 type_mask: u32,
760 size: u64,
761 ) -> Result<(B::Buffer, B::Memory), external_memory::ExternalResourceError>;
762
763 /// Import external memory as binded buffer and memory.
764 /// # Arguments
765 ///
766 /// * `external_memory` - the external memory types the buffer will be valid to be used.
767 /// * `usage` - the usage of the buffer.
768 /// * `sparse` - the sparse flags of the buffer.
769 /// * `type_mask` - a memory type mask containing all the desired memory type ids.
770 /// * `size` - the size of the buffer.
771 /// # Errors
772 ///
773 /// - Returns `OutOfMemory` if the implementation goes out of memory during the operation.
774 /// - Returns `TooManyObjects` if the implementation can allocate buffers no more.
775 /// - Returns `NoValidMemoryTypeId` if the no one of the desired memory type id is valid for the implementation.
776 /// - Returns `InvalidExternalHandle` if the requested external memory type is invalid for the implementation.
777 ///
778 unsafe fn import_external_buffer(
779 &self,
780 external_memory: external_memory::ExternalBufferMemory,
781 usage: buffer::Usage,
782 sparse: memory::SparseFlags,
783 type_mask: u32,
784 size: u64,
785 ) -> Result<(B::Buffer, B::Memory), external_memory::ExternalResourceError>;
786
787 /// Create, allocate and bind an image that can be exported.
788 /// # Arguments
789 ///
790 /// * `external_memory` - the external memory types the image will be valid to be used.
791 /// * `kind` - the image kind.
792 /// * `mip_levels` - the mip levels of the image.
793 /// * `format` - the format of the image.
794 /// * `tiling` - the tiling mode of the image.
795 /// * `dimensions` - the dimensions of the image.
796 /// * `usage` - the usage of the image.
797 /// * `sparse` - the sparse flags of the image.
798 /// * `view_caps` - the view capabilities of the image.
799 /// * `type_mask` - a memory type mask containing all the desired memory type ids.
800 /// # Errors
801 ///
802 /// - Returns `OutOfMemory` if the implementation goes out of memory during the operation.
803 /// - Returns `TooManyObjects` if the implementation can allocate images no more.
804 /// - Returns `NoValidMemoryTypeId` if the no one of the desired memory type id is valid for the implementation.
805 /// - Returns `InvalidExternalHandle` if the requested external memory type is invalid for the implementation.
806 ///
807 unsafe fn create_allocate_external_image(
808 &self,
809 external_memory_type: external_memory::ExternalImageMemoryType,
810 kind: image::Kind,
811 mip_levels: image::Level,
812 format: format::Format,
813 tiling: image::Tiling,
814 usage: image::Usage,
815 sparse: memory::SparseFlags,
816 view_caps: image::ViewCapabilities,
817 type_mask: u32,
818 ) -> Result<(B::Image, B::Memory), external_memory::ExternalResourceError>;
819
820 /// Import external memory as binded image and memory.
821 /// # Arguments
822 ///
823 /// * `external_memory` - the external memory types the image will be valid to be used.
824 /// * `kind` - the image kind.
825 /// * `mip_levels` - the mip levels of the image.
826 /// * `format` - the format of the image.
827 /// * `tiling` - the tiling mode of the image.
828 /// * `dimensions` - the dimensions of the image.
829 /// * `usage` - the usage of the image.
830 /// * `sparse` - the sparse flags of the image.
831 /// * `view_caps` - the view capabilities of the image.
832 /// * `type_mask` - a memory type mask containing all the desired memory type ids.
833 /// # Errors
834 ///
835 /// - Returns `OutOfMemory` if the implementation goes out of memory during the operation.
836 /// - Returns `TooManyObjects` if the implementation can allocate images no more.
837 /// - Returns `NoValidMemoryTypeId` if the no one of the desired memory type id is valid for the implementation.
838 /// - Returns `InvalidExternalHandle` if the requested external memory type is invalid for the implementation.
839 ///
840 unsafe fn import_external_image(
841 &self,
842 external_memory: external_memory::ExternalImageMemory,
843 kind: image::Kind,
844 mip_levels: image::Level,
845 format: format::Format,
846 tiling: image::Tiling,
847 usage: image::Usage,
848 sparse: memory::SparseFlags,
849 view_caps: image::ViewCapabilities,
850 type_mask: u32,
851 ) -> Result<(B::Image, B::Memory), external_memory::ExternalResourceError>;
852
853 /// Export memory as os type (Fd, Handle or Ptr) based on the requested external memory type.
854 /// # Arguments
855 ///
856 /// * `external_memory_type` - the external memory type the memory will be exported to.
857 /// * `memory` - the memory object.
858 /// # Errors
859 ///
860 /// - Returns `OutOfMemory` if the implementation goes out of memory during the operation.
861 /// - Returns `TooManyObjects` if the implementation can allocate images no more.
862 /// - Returns `InvalidExternalHandle` if the requested external memory type is invalid for the implementation.
863 ///
864 unsafe fn export_memory(
865 &self,
866 external_memory_type: external_memory::ExternalMemoryType,
867 memory: &B::Memory,
868 ) -> Result<external_memory::PlatformMemory, external_memory::ExternalMemoryExportError>;
869
870 /// Retrieve the underlying drm format modifier from an image, if any.
871 /// # Arguments
872 ///
873 /// * `image` - the image object.
874 unsafe fn drm_format_modifier(&self, image: &B::Image) -> Option<format::DrmModifier>;
875
876 /// Starts frame capture.
877 fn start_capture(&self);
878
879 /// Stops frame capture.
880 fn stop_capture(&self);
881}