pub struct ComputeCommandEncoder { /* private fields */ }Expand description
Re-exports the Metal framework surface for this item.
Apple’s id<MTLComputeCommandEncoder> — encodes compute dispatches.
Implementations§
Source§impl ComputeCommandEncoder
impl ComputeCommandEncoder
Sourcepub fn as_ptr(&self) -> *mut c_void
pub fn as_ptr(&self) -> *mut c_void
Borrowed raw native command-encoder pointer.
The pointer is valid only until this wrapper is dropped. Calling
endEncoding through it bypasses lifecycle tracking.
Sourcepub fn end_encoding(self) -> Result<(), CommandBufferError>
pub fn end_encoding(self) -> Result<(), CommandBufferError>
Finish encoding. Dropping an active encoder performs this once automatically.
Examples found in repository?
examples/05_render_and_explicit_encoders.rs (line 78)
11fn main() {
12 let device = MetalDevice::system_default().expect("Metal device available");
13 println!(
14 "device: {} (registry id {})",
15 device.name(),
16 device.registry_id()
17 );
18
19 let queue = device.new_command_queue().expect("command queue");
20 let status_buffer = unsafe {
21 queue
22 .new_command_buffer_with_unretained_references()
23 .expect("scratch command buffer")
24 };
25 println!("scratch command buffer status={}", status_buffer.status());
26
27 let src = device
28 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
29 .expect("source buffer");
30 let dst = device
31 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
32 .expect("destination buffer");
33 let blit_cb = queue.new_command_buffer().expect("blit command buffer");
34 let mut blit = blit_cb
35 .new_blit_command_encoder()
36 .expect("blit command encoder");
37 blit.fill_buffer(&src, 0..64, b'Z').expect("fill source");
38 blit.copy_buffer(&src, 0, &dst, 0, 64)
39 .expect("copy buffers");
40 blit.end_encoding().expect("end blit encoder");
41 blit_cb.commit().expect("commit blit");
42 blit_cb.wait_until_completed().expect("complete blit");
43 let copied = {
44 let mapping = unsafe { dst.map_read().expect("map destination") };
45 let copied = mapping[..8].to_vec();
46 drop(mapping);
47 copied
48 };
49 println!("blit copied bytes: {copied:?}");
50
51 let library = device
52 .new_library_with_source(common::COMPUTE_SRC)
53 .expect("compile compute library");
54 let increment = library
55 .new_function("increment")
56 .expect("increment function");
57 let pipeline = device
58 .new_compute_pipeline_state(&increment)
59 .expect("compute pipeline");
60
61 let buffer = device
62 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
63 .expect("compute buffer");
64 common::write_u32_words(&buffer, &[10, 20, 30, 40]);
65 let compute_cb = queue.new_command_buffer().expect("compute command buffer");
66 let mut compute = compute_cb
67 .new_compute_command_encoder()
68 .expect("compute command encoder");
69 compute
70 .set_compute_pipeline_state(&pipeline)
71 .expect("bind compute pipeline");
72 compute
73 .set_buffer(&buffer, 0, 0)
74 .expect("bind compute buffer");
75 compute
76 .dispatch_threads((4, 1, 1), (1, 1, 1))
77 .expect("dispatch compute");
78 compute.end_encoding().expect("end compute encoder");
79 compute_cb.commit().expect("commit compute");
80 compute_cb.wait_until_completed().expect("complete compute");
81 println!("compute output: {:?}", common::read_u32_words(&buffer, 4));
82
83 let render_library = device
84 .new_library_with_source(common::RENDER_SRC)
85 .expect("compile render library");
86 let vertex = render_library
87 .new_function("fullscreen_vertex")
88 .expect("vertex function");
89 let fragment = render_library
90 .new_function("solid_fragment")
91 .expect("fragment function");
92 let render_pipeline = device
93 .new_render_pipeline_state(&vertex, &fragment, pixel_format::BGRA8UNORM, 1)
94 .expect("render pipeline");
95 println!("render pipeline label: {:?}", render_pipeline.label());
96
97 let render_target = device
98 .new_texture(common::shared_render_target(4, 4))
99 .expect("render target");
100 let vertex_buffer = device
101 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
102 .expect("vertex buffer");
103 let render_cb = queue.new_command_buffer().expect("render command buffer");
104 let mut render = render_cb
105 .new_render_command_encoder(
106 &render_target,
107 load_action::CLEAR,
108 store_action::STORE,
109 [0.0, 0.0, 0.0, 1.0],
110 )
111 .expect("render command encoder");
112 render
113 .set_render_pipeline_state(&render_pipeline)
114 .expect("bind render pipeline");
115 render
116 .set_vertex_buffer(&vertex_buffer, 0, 0)
117 .expect("bind vertex buffer");
118 render
119 .draw_primitives(primitive_type::TRIANGLE, 0, 3)
120 .expect("draw triangle");
121 render.end_encoding().expect("end render encoder");
122 render_cb.commit().expect("commit render");
123 render_cb.wait_until_completed().expect("complete render");
124
125 let mut rendered = vec![0_u8; 4 * 4 * 4];
126 unsafe {
127 render_target
128 .read_bytes_2d(&mut rendered, 16, (0, 0), (4, 4), 0)
129 .expect("read render target");
130 }
131 println!("first rendered pixel: {:?}", &rendered[..4]);
132
133 let shared_texture = device
134 .new_texture(TextureDescriptor::new_2d(4, 4, pixel_format::BGRA8UNORM))
135 .expect("shared texture");
136 let upload = vec![0x22_u8; 4 * 4 * 4];
137 unsafe {
138 shared_texture
139 .replace_region_2d(&upload, 16, (0, 0), (4, 4), 0)
140 .expect("upload texture");
141 }
142 let mut download = vec![0_u8; upload.len()];
143 unsafe {
144 shared_texture
145 .read_bytes_2d(&mut download, 16, (0, 0), (4, 4), 0)
146 .expect("read texture");
147 }
148 let view = shared_texture
149 .new_view(pixel_format::BGRA8UNORM)
150 .expect("texture view");
151 println!(
152 "texture {}x{} usage={} storage_mode={} view_width={}",
153 shared_texture.width(),
154 shared_texture.height(),
155 shared_texture.usage(),
156 shared_texture.storage_mode(),
157 view.width(),
158 );
159}More examples
examples/07_advanced_objects.rs (line 175)
11fn main() {
12 let device = MetalDevice::system_default().expect("Metal device available");
13 let queue = device.new_command_queue().expect("command queue");
14 let counter_sets = device.counter_set_names();
15 println!("counter sets: {counter_sets:?}");
16
17 if let Some(event) = device.new_shared_event() {
18 event.set_signaled_value(1);
19 println!("event signaled value={}", event.signaled_value());
20 let signal = queue
21 .new_command_buffer()
22 .expect("event signal command buffer");
23 signal
24 .encode_signal_event(&event, 2)
25 .expect("encode event signal");
26 signal.commit().expect("commit event signal");
27 signal
28 .wait_until_completed()
29 .expect("complete event signal");
30 println!(
31 "event reached value 2: {}",
32 event.wait_until_signaled_value(2, 1_000),
33 );
34
35 let wait = queue
36 .new_command_buffer()
37 .expect("event wait command buffer");
38 wait.encode_wait_for_event(&event, 2)
39 .expect("encode event wait");
40 wait.commit().expect("commit event wait");
41 wait.wait_until_completed().expect("complete event wait");
42 }
43
44 let fence_a = device.new_fence();
45 let fence_b = device.new_fence();
46 let sample_buffer = counter_sets.first().and_then(|name| {
47 if device.supports_counter_sampling(counter_sampling_point::AT_BLIT_BOUNDARY) {
48 device
49 .new_counter_sample_buffer(name, 2, storage_mode::SHARED, Some("example-samples"))
50 .ok()
51 } else {
52 None
53 }
54 });
55
56 let src = device
57 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
58 .expect("source buffer");
59 let dst = device
60 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
61 .expect("destination buffer");
62 let blit = queue.new_command_buffer().expect("blit command buffer");
63 let mut encoder = blit.new_blit_command_encoder().expect("blit encoder");
64 encoder
65 .fill_buffer(&src, 0..64, b'Q')
66 .expect("fill source buffer");
67 if let Some(fence) = fence_a.as_ref() {
68 encoder.update_fence(fence).expect("update fence");
69 }
70 encoder.end_encoding().expect("end first blit encoder");
71 blit.commit().expect("commit first blit");
72 blit.wait_until_completed().expect("complete first blit");
73
74 let blit = queue
75 .new_command_buffer()
76 .expect("second blit command buffer");
77 let mut encoder = blit
78 .new_blit_command_encoder()
79 .expect("second blit encoder");
80 if let Some(fence) = fence_a.as_ref() {
81 encoder.wait_for_fence(fence).expect("wait for fence");
82 }
83 if let Some(sample_buffer) = sample_buffer.as_ref() {
84 encoder
85 .sample_counters(sample_buffer, 0, false)
86 .expect("sample counters");
87 }
88 encoder
89 .copy_buffer(&src, 0, &dst, 0, 64)
90 .expect("copy buffers");
91 encoder.end_encoding().expect("end second blit encoder");
92 blit.commit().expect("commit second blit");
93 blit.wait_until_completed().expect("complete second blit");
94 if let Some(sample_buffer) = sample_buffer.as_ref() {
95 println!(
96 "resolved counter bytes={}",
97 sample_buffer
98 .resolve_range(0..1)
99 .map_or(0, |bytes| bytes.len())
100 );
101 }
102
103 let library = device
104 .new_library_with_source(common::COMPUTE_SRC)
105 .expect("compile compute library");
106 let increment = library
107 .new_function("increment")
108 .expect("increment function");
109 let pipeline = device
110 .new_compute_pipeline_state(&increment)
111 .expect("compute pipeline");
112 let visible_table = pipeline.new_visible_function_table(1);
113 let intersection_table = if device.supports_raytracing() {
114 pipeline.new_intersection_function_table(1)
115 } else {
116 None
117 };
118 if let Some(table) = intersection_table.as_ref() {
119 table.set_opaque_triangle_intersection_function(intersection_function_signature::NONE, 0);
120 }
121 let acceleration_structure = if device.supports_raytracing() {
122 device.new_acceleration_structure_with_size(256)
123 } else {
124 None
125 };
126
127 let buffer = device
128 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
129 .expect("compute buffer");
130 common::write_u32_words(&buffer, &[1, 2, 3, 4]);
131 let texture = device
132 .new_texture(apple_metal::TextureDescriptor::new_2d(
133 4,
134 4,
135 apple_metal::pixel_format::BGRA8UNORM,
136 ))
137 .expect("compute texture");
138 let compute = queue.new_command_buffer().expect("compute command buffer");
139 let mut encoder = compute
140 .new_compute_command_encoder()
141 .expect("compute command encoder");
142 encoder
143 .set_compute_pipeline_state(&pipeline)
144 .expect("bind compute pipeline");
145 encoder
146 .set_buffer(&buffer, 0, 0)
147 .expect("bind compute buffer");
148 encoder
149 .set_texture(&texture, 1)
150 .expect("bind compute texture");
151 if let Some(fence) = fence_a.as_ref() {
152 encoder.wait_for_fence(fence).expect("wait for fence");
153 }
154 if let Some(table) = visible_table.as_ref() {
155 encoder
156 .set_visible_function_table(table, 2)
157 .expect("bind visible function table");
158 }
159 if let Some(table) = intersection_table.as_ref() {
160 encoder
161 .set_intersection_function_table(table, 3)
162 .expect("bind intersection function table");
163 }
164 if let Some(acceleration_structure) = acceleration_structure.as_ref() {
165 encoder
166 .set_acceleration_structure(acceleration_structure, 4)
167 .expect("bind acceleration structure");
168 }
169 encoder
170 .dispatch_threadgroups((1, 1, 1), (4, 1, 1))
171 .expect("dispatch compute");
172 if let Some(fence) = fence_b.as_ref() {
173 encoder.update_fence(fence).expect("update fence");
174 }
175 encoder.end_encoding().expect("end compute encoder");
176 compute.commit().expect("commit compute");
177 compute.wait_until_completed().expect("complete compute");
178 println!(
179 "compute buffer after dispatch: {:?}",
180 common::read_u32_words(&buffer, 4)
181 );
182
183 if let Some(indirect) = device.new_indirect_command_buffer(
184 indirect_command_type::CONCURRENT_DISPATCH,
185 1,
186 0,
187 0,
188 4,
189 resource_options::STORAGE_MODE_PRIVATE,
190 ) {
191 indirect.reset_range(0..1);
192 println!("indirect command buffer size={}", indirect.size());
193 }
194
195 if let Some(heap) = device.new_heap(1 << 20, storage_mode::SHARED) {
196 if let Ok(residency_set) = device.new_residency_set(Some("example-residency"), 4) {
197 let heap_buffer = heap
198 .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
199 .expect("heap buffer");
200 residency_set.add_buffer(&heap_buffer);
201 residency_set.add_heap(&heap);
202 residency_set.commit();
203 residency_set.request_residency();
204 queue.add_residency_set(&residency_set);
205 queue.remove_residency_set(&residency_set);
206 residency_set.end_residency();
207 residency_set.remove_all_allocations();
208 residency_set.commit();
209 println!(
210 "residency allocation count={}",
211 residency_set.allocation_count()
212 );
213 } else {
214 println!("residency sets unavailable on this OS");
215 }
216 }
217
218 if let Some(capture_manager) = CaptureManager::shared() {
219 println!(
220 "capture supported for developer tools={} active={}",
221 capture_manager.supports_destination(capture_destination::DEVELOPER_TOOLS),
222 capture_manager.is_capturing(),
223 );
224 if let Some(scope) = capture_manager.new_capture_scope_with_device(&device) {
225 scope.begin();
226 scope.end();
227 }
228 if let Some(scope) = capture_manager.new_capture_scope_with_command_queue(&queue) {
229 scope.begin();
230 scope.end();
231 }
232 }
233}Source§impl ComputeCommandEncoder
impl ComputeCommandEncoder
Sourcepub fn set_compute_pipeline_state(
&mut self,
pipeline: &ComputePipelineState,
) -> Result<(), CommandBufferError>
pub fn set_compute_pipeline_state( &mut self, pipeline: &ComputePipelineState, ) -> Result<(), CommandBufferError>
Bind a compute pipeline state.
Examples found in repository?
examples/05_render_and_explicit_encoders.rs (line 70)
11fn main() {
12 let device = MetalDevice::system_default().expect("Metal device available");
13 println!(
14 "device: {} (registry id {})",
15 device.name(),
16 device.registry_id()
17 );
18
19 let queue = device.new_command_queue().expect("command queue");
20 let status_buffer = unsafe {
21 queue
22 .new_command_buffer_with_unretained_references()
23 .expect("scratch command buffer")
24 };
25 println!("scratch command buffer status={}", status_buffer.status());
26
27 let src = device
28 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
29 .expect("source buffer");
30 let dst = device
31 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
32 .expect("destination buffer");
33 let blit_cb = queue.new_command_buffer().expect("blit command buffer");
34 let mut blit = blit_cb
35 .new_blit_command_encoder()
36 .expect("blit command encoder");
37 blit.fill_buffer(&src, 0..64, b'Z').expect("fill source");
38 blit.copy_buffer(&src, 0, &dst, 0, 64)
39 .expect("copy buffers");
40 blit.end_encoding().expect("end blit encoder");
41 blit_cb.commit().expect("commit blit");
42 blit_cb.wait_until_completed().expect("complete blit");
43 let copied = {
44 let mapping = unsafe { dst.map_read().expect("map destination") };
45 let copied = mapping[..8].to_vec();
46 drop(mapping);
47 copied
48 };
49 println!("blit copied bytes: {copied:?}");
50
51 let library = device
52 .new_library_with_source(common::COMPUTE_SRC)
53 .expect("compile compute library");
54 let increment = library
55 .new_function("increment")
56 .expect("increment function");
57 let pipeline = device
58 .new_compute_pipeline_state(&increment)
59 .expect("compute pipeline");
60
61 let buffer = device
62 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
63 .expect("compute buffer");
64 common::write_u32_words(&buffer, &[10, 20, 30, 40]);
65 let compute_cb = queue.new_command_buffer().expect("compute command buffer");
66 let mut compute = compute_cb
67 .new_compute_command_encoder()
68 .expect("compute command encoder");
69 compute
70 .set_compute_pipeline_state(&pipeline)
71 .expect("bind compute pipeline");
72 compute
73 .set_buffer(&buffer, 0, 0)
74 .expect("bind compute buffer");
75 compute
76 .dispatch_threads((4, 1, 1), (1, 1, 1))
77 .expect("dispatch compute");
78 compute.end_encoding().expect("end compute encoder");
79 compute_cb.commit().expect("commit compute");
80 compute_cb.wait_until_completed().expect("complete compute");
81 println!("compute output: {:?}", common::read_u32_words(&buffer, 4));
82
83 let render_library = device
84 .new_library_with_source(common::RENDER_SRC)
85 .expect("compile render library");
86 let vertex = render_library
87 .new_function("fullscreen_vertex")
88 .expect("vertex function");
89 let fragment = render_library
90 .new_function("solid_fragment")
91 .expect("fragment function");
92 let render_pipeline = device
93 .new_render_pipeline_state(&vertex, &fragment, pixel_format::BGRA8UNORM, 1)
94 .expect("render pipeline");
95 println!("render pipeline label: {:?}", render_pipeline.label());
96
97 let render_target = device
98 .new_texture(common::shared_render_target(4, 4))
99 .expect("render target");
100 let vertex_buffer = device
101 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
102 .expect("vertex buffer");
103 let render_cb = queue.new_command_buffer().expect("render command buffer");
104 let mut render = render_cb
105 .new_render_command_encoder(
106 &render_target,
107 load_action::CLEAR,
108 store_action::STORE,
109 [0.0, 0.0, 0.0, 1.0],
110 )
111 .expect("render command encoder");
112 render
113 .set_render_pipeline_state(&render_pipeline)
114 .expect("bind render pipeline");
115 render
116 .set_vertex_buffer(&vertex_buffer, 0, 0)
117 .expect("bind vertex buffer");
118 render
119 .draw_primitives(primitive_type::TRIANGLE, 0, 3)
120 .expect("draw triangle");
121 render.end_encoding().expect("end render encoder");
122 render_cb.commit().expect("commit render");
123 render_cb.wait_until_completed().expect("complete render");
124
125 let mut rendered = vec![0_u8; 4 * 4 * 4];
126 unsafe {
127 render_target
128 .read_bytes_2d(&mut rendered, 16, (0, 0), (4, 4), 0)
129 .expect("read render target");
130 }
131 println!("first rendered pixel: {:?}", &rendered[..4]);
132
133 let shared_texture = device
134 .new_texture(TextureDescriptor::new_2d(4, 4, pixel_format::BGRA8UNORM))
135 .expect("shared texture");
136 let upload = vec![0x22_u8; 4 * 4 * 4];
137 unsafe {
138 shared_texture
139 .replace_region_2d(&upload, 16, (0, 0), (4, 4), 0)
140 .expect("upload texture");
141 }
142 let mut download = vec![0_u8; upload.len()];
143 unsafe {
144 shared_texture
145 .read_bytes_2d(&mut download, 16, (0, 0), (4, 4), 0)
146 .expect("read texture");
147 }
148 let view = shared_texture
149 .new_view(pixel_format::BGRA8UNORM)
150 .expect("texture view");
151 println!(
152 "texture {}x{} usage={} storage_mode={} view_width={}",
153 shared_texture.width(),
154 shared_texture.height(),
155 shared_texture.usage(),
156 shared_texture.storage_mode(),
157 view.width(),
158 );
159}More examples
examples/07_advanced_objects.rs (line 143)
11fn main() {
12 let device = MetalDevice::system_default().expect("Metal device available");
13 let queue = device.new_command_queue().expect("command queue");
14 let counter_sets = device.counter_set_names();
15 println!("counter sets: {counter_sets:?}");
16
17 if let Some(event) = device.new_shared_event() {
18 event.set_signaled_value(1);
19 println!("event signaled value={}", event.signaled_value());
20 let signal = queue
21 .new_command_buffer()
22 .expect("event signal command buffer");
23 signal
24 .encode_signal_event(&event, 2)
25 .expect("encode event signal");
26 signal.commit().expect("commit event signal");
27 signal
28 .wait_until_completed()
29 .expect("complete event signal");
30 println!(
31 "event reached value 2: {}",
32 event.wait_until_signaled_value(2, 1_000),
33 );
34
35 let wait = queue
36 .new_command_buffer()
37 .expect("event wait command buffer");
38 wait.encode_wait_for_event(&event, 2)
39 .expect("encode event wait");
40 wait.commit().expect("commit event wait");
41 wait.wait_until_completed().expect("complete event wait");
42 }
43
44 let fence_a = device.new_fence();
45 let fence_b = device.new_fence();
46 let sample_buffer = counter_sets.first().and_then(|name| {
47 if device.supports_counter_sampling(counter_sampling_point::AT_BLIT_BOUNDARY) {
48 device
49 .new_counter_sample_buffer(name, 2, storage_mode::SHARED, Some("example-samples"))
50 .ok()
51 } else {
52 None
53 }
54 });
55
56 let src = device
57 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
58 .expect("source buffer");
59 let dst = device
60 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
61 .expect("destination buffer");
62 let blit = queue.new_command_buffer().expect("blit command buffer");
63 let mut encoder = blit.new_blit_command_encoder().expect("blit encoder");
64 encoder
65 .fill_buffer(&src, 0..64, b'Q')
66 .expect("fill source buffer");
67 if let Some(fence) = fence_a.as_ref() {
68 encoder.update_fence(fence).expect("update fence");
69 }
70 encoder.end_encoding().expect("end first blit encoder");
71 blit.commit().expect("commit first blit");
72 blit.wait_until_completed().expect("complete first blit");
73
74 let blit = queue
75 .new_command_buffer()
76 .expect("second blit command buffer");
77 let mut encoder = blit
78 .new_blit_command_encoder()
79 .expect("second blit encoder");
80 if let Some(fence) = fence_a.as_ref() {
81 encoder.wait_for_fence(fence).expect("wait for fence");
82 }
83 if let Some(sample_buffer) = sample_buffer.as_ref() {
84 encoder
85 .sample_counters(sample_buffer, 0, false)
86 .expect("sample counters");
87 }
88 encoder
89 .copy_buffer(&src, 0, &dst, 0, 64)
90 .expect("copy buffers");
91 encoder.end_encoding().expect("end second blit encoder");
92 blit.commit().expect("commit second blit");
93 blit.wait_until_completed().expect("complete second blit");
94 if let Some(sample_buffer) = sample_buffer.as_ref() {
95 println!(
96 "resolved counter bytes={}",
97 sample_buffer
98 .resolve_range(0..1)
99 .map_or(0, |bytes| bytes.len())
100 );
101 }
102
103 let library = device
104 .new_library_with_source(common::COMPUTE_SRC)
105 .expect("compile compute library");
106 let increment = library
107 .new_function("increment")
108 .expect("increment function");
109 let pipeline = device
110 .new_compute_pipeline_state(&increment)
111 .expect("compute pipeline");
112 let visible_table = pipeline.new_visible_function_table(1);
113 let intersection_table = if device.supports_raytracing() {
114 pipeline.new_intersection_function_table(1)
115 } else {
116 None
117 };
118 if let Some(table) = intersection_table.as_ref() {
119 table.set_opaque_triangle_intersection_function(intersection_function_signature::NONE, 0);
120 }
121 let acceleration_structure = if device.supports_raytracing() {
122 device.new_acceleration_structure_with_size(256)
123 } else {
124 None
125 };
126
127 let buffer = device
128 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
129 .expect("compute buffer");
130 common::write_u32_words(&buffer, &[1, 2, 3, 4]);
131 let texture = device
132 .new_texture(apple_metal::TextureDescriptor::new_2d(
133 4,
134 4,
135 apple_metal::pixel_format::BGRA8UNORM,
136 ))
137 .expect("compute texture");
138 let compute = queue.new_command_buffer().expect("compute command buffer");
139 let mut encoder = compute
140 .new_compute_command_encoder()
141 .expect("compute command encoder");
142 encoder
143 .set_compute_pipeline_state(&pipeline)
144 .expect("bind compute pipeline");
145 encoder
146 .set_buffer(&buffer, 0, 0)
147 .expect("bind compute buffer");
148 encoder
149 .set_texture(&texture, 1)
150 .expect("bind compute texture");
151 if let Some(fence) = fence_a.as_ref() {
152 encoder.wait_for_fence(fence).expect("wait for fence");
153 }
154 if let Some(table) = visible_table.as_ref() {
155 encoder
156 .set_visible_function_table(table, 2)
157 .expect("bind visible function table");
158 }
159 if let Some(table) = intersection_table.as_ref() {
160 encoder
161 .set_intersection_function_table(table, 3)
162 .expect("bind intersection function table");
163 }
164 if let Some(acceleration_structure) = acceleration_structure.as_ref() {
165 encoder
166 .set_acceleration_structure(acceleration_structure, 4)
167 .expect("bind acceleration structure");
168 }
169 encoder
170 .dispatch_threadgroups((1, 1, 1), (4, 1, 1))
171 .expect("dispatch compute");
172 if let Some(fence) = fence_b.as_ref() {
173 encoder.update_fence(fence).expect("update fence");
174 }
175 encoder.end_encoding().expect("end compute encoder");
176 compute.commit().expect("commit compute");
177 compute.wait_until_completed().expect("complete compute");
178 println!(
179 "compute buffer after dispatch: {:?}",
180 common::read_u32_words(&buffer, 4)
181 );
182
183 if let Some(indirect) = device.new_indirect_command_buffer(
184 indirect_command_type::CONCURRENT_DISPATCH,
185 1,
186 0,
187 0,
188 4,
189 resource_options::STORAGE_MODE_PRIVATE,
190 ) {
191 indirect.reset_range(0..1);
192 println!("indirect command buffer size={}", indirect.size());
193 }
194
195 if let Some(heap) = device.new_heap(1 << 20, storage_mode::SHARED) {
196 if let Ok(residency_set) = device.new_residency_set(Some("example-residency"), 4) {
197 let heap_buffer = heap
198 .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
199 .expect("heap buffer");
200 residency_set.add_buffer(&heap_buffer);
201 residency_set.add_heap(&heap);
202 residency_set.commit();
203 residency_set.request_residency();
204 queue.add_residency_set(&residency_set);
205 queue.remove_residency_set(&residency_set);
206 residency_set.end_residency();
207 residency_set.remove_all_allocations();
208 residency_set.commit();
209 println!(
210 "residency allocation count={}",
211 residency_set.allocation_count()
212 );
213 } else {
214 println!("residency sets unavailable on this OS");
215 }
216 }
217
218 if let Some(capture_manager) = CaptureManager::shared() {
219 println!(
220 "capture supported for developer tools={} active={}",
221 capture_manager.supports_destination(capture_destination::DEVELOPER_TOOLS),
222 capture_manager.is_capturing(),
223 );
224 if let Some(scope) = capture_manager.new_capture_scope_with_device(&device) {
225 scope.begin();
226 scope.end();
227 }
228 if let Some(scope) = capture_manager.new_capture_scope_with_command_queue(&queue) {
229 scope.begin();
230 scope.end();
231 }
232 }
233}Sourcepub fn set_buffer(
&mut self,
buffer: &MetalBuffer,
offset: usize,
index: usize,
) -> Result<(), CommandBufferError>
pub fn set_buffer( &mut self, buffer: &MetalBuffer, offset: usize, index: usize, ) -> Result<(), CommandBufferError>
Bind a buffer at index.
Examples found in repository?
examples/05_render_and_explicit_encoders.rs (line 73)
11fn main() {
12 let device = MetalDevice::system_default().expect("Metal device available");
13 println!(
14 "device: {} (registry id {})",
15 device.name(),
16 device.registry_id()
17 );
18
19 let queue = device.new_command_queue().expect("command queue");
20 let status_buffer = unsafe {
21 queue
22 .new_command_buffer_with_unretained_references()
23 .expect("scratch command buffer")
24 };
25 println!("scratch command buffer status={}", status_buffer.status());
26
27 let src = device
28 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
29 .expect("source buffer");
30 let dst = device
31 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
32 .expect("destination buffer");
33 let blit_cb = queue.new_command_buffer().expect("blit command buffer");
34 let mut blit = blit_cb
35 .new_blit_command_encoder()
36 .expect("blit command encoder");
37 blit.fill_buffer(&src, 0..64, b'Z').expect("fill source");
38 blit.copy_buffer(&src, 0, &dst, 0, 64)
39 .expect("copy buffers");
40 blit.end_encoding().expect("end blit encoder");
41 blit_cb.commit().expect("commit blit");
42 blit_cb.wait_until_completed().expect("complete blit");
43 let copied = {
44 let mapping = unsafe { dst.map_read().expect("map destination") };
45 let copied = mapping[..8].to_vec();
46 drop(mapping);
47 copied
48 };
49 println!("blit copied bytes: {copied:?}");
50
51 let library = device
52 .new_library_with_source(common::COMPUTE_SRC)
53 .expect("compile compute library");
54 let increment = library
55 .new_function("increment")
56 .expect("increment function");
57 let pipeline = device
58 .new_compute_pipeline_state(&increment)
59 .expect("compute pipeline");
60
61 let buffer = device
62 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
63 .expect("compute buffer");
64 common::write_u32_words(&buffer, &[10, 20, 30, 40]);
65 let compute_cb = queue.new_command_buffer().expect("compute command buffer");
66 let mut compute = compute_cb
67 .new_compute_command_encoder()
68 .expect("compute command encoder");
69 compute
70 .set_compute_pipeline_state(&pipeline)
71 .expect("bind compute pipeline");
72 compute
73 .set_buffer(&buffer, 0, 0)
74 .expect("bind compute buffer");
75 compute
76 .dispatch_threads((4, 1, 1), (1, 1, 1))
77 .expect("dispatch compute");
78 compute.end_encoding().expect("end compute encoder");
79 compute_cb.commit().expect("commit compute");
80 compute_cb.wait_until_completed().expect("complete compute");
81 println!("compute output: {:?}", common::read_u32_words(&buffer, 4));
82
83 let render_library = device
84 .new_library_with_source(common::RENDER_SRC)
85 .expect("compile render library");
86 let vertex = render_library
87 .new_function("fullscreen_vertex")
88 .expect("vertex function");
89 let fragment = render_library
90 .new_function("solid_fragment")
91 .expect("fragment function");
92 let render_pipeline = device
93 .new_render_pipeline_state(&vertex, &fragment, pixel_format::BGRA8UNORM, 1)
94 .expect("render pipeline");
95 println!("render pipeline label: {:?}", render_pipeline.label());
96
97 let render_target = device
98 .new_texture(common::shared_render_target(4, 4))
99 .expect("render target");
100 let vertex_buffer = device
101 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
102 .expect("vertex buffer");
103 let render_cb = queue.new_command_buffer().expect("render command buffer");
104 let mut render = render_cb
105 .new_render_command_encoder(
106 &render_target,
107 load_action::CLEAR,
108 store_action::STORE,
109 [0.0, 0.0, 0.0, 1.0],
110 )
111 .expect("render command encoder");
112 render
113 .set_render_pipeline_state(&render_pipeline)
114 .expect("bind render pipeline");
115 render
116 .set_vertex_buffer(&vertex_buffer, 0, 0)
117 .expect("bind vertex buffer");
118 render
119 .draw_primitives(primitive_type::TRIANGLE, 0, 3)
120 .expect("draw triangle");
121 render.end_encoding().expect("end render encoder");
122 render_cb.commit().expect("commit render");
123 render_cb.wait_until_completed().expect("complete render");
124
125 let mut rendered = vec![0_u8; 4 * 4 * 4];
126 unsafe {
127 render_target
128 .read_bytes_2d(&mut rendered, 16, (0, 0), (4, 4), 0)
129 .expect("read render target");
130 }
131 println!("first rendered pixel: {:?}", &rendered[..4]);
132
133 let shared_texture = device
134 .new_texture(TextureDescriptor::new_2d(4, 4, pixel_format::BGRA8UNORM))
135 .expect("shared texture");
136 let upload = vec![0x22_u8; 4 * 4 * 4];
137 unsafe {
138 shared_texture
139 .replace_region_2d(&upload, 16, (0, 0), (4, 4), 0)
140 .expect("upload texture");
141 }
142 let mut download = vec![0_u8; upload.len()];
143 unsafe {
144 shared_texture
145 .read_bytes_2d(&mut download, 16, (0, 0), (4, 4), 0)
146 .expect("read texture");
147 }
148 let view = shared_texture
149 .new_view(pixel_format::BGRA8UNORM)
150 .expect("texture view");
151 println!(
152 "texture {}x{} usage={} storage_mode={} view_width={}",
153 shared_texture.width(),
154 shared_texture.height(),
155 shared_texture.usage(),
156 shared_texture.storage_mode(),
157 view.width(),
158 );
159}More examples
examples/07_advanced_objects.rs (line 146)
11fn main() {
12 let device = MetalDevice::system_default().expect("Metal device available");
13 let queue = device.new_command_queue().expect("command queue");
14 let counter_sets = device.counter_set_names();
15 println!("counter sets: {counter_sets:?}");
16
17 if let Some(event) = device.new_shared_event() {
18 event.set_signaled_value(1);
19 println!("event signaled value={}", event.signaled_value());
20 let signal = queue
21 .new_command_buffer()
22 .expect("event signal command buffer");
23 signal
24 .encode_signal_event(&event, 2)
25 .expect("encode event signal");
26 signal.commit().expect("commit event signal");
27 signal
28 .wait_until_completed()
29 .expect("complete event signal");
30 println!(
31 "event reached value 2: {}",
32 event.wait_until_signaled_value(2, 1_000),
33 );
34
35 let wait = queue
36 .new_command_buffer()
37 .expect("event wait command buffer");
38 wait.encode_wait_for_event(&event, 2)
39 .expect("encode event wait");
40 wait.commit().expect("commit event wait");
41 wait.wait_until_completed().expect("complete event wait");
42 }
43
44 let fence_a = device.new_fence();
45 let fence_b = device.new_fence();
46 let sample_buffer = counter_sets.first().and_then(|name| {
47 if device.supports_counter_sampling(counter_sampling_point::AT_BLIT_BOUNDARY) {
48 device
49 .new_counter_sample_buffer(name, 2, storage_mode::SHARED, Some("example-samples"))
50 .ok()
51 } else {
52 None
53 }
54 });
55
56 let src = device
57 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
58 .expect("source buffer");
59 let dst = device
60 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
61 .expect("destination buffer");
62 let blit = queue.new_command_buffer().expect("blit command buffer");
63 let mut encoder = blit.new_blit_command_encoder().expect("blit encoder");
64 encoder
65 .fill_buffer(&src, 0..64, b'Q')
66 .expect("fill source buffer");
67 if let Some(fence) = fence_a.as_ref() {
68 encoder.update_fence(fence).expect("update fence");
69 }
70 encoder.end_encoding().expect("end first blit encoder");
71 blit.commit().expect("commit first blit");
72 blit.wait_until_completed().expect("complete first blit");
73
74 let blit = queue
75 .new_command_buffer()
76 .expect("second blit command buffer");
77 let mut encoder = blit
78 .new_blit_command_encoder()
79 .expect("second blit encoder");
80 if let Some(fence) = fence_a.as_ref() {
81 encoder.wait_for_fence(fence).expect("wait for fence");
82 }
83 if let Some(sample_buffer) = sample_buffer.as_ref() {
84 encoder
85 .sample_counters(sample_buffer, 0, false)
86 .expect("sample counters");
87 }
88 encoder
89 .copy_buffer(&src, 0, &dst, 0, 64)
90 .expect("copy buffers");
91 encoder.end_encoding().expect("end second blit encoder");
92 blit.commit().expect("commit second blit");
93 blit.wait_until_completed().expect("complete second blit");
94 if let Some(sample_buffer) = sample_buffer.as_ref() {
95 println!(
96 "resolved counter bytes={}",
97 sample_buffer
98 .resolve_range(0..1)
99 .map_or(0, |bytes| bytes.len())
100 );
101 }
102
103 let library = device
104 .new_library_with_source(common::COMPUTE_SRC)
105 .expect("compile compute library");
106 let increment = library
107 .new_function("increment")
108 .expect("increment function");
109 let pipeline = device
110 .new_compute_pipeline_state(&increment)
111 .expect("compute pipeline");
112 let visible_table = pipeline.new_visible_function_table(1);
113 let intersection_table = if device.supports_raytracing() {
114 pipeline.new_intersection_function_table(1)
115 } else {
116 None
117 };
118 if let Some(table) = intersection_table.as_ref() {
119 table.set_opaque_triangle_intersection_function(intersection_function_signature::NONE, 0);
120 }
121 let acceleration_structure = if device.supports_raytracing() {
122 device.new_acceleration_structure_with_size(256)
123 } else {
124 None
125 };
126
127 let buffer = device
128 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
129 .expect("compute buffer");
130 common::write_u32_words(&buffer, &[1, 2, 3, 4]);
131 let texture = device
132 .new_texture(apple_metal::TextureDescriptor::new_2d(
133 4,
134 4,
135 apple_metal::pixel_format::BGRA8UNORM,
136 ))
137 .expect("compute texture");
138 let compute = queue.new_command_buffer().expect("compute command buffer");
139 let mut encoder = compute
140 .new_compute_command_encoder()
141 .expect("compute command encoder");
142 encoder
143 .set_compute_pipeline_state(&pipeline)
144 .expect("bind compute pipeline");
145 encoder
146 .set_buffer(&buffer, 0, 0)
147 .expect("bind compute buffer");
148 encoder
149 .set_texture(&texture, 1)
150 .expect("bind compute texture");
151 if let Some(fence) = fence_a.as_ref() {
152 encoder.wait_for_fence(fence).expect("wait for fence");
153 }
154 if let Some(table) = visible_table.as_ref() {
155 encoder
156 .set_visible_function_table(table, 2)
157 .expect("bind visible function table");
158 }
159 if let Some(table) = intersection_table.as_ref() {
160 encoder
161 .set_intersection_function_table(table, 3)
162 .expect("bind intersection function table");
163 }
164 if let Some(acceleration_structure) = acceleration_structure.as_ref() {
165 encoder
166 .set_acceleration_structure(acceleration_structure, 4)
167 .expect("bind acceleration structure");
168 }
169 encoder
170 .dispatch_threadgroups((1, 1, 1), (4, 1, 1))
171 .expect("dispatch compute");
172 if let Some(fence) = fence_b.as_ref() {
173 encoder.update_fence(fence).expect("update fence");
174 }
175 encoder.end_encoding().expect("end compute encoder");
176 compute.commit().expect("commit compute");
177 compute.wait_until_completed().expect("complete compute");
178 println!(
179 "compute buffer after dispatch: {:?}",
180 common::read_u32_words(&buffer, 4)
181 );
182
183 if let Some(indirect) = device.new_indirect_command_buffer(
184 indirect_command_type::CONCURRENT_DISPATCH,
185 1,
186 0,
187 0,
188 4,
189 resource_options::STORAGE_MODE_PRIVATE,
190 ) {
191 indirect.reset_range(0..1);
192 println!("indirect command buffer size={}", indirect.size());
193 }
194
195 if let Some(heap) = device.new_heap(1 << 20, storage_mode::SHARED) {
196 if let Ok(residency_set) = device.new_residency_set(Some("example-residency"), 4) {
197 let heap_buffer = heap
198 .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
199 .expect("heap buffer");
200 residency_set.add_buffer(&heap_buffer);
201 residency_set.add_heap(&heap);
202 residency_set.commit();
203 residency_set.request_residency();
204 queue.add_residency_set(&residency_set);
205 queue.remove_residency_set(&residency_set);
206 residency_set.end_residency();
207 residency_set.remove_all_allocations();
208 residency_set.commit();
209 println!(
210 "residency allocation count={}",
211 residency_set.allocation_count()
212 );
213 } else {
214 println!("residency sets unavailable on this OS");
215 }
216 }
217
218 if let Some(capture_manager) = CaptureManager::shared() {
219 println!(
220 "capture supported for developer tools={} active={}",
221 capture_manager.supports_destination(capture_destination::DEVELOPER_TOOLS),
222 capture_manager.is_capturing(),
223 );
224 if let Some(scope) = capture_manager.new_capture_scope_with_device(&device) {
225 scope.begin();
226 scope.end();
227 }
228 if let Some(scope) = capture_manager.new_capture_scope_with_command_queue(&queue) {
229 scope.begin();
230 scope.end();
231 }
232 }
233}Sourcepub fn set_texture(
&mut self,
texture: &MetalTexture,
index: usize,
) -> Result<(), CommandBufferError>
pub fn set_texture( &mut self, texture: &MetalTexture, index: usize, ) -> Result<(), CommandBufferError>
Bind a texture at index.
Examples found in repository?
examples/07_advanced_objects.rs (line 149)
11fn main() {
12 let device = MetalDevice::system_default().expect("Metal device available");
13 let queue = device.new_command_queue().expect("command queue");
14 let counter_sets = device.counter_set_names();
15 println!("counter sets: {counter_sets:?}");
16
17 if let Some(event) = device.new_shared_event() {
18 event.set_signaled_value(1);
19 println!("event signaled value={}", event.signaled_value());
20 let signal = queue
21 .new_command_buffer()
22 .expect("event signal command buffer");
23 signal
24 .encode_signal_event(&event, 2)
25 .expect("encode event signal");
26 signal.commit().expect("commit event signal");
27 signal
28 .wait_until_completed()
29 .expect("complete event signal");
30 println!(
31 "event reached value 2: {}",
32 event.wait_until_signaled_value(2, 1_000),
33 );
34
35 let wait = queue
36 .new_command_buffer()
37 .expect("event wait command buffer");
38 wait.encode_wait_for_event(&event, 2)
39 .expect("encode event wait");
40 wait.commit().expect("commit event wait");
41 wait.wait_until_completed().expect("complete event wait");
42 }
43
44 let fence_a = device.new_fence();
45 let fence_b = device.new_fence();
46 let sample_buffer = counter_sets.first().and_then(|name| {
47 if device.supports_counter_sampling(counter_sampling_point::AT_BLIT_BOUNDARY) {
48 device
49 .new_counter_sample_buffer(name, 2, storage_mode::SHARED, Some("example-samples"))
50 .ok()
51 } else {
52 None
53 }
54 });
55
56 let src = device
57 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
58 .expect("source buffer");
59 let dst = device
60 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
61 .expect("destination buffer");
62 let blit = queue.new_command_buffer().expect("blit command buffer");
63 let mut encoder = blit.new_blit_command_encoder().expect("blit encoder");
64 encoder
65 .fill_buffer(&src, 0..64, b'Q')
66 .expect("fill source buffer");
67 if let Some(fence) = fence_a.as_ref() {
68 encoder.update_fence(fence).expect("update fence");
69 }
70 encoder.end_encoding().expect("end first blit encoder");
71 blit.commit().expect("commit first blit");
72 blit.wait_until_completed().expect("complete first blit");
73
74 let blit = queue
75 .new_command_buffer()
76 .expect("second blit command buffer");
77 let mut encoder = blit
78 .new_blit_command_encoder()
79 .expect("second blit encoder");
80 if let Some(fence) = fence_a.as_ref() {
81 encoder.wait_for_fence(fence).expect("wait for fence");
82 }
83 if let Some(sample_buffer) = sample_buffer.as_ref() {
84 encoder
85 .sample_counters(sample_buffer, 0, false)
86 .expect("sample counters");
87 }
88 encoder
89 .copy_buffer(&src, 0, &dst, 0, 64)
90 .expect("copy buffers");
91 encoder.end_encoding().expect("end second blit encoder");
92 blit.commit().expect("commit second blit");
93 blit.wait_until_completed().expect("complete second blit");
94 if let Some(sample_buffer) = sample_buffer.as_ref() {
95 println!(
96 "resolved counter bytes={}",
97 sample_buffer
98 .resolve_range(0..1)
99 .map_or(0, |bytes| bytes.len())
100 );
101 }
102
103 let library = device
104 .new_library_with_source(common::COMPUTE_SRC)
105 .expect("compile compute library");
106 let increment = library
107 .new_function("increment")
108 .expect("increment function");
109 let pipeline = device
110 .new_compute_pipeline_state(&increment)
111 .expect("compute pipeline");
112 let visible_table = pipeline.new_visible_function_table(1);
113 let intersection_table = if device.supports_raytracing() {
114 pipeline.new_intersection_function_table(1)
115 } else {
116 None
117 };
118 if let Some(table) = intersection_table.as_ref() {
119 table.set_opaque_triangle_intersection_function(intersection_function_signature::NONE, 0);
120 }
121 let acceleration_structure = if device.supports_raytracing() {
122 device.new_acceleration_structure_with_size(256)
123 } else {
124 None
125 };
126
127 let buffer = device
128 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
129 .expect("compute buffer");
130 common::write_u32_words(&buffer, &[1, 2, 3, 4]);
131 let texture = device
132 .new_texture(apple_metal::TextureDescriptor::new_2d(
133 4,
134 4,
135 apple_metal::pixel_format::BGRA8UNORM,
136 ))
137 .expect("compute texture");
138 let compute = queue.new_command_buffer().expect("compute command buffer");
139 let mut encoder = compute
140 .new_compute_command_encoder()
141 .expect("compute command encoder");
142 encoder
143 .set_compute_pipeline_state(&pipeline)
144 .expect("bind compute pipeline");
145 encoder
146 .set_buffer(&buffer, 0, 0)
147 .expect("bind compute buffer");
148 encoder
149 .set_texture(&texture, 1)
150 .expect("bind compute texture");
151 if let Some(fence) = fence_a.as_ref() {
152 encoder.wait_for_fence(fence).expect("wait for fence");
153 }
154 if let Some(table) = visible_table.as_ref() {
155 encoder
156 .set_visible_function_table(table, 2)
157 .expect("bind visible function table");
158 }
159 if let Some(table) = intersection_table.as_ref() {
160 encoder
161 .set_intersection_function_table(table, 3)
162 .expect("bind intersection function table");
163 }
164 if let Some(acceleration_structure) = acceleration_structure.as_ref() {
165 encoder
166 .set_acceleration_structure(acceleration_structure, 4)
167 .expect("bind acceleration structure");
168 }
169 encoder
170 .dispatch_threadgroups((1, 1, 1), (4, 1, 1))
171 .expect("dispatch compute");
172 if let Some(fence) = fence_b.as_ref() {
173 encoder.update_fence(fence).expect("update fence");
174 }
175 encoder.end_encoding().expect("end compute encoder");
176 compute.commit().expect("commit compute");
177 compute.wait_until_completed().expect("complete compute");
178 println!(
179 "compute buffer after dispatch: {:?}",
180 common::read_u32_words(&buffer, 4)
181 );
182
183 if let Some(indirect) = device.new_indirect_command_buffer(
184 indirect_command_type::CONCURRENT_DISPATCH,
185 1,
186 0,
187 0,
188 4,
189 resource_options::STORAGE_MODE_PRIVATE,
190 ) {
191 indirect.reset_range(0..1);
192 println!("indirect command buffer size={}", indirect.size());
193 }
194
195 if let Some(heap) = device.new_heap(1 << 20, storage_mode::SHARED) {
196 if let Ok(residency_set) = device.new_residency_set(Some("example-residency"), 4) {
197 let heap_buffer = heap
198 .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
199 .expect("heap buffer");
200 residency_set.add_buffer(&heap_buffer);
201 residency_set.add_heap(&heap);
202 residency_set.commit();
203 residency_set.request_residency();
204 queue.add_residency_set(&residency_set);
205 queue.remove_residency_set(&residency_set);
206 residency_set.end_residency();
207 residency_set.remove_all_allocations();
208 residency_set.commit();
209 println!(
210 "residency allocation count={}",
211 residency_set.allocation_count()
212 );
213 } else {
214 println!("residency sets unavailable on this OS");
215 }
216 }
217
218 if let Some(capture_manager) = CaptureManager::shared() {
219 println!(
220 "capture supported for developer tools={} active={}",
221 capture_manager.supports_destination(capture_destination::DEVELOPER_TOOLS),
222 capture_manager.is_capturing(),
223 );
224 if let Some(scope) = capture_manager.new_capture_scope_with_device(&device) {
225 scope.begin();
226 scope.end();
227 }
228 if let Some(scope) = capture_manager.new_capture_scope_with_command_queue(&queue) {
229 scope.begin();
230 scope.end();
231 }
232 }
233}Sourcepub fn set_sampler_state(
&mut self,
sampler: &SamplerState,
index: usize,
) -> Result<(), CommandBufferError>
pub fn set_sampler_state( &mut self, sampler: &SamplerState, index: usize, ) -> Result<(), CommandBufferError>
Bind a sampler state at index.
Sourcepub fn set_visible_function_table(
&mut self,
table: &VisibleFunctionTable,
index: usize,
) -> Result<(), CommandBufferError>
pub fn set_visible_function_table( &mut self, table: &VisibleFunctionTable, index: usize, ) -> Result<(), CommandBufferError>
Bind a visible function table at index.
Examples found in repository?
examples/07_advanced_objects.rs (line 156)
11fn main() {
12 let device = MetalDevice::system_default().expect("Metal device available");
13 let queue = device.new_command_queue().expect("command queue");
14 let counter_sets = device.counter_set_names();
15 println!("counter sets: {counter_sets:?}");
16
17 if let Some(event) = device.new_shared_event() {
18 event.set_signaled_value(1);
19 println!("event signaled value={}", event.signaled_value());
20 let signal = queue
21 .new_command_buffer()
22 .expect("event signal command buffer");
23 signal
24 .encode_signal_event(&event, 2)
25 .expect("encode event signal");
26 signal.commit().expect("commit event signal");
27 signal
28 .wait_until_completed()
29 .expect("complete event signal");
30 println!(
31 "event reached value 2: {}",
32 event.wait_until_signaled_value(2, 1_000),
33 );
34
35 let wait = queue
36 .new_command_buffer()
37 .expect("event wait command buffer");
38 wait.encode_wait_for_event(&event, 2)
39 .expect("encode event wait");
40 wait.commit().expect("commit event wait");
41 wait.wait_until_completed().expect("complete event wait");
42 }
43
44 let fence_a = device.new_fence();
45 let fence_b = device.new_fence();
46 let sample_buffer = counter_sets.first().and_then(|name| {
47 if device.supports_counter_sampling(counter_sampling_point::AT_BLIT_BOUNDARY) {
48 device
49 .new_counter_sample_buffer(name, 2, storage_mode::SHARED, Some("example-samples"))
50 .ok()
51 } else {
52 None
53 }
54 });
55
56 let src = device
57 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
58 .expect("source buffer");
59 let dst = device
60 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
61 .expect("destination buffer");
62 let blit = queue.new_command_buffer().expect("blit command buffer");
63 let mut encoder = blit.new_blit_command_encoder().expect("blit encoder");
64 encoder
65 .fill_buffer(&src, 0..64, b'Q')
66 .expect("fill source buffer");
67 if let Some(fence) = fence_a.as_ref() {
68 encoder.update_fence(fence).expect("update fence");
69 }
70 encoder.end_encoding().expect("end first blit encoder");
71 blit.commit().expect("commit first blit");
72 blit.wait_until_completed().expect("complete first blit");
73
74 let blit = queue
75 .new_command_buffer()
76 .expect("second blit command buffer");
77 let mut encoder = blit
78 .new_blit_command_encoder()
79 .expect("second blit encoder");
80 if let Some(fence) = fence_a.as_ref() {
81 encoder.wait_for_fence(fence).expect("wait for fence");
82 }
83 if let Some(sample_buffer) = sample_buffer.as_ref() {
84 encoder
85 .sample_counters(sample_buffer, 0, false)
86 .expect("sample counters");
87 }
88 encoder
89 .copy_buffer(&src, 0, &dst, 0, 64)
90 .expect("copy buffers");
91 encoder.end_encoding().expect("end second blit encoder");
92 blit.commit().expect("commit second blit");
93 blit.wait_until_completed().expect("complete second blit");
94 if let Some(sample_buffer) = sample_buffer.as_ref() {
95 println!(
96 "resolved counter bytes={}",
97 sample_buffer
98 .resolve_range(0..1)
99 .map_or(0, |bytes| bytes.len())
100 );
101 }
102
103 let library = device
104 .new_library_with_source(common::COMPUTE_SRC)
105 .expect("compile compute library");
106 let increment = library
107 .new_function("increment")
108 .expect("increment function");
109 let pipeline = device
110 .new_compute_pipeline_state(&increment)
111 .expect("compute pipeline");
112 let visible_table = pipeline.new_visible_function_table(1);
113 let intersection_table = if device.supports_raytracing() {
114 pipeline.new_intersection_function_table(1)
115 } else {
116 None
117 };
118 if let Some(table) = intersection_table.as_ref() {
119 table.set_opaque_triangle_intersection_function(intersection_function_signature::NONE, 0);
120 }
121 let acceleration_structure = if device.supports_raytracing() {
122 device.new_acceleration_structure_with_size(256)
123 } else {
124 None
125 };
126
127 let buffer = device
128 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
129 .expect("compute buffer");
130 common::write_u32_words(&buffer, &[1, 2, 3, 4]);
131 let texture = device
132 .new_texture(apple_metal::TextureDescriptor::new_2d(
133 4,
134 4,
135 apple_metal::pixel_format::BGRA8UNORM,
136 ))
137 .expect("compute texture");
138 let compute = queue.new_command_buffer().expect("compute command buffer");
139 let mut encoder = compute
140 .new_compute_command_encoder()
141 .expect("compute command encoder");
142 encoder
143 .set_compute_pipeline_state(&pipeline)
144 .expect("bind compute pipeline");
145 encoder
146 .set_buffer(&buffer, 0, 0)
147 .expect("bind compute buffer");
148 encoder
149 .set_texture(&texture, 1)
150 .expect("bind compute texture");
151 if let Some(fence) = fence_a.as_ref() {
152 encoder.wait_for_fence(fence).expect("wait for fence");
153 }
154 if let Some(table) = visible_table.as_ref() {
155 encoder
156 .set_visible_function_table(table, 2)
157 .expect("bind visible function table");
158 }
159 if let Some(table) = intersection_table.as_ref() {
160 encoder
161 .set_intersection_function_table(table, 3)
162 .expect("bind intersection function table");
163 }
164 if let Some(acceleration_structure) = acceleration_structure.as_ref() {
165 encoder
166 .set_acceleration_structure(acceleration_structure, 4)
167 .expect("bind acceleration structure");
168 }
169 encoder
170 .dispatch_threadgroups((1, 1, 1), (4, 1, 1))
171 .expect("dispatch compute");
172 if let Some(fence) = fence_b.as_ref() {
173 encoder.update_fence(fence).expect("update fence");
174 }
175 encoder.end_encoding().expect("end compute encoder");
176 compute.commit().expect("commit compute");
177 compute.wait_until_completed().expect("complete compute");
178 println!(
179 "compute buffer after dispatch: {:?}",
180 common::read_u32_words(&buffer, 4)
181 );
182
183 if let Some(indirect) = device.new_indirect_command_buffer(
184 indirect_command_type::CONCURRENT_DISPATCH,
185 1,
186 0,
187 0,
188 4,
189 resource_options::STORAGE_MODE_PRIVATE,
190 ) {
191 indirect.reset_range(0..1);
192 println!("indirect command buffer size={}", indirect.size());
193 }
194
195 if let Some(heap) = device.new_heap(1 << 20, storage_mode::SHARED) {
196 if let Ok(residency_set) = device.new_residency_set(Some("example-residency"), 4) {
197 let heap_buffer = heap
198 .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
199 .expect("heap buffer");
200 residency_set.add_buffer(&heap_buffer);
201 residency_set.add_heap(&heap);
202 residency_set.commit();
203 residency_set.request_residency();
204 queue.add_residency_set(&residency_set);
205 queue.remove_residency_set(&residency_set);
206 residency_set.end_residency();
207 residency_set.remove_all_allocations();
208 residency_set.commit();
209 println!(
210 "residency allocation count={}",
211 residency_set.allocation_count()
212 );
213 } else {
214 println!("residency sets unavailable on this OS");
215 }
216 }
217
218 if let Some(capture_manager) = CaptureManager::shared() {
219 println!(
220 "capture supported for developer tools={} active={}",
221 capture_manager.supports_destination(capture_destination::DEVELOPER_TOOLS),
222 capture_manager.is_capturing(),
223 );
224 if let Some(scope) = capture_manager.new_capture_scope_with_device(&device) {
225 scope.begin();
226 scope.end();
227 }
228 if let Some(scope) = capture_manager.new_capture_scope_with_command_queue(&queue) {
229 scope.begin();
230 scope.end();
231 }
232 }
233}Sourcepub fn set_intersection_function_table(
&mut self,
table: &IntersectionFunctionTable,
index: usize,
) -> Result<(), CommandBufferError>
pub fn set_intersection_function_table( &mut self, table: &IntersectionFunctionTable, index: usize, ) -> Result<(), CommandBufferError>
Bind an intersection function table at index.
Examples found in repository?
examples/07_advanced_objects.rs (line 161)
11fn main() {
12 let device = MetalDevice::system_default().expect("Metal device available");
13 let queue = device.new_command_queue().expect("command queue");
14 let counter_sets = device.counter_set_names();
15 println!("counter sets: {counter_sets:?}");
16
17 if let Some(event) = device.new_shared_event() {
18 event.set_signaled_value(1);
19 println!("event signaled value={}", event.signaled_value());
20 let signal = queue
21 .new_command_buffer()
22 .expect("event signal command buffer");
23 signal
24 .encode_signal_event(&event, 2)
25 .expect("encode event signal");
26 signal.commit().expect("commit event signal");
27 signal
28 .wait_until_completed()
29 .expect("complete event signal");
30 println!(
31 "event reached value 2: {}",
32 event.wait_until_signaled_value(2, 1_000),
33 );
34
35 let wait = queue
36 .new_command_buffer()
37 .expect("event wait command buffer");
38 wait.encode_wait_for_event(&event, 2)
39 .expect("encode event wait");
40 wait.commit().expect("commit event wait");
41 wait.wait_until_completed().expect("complete event wait");
42 }
43
44 let fence_a = device.new_fence();
45 let fence_b = device.new_fence();
46 let sample_buffer = counter_sets.first().and_then(|name| {
47 if device.supports_counter_sampling(counter_sampling_point::AT_BLIT_BOUNDARY) {
48 device
49 .new_counter_sample_buffer(name, 2, storage_mode::SHARED, Some("example-samples"))
50 .ok()
51 } else {
52 None
53 }
54 });
55
56 let src = device
57 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
58 .expect("source buffer");
59 let dst = device
60 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
61 .expect("destination buffer");
62 let blit = queue.new_command_buffer().expect("blit command buffer");
63 let mut encoder = blit.new_blit_command_encoder().expect("blit encoder");
64 encoder
65 .fill_buffer(&src, 0..64, b'Q')
66 .expect("fill source buffer");
67 if let Some(fence) = fence_a.as_ref() {
68 encoder.update_fence(fence).expect("update fence");
69 }
70 encoder.end_encoding().expect("end first blit encoder");
71 blit.commit().expect("commit first blit");
72 blit.wait_until_completed().expect("complete first blit");
73
74 let blit = queue
75 .new_command_buffer()
76 .expect("second blit command buffer");
77 let mut encoder = blit
78 .new_blit_command_encoder()
79 .expect("second blit encoder");
80 if let Some(fence) = fence_a.as_ref() {
81 encoder.wait_for_fence(fence).expect("wait for fence");
82 }
83 if let Some(sample_buffer) = sample_buffer.as_ref() {
84 encoder
85 .sample_counters(sample_buffer, 0, false)
86 .expect("sample counters");
87 }
88 encoder
89 .copy_buffer(&src, 0, &dst, 0, 64)
90 .expect("copy buffers");
91 encoder.end_encoding().expect("end second blit encoder");
92 blit.commit().expect("commit second blit");
93 blit.wait_until_completed().expect("complete second blit");
94 if let Some(sample_buffer) = sample_buffer.as_ref() {
95 println!(
96 "resolved counter bytes={}",
97 sample_buffer
98 .resolve_range(0..1)
99 .map_or(0, |bytes| bytes.len())
100 );
101 }
102
103 let library = device
104 .new_library_with_source(common::COMPUTE_SRC)
105 .expect("compile compute library");
106 let increment = library
107 .new_function("increment")
108 .expect("increment function");
109 let pipeline = device
110 .new_compute_pipeline_state(&increment)
111 .expect("compute pipeline");
112 let visible_table = pipeline.new_visible_function_table(1);
113 let intersection_table = if device.supports_raytracing() {
114 pipeline.new_intersection_function_table(1)
115 } else {
116 None
117 };
118 if let Some(table) = intersection_table.as_ref() {
119 table.set_opaque_triangle_intersection_function(intersection_function_signature::NONE, 0);
120 }
121 let acceleration_structure = if device.supports_raytracing() {
122 device.new_acceleration_structure_with_size(256)
123 } else {
124 None
125 };
126
127 let buffer = device
128 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
129 .expect("compute buffer");
130 common::write_u32_words(&buffer, &[1, 2, 3, 4]);
131 let texture = device
132 .new_texture(apple_metal::TextureDescriptor::new_2d(
133 4,
134 4,
135 apple_metal::pixel_format::BGRA8UNORM,
136 ))
137 .expect("compute texture");
138 let compute = queue.new_command_buffer().expect("compute command buffer");
139 let mut encoder = compute
140 .new_compute_command_encoder()
141 .expect("compute command encoder");
142 encoder
143 .set_compute_pipeline_state(&pipeline)
144 .expect("bind compute pipeline");
145 encoder
146 .set_buffer(&buffer, 0, 0)
147 .expect("bind compute buffer");
148 encoder
149 .set_texture(&texture, 1)
150 .expect("bind compute texture");
151 if let Some(fence) = fence_a.as_ref() {
152 encoder.wait_for_fence(fence).expect("wait for fence");
153 }
154 if let Some(table) = visible_table.as_ref() {
155 encoder
156 .set_visible_function_table(table, 2)
157 .expect("bind visible function table");
158 }
159 if let Some(table) = intersection_table.as_ref() {
160 encoder
161 .set_intersection_function_table(table, 3)
162 .expect("bind intersection function table");
163 }
164 if let Some(acceleration_structure) = acceleration_structure.as_ref() {
165 encoder
166 .set_acceleration_structure(acceleration_structure, 4)
167 .expect("bind acceleration structure");
168 }
169 encoder
170 .dispatch_threadgroups((1, 1, 1), (4, 1, 1))
171 .expect("dispatch compute");
172 if let Some(fence) = fence_b.as_ref() {
173 encoder.update_fence(fence).expect("update fence");
174 }
175 encoder.end_encoding().expect("end compute encoder");
176 compute.commit().expect("commit compute");
177 compute.wait_until_completed().expect("complete compute");
178 println!(
179 "compute buffer after dispatch: {:?}",
180 common::read_u32_words(&buffer, 4)
181 );
182
183 if let Some(indirect) = device.new_indirect_command_buffer(
184 indirect_command_type::CONCURRENT_DISPATCH,
185 1,
186 0,
187 0,
188 4,
189 resource_options::STORAGE_MODE_PRIVATE,
190 ) {
191 indirect.reset_range(0..1);
192 println!("indirect command buffer size={}", indirect.size());
193 }
194
195 if let Some(heap) = device.new_heap(1 << 20, storage_mode::SHARED) {
196 if let Ok(residency_set) = device.new_residency_set(Some("example-residency"), 4) {
197 let heap_buffer = heap
198 .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
199 .expect("heap buffer");
200 residency_set.add_buffer(&heap_buffer);
201 residency_set.add_heap(&heap);
202 residency_set.commit();
203 residency_set.request_residency();
204 queue.add_residency_set(&residency_set);
205 queue.remove_residency_set(&residency_set);
206 residency_set.end_residency();
207 residency_set.remove_all_allocations();
208 residency_set.commit();
209 println!(
210 "residency allocation count={}",
211 residency_set.allocation_count()
212 );
213 } else {
214 println!("residency sets unavailable on this OS");
215 }
216 }
217
218 if let Some(capture_manager) = CaptureManager::shared() {
219 println!(
220 "capture supported for developer tools={} active={}",
221 capture_manager.supports_destination(capture_destination::DEVELOPER_TOOLS),
222 capture_manager.is_capturing(),
223 );
224 if let Some(scope) = capture_manager.new_capture_scope_with_device(&device) {
225 scope.begin();
226 scope.end();
227 }
228 if let Some(scope) = capture_manager.new_capture_scope_with_command_queue(&queue) {
229 scope.begin();
230 scope.end();
231 }
232 }
233}Sourcepub fn set_acceleration_structure(
&mut self,
acceleration_structure: &AccelerationStructure,
index: usize,
) -> Result<(), CommandBufferError>
pub fn set_acceleration_structure( &mut self, acceleration_structure: &AccelerationStructure, index: usize, ) -> Result<(), CommandBufferError>
Bind an acceleration structure at index.
Examples found in repository?
examples/07_advanced_objects.rs (line 166)
11fn main() {
12 let device = MetalDevice::system_default().expect("Metal device available");
13 let queue = device.new_command_queue().expect("command queue");
14 let counter_sets = device.counter_set_names();
15 println!("counter sets: {counter_sets:?}");
16
17 if let Some(event) = device.new_shared_event() {
18 event.set_signaled_value(1);
19 println!("event signaled value={}", event.signaled_value());
20 let signal = queue
21 .new_command_buffer()
22 .expect("event signal command buffer");
23 signal
24 .encode_signal_event(&event, 2)
25 .expect("encode event signal");
26 signal.commit().expect("commit event signal");
27 signal
28 .wait_until_completed()
29 .expect("complete event signal");
30 println!(
31 "event reached value 2: {}",
32 event.wait_until_signaled_value(2, 1_000),
33 );
34
35 let wait = queue
36 .new_command_buffer()
37 .expect("event wait command buffer");
38 wait.encode_wait_for_event(&event, 2)
39 .expect("encode event wait");
40 wait.commit().expect("commit event wait");
41 wait.wait_until_completed().expect("complete event wait");
42 }
43
44 let fence_a = device.new_fence();
45 let fence_b = device.new_fence();
46 let sample_buffer = counter_sets.first().and_then(|name| {
47 if device.supports_counter_sampling(counter_sampling_point::AT_BLIT_BOUNDARY) {
48 device
49 .new_counter_sample_buffer(name, 2, storage_mode::SHARED, Some("example-samples"))
50 .ok()
51 } else {
52 None
53 }
54 });
55
56 let src = device
57 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
58 .expect("source buffer");
59 let dst = device
60 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
61 .expect("destination buffer");
62 let blit = queue.new_command_buffer().expect("blit command buffer");
63 let mut encoder = blit.new_blit_command_encoder().expect("blit encoder");
64 encoder
65 .fill_buffer(&src, 0..64, b'Q')
66 .expect("fill source buffer");
67 if let Some(fence) = fence_a.as_ref() {
68 encoder.update_fence(fence).expect("update fence");
69 }
70 encoder.end_encoding().expect("end first blit encoder");
71 blit.commit().expect("commit first blit");
72 blit.wait_until_completed().expect("complete first blit");
73
74 let blit = queue
75 .new_command_buffer()
76 .expect("second blit command buffer");
77 let mut encoder = blit
78 .new_blit_command_encoder()
79 .expect("second blit encoder");
80 if let Some(fence) = fence_a.as_ref() {
81 encoder.wait_for_fence(fence).expect("wait for fence");
82 }
83 if let Some(sample_buffer) = sample_buffer.as_ref() {
84 encoder
85 .sample_counters(sample_buffer, 0, false)
86 .expect("sample counters");
87 }
88 encoder
89 .copy_buffer(&src, 0, &dst, 0, 64)
90 .expect("copy buffers");
91 encoder.end_encoding().expect("end second blit encoder");
92 blit.commit().expect("commit second blit");
93 blit.wait_until_completed().expect("complete second blit");
94 if let Some(sample_buffer) = sample_buffer.as_ref() {
95 println!(
96 "resolved counter bytes={}",
97 sample_buffer
98 .resolve_range(0..1)
99 .map_or(0, |bytes| bytes.len())
100 );
101 }
102
103 let library = device
104 .new_library_with_source(common::COMPUTE_SRC)
105 .expect("compile compute library");
106 let increment = library
107 .new_function("increment")
108 .expect("increment function");
109 let pipeline = device
110 .new_compute_pipeline_state(&increment)
111 .expect("compute pipeline");
112 let visible_table = pipeline.new_visible_function_table(1);
113 let intersection_table = if device.supports_raytracing() {
114 pipeline.new_intersection_function_table(1)
115 } else {
116 None
117 };
118 if let Some(table) = intersection_table.as_ref() {
119 table.set_opaque_triangle_intersection_function(intersection_function_signature::NONE, 0);
120 }
121 let acceleration_structure = if device.supports_raytracing() {
122 device.new_acceleration_structure_with_size(256)
123 } else {
124 None
125 };
126
127 let buffer = device
128 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
129 .expect("compute buffer");
130 common::write_u32_words(&buffer, &[1, 2, 3, 4]);
131 let texture = device
132 .new_texture(apple_metal::TextureDescriptor::new_2d(
133 4,
134 4,
135 apple_metal::pixel_format::BGRA8UNORM,
136 ))
137 .expect("compute texture");
138 let compute = queue.new_command_buffer().expect("compute command buffer");
139 let mut encoder = compute
140 .new_compute_command_encoder()
141 .expect("compute command encoder");
142 encoder
143 .set_compute_pipeline_state(&pipeline)
144 .expect("bind compute pipeline");
145 encoder
146 .set_buffer(&buffer, 0, 0)
147 .expect("bind compute buffer");
148 encoder
149 .set_texture(&texture, 1)
150 .expect("bind compute texture");
151 if let Some(fence) = fence_a.as_ref() {
152 encoder.wait_for_fence(fence).expect("wait for fence");
153 }
154 if let Some(table) = visible_table.as_ref() {
155 encoder
156 .set_visible_function_table(table, 2)
157 .expect("bind visible function table");
158 }
159 if let Some(table) = intersection_table.as_ref() {
160 encoder
161 .set_intersection_function_table(table, 3)
162 .expect("bind intersection function table");
163 }
164 if let Some(acceleration_structure) = acceleration_structure.as_ref() {
165 encoder
166 .set_acceleration_structure(acceleration_structure, 4)
167 .expect("bind acceleration structure");
168 }
169 encoder
170 .dispatch_threadgroups((1, 1, 1), (4, 1, 1))
171 .expect("dispatch compute");
172 if let Some(fence) = fence_b.as_ref() {
173 encoder.update_fence(fence).expect("update fence");
174 }
175 encoder.end_encoding().expect("end compute encoder");
176 compute.commit().expect("commit compute");
177 compute.wait_until_completed().expect("complete compute");
178 println!(
179 "compute buffer after dispatch: {:?}",
180 common::read_u32_words(&buffer, 4)
181 );
182
183 if let Some(indirect) = device.new_indirect_command_buffer(
184 indirect_command_type::CONCURRENT_DISPATCH,
185 1,
186 0,
187 0,
188 4,
189 resource_options::STORAGE_MODE_PRIVATE,
190 ) {
191 indirect.reset_range(0..1);
192 println!("indirect command buffer size={}", indirect.size());
193 }
194
195 if let Some(heap) = device.new_heap(1 << 20, storage_mode::SHARED) {
196 if let Ok(residency_set) = device.new_residency_set(Some("example-residency"), 4) {
197 let heap_buffer = heap
198 .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
199 .expect("heap buffer");
200 residency_set.add_buffer(&heap_buffer);
201 residency_set.add_heap(&heap);
202 residency_set.commit();
203 residency_set.request_residency();
204 queue.add_residency_set(&residency_set);
205 queue.remove_residency_set(&residency_set);
206 residency_set.end_residency();
207 residency_set.remove_all_allocations();
208 residency_set.commit();
209 println!(
210 "residency allocation count={}",
211 residency_set.allocation_count()
212 );
213 } else {
214 println!("residency sets unavailable on this OS");
215 }
216 }
217
218 if let Some(capture_manager) = CaptureManager::shared() {
219 println!(
220 "capture supported for developer tools={} active={}",
221 capture_manager.supports_destination(capture_destination::DEVELOPER_TOOLS),
222 capture_manager.is_capturing(),
223 );
224 if let Some(scope) = capture_manager.new_capture_scope_with_device(&device) {
225 scope.begin();
226 scope.end();
227 }
228 if let Some(scope) = capture_manager.new_capture_scope_with_command_queue(&queue) {
229 scope.begin();
230 scope.end();
231 }
232 }
233}Sourcepub fn dispatch_threadgroups(
&mut self,
threadgroups: (usize, usize, usize),
threads_per_threadgroup: (usize, usize, usize),
) -> Result<(), CommandBufferError>
pub fn dispatch_threadgroups( &mut self, threadgroups: (usize, usize, usize), threads_per_threadgroup: (usize, usize, usize), ) -> Result<(), CommandBufferError>
Dispatch threadgroups of fixed size.
Examples found in repository?
examples/07_advanced_objects.rs (line 170)
11fn main() {
12 let device = MetalDevice::system_default().expect("Metal device available");
13 let queue = device.new_command_queue().expect("command queue");
14 let counter_sets = device.counter_set_names();
15 println!("counter sets: {counter_sets:?}");
16
17 if let Some(event) = device.new_shared_event() {
18 event.set_signaled_value(1);
19 println!("event signaled value={}", event.signaled_value());
20 let signal = queue
21 .new_command_buffer()
22 .expect("event signal command buffer");
23 signal
24 .encode_signal_event(&event, 2)
25 .expect("encode event signal");
26 signal.commit().expect("commit event signal");
27 signal
28 .wait_until_completed()
29 .expect("complete event signal");
30 println!(
31 "event reached value 2: {}",
32 event.wait_until_signaled_value(2, 1_000),
33 );
34
35 let wait = queue
36 .new_command_buffer()
37 .expect("event wait command buffer");
38 wait.encode_wait_for_event(&event, 2)
39 .expect("encode event wait");
40 wait.commit().expect("commit event wait");
41 wait.wait_until_completed().expect("complete event wait");
42 }
43
44 let fence_a = device.new_fence();
45 let fence_b = device.new_fence();
46 let sample_buffer = counter_sets.first().and_then(|name| {
47 if device.supports_counter_sampling(counter_sampling_point::AT_BLIT_BOUNDARY) {
48 device
49 .new_counter_sample_buffer(name, 2, storage_mode::SHARED, Some("example-samples"))
50 .ok()
51 } else {
52 None
53 }
54 });
55
56 let src = device
57 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
58 .expect("source buffer");
59 let dst = device
60 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
61 .expect("destination buffer");
62 let blit = queue.new_command_buffer().expect("blit command buffer");
63 let mut encoder = blit.new_blit_command_encoder().expect("blit encoder");
64 encoder
65 .fill_buffer(&src, 0..64, b'Q')
66 .expect("fill source buffer");
67 if let Some(fence) = fence_a.as_ref() {
68 encoder.update_fence(fence).expect("update fence");
69 }
70 encoder.end_encoding().expect("end first blit encoder");
71 blit.commit().expect("commit first blit");
72 blit.wait_until_completed().expect("complete first blit");
73
74 let blit = queue
75 .new_command_buffer()
76 .expect("second blit command buffer");
77 let mut encoder = blit
78 .new_blit_command_encoder()
79 .expect("second blit encoder");
80 if let Some(fence) = fence_a.as_ref() {
81 encoder.wait_for_fence(fence).expect("wait for fence");
82 }
83 if let Some(sample_buffer) = sample_buffer.as_ref() {
84 encoder
85 .sample_counters(sample_buffer, 0, false)
86 .expect("sample counters");
87 }
88 encoder
89 .copy_buffer(&src, 0, &dst, 0, 64)
90 .expect("copy buffers");
91 encoder.end_encoding().expect("end second blit encoder");
92 blit.commit().expect("commit second blit");
93 blit.wait_until_completed().expect("complete second blit");
94 if let Some(sample_buffer) = sample_buffer.as_ref() {
95 println!(
96 "resolved counter bytes={}",
97 sample_buffer
98 .resolve_range(0..1)
99 .map_or(0, |bytes| bytes.len())
100 );
101 }
102
103 let library = device
104 .new_library_with_source(common::COMPUTE_SRC)
105 .expect("compile compute library");
106 let increment = library
107 .new_function("increment")
108 .expect("increment function");
109 let pipeline = device
110 .new_compute_pipeline_state(&increment)
111 .expect("compute pipeline");
112 let visible_table = pipeline.new_visible_function_table(1);
113 let intersection_table = if device.supports_raytracing() {
114 pipeline.new_intersection_function_table(1)
115 } else {
116 None
117 };
118 if let Some(table) = intersection_table.as_ref() {
119 table.set_opaque_triangle_intersection_function(intersection_function_signature::NONE, 0);
120 }
121 let acceleration_structure = if device.supports_raytracing() {
122 device.new_acceleration_structure_with_size(256)
123 } else {
124 None
125 };
126
127 let buffer = device
128 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
129 .expect("compute buffer");
130 common::write_u32_words(&buffer, &[1, 2, 3, 4]);
131 let texture = device
132 .new_texture(apple_metal::TextureDescriptor::new_2d(
133 4,
134 4,
135 apple_metal::pixel_format::BGRA8UNORM,
136 ))
137 .expect("compute texture");
138 let compute = queue.new_command_buffer().expect("compute command buffer");
139 let mut encoder = compute
140 .new_compute_command_encoder()
141 .expect("compute command encoder");
142 encoder
143 .set_compute_pipeline_state(&pipeline)
144 .expect("bind compute pipeline");
145 encoder
146 .set_buffer(&buffer, 0, 0)
147 .expect("bind compute buffer");
148 encoder
149 .set_texture(&texture, 1)
150 .expect("bind compute texture");
151 if let Some(fence) = fence_a.as_ref() {
152 encoder.wait_for_fence(fence).expect("wait for fence");
153 }
154 if let Some(table) = visible_table.as_ref() {
155 encoder
156 .set_visible_function_table(table, 2)
157 .expect("bind visible function table");
158 }
159 if let Some(table) = intersection_table.as_ref() {
160 encoder
161 .set_intersection_function_table(table, 3)
162 .expect("bind intersection function table");
163 }
164 if let Some(acceleration_structure) = acceleration_structure.as_ref() {
165 encoder
166 .set_acceleration_structure(acceleration_structure, 4)
167 .expect("bind acceleration structure");
168 }
169 encoder
170 .dispatch_threadgroups((1, 1, 1), (4, 1, 1))
171 .expect("dispatch compute");
172 if let Some(fence) = fence_b.as_ref() {
173 encoder.update_fence(fence).expect("update fence");
174 }
175 encoder.end_encoding().expect("end compute encoder");
176 compute.commit().expect("commit compute");
177 compute.wait_until_completed().expect("complete compute");
178 println!(
179 "compute buffer after dispatch: {:?}",
180 common::read_u32_words(&buffer, 4)
181 );
182
183 if let Some(indirect) = device.new_indirect_command_buffer(
184 indirect_command_type::CONCURRENT_DISPATCH,
185 1,
186 0,
187 0,
188 4,
189 resource_options::STORAGE_MODE_PRIVATE,
190 ) {
191 indirect.reset_range(0..1);
192 println!("indirect command buffer size={}", indirect.size());
193 }
194
195 if let Some(heap) = device.new_heap(1 << 20, storage_mode::SHARED) {
196 if let Ok(residency_set) = device.new_residency_set(Some("example-residency"), 4) {
197 let heap_buffer = heap
198 .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
199 .expect("heap buffer");
200 residency_set.add_buffer(&heap_buffer);
201 residency_set.add_heap(&heap);
202 residency_set.commit();
203 residency_set.request_residency();
204 queue.add_residency_set(&residency_set);
205 queue.remove_residency_set(&residency_set);
206 residency_set.end_residency();
207 residency_set.remove_all_allocations();
208 residency_set.commit();
209 println!(
210 "residency allocation count={}",
211 residency_set.allocation_count()
212 );
213 } else {
214 println!("residency sets unavailable on this OS");
215 }
216 }
217
218 if let Some(capture_manager) = CaptureManager::shared() {
219 println!(
220 "capture supported for developer tools={} active={}",
221 capture_manager.supports_destination(capture_destination::DEVELOPER_TOOLS),
222 capture_manager.is_capturing(),
223 );
224 if let Some(scope) = capture_manager.new_capture_scope_with_device(&device) {
225 scope.begin();
226 scope.end();
227 }
228 if let Some(scope) = capture_manager.new_capture_scope_with_command_queue(&queue) {
229 scope.begin();
230 scope.end();
231 }
232 }
233}Sourcepub fn dispatch_threads(
&mut self,
threads: (usize, usize, usize),
threads_per_threadgroup: (usize, usize, usize),
) -> Result<(), CommandBufferError>
pub fn dispatch_threads( &mut self, threads: (usize, usize, usize), threads_per_threadgroup: (usize, usize, usize), ) -> Result<(), CommandBufferError>
Dispatch an arbitrary thread grid.
Examples found in repository?
examples/05_render_and_explicit_encoders.rs (line 76)
11fn main() {
12 let device = MetalDevice::system_default().expect("Metal device available");
13 println!(
14 "device: {} (registry id {})",
15 device.name(),
16 device.registry_id()
17 );
18
19 let queue = device.new_command_queue().expect("command queue");
20 let status_buffer = unsafe {
21 queue
22 .new_command_buffer_with_unretained_references()
23 .expect("scratch command buffer")
24 };
25 println!("scratch command buffer status={}", status_buffer.status());
26
27 let src = device
28 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
29 .expect("source buffer");
30 let dst = device
31 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
32 .expect("destination buffer");
33 let blit_cb = queue.new_command_buffer().expect("blit command buffer");
34 let mut blit = blit_cb
35 .new_blit_command_encoder()
36 .expect("blit command encoder");
37 blit.fill_buffer(&src, 0..64, b'Z').expect("fill source");
38 blit.copy_buffer(&src, 0, &dst, 0, 64)
39 .expect("copy buffers");
40 blit.end_encoding().expect("end blit encoder");
41 blit_cb.commit().expect("commit blit");
42 blit_cb.wait_until_completed().expect("complete blit");
43 let copied = {
44 let mapping = unsafe { dst.map_read().expect("map destination") };
45 let copied = mapping[..8].to_vec();
46 drop(mapping);
47 copied
48 };
49 println!("blit copied bytes: {copied:?}");
50
51 let library = device
52 .new_library_with_source(common::COMPUTE_SRC)
53 .expect("compile compute library");
54 let increment = library
55 .new_function("increment")
56 .expect("increment function");
57 let pipeline = device
58 .new_compute_pipeline_state(&increment)
59 .expect("compute pipeline");
60
61 let buffer = device
62 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
63 .expect("compute buffer");
64 common::write_u32_words(&buffer, &[10, 20, 30, 40]);
65 let compute_cb = queue.new_command_buffer().expect("compute command buffer");
66 let mut compute = compute_cb
67 .new_compute_command_encoder()
68 .expect("compute command encoder");
69 compute
70 .set_compute_pipeline_state(&pipeline)
71 .expect("bind compute pipeline");
72 compute
73 .set_buffer(&buffer, 0, 0)
74 .expect("bind compute buffer");
75 compute
76 .dispatch_threads((4, 1, 1), (1, 1, 1))
77 .expect("dispatch compute");
78 compute.end_encoding().expect("end compute encoder");
79 compute_cb.commit().expect("commit compute");
80 compute_cb.wait_until_completed().expect("complete compute");
81 println!("compute output: {:?}", common::read_u32_words(&buffer, 4));
82
83 let render_library = device
84 .new_library_with_source(common::RENDER_SRC)
85 .expect("compile render library");
86 let vertex = render_library
87 .new_function("fullscreen_vertex")
88 .expect("vertex function");
89 let fragment = render_library
90 .new_function("solid_fragment")
91 .expect("fragment function");
92 let render_pipeline = device
93 .new_render_pipeline_state(&vertex, &fragment, pixel_format::BGRA8UNORM, 1)
94 .expect("render pipeline");
95 println!("render pipeline label: {:?}", render_pipeline.label());
96
97 let render_target = device
98 .new_texture(common::shared_render_target(4, 4))
99 .expect("render target");
100 let vertex_buffer = device
101 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
102 .expect("vertex buffer");
103 let render_cb = queue.new_command_buffer().expect("render command buffer");
104 let mut render = render_cb
105 .new_render_command_encoder(
106 &render_target,
107 load_action::CLEAR,
108 store_action::STORE,
109 [0.0, 0.0, 0.0, 1.0],
110 )
111 .expect("render command encoder");
112 render
113 .set_render_pipeline_state(&render_pipeline)
114 .expect("bind render pipeline");
115 render
116 .set_vertex_buffer(&vertex_buffer, 0, 0)
117 .expect("bind vertex buffer");
118 render
119 .draw_primitives(primitive_type::TRIANGLE, 0, 3)
120 .expect("draw triangle");
121 render.end_encoding().expect("end render encoder");
122 render_cb.commit().expect("commit render");
123 render_cb.wait_until_completed().expect("complete render");
124
125 let mut rendered = vec![0_u8; 4 * 4 * 4];
126 unsafe {
127 render_target
128 .read_bytes_2d(&mut rendered, 16, (0, 0), (4, 4), 0)
129 .expect("read render target");
130 }
131 println!("first rendered pixel: {:?}", &rendered[..4]);
132
133 let shared_texture = device
134 .new_texture(TextureDescriptor::new_2d(4, 4, pixel_format::BGRA8UNORM))
135 .expect("shared texture");
136 let upload = vec![0x22_u8; 4 * 4 * 4];
137 unsafe {
138 shared_texture
139 .replace_region_2d(&upload, 16, (0, 0), (4, 4), 0)
140 .expect("upload texture");
141 }
142 let mut download = vec![0_u8; upload.len()];
143 unsafe {
144 shared_texture
145 .read_bytes_2d(&mut download, 16, (0, 0), (4, 4), 0)
146 .expect("read texture");
147 }
148 let view = shared_texture
149 .new_view(pixel_format::BGRA8UNORM)
150 .expect("texture view");
151 println!(
152 "texture {}x{} usage={} storage_mode={} view_width={}",
153 shared_texture.width(),
154 shared_texture.height(),
155 shared_texture.usage(),
156 shared_texture.storage_mode(),
157 view.width(),
158 );
159}Sourcepub fn update_fence(&mut self, fence: &Fence) -> Result<(), CommandBufferError>
pub fn update_fence(&mut self, fence: &Fence) -> Result<(), CommandBufferError>
Update fence with work encoded so far.
Examples found in repository?
examples/07_advanced_objects.rs (line 173)
11fn main() {
12 let device = MetalDevice::system_default().expect("Metal device available");
13 let queue = device.new_command_queue().expect("command queue");
14 let counter_sets = device.counter_set_names();
15 println!("counter sets: {counter_sets:?}");
16
17 if let Some(event) = device.new_shared_event() {
18 event.set_signaled_value(1);
19 println!("event signaled value={}", event.signaled_value());
20 let signal = queue
21 .new_command_buffer()
22 .expect("event signal command buffer");
23 signal
24 .encode_signal_event(&event, 2)
25 .expect("encode event signal");
26 signal.commit().expect("commit event signal");
27 signal
28 .wait_until_completed()
29 .expect("complete event signal");
30 println!(
31 "event reached value 2: {}",
32 event.wait_until_signaled_value(2, 1_000),
33 );
34
35 let wait = queue
36 .new_command_buffer()
37 .expect("event wait command buffer");
38 wait.encode_wait_for_event(&event, 2)
39 .expect("encode event wait");
40 wait.commit().expect("commit event wait");
41 wait.wait_until_completed().expect("complete event wait");
42 }
43
44 let fence_a = device.new_fence();
45 let fence_b = device.new_fence();
46 let sample_buffer = counter_sets.first().and_then(|name| {
47 if device.supports_counter_sampling(counter_sampling_point::AT_BLIT_BOUNDARY) {
48 device
49 .new_counter_sample_buffer(name, 2, storage_mode::SHARED, Some("example-samples"))
50 .ok()
51 } else {
52 None
53 }
54 });
55
56 let src = device
57 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
58 .expect("source buffer");
59 let dst = device
60 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
61 .expect("destination buffer");
62 let blit = queue.new_command_buffer().expect("blit command buffer");
63 let mut encoder = blit.new_blit_command_encoder().expect("blit encoder");
64 encoder
65 .fill_buffer(&src, 0..64, b'Q')
66 .expect("fill source buffer");
67 if let Some(fence) = fence_a.as_ref() {
68 encoder.update_fence(fence).expect("update fence");
69 }
70 encoder.end_encoding().expect("end first blit encoder");
71 blit.commit().expect("commit first blit");
72 blit.wait_until_completed().expect("complete first blit");
73
74 let blit = queue
75 .new_command_buffer()
76 .expect("second blit command buffer");
77 let mut encoder = blit
78 .new_blit_command_encoder()
79 .expect("second blit encoder");
80 if let Some(fence) = fence_a.as_ref() {
81 encoder.wait_for_fence(fence).expect("wait for fence");
82 }
83 if let Some(sample_buffer) = sample_buffer.as_ref() {
84 encoder
85 .sample_counters(sample_buffer, 0, false)
86 .expect("sample counters");
87 }
88 encoder
89 .copy_buffer(&src, 0, &dst, 0, 64)
90 .expect("copy buffers");
91 encoder.end_encoding().expect("end second blit encoder");
92 blit.commit().expect("commit second blit");
93 blit.wait_until_completed().expect("complete second blit");
94 if let Some(sample_buffer) = sample_buffer.as_ref() {
95 println!(
96 "resolved counter bytes={}",
97 sample_buffer
98 .resolve_range(0..1)
99 .map_or(0, |bytes| bytes.len())
100 );
101 }
102
103 let library = device
104 .new_library_with_source(common::COMPUTE_SRC)
105 .expect("compile compute library");
106 let increment = library
107 .new_function("increment")
108 .expect("increment function");
109 let pipeline = device
110 .new_compute_pipeline_state(&increment)
111 .expect("compute pipeline");
112 let visible_table = pipeline.new_visible_function_table(1);
113 let intersection_table = if device.supports_raytracing() {
114 pipeline.new_intersection_function_table(1)
115 } else {
116 None
117 };
118 if let Some(table) = intersection_table.as_ref() {
119 table.set_opaque_triangle_intersection_function(intersection_function_signature::NONE, 0);
120 }
121 let acceleration_structure = if device.supports_raytracing() {
122 device.new_acceleration_structure_with_size(256)
123 } else {
124 None
125 };
126
127 let buffer = device
128 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
129 .expect("compute buffer");
130 common::write_u32_words(&buffer, &[1, 2, 3, 4]);
131 let texture = device
132 .new_texture(apple_metal::TextureDescriptor::new_2d(
133 4,
134 4,
135 apple_metal::pixel_format::BGRA8UNORM,
136 ))
137 .expect("compute texture");
138 let compute = queue.new_command_buffer().expect("compute command buffer");
139 let mut encoder = compute
140 .new_compute_command_encoder()
141 .expect("compute command encoder");
142 encoder
143 .set_compute_pipeline_state(&pipeline)
144 .expect("bind compute pipeline");
145 encoder
146 .set_buffer(&buffer, 0, 0)
147 .expect("bind compute buffer");
148 encoder
149 .set_texture(&texture, 1)
150 .expect("bind compute texture");
151 if let Some(fence) = fence_a.as_ref() {
152 encoder.wait_for_fence(fence).expect("wait for fence");
153 }
154 if let Some(table) = visible_table.as_ref() {
155 encoder
156 .set_visible_function_table(table, 2)
157 .expect("bind visible function table");
158 }
159 if let Some(table) = intersection_table.as_ref() {
160 encoder
161 .set_intersection_function_table(table, 3)
162 .expect("bind intersection function table");
163 }
164 if let Some(acceleration_structure) = acceleration_structure.as_ref() {
165 encoder
166 .set_acceleration_structure(acceleration_structure, 4)
167 .expect("bind acceleration structure");
168 }
169 encoder
170 .dispatch_threadgroups((1, 1, 1), (4, 1, 1))
171 .expect("dispatch compute");
172 if let Some(fence) = fence_b.as_ref() {
173 encoder.update_fence(fence).expect("update fence");
174 }
175 encoder.end_encoding().expect("end compute encoder");
176 compute.commit().expect("commit compute");
177 compute.wait_until_completed().expect("complete compute");
178 println!(
179 "compute buffer after dispatch: {:?}",
180 common::read_u32_words(&buffer, 4)
181 );
182
183 if let Some(indirect) = device.new_indirect_command_buffer(
184 indirect_command_type::CONCURRENT_DISPATCH,
185 1,
186 0,
187 0,
188 4,
189 resource_options::STORAGE_MODE_PRIVATE,
190 ) {
191 indirect.reset_range(0..1);
192 println!("indirect command buffer size={}", indirect.size());
193 }
194
195 if let Some(heap) = device.new_heap(1 << 20, storage_mode::SHARED) {
196 if let Ok(residency_set) = device.new_residency_set(Some("example-residency"), 4) {
197 let heap_buffer = heap
198 .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
199 .expect("heap buffer");
200 residency_set.add_buffer(&heap_buffer);
201 residency_set.add_heap(&heap);
202 residency_set.commit();
203 residency_set.request_residency();
204 queue.add_residency_set(&residency_set);
205 queue.remove_residency_set(&residency_set);
206 residency_set.end_residency();
207 residency_set.remove_all_allocations();
208 residency_set.commit();
209 println!(
210 "residency allocation count={}",
211 residency_set.allocation_count()
212 );
213 } else {
214 println!("residency sets unavailable on this OS");
215 }
216 }
217
218 if let Some(capture_manager) = CaptureManager::shared() {
219 println!(
220 "capture supported for developer tools={} active={}",
221 capture_manager.supports_destination(capture_destination::DEVELOPER_TOOLS),
222 capture_manager.is_capturing(),
223 );
224 if let Some(scope) = capture_manager.new_capture_scope_with_device(&device) {
225 scope.begin();
226 scope.end();
227 }
228 if let Some(scope) = capture_manager.new_capture_scope_with_command_queue(&queue) {
229 scope.begin();
230 scope.end();
231 }
232 }
233}Sourcepub fn wait_for_fence(
&mut self,
fence: &Fence,
) -> Result<(), CommandBufferError>
pub fn wait_for_fence( &mut self, fence: &Fence, ) -> Result<(), CommandBufferError>
Wait for fence before executing subsequent work.
Examples found in repository?
examples/07_advanced_objects.rs (line 152)
11fn main() {
12 let device = MetalDevice::system_default().expect("Metal device available");
13 let queue = device.new_command_queue().expect("command queue");
14 let counter_sets = device.counter_set_names();
15 println!("counter sets: {counter_sets:?}");
16
17 if let Some(event) = device.new_shared_event() {
18 event.set_signaled_value(1);
19 println!("event signaled value={}", event.signaled_value());
20 let signal = queue
21 .new_command_buffer()
22 .expect("event signal command buffer");
23 signal
24 .encode_signal_event(&event, 2)
25 .expect("encode event signal");
26 signal.commit().expect("commit event signal");
27 signal
28 .wait_until_completed()
29 .expect("complete event signal");
30 println!(
31 "event reached value 2: {}",
32 event.wait_until_signaled_value(2, 1_000),
33 );
34
35 let wait = queue
36 .new_command_buffer()
37 .expect("event wait command buffer");
38 wait.encode_wait_for_event(&event, 2)
39 .expect("encode event wait");
40 wait.commit().expect("commit event wait");
41 wait.wait_until_completed().expect("complete event wait");
42 }
43
44 let fence_a = device.new_fence();
45 let fence_b = device.new_fence();
46 let sample_buffer = counter_sets.first().and_then(|name| {
47 if device.supports_counter_sampling(counter_sampling_point::AT_BLIT_BOUNDARY) {
48 device
49 .new_counter_sample_buffer(name, 2, storage_mode::SHARED, Some("example-samples"))
50 .ok()
51 } else {
52 None
53 }
54 });
55
56 let src = device
57 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
58 .expect("source buffer");
59 let dst = device
60 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
61 .expect("destination buffer");
62 let blit = queue.new_command_buffer().expect("blit command buffer");
63 let mut encoder = blit.new_blit_command_encoder().expect("blit encoder");
64 encoder
65 .fill_buffer(&src, 0..64, b'Q')
66 .expect("fill source buffer");
67 if let Some(fence) = fence_a.as_ref() {
68 encoder.update_fence(fence).expect("update fence");
69 }
70 encoder.end_encoding().expect("end first blit encoder");
71 blit.commit().expect("commit first blit");
72 blit.wait_until_completed().expect("complete first blit");
73
74 let blit = queue
75 .new_command_buffer()
76 .expect("second blit command buffer");
77 let mut encoder = blit
78 .new_blit_command_encoder()
79 .expect("second blit encoder");
80 if let Some(fence) = fence_a.as_ref() {
81 encoder.wait_for_fence(fence).expect("wait for fence");
82 }
83 if let Some(sample_buffer) = sample_buffer.as_ref() {
84 encoder
85 .sample_counters(sample_buffer, 0, false)
86 .expect("sample counters");
87 }
88 encoder
89 .copy_buffer(&src, 0, &dst, 0, 64)
90 .expect("copy buffers");
91 encoder.end_encoding().expect("end second blit encoder");
92 blit.commit().expect("commit second blit");
93 blit.wait_until_completed().expect("complete second blit");
94 if let Some(sample_buffer) = sample_buffer.as_ref() {
95 println!(
96 "resolved counter bytes={}",
97 sample_buffer
98 .resolve_range(0..1)
99 .map_or(0, |bytes| bytes.len())
100 );
101 }
102
103 let library = device
104 .new_library_with_source(common::COMPUTE_SRC)
105 .expect("compile compute library");
106 let increment = library
107 .new_function("increment")
108 .expect("increment function");
109 let pipeline = device
110 .new_compute_pipeline_state(&increment)
111 .expect("compute pipeline");
112 let visible_table = pipeline.new_visible_function_table(1);
113 let intersection_table = if device.supports_raytracing() {
114 pipeline.new_intersection_function_table(1)
115 } else {
116 None
117 };
118 if let Some(table) = intersection_table.as_ref() {
119 table.set_opaque_triangle_intersection_function(intersection_function_signature::NONE, 0);
120 }
121 let acceleration_structure = if device.supports_raytracing() {
122 device.new_acceleration_structure_with_size(256)
123 } else {
124 None
125 };
126
127 let buffer = device
128 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
129 .expect("compute buffer");
130 common::write_u32_words(&buffer, &[1, 2, 3, 4]);
131 let texture = device
132 .new_texture(apple_metal::TextureDescriptor::new_2d(
133 4,
134 4,
135 apple_metal::pixel_format::BGRA8UNORM,
136 ))
137 .expect("compute texture");
138 let compute = queue.new_command_buffer().expect("compute command buffer");
139 let mut encoder = compute
140 .new_compute_command_encoder()
141 .expect("compute command encoder");
142 encoder
143 .set_compute_pipeline_state(&pipeline)
144 .expect("bind compute pipeline");
145 encoder
146 .set_buffer(&buffer, 0, 0)
147 .expect("bind compute buffer");
148 encoder
149 .set_texture(&texture, 1)
150 .expect("bind compute texture");
151 if let Some(fence) = fence_a.as_ref() {
152 encoder.wait_for_fence(fence).expect("wait for fence");
153 }
154 if let Some(table) = visible_table.as_ref() {
155 encoder
156 .set_visible_function_table(table, 2)
157 .expect("bind visible function table");
158 }
159 if let Some(table) = intersection_table.as_ref() {
160 encoder
161 .set_intersection_function_table(table, 3)
162 .expect("bind intersection function table");
163 }
164 if let Some(acceleration_structure) = acceleration_structure.as_ref() {
165 encoder
166 .set_acceleration_structure(acceleration_structure, 4)
167 .expect("bind acceleration structure");
168 }
169 encoder
170 .dispatch_threadgroups((1, 1, 1), (4, 1, 1))
171 .expect("dispatch compute");
172 if let Some(fence) = fence_b.as_ref() {
173 encoder.update_fence(fence).expect("update fence");
174 }
175 encoder.end_encoding().expect("end compute encoder");
176 compute.commit().expect("commit compute");
177 compute.wait_until_completed().expect("complete compute");
178 println!(
179 "compute buffer after dispatch: {:?}",
180 common::read_u32_words(&buffer, 4)
181 );
182
183 if let Some(indirect) = device.new_indirect_command_buffer(
184 indirect_command_type::CONCURRENT_DISPATCH,
185 1,
186 0,
187 0,
188 4,
189 resource_options::STORAGE_MODE_PRIVATE,
190 ) {
191 indirect.reset_range(0..1);
192 println!("indirect command buffer size={}", indirect.size());
193 }
194
195 if let Some(heap) = device.new_heap(1 << 20, storage_mode::SHARED) {
196 if let Ok(residency_set) = device.new_residency_set(Some("example-residency"), 4) {
197 let heap_buffer = heap
198 .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
199 .expect("heap buffer");
200 residency_set.add_buffer(&heap_buffer);
201 residency_set.add_heap(&heap);
202 residency_set.commit();
203 residency_set.request_residency();
204 queue.add_residency_set(&residency_set);
205 queue.remove_residency_set(&residency_set);
206 residency_set.end_residency();
207 residency_set.remove_all_allocations();
208 residency_set.commit();
209 println!(
210 "residency allocation count={}",
211 residency_set.allocation_count()
212 );
213 } else {
214 println!("residency sets unavailable on this OS");
215 }
216 }
217
218 if let Some(capture_manager) = CaptureManager::shared() {
219 println!(
220 "capture supported for developer tools={} active={}",
221 capture_manager.supports_destination(capture_destination::DEVELOPER_TOOLS),
222 capture_manager.is_capturing(),
223 );
224 if let Some(scope) = capture_manager.new_capture_scope_with_device(&device) {
225 scope.begin();
226 scope.end();
227 }
228 if let Some(scope) = capture_manager.new_capture_scope_with_command_queue(&queue) {
229 scope.begin();
230 scope.end();
231 }
232 }
233}Auto Trait Implementations§
impl !Send for ComputeCommandEncoder
impl !Sync for ComputeCommandEncoder
impl Freeze for ComputeCommandEncoder
impl RefUnwindSafe for ComputeCommandEncoder
impl Unpin for ComputeCommandEncoder
impl UnsafeUnpin for ComputeCommandEncoder
impl UnwindSafe for ComputeCommandEncoder
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more