mtl_gpu/encoder/render_encoder/
mod.rs1mod advanced;
6mod binding;
7mod draw;
8mod mesh;
9mod state;
10mod tile;
11mod viewport;
12
13use std::ffi::c_void;
14use std::ptr::NonNull;
15
16use mtl_foundation::Referencing;
17use mtl_sys::{msg_send_0, msg_send_1, sel};
18
19#[repr(transparent)]
26pub struct RenderCommandEncoder(pub(crate) NonNull<c_void>);
27
28impl RenderCommandEncoder {
29 #[inline]
35 pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
36 NonNull::new(ptr).map(Self)
37 }
38
39 #[inline]
41 pub fn as_raw(&self) -> *mut c_void {
42 self.0.as_ptr()
43 }
44
45 pub fn device(&self) -> crate::Device {
53 unsafe {
54 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(device));
55 let _: *mut c_void = msg_send_0(ptr, sel!(retain));
56 crate::Device::from_raw(ptr).expect("encoder has no device")
57 }
58 }
59
60 pub fn command_buffer(&self) -> crate::CommandBuffer {
64 unsafe {
65 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(commandBuffer));
66 let _: *mut c_void = msg_send_0(ptr, sel!(retain));
67 crate::CommandBuffer::from_raw(ptr).expect("encoder has no command buffer")
68 }
69 }
70
71 pub fn label(&self) -> Option<String> {
75 unsafe {
76 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(label));
77 if ptr.is_null() {
78 return None;
79 }
80 let utf8_ptr: *const std::ffi::c_char =
81 mtl_sys::msg_send_0(ptr as *const c_void, sel!(UTF8String));
82 if utf8_ptr.is_null() {
83 return None;
84 }
85 let c_str = std::ffi::CStr::from_ptr(utf8_ptr);
86 Some(c_str.to_string_lossy().into_owned())
87 }
88 }
89
90 pub fn set_label(&self, label: &str) {
94 if let Some(ns_label) = mtl_foundation::String::from_str(label) {
95 unsafe {
96 msg_send_1::<(), *const c_void>(self.as_ptr(), sel!(setLabel:), ns_label.as_ptr());
97 }
98 }
99 }
100
101 #[inline]
105 pub fn end_encoding(&self) {
106 unsafe {
107 msg_send_0::<()>(self.as_ptr(), sel!(endEncoding));
108 }
109 }
110
111 pub fn insert_debug_signpost(&self, string: &str) {
115 if let Some(ns_string) = mtl_foundation::String::from_str(string) {
116 unsafe {
117 msg_send_1::<(), *const c_void>(
118 self.as_ptr(),
119 sel!(insertDebugSignpost:),
120 ns_string.as_ptr(),
121 );
122 }
123 }
124 }
125
126 pub fn push_debug_group(&self, string: &str) {
130 if let Some(ns_string) = mtl_foundation::String::from_str(string) {
131 unsafe {
132 msg_send_1::<(), *const c_void>(
133 self.as_ptr(),
134 sel!(pushDebugGroup:),
135 ns_string.as_ptr(),
136 );
137 }
138 }
139 }
140
141 #[inline]
145 pub fn pop_debug_group(&self) {
146 unsafe {
147 msg_send_0::<()>(self.as_ptr(), sel!(popDebugGroup));
148 }
149 }
150
151 #[inline]
155 pub fn barrier_after_queue_stages(
156 &self,
157 after_stages: crate::enums::Stages,
158 before_stages: crate::enums::Stages,
159 ) {
160 unsafe {
161 mtl_sys::msg_send_2::<(), crate::enums::Stages, crate::enums::Stages>(
162 self.as_ptr(),
163 sel!(barrierAfterQueueStages:beforeQueueStages:),
164 after_stages,
165 before_stages,
166 );
167 }
168 }
169
170 #[inline]
178 pub fn set_render_pipeline_state(&self, state: &crate::RenderPipelineState) {
179 unsafe {
180 msg_send_1::<(), *const c_void>(
181 self.as_ptr(),
182 sel!(setRenderPipelineState:),
183 state.as_ptr(),
184 );
185 }
186 }
187}
188
189impl Clone for RenderCommandEncoder {
190 fn clone(&self) -> Self {
191 unsafe {
192 msg_send_0::<*mut c_void>(self.as_ptr(), sel!(retain));
193 }
194 Self(self.0)
195 }
196}
197
198impl Drop for RenderCommandEncoder {
199 fn drop(&mut self) {
200 unsafe {
201 msg_send_0::<()>(self.as_ptr(), sel!(release));
202 }
203 }
204}
205
206impl Referencing for RenderCommandEncoder {
207 #[inline]
208 fn as_ptr(&self) -> *const c_void {
209 self.0.as_ptr()
210 }
211}
212
213unsafe impl Send for RenderCommandEncoder {}
214unsafe impl Sync for RenderCommandEncoder {}
215
216impl std::fmt::Debug for RenderCommandEncoder {
217 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
218 f.debug_struct("RenderCommandEncoder")
219 .field("label", &self.label())
220 .finish()
221 }
222}
223
224#[cfg(test)]
225mod tests {
226 use super::*;
227
228 #[test]
229 fn test_render_encoder_size() {
230 assert_eq!(
231 std::mem::size_of::<RenderCommandEncoder>(),
232 std::mem::size_of::<*mut c_void>()
233 );
234 }
235}