pub struct ArgumentEncoder { /* private fields */ }Expand description
Re-exports the Metal framework surface for this item.
Apple’s id<MTLArgumentEncoder> with an explicit active binding.
Implementations§
Source§impl ArgumentEncoder
impl ArgumentEncoder
Sourcepub fn encoded_length(&self) -> usize
pub fn encoded_length(&self) -> usize
Number of bytes required to encode the argument layout.
Examples found in repository?
examples/06_resources_and_archives.rs (line 31)
10fn main() {
11 let device = MetalDevice::system_default().expect("Metal device available");
12 println!("device: {}", device.name());
13
14 let queue = device
15 .new_command_queue_with_max_command_buffer_count(4)
16 .expect("bounded command queue");
17 let scratch = unsafe {
18 queue
19 .new_command_buffer_with_unretained_references()
20 .expect("bounded scratch command buffer")
21 };
22 println!("bounded queue scratch status={}", scratch.status());
23
24 let library = device
25 .new_library_with_source(common::COMPUTE_SRC)
26 .expect("compile compute library");
27 let args = library.new_function("use_args").expect("use_args function");
28 let mut argument_encoder = args.new_argument_encoder(0).expect("argument encoder");
29 let argument_buffer = device
30 .new_buffer(
31 argument_encoder.encoded_length(),
32 resource_options::STORAGE_MODE_SHARED,
33 )
34 .expect("argument buffer");
35 let payload = device
36 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
37 .expect("payload buffer");
38 let texture = device
39 .new_texture(TextureDescriptor::new_2d(4, 4, pixel_format::BGRA8UNORM))
40 .expect("argument texture");
41 unsafe {
42 let mut binding = argument_encoder
43 .bind_argument_buffer(&argument_buffer, 0)
44 .expect("bind argument buffer");
45 binding
46 .set_buffer_unchecked(&payload, 0, 0)
47 .expect("bind payload");
48 binding
49 .set_texture_unchecked(&texture, 1)
50 .expect("bind texture");
51 }
52 println!(
53 "argument encoder length={} alignment={}",
54 argument_encoder.encoded_length(),
55 argument_encoder.alignment(),
56 );
57
58 let backing = device
59 .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
60 .expect("backing buffer");
61 let buffer_texture = backing
62 .new_texture_view_2d(pixel_format::BGRA8UNORM, 16, 4, 64, 0)
63 .expect("buffer-backed texture");
64 println!(
65 "buffer-backed texture {}x{} fmt={}",
66 buffer_texture.width(),
67 buffer_texture.height(),
68 buffer_texture.pixel_format(),
69 );
70
71 if let Some(heap) = device.new_heap(1 << 20, storage_mode::SHARED) {
72 let heap_buffer = heap
73 .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
74 .expect("heap buffer");
75 let heap_texture = heap
76 .new_texture(TextureDescriptor::new_2d(4, 4, pixel_format::BGRA8UNORM))
77 .expect("heap texture");
78 println!(
79 "heap size={} used={} current={} max_available={}",
80 heap.size(),
81 heap.used_size(),
82 heap.current_allocated_size(),
83 heap.max_available_size(256),
84 );
85 println!(
86 "heap buffer len={} heap texture {}x{} purgeable={}",
87 heap_buffer.length(),
88 heap_texture.width(),
89 heap_texture.height(),
90 heap.set_purgeable_state(apple_metal::purgeable_state::KEEP_CURRENT),
91 );
92 } else {
93 println!("heaps are unavailable on this device");
94 }
95
96 match device.new_log_state(log_level::INFO, 1_024) {
97 Ok(log_state) => {
98 let _ = device
99 .new_command_queue_with_log_state(4, &log_state)
100 .expect("log-state queue");
101 println!("created queue with log state");
102 }
103 Err(error) => println!("log state unavailable on this OS: {error}"),
104 }
105
106 if device.supports_dynamic_libraries() {
107 let dynamic_path = common::artifact_path("example-dylib.metallib");
108 let dynamic_library = device
109 .new_dynamic_library_with_source(
110 common::DYNAMIC_LIB_SRC,
111 dynamic_path.to_string_lossy().as_ref(),
112 )
113 .expect("dynamic library from source");
114 dynamic_library
115 .serialize_to_file(&dynamic_path)
116 .expect("serialize dynamic library");
117 let reloaded = device
118 .load_dynamic_library(&dynamic_path)
119 .expect("reload dynamic library");
120 println!("dynamic library install name: {}", reloaded.install_name());
121
122 let render_library = device
123 .new_library_with_source(common::RENDER_SRC)
124 .expect("compile render library");
125 let vertex = render_library
126 .new_function("fullscreen_vertex")
127 .expect("vertex function");
128 let fragment = render_library
129 .new_function("solid_fragment")
130 .expect("fragment function");
131 let increment = library
132 .new_function("increment")
133 .expect("increment function");
134
135 let archive_path = common::artifact_path("example-archive.metalarc");
136 let archive = device.new_binary_archive(None).expect("binary archive");
137 archive
138 .add_compute_function(&increment)
139 .expect("archive compute pipeline");
140 archive
141 .add_render_functions(&vertex, &fragment, pixel_format::BGRA8UNORM, 1)
142 .expect("archive render pipeline");
143 archive
144 .serialize_to_file(&archive_path)
145 .expect("serialize binary archive");
146 let _ = device
147 .new_binary_archive(Some(&archive_path))
148 .expect("reload binary archive");
149 println!("binary archive written to {}", archive_path.display());
150 } else {
151 println!("dynamic libraries unsupported; skipping archive serialization");
152 }
153}Sourcepub fn alignment(&self) -> usize
pub fn alignment(&self) -> usize
Required alignment for the encoded argument data.
Examples found in repository?
examples/06_resources_and_archives.rs (line 55)
10fn main() {
11 let device = MetalDevice::system_default().expect("Metal device available");
12 println!("device: {}", device.name());
13
14 let queue = device
15 .new_command_queue_with_max_command_buffer_count(4)
16 .expect("bounded command queue");
17 let scratch = unsafe {
18 queue
19 .new_command_buffer_with_unretained_references()
20 .expect("bounded scratch command buffer")
21 };
22 println!("bounded queue scratch status={}", scratch.status());
23
24 let library = device
25 .new_library_with_source(common::COMPUTE_SRC)
26 .expect("compile compute library");
27 let args = library.new_function("use_args").expect("use_args function");
28 let mut argument_encoder = args.new_argument_encoder(0).expect("argument encoder");
29 let argument_buffer = device
30 .new_buffer(
31 argument_encoder.encoded_length(),
32 resource_options::STORAGE_MODE_SHARED,
33 )
34 .expect("argument buffer");
35 let payload = device
36 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
37 .expect("payload buffer");
38 let texture = device
39 .new_texture(TextureDescriptor::new_2d(4, 4, pixel_format::BGRA8UNORM))
40 .expect("argument texture");
41 unsafe {
42 let mut binding = argument_encoder
43 .bind_argument_buffer(&argument_buffer, 0)
44 .expect("bind argument buffer");
45 binding
46 .set_buffer_unchecked(&payload, 0, 0)
47 .expect("bind payload");
48 binding
49 .set_texture_unchecked(&texture, 1)
50 .expect("bind texture");
51 }
52 println!(
53 "argument encoder length={} alignment={}",
54 argument_encoder.encoded_length(),
55 argument_encoder.alignment(),
56 );
57
58 let backing = device
59 .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
60 .expect("backing buffer");
61 let buffer_texture = backing
62 .new_texture_view_2d(pixel_format::BGRA8UNORM, 16, 4, 64, 0)
63 .expect("buffer-backed texture");
64 println!(
65 "buffer-backed texture {}x{} fmt={}",
66 buffer_texture.width(),
67 buffer_texture.height(),
68 buffer_texture.pixel_format(),
69 );
70
71 if let Some(heap) = device.new_heap(1 << 20, storage_mode::SHARED) {
72 let heap_buffer = heap
73 .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
74 .expect("heap buffer");
75 let heap_texture = heap
76 .new_texture(TextureDescriptor::new_2d(4, 4, pixel_format::BGRA8UNORM))
77 .expect("heap texture");
78 println!(
79 "heap size={} used={} current={} max_available={}",
80 heap.size(),
81 heap.used_size(),
82 heap.current_allocated_size(),
83 heap.max_available_size(256),
84 );
85 println!(
86 "heap buffer len={} heap texture {}x{} purgeable={}",
87 heap_buffer.length(),
88 heap_texture.width(),
89 heap_texture.height(),
90 heap.set_purgeable_state(apple_metal::purgeable_state::KEEP_CURRENT),
91 );
92 } else {
93 println!("heaps are unavailable on this device");
94 }
95
96 match device.new_log_state(log_level::INFO, 1_024) {
97 Ok(log_state) => {
98 let _ = device
99 .new_command_queue_with_log_state(4, &log_state)
100 .expect("log-state queue");
101 println!("created queue with log state");
102 }
103 Err(error) => println!("log state unavailable on this OS: {error}"),
104 }
105
106 if device.supports_dynamic_libraries() {
107 let dynamic_path = common::artifact_path("example-dylib.metallib");
108 let dynamic_library = device
109 .new_dynamic_library_with_source(
110 common::DYNAMIC_LIB_SRC,
111 dynamic_path.to_string_lossy().as_ref(),
112 )
113 .expect("dynamic library from source");
114 dynamic_library
115 .serialize_to_file(&dynamic_path)
116 .expect("serialize dynamic library");
117 let reloaded = device
118 .load_dynamic_library(&dynamic_path)
119 .expect("reload dynamic library");
120 println!("dynamic library install name: {}", reloaded.install_name());
121
122 let render_library = device
123 .new_library_with_source(common::RENDER_SRC)
124 .expect("compile render library");
125 let vertex = render_library
126 .new_function("fullscreen_vertex")
127 .expect("vertex function");
128 let fragment = render_library
129 .new_function("solid_fragment")
130 .expect("fragment function");
131 let increment = library
132 .new_function("increment")
133 .expect("increment function");
134
135 let archive_path = common::artifact_path("example-archive.metalarc");
136 let archive = device.new_binary_archive(None).expect("binary archive");
137 archive
138 .add_compute_function(&increment)
139 .expect("archive compute pipeline");
140 archive
141 .add_render_functions(&vertex, &fragment, pixel_format::BGRA8UNORM, 1)
142 .expect("archive render pipeline");
143 archive
144 .serialize_to_file(&archive_path)
145 .expect("serialize binary archive");
146 let _ = device
147 .new_binary_archive(Some(&archive_path))
148 .expect("reload binary archive");
149 println!("binary archive written to {}", archive_path.display());
150 } else {
151 println!("dynamic libraries unsupported; skipping archive serialization");
152 }
153}Sourcepub unsafe fn bind_argument_buffer<'a>(
&'a mut self,
buffer: &'a MetalBuffer,
offset: usize,
) -> Result<ArgumentBufferBinding<'a>, ArgumentEncoderError>
pub unsafe fn bind_argument_buffer<'a>( &'a mut self, buffer: &'a MetalBuffer, offset: usize, ) -> Result<ArgumentBufferBinding<'a>, ArgumentEncoderError>
Bind a destination argument buffer for a scoped sequence of setters.
Managed storage is marked modified when the returned guard is dropped.
§Safety
The caller must exclude all GPU access to the encoded byte range until the returned binding guard is dropped, and must not submit GPU work that uses the argument buffer until then. Once a dispatch or draw references this argument buffer, its bindings must not change until that command buffer completes because resource declarations are captured while the command is encoded.
Examples found in repository?
examples/06_resources_and_archives.rs (line 43)
10fn main() {
11 let device = MetalDevice::system_default().expect("Metal device available");
12 println!("device: {}", device.name());
13
14 let queue = device
15 .new_command_queue_with_max_command_buffer_count(4)
16 .expect("bounded command queue");
17 let scratch = unsafe {
18 queue
19 .new_command_buffer_with_unretained_references()
20 .expect("bounded scratch command buffer")
21 };
22 println!("bounded queue scratch status={}", scratch.status());
23
24 let library = device
25 .new_library_with_source(common::COMPUTE_SRC)
26 .expect("compile compute library");
27 let args = library.new_function("use_args").expect("use_args function");
28 let mut argument_encoder = args.new_argument_encoder(0).expect("argument encoder");
29 let argument_buffer = device
30 .new_buffer(
31 argument_encoder.encoded_length(),
32 resource_options::STORAGE_MODE_SHARED,
33 )
34 .expect("argument buffer");
35 let payload = device
36 .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
37 .expect("payload buffer");
38 let texture = device
39 .new_texture(TextureDescriptor::new_2d(4, 4, pixel_format::BGRA8UNORM))
40 .expect("argument texture");
41 unsafe {
42 let mut binding = argument_encoder
43 .bind_argument_buffer(&argument_buffer, 0)
44 .expect("bind argument buffer");
45 binding
46 .set_buffer_unchecked(&payload, 0, 0)
47 .expect("bind payload");
48 binding
49 .set_texture_unchecked(&texture, 1)
50 .expect("bind texture");
51 }
52 println!(
53 "argument encoder length={} alignment={}",
54 argument_encoder.encoded_length(),
55 argument_encoder.alignment(),
56 );
57
58 let backing = device
59 .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
60 .expect("backing buffer");
61 let buffer_texture = backing
62 .new_texture_view_2d(pixel_format::BGRA8UNORM, 16, 4, 64, 0)
63 .expect("buffer-backed texture");
64 println!(
65 "buffer-backed texture {}x{} fmt={}",
66 buffer_texture.width(),
67 buffer_texture.height(),
68 buffer_texture.pixel_format(),
69 );
70
71 if let Some(heap) = device.new_heap(1 << 20, storage_mode::SHARED) {
72 let heap_buffer = heap
73 .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
74 .expect("heap buffer");
75 let heap_texture = heap
76 .new_texture(TextureDescriptor::new_2d(4, 4, pixel_format::BGRA8UNORM))
77 .expect("heap texture");
78 println!(
79 "heap size={} used={} current={} max_available={}",
80 heap.size(),
81 heap.used_size(),
82 heap.current_allocated_size(),
83 heap.max_available_size(256),
84 );
85 println!(
86 "heap buffer len={} heap texture {}x{} purgeable={}",
87 heap_buffer.length(),
88 heap_texture.width(),
89 heap_texture.height(),
90 heap.set_purgeable_state(apple_metal::purgeable_state::KEEP_CURRENT),
91 );
92 } else {
93 println!("heaps are unavailable on this device");
94 }
95
96 match device.new_log_state(log_level::INFO, 1_024) {
97 Ok(log_state) => {
98 let _ = device
99 .new_command_queue_with_log_state(4, &log_state)
100 .expect("log-state queue");
101 println!("created queue with log state");
102 }
103 Err(error) => println!("log state unavailable on this OS: {error}"),
104 }
105
106 if device.supports_dynamic_libraries() {
107 let dynamic_path = common::artifact_path("example-dylib.metallib");
108 let dynamic_library = device
109 .new_dynamic_library_with_source(
110 common::DYNAMIC_LIB_SRC,
111 dynamic_path.to_string_lossy().as_ref(),
112 )
113 .expect("dynamic library from source");
114 dynamic_library
115 .serialize_to_file(&dynamic_path)
116 .expect("serialize dynamic library");
117 let reloaded = device
118 .load_dynamic_library(&dynamic_path)
119 .expect("reload dynamic library");
120 println!("dynamic library install name: {}", reloaded.install_name());
121
122 let render_library = device
123 .new_library_with_source(common::RENDER_SRC)
124 .expect("compile render library");
125 let vertex = render_library
126 .new_function("fullscreen_vertex")
127 .expect("vertex function");
128 let fragment = render_library
129 .new_function("solid_fragment")
130 .expect("fragment function");
131 let increment = library
132 .new_function("increment")
133 .expect("increment function");
134
135 let archive_path = common::artifact_path("example-archive.metalarc");
136 let archive = device.new_binary_archive(None).expect("binary archive");
137 archive
138 .add_compute_function(&increment)
139 .expect("archive compute pipeline");
140 archive
141 .add_render_functions(&vertex, &fragment, pixel_format::BGRA8UNORM, 1)
142 .expect("archive render pipeline");
143 archive
144 .serialize_to_file(&archive_path)
145 .expect("serialize binary archive");
146 let _ = device
147 .new_binary_archive(Some(&archive_path))
148 .expect("reload binary archive");
149 println!("binary archive written to {}", archive_path.display());
150 } else {
151 println!("dynamic libraries unsupported; skipping archive serialization");
152 }
153}Trait Implementations§
Source§impl Drop for ArgumentEncoder
impl Drop for ArgumentEncoder
impl Send for ArgumentEncoder
Auto Trait Implementations§
impl !Sync for ArgumentEncoder
impl Freeze for ArgumentEncoder
impl RefUnwindSafe for ArgumentEncoder
impl Unpin for ArgumentEncoder
impl UnsafeUnpin for ArgumentEncoder
impl UnwindSafe for ArgumentEncoder
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