Skip to main content

MetalTexture

Struct MetalTexture 

Source
pub struct MetalTexture { /* private fields */ }
Expand description

Apple’s id<MTLTexture> — a GPU-resident 2D image.

Implementations§

Source§

impl MetalTexture

Source

pub fn depth(&self) -> usize

Texture depth in pixels.

Source

pub fn mipmap_level_count(&self) -> usize

Number of mipmap levels.

Source

pub fn array_length(&self) -> usize

Number of array slices.

Source

pub fn usage(&self) -> usize

MTLTextureUsage bitmask.

Examples found in repository?
examples/05_render_and_explicit_encoders.rs (line 125)
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}
Source

pub fn storage_mode(&self) -> usize

MTLStorageMode enum value.

Examples found in repository?
examples/05_render_and_explicit_encoders.rs (line 126)
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}
Source

pub fn replace_region_2d( &self, bytes: &[u8], bytes_per_row: usize, origin: (usize, usize), size: (usize, usize), mipmap_level: usize, ) -> bool

Upload bytes into a 2D region of the texture.

Examples found in repository?
examples/05_render_and_explicit_encoders.rs (line 115)
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}
Source

pub fn read_bytes_2d( &self, out: &mut [u8], bytes_per_row: usize, origin: (usize, usize), size: (usize, usize), mipmap_level: usize, ) -> bool

Read bytes from a 2D region of the texture into out.

Examples found in repository?
examples/05_render_and_explicit_encoders.rs (line 108)
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}
Source

pub fn new_view(&self, pixel_format: usize) -> Option<Self>

Create a texture view with a compatible pixel format.

Examples found in repository?
examples/05_render_and_explicit_encoders.rs (line 119)
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}
Source§

impl MetalTexture

Source

pub fn width(&self) -> usize

Texture width in pixels.

