Skip to main content

05_render_and_explicit_encoders/common/
mod.rs

1#![allow(dead_code)]
2
3use apple_metal::{pixel_format, storage_mode, texture_usage, MetalBuffer, TextureDescriptor};
4use std::fs;
5use std::path::PathBuf;
6
7pub const COMPUTE_SRC: &str = r"
8#include <metal_stdlib>
9using namespace metal;
10
11struct Args {
12    device uint *buffer;
13    texture2d<float> texture;
14};
15
16kernel void increment(device uint *data [[buffer(0)]],
17                      uint gid [[thread_position_in_grid]]) {
18    if (gid < 4) {
19        data[gid] += 1;
20    }
21}
22
23kernel void use_args(constant Args &args [[buffer(0)]],
24                     uint gid [[thread_position_in_grid]]) {
25    if (gid == 0) {
26        args.buffer[0] = 7;
27    }
28}
29";
30
31pub const RENDER_SRC: &str = r"
32#include <metal_stdlib>
33using namespace metal;
34
35struct VertexOut {
36    float4 position [[position]];
37};
38
39vertex VertexOut fullscreen_vertex(uint vertex_id [[vertex_id]]) {
40    float2 positions[3] = {
41        float2(-1.0, -1.0),
42        float2( 3.0, -1.0),
43        float2(-1.0,  3.0)
44    };
45
46    VertexOut out;
47    out.position = float4(positions[vertex_id], 0.0, 1.0);
48    return out;
49}
50
51fragment float4 solid_fragment() {
52    return float4(0.2, 0.4, 0.8, 1.0);
53}
54";
55
56pub const DYNAMIC_LIB_SRC: &str = r"
57#include <metal_stdlib>
58using namespace metal;
59
60kernel void dynamic_noop(device uint *data [[buffer(0)]],
61                         uint gid [[thread_position_in_grid]]) {
62    if (gid == 0) {
63        data[gid] += 1;
64    }
65}
66";
67
68pub fn artifact_path(name: &str) -> PathBuf {
69    let mut dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
70    dir.push("target");
71    dir.push("apple-metal-example-artifacts");
72    fs::create_dir_all(&dir).expect("create example artifact dir");
73    let mut path = dir;
74    path.push(name);
75    let _ = fs::remove_file(&path);
76    path
77}
78
79pub fn write_u32_words(buffer: &MetalBuffer, data: &[u32]) {
80    let words = unsafe {
81        core::slice::from_raw_parts_mut(
82            buffer
83                .contents()
84                .expect("shared buffer contents")
85                .cast::<u32>(),
86            data.len(),
87        )
88    };
89    words.copy_from_slice(data);
90}
91
92pub fn read_u32_words(buffer: &MetalBuffer, len: usize) -> Vec<u32> {
93    unsafe {
94        core::slice::from_raw_parts(
95            buffer
96                .contents()
97                .expect("shared buffer contents")
98                .cast::<u32>(),
99            len,
100        )
101        .to_vec()
102    }
103}
104
105pub const fn shared_render_target(width: usize, height: usize) -> TextureDescriptor {
106    let mut descriptor =
107        TextureDescriptor::render_target_2d(width, height, pixel_format::BGRA8UNORM);
108    descriptor.storage_mode = storage_mode::SHARED;
109    descriptor.usage = texture_usage::RENDER_TARGET | texture_usage::SHADER_READ;
110    descriptor
111}