summaryrefslogtreecommitdiff
path: root/src/renderer/metal/Sampler.zig
blob: 0f4de8848462944cbc7f3846670c891595c4807b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//! Wrapper for handling samplers.
const Self = @This();

const std = @import("std");
const Allocator = std.mem.Allocator;
const assert = std.debug.assert;
const builtin = @import("builtin");
const objc = @import("objc");

const mtl = @import("api.zig");
const Metal = @import("../Metal.zig");

const log = std.log.scoped(.metal);

/// Options for initializing a sampler.
pub const Options = struct {
    /// MTLDevice
    device: objc.Object,
    min_filter: mtl.MTLSamplerMinMagFilter,
    mag_filter: mtl.MTLSamplerMinMagFilter,
    s_address_mode: mtl.MTLSamplerAddressMode,
    t_address_mode: mtl.MTLSamplerAddressMode,
};

/// The underlying MTLSamplerState Object.
sampler: objc.Object,

pub const Error = error{
    /// A Metal API call failed.
    MetalFailed,
};

/// Initialize a sampler
pub fn init(
    opts: Options,
) Error!Self {
    // Create our descriptor
    const desc = init: {
        const Class = objc.getClass("MTLSamplerDescriptor").?;
        const id_alloc = Class.msgSend(objc.Object, objc.sel("alloc"), .{});
        const id_init = id_alloc.msgSend(objc.Object, objc.sel("init"), .{});
        break :init id_init;
    };
    defer desc.release();

    // Properties
    desc.setProperty("minFilter", opts.min_filter);
    desc.setProperty("magFilter", opts.mag_filter);
    desc.setProperty("sAddressMode", opts.s_address_mode);
    desc.setProperty("tAddressMode", opts.t_address_mode);

    // Create the sampler state
    const id = opts.device.msgSend(
        ?*anyopaque,
        objc.sel("newSamplerStateWithDescriptor:"),
        .{desc},
    ) orelse return error.MetalFailed;

    return .{
        .sampler = objc.Object.fromId(id),
    };
}

pub fn deinit(self: Self) void {
    self.sampler.release();
}