Examples found in repository?
examples/02_caps_buffer_texture.rs (line 33)
3fn main() {
4    let d = MetalDevice::system_default().expect("no Metal");
5    println!("unified memory: {}", d.has_unified_memory());
6    println!(
7        "recommended max working set: {} MB",
8        d.recommended_max_working_set_size() / (1024 * 1024)
9    );
10    println!("supports Metal3: {}", d.supports_family(gpu_family::METAL3));
11    println!("supports Apple7: {}", d.supports_family(gpu_family::APPLE7));
12
13    let buf = d
14        .new_buffer(4096, resource_options::STORAGE_MODE_SHARED)
15        .expect("buffer create failed");
16    println!(
17        "buffer {} bytes, contents={:?}",
18        buf.length(),
19        buf.contents().is_some()
20    );
21    let n = buf.write_bytes(b"hello metal");
22    println!("wrote {n} bytes");
23
24    let tx = d
25        .new_texture(TextureDescriptor::new_2d(
26            256,
27            256,
28            pixel_format::BGRA8UNORM,
29        ))
30        .expect("texture create failed");
31    println!(
32        "texture {}x{} fmt={}",
33        tx.width(),
34        tx.height(),
35        tx.pixel_format()
36    );
37}
More examples
Hide additional examples
examples/05_render_and_explicit_encoders.rs (line 123)
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}
examples/06_resources_and_archives.rs (line 56)
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 = queue
18        .new_command_buffer_with_unretained_references()
19        .expect("bounded scratch command buffer");
20    println!("bounded queue scratch status={}", scratch.status());
21
22    let library = device
23        .new_library_with_source(common::COMPUTE_SRC)
24        .expect("compile compute library");
25    let args = library.new_function("use_args").expect("use_args function");
26    let argument_encoder = args.new_argument_encoder(0).expect("argument encoder");
27    let argument_buffer = device
28        .new_buffer(
29            argument_encoder.encoded_length(),
30            resource_options::STORAGE_MODE_SHARED,
31        )
32        .expect("argument buffer");
33    let payload = device
34        .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
35        .expect("payload buffer");
36    let texture = device
37        .new_texture(TextureDescriptor::new_2d(4, 4, pixel_format::BGRA8UNORM))
38        .expect("argument texture");
39    argument_encoder.set_argument_buffer(&argument_buffer, 0);
40    argument_encoder.set_buffer(&payload, 0, 0);
41    argument_encoder.set_texture(&texture, 1);
42    println!(
43        "argument encoder length={} alignment={}",
44        argument_encoder.encoded_length(),
45        argument_encoder.alignment(),
46    );
47
48    let backing = device
49        .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
50        .expect("backing buffer");
51    let buffer_texture = backing
52        .new_texture_view_2d(pixel_format::BGRA8UNORM, 16, 4, 64, 0)
53        .expect("buffer-backed texture");
54    println!(
55        "buffer-backed texture {}x{} fmt={}",
56        buffer_texture.width(),
57        buffer_texture.height(),
58        buffer_texture.pixel_format(),
59    );
60
61    if let Some(heap) = device.new_heap(1 << 20, storage_mode::SHARED) {
62        let heap_buffer = heap
63            .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
64            .expect("heap buffer");
65        let heap_texture = heap
66            .new_texture(TextureDescriptor::new_2d(4, 4, pixel_format::BGRA8UNORM))
67            .expect("heap texture");
68        println!(
69            "heap size={} used={} current={} max_available={}",
70            heap.size(),
71            heap.used_size(),
72            heap.current_allocated_size(),
73            heap.max_available_size(256),
74        );
75        println!(
76            "heap buffer len={} heap texture {}x{} purgeable={}",
77            heap_buffer.length(),
78            heap_texture.width(),
79            heap_texture.height(),
80            heap.set_purgeable_state(apple_metal::purgeable_state::KEEP_CURRENT),
81        );
82    } else {
83        println!("heaps are unavailable on this device");
84    }
85
86    match device.new_log_state(log_level::INFO, 1_024) {
87        Ok(log_state) => {
88            let _ = device
89                .new_command_queue_with_log_state(4, &log_state)
90                .expect("log-state queue");
91            println!("created queue with log state");
92        }
93        Err(error) => println!("log state unavailable on this OS: {error}"),
94    }
95
96    if device.supports_dynamic_libraries() {
97        let dynamic_path = common::artifact_path("example-dylib.metallib");
98        let dynamic_library = device
99            .new_dynamic_library_with_source(
100                common::DYNAMIC_LIB_SRC,
101                dynamic_path.to_string_lossy().as_ref(),
102            )
103            .expect("dynamic library from source");
104        dynamic_library
105            .serialize_to_file(&dynamic_path)
106            .expect("serialize dynamic library");
107        let reloaded = device
108            .load_dynamic_library(&dynamic_path)
109            .expect("reload dynamic library");
110        println!("dynamic library install name: {}", reloaded.install_name());
111
112        let render_library = device
113            .new_library_with_source(common::RENDER_SRC)
114            .expect("compile render library");
115        let vertex = render_library
116            .new_function("fullscreen_vertex")
117            .expect("vertex function");
118        let fragment = render_library
119            .new_function("solid_fragment")
120            .expect("fragment function");
121        let increment = library
122            .new_function("increment")
123            .expect("increment function");
124
125        let archive_path = common::artifact_path("example-archive.metalarc");
126        let archive = device.new_binary_archive(None).expect("binary archive");
127        archive
128            .add_compute_function(&increment)
129            .expect("archive compute pipeline");
130        archive
131            .add_render_functions(&vertex, &fragment, pixel_format::BGRA8UNORM, 1)
132            .expect("archive render pipeline");
133        archive
134            .serialize_to_file(&archive_path)
135            .expect("serialize binary archive");
136        let _ = device
137            .new_binary_archive(Some(&archive_path))
138            .expect("reload binary archive");
139        println!("binary archive written to {}", archive_path.display());
140    } else {
141        println!("dynamic libraries unsupported; skipping archive serialization");
142    }
143}
Source

pub fn height(&self) -> usize

Texture height in pixels.

