iron_oxide/encoder/
render.rs

1use crate::import_objc_macros::*;
2use crate::{
3    handle, MTLBuffer, MTLCommandEncoder, MTLDepthStencilState, MTLRenderPipelineState,
4    MTLSamplerState, MTLStoreAction, MTLStoreActionOptions, MTLTexture, NSInteger, NSRange,
5    NSUInteger, NSUIntegerRange, Object, ObjectPointer,
6};
7use std::os::raw::c_void;
8
9#[repr(u64)]
10pub enum MTLTriangleFillMode {
11    Fill = 0,
12    Lines = 1,
13}
14
15#[repr(u64)]
16pub enum MTLWinding {
17    Clockwise = 0,
18    CounterClockwise = 1,
19}
20
21#[repr(u64)]
22pub enum MTLCullMode {
23    None = 0,
24    Front = 1,
25    Back = 2,
26}
27
28#[repr(u64)]
29pub enum MTLDepthClipMode {
30    Clip = 0,
31    Clamp = 1,
32}
33
34#[repr(C)]
35pub struct MTLViewport {
36    pub origin_x: f64,
37    pub origin_y: f64,
38    pub width: f64,
39    pub height: f64,
40    pub znear: f64,
41    pub zfar: f64,
42}
43
44#[repr(C)]
45pub struct MTLScissorRect {
46    pub width: NSUInteger,
47    pub height: NSUInteger,
48    pub x: NSUInteger,
49    pub y: NSUInteger,
50}
51
52#[repr(u64)]
53pub enum MTLPrimitiveType {
54    Point = 0,
55    Line = 1,
56    LineStrip = 2,
57    Triangle = 3,
58    TriangleStrip = 4,
59}
60
61#[repr(u64)]
62pub enum MTLIndexType {
63    UInt16 = 0,
64    UInt32 = 1,
65}
66
67pub struct MTLRenderCommandEncoder(ObjectPointer);
68handle!(MTLRenderCommandEncoder);
69
70impl MTLRenderCommandEncoder {
71    pub unsafe fn set_render_pipeline_state(&self, state: &MTLRenderPipelineState) {
72        msg_send![self.get_ptr(), setRenderPipelineState:state.get_ptr()]
73    }
74    pub unsafe fn set_triangle_fill_mode(&self, mode: MTLTriangleFillMode) {
75        msg_send![self.get_ptr(), setTriangleFillMode: mode]
76    }
77    pub unsafe fn set_front_face_winding(&self, winding: MTLWinding) {
78        msg_send![self.get_ptr(), setFrontFaceWinding: winding]
79    }
80    pub unsafe fn set_cull_mode(&self, mode: MTLCullMode) {
81        msg_send![self.get_ptr(), setCullMode: mode]
82    }
83    pub unsafe fn set_depth_stencil_state(&self, state: &MTLDepthStencilState) {
84        msg_send![self.get_ptr(), setDepthStencilState:state.get_ptr()]
85    }
86    pub unsafe fn set_depth_clip_mode(&self, mode: MTLDepthClipMode) {
87        msg_send![self.get_ptr(), setDepthClipMode: mode]
88    }
89    pub unsafe fn set_stencil_reference_values(&self, front: u32, back: u32) {
90        msg_send![self.get_ptr(), setStencilFrontReferenceValue:front backReferenceValue:back]
91    }
92    pub unsafe fn set_viewport(&self, viewport: MTLViewport) {
93        msg_send![self.get_ptr(), setViewport: viewport]
94    }
95    pub unsafe fn set_viewports(&self, viewports: &[MTLViewport]) {
96        msg_send![self.get_ptr(), setViewports:viewports.as_ptr() count:viewports.len()]
97    }
98    pub unsafe fn set_scissor_rect(&self, rect: MTLScissorRect) {
99        msg_send![self.get_ptr(), setScissorRect: rect]
100    }
101    pub unsafe fn set_scissor_rects(&self, rects: &[MTLScissorRect]) {
102        msg_send![self.get_ptr(), setScissorRects:rects.as_ptr() count:rects.len()]
103    }
104    pub unsafe fn set_blend_color(&self, red: f32, green: f32, blue: f32, alpha: f32) {
105        msg_send![self.get_ptr(), setBlendColorRed:red green:green blue:blue alpha:alpha]
106    }
107    pub unsafe fn set_vertex_buffer(
108        &self,
109        buffer: &MTLBuffer,
110        offset: NSUInteger,
111        index: NSUInteger,
112    ) {
113        msg_send![self.get_ptr(), setVertexBuffer:buffer.get_ptr() offset:offset atIndex:index]
114    }
115    pub unsafe fn set_vertex_buffers(
116        &self,
117        buffers: &[MTLBuffer],
118        offsets: &[NSUInteger],
119        range: NSUIntegerRange,
120    ) {
121        let range = NSRange {
122            location: range.start,
123            length: range.end - range.start,
124        };
125        let pointers = buffers
126            .iter()
127            .map(|buffer| buffer.get_ptr())
128            .collect::<Vec<ObjectPointer>>();
129        let pointers = pointers.as_slice().as_ptr();
130
131        msg_send![self.get_ptr(), setVertexBuffers:pointers offsets:offsets.as_ptr() withRange:range]
132    }
133    pub unsafe fn set_vertex_buffer_offset(&self, offset: NSUInteger, index: NSUInteger) {
134        msg_send![self.get_ptr(), setVertexBufferOffset:offset atIndex:index]
135    }
136    pub unsafe fn set_vertex_bytes(
137        &self,
138        bytes: *const c_void,
139        length: NSUInteger,
140        index: NSUInteger,
141    ) {
142        msg_send![self.get_ptr(), setVertexBytes:bytes length:length atIndex:index]
143    }
144    pub unsafe fn set_vertex_sampler_state(&self, sampler: &MTLSamplerState, index: NSUInteger) {
145        msg_send![self.get_ptr(), setVertexSamplerState:sampler.get_ptr() atIndex:index]
146    }
147    pub unsafe fn set_vertex_sampler_state_clamp(
148        &self,
149        sampler: &MTLSamplerState,
150        lod_min_clamp: f32,
151        lod_max_clamp: f32,
152        index: NSUInteger,
153    ) {
154        msg_send![
155            self.get_ptr(),
156            setVertexSamplerState:sampler.get_ptr()
157            lodMinClamp:lod_min_clamp
158            lodMaxClamp:lod_max_clamp
159            atIndex:index
160        ]
161    }
162    pub unsafe fn set_vertex_sampler_states(
163        &self,
164        samplers: &[MTLSamplerState],
165        range: NSUIntegerRange,
166    ) {
167        let pointers = samplers
168            .iter()
169            .map(|sampler| sampler.get_ptr())
170            .collect::<Vec<_>>();
171        let pointers = pointers.as_slice().as_ptr();
172        let range = NSRange {
173            location: range.start,
174            length: range.end - range.start,
175        };
176        msg_send![self.get_ptr(), setVertexSamplerStates:pointers withRange:range]
177    }
178    pub unsafe fn set_vertex_texture(&self, texture: &MTLTexture, index: NSUInteger) {
179        msg_send![self.get_ptr(), setVertexTexture:texture.get_ptr() atIndex:index]
180    }
181    pub unsafe fn set_vertex_textures(&self, textures: &[MTLTexture], range: NSUIntegerRange) {
182        let pointers = textures
183            .iter()
184            .map(|texture| texture.get_ptr())
185            .collect::<Vec<_>>();
186        let pointers = pointers.as_slice().as_ptr();
187        let range = NSRange {
188            location: range.start,
189            length: range.end - range.start,
190        };
191        msg_send![self.get_ptr(), setVertexTextures:pointers withRange:range]
192    }
193
194    pub unsafe fn set_fragment_buffer(
195        &self,
196        buffer: &MTLBuffer,
197        offset: NSUInteger,
198        index: NSUInteger,
199    ) {
200        msg_send![self.get_ptr(), setFragmentBuffer:buffer.get_ptr() offset:offset atIndex:index]
201    }
202    pub unsafe fn set_fragment_buffers(
203        &self,
204        buffers: &[MTLBuffer],
205        offsets: &[NSUInteger],
206        range: NSUIntegerRange,
207    ) {
208        let range = NSRange {
209            location: range.start,
210            length: range.end - range.start,
211        };
212        let pointers = buffers
213            .iter()
214            .map(|buffer| buffer.get_ptr())
215            .collect::<Vec<ObjectPointer>>();
216        let pointers = pointers.as_slice().as_ptr();
217
218        msg_send![self.get_ptr(), setFragmentBuffers:pointers offsets:offsets.as_ptr() withRange:range]
219    }
220    pub unsafe fn set_fragment_buffer_offset(&self, offset: NSUInteger, index: NSUInteger) {
221        msg_send![self.get_ptr(), setFragmentBufferOffset:offset atIndex:index]
222    }
223    pub unsafe fn set_fragment_bytes(
224        &self,
225        bytes: *const c_void,
226        length: NSUInteger,
227        index: NSUInteger,
228    ) {
229        msg_send![self.get_ptr(), setFragmentBytes:bytes length:length atIndex:index]
230    }
231    pub unsafe fn set_fragment_sampler_state(&self, sampler: &MTLSamplerState, index: NSUInteger) {
232        msg_send![self.get_ptr(), setFragmentSamplerState:sampler.get_ptr() atIndex:index]
233    }
234    pub unsafe fn set_fragment_sampler_state_clamp(
235        &self,
236        sampler: &MTLSamplerState,
237        lod_min_clamp: f32,
238        lod_max_clamp: f32,
239        index: NSUInteger,
240    ) {
241        msg_send![
242            self.get_ptr(),
243            setFragmentSamplerState:sampler.get_ptr()
244            lodMinClamp:lod_min_clamp
245            lodMaxClamp:lod_max_clamp
246            atIndex:index
247        ]
248    }
249    pub unsafe fn set_fragment_sampler_states(
250        &self,
251        samplers: &[MTLSamplerState],
252        range: NSUIntegerRange,
253    ) {
254        let pointers = samplers
255            .iter()
256            .map(|sampler| sampler.get_ptr())
257            .collect::<Vec<_>>();
258        let pointers = pointers.as_slice().as_ptr();
259        let range = NSRange {
260            location: range.start,
261            length: range.end - range.start,
262        };
263        msg_send![self.get_ptr(), setFragmentSamplerStates:pointers withRange:range]
264    }
265    pub unsafe fn set_fragment_texture(&self, texture: &MTLTexture, index: NSUInteger) {
266        msg_send![self.get_ptr(), setFragmentTexture:texture.get_ptr() atIndex:index]
267    }
268    pub unsafe fn set_fragment_textures(&self, textures: &[MTLTexture], range: NSUIntegerRange) {
269        let pointers = textures
270            .iter()
271            .map(|texture| texture.get_ptr())
272            .collect::<Vec<_>>();
273        let pointers = pointers.as_slice().as_ptr();
274        let range = NSRange {
275            location: range.start,
276            length: range.end - range.start,
277        };
278        msg_send![self.get_ptr(), setFragmentTextures:pointers withRange:range]
279    }
280    pub unsafe fn draw_primitives(
281        &self,
282        primitive: MTLPrimitiveType,
283        start: NSUInteger,
284        vertices: NSUInteger,
285        instances: NSUInteger,
286        base_instance: NSUInteger,
287    ) {
288        msg_send![
289            self.get_ptr(),
290            drawPrimitives:primitive
291            vertexStart:start
292            vertexCount:vertices
293            instanceCount:instances
294            baseInstance:base_instance
295        ]
296    }
297    pub unsafe fn draw_indexed_primitives(
298        &self,
299        primitive: MTLPrimitiveType,
300        indices: NSUInteger,
301        index_type: MTLIndexType,
302        index_buffer: &MTLBuffer,
303        index_buffer_offset: NSUInteger,
304        instance_count: NSUInteger,
305        base_vertex: NSInteger,
306        base_instance: NSUInteger,
307    ) {
308        msg_send![
309            self.get_ptr(),
310            drawIndexedPrimitives:primitive
311            indexCount:indices
312            indexType:index_type
313            indexBuffer:index_buffer.get_ptr()
314            indexBufferOffset:index_buffer_offset
315            instanceCount:instance_count
316            baseVertex:base_vertex
317            baseInstance:base_instance
318        ]
319    }
320}
321
322impl MTLCommandEncoder for MTLRenderCommandEncoder {}
323
324impl Object for MTLRenderCommandEncoder {
325    unsafe fn from_ptr(ptr: ObjectPointer) -> Self
326    where
327        Self: Sized,
328    {
329        MTLRenderCommandEncoder(ptr)
330    }
331
332    fn get_ptr(&self) -> ObjectPointer {
333        self.0
334    }
335}
336
337pub struct MTLParallelRenderCommandEncoder(ObjectPointer);
338handle!(MTLParallelRenderCommandEncoder);
339
340impl MTLParallelRenderCommandEncoder {
341    pub unsafe fn new_render_command_encoder(&self) -> MTLRenderCommandEncoder {
342        MTLRenderCommandEncoder::from_ptr({
343            let k = ObjectPointer(msg_send![self.get_ptr(), renderCommandEncoder]);
344            msg_send![k, retain]
345        })
346    }
347    pub unsafe fn set_color_store_action(&self, action: MTLStoreAction, index: NSUInteger) {
348        msg_send![self.get_ptr(), setColorStoreAction:action atIndex:index]
349    }
350    pub unsafe fn set_color_store_action_options(
351        &self,
352        options: MTLStoreActionOptions,
353        index: NSUInteger,
354    ) {
355        msg_send![self.get_ptr(), setColorStoreActionOptions:options atIndex:index]
356    }
357    pub unsafe fn set_depth_store_action(&self, action: MTLStoreAction, index: NSUInteger) {
358        msg_send![self.get_ptr(), setDepthStoreAction:action atIndex:index]
359    }
360    pub unsafe fn set_depth_store_action_options(
361        &self,
362        options: MTLStoreActionOptions,
363        index: NSUInteger,
364    ) {
365        msg_send![self.get_ptr(), setDepthStoreActionOptions:options atIndex:index]
366    }
367    pub unsafe fn set_stencil_store_action(&self, action: MTLStoreAction, index: NSUInteger) {
368        msg_send![self.get_ptr(), setStencilStoreAction:action atIndex:index]
369    }
370    pub unsafe fn set_stencil_store_action_options(
371        &self,
372        options: MTLStoreActionOptions,
373        index: NSUInteger,
374    ) {
375        msg_send![self.get_ptr(), setStencilStoreActionOptions:options atIndex:index]
376    }
377}
378
379impl MTLCommandEncoder for MTLParallelRenderCommandEncoder {}
380
381impl Object for MTLParallelRenderCommandEncoder {
382    unsafe fn from_ptr(ptr: ObjectPointer) -> Self
383    where
384        Self: Sized,
385    {
386        MTLParallelRenderCommandEncoder(ptr)
387    }
388
389    fn get_ptr(&self) -> ObjectPointer {
390        self.0
391    }
392}