pub struct CaptureManager { /* private fields */ }Expand description
Re-exports the Metal framework surface for this item.
Apple’s MTLCaptureManager singleton.
Mirrors the Metal framework counterpart for this type.
Implementations§
Source§impl CaptureManager
impl CaptureManager
Retrieve the process-global capture manager.
Examples found in repository?
examples/07_advanced_objects.rs (line 218)
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 supports_destination(&self, destination: usize) -> bool
pub fn supports_destination(&self, destination: usize) -> bool
Query whether the given capture destination is supported.
Examples found in repository?
examples/07_advanced_objects.rs (line 221)
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 is_capturing(&self) -> bool
pub fn is_capturing(&self) -> bool
Whether a capture is currently in progress.
Examples found in repository?
examples/07_advanced_objects.rs (line 222)
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 new_capture_scope_with_device(
&self,
device: &MetalDevice,
) -> Option<CaptureScope>
pub fn new_capture_scope_with_device( &self, device: &MetalDevice, ) -> Option<CaptureScope>
Create a capture scope that captures all command queues on device.
Examples found in repository?
examples/07_advanced_objects.rs (line 224)
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 new_capture_scope_with_command_queue(
&self,
command_queue: &CommandQueue,
) -> Option<CaptureScope>
pub fn new_capture_scope_with_command_queue( &self, command_queue: &CommandQueue, ) -> Option<CaptureScope>
Create a capture scope restricted to command_queue.
Examples found in repository?
examples/07_advanced_objects.rs (line 228)
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}Trait Implementations§
Source§impl Drop for CaptureManager
impl Drop for CaptureManager
impl Send for CaptureManager
impl Sync for CaptureManager
Auto Trait Implementations§
impl Freeze for CaptureManager
impl RefUnwindSafe for CaptureManager
impl Unpin for CaptureManager
impl UnsafeUnpin for CaptureManager
impl UnwindSafe for CaptureManager
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