Examples found in repository?
examples/02_caps_buffer_texture.rs (line 34)
3fn main() {
4    let d = MetalDevice::system_default().expect("no Metal");
5    println!("unified memory: {}", d.has_unified_memory());
6    println!(
7        "recommended max working set: {} MB",
8        d.recommended_max_working_set_size() / (1024 * 1024)
9    );
10    println!("supports Metal3: {}", d.supports_family(gpu_family::METAL3));
11    println!("supports Apple7: {}", d.supports_family(gpu_family::APPLE7));
12
13    let buf = d
14        .new_buffer(4096, resource_options::STORAGE_MODE_SHARED)
15        .expect("buffer create failed");
16    println!(
17        "buffer {} bytes, contents={:?}",
18        buf.length(),
19        buf.contents().is_some()
20    );
21    let n = buf.write_bytes(b"hello metal");
22    println!("wrote {n} bytes");
23
24    let tx = d
25        .new_texture(TextureDescriptor::new_2d(
26            256,
27            256,
28            pixel_format::BGRA8UNORM,
29        ))
30        .expect("texture create failed");
31    println!(
32        "texture {}x{} fmt={}",
33        tx.width(),
34        tx.height(),
35        tx.pixel_format()
36    );
37}
More examples
Hide additional examples
examples/05_render_and_explicit_encoders.rs (line 124)
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}
examples/06_resources_and_archives.rs (line 57)
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 = queue
18        .new_command_buffer_with_unretained_references()
19        .expect("bounded scratch command buffer");
20    println!("bounded queue scratch status={}", scratch.status());
21
22    let library = device
23        .new_library_with_source(common::COMPUTE_SRC)
24        .expect("compile compute library");
25    let args = library.new_function("use_args").expect("use_args function");
26    let argument_encoder = args.new_argument_encoder(0).expect("argument encoder");
27    let argument_buffer = device
28        .new_buffer(
29            argument_encoder.encoded_length(),
30            resource_options::STORAGE_MODE_SHARED,
31        )
32        .expect("argument buffer");
33    let payload = device
34        .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
35        .expect("payload buffer");
36    let texture = device
37        .new_texture(TextureDescriptor::new_2d(4, 4, pixel_format::BGRA8UNORM))
38        .expect("argument texture");
39    argument_encoder.set_argument_buffer(&argument_buffer, 0);
40    argument_encoder.set_buffer(&payload, 0, 0);
41    argument_encoder.set_texture(&texture, 1);
42    println!(
43        "argument encoder length={} alignment={}",
44        argument_encoder.encoded_length(),
45        argument_encoder.alignment(),
46    );
47
48    let backing = device
49        .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
50        .expect("backing buffer");
51    let buffer_texture = backing
52        .new_texture_view_2d(pixel_format::BGRA8UNORM, 16, 4, 64, 0)
53        .expect("buffer-backed texture");
54    println!(
55        "buffer-backed texture {}x{} fmt={}",
56        buffer_texture.width(),
57        buffer_texture.height(),
58        buffer_texture.pixel_format(),
59    );
60
61    if let Some(heap) = device.new_heap(1 << 20, storage_mode::SHARED) {
62        let heap_buffer = heap
63            .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
64            .expect("heap buffer");
65        let heap_texture = heap
66            .new_texture(TextureDescriptor::new_2d(4, 4, pixel_format::BGRA8UNORM))
67            .expect("heap texture");
68        println!(
69            "heap size={} used={} current={} max_available={}",
70            heap.size(),
71            heap.used_size(),
72            heap.current_allocated_size(),
73            heap.max_available_size(256),
74        );
75        println!(
76            "heap buffer len={} heap texture {}x{} purgeable={}",
77            heap_buffer.length(),
78            heap_texture.width(),
79            heap_texture.height(),
80            heap.set_purgeable_state(apple_metal::purgeable_state::KEEP_CURRENT),
81        );
82    } else {
83        println!("heaps are unavailable on this device");
84    }
85
86    match device.new_log_state(log_level::INFO, 1_024) {
87        Ok(log_state) => {
88            let _ = device
89                .new_command_queue_with_log_state(4, &log_state)
90                .expect("log-state queue");
91            println!("created queue with log state");
92        }
93        Err(error) => println!("log state unavailable on this OS: {error}"),
94    }
95
96    if device.supports_dynamic_libraries() {
97        let dynamic_path = common::artifact_path("example-dylib.metallib");
98        let dynamic_library = device
99            .new_dynamic_library_with_source(
100                common::DYNAMIC_LIB_SRC,
101                dynamic_path.to_string_lossy().as_ref(),
102            )
103            .expect("dynamic library from source");
104        dynamic_library
105            .serialize_to_file(&dynamic_path)
106            .expect("serialize dynamic library");
107        let reloaded = device
108            .load_dynamic_library(&dynamic_path)
109            .expect("reload dynamic library");
110        println!("dynamic library install name: {}", reloaded.install_name());
111
112        let render_library = device
113            .new_library_with_source(common::RENDER_SRC)
114            .expect("compile render library");
115        let vertex = render_library
116            .new_function("fullscreen_vertex")
117            .expect("vertex function");
118        let fragment = render_library
119            .new_function("solid_fragment")
120            .expect("fragment function");
121        let increment = library
122            .new_function("increment")
123            .expect("increment function");
124
125        let archive_path = common::artifact_path("example-archive.metalarc");
126        let archive = device.new_binary_archive(None).expect("binary archive");
127        archive
128            .add_compute_function(&increment)
129            .expect("archive compute pipeline");
130        archive
131            .add_render_functions(&vertex, &fragment, pixel_format::BGRA8UNORM, 1)
132            .expect("archive render pipeline");
133        archive
134            .serialize_to_file(&archive_path)
135            .expect("serialize binary archive");
136        let _ = device
137            .new_binary_archive(Some(&archive_path))
138            .expect("reload binary archive");
139        println!("binary archive written to {}", archive_path.display());
140    } else {
141        println!("dynamic libraries unsupported; skipping archive serialization");
142    }
143}
Source

