gfx_hal/command/
mod.rs

1//! Command buffers.
2//!
3//! A command buffer collects a list of commands to be submitted to the device.
4//!
5//! Each command buffer has specific capabilities for graphics, compute or transfer operations,
6//! and can be either a *primary* command buffer or a *secondary* command buffer.
7//!
8//! Operations are always initiated by a primary command buffer,
9//! but a primary command buffer can contain calls to secondary command buffers
10//! that contain snippets of commands that do specific things, similar to function calls.
11//!
12//! All the possible commands are exposed by the [`CommandBuffer`][CommandBuffer] trait.
13
14// TODO: Document pipelines and subpasses better.
15
16mod clear;
17mod structs;
18
19use crate::{
20    buffer,
21    image::{Filter, Layout, SubresourceRange},
22    memory::{Barrier, Dependencies},
23    pass, pso, query, Backend, DrawCount, IndexCount, IndexType, InstanceCount, TaskCount,
24    VertexCount, VertexOffset, WorkGroupCount,
25};
26
27use std::{any::Any, fmt, ops::Range};
28
29pub use self::clear::*;
30pub use self::structs::*;
31
32/// Offset for dynamic descriptors.
33pub type DescriptorSetOffset = u32;
34
35bitflags! {
36    /// Option flags for various command buffer settings.
37    #[derive(Default)]
38    pub struct CommandBufferFlags: u32 {
39        /// Says that the command buffer will be recorded, submitted only once, and then reset and re-filled
40        /// for another submission.
41        const ONE_TIME_SUBMIT = 0x1;
42
43        /// If set on a secondary command buffer, it says the command buffer takes place entirely inside
44        /// a render pass. Ignored on primary command buffer.
45        const RENDER_PASS_CONTINUE = 0x2;
46
47        /// Says that a command buffer can be recorded into multiple primary command buffers,
48        /// and submitted to a queue while it is still pending.
49        const SIMULTANEOUS_USE = 0x4;
50    }
51}
52
53/// An enum that indicates whether a command buffer is primary or secondary.
54#[derive(Clone, Copy, Debug, PartialEq)]
55pub enum Level {
56    /// Can be submitted to a queue for execution, but cannot be called from other
57    /// command buffers.
58    Primary,
59    /// Cannot be submitted directly, but can be called from primary command buffers.
60    Secondary,
61}
62
63/// Specifies how commands for the following render passes will be recorded.
64#[derive(Debug)]
65pub enum SubpassContents {
66    /// Contents of the subpass will be inline in the command buffer,
67    /// NOT in secondary command buffers.
68    Inline,
69    /// Contents of the subpass will be in secondary command buffers, and
70    /// the primary command buffer will only contain `execute_command()` calls
71    /// until the subpass or render pass is complete.
72    SecondaryBuffers,
73}
74
75/// A render attachment provided to `begin_render_pass`.
76#[derive(Debug)]
77pub struct RenderAttachmentInfo<'a, B: Backend> {
78    /// View of the attachment image.
79    pub image_view: &'a B::ImageView,
80    /// Clear value, if needed.
81    pub clear_value: ClearValue,
82}
83
84#[allow(missing_docs)]
85#[derive(Debug)]
86pub struct CommandBufferInheritanceInfo<'a, B: Backend> {
87    pub subpass: Option<pass::Subpass<'a, B>>,
88    pub framebuffer: Option<&'a B::Framebuffer>,
89    pub occlusion_query_enable: bool,
90    pub occlusion_query_flags: query::ControlFlags,
91    pub pipeline_statistics: query::PipelineStatistic,
92}
93
94impl<'a, B: Backend> Default for CommandBufferInheritanceInfo<'a, B> {
95    fn default() -> Self {
96        CommandBufferInheritanceInfo {
97            subpass: None,
98            framebuffer: None,
99            occlusion_query_enable: false,
100            occlusion_query_flags: query::ControlFlags::empty(),
101            pipeline_statistics: query::PipelineStatistic::empty(),
102        }
103    }
104}
105
106/// A trait that describes all the operations that must be
107/// provided by a `Backend`'s command buffer.
108pub trait CommandBuffer<B: Backend>: fmt::Debug + Any + Send + Sync {
109    /// Begins recording commands to a command buffer.
110    unsafe fn begin(
111        &mut self,
112        flags: CommandBufferFlags,
113        inheritance_info: CommandBufferInheritanceInfo<B>,
114    );
115
116    /// Begins recording a primary command buffer
117    /// (that has no inheritance information).
118    unsafe fn begin_primary(&mut self, flags: CommandBufferFlags) {
119        self.begin(flags, CommandBufferInheritanceInfo::default());
120    }
121
122    /// Finish recording commands to a command buffer.
123    unsafe fn finish(&mut self);
124
125    /// Empties the command buffer, optionally releasing all
126    /// resources from the commands that have been submitted.
127    unsafe fn reset(&mut self, release_resources: bool);
128
129    // TODO: This REALLY needs to be deeper, but it's complicated.
130    // Should probably be a whole book chapter on synchronization and stuff really.
131    /// Inserts a synchronization dependency between pipeline stages
132    /// in the command buffer.
133    unsafe fn pipeline_barrier<'a, T>(
134        &mut self,
135        stages: Range<pso::PipelineStage>,
136        dependencies: Dependencies,
137        barriers: T,
138    ) where
139        T: Iterator<Item = Barrier<'a, B>>;
140
141    /// Fill a buffer with the given `u32` value.
142    unsafe fn fill_buffer(&mut self, buffer: &B::Buffer, range: buffer::SubRange, data: u32);
143
144    /// Copy data from the given slice into a buffer.
145    unsafe fn update_buffer(&mut self, buffer: &B::Buffer, offset: buffer::Offset, data: &[u8]);
146
147    /// Clears an image to the given color/depth/stencil.
148    unsafe fn clear_image<T>(
149        &mut self,
150        image: &B::Image,
151        layout: Layout,
152        value: ClearValue,
153        subresource_ranges: T,
154    ) where
155        T: Iterator<Item = SubresourceRange>;
156
157    /// Takes an iterator of attachments and an iterator of rect's,
158    /// and clears the given rect's for *each* attachment.
159    unsafe fn clear_attachments<T, U>(&mut self, clears: T, rects: U)
160    where
161        T: Iterator<Item = AttachmentClear>,
162        U: Iterator<Item = pso::ClearRect>;
163
164    /// "Resolves" a multisampled image, converting it into a non-multisampled
165    /// image. Takes an iterator of regions to apply the resolution to.
166    unsafe fn resolve_image<T>(
167        &mut self,
168        src: &B::Image,
169        src_layout: Layout,
170        dst: &B::Image,
171        dst_layout: Layout,
172        regions: T,
173    ) where
174        T: Iterator<Item = ImageResolve>;
175
176    /// Copies regions from the source to destination image,
177    /// applying scaling, filtering and potentially format conversion.
178    unsafe fn blit_image<T>(
179        &mut self,
180        src: &B::Image,
181        src_layout: Layout,
182        dst: &B::Image,
183        dst_layout: Layout,
184        filter: Filter,
185        regions: T,
186    ) where
187        T: Iterator<Item = ImageBlit>;
188
189    /// Bind the index buffer view, making it the "current" one that draw commands
190    /// will operate on.
191    unsafe fn bind_index_buffer(
192        &mut self,
193        buffer: &B::Buffer,
194        sub: buffer::SubRange,
195        ty: IndexType,
196    );
197
198    /// Bind the vertex buffer set, making it the "current" one that draw commands
199    /// will operate on.
200    ///
201    /// Each buffer passed corresponds to the vertex input binding with the same index,
202    /// starting from an offset index `first_binding`. For example an iterator with
203    /// two items and `first_binding` of 1 would fill vertex buffer binding numbers
204    /// 1 and 2.
205    ///
206    /// This binding number refers only to binding points for vertex buffers and is
207    /// completely separate from the binding numbers of `Descriptor`s in `DescriptorSet`s.
208    /// It needs to match with the `VertexBufferDesc` and `AttributeDesc`s to which the
209    /// data from each bound vertex buffer should flow.
210    ///
211    /// The `buffers` iterator should yield the `Buffer` to bind, as well as a subrange,
212    /// in bytes, into that buffer where the vertex data that should be bound.
213    unsafe fn bind_vertex_buffers<'a, T>(&mut self, first_binding: pso::BufferIndex, buffers: T)
214    where
215        T: Iterator<Item = (&'a B::Buffer, buffer::SubRange)>;
216
217    /// Set the [viewport][crate::pso::Viewport] parameters for the rasterizer.
218    ///
219    /// Each viewport passed corresponds to the viewport with the same index,
220    /// starting from an offset index `first_viewport`.
221    ///
222    /// # Errors
223    ///
224    /// This function does not return an error. Invalid usage of this function
225    /// will result in undefined behavior.
226    ///
227    /// - Command buffer must be in recording state.
228    /// - Number of viewports must be between 1 and `max_viewports - first_viewport`.
229    /// - The first viewport must be less than `max_viewports`.
230    /// - Only queues with graphics capability support this function.
231    /// - The bound pipeline must not have baked viewport state.
232    /// - All viewports used by the pipeline must be specified before the first
233    ///   draw call.
234    unsafe fn set_viewports<T>(&mut self, first_viewport: u32, viewports: T)
235    where
236        T: Iterator<Item = pso::Viewport>;
237
238    /// Set the scissor rectangles for the rasterizer.
239    ///
240    /// Each scissor corresponds to the viewport with the same index, starting
241    /// from an offset index `first_scissor`.
242    ///
243    /// # Errors
244    ///
245    /// This function does not return an error. Invalid usage of this function
246    /// will result in undefined behavior.
247    ///
248    /// - Command buffer must be in recording state.
249    /// - Number of scissors must be between 1 and `max_viewports - first_scissor`.
250    /// - The first scissor must be less than `max_viewports`.
251    /// - Only queues with graphics capability support this function.
252    /// - The bound pipeline must not have baked scissor state.
253    /// - All scissors used by the pipeline must be specified before the first draw
254    ///   call.
255    unsafe fn set_scissors<T>(&mut self, first_scissor: u32, rects: T)
256    where
257        T: Iterator<Item = pso::Rect>;
258
259    /// Sets the stencil reference value for comparison operations and store operations.
260    /// Will be used on the LHS of stencil compare ops and as store value when the
261    /// store op is Reference.
262    unsafe fn set_stencil_reference(&mut self, faces: pso::Face, value: pso::StencilValue);
263
264    /// Sets the stencil read mask.
265    unsafe fn set_stencil_read_mask(&mut self, faces: pso::Face, value: pso::StencilValue);
266
267    /// Sets the stencil write mask.
268    unsafe fn set_stencil_write_mask(&mut self, faces: pso::Face, value: pso::StencilValue);
269
270    /// Set the blend constant values dynamically.
271    unsafe fn set_blend_constants(&mut self, color: pso::ColorValue);
272
273    /// Set the depth bounds test values dynamically.
274    unsafe fn set_depth_bounds(&mut self, bounds: Range<f32>);
275
276    /// Set the line width dynamically.
277    ///
278    /// Only valid to call if `Features::LINE_WIDTH` is enabled.
279    unsafe fn set_line_width(&mut self, width: f32);
280
281    /// Set the depth bias dynamically.
282    unsafe fn set_depth_bias(&mut self, depth_bias: pso::DepthBias);
283
284    /// Begins recording commands for a render pass on the given framebuffer.
285    ///
286    /// # Arguments
287    ///
288    /// * `render_area` - section of the framebuffer to render.
289    /// * `attachments` - iterator of [attachments][crate::command::RenderAttachmentInfo]
290    ///   that has both the image views and the clear values
291    /// * `first_subpass` - specifies, for the first subpass, whether the
292    ///   rendering commands are provided inline or whether the render
293    ///   pass is composed of subpasses.
294    unsafe fn begin_render_pass<'a, T>(
295        &mut self,
296        render_pass: &B::RenderPass,
297        framebuffer: &B::Framebuffer,
298        render_area: pso::Rect,
299        attachments: T,
300        first_subpass: SubpassContents,
301    ) where
302        T: Iterator<Item = RenderAttachmentInfo<'a, B>>;
303
304    /// Steps to the next subpass in the current render pass.
305    unsafe fn next_subpass(&mut self, contents: SubpassContents);
306
307    /// Finishes recording commands for the current a render pass.
308    unsafe fn end_render_pass(&mut self);
309
310    /// Bind a graphics pipeline.
311    ///
312    /// # Errors
313    ///
314    /// This function does not return an error. Invalid usage of this function
315    /// will result in an error on `finish`.
316    ///
317    /// - Command buffer must be in recording state.
318    /// - Only queues with graphics capability support this function.
319    unsafe fn bind_graphics_pipeline(&mut self, pipeline: &B::GraphicsPipeline);
320
321    /// Takes an iterator of graphics `DescriptorSet`'s, and binds them to the command buffer.
322    /// `first_set` is the index that the first descriptor is mapped to in the command buffer.
323    unsafe fn bind_graphics_descriptor_sets<'a, I, J>(
324        &mut self,
325        layout: &B::PipelineLayout,
326        first_set: usize,
327        sets: I,
328        offsets: J,
329    ) where
330        I: Iterator<Item = &'a B::DescriptorSet>,
331        J: Iterator<Item = DescriptorSetOffset>;
332
333    /// Bind a compute pipeline.
334    ///
335    /// # Errors
336    ///
337    /// This function does not return an error. Invalid usage of this function
338    /// will result in an error on `finish`.
339    ///
340    /// - Command buffer must be in recording state.
341    /// - Only queues with compute capability support this function.
342    unsafe fn bind_compute_pipeline(&mut self, pipeline: &B::ComputePipeline);
343
344    /// Takes an iterator of compute `DescriptorSet`'s, and binds them to the command buffer,
345    /// `first_set` is the index that the first descriptor is mapped to in the command buffer.
346    unsafe fn bind_compute_descriptor_sets<'a, I, J>(
347        &mut self,
348        layout: &B::PipelineLayout,
349        first_set: usize,
350        sets: I,
351        offsets: J,
352    ) where
353        I: Iterator<Item = &'a B::DescriptorSet>,
354        J: Iterator<Item = DescriptorSetOffset>;
355
356    /// Execute a workgroup in the compute pipeline. `x`, `y` and `z` are the
357    /// number of local workgroups to dispatch along each "axis"; a total of `x`*`y`*`z`
358    /// local workgroups will be created.
359    ///
360    /// # Errors
361    ///
362    /// This function does not return an error. Invalid usage of this function
363    /// will result in an error on `finish`.
364    ///
365    /// - Command buffer must be in recording state.
366    /// - A compute pipeline must be bound using `bind_compute_pipeline`.
367    /// - Only queues with compute capability support this function.
368    /// - This function must be called outside of a render pass.
369    /// - `count` must be less than or equal to `Limits::max_compute_work_group_count`
370    ///
371    /// TODO:
372    unsafe fn dispatch(&mut self, count: WorkGroupCount);
373
374    /// Works similarly to `dispatch()` but reads parameters from the given
375    /// buffer during execution.
376    unsafe fn dispatch_indirect(&mut self, buffer: &B::Buffer, offset: buffer::Offset);
377
378    /// Adds a command to copy regions from the source to destination buffer.
379    unsafe fn copy_buffer<T>(&mut self, src: &B::Buffer, dst: &B::Buffer, regions: T)
380    where
381        T: Iterator<Item = BufferCopy>;
382
383    /// Copies regions from the source to the destination images, which
384    /// have the given layouts.  No format conversion is done; the source and destination
385    /// `Layout`'s **must** have the same sized image formats (such as `Rgba8Unorm` and
386    /// `R32`, both of which are 32 bits).
387    unsafe fn copy_image<T>(
388        &mut self,
389        src: &B::Image,
390        src_layout: Layout,
391        dst: &B::Image,
392        dst_layout: Layout,
393        regions: T,
394    ) where
395        T: Iterator<Item = ImageCopy>;
396
397    /// Copies regions from the source buffer to the destination image.
398    unsafe fn copy_buffer_to_image<T>(
399        &mut self,
400        src: &B::Buffer,
401        dst: &B::Image,
402        dst_layout: Layout,
403        regions: T,
404    ) where
405        T: Iterator<Item = BufferImageCopy>;
406
407    /// Copies regions from the source image to the destination buffer.
408    unsafe fn copy_image_to_buffer<T>(
409        &mut self,
410        src: &B::Image,
411        src_layout: Layout,
412        dst: &B::Buffer,
413        regions: T,
414    ) where
415        T: Iterator<Item = BufferImageCopy>;
416
417    // TODO: This explanation needs improvement.
418    /// Performs a non-indexed drawing operation, fetching vertex attributes
419    /// from the currently bound vertex buffers.  It performs instanced
420    /// drawing, drawing `instances.len()`
421    /// times with an `instanceIndex` starting with the start of the range.
422    unsafe fn draw(&mut self, vertices: Range<VertexCount>, instances: Range<InstanceCount>);
423
424    /// Performs indexed drawing, drawing the range of indices
425    /// given by the current index buffer and any bound vertex buffers.
426    /// `base_vertex` specifies the vertex offset corresponding to index 0.
427    /// That is, the offset into the vertex buffer is `(current_index + base_vertex)`
428    ///
429    /// It also performs instanced drawing, identical to `draw()`.
430    unsafe fn draw_indexed(
431        &mut self,
432        indices: Range<IndexCount>,
433        base_vertex: VertexOffset,
434        instances: Range<InstanceCount>,
435    );
436
437    /// Functions identically to `draw()`, except the parameters are read
438    /// from the given buffer, starting at `offset` and increasing `stride`
439    /// bytes with each successive draw.  Performs `draw_count` draws total.
440    /// `draw_count` may be zero.
441    ///
442    /// Each draw command in the buffer is a series of 4 `u32` values specifying,
443    /// in order, the number of vertices to draw, the number of instances to draw,
444    /// the index of the first vertex to draw, and the instance ID of the first
445    /// instance to draw.
446    unsafe fn draw_indirect(
447        &mut self,
448        buffer: &B::Buffer,
449        offset: buffer::Offset,
450        draw_count: DrawCount,
451        stride: buffer::Stride,
452    );
453
454    /// Like `draw_indirect()`, this does indexed drawing a la `draw_indexed()` but
455    /// reads the draw parameters out of the given buffer.
456    ///
457    /// Each draw command in the buffer is a series of 5 values specifying,
458    /// in order, the number of indices, the number of instances, the first index,
459    /// the vertex offset, and the first instance.  All are `u32`'s except
460    /// the vertex offset, which is an `i32`.
461    unsafe fn draw_indexed_indirect(
462        &mut self,
463        buffer: &B::Buffer,
464        offset: buffer::Offset,
465        draw_count: DrawCount,
466        stride: buffer::Stride,
467    );
468
469    /// Functions identically to `draw_indirect()`, except the amount of draw
470    /// calls are specified by the u32 in `count_buffer` at `count_buffer_offset`.
471    /// There is a limit of `max_draw_count` invocations.
472    ///
473    /// Each draw command in the buffer is a series of 4 `u32` values specifying,
474    /// in order, the number of vertices to draw, the number of instances to draw,
475    /// the index of the first vertex to draw, and the instance ID of the first
476    /// instance to draw.
477    unsafe fn draw_indirect_count(
478        &mut self,
479        _buffer: &B::Buffer,
480        _offset: buffer::Offset,
481        _count_buffer: &B::Buffer,
482        _count_buffer_offset: buffer::Offset,
483        _max_draw_count: u32,
484        _stride: buffer::Stride,
485    );
486
487    /// Functions identically to `draw_indexed_indirect()`, except the amount of draw
488    /// calls are specified by the u32 in `count_buffer` at `count_buffer_offset`.
489    /// There is a limit of `max_draw_count` invocations.
490    ///
491    /// Each draw command in the buffer is a series of 5 values specifying,
492    /// in order, the number of indices, the number of instances, the first index,
493    /// the vertex offset, and the first instance.  All are `u32`'s except
494    /// the vertex offset, which is an `i32`.
495    unsafe fn draw_indexed_indirect_count(
496        &mut self,
497        _buffer: &B::Buffer,
498        _offset: buffer::Offset,
499        _count_buffer: &B::Buffer,
500        _count_buffer_offset: buffer::Offset,
501        _max_draw_count: u32,
502        _stride: buffer::Stride,
503    );
504
505    /// Dispatches `task_count` of threads. Similar to compute dispatch.
506    unsafe fn draw_mesh_tasks(&mut self, task_count: TaskCount, first_task: TaskCount);
507
508    /// Indirect version of `draw_mesh_tasks`. Analogous to `draw_indirect`, but for mesh shaders.
509    unsafe fn draw_mesh_tasks_indirect(
510        &mut self,
511        buffer: &B::Buffer,
512        offset: buffer::Offset,
513        draw_count: DrawCount,
514        stride: buffer::Stride,
515    );
516
517    /// Like `draw_mesh_tasks_indirect` except that the draw count is read by
518    /// the device from a buffer during execution. The command will read an
519    /// unsigned 32-bit integer from `count_buffer` located at `count_buffer_offset`
520    /// and use this as the draw count.
521    unsafe fn draw_mesh_tasks_indirect_count(
522        &mut self,
523        buffer: &B::Buffer,
524        offset: buffer::Offset,
525        count_buffer: &B::Buffer,
526        count_buffer_offset: buffer::Offset,
527        max_draw_count: DrawCount,
528        stride: buffer::Stride,
529    );
530
531    /// Signals an event once all specified stages of the shader pipeline have completed.
532    unsafe fn set_event(&mut self, event: &B::Event, stages: pso::PipelineStage);
533
534    /// Resets an event once all specified stages of the shader pipeline have completed.
535    unsafe fn reset_event(&mut self, event: &B::Event, stages: pso::PipelineStage);
536
537    /// Waits at some shader stage(s) until all events have been signalled.
538    ///
539    /// - `src_stages` specifies the shader pipeline stages in which the events were signalled.
540    /// - `dst_stages` specifies the shader pipeline stages at which execution should wait.
541    /// - `barriers` specifies a series of memory barriers to be executed before pipeline execution
542    ///   resumes.
543    unsafe fn wait_events<'a, I, J>(
544        &mut self,
545        events: I,
546        stages: Range<pso::PipelineStage>,
547        barriers: J,
548    ) where
549        I: Iterator<Item = &'a B::Event>,
550        J: Iterator<Item = Barrier<'a, B>>;
551
552    /// Begins a query operation.  Queries count operations or record timestamps
553    /// resulting from commands that occur between the beginning and end of the query,
554    /// and save the results to the query pool.
555    unsafe fn begin_query(&mut self, query: query::Query<B>, flags: query::ControlFlags);
556
557    /// End a query.
558    unsafe fn end_query(&mut self, query: query::Query<B>);
559
560    /// Reset/clear the values in the given range of the query pool.
561    unsafe fn reset_query_pool(&mut self, pool: &B::QueryPool, queries: Range<query::Id>);
562
563    /// Copy query results into a buffer.
564    unsafe fn copy_query_pool_results(
565        &mut self,
566        pool: &B::QueryPool,
567        queries: Range<query::Id>,
568        buffer: &B::Buffer,
569        offset: buffer::Offset,
570        stride: buffer::Stride,
571        flags: query::ResultFlags,
572    );
573
574    /// Requests a timestamp to be written.
575    unsafe fn write_timestamp(&mut self, stage: pso::PipelineStage, query: query::Query<B>);
576
577    /// Modify constant data in a graphics pipeline. Push constants are intended to modify data in a
578    /// pipeline more quickly than a updating the values inside a descriptor set.
579    ///
580    /// Push constants must be aligned to 4 bytes, and to guarantee alignment, this function takes a
581    /// `&[u32]` instead of a `&[u8]`. Note that the offset is still specified in units of bytes.
582    unsafe fn push_graphics_constants(
583        &mut self,
584        layout: &B::PipelineLayout,
585        stages: pso::ShaderStageFlags,
586        offset: u32,
587        constants: &[u32],
588    );
589
590    /// Modify constant data in a compute pipeline. Push constants are intended to modify data in a
591    /// pipeline more quickly than a updating the values inside a descriptor set.
592    ///
593    /// Push constants must be aligned to 4 bytes, and to guarantee alignment, this function takes a
594    /// `&[u32]` instead of a `&[u8]`. Note that the offset is still specified in units of bytes.
595    unsafe fn push_compute_constants(
596        &mut self,
597        layout: &B::PipelineLayout,
598        offset: u32,
599        constants: &[u32],
600    );
601
602    /// Execute the given secondary command buffers.
603    unsafe fn execute_commands<'a, T>(&mut self, cmd_buffers: T)
604    where
605        T: Iterator<Item = &'a B::CommandBuffer>;
606
607    /// Debug mark the current spot in the command buffer.
608    unsafe fn insert_debug_marker(&mut self, name: &str, color: u32);
609    /// Start a debug marker at the current place in the command buffer.
610    unsafe fn begin_debug_marker(&mut self, name: &str, color: u32);
611    /// End the last started debug marker scope.
612    unsafe fn end_debug_marker(&mut self);
613}