Skip to main content

metal/
indirect_encoder.rs

1use super::*;
2
3bitflags::bitflags! {
4    /// See <https://developer.apple.com/documentation/metal/mtlindirectcommandtype/>
5    #[allow(non_upper_case_globals)]
6    #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
7    pub struct MTLIndirectCommandType: NSUInteger {
8        const Draw                      = 1 << 0;
9        const DrawIndexed               = 1 << 1;
10        const DrawPatches               = 1 << 2;
11        const DrawIndexedPatches        = 1 << 3;
12        const ConcurrentDispatch        = 1 << 4;
13        const ConcurrentDispatchThreads = 1 << 5;
14    }
15}
16
17/// See <https://developer.apple.com/documentation/metal/mtlindirectcommandbufferdescriptor/>
18pub enum MTLIndirectCommandBufferDescriptor {}
19
20foreign_obj_type! {
21    type CType = MTLIndirectCommandBufferDescriptor;
22    pub struct IndirectCommandBufferDescriptor;
23}
24
25impl IndirectCommandBufferDescriptor {
26    pub fn new() -> Self {
27        let class = class!(MTLIndirectCommandBufferDescriptor);
28        unsafe { msg_send![class, new] }
29    }
30}
31
32impl IndirectCommandBufferDescriptorRef {
33    pub fn command_types(&self) -> MTLIndirectCommandType {
34        unsafe { msg_send![self, commandTypes] }
35    }
36
37    pub fn set_command_types(&self, types: MTLIndirectCommandType) {
38        unsafe { msg_send![self, setCommandTypes: types] }
39    }
40
41    pub fn inherit_buffers(&self) -> bool {
42        unsafe { msg_send_bool![self, inheritBuffers] }
43    }
44
45    pub fn set_inherit_buffers(&self, inherit: bool) {
46        unsafe { msg_send![self, setInheritBuffers: inherit] }
47    }
48
49    pub fn inherit_pipeline_state(&self) -> bool {
50        unsafe { msg_send_bool![self, inheritPipelineState] }
51    }
52
53    pub fn set_inherit_pipeline_state(&self, inherit: bool) {
54        unsafe { msg_send![self, setInheritPipelineState: inherit] }
55    }
56
57    pub fn max_vertex_buffer_bind_count(&self) -> NSUInteger {
58        unsafe { msg_send![self, maxVertexBufferBindCount] }
59    }
60
61    pub fn set_max_vertex_buffer_bind_count(&self, count: NSUInteger) {
62        unsafe { msg_send![self, setMaxVertexBufferBindCount: count] }
63    }
64
65    pub fn max_fragment_buffer_bind_count(&self) -> NSUInteger {
66        unsafe { msg_send![self, maxFragmentBufferBindCount] }
67    }
68
69    pub fn set_max_fragment_buffer_bind_count(&self, count: NSUInteger) {
70        unsafe { msg_send![self, setMaxFragmentBufferBindCount: count] }
71    }
72
73    pub fn max_kernel_buffer_bind_count(&self) -> NSUInteger {
74        unsafe { msg_send![self, maxKernelBufferBindCount] }
75    }
76
77    pub fn set_max_kernel_buffer_bind_count(&self, count: NSUInteger) {
78        unsafe { msg_send![self, setMaxKernelBufferBindCount: count] }
79    }
80}
81
82/// See <https://developer.apple.com/documentation/metal/mtlindirectcommandbuffer/>
83pub enum MTLIndirectCommandBuffer {}
84
85foreign_obj_type! {
86    type CType = MTLIndirectCommandBuffer;
87    pub struct IndirectCommandBuffer;
88    type ParentType = Resource;
89}
90
91impl IndirectCommandBufferRef {
92    pub fn size(&self) -> NSUInteger {
93        unsafe { msg_send![self, size] }
94    }
95
96    pub fn indirect_render_command_at_index(&self, index: NSUInteger) -> &IndirectRenderCommandRef {
97        unsafe { msg_send![self, indirectRenderCommandAtIndex: index] }
98    }
99
100    pub fn indirect_compute_command_at_index(
101        &self,
102        index: NSUInteger,
103    ) -> &IndirectComputeCommandRef {
104        unsafe { msg_send![self, indirectComputeCommandAtIndex: index] }
105    }
106
107    pub fn reset_with_range(&self, range: crate::NSRange) {
108        unsafe { msg_send![self, resetWithRange: range] }
109    }
110}
111
112/// See <https://developer.apple.com/documentation/metal/mtlindirectrendercommand/>
113pub enum MTLIndirectRenderCommand {}
114
115foreign_obj_type! {
116    type CType = MTLIndirectRenderCommand;
117    pub struct IndirectRenderCommand;
118}
119
120impl IndirectRenderCommandRef {
121    pub fn set_render_pipeline_state(&self, pipeline_state: &RenderPipelineStateRef) {
122        unsafe { msg_send![self, setRenderPipelineState: pipeline_state] }
123    }
124
125    pub fn set_vertex_buffer(
126        &self,
127        index: NSUInteger,
128        buffer: Option<&BufferRef>,
129        offset: NSUInteger,
130    ) {
131        unsafe {
132            msg_send![self,
133                setVertexBuffer: buffer
134                offset: offset
135                atIndex: index
136            ]
137        }
138    }
139
140    pub fn set_fragment_buffer(
141        &self,
142        index: NSUInteger,
143        buffer: Option<&BufferRef>,
144        offset: NSUInteger,
145    ) {
146        unsafe {
147            msg_send![self,
148                setFragmentBuffer:buffer
149                offset:offset
150                atIndex:index
151            ]
152        }
153    }
154
155    pub fn draw_primitives(
156        &self,
157        primitive_type: MTLPrimitiveType,
158        vertex_start: NSUInteger,
159        vertex_count: NSUInteger,
160        instance_count: NSUInteger,
161        base_instance: NSUInteger,
162    ) {
163        unsafe {
164            msg_send![self,
165                drawPrimitives: primitive_type
166                vertexStart: vertex_start
167                vertexCount: vertex_count
168                instanceCount: instance_count
169                baseInstance: base_instance
170            ]
171        }
172    }
173
174    #[allow(clippy::too_many_arguments)]
175    pub fn draw_indexed_primitives(
176        &self,
177        primitive_type: MTLPrimitiveType,
178        index_count: NSUInteger,
179        index_type: MTLIndexType,
180        index_buffer: &BufferRef,
181        index_buffer_offset: NSUInteger,
182        instance_count: NSUInteger,
183        base_vertex: NSUInteger,
184        base_instance: NSUInteger,
185    ) {
186        unsafe {
187            msg_send![self,
188                drawIndexedPrimitives: primitive_type
189                indexCount: index_count
190                indexType: index_type
191                indexBuffer: index_buffer
192                indexBufferOffset: index_buffer_offset
193                instanceCount: instance_count
194                baseVertex: base_vertex
195                baseInstance: base_instance
196            ]
197        }
198    }
199
200    #[allow(clippy::too_many_arguments)]
201    pub fn draw_patches(
202        &self,
203        number_of_patch_control_points: NSUInteger,
204        patch_start: NSUInteger,
205        patch_count: NSUInteger,
206        patch_index_buffer: &BufferRef,
207        patch_index_buffer_offset: NSUInteger,
208        instance_count: NSUInteger,
209        base_instance: NSUInteger,
210        tesselation_factor_buffer: &BufferRef,
211        tesselation_factor_buffer_offset: NSUInteger,
212        tesselation_factor_buffer_instance_stride: NSUInteger,
213    ) {
214        unsafe {
215            msg_send![self,
216                drawPatches: number_of_patch_control_points
217                patchStart: patch_start
218                patchCount: patch_count
219                patchIndexBuffer: patch_index_buffer
220                patchIndexBufferOffset: patch_index_buffer_offset
221                instanceCount: instance_count
222                baseInstance: base_instance
223                tessellationFactorBuffer: tesselation_factor_buffer
224                tessellationFactorBufferOffset: tesselation_factor_buffer_offset
225                tessellationFactorBufferInstanceStride: tesselation_factor_buffer_instance_stride
226            ]
227        }
228    }
229
230    #[allow(clippy::too_many_arguments)]
231    pub fn draw_indexed_patches(
232        &self,
233        number_of_patch_control_points: NSUInteger,
234        patch_start: NSUInteger,
235        patch_count: NSUInteger,
236        patch_index_buffer: &BufferRef,
237        patch_index_buffer_offset: NSUInteger,
238        control_point_index_buffer: &BufferRef,
239        control_point_index_buffer_offset: NSUInteger,
240        instance_count: NSUInteger,
241        base_instance: NSUInteger,
242        tesselation_factor_buffer: &BufferRef,
243        tesselation_factor_buffer_offset: NSUInteger,
244        tesselation_factor_buffer_instance_stride: NSUInteger,
245    ) {
246        unsafe {
247            msg_send![self,
248                drawIndexedPatches: number_of_patch_control_points
249                patchStart: patch_start
250                patchCount: patch_count
251                patchIndexBuffer: patch_index_buffer
252                patchIndexBufferOffset: patch_index_buffer_offset
253                controlPointIndexBuffer: control_point_index_buffer
254                controlPointIndexBufferOffset: control_point_index_buffer_offset
255                instanceCount: instance_count
256                baseInstance: base_instance
257                tessellationFactorBuffer: tesselation_factor_buffer
258                tessellationFactorBufferOffset: tesselation_factor_buffer_offset
259                tessellationFactorBufferInstanceStride: tesselation_factor_buffer_instance_stride
260            ]
261        }
262    }
263
264    pub fn reset(&self) {
265        unsafe { msg_send![self, reset] }
266    }
267}
268
269/// See <https://developer.apple.com/documentation/metal/mtlindirectcomputecommand/>
270pub enum MTLIndirectComputeCommand {}
271
272foreign_obj_type! {
273    type CType = MTLIndirectComputeCommand;
274    pub struct IndirectComputeCommand;
275}
276
277impl IndirectComputeCommandRef {
278    pub fn set_compute_pipeline_state(&self, state: &ComputePipelineStateRef) {
279        unsafe { msg_send![self, setComputePipelineState: state] }
280    }
281
282    pub fn set_kernel_buffer(
283        &self,
284        index: NSUInteger,
285        buffer: Option<&BufferRef>,
286        offset: NSUInteger,
287    ) {
288        unsafe {
289            msg_send![self,
290                setKernelBuffer: buffer
291                offset: offset
292                atIndex: index
293            ]
294        }
295    }
296
297    pub fn set_threadgroup_memory_length(&self, index: NSUInteger, length: NSUInteger) {
298        unsafe {
299            msg_send![self,
300                setThreadgroupMemoryLength: length
301                atIndex: index
302            ]
303        }
304    }
305
306    pub fn set_stage_in_region(&self, region: MTLRegion) {
307        unsafe { msg_send![self, setStageInRegion: region] }
308    }
309
310    pub fn set_barrier(&self) {
311        unsafe { msg_send![self, setBarrier] }
312    }
313
314    pub fn clear_barrier(&self) {
315        unsafe { msg_send![self, clearBarrier] }
316    }
317
318    pub fn concurrent_dispatch_threadgroups(
319        &self,
320        thread_groups_per_grid: MTLSize,
321        threads_per_threadgroup: MTLSize,
322    ) {
323        unsafe {
324            msg_send![self,
325                concurrentDispatchThreadgroups: thread_groups_per_grid
326                threadsPerThreadgroup: threads_per_threadgroup
327            ]
328        }
329    }
330
331    pub fn concurrent_dispatch_threads(
332        &self,
333        thread_groups_per_grid: MTLSize,
334        threads_per_threadgroup: MTLSize,
335    ) {
336        unsafe {
337            msg_send![self,
338                concurrentDispatchThreads: thread_groups_per_grid
339                threadsPerThreadgroup: threads_per_threadgroup
340            ]
341        }
342    }
343
344    pub fn reset(&self) {
345        unsafe { msg_send![self, reset] }
346    }
347}