pub fn pixel_format(&self) -> usize

Underlying MTLPixelFormat enum value — see pixel_format.

Examples found in repository?
examples/02_caps_buffer_texture.rs (line 35)
3fn main() {
4    let d = MetalDevice::system_default().expect("no Metal");
5    println!("unified memory: {}", d.has_unified_memory());
6    println!(
7        "recommended max working set: {} MB",
8        d.recommended_max_working_set_size() / (1024 * 1024)
9    );
10    println!("supports Metal3: {}", d.supports_family(gpu_family::METAL3));
11    println!("supports Apple7: {}", d.supports_family(gpu_family::APPLE7));
12
13    let buf = d
14        .new_buffer(4096, resource_options::STORAGE_MODE_SHARED)
15        .expect("buffer create failed");
16    println!(
17        "buffer {} bytes, contents={:?}",
18        buf.length(),
19        buf.contents().is_some()
20    );
21    let n = buf.write_bytes(b"hello metal");
22    println!("wrote {n} bytes");
23
24    let tx = d
25        .new_texture(TextureDescriptor::new_2d(
26            256,
27            256,
28            pixel_format::BGRA8UNORM,
29        ))
30        .expect("texture create failed");
31    println!(
32        "texture {}x{} fmt={}",
33        tx.width(),
34        tx.height(),
35        tx.pixel_format()
36    );
37}
More examples
Hide additional examples
examples/06_resources_and_archives.rs (line 58)
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 = queue
18        .new_command_buffer_with_unretained_references()
19        .expect("bounded scratch command buffer");
20    println!("bounded queue scratch status={}", scratch.status());
21
22    let library = device
23        .new_library_with_source(common::COMPUTE_SRC)
24        .expect("compile compute library");
25    let args = library.new_function("use_args").expect("use_args function");
26    let argument_encoder = args.new_argument_encoder(0).expect("argument encoder");
27    let argument_buffer = device
28        .new_buffer(
29            argument_encoder.encoded_length(),
30            resource_options::STORAGE_MODE_SHARED,
31        )
32        .expect("argument buffer");
33    let payload = device
34        .new_buffer(16, resource_options::STORAGE_MODE_SHARED)
35        .expect("payload buffer");
36    let texture = device
37        .new_texture(TextureDescriptor::new_2d(4, 4, pixel_format::BGRA8UNORM))
38        .expect("argument texture");
39    argument_encoder.set_argument_buffer(&argument_buffer, 0);
40    argument_encoder.set_buffer(&payload, 0, 0);
41    argument_encoder.set_texture(&texture, 1);
42    println!(
43        "argument encoder length={} alignment={}",
44        argument_encoder.encoded_length(),
45        argument_encoder.alignment(),
46    );
47
48    let backing = device
49        .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
50        .expect("backing buffer");
51    let buffer_texture = backing
52        .new_texture_view_2d(pixel_format::BGRA8UNORM, 16, 4, 64, 0)
53        .expect("buffer-backed texture");
54    println!(
55        "buffer-backed texture {}x{} fmt={}",
56        buffer_texture.width(),
57        buffer_texture.height(),
58        buffer_texture.pixel_format(),
59    );
60
61    if let Some(heap) = device.new_heap(1 << 20, storage_mode::SHARED) {
62        let heap_buffer = heap
63            .new_buffer(256, resource_options::STORAGE_MODE_SHARED)
64            .expect("heap buffer");
65        let heap_texture = heap
66            .new_texture(TextureDescriptor::new_2d(4, 4, pixel_format::BGRA8UNORM))
67            .expect("heap texture");
68        println!(
69            "heap size={} used={} current={} max_available={}",
70            heap.size(),
71            heap.used_size(),
72            heap.current_allocated_size(),
73            heap.max_available_size(256),
74        );
75        println!(
76            "heap buffer len={} heap texture {}x{} purgeable={}",
77            heap_buffer.length(),
78            heap_texture.width(),
79            heap_texture.height(),
80            heap.set_purgeable_state(apple_metal::purgeable_state::KEEP_CURRENT),
81        );
82    } else {
83        println!("heaps are unavailable on this device");
84    }
85
86    match device.new_log_state(log_level::INFO, 1_024) {
87        Ok(log_state) => {
88            let _ = device
89                .new_command_queue_with_log_state(4, &log_state)
90                .expect("log-state queue");
91            println!("created queue with log state");
92        }
93        Err(error) => println!("log state unavailable on this OS: {error}"),
94    }
95
96    if device.supports_dynamic_libraries() {
97        let dynamic_path = common::artifact_path("example-dylib.metallib");
98        let dynamic_library = device
99            .new_dynamic_library_with_source(
100                common::DYNAMIC_LIB_SRC,
101                dynamic_path.to_string_lossy().as_ref(),
102            )
103            .expect("dynamic library from source");
104        dynamic_library
105            .serialize_to_file(&dynamic_path)
106            .expect("serialize dynamic library");
107        let reloaded = device
108            .load_dynamic_library(&dynamic_path)
109            .expect("reload dynamic library");
110        println!("dynamic library install name: {}", reloaded.install_name());
111
112        let render_library = device
113            .new_library_with_source(common::RENDER_SRC)
114            .expect("compile render library");
115        let vertex = render_library
116            .new_function("fullscreen_vertex")
117            .expect("vertex function");
118        let fragment = render_library
119            .new_function("solid_fragment")
120            .expect("fragment function");
121        let increment = library
122            .new_function("increment")
123            .expect("increment function");
124
125        let archive_path = common::artifact_path("example-archive.metalarc");
126        let archive = device.new_binary_archive(None).expect("binary archive");
127        archive
128            .add_compute_function(&increment)
129            .expect("archive compute pipeline");
130        archive
131            .add_render_functions(&vertex, &fragment, pixel_format::BGRA8UNORM, 1)
132            .expect("archive render pipeline");
133        archive
134            .serialize_to_file(&archive_path)
135            .expect("serialize binary archive");
136        let _ = device
137            .new_binary_archive(Some(&archive_path))
138            .expect("reload binary archive");
139        println!("binary archive written to {}", archive_path.display());
140    } else {
141        println!("dynamic libraries unsupported; skipping archive serialization");
142    }
143}
Source

pub const fn as_ptr(&self) -> *mut c_void

Raw id<MTLTexture> pointer.

Source

pub const unsafe fn from_raw(ptr: *mut c_void) -> Self

Wrap a raw, +1-retained id<MTLTexture> pointer. Ownership is transferred to the returned wrapper and released once on drop (no extra retain is taken here).

§Safety

ptr must be a valid id<MTLTexture> whose ownership the caller is transferring.

Trait Implementations§

Source§

impl Drop for MetalTexture

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more
Source§

impl Send for MetalTexture

Source§

impl Sync for MetalTexture

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.