05_render_and_explicit_encoders/common/
mod.rs1#![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}