1use crate::__gl;
2use crate::__gl::types::{GLenum, GLuint};
3use crate::device::Device;
4
5#[derive(Debug, Copy, Clone, PartialEq, Eq)]
7pub enum MsgFilter<T> {
8 All,
10 Some(T),
12}
13
14impl MsgFilter<DebugSource> {
15 fn as_gl(self) -> GLenum {
16 match self {
17 MsgFilter::All => __gl::DONT_CARE,
18 MsgFilter::Some(v) => v as _,
19 }
20 }
21}
22
23impl MsgFilter<DebugType> {
24 fn as_gl(self) -> GLenum {
25 match self {
26 MsgFilter::All => __gl::DONT_CARE,
27 MsgFilter::Some(v) => v as _,
28 }
29 }
30}
31
32bitflags!(
33 pub struct DebugReport: GLenum {
37 const NOTIFICATION = __gl::DEBUG_SEVERITY_NOTIFICATION;
38 const WARNING = __gl::DEBUG_SEVERITY_MEDIUM;
39 const ERROR = __gl::DEBUG_SEVERITY_HIGH;
40 const PERFORMANCE_WARNING = __gl::DEBUG_SEVERITY_LOW;
41 const FULL = Self::NOTIFICATION.bits | Self::WARNING.bits | Self::ERROR.bits | Self::PERFORMANCE_WARNING.bits;
42 }
43);
44
45#[repr(u32)]
47#[derive(Debug, Copy, Clone, PartialEq, Eq)]
48pub enum DebugSource {
49 Api = __gl::DEBUG_SOURCE_API,
50 ShaderCompiler = __gl::DEBUG_SOURCE_SHADER_COMPILER,
51 Wsi = __gl::DEBUG_SOURCE_WINDOW_SYSTEM,
52 ThirdParty = __gl::DEBUG_SOURCE_THIRD_PARTY,
53 Application = __gl::DEBUG_SOURCE_APPLICATION,
54 Other = __gl::DEBUG_SOURCE_OTHER,
55}
56
57#[repr(u32)]
59#[derive(Debug, Copy, Clone, PartialEq, Eq)]
60pub enum DebugType {
61 Error = __gl::DEBUG_TYPE_ERROR,
62 Deprecated = __gl::DEBUG_TYPE_DEPRECATED_BEHAVIOR,
63 UndefinedBehavior = __gl::DEBUG_TYPE_UNDEFINED_BEHAVIOR,
64 Performance = __gl::DEBUG_TYPE_PERFORMANCE,
65 Portability = __gl::DEBUG_TYPE_PORTABILITY,
66 Marker = __gl::DEBUG_TYPE_MARKER,
67 PushGroup = __gl::DEBUG_TYPE_PUSH_GROUP,
68 PopGroup = __gl::DEBUG_TYPE_POP_GROUP,
69 Other = __gl::DEBUG_TYPE_OTHER,
70}
71
72pub type DebugCallback = fn(DebugReport, DebugSource, DebugType, u32, &str);
74
75#[repr(u32)]
77#[derive(Debug, Copy, Clone, PartialEq, Eq)]
78pub enum ObjectType {
79 Buffer = __gl::BUFFER,
80 Shader = __gl::SHADER,
81 Image = __gl::TEXTURE,
82 VertexArray = __gl::VERTEX_ARRAY,
83 Pipeline = __gl::PROGRAM,
84 Framebuffer = __gl::FRAMEBUFFER,
85 Renderbuffer = __gl::RENDERBUFFER,
86 Sampler = __gl::SAMPLER,
87}
88
89pub trait Object: Copy {
90 const TYPE: ObjectType;
91
92 fn handle(&self) -> GLuint;
93}
94
95pub(crate) unsafe fn set_debug_message_control(
96 ctxt: &__gl::Gl,
97 enable: bool,
98 src: MsgFilter<DebugSource>,
99 ty: MsgFilter<DebugType>,
100 flags: DebugReport,
101 ids: Option<&[u32]>,
102) {
103 let src = src.as_gl();
104 let ty = ty.as_gl();
105 let num_ids = match ids {
106 Some(ids) => ids.len() as i32,
107 None => 0,
108 };
109 let id_ptr = match ids {
110 Some(ids) => ids.as_ptr(),
111 None => std::ptr::null(),
112 };
113 let enable = if enable { __gl::TRUE } else { __gl::FALSE };
114
115 if flags.contains(DebugReport::NOTIFICATION) {
116 ctxt.DebugMessageControl(
117 src,
118 ty,
119 DebugReport::NOTIFICATION.bits(),
120 num_ids,
121 id_ptr,
122 enable,
123 );
124 }
125 if flags.contains(DebugReport::WARNING) {
126 ctxt.DebugMessageControl(
127 src,
128 ty,
129 DebugReport::WARNING.bits(),
130 num_ids,
131 id_ptr,
132 enable,
133 );
134 }
135 if flags.contains(DebugReport::ERROR) {
136 ctxt.DebugMessageControl(src, ty, DebugReport::ERROR.bits(), num_ids, id_ptr, enable);
137 }
138 if flags.contains(DebugReport::PERFORMANCE_WARNING) {
139 ctxt.DebugMessageControl(
140 src,
141 ty,
142 DebugReport::PERFORMANCE_WARNING.bits(),
143 num_ids,
144 id_ptr,
145 enable,
146 );
147 }
148}
149
150impl Device {
151 pub unsafe fn object_name<T: Object>(&self, object: T, name: &str) {
153 let label = name.as_bytes();
154 self.0.ObjectLabel(
155 T::TYPE as _,
156 object.handle(),
157 label.len() as _,
158 label.as_ptr() as *const _,
159 );
160 }
161
162 pub unsafe fn enable_debug_message(
163 &self,
164 src: MsgFilter<DebugSource>,
165 ty: MsgFilter<DebugType>,
166 flags: DebugReport,
167 ids: Option<&[u32]>,
168 ) {
169 set_debug_message_control(&self.0, true, src, ty, flags, ids);
170 }
171
172 pub unsafe fn disable_debug_message(
173 &self,
174 src: MsgFilter<DebugSource>,
175 ty: MsgFilter<DebugType>,
176 flags: DebugReport,
177 ids: Option<&[u32]>,
178 ) {
179 set_debug_message_control(&self.0, false, src, ty, flags, ids);
180 }
181
182 pub unsafe fn begin_debug_marker(&self, src: DebugSource, id: u32, msg: &str) {
183 self.0
184 .PushDebugGroup(src as _, id, msg.len() as _, msg.as_ptr() as *const _);
185 }
186
187 pub unsafe fn end_debug_marker(&self) {
188 self.0.PopDebugGroup();
189 }
190}