pub struct BlitCommandEncoder { /* private fields */ }Expand description
Re-exports the Metal framework surface for this item.
Apple’s id<MTLBlitCommandEncoder> — encodes buffer and texture copy work.
Mirrors the Metal framework counterpart for this type.
Implementations§
Source§impl BlitCommandEncoder
impl BlitCommandEncoder
Sourcepub fn copy_buffer(
&self,
src: &MetalBuffer,
src_offset: usize,
dst: &MetalBuffer,
dst_offset: usize,
size: usize,
) -> bool
pub fn copy_buffer( &self, src: &MetalBuffer, src_offset: usize, dst: &MetalBuffer, dst_offset: usize, size: usize, ) -> bool
Copy size bytes from src into dst.
Examples found in repository?
examples/05_render_and_explicit_encoders.rs (line 36)
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 = queue
21 .new_command_buffer_with_unretained_references()
22 .expect("scratch command buffer");
23 println!("scratch command buffer status={}", status_buffer.status());
24
25 let src = device
26 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
27 .expect("source buffer");
28 let dst = device
29 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
30 .expect("destination buffer");
31 let blit_cb = queue.new_command_buffer().expect("blit command buffer");
32 let blit = blit_cb
33 .new_blit_command_encoder()
34 .expect("blit command encoder");
35 assert!(blit.fill_buffer(&src, 0..64, b'Z'));
36 assert!(blit.copy_buffer(&src, 0, &dst, 0, 64));
37 blit.end_encoding();
38 blit_cb.commit();
39 blit_cb.wait_until_completed();
40 let copied = unsafe {
41 core::slice::from_raw_parts(dst.contents().expect("dst contents").cast::<u8>(), 8)
42 };
43 println!("blit copied bytes: {copied:?}");
44
45 let library = device
46 .new_library_with_source(common::COMPUTE_SRC)
47 .expect("compile compute library");
48 let increment = library
49 .new_function("increment")
50 .expect("increment function");
51 let pipeline = device
52 .new_compute_pipeline_state(&increment)
53 .expect("compute pipeline");
54
55 let buffer = device
56 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
57 .expect("compute buffer");
58 common::write_u32_words(&buffer, &[10, 20, 30, 40]);
59 let compute_cb = queue.new_command_buffer().expect("compute command buffer");
60 let compute = compute_cb
61 .new_compute_command_encoder()
62 .expect("compute command encoder");
63 compute.set_compute_pipeline_state(&pipeline);
64 compute.set_buffer(&buffer, 0, 0);
65 compute.dispatch_threads((4, 1, 1), (1, 1, 1));
66 compute.end_encoding();
67 compute_cb.commit();
68 compute_cb.wait_until_completed();
69 println!("compute output: {:?}", common::read_u32_words(&buffer, 4));
70
71 let render_library = device
72 .new_library_with_source(common::RENDER_SRC)
73 .expect("compile render library");
74 let vertex = render_library
75 .new_function("fullscreen_vertex")
76 .expect("vertex function");
77 let fragment = render_library
78 .new_function("solid_fragment")
79 .expect("fragment function");
80 let render_pipeline = device
81 .new_render_pipeline_state(&vertex, &fragment, pixel_format::BGRA8UNORM, 1)
82 .expect("render pipeline");
83 println!("render pipeline label: {:?}", render_pipeline.label());
84
85 let render_target = device
86 .new_texture(common::shared_render_target(4, 4))
87 .expect("render target");
88 let vertex_buffer = device
89 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
90 .expect("vertex buffer");
91 let render_cb = queue.new_command_buffer().expect("render command buffer");
92 let render = render_cb
93 .new_render_command_encoder(
94 &render_target,
95 load_action::CLEAR,
96 store_action::STORE,
97 [0.0, 0.0, 0.0, 1.0],
98 )
99 .expect("render command encoder");
100 render.set_render_pipeline_state(&render_pipeline);
101 render.set_vertex_buffer(&vertex_buffer, 0, 0);
102 render.draw_primitives(primitive_type::TRIANGLE, 0, 3);
103 render.end_encoding();
104 render_cb.commit();
105 render_cb.wait_until_completed();
106
107 let mut rendered = vec![0_u8; 4 * 4 * 4];
108 assert!(render_target.read_bytes_2d(&mut rendered, 16, (0, 0), (4, 4), 0));
109 println!("first rendered pixel: {:?}", &rendered[..4]);
110
111 let shared_texture = device
112 .new_texture(TextureDescriptor::new_2d(4, 4, pixel_format::BGRA8UNORM))
113 .expect("shared texture");
114 let upload = vec![0x22_u8; 4 * 4 * 4];
115 assert!(shared_texture.replace_region_2d(&upload, 16, (0, 0), (4, 4), 0));
116 let mut download = vec![0_u8; upload.len()];
117 assert!(shared_texture.read_bytes_2d(&mut download, 16, (0, 0), (4, 4), 0));
118 let view = shared_texture
119 .new_view(pixel_format::BGRA8UNORM)
120 .expect("texture view");
121 println!(
122 "texture {}x{} usage={} storage_mode={} view_width={}",
123 shared_texture.width(),
124 shared_texture.height(),
125 shared_texture.usage(),
126 shared_texture.storage_mode(),
127 view.width(),
128 );
129}More examples
examples/07_advanced_objects.rs (line 79)
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.encode_signal_event(&event, 2);
24 signal.commit();
25 signal.wait_until_completed();
26 println!(
27 "event reached value 2: {}",
28 event.wait_until_signaled_value(2, 1_000),
29 );
30
31 let wait = queue
32 .new_command_buffer()
33 .expect("event wait command buffer");
34 wait.encode_wait_for_event(&event, 2);
35 wait.commit();
36 wait.wait_until_completed();
37 }
38
39 let fence_a = device.new_fence();
40 let fence_b = device.new_fence();
41 let sample_buffer = counter_sets.first().and_then(|name| {
42 if device.supports_counter_sampling(counter_sampling_point::AT_BLIT_BOUNDARY) {
43 device
44 .new_counter_sample_buffer(name, 2, storage_mode::SHARED, Some("example-samples"))
45 .ok()
46 } else {
47 None
48 }
49 });
50
51 let src = device
52 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
53 .expect("source buffer");
54 let dst = device
55 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
56 .expect("destination buffer");
57 let blit = queue.new_command_buffer().expect("blit command buffer");
58 let encoder = blit.new_blit_command_encoder().expect("blit encoder");
59 let _ = encoder.fill_buffer(&src, 0..64, b'Q');
60 if let Some(fence) = fence_a.as_ref() {
61 encoder.update_fence(fence);
62 }
63 encoder.end_encoding();
64 blit.commit();
65 blit.wait_until_completed();
66
67 let blit = queue
68 .new_command_buffer()
69 .expect("second blit command buffer");
70 let encoder = blit
71 .new_blit_command_encoder()
72 .expect("second blit encoder");
73 if let Some(fence) = fence_a.as_ref() {
74 encoder.wait_for_fence(fence);
75 }
76 if let Some(sample_buffer) = sample_buffer.as_ref() {
77 let _ = encoder.sample_counters(sample_buffer, 0, false);
78 }
79 let _ = encoder.copy_buffer(&src, 0, &dst, 0, 64);
80 encoder.end_encoding();
81 blit.commit();
82 blit.wait_until_completed();
83 if let Some(sample_buffer) = sample_buffer.as_ref() {
84 println!(
85 "resolved counter bytes={}",
86 sample_buffer
87 .resolve_range(0..1)
88 .map_or(0, |bytes| bytes.len())
89 );
90 }
91
92 let library = device
93 .new_library_with_source(common::COMPUTE_SRC)
94 .expect("compile compute library");
95 let increment = library
96 .new_function("increment")
97 .expect("increment function");
98 let pipeline = device
99 .new_compute_pipeline_state(&increment)
100 .expect("compute pipeline");
101 let visible_table = pipeline.new_visible_function_table(1);
102 let intersection_table = if device.supports_raytracing() {
103 pipeline.new_intersection_function_table(1)
104 } else {
105 None
106 };
107 if let Some(table) = intersection_table.as_ref() {
108 table.set_opaque_triangle_intersection_function(intersection_function_signature::NONE, 0);
109 }
110 let acceleration_structure = if device.supports_raytracing() {
111 device.new_acceleration_structure_with_size(256)
112 } else {
113 None
114 };
115
116 let buffer = device
117 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
118 .expect("compute buffer");
119 common::write_u32_words(&buffer, &[1, 2, 3, 4]);
120 let texture = device
121 .new_texture(apple_metal::TextureDescriptor::new_2d(
122 4,
123 4,
124 apple_metal::pixel_format::BGRA8UNORM,
125 ))
126 .expect("compute texture");
127 let compute = queue.new_command_buffer().expect("compute command buffer");
128 let encoder = compute
129 .new_compute_command_encoder()
130 .expect("compute command encoder");
131 encoder.set_compute_pipeline_state(&pipeline);
132 encoder.set_buffer(&buffer, 0, 0);
133 encoder.set_texture(&texture, 1);
134 if let Some(fence) = fence_a.as_ref() {
135 encoder.wait_for_fence(fence);
136 }
137 if let Some(table) = visible_table.as_ref() {
138 encoder.set_visible_function_table(table, 2);
139 }
140 if let Some(table) = intersection_table.as_ref() {
141 encoder.set_intersection_function_table(table, 3);
142 }
143 if let Some(acceleration_structure) = acceleration_structure.as_ref() {
144 encoder.set_acceleration_structure(acceleration_structure, 4);
145 }
146 encoder.dispatch_threadgroups((1, 1, 1), (4, 1, 1));
147 if let Some(fence) = fence_b.as_ref() {
148 encoder.update_fence(fence);
149 }
150 encoder.end_encoding();
151 compute.commit();
152 compute.wait_until_completed();
153 println!(
154 "compute buffer after dispatch: {:?}",
155 common::read_u32_words(&buffer, 4)
156 );
157
158 if let Some(indirect) = device.new_indirect_command_buffer(
159 indirect_command_type::CONCURRENT_DISPATCH,
160 1,
161 0,
162 0,
163 4,
164 resource_options::STORAGE_MODE_PRIVATE,
165 ) {
166 indirect.reset_range(0..1);
167 println!("indirect command buffer size={}", indirect.size());
168 }
169
170 if let Some(heap) = device.new_heap(1 << 20, storage_mode::SHARED) {
171 if let Ok(residency_set) = device.new_residency_set(Some("example-residency"), 4) {
172 let heap_buffer = heap
173 .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
174 .expect("heap buffer");
175 residency_set.add_buffer(&heap_buffer);
176 residency_set.add_heap(&heap);
177 residency_set.commit();
178 residency_set.request_residency();
179 queue.add_residency_set(&residency_set);
180 queue.remove_residency_set(&residency_set);
181 residency_set.end_residency();
182 residency_set.remove_all_allocations();
183 residency_set.commit();
184 println!(
185 "residency allocation count={}",
186 residency_set.allocation_count()
187 );
188 } else {
189 println!("residency sets unavailable on this OS");
190 }
191 }
192
193 if let Some(capture_manager) = CaptureManager::shared() {
194 println!(
195 "capture supported for developer tools={} active={}",
196 capture_manager.supports_destination(capture_destination::DEVELOPER_TOOLS),
197 capture_manager.is_capturing(),
198 );
199 if let Some(scope) = capture_manager.new_capture_scope_with_device(&device) {
200 scope.begin();
201 scope.end();
202 }
203 if let Some(scope) = capture_manager.new_capture_scope_with_command_queue(&queue) {
204 scope.begin();
205 scope.end();
206 }
207 }
208}Sourcepub fn fill_buffer(
&self,
buffer: &MetalBuffer,
range: Range<usize>,
value: u8,
) -> bool
pub fn fill_buffer( &self, buffer: &MetalBuffer, range: Range<usize>, value: u8, ) -> bool
Fill a byte range of buffer with value.
Examples found in repository?
examples/05_render_and_explicit_encoders.rs (line 35)
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 = queue
21 .new_command_buffer_with_unretained_references()
22 .expect("scratch command buffer");
23 println!("scratch command buffer status={}", status_buffer.status());
24
25 let src = device
26 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
27 .expect("source buffer");
28 let dst = device
29 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
30 .expect("destination buffer");
31 let blit_cb = queue.new_command_buffer().expect("blit command buffer");
32 let blit = blit_cb
33 .new_blit_command_encoder()
34 .expect("blit command encoder");
35 assert!(blit.fill_buffer(&src, 0..64, b'Z'));
36 assert!(blit.copy_buffer(&src, 0, &dst, 0, 64));
37 blit.end_encoding();
38 blit_cb.commit();
39 blit_cb.wait_until_completed();
40 let copied = unsafe {
41 core::slice::from_raw_parts(dst.contents().expect("dst contents").cast::<u8>(), 8)
42 };
43 println!("blit copied bytes: {copied:?}");
44
45 let library = device
46 .new_library_with_source(common::COMPUTE_SRC)
47 .expect("compile compute library");
48 let increment = library
49 .new_function("increment")
50 .expect("increment function");
51 let pipeline = device
52 .new_compute_pipeline_state(&increment)
53 .expect("compute pipeline");
54
55 let buffer = device
56 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
57 .expect("compute buffer");
58 common::write_u32_words(&buffer, &[10, 20, 30, 40]);
59 let compute_cb = queue.new_command_buffer().expect("compute command buffer");
60 let compute = compute_cb
61 .new_compute_command_encoder()
62 .expect("compute command encoder");
63 compute.set_compute_pipeline_state(&pipeline);
64 compute.set_buffer(&buffer, 0, 0);
65 compute.dispatch_threads((4, 1, 1), (1, 1, 1));
66 compute.end_encoding();
67 compute_cb.commit();
68 compute_cb.wait_until_completed();
69 println!("compute output: {:?}", common::read_u32_words(&buffer, 4));
70
71 let render_library = device
72 .new_library_with_source(common::RENDER_SRC)
73 .expect("compile render library");
74 let vertex = render_library
75 .new_function("fullscreen_vertex")
76 .expect("vertex function");
77 let fragment = render_library
78 .new_function("solid_fragment")
79 .expect("fragment function");
80 let render_pipeline = device
81 .new_render_pipeline_state(&vertex, &fragment, pixel_format::BGRA8UNORM, 1)
82 .expect("render pipeline");
83 println!("render pipeline label: {:?}", render_pipeline.label());
84
85 let render_target = device
86 .new_texture(common::shared_render_target(4, 4))
87 .expect("render target");
88 let vertex_buffer = device
89 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
90 .expect("vertex buffer");
91 let render_cb = queue.new_command_buffer().expect("render command buffer");
92 let render = render_cb
93 .new_render_command_encoder(
94 &render_target,
95 load_action::CLEAR,
96 store_action::STORE,
97 [0.0, 0.0, 0.0, 1.0],
98 )
99 .expect("render command encoder");
100 render.set_render_pipeline_state(&render_pipeline);
101 render.set_vertex_buffer(&vertex_buffer, 0, 0);
102 render.draw_primitives(primitive_type::TRIANGLE, 0, 3);
103 render.end_encoding();
104 render_cb.commit();
105 render_cb.wait_until_completed();
106
107 let mut rendered = vec![0_u8; 4 * 4 * 4];
108 assert!(render_target.read_bytes_2d(&mut rendered, 16, (0, 0), (4, 4), 0));
109 println!("first rendered pixel: {:?}", &rendered[..4]);
110
111 let shared_texture = device
112 .new_texture(TextureDescriptor::new_2d(4, 4, pixel_format::BGRA8UNORM))
113 .expect("shared texture");
114 let upload = vec![0x22_u8; 4 * 4 * 4];
115 assert!(shared_texture.replace_region_2d(&upload, 16, (0, 0), (4, 4), 0));
116 let mut download = vec![0_u8; upload.len()];
117 assert!(shared_texture.read_bytes_2d(&mut download, 16, (0, 0), (4, 4), 0));
118 let view = shared_texture
119 .new_view(pixel_format::BGRA8UNORM)
120 .expect("texture view");
121 println!(
122 "texture {}x{} usage={} storage_mode={} view_width={}",
123 shared_texture.width(),
124 shared_texture.height(),
125 shared_texture.usage(),
126 shared_texture.storage_mode(),
127 view.width(),
128 );
129}More examples
examples/07_advanced_objects.rs (line 59)
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.encode_signal_event(&event, 2);
24 signal.commit();
25 signal.wait_until_completed();
26 println!(
27 "event reached value 2: {}",
28 event.wait_until_signaled_value(2, 1_000),
29 );
30
31 let wait = queue
32 .new_command_buffer()
33 .expect("event wait command buffer");
34 wait.encode_wait_for_event(&event, 2);
35 wait.commit();
36 wait.wait_until_completed();
37 }
38
39 let fence_a = device.new_fence();
40 let fence_b = device.new_fence();
41 let sample_buffer = counter_sets.first().and_then(|name| {
42 if device.supports_counter_sampling(counter_sampling_point::AT_BLIT_BOUNDARY) {
43 device
44 .new_counter_sample_buffer(name, 2, storage_mode::SHARED, Some("example-samples"))
45 .ok()
46 } else {
47 None
48 }
49 });
50
51 let src = device
52 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
53 .expect("source buffer");
54 let dst = device
55 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
56 .expect("destination buffer");
57 let blit = queue.new_command_buffer().expect("blit command buffer");
58 let encoder = blit.new_blit_command_encoder().expect("blit encoder");
59 let _ = encoder.fill_buffer(&src, 0..64, b'Q');
60 if let Some(fence) = fence_a.as_ref() {
61 encoder.update_fence(fence);
62 }
63 encoder.end_encoding();
64 blit.commit();
65 blit.wait_until_completed();
66
67 let blit = queue
68 .new_command_buffer()
69 .expect("second blit command buffer");
70 let encoder = blit
71 .new_blit_command_encoder()
72 .expect("second blit encoder");
73 if let Some(fence) = fence_a.as_ref() {
74 encoder.wait_for_fence(fence);
75 }
76 if let Some(sample_buffer) = sample_buffer.as_ref() {
77 let _ = encoder.sample_counters(sample_buffer, 0, false);
78 }
79 let _ = encoder.copy_buffer(&src, 0, &dst, 0, 64);
80 encoder.end_encoding();
81 blit.commit();
82 blit.wait_until_completed();
83 if let Some(sample_buffer) = sample_buffer.as_ref() {
84 println!(
85 "resolved counter bytes={}",
86 sample_buffer
87 .resolve_range(0..1)
88 .map_or(0, |bytes| bytes.len())
89 );
90 }
91
92 let library = device
93 .new_library_with_source(common::COMPUTE_SRC)
94 .expect("compile compute library");
95 let increment = library
96 .new_function("increment")
97 .expect("increment function");
98 let pipeline = device
99 .new_compute_pipeline_state(&increment)
100 .expect("compute pipeline");
101 let visible_table = pipeline.new_visible_function_table(1);
102 let intersection_table = if device.supports_raytracing() {
103 pipeline.new_intersection_function_table(1)
104 } else {
105 None
106 };
107 if let Some(table) = intersection_table.as_ref() {
108 table.set_opaque_triangle_intersection_function(intersection_function_signature::NONE, 0);
109 }
110 let acceleration_structure = if device.supports_raytracing() {
111 device.new_acceleration_structure_with_size(256)
112 } else {
113 None
114 };
115
116 let buffer = device
117 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
118 .expect("compute buffer");
119 common::write_u32_words(&buffer, &[1, 2, 3, 4]);
120 let texture = device
121 .new_texture(apple_metal::TextureDescriptor::new_2d(
122 4,
123 4,
124 apple_metal::pixel_format::BGRA8UNORM,
125 ))
126 .expect("compute texture");
127 let compute = queue.new_command_buffer().expect("compute command buffer");
128 let encoder = compute
129 .new_compute_command_encoder()
130 .expect("compute command encoder");
131 encoder.set_compute_pipeline_state(&pipeline);
132 encoder.set_buffer(&buffer, 0, 0);
133 encoder.set_texture(&texture, 1);
134 if let Some(fence) = fence_a.as_ref() {
135 encoder.wait_for_fence(fence);
136 }
137 if let Some(table) = visible_table.as_ref() {
138 encoder.set_visible_function_table(table, 2);
139 }
140 if let Some(table) = intersection_table.as_ref() {
141 encoder.set_intersection_function_table(table, 3);
142 }
143 if let Some(acceleration_structure) = acceleration_structure.as_ref() {
144 encoder.set_acceleration_structure(acceleration_structure, 4);
145 }
146 encoder.dispatch_threadgroups((1, 1, 1), (4, 1, 1));
147 if let Some(fence) = fence_b.as_ref() {
148 encoder.update_fence(fence);
149 }
150 encoder.end_encoding();
151 compute.commit();
152 compute.wait_until_completed();
153 println!(
154 "compute buffer after dispatch: {:?}",
155 common::read_u32_words(&buffer, 4)
156 );
157
158 if let Some(indirect) = device.new_indirect_command_buffer(
159 indirect_command_type::CONCURRENT_DISPATCH,
160 1,
161 0,
162 0,
163 4,
164 resource_options::STORAGE_MODE_PRIVATE,
165 ) {
166 indirect.reset_range(0..1);
167 println!("indirect command buffer size={}", indirect.size());
168 }
169
170 if let Some(heap) = device.new_heap(1 << 20, storage_mode::SHARED) {
171 if let Ok(residency_set) = device.new_residency_set(Some("example-residency"), 4) {
172 let heap_buffer = heap
173 .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
174 .expect("heap buffer");
175 residency_set.add_buffer(&heap_buffer);
176 residency_set.add_heap(&heap);
177 residency_set.commit();
178 residency_set.request_residency();
179 queue.add_residency_set(&residency_set);
180 queue.remove_residency_set(&residency_set);
181 residency_set.end_residency();
182 residency_set.remove_all_allocations();
183 residency_set.commit();
184 println!(
185 "residency allocation count={}",
186 residency_set.allocation_count()
187 );
188 } else {
189 println!("residency sets unavailable on this OS");
190 }
191 }
192
193 if let Some(capture_manager) = CaptureManager::shared() {
194 println!(
195 "capture supported for developer tools={} active={}",
196 capture_manager.supports_destination(capture_destination::DEVELOPER_TOOLS),
197 capture_manager.is_capturing(),
198 );
199 if let Some(scope) = capture_manager.new_capture_scope_with_device(&device) {
200 scope.begin();
201 scope.end();
202 }
203 if let Some(scope) = capture_manager.new_capture_scope_with_command_queue(&queue) {
204 scope.begin();
205 scope.end();
206 }
207 }
208}Sourcepub fn sample_counters(
&self,
sample_buffer: &CounterSampleBuffer,
sample_index: usize,
barrier: bool,
) -> bool
pub fn sample_counters( &self, sample_buffer: &CounterSampleBuffer, sample_index: usize, barrier: bool, ) -> bool
Sample hardware counters into sample_buffer.
Examples found in repository?
examples/07_advanced_objects.rs (line 77)
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.encode_signal_event(&event, 2);
24 signal.commit();
25 signal.wait_until_completed();
26 println!(
27 "event reached value 2: {}",
28 event.wait_until_signaled_value(2, 1_000),
29 );
30
31 let wait = queue
32 .new_command_buffer()
33 .expect("event wait command buffer");
34 wait.encode_wait_for_event(&event, 2);
35 wait.commit();
36 wait.wait_until_completed();
37 }
38
39 let fence_a = device.new_fence();
40 let fence_b = device.new_fence();
41 let sample_buffer = counter_sets.first().and_then(|name| {
42 if device.supports_counter_sampling(counter_sampling_point::AT_BLIT_BOUNDARY) {
43 device
44 .new_counter_sample_buffer(name, 2, storage_mode::SHARED, Some("example-samples"))
45 .ok()
46 } else {
47 None
48 }
49 });
50
51 let src = device
52 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
53 .expect("source buffer");
54 let dst = device
55 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
56 .expect("destination buffer");
57 let blit = queue.new_command_buffer().expect("blit command buffer");
58 let encoder = blit.new_blit_command_encoder().expect("blit encoder");
59 let _ = encoder.fill_buffer(&src, 0..64, b'Q');
60 if let Some(fence) = fence_a.as_ref() {
61 encoder.update_fence(fence);
62 }
63 encoder.end_encoding();
64 blit.commit();
65 blit.wait_until_completed();
66
67 let blit = queue
68 .new_command_buffer()
69 .expect("second blit command buffer");
70 let encoder = blit
71 .new_blit_command_encoder()
72 .expect("second blit encoder");
73 if let Some(fence) = fence_a.as_ref() {
74 encoder.wait_for_fence(fence);
75 }
76 if let Some(sample_buffer) = sample_buffer.as_ref() {
77 let _ = encoder.sample_counters(sample_buffer, 0, false);
78 }
79 let _ = encoder.copy_buffer(&src, 0, &dst, 0, 64);
80 encoder.end_encoding();
81 blit.commit();
82 blit.wait_until_completed();
83 if let Some(sample_buffer) = sample_buffer.as_ref() {
84 println!(
85 "resolved counter bytes={}",
86 sample_buffer
87 .resolve_range(0..1)
88 .map_or(0, |bytes| bytes.len())
89 );
90 }
91
92 let library = device
93 .new_library_with_source(common::COMPUTE_SRC)
94 .expect("compile compute library");
95 let increment = library
96 .new_function("increment")
97 .expect("increment function");
98 let pipeline = device
99 .new_compute_pipeline_state(&increment)
100 .expect("compute pipeline");
101 let visible_table = pipeline.new_visible_function_table(1);
102 let intersection_table = if device.supports_raytracing() {
103 pipeline.new_intersection_function_table(1)
104 } else {
105 None
106 };
107 if let Some(table) = intersection_table.as_ref() {
108 table.set_opaque_triangle_intersection_function(intersection_function_signature::NONE, 0);
109 }
110 let acceleration_structure = if device.supports_raytracing() {
111 device.new_acceleration_structure_with_size(256)
112 } else {
113 None
114 };
115
116 let buffer = device
117 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
118 .expect("compute buffer");
119 common::write_u32_words(&buffer, &[1, 2, 3, 4]);
120 let texture = device
121 .new_texture(apple_metal::TextureDescriptor::new_2d(
122 4,
123 4,
124 apple_metal::pixel_format::BGRA8UNORM,
125 ))
126 .expect("compute texture");
127 let compute = queue.new_command_buffer().expect("compute command buffer");
128 let encoder = compute
129 .new_compute_command_encoder()
130 .expect("compute command encoder");
131 encoder.set_compute_pipeline_state(&pipeline);
132 encoder.set_buffer(&buffer, 0, 0);
133 encoder.set_texture(&texture, 1);
134 if let Some(fence) = fence_a.as_ref() {
135 encoder.wait_for_fence(fence);
136 }
137 if let Some(table) = visible_table.as_ref() {
138 encoder.set_visible_function_table(table, 2);
139 }
140 if let Some(table) = intersection_table.as_ref() {
141 encoder.set_intersection_function_table(table, 3);
142 }
143 if let Some(acceleration_structure) = acceleration_structure.as_ref() {
144 encoder.set_acceleration_structure(acceleration_structure, 4);
145 }
146 encoder.dispatch_threadgroups((1, 1, 1), (4, 1, 1));
147 if let Some(fence) = fence_b.as_ref() {
148 encoder.update_fence(fence);
149 }
150 encoder.end_encoding();
151 compute.commit();
152 compute.wait_until_completed();
153 println!(
154 "compute buffer after dispatch: {:?}",
155 common::read_u32_words(&buffer, 4)
156 );
157
158 if let Some(indirect) = device.new_indirect_command_buffer(
159 indirect_command_type::CONCURRENT_DISPATCH,
160 1,
161 0,
162 0,
163 4,
164 resource_options::STORAGE_MODE_PRIVATE,
165 ) {
166 indirect.reset_range(0..1);
167 println!("indirect command buffer size={}", indirect.size());
168 }
169
170 if let Some(heap) = device.new_heap(1 << 20, storage_mode::SHARED) {
171 if let Ok(residency_set) = device.new_residency_set(Some("example-residency"), 4) {
172 let heap_buffer = heap
173 .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
174 .expect("heap buffer");
175 residency_set.add_buffer(&heap_buffer);
176 residency_set.add_heap(&heap);
177 residency_set.commit();
178 residency_set.request_residency();
179 queue.add_residency_set(&residency_set);
180 queue.remove_residency_set(&residency_set);
181 residency_set.end_residency();
182 residency_set.remove_all_allocations();
183 residency_set.commit();
184 println!(
185 "residency allocation count={}",
186 residency_set.allocation_count()
187 );
188 } else {
189 println!("residency sets unavailable on this OS");
190 }
191 }
192
193 if let Some(capture_manager) = CaptureManager::shared() {
194 println!(
195 "capture supported for developer tools={} active={}",
196 capture_manager.supports_destination(capture_destination::DEVELOPER_TOOLS),
197 capture_manager.is_capturing(),
198 );
199 if let Some(scope) = capture_manager.new_capture_scope_with_device(&device) {
200 scope.begin();
201 scope.end();
202 }
203 if let Some(scope) = capture_manager.new_capture_scope_with_command_queue(&queue) {
204 scope.begin();
205 scope.end();
206 }
207 }
208}Sourcepub fn update_fence(&self, fence: &Fence)
pub fn update_fence(&self, fence: &Fence)
Update fence with work encoded so far.
Examples found in repository?
examples/07_advanced_objects.rs (line 61)
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.encode_signal_event(&event, 2);
24 signal.commit();
25 signal.wait_until_completed();
26 println!(
27 "event reached value 2: {}",
28 event.wait_until_signaled_value(2, 1_000),
29 );
30
31 let wait = queue
32 .new_command_buffer()
33 .expect("event wait command buffer");
34 wait.encode_wait_for_event(&event, 2);
35 wait.commit();
36 wait.wait_until_completed();
37 }
38
39 let fence_a = device.new_fence();
40 let fence_b = device.new_fence();
41 let sample_buffer = counter_sets.first().and_then(|name| {
42 if device.supports_counter_sampling(counter_sampling_point::AT_BLIT_BOUNDARY) {
43 device
44 .new_counter_sample_buffer(name, 2, storage_mode::SHARED, Some("example-samples"))
45 .ok()
46 } else {
47 None
48 }
49 });
50
51 let src = device
52 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
53 .expect("source buffer");
54 let dst = device
55 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
56 .expect("destination buffer");
57 let blit = queue.new_command_buffer().expect("blit command buffer");
58 let encoder = blit.new_blit_command_encoder().expect("blit encoder");
59 let _ = encoder.fill_buffer(&src, 0..64, b'Q');
60 if let Some(fence) = fence_a.as_ref() {
61 encoder.update_fence(fence);
62 }
63 encoder.end_encoding();
64 blit.commit();
65 blit.wait_until_completed();
66
67 let blit = queue
68 .new_command_buffer()
69 .expect("second blit command buffer");
70 let encoder = blit
71 .new_blit_command_encoder()
72 .expect("second blit encoder");
73 if let Some(fence) = fence_a.as_ref() {
74 encoder.wait_for_fence(fence);
75 }
76 if let Some(sample_buffer) = sample_buffer.as_ref() {
77 let _ = encoder.sample_counters(sample_buffer, 0, false);
78 }
79 let _ = encoder.copy_buffer(&src, 0, &dst, 0, 64);
80 encoder.end_encoding();
81 blit.commit();
82 blit.wait_until_completed();
83 if let Some(sample_buffer) = sample_buffer.as_ref() {
84 println!(
85 "resolved counter bytes={}",
86 sample_buffer
87 .resolve_range(0..1)
88 .map_or(0, |bytes| bytes.len())
89 );
90 }
91
92 let library = device
93 .new_library_with_source(common::COMPUTE_SRC)
94 .expect("compile compute library");
95 let increment = library
96 .new_function("increment")
97 .expect("increment function");
98 let pipeline = device
99 .new_compute_pipeline_state(&increment)
100 .expect("compute pipeline");
101 let visible_table = pipeline.new_visible_function_table(1);
102 let intersection_table = if device.supports_raytracing() {
103 pipeline.new_intersection_function_table(1)
104 } else {
105 None
106 };
107 if let Some(table) = intersection_table.as_ref() {
108 table.set_opaque_triangle_intersection_function(intersection_function_signature::NONE, 0);
109 }
110 let acceleration_structure = if device.supports_raytracing() {
111 device.new_acceleration_structure_with_size(256)
112 } else {
113 None
114 };
115
116 let buffer = device
117 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
118 .expect("compute buffer");
119 common::write_u32_words(&buffer, &[1, 2, 3, 4]);
120 let texture = device
121 .new_texture(apple_metal::TextureDescriptor::new_2d(
122 4,
123 4,
124 apple_metal::pixel_format::BGRA8UNORM,
125 ))
126 .expect("compute texture");
127 let compute = queue.new_command_buffer().expect("compute command buffer");
128 let encoder = compute
129 .new_compute_command_encoder()
130 .expect("compute command encoder");
131 encoder.set_compute_pipeline_state(&pipeline);
132 encoder.set_buffer(&buffer, 0, 0);
133 encoder.set_texture(&texture, 1);
134 if let Some(fence) = fence_a.as_ref() {
135 encoder.wait_for_fence(fence);
136 }
137 if let Some(table) = visible_table.as_ref() {
138 encoder.set_visible_function_table(table, 2);
139 }
140 if let Some(table) = intersection_table.as_ref() {
141 encoder.set_intersection_function_table(table, 3);
142 }
143 if let Some(acceleration_structure) = acceleration_structure.as_ref() {
144 encoder.set_acceleration_structure(acceleration_structure, 4);
145 }
146 encoder.dispatch_threadgroups((1, 1, 1), (4, 1, 1));
147 if let Some(fence) = fence_b.as_ref() {
148 encoder.update_fence(fence);
149 }
150 encoder.end_encoding();
151 compute.commit();
152 compute.wait_until_completed();
153 println!(
154 "compute buffer after dispatch: {:?}",
155 common::read_u32_words(&buffer, 4)
156 );
157
158 if let Some(indirect) = device.new_indirect_command_buffer(
159 indirect_command_type::CONCURRENT_DISPATCH,
160 1,
161 0,
162 0,
163 4,
164 resource_options::STORAGE_MODE_PRIVATE,
165 ) {
166 indirect.reset_range(0..1);
167 println!("indirect command buffer size={}", indirect.size());
168 }
169
170 if let Some(heap) = device.new_heap(1 << 20, storage_mode::SHARED) {
171 if let Ok(residency_set) = device.new_residency_set(Some("example-residency"), 4) {
172 let heap_buffer = heap
173 .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
174 .expect("heap buffer");
175 residency_set.add_buffer(&heap_buffer);
176 residency_set.add_heap(&heap);
177 residency_set.commit();
178 residency_set.request_residency();
179 queue.add_residency_set(&residency_set);
180 queue.remove_residency_set(&residency_set);
181 residency_set.end_residency();
182 residency_set.remove_all_allocations();
183 residency_set.commit();
184 println!(
185 "residency allocation count={}",
186 residency_set.allocation_count()
187 );
188 } else {
189 println!("residency sets unavailable on this OS");
190 }
191 }
192
193 if let Some(capture_manager) = CaptureManager::shared() {
194 println!(
195 "capture supported for developer tools={} active={}",
196 capture_manager.supports_destination(capture_destination::DEVELOPER_TOOLS),
197 capture_manager.is_capturing(),
198 );
199 if let Some(scope) = capture_manager.new_capture_scope_with_device(&device) {
200 scope.begin();
201 scope.end();
202 }
203 if let Some(scope) = capture_manager.new_capture_scope_with_command_queue(&queue) {
204 scope.begin();
205 scope.end();
206 }
207 }
208}Sourcepub fn wait_for_fence(&self, fence: &Fence)
pub fn wait_for_fence(&self, fence: &Fence)
Wait for fence before executing subsequent work.
Examples found in repository?
examples/07_advanced_objects.rs (line 74)
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.encode_signal_event(&event, 2);
24 signal.commit();
25 signal.wait_until_completed();
26 println!(
27 "event reached value 2: {}",
28 event.wait_until_signaled_value(2, 1_000),
29 );
30
31 let wait = queue
32 .new_command_buffer()
33 .expect("event wait command buffer");
34 wait.encode_wait_for_event(&event, 2);
35 wait.commit();
36 wait.wait_until_completed();
37 }
38
39 let fence_a = device.new_fence();
40 let fence_b = device.new_fence();
41 let sample_buffer = counter_sets.first().and_then(|name| {
42 if device.supports_counter_sampling(counter_sampling_point::AT_BLIT_BOUNDARY) {
43 device
44 .new_counter_sample_buffer(name, 2, storage_mode::SHARED, Some("example-samples"))
45 .ok()
46 } else {
47 None
48 }
49 });
50
51 let src = device
52 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
53 .expect("source buffer");
54 let dst = device
55 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
56 .expect("destination buffer");
57 let blit = queue.new_command_buffer().expect("blit command buffer");
58 let encoder = blit.new_blit_command_encoder().expect("blit encoder");
59 let _ = encoder.fill_buffer(&src, 0..64, b'Q');
60 if let Some(fence) = fence_a.as_ref() {
61 encoder.update_fence(fence);
62 }
63 encoder.end_encoding();
64 blit.commit();
65 blit.wait_until_completed();
66
67 let blit = queue
68 .new_command_buffer()
69 .expect("second blit command buffer");
70 let encoder = blit
71 .new_blit_command_encoder()
72 .expect("second blit encoder");
73 if let Some(fence) = fence_a.as_ref() {
74 encoder.wait_for_fence(fence);
75 }
76 if let Some(sample_buffer) = sample_buffer.as_ref() {
77 let _ = encoder.sample_counters(sample_buffer, 0, false);
78 }
79 let _ = encoder.copy_buffer(&src, 0, &dst, 0, 64);
80 encoder.end_encoding();
81 blit.commit();
82 blit.wait_until_completed();
83 if let Some(sample_buffer) = sample_buffer.as_ref() {
84 println!(
85 "resolved counter bytes={}",
86 sample_buffer
87 .resolve_range(0..1)
88 .map_or(0, |bytes| bytes.len())
89 );
90 }
91
92 let library = device
93 .new_library_with_source(common::COMPUTE_SRC)
94 .expect("compile compute library");
95 let increment = library
96 .new_function("increment")
97 .expect("increment function");
98 let pipeline = device
99 .new_compute_pipeline_state(&increment)
100 .expect("compute pipeline");
101 let visible_table = pipeline.new_visible_function_table(1);
102 let intersection_table = if device.supports_raytracing() {
103 pipeline.new_intersection_function_table(1)
104 } else {
105 None
106 };
107 if let Some(table) = intersection_table.as_ref() {
108 table.set_opaque_triangle_intersection_function(intersection_function_signature::NONE, 0);
109 }
110 let acceleration_structure = if device.supports_raytracing() {
111 device.new_acceleration_structure_with_size(256)
112 } else {
113 None
114 };
115
116 let buffer = device
117 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
118 .expect("compute buffer");
119 common::write_u32_words(&buffer, &[1, 2, 3, 4]);
120 let texture = device
121 .new_texture(apple_metal::TextureDescriptor::new_2d(
122 4,
123 4,
124 apple_metal::pixel_format::BGRA8UNORM,
125 ))
126 .expect("compute texture");
127 let compute = queue.new_command_buffer().expect("compute command buffer");
128 let encoder = compute
129 .new_compute_command_encoder()
130 .expect("compute command encoder");
131 encoder.set_compute_pipeline_state(&pipeline);
132 encoder.set_buffer(&buffer, 0, 0);
133 encoder.set_texture(&texture, 1);
134 if let Some(fence) = fence_a.as_ref() {
135 encoder.wait_for_fence(fence);
136 }
137 if let Some(table) = visible_table.as_ref() {
138 encoder.set_visible_function_table(table, 2);
139 }
140 if let Some(table) = intersection_table.as_ref() {
141 encoder.set_intersection_function_table(table, 3);
142 }
143 if let Some(acceleration_structure) = acceleration_structure.as_ref() {
144 encoder.set_acceleration_structure(acceleration_structure, 4);
145 }
146 encoder.dispatch_threadgroups((1, 1, 1), (4, 1, 1));
147 if let Some(fence) = fence_b.as_ref() {
148 encoder.update_fence(fence);
149 }
150 encoder.end_encoding();
151 compute.commit();
152 compute.wait_until_completed();
153 println!(
154 "compute buffer after dispatch: {:?}",
155 common::read_u32_words(&buffer, 4)
156 );
157
158 if let Some(indirect) = device.new_indirect_command_buffer(
159 indirect_command_type::CONCURRENT_DISPATCH,
160 1,
161 0,
162 0,
163 4,
164 resource_options::STORAGE_MODE_PRIVATE,
165 ) {
166 indirect.reset_range(0..1);
167 println!("indirect command buffer size={}", indirect.size());
168 }
169
170 if let Some(heap) = device.new_heap(1 << 20, storage_mode::SHARED) {
171 if let Ok(residency_set) = device.new_residency_set(Some("example-residency"), 4) {
172 let heap_buffer = heap
173 .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
174 .expect("heap buffer");
175 residency_set.add_buffer(&heap_buffer);
176 residency_set.add_heap(&heap);
177 residency_set.commit();
178 residency_set.request_residency();
179 queue.add_residency_set(&residency_set);
180 queue.remove_residency_set(&residency_set);
181 residency_set.end_residency();
182 residency_set.remove_all_allocations();
183 residency_set.commit();
184 println!(
185 "residency allocation count={}",
186 residency_set.allocation_count()
187 );
188 } else {
189 println!("residency sets unavailable on this OS");
190 }
191 }
192
193 if let Some(capture_manager) = CaptureManager::shared() {
194 println!(
195 "capture supported for developer tools={} active={}",
196 capture_manager.supports_destination(capture_destination::DEVELOPER_TOOLS),
197 capture_manager.is_capturing(),
198 );
199 if let Some(scope) = capture_manager.new_capture_scope_with_device(&device) {
200 scope.begin();
201 scope.end();
202 }
203 if let Some(scope) = capture_manager.new_capture_scope_with_command_queue(&queue) {
204 scope.begin();
205 scope.end();
206 }
207 }
208}Sourcepub fn end_encoding(&self)
pub fn end_encoding(&self)
Finish encoding commands.
Examples found in repository?
examples/05_render_and_explicit_encoders.rs (line 37)
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 = queue
21 .new_command_buffer_with_unretained_references()
22 .expect("scratch command buffer");
23 println!("scratch command buffer status={}", status_buffer.status());
24
25 let src = device
26 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
27 .expect("source buffer");
28 let dst = device
29 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
30 .expect("destination buffer");
31 let blit_cb = queue.new_command_buffer().expect("blit command buffer");
32 let blit = blit_cb
33 .new_blit_command_encoder()
34 .expect("blit command encoder");
35 assert!(blit.fill_buffer(&src, 0..64, b'Z'));
36 assert!(blit.copy_buffer(&src, 0, &dst, 0, 64));
37 blit.end_encoding();
38 blit_cb.commit();
39 blit_cb.wait_until_completed();
40 let copied = unsafe {
41 core::slice::from_raw_parts(dst.contents().expect("dst contents").cast::<u8>(), 8)
42 };
43 println!("blit copied bytes: {copied:?}");
44
45 let library = device
46 .new_library_with_source(common::COMPUTE_SRC)
47 .expect("compile compute library");
48 let increment = library
49 .new_function("increment")
50 .expect("increment function");
51 let pipeline = device
52 .new_compute_pipeline_state(&increment)
53 .expect("compute pipeline");
54
55 let buffer = device
56 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
57 .expect("compute buffer");
58 common::write_u32_words(&buffer, &[10, 20, 30, 40]);
59 let compute_cb = queue.new_command_buffer().expect("compute command buffer");
60 let compute = compute_cb
61 .new_compute_command_encoder()
62 .expect("compute command encoder");
63 compute.set_compute_pipeline_state(&pipeline);
64 compute.set_buffer(&buffer, 0, 0);
65 compute.dispatch_threads((4, 1, 1), (1, 1, 1));
66 compute.end_encoding();
67 compute_cb.commit();
68 compute_cb.wait_until_completed();
69 println!("compute output: {:?}", common::read_u32_words(&buffer, 4));
70
71 let render_library = device
72 .new_library_with_source(common::RENDER_SRC)
73 .expect("compile render library");
74 let vertex = render_library
75 .new_function("fullscreen_vertex")
76 .expect("vertex function");
77 let fragment = render_library
78 .new_function("solid_fragment")
79 .expect("fragment function");
80 let render_pipeline = device
81 .new_render_pipeline_state(&vertex, &fragment, pixel_format::BGRA8UNORM, 1)
82 .expect("render pipeline");
83 println!("render pipeline label: {:?}", render_pipeline.label());
84
85 let render_target = device
86 .new_texture(common::shared_render_target(4, 4))
87 .expect("render target");
88 let vertex_buffer = device
89 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
90 .expect("vertex buffer");
91 let render_cb = queue.new_command_buffer().expect("render command buffer");
92 let render = render_cb
93 .new_render_command_encoder(
94 &render_target,
95 load_action::CLEAR,
96 store_action::STORE,
97 [0.0, 0.0, 0.0, 1.0],
98 )
99 .expect("render command encoder");
100 render.set_render_pipeline_state(&render_pipeline);
101 render.set_vertex_buffer(&vertex_buffer, 0, 0);
102 render.draw_primitives(primitive_type::TRIANGLE, 0, 3);
103 render.end_encoding();
104 render_cb.commit();
105 render_cb.wait_until_completed();
106
107 let mut rendered = vec![0_u8; 4 * 4 * 4];
108 assert!(render_target.read_bytes_2d(&mut rendered, 16, (0, 0), (4, 4), 0));
109 println!("first rendered pixel: {:?}", &rendered[..4]);
110
111 let shared_texture = device
112 .new_texture(TextureDescriptor::new_2d(4, 4, pixel_format::BGRA8UNORM))
113 .expect("shared texture");
114 let upload = vec![0x22_u8; 4 * 4 * 4];
115 assert!(shared_texture.replace_region_2d(&upload, 16, (0, 0), (4, 4), 0));
116 let mut download = vec![0_u8; upload.len()];
117 assert!(shared_texture.read_bytes_2d(&mut download, 16, (0, 0), (4, 4), 0));
118 let view = shared_texture
119 .new_view(pixel_format::BGRA8UNORM)
120 .expect("texture view");
121 println!(
122 "texture {}x{} usage={} storage_mode={} view_width={}",
123 shared_texture.width(),
124 shared_texture.height(),
125 shared_texture.usage(),
126 shared_texture.storage_mode(),
127 view.width(),
128 );
129}More examples
examples/07_advanced_objects.rs (line 63)
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.encode_signal_event(&event, 2);
24 signal.commit();
25 signal.wait_until_completed();
26 println!(
27 "event reached value 2: {}",
28 event.wait_until_signaled_value(2, 1_000),
29 );
30
31 let wait = queue
32 .new_command_buffer()
33 .expect("event wait command buffer");
34 wait.encode_wait_for_event(&event, 2);
35 wait.commit();
36 wait.wait_until_completed();
37 }
38
39 let fence_a = device.new_fence();
40 let fence_b = device.new_fence();
41 let sample_buffer = counter_sets.first().and_then(|name| {
42 if device.supports_counter_sampling(counter_sampling_point::AT_BLIT_BOUNDARY) {
43 device
44 .new_counter_sample_buffer(name, 2, storage_mode::SHARED, Some("example-samples"))
45 .ok()
46 } else {
47 None
48 }
49 });
50
51 let src = device
52 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
53 .expect("source buffer");
54 let dst = device
55 .new_buffer(64, resource_options::STORAGE_MODE_SHARED)
56 .expect("destination buffer");
57 let blit = queue.new_command_buffer().expect("blit command buffer");
58 let encoder = blit.new_blit_command_encoder().expect("blit encoder");
59 let _ = encoder.fill_buffer(&src, 0..64, b'Q');
60 if let Some(fence) = fence_a.as_ref() {
61 encoder.update_fence(fence);
62 }
63 encoder.end_encoding();
64 blit.commit();
65 blit.wait_until_completed();
66
67 let blit = queue
68 .new_command_buffer()
69 .expect("second blit command buffer");
70 let encoder = blit
71 .new_blit_command_encoder()
72 .expect("second blit encoder");
73 if let Some(fence) = fence_a.as_ref() {
74 encoder.wait_for_fence(fence);
75 }
76 if let Some(sample_buffer) = sample_buffer.as_ref() {
77 let _ = encoder.sample_counters(sample_buffer, 0, false);
78 }
79 let _ = encoder.copy_buffer(&src, 0, &dst, 0, 64);
80 encoder.end_encoding();
81 blit.commit();
82 blit.wait_until_completed();
83 if let Some(sample_buffer) = sample_buffer.as_ref() {
84 println!(
85 "resolved counter bytes={}",
86 sample_buffer
87 .resolve_range(0..1)
88 .map_or(0, |bytes| bytes.len())
89 );
90 }
91
92 let library = device
93 .new_library_with_source(common::COMPUTE_SRC)
94 .expect("compile compute library");
95 let increment = library
96 .new_function("increment")
97 .expect("increment function");
98 let pipeline = device
99 .new_compute_pipeline_state(&increment)
100 .expect("compute pipeline");
101 let visible_table = pipeline.new_visible_function_table(1);
102 let intersection_table = if device.supports_raytracing() {
103 pipeline.new_intersection_function_table(1)
104 } else {
105 None
106 };
107 if let Some(table) = intersection_table.as_ref() {
108 table.set_opaque_triangle_intersection_function(intersection_function_signature::NONE, 0);
109 }
110 let acceleration_structure = if device.supports_raytracing() {
111 device.new_acceleration_structure_with_size(256)
112 } else {
113 None
114 };
115
116 let buffer = device
117 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
118 .expect("compute buffer");
119 common::write_u32_words(&buffer, &[1, 2, 3, 4]);
120 let texture = device
121 .new_texture(apple_metal::TextureDescriptor::new_2d(
122 4,
123 4,
124 apple_metal::pixel_format::BGRA8UNORM,
125 ))
126 .expect("compute texture");
127 let compute = queue.new_command_buffer().expect("compute command buffer");
128 let encoder = compute
129 .new_compute_command_encoder()
130 .expect("compute command encoder");
131 encoder.set_compute_pipeline_state(&pipeline);
132 encoder.set_buffer(&buffer, 0, 0);
133 encoder.set_texture(&texture, 1);
134 if let Some(fence) = fence_a.as_ref() {
135 encoder.wait_for_fence(fence);
136 }
137 if let Some(table) = visible_table.as_ref() {
138 encoder.set_visible_function_table(table, 2);
139 }
140 if let Some(table) = intersection_table.as_ref() {
141 encoder.set_intersection_function_table(table, 3);
142 }
143 if let Some(acceleration_structure) = acceleration_structure.as_ref() {
144 encoder.set_acceleration_structure(acceleration_structure, 4);
145 }
146 encoder.dispatch_threadgroups((1, 1, 1), (4, 1, 1));
147 if let Some(fence) = fence_b.as_ref() {
148 encoder.update_fence(fence);
149 }
150 encoder.end_encoding();
151 compute.commit();
152 compute.wait_until_completed();
153 println!(
154 "compute buffer after dispatch: {:?}",
155 common::read_u32_words(&buffer, 4)
156 );
157
158 if let Some(indirect) = device.new_indirect_command_buffer(
159 indirect_command_type::CONCURRENT_DISPATCH,
160 1,
161 0,
162 0,
163 4,
164 resource_options::STORAGE_MODE_PRIVATE,
165 ) {
166 indirect.reset_range(0..1);
167 println!("indirect command buffer size={}", indirect.size());
168 }
169
170 if let Some(heap) = device.new_heap(1 << 20, storage_mode::SHARED) {
171 if let Ok(residency_set) = device.new_residency_set(Some("example-residency"), 4) {
172 let heap_buffer = heap
173 .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
174 .expect("heap buffer");
175 residency_set.add_buffer(&heap_buffer);
176 residency_set.add_heap(&heap);
177 residency_set.commit();
178 residency_set.request_residency();
179 queue.add_residency_set(&residency_set);
180 queue.remove_residency_set(&residency_set);
181 residency_set.end_residency();
182 residency_set.remove_all_allocations();
183 residency_set.commit();
184 println!(
185 "residency allocation count={}",
186 residency_set.allocation_count()
187 );
188 } else {
189 println!("residency sets unavailable on this OS");
190 }
191 }
192
193 if let Some(capture_manager) = CaptureManager::shared() {
194 println!(
195 "capture supported for developer tools={} active={}",
196 capture_manager.supports_destination(capture_destination::DEVELOPER_TOOLS),
197 capture_manager.is_capturing(),
198 );
199 if let Some(scope) = capture_manager.new_capture_scope_with_device(&device) {
200 scope.begin();
201 scope.end();
202 }
203 if let Some(scope) = capture_manager.new_capture_scope_with_command_queue(&queue) {
204 scope.begin();
205 scope.end();
206 }
207 }
208}Trait Implementations§
Source§impl Drop for BlitCommandEncoder
impl Drop for BlitCommandEncoder
Auto Trait Implementations§
impl !Send for BlitCommandEncoder
impl !Sync for BlitCommandEncoder
impl Freeze for BlitCommandEncoder
impl RefUnwindSafe for BlitCommandEncoder
impl Unpin for BlitCommandEncoder
impl UnsafeUnpin for BlitCommandEncoder
impl UnwindSafe for BlitCommandEncoder
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