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}