Compare commits
9 Commits
94c08ff3b6
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 8a8b84a730 | |||
| c5c6c61251 | |||
| 99b8cf1d8e | |||
| af5f035830 | |||
| af8d725e0c | |||
| ff87d58319 | |||
| 70076f2268 | |||
| 8dbac71007 | |||
| c14fc89c74 |
@@ -114,5 +114,3 @@ typedef uint64_t uintptr_t;
|
|||||||
|
|
||||||
#define WCHAR_MIN (0)
|
#define WCHAR_MIN (0)
|
||||||
#define WCHAR_MAX (0x10FFFF)
|
#define WCHAR_MAX (0x10FFFF)
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ pub fn isCompatible(comptime ZigType: type, c_type: Type) bool {
|
|||||||
.unsigned_long => zig_int.signedness == .unsigned and zig_int.bits == 64,
|
.unsigned_long => zig_int.signedness == .unsigned and zig_int.bits == 64,
|
||||||
.unsigned_long_long => zig_int.signedness == .unsigned and zig_int.bits == 64,
|
.unsigned_long_long => zig_int.signedness == .unsigned and zig_int.bits == 64,
|
||||||
|
|
||||||
.char => zig_int.bits = 8,
|
.char => zig_int.bits == 8,
|
||||||
|
|
||||||
else => false,
|
else => false,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -17,8 +17,11 @@ pub fn build(b: *std.Build) void {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
mod.addCSourceFile(.{
|
mod.addCSourceFiles(.{
|
||||||
.file = b.path("src/stbi/stb_image.c"),
|
.files = &.{
|
||||||
|
"src/stbi/stb_image.c",
|
||||||
|
"src/stbtt/stb_truetype.c",
|
||||||
|
},
|
||||||
.flags = &.{
|
.flags = &.{
|
||||||
"-std=c17",
|
"-std=c17",
|
||||||
"-Wall",
|
"-Wall",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
.{
|
.{
|
||||||
.name = .media,
|
.name = .media,
|
||||||
.version = "0.0.0",
|
.version = "0.0.0",
|
||||||
.minimum_zig_version = "0.16.0",
|
.minimum_zig_version = "0.17.0",
|
||||||
.paths = .{
|
.paths = .{
|
||||||
"src",
|
"src",
|
||||||
"build.zig",
|
"build.zig",
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
|
const Crc = std.hash.crc.@"CRC-32/ISO-HDLC";
|
||||||
const Format = @import("Format.zig");
|
const Format = @import("Format.zig");
|
||||||
|
|
||||||
pub const format: Format = .{
|
pub const format: Format = .{
|
||||||
@@ -72,11 +73,11 @@ pub const Header = struct {
|
|||||||
return .{
|
return .{
|
||||||
.width = width,
|
.width = width,
|
||||||
.height = height,
|
.height = height,
|
||||||
.bit_depth = @enumFromInt(bit_depth),
|
.bit_depth = @fromBackingInt(bit_depth),
|
||||||
.color_type = @enumFromInt(color_type),
|
.color_type = @fromBackingInt(color_type),
|
||||||
.compression_method = @enumFromInt(compression_method),
|
.compression_method = @fromBackingInt(compression_method),
|
||||||
.filter_method = @enumFromInt(filter_method),
|
.filter_method = @fromBackingInt(filter_method),
|
||||||
.interlace_method = @enumFromInt(interlace_method),
|
.interlace_method = @fromBackingInt(interlace_method),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +94,7 @@ pub const BitDepth = enum(u8) {
|
|||||||
@"16" = 16,
|
@"16" = 16,
|
||||||
|
|
||||||
pub fn range(self: BitDepth) usize {
|
pub fn range(self: BitDepth) usize {
|
||||||
return @as(usize, 2) << @intCast(@intFromEnum(self));
|
return @as(usize, 2) << @intCast(@backingInt(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
test "refAllDecls" {
|
test "refAllDecls" {
|
||||||
@@ -109,15 +110,15 @@ pub const ColorType = enum(u8) {
|
|||||||
rgba = 6,
|
rgba = 6,
|
||||||
|
|
||||||
pub fn paletteUsed(self: ColorType) bool {
|
pub fn paletteUsed(self: ColorType) bool {
|
||||||
return @intFromEnum(self) & 0b0000_0001 != 0;
|
return @backingInt(self) & 0b0000_0001 != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn colorUsed(self: ColorType) bool {
|
pub fn colorUsed(self: ColorType) bool {
|
||||||
return @intFromEnum(self) & 0b0000_0010 != 0;
|
return @backingInt(self) & 0b0000_0010 != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alphaChannelUsed(self: ColorType) bool {
|
pub fn alphaChannelUsed(self: ColorType) bool {
|
||||||
return @intFromEnum(self) & 0b0000_0100 != 0;
|
return @backingInt(self) & 0b0000_0100 != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
test "refAllDecls" {
|
test "refAllDecls" {
|
||||||
@@ -331,7 +332,7 @@ const RenderingIntent = enum(u8) {
|
|||||||
if (chunk.data.len != 1) return error.InvalidPng;
|
if (chunk.data.len != 1) return error.InvalidPng;
|
||||||
const rendering_intent = chunk.data[0];
|
const rendering_intent = chunk.data[0];
|
||||||
if (rendering_intent > 3) return error.InvalidPng;
|
if (rendering_intent > 3) return error.InvalidPng;
|
||||||
return @enumFromInt(rendering_intent);
|
return @fromBackingInt(rendering_intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "refAllDecls" {
|
test "refAllDecls" {
|
||||||
@@ -361,7 +362,7 @@ pub const PhysicalPixelDimensions = struct {
|
|||||||
return .{
|
return .{
|
||||||
.pixels_per_unit_x = pixels_per_unit_x,
|
.pixels_per_unit_x = pixels_per_unit_x,
|
||||||
.pixels_per_unit_y = pixels_per_unit_y,
|
.pixels_per_unit_y = pixels_per_unit_y,
|
||||||
.unit = @enumFromInt(unit),
|
.unit = @fromBackingInt(unit),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -451,26 +452,26 @@ pub const ChunkType = enum(u32) {
|
|||||||
_,
|
_,
|
||||||
|
|
||||||
fn fromName(name: *const [4]u8) u32 {
|
fn fromName(name: *const [4]u8) u32 {
|
||||||
return @bitCast(name.*);
|
return std.mem.bytesToValue(u32, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fromBytes(bytes: *const [4]u8) ChunkType {
|
pub fn fromBytes(bytes: *const [4]u8) ChunkType {
|
||||||
return @enumFromInt(fromName(bytes));
|
return @fromBackingInt(fromName(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn toBytes(self: ChunkType) [4]u8 {
|
pub fn toBytes(self: ChunkType) [4]u8 {
|
||||||
return @bitCast(@intFromEnum(self));
|
return std.mem.toBytes(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ancillary(self: ChunkType) bool {
|
pub fn isAncillary(self: ChunkType) bool {
|
||||||
return self.toBytes()[0] & 0b0010_0000 != 0;
|
return self.toBytes()[0] & 0b0010_0000 != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn private(self: ChunkType) bool {
|
pub fn isPrivate(self: ChunkType) bool {
|
||||||
return self.toBytes()[1] & 0b0010_0000 != 0;
|
return self.toBytes()[1] & 0b0010_0000 != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn safeToCopy(self: ChunkType) bool {
|
pub fn isSafeToCopy(self: ChunkType) bool {
|
||||||
return self.toBytes()[3] & 0b0010_0000 != 0;
|
return self.toBytes()[3] & 0b0010_0000 != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,7 +494,7 @@ pub const StandardKeyword = enum {
|
|||||||
Description,
|
Description,
|
||||||
/// Copyright notice
|
/// Copyright notice
|
||||||
Copyright,
|
Copyright,
|
||||||
/// Time Time of original image creation
|
/// Time of original image creation
|
||||||
Creation,
|
Creation,
|
||||||
/// Software used to create the image
|
/// Software used to create the image
|
||||||
Software,
|
Software,
|
||||||
@@ -507,11 +508,11 @@ pub const StandardKeyword = enum {
|
|||||||
Comment,
|
Comment,
|
||||||
|
|
||||||
pub const map: std.StaticStringMap(StandardKeyword) = blk: {
|
pub const map: std.StaticStringMap(StandardKeyword) = blk: {
|
||||||
const fields = @typeInfo(StandardKeyword).@"enum".fields;
|
const field_names = @typeInfo(StandardKeyword).@"enum".field_names;
|
||||||
|
|
||||||
var kvs_list: [fields.len]struct { []const u8, StandardKeyword } = undefined;
|
var kvs_list: [field_names.len]struct { []const u8, StandardKeyword } = undefined;
|
||||||
for (fields, 0..) |field, i| {
|
for (field_names, 0..) |field_name, i| {
|
||||||
kvs_list[i] = .{ field.name, @field(StandardKeyword, field.name) };
|
kvs_list[i] = .{ field_name, @field(StandardKeyword, field_name) };
|
||||||
}
|
}
|
||||||
|
|
||||||
break :blk .initComptime(kvs_list);
|
break :blk .initComptime(kvs_list);
|
||||||
@@ -582,7 +583,7 @@ pub fn decodeChunk(buffer: []const u8) !?struct { Chunk, []const u8 } {
|
|||||||
const crc = std.mem.readInt(u32, rest[0..4], .big);
|
const crc = std.mem.readInt(u32, rest[0..4], .big);
|
||||||
rest = rest[4..];
|
rest = rest[4..];
|
||||||
|
|
||||||
if (std.hash.crc.Crc32IsoHdlc.hash(data) != crc) {
|
if (Crc.hash(data) != crc) {
|
||||||
return error.InvalidPng;
|
return error.InvalidPng;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -627,7 +628,7 @@ pub fn encodeChunks(chunks: []const Chunk, writer: *std.Io.Writer) !void {
|
|||||||
try writer.writeAll(magic);
|
try writer.writeAll(magic);
|
||||||
|
|
||||||
for (chunks) |chunk| {
|
for (chunks) |chunk| {
|
||||||
var crc: std.hash.crc.Crc32IsoHdlc = .init();
|
var crc: Crc = .init();
|
||||||
var data: []const u8 = chunk.data;
|
var data: []const u8 = chunk.data;
|
||||||
|
|
||||||
while (data.len > 0) {
|
while (data.len > 0) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ pub const png = @import("png.zig");
|
|||||||
pub const qoa = @import("qoa.zig");
|
pub const qoa = @import("qoa.zig");
|
||||||
pub const qoi = @import("qoi.zig");
|
pub const qoi = @import("qoi.zig");
|
||||||
pub const stbi = @import("stbi.zig");
|
pub const stbi = @import("stbi.zig");
|
||||||
|
pub const stbtt = @import("stbtt.zig");
|
||||||
|
|
||||||
test "refAllDecls" {
|
test "refAllDecls" {
|
||||||
std.testing.refAllDecls(@This());
|
std.testing.refAllDecls(@This());
|
||||||
|
|||||||
297
packages/media/src/stbtt.zig
Normal file
297
packages/media/src/stbtt.zig
Normal file
@@ -0,0 +1,297 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
allocator: std.mem.Allocator,
|
||||||
|
io: std.Io,
|
||||||
|
|
||||||
|
mutex: std.Io.Mutex = .init,
|
||||||
|
allocations: std.AutoHashMapUnmanaged(*anyopaque, usize) = .empty,
|
||||||
|
allocated_bytes: usize = 0,
|
||||||
|
|
||||||
|
const alignment: std.mem.Alignment = .@"16";
|
||||||
|
const VoidPtr = ?*align(alignment.toByteUnits()) anyopaque;
|
||||||
|
const log = std.log.scoped(.stbi);
|
||||||
|
|
||||||
|
pub fn init(allocator: std.mem.Allocator, io: std.Io) Self {
|
||||||
|
return .{
|
||||||
|
.allocator = allocator,
|
||||||
|
.io = io,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *Self) void {
|
||||||
|
std.log.scoped(.deinit).debug("Deinitializing {*}", .{self});
|
||||||
|
if (self.allocated_bytes > 0) {
|
||||||
|
log.warn("{d} byte(s) still allocated while deinitializing", .{self.allocated_bytes});
|
||||||
|
}
|
||||||
|
if (self.allocations.size > 0) {
|
||||||
|
log.warn("{d} allocation(s) still tracked while deinitializing", .{self.allocations.size});
|
||||||
|
var it = self.allocations.iterator();
|
||||||
|
var index: usize = 0;
|
||||||
|
while (it.next()) |entry| : (index += 1) {
|
||||||
|
log.warn("Leaked allocation ({d}/{d}) at 0x{x} of {d} byte(s)", .{
|
||||||
|
index + 1,
|
||||||
|
self.allocations.size,
|
||||||
|
@intFromPtr(entry.key_ptr.*),
|
||||||
|
entry.value_ptr.*,
|
||||||
|
});
|
||||||
|
const memory = @as([*]align(alignment.toByteUnits()) u8, @ptrCast(@alignCast(entry.key_ptr.*)))[0..entry.value_ptr.*];
|
||||||
|
self.allocator.free(memory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.allocations.deinit(self.allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
const import = struct {
|
||||||
|
const stbtt__buf = extern struct {
|
||||||
|
data: ?[*]const u8,
|
||||||
|
cursor: c_int,
|
||||||
|
size: c_int,
|
||||||
|
};
|
||||||
|
|
||||||
|
const stbtt_fontinfo = extern struct {
|
||||||
|
userdata: ?*anyopaque,
|
||||||
|
data: [*]const u8,
|
||||||
|
fonstart: c_int,
|
||||||
|
|
||||||
|
numGlyphs: c_int,
|
||||||
|
|
||||||
|
loca: c_int,
|
||||||
|
head: c_int,
|
||||||
|
glyf: c_int,
|
||||||
|
hhea: c_int,
|
||||||
|
hmtx: c_int,
|
||||||
|
kern: c_int,
|
||||||
|
gpos: c_int,
|
||||||
|
svg: c_int,
|
||||||
|
index_map: c_int,
|
||||||
|
indexToLocFormat: c_int,
|
||||||
|
|
||||||
|
cff: stbtt__buf,
|
||||||
|
charstrings: stbtt__buf,
|
||||||
|
gsubrs: stbtt__buf,
|
||||||
|
subrs: stbtt__buf,
|
||||||
|
fontdicts: stbtt__buf,
|
||||||
|
fdselect: stbtt__buf,
|
||||||
|
};
|
||||||
|
|
||||||
|
const stbtt_kerningentry = extern struct {
|
||||||
|
glyph1: c_int,
|
||||||
|
glyph2: c_int,
|
||||||
|
advance: c_int,
|
||||||
|
};
|
||||||
|
|
||||||
|
const STBTT_vmove = enum(u8) {
|
||||||
|
STBTT_vmove = 1,
|
||||||
|
STBTT_vline,
|
||||||
|
STBTT_vcurve,
|
||||||
|
STBTT_vcubic,
|
||||||
|
};
|
||||||
|
|
||||||
|
const stbtt_vertex = extern struct {
|
||||||
|
x: i16,
|
||||||
|
y: i16,
|
||||||
|
cx: i16,
|
||||||
|
cy: i16,
|
||||||
|
cx1: i16,
|
||||||
|
cy1: i16,
|
||||||
|
type: STBTT_vmove,
|
||||||
|
padding: u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
const stbtt_kerning_table_iterator = extern struct {
|
||||||
|
data: [*]u8,
|
||||||
|
k: c_int,
|
||||||
|
length: c_int,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern fn stbtt_GetNumberOfFonts(data: [*]const u8) c_int;
|
||||||
|
extern fn stbtt_GetFontOffsetForIndex(index: c_int, data: [*]const u8) c_int;
|
||||||
|
extern fn stbtt_InitFont(info: *stbtt_fontinfo, data: [*]const u8, offset: c_int) c_int;
|
||||||
|
extern fn stbtt_FindGlyphIndex(info: *const stbtt_fontinfo, unicode_codepoint: c_int) c_int;
|
||||||
|
extern fn stbtt_GetFontVMetrics(info: *const stbtt_fontinfo, ascent: ?*c_int, descent: ?*c_int, lineGap: ?*c_int) void;
|
||||||
|
extern fn stbtt_GetFontVMetricsOS2(info: *const stbtt_fontinfo, typoAscent: ?*c_int, typoDescent: ?*c_int, typoLineGap: ?*c_int) c_int;
|
||||||
|
extern fn stbtt_GetGlyphHMetrics(info: *const stbtt_fontinfo, glyph_index: c_int, advanceWidth: *c_int, leftSideBearing: *c_int) void;
|
||||||
|
extern fn stbtt_GetGlyphKernAdvance(info: *const stbtt_fontinfo, glyph1: c_int, glyph2: c_int) c_int;
|
||||||
|
extern fn stbtt_GetGlyphBox(info: *const stbtt_fontinfo, glyph_index: c_int, x0: *c_int, y0: *c_int, x1: *c_int, y1: *c_int) c_int;
|
||||||
|
extern fn stbtt_GetKerningTableLength(info: *const stbtt_fontinfo) c_int;
|
||||||
|
extern fn stbtt_GetKerningTable(info: *const stbtt_fontinfo, table: [*]stbtt_kerningentry, table_length: c_int) c_int;
|
||||||
|
extern fn stbtt_IsGlyphEmpty(info: *const stbtt_fontinfo, glyph_index: c_int) c_int;
|
||||||
|
extern fn stbtt_GetGlyphShape(info: *const stbtt_fontinfo, glyph_index: c_int, vertices: *[*]stbtt_vertex) c_int;
|
||||||
|
extern fn stbtt_FreeShape(info: *const stbtt_fontinfo, vertices: [*]stbtt_vertex) void;
|
||||||
|
|
||||||
|
extern fn stbtt_UnitsPerEm(info: *const stbtt_fontinfo) c_int;
|
||||||
|
extern fn stbtt_GetFontCapHeight(info: *const stbtt_fontinfo, capHeight: ?*c_int) c_int;
|
||||||
|
extern fn stbtt_KerningTableIterator(info: *const stbtt_fontinfo, it: *stbtt_kerning_table_iterator) void;
|
||||||
|
extern fn stbtt_KerningTableNext(it: *stbtt_kerning_table_iterator, entry: *stbtt_kerningentry) c_int;
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn initFont(self: *Self, data: []const u8) !*Font {
|
||||||
|
const info = try self.allocator.create(import.stbtt_fontinfo);
|
||||||
|
errdefer self.allocator.destroy(info);
|
||||||
|
|
||||||
|
info.userdata = self;
|
||||||
|
const res = import.stbtt_InitFont(info, data.ptr, 0);
|
||||||
|
if (res == 0) return error.StbttError;
|
||||||
|
|
||||||
|
return @ptrCast(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const Font = opaque {
|
||||||
|
pub fn deinit(self: *Font) void {
|
||||||
|
const info = @as(*import.stbtt_fontinfo, @ptrCast(@alignCast(self)));
|
||||||
|
const stbtt = @as(*Self, @ptrCast(@alignCast(info.userdata.?)));
|
||||||
|
stbtt.allocator.destroy(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn findGlyphIndex(self: *const Font, codepoint: u21) ?u16 {
|
||||||
|
const info = @as(*const import.stbtt_fontinfo, @ptrCast(@alignCast(self)));
|
||||||
|
const res = import.stbtt_FindGlyphIndex(info, codepoint);
|
||||||
|
return if (res != 0) @intCast(res) else null;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getGlyphMetrics(self: *const Font, glyph: u16) GlyphMetrics {
|
||||||
|
const info = @as(*const import.stbtt_fontinfo, @ptrCast(@alignCast(self)));
|
||||||
|
var advance_width: c_int = undefined;
|
||||||
|
var left_side_bearing: c_int = undefined;
|
||||||
|
import.stbtt_GetGlyphHMetrics(info, glyph, &advance_width, &left_side_bearing);
|
||||||
|
return .{
|
||||||
|
.advance_width = @intCast(advance_width),
|
||||||
|
.left_side_bearing = @intCast(left_side_bearing),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getGlyphBox(self: *const Font, glyph: u16) ?GlyphBox {
|
||||||
|
const info = @as(*const import.stbtt_fontinfo, @ptrCast(@alignCast(self)));
|
||||||
|
var x0: c_int = undefined;
|
||||||
|
var y0: c_int = undefined;
|
||||||
|
var x1: c_int = undefined;
|
||||||
|
var y1: c_int = undefined;
|
||||||
|
const res = import.stbtt_GetGlyphBox(info, glyph, &x0, &y0, &x1, &y1);
|
||||||
|
return if (res != 0) .{
|
||||||
|
.x_min = @intCast(x0),
|
||||||
|
.y_min = @intCast(y0),
|
||||||
|
.x_max = @intCast(x1),
|
||||||
|
.y_max = @intCast(y1),
|
||||||
|
} else null;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn isGlyphEmpty(self: *const Font, glyph: u16) bool {
|
||||||
|
const info = @as(*const import.stbtt_fontinfo, @ptrCast(@alignCast(self)));
|
||||||
|
const res = import.stbtt_IsGlyphEmpty(info, glyph);
|
||||||
|
return res != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getGlyphShape(self: *const Font, glyph: u16) []import.stbtt_vertex {
|
||||||
|
const info = @as(*const import.stbtt_fontinfo, @ptrCast(@alignCast(self)));
|
||||||
|
var vertices_ptr: [*]import.stbtt_vertex = undefined;
|
||||||
|
const vertices_len = @as(usize, @intCast(import.stbtt_GetGlyphShape(info, glyph, &vertices_ptr)));
|
||||||
|
return if (vertices_len == 0) &.{} else vertices_ptr[0..vertices_len];
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn freeShape(self: *const Font, vertices: []import.stbtt_vertex) void {
|
||||||
|
const info = @as(*const import.stbtt_fontinfo, @ptrCast(@alignCast(self)));
|
||||||
|
if (vertices.len > 0) {
|
||||||
|
import.stbtt_FreeShape(info, vertices.ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unitsPerEm(self: *const Font) u16 {
|
||||||
|
const info = @as(*const import.stbtt_fontinfo, @ptrCast(@alignCast(self)));
|
||||||
|
const res = import.stbtt_UnitsPerEm(info);
|
||||||
|
return @intCast(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getCapHeight(self: *const Font) ?i16 {
|
||||||
|
const info = @as(*const import.stbtt_fontinfo, @ptrCast(@alignCast(self)));
|
||||||
|
|
||||||
|
var cap_height: c_int = undefined;
|
||||||
|
if (import.stbtt_GetFontCapHeight(info, &cap_height) != 0) {
|
||||||
|
return @intCast(cap_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.findGlyphIndex('H')) |glyph| {
|
||||||
|
if (self.getGlyphBox(glyph)) |box| {
|
||||||
|
return box.y_max;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn kerningTableIterator(self: *const Font) KerningTableIterator {
|
||||||
|
const info = @as(*const import.stbtt_fontinfo, @ptrCast(@alignCast(self)));
|
||||||
|
var it: import.stbtt_kerning_table_iterator = undefined;
|
||||||
|
import.stbtt_KerningTableIterator(info, &it);
|
||||||
|
return .{ .it = it };
|
||||||
|
}
|
||||||
|
|
||||||
|
test "refAllDecls" {
|
||||||
|
std.testing.refAllDecls(@This());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const GlyphBox = struct {
|
||||||
|
x_min: i16,
|
||||||
|
y_min: i16,
|
||||||
|
x_max: i16,
|
||||||
|
y_max: i16,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const GlyphMetrics = struct {
|
||||||
|
advance_width: i16,
|
||||||
|
left_side_bearing: i16,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const KerningTableEntry = struct {
|
||||||
|
glyph_prev: u16,
|
||||||
|
glyph_next: u16,
|
||||||
|
advance: i16,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const KerningTableIterator = struct {
|
||||||
|
it: import.stbtt_kerning_table_iterator,
|
||||||
|
|
||||||
|
pub fn next(self: *KerningTableIterator) ?KerningTableEntry {
|
||||||
|
var entry: import.stbtt_kerningentry = undefined;
|
||||||
|
return if (import.stbtt_KerningTableNext(&self.it, &entry) != 0) .{
|
||||||
|
.glyph_prev = @intCast(entry.glyph1),
|
||||||
|
.glyph_next = @intCast(entry.glyph2),
|
||||||
|
.advance = @intCast(entry.advance),
|
||||||
|
} else null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// --- MALLOC INTERFACE --------------------------------------------------------
|
||||||
|
|
||||||
|
export fn castle_media_stbtt_malloc(self: *Self, size: usize) callconv(.c) VoidPtr {
|
||||||
|
self.mutex.lock(self.io) catch return null;
|
||||||
|
defer self.mutex.unlock(self.io);
|
||||||
|
|
||||||
|
self.allocations.ensureUnusedCapacity(self.allocator, 1) catch return null;
|
||||||
|
const memory = self.allocator.alignedAlloc(u8, alignment, size) catch return null;
|
||||||
|
|
||||||
|
self.allocations.putAssumeCapacityNoClobber(memory.ptr, size);
|
||||||
|
self.allocated_bytes += size;
|
||||||
|
//log.debug("Allocated {d} bytes(s) at 0x{x}", .{ size, @intFromPtr(memory.ptr) });
|
||||||
|
|
||||||
|
return memory.ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn castle_media_stbtt_free(self: *Self, maybe_ptr: VoidPtr) callconv(.c) void {
|
||||||
|
if (maybe_ptr) |ptr| {
|
||||||
|
self.mutex.lockUncancelable(self.io);
|
||||||
|
defer self.mutex.unlock(self.io);
|
||||||
|
|
||||||
|
const size = self.allocations.fetchRemove(ptr).?.value;
|
||||||
|
self.allocated_bytes -= size;
|
||||||
|
const memory = @as([*]align(alignment.toByteUnits()) u8, @ptrCast(ptr))[0..size];
|
||||||
|
|
||||||
|
self.allocator.free(memory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "refAllDecls" {
|
||||||
|
std.testing.refAllDecls(@This());
|
||||||
|
}
|
||||||
67
packages/media/src/stbtt/stb_truetype.c
Normal file
67
packages/media/src/stbtt/stb_truetype.c
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
void *castle_media_stbtt_malloc(void *self, size_t size);
|
||||||
|
void castle_media_stbtt_free(void *self, void *ptr);
|
||||||
|
|
||||||
|
#define STBTT_malloc(size, self) castle_media_stbtt_malloc(self, size)
|
||||||
|
#define STBTT_free(ptr, self) castle_media_stbtt_free(self, ptr)
|
||||||
|
|
||||||
|
#define STB_TRUETYPE_IMPLEMENTATION
|
||||||
|
#include "stb_truetype.h"
|
||||||
|
|
||||||
|
STBTT_DEF int stbtt_UnitsPerEm(const stbtt_fontinfo *info)
|
||||||
|
{
|
||||||
|
return ttUSHORT(info->data + info->head + 18);
|
||||||
|
}
|
||||||
|
|
||||||
|
STBTT_DEF int stbtt_GetFontCapHeight(const stbtt_fontinfo *info, int *capHeight)
|
||||||
|
{
|
||||||
|
int tab = stbtt__find_table(info->data, info->fontstart, "OS/2");
|
||||||
|
if (!tab || ttUSHORT(info->data+tab) < 2)
|
||||||
|
return 0;
|
||||||
|
if (capHeight) *capHeight = ttSHORT(info->data+tab + 88);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct stbtt_kerning_table_iterator {
|
||||||
|
stbtt_uint8 *data;
|
||||||
|
int k;
|
||||||
|
int length;
|
||||||
|
} stbtt_kerning_table_iterator;
|
||||||
|
|
||||||
|
STBTT_DEF void stbtt_KerningTableIterator(const stbtt_fontinfo *info, stbtt_kerning_table_iterator *it)
|
||||||
|
{
|
||||||
|
stbtt_uint8 *data = info->data + info->kern;
|
||||||
|
|
||||||
|
it->data = data;
|
||||||
|
it->k = 0;
|
||||||
|
it->length = 0;
|
||||||
|
|
||||||
|
if (!info->kern)
|
||||||
|
return;
|
||||||
|
if (ttUSHORT(data+2) < 1) // number of tables, need at least 1
|
||||||
|
return;
|
||||||
|
if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format
|
||||||
|
return;
|
||||||
|
|
||||||
|
it->length = ttUSHORT(data+10);
|
||||||
|
}
|
||||||
|
|
||||||
|
STBTT_DEF int stbtt_KerningTableNext(stbtt_kerning_table_iterator *it, stbtt_kerningentry *entry)
|
||||||
|
{
|
||||||
|
stbtt_uint8 *data = it->data;
|
||||||
|
int k = it->k;
|
||||||
|
int length = it->length;
|
||||||
|
|
||||||
|
if (k < length)
|
||||||
|
{
|
||||||
|
entry->glyph1 = ttUSHORT(data+18+(k*6));
|
||||||
|
entry->glyph2 = ttUSHORT(data+20+(k*6));
|
||||||
|
entry->advance = ttSHORT(data+22+(k*6));
|
||||||
|
|
||||||
|
it->k += 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
5079
packages/media/src/stbtt/stb_truetype.h
Normal file
5079
packages/media/src/stbtt/stb_truetype.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
.{
|
.{
|
||||||
.name = .vecmath,
|
.name = .vecmath,
|
||||||
.version = "0.0.0",
|
.version = "0.0.0",
|
||||||
.minimum_zig_version = "0.16.0",
|
.minimum_zig_version = "0.17.0",
|
||||||
.paths = .{
|
.paths = .{
|
||||||
"src",
|
"src",
|
||||||
"build.zig",
|
"build.zig",
|
||||||
|
|||||||
@@ -28,7 +28,15 @@ pub const Color = extern struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initArray(array: Array) Color {
|
pub inline fn initArray(array: Array) Color {
|
||||||
return @bitCast(array);
|
return @as(*const Color, @ptrCast(&array)).*;
|
||||||
|
}
|
||||||
|
|
||||||
|
test initArray {
|
||||||
|
const color = initArray(.{ 0x00, 0x11, 0x22, 0x33 });
|
||||||
|
try std.testing.expectEqual(0x00, color.r);
|
||||||
|
try std.testing.expectEqual(0x11, color.g);
|
||||||
|
try std.testing.expectEqual(0x22, color.b);
|
||||||
|
try std.testing.expectEqual(0x33, color.a);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn l(comptime literal: []const u8) Color {
|
pub inline fn l(comptime literal: []const u8) Color {
|
||||||
@@ -90,7 +98,15 @@ pub const Color = extern struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn asArray(self: Color) Array {
|
pub inline fn asArray(self: Color) Array {
|
||||||
return @bitCast(self);
|
return @as(*const Array, @ptrCast(&self)).*;
|
||||||
|
}
|
||||||
|
|
||||||
|
test asArray {
|
||||||
|
const array = asArray(init(0x00, 0x11, 0x22, 0x33));
|
||||||
|
try std.testing.expectEqual(0x00, array[0]);
|
||||||
|
try std.testing.expectEqual(0x11, array[1]);
|
||||||
|
try std.testing.expectEqual(0x22, array[2]);
|
||||||
|
try std.testing.expectEqual(0x33, array[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format(self: Color, w: *std.Io.Writer) !void {
|
pub fn format(self: Color, w: *std.Io.Writer) !void {
|
||||||
|
|||||||
@@ -17,11 +17,27 @@ pub const ColorHdr = extern struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initArray(array: Array) ColorHdr {
|
pub inline fn initArray(array: Array) ColorHdr {
|
||||||
return @bitCast(array);
|
return @as(*const ColorHdr, @ptrCast(&array)).*;
|
||||||
|
}
|
||||||
|
|
||||||
|
test initArray {
|
||||||
|
const color = initArray(.{ 0, 1, 2, 3 });
|
||||||
|
try std.testing.expectEqual(0, color.r);
|
||||||
|
try std.testing.expectEqual(1, color.g);
|
||||||
|
try std.testing.expectEqual(2, color.b);
|
||||||
|
try std.testing.expectEqual(3, color.a);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn asArray(self: ColorHdr) Array {
|
pub inline fn asArray(self: ColorHdr) Array {
|
||||||
return @bitCast(self);
|
return @as(*const Array, @ptrCast(&self)).*;
|
||||||
|
}
|
||||||
|
|
||||||
|
test asArray {
|
||||||
|
const array = asArray(init(0, 1, 2, 3));
|
||||||
|
try std.testing.expectEqual(0, array[0]);
|
||||||
|
try std.testing.expectEqual(1, array[1]);
|
||||||
|
try std.testing.expectEqual(2, array[2]);
|
||||||
|
try std.testing.expectEqual(3, array[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format(self: ColorHdr, w: *std.Io.Writer) !void {
|
pub fn format(self: ColorHdr, w: *std.Io.Writer) !void {
|
||||||
|
|||||||
@@ -107,13 +107,13 @@ pub const Matrix3x2 = extern struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initArray(array: Array) Matrix3x2 {
|
pub inline fn initArray(array: Array) Matrix3x2 {
|
||||||
return @bitCast(array);
|
return @as(*Matrix3x2, @ptrCast(&array)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- CONVERSION ----------------------------------------------------------
|
// --- CONVERSION ----------------------------------------------------------
|
||||||
|
|
||||||
pub inline fn asArray(self: Matrix3x2) Array {
|
pub inline fn asArray(self: Matrix3x2) Array {
|
||||||
return @bitCast(self);
|
return @as(*Array, @ptrCast(self)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- ACCESSORS -----------------------------------------------------------
|
// --- ACCESSORS -----------------------------------------------------------
|
||||||
|
|||||||
@@ -190,18 +190,6 @@ pub const Matrix3x2x8 = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initArrayOfMatrices(matrices: [8]vm.Matrix3x2) Matrix3x2x8 {
|
|
||||||
const vector: @Vector(48, f32) = @as([48]f32, @bitCast(matrices));
|
|
||||||
return .{
|
|
||||||
.ix = @shuffle(f32, vector, undefined, [_]i32{ 0, 6, 12, 18, 24, 30, 36, 42 }),
|
|
||||||
.iy = @shuffle(f32, vector, undefined, [_]i32{ 1, 7, 13, 19, 25, 31, 37, 43 }),
|
|
||||||
.jx = @shuffle(f32, vector, undefined, [_]i32{ 2, 8, 14, 20, 26, 32, 38, 44 }),
|
|
||||||
.jy = @shuffle(f32, vector, undefined, [_]i32{ 3, 9, 15, 21, 27, 33, 39, 45 }),
|
|
||||||
.tx = @shuffle(f32, vector, undefined, [_]i32{ 4, 10, 16, 22, 28, 34, 40, 46 }),
|
|
||||||
.ty = @shuffle(f32, vector, undefined, [_]i32{ 5, 11, 17, 23, 29, 35, 41, 47 }),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn splat(matrix: vm.Matrix3x2) Matrix3x2x8 {
|
pub inline fn splat(matrix: vm.Matrix3x2) Matrix3x2x8 {
|
||||||
return .{
|
return .{
|
||||||
// zig fmt: off
|
// zig fmt: off
|
||||||
@@ -214,50 +202,10 @@ pub const Matrix3x2x8 = struct {
|
|||||||
|
|
||||||
// --- CONVERSION ----------------------------------------------------------
|
// --- CONVERSION ----------------------------------------------------------
|
||||||
|
|
||||||
pub inline fn asArrayOfMatrices(self: Matrix3x2x8) [8]vm.Matrix3x2 {
|
|
||||||
const vector: @Vector(48, f32) = self.ix ++ self.iy ++ self.jx ++ self.jy ++ self.tx ++ self.ty;
|
|
||||||
return @bitCast(@as([48]f32, @shuffle(f32, vector, undefined, [_]i32{
|
|
||||||
0, 8, 16, 24, 32, 40,
|
|
||||||
1, 9, 17, 25, 33, 41,
|
|
||||||
2, 10, 18, 26, 34, 42,
|
|
||||||
3, 11, 19, 27, 35, 43,
|
|
||||||
4, 12, 20, 28, 36, 44,
|
|
||||||
5, 13, 21, 29, 37, 45,
|
|
||||||
6, 14, 22, 30, 38, 46,
|
|
||||||
7, 15, 23, 31, 39, 47,
|
|
||||||
})));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn unpack(self: Matrix3x2x8) [6]vm.f32x8 {
|
pub inline fn unpack(self: Matrix3x2x8) [6]vm.f32x8 {
|
||||||
return .{ self.ix, self.iy, self.jx, self.jy, self.tx, self.ty };
|
return .{ self.ix, self.iy, self.jx, self.jy, self.tx, self.ty };
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- LOAD AND STORE ------------------------------------------------------
|
|
||||||
|
|
||||||
pub inline fn loadArrayOfMatrices(self: *Matrix3x2x8, array: *const [8]vm.Matrix3x2) void {
|
|
||||||
const vector: @Vector(48, f32) = @as(*const [48]f32, @ptrCast(array)).*;
|
|
||||||
self.ix = @shuffle(f32, vector, undefined, [_]i32{ 0, 6, 12, 18, 24, 30, 36, 42 });
|
|
||||||
self.iy = @shuffle(f32, vector, undefined, [_]i32{ 1, 7, 13, 19, 25, 31, 37, 43 });
|
|
||||||
self.jx = @shuffle(f32, vector, undefined, [_]i32{ 2, 8, 14, 20, 26, 32, 38, 44 });
|
|
||||||
self.jy = @shuffle(f32, vector, undefined, [_]i32{ 3, 9, 15, 21, 27, 33, 39, 45 });
|
|
||||||
self.tx = @shuffle(f32, vector, undefined, [_]i32{ 4, 10, 16, 22, 28, 34, 40, 46 });
|
|
||||||
self.ty = @shuffle(f32, vector, undefined, [_]i32{ 5, 11, 17, 23, 29, 35, 41, 47 });
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn storeArrayOfMatrices(self: *const Matrix3x2x8, array: *[8]vm.Matrix3x2) void {
|
|
||||||
const vector: @Vector(48, f32) = self.ix ++ self.iy ++ self.jx ++ self.jy ++ self.tx ++ self.ty;
|
|
||||||
@as(*[48]f32, @ptrCast(array)).* = @shuffle(f32, vector, undefined, [_]i32{
|
|
||||||
0, 8, 16, 24, 32, 40,
|
|
||||||
1, 9, 17, 25, 33, 41,
|
|
||||||
2, 10, 18, 26, 34, 42,
|
|
||||||
3, 11, 19, 27, 35, 43,
|
|
||||||
4, 12, 20, 28, 36, 44,
|
|
||||||
5, 13, 21, 29, 37, 45,
|
|
||||||
6, 14, 22, 30, 38, 46,
|
|
||||||
7, 15, 23, 31, 39, 47,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- ACCESSORS -----------------------------------------------------------
|
// --- ACCESSORS -----------------------------------------------------------
|
||||||
|
|
||||||
pub inline fn getIVersor(self: Matrix3x2x8) vm.Vector2x8 {
|
pub inline fn getIVersor(self: Matrix3x2x8) vm.Vector2x8 {
|
||||||
|
|||||||
@@ -162,13 +162,13 @@ pub const Matrix4x4 = extern struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initArray(array: Array) Matrix4x4 {
|
pub inline fn initArray(array: Array) Matrix4x4 {
|
||||||
return @bitCast(array);
|
return @as(*Matrix4x4, @ptrCast(&array)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- CONVERSION ----------------------------------------------------------
|
// --- CONVERSION ----------------------------------------------------------
|
||||||
|
|
||||||
pub inline fn asArray(self: Matrix4x4) Array {
|
pub inline fn asArray(self: Matrix4x4) Array {
|
||||||
return @bitCast(self);
|
return @as(*Array, @ptrCast(self)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- ACCESSORS -----------------------------------------------------------
|
// --- ACCESSORS -----------------------------------------------------------
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const vm = @import("../root.zig");
|
const vm = @import("../root.zig");
|
||||||
|
|
||||||
pub const Matrix4x4x8 = extern struct {
|
pub const Matrix4x4x8 = struct {
|
||||||
// zig fmt: off
|
// zig fmt: off
|
||||||
ix: vm.f32x8, iy: vm.f32x8, iz: vm.f32x8, iw: vm.f32x8,
|
ix: vm.f32x8, iy: vm.f32x8, iz: vm.f32x8, iw: vm.f32x8,
|
||||||
jx: vm.f32x8, jy: vm.f32x8, jz: vm.f32x8, jw: vm.f32x8,
|
jx: vm.f32x8, jy: vm.f32x8, jz: vm.f32x8, jw: vm.f32x8,
|
||||||
@@ -270,28 +270,6 @@ pub const Matrix4x4x8 = extern struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initArrayOfMatrices(matrices: [8]vm.Matrix4x4) Matrix4x4x8 {
|
|
||||||
const vector: @Vector(128, f32) = @as([128]f32, @bitCast(matrices));
|
|
||||||
return .{
|
|
||||||
.ix = @shuffle(f32, vector, undefined, [_]i32{ 0, 16, 32, 48, 64, 80, 96, 112 }),
|
|
||||||
.iy = @shuffle(f32, vector, undefined, [_]i32{ 1, 17, 33, 49, 65, 81, 97, 113 }),
|
|
||||||
.iz = @shuffle(f32, vector, undefined, [_]i32{ 2, 18, 34, 50, 66, 82, 98, 114 }),
|
|
||||||
.iw = @shuffle(f32, vector, undefined, [_]i32{ 3, 19, 35, 51, 67, 83, 99, 115 }),
|
|
||||||
.jx = @shuffle(f32, vector, undefined, [_]i32{ 4, 20, 36, 52, 68, 84, 100, 116 }),
|
|
||||||
.jy = @shuffle(f32, vector, undefined, [_]i32{ 5, 21, 37, 53, 69, 85, 101, 117 }),
|
|
||||||
.jz = @shuffle(f32, vector, undefined, [_]i32{ 6, 22, 38, 54, 70, 86, 102, 118 }),
|
|
||||||
.jw = @shuffle(f32, vector, undefined, [_]i32{ 7, 23, 39, 55, 71, 87, 103, 119 }),
|
|
||||||
.kx = @shuffle(f32, vector, undefined, [_]i32{ 8, 24, 40, 56, 72, 88, 104, 120 }),
|
|
||||||
.ky = @shuffle(f32, vector, undefined, [_]i32{ 9, 25, 41, 57, 73, 89, 105, 121 }),
|
|
||||||
.kz = @shuffle(f32, vector, undefined, [_]i32{ 10, 26, 42, 58, 74, 90, 106, 122 }),
|
|
||||||
.kw = @shuffle(f32, vector, undefined, [_]i32{ 11, 27, 43, 59, 75, 91, 107, 123 }),
|
|
||||||
.tx = @shuffle(f32, vector, undefined, [_]i32{ 12, 28, 44, 60, 76, 92, 108, 124 }),
|
|
||||||
.ty = @shuffle(f32, vector, undefined, [_]i32{ 13, 29, 45, 61, 77, 93, 109, 125 }),
|
|
||||||
.tz = @shuffle(f32, vector, undefined, [_]i32{ 14, 30, 46, 62, 78, 94, 110, 126 }),
|
|
||||||
.tw = @shuffle(f32, vector, undefined, [_]i32{ 15, 31, 47, 63, 79, 95, 111, 127 }),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn splat(matrix: vm.Matrix4x4) Matrix4x4x8 {
|
pub inline fn splat(matrix: vm.Matrix4x4) Matrix4x4x8 {
|
||||||
return .{
|
return .{
|
||||||
// zig fmt: off
|
// zig fmt: off
|
||||||
@@ -305,60 +283,10 @@ pub const Matrix4x4x8 = extern struct {
|
|||||||
|
|
||||||
// --- CONVERSION ----------------------------------------------------------
|
// --- CONVERSION ----------------------------------------------------------
|
||||||
|
|
||||||
pub inline fn asArrayOfMatrices(self: Matrix4x4x8) [8]vm.Matrix4x4 {
|
|
||||||
const vector: @Vector(128, f32) = self.ix ++ self.iy ++ self.iz ++ self.iw ++ self.jx ++ self.jy ++ self.jz ++ self.jw ++ self.kx ++ self.ky ++ self.kz ++ self.kw ++ self.tx ++ self.ty ++ self.tz ++ self.tw;
|
|
||||||
return @bitCast(@as([128]f32, @shuffle(f32, vector, undefined, [_]i32{
|
|
||||||
0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120,
|
|
||||||
1, 9, 17, 25, 33, 41, 49, 57, 65, 73, 81, 89, 97, 105, 113, 121,
|
|
||||||
2, 10, 18, 26, 34, 42, 50, 58, 66, 74, 82, 90, 98, 106, 114, 122,
|
|
||||||
3, 11, 19, 27, 35, 43, 51, 59, 67, 75, 83, 91, 99, 107, 115, 123,
|
|
||||||
4, 12, 20, 28, 36, 44, 52, 60, 68, 76, 84, 92, 100, 108, 116, 124,
|
|
||||||
5, 13, 21, 29, 37, 45, 53, 61, 69, 77, 85, 93, 101, 109, 117, 125,
|
|
||||||
6, 14, 22, 30, 38, 46, 54, 62, 70, 78, 86, 94, 102, 110, 118, 126,
|
|
||||||
7, 15, 23, 31, 39, 47, 55, 63, 71, 79, 87, 95, 103, 111, 119, 127,
|
|
||||||
})));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn unpack(self: Matrix4x4x8) [16]vm.f32x8 {
|
pub inline fn unpack(self: Matrix4x4x8) [16]vm.f32x8 {
|
||||||
return .{ self.ix, self.iy, self.iz, self.iw, self.jx, self.jy, self.jz, self.jw, self.kx, self.ky, self.kz, self.kw, self.tx, self.ty, self.tz, self.tw };
|
return .{ self.ix, self.iy, self.iz, self.iw, self.jx, self.jy, self.jz, self.jw, self.kx, self.ky, self.kz, self.kw, self.tx, self.ty, self.tz, self.tw };
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- LOAD AND STORE ------------------------------------------------------
|
|
||||||
|
|
||||||
pub inline fn loadArrayOfMatrices(self: *Matrix4x4x8, array: *const [8]vm.Matrix4x4) void {
|
|
||||||
const vector: @Vector(128, f32) = @as(*const [128]f32, @ptrCast(array)).*;
|
|
||||||
self.ix = @shuffle(f32, vector, undefined, [_]i32{ 0, 16, 32, 48, 64, 80, 96, 112 });
|
|
||||||
self.iy = @shuffle(f32, vector, undefined, [_]i32{ 1, 17, 33, 49, 65, 81, 97, 113 });
|
|
||||||
self.iz = @shuffle(f32, vector, undefined, [_]i32{ 2, 18, 34, 50, 66, 82, 98, 114 });
|
|
||||||
self.iw = @shuffle(f32, vector, undefined, [_]i32{ 3, 19, 35, 51, 67, 83, 99, 115 });
|
|
||||||
self.jx = @shuffle(f32, vector, undefined, [_]i32{ 4, 20, 36, 52, 68, 84, 100, 116 });
|
|
||||||
self.jy = @shuffle(f32, vector, undefined, [_]i32{ 5, 21, 37, 53, 69, 85, 101, 117 });
|
|
||||||
self.jz = @shuffle(f32, vector, undefined, [_]i32{ 6, 22, 38, 54, 70, 86, 102, 118 });
|
|
||||||
self.jw = @shuffle(f32, vector, undefined, [_]i32{ 7, 23, 39, 55, 71, 87, 103, 119 });
|
|
||||||
self.kx = @shuffle(f32, vector, undefined, [_]i32{ 8, 24, 40, 56, 72, 88, 104, 120 });
|
|
||||||
self.ky = @shuffle(f32, vector, undefined, [_]i32{ 9, 25, 41, 57, 73, 89, 105, 121 });
|
|
||||||
self.kz = @shuffle(f32, vector, undefined, [_]i32{ 10, 26, 42, 58, 74, 90, 106, 122 });
|
|
||||||
self.kw = @shuffle(f32, vector, undefined, [_]i32{ 11, 27, 43, 59, 75, 91, 107, 123 });
|
|
||||||
self.tx = @shuffle(f32, vector, undefined, [_]i32{ 12, 28, 44, 60, 76, 92, 108, 124 });
|
|
||||||
self.ty = @shuffle(f32, vector, undefined, [_]i32{ 13, 29, 45, 61, 77, 93, 109, 125 });
|
|
||||||
self.tz = @shuffle(f32, vector, undefined, [_]i32{ 14, 30, 46, 62, 78, 94, 110, 126 });
|
|
||||||
self.tw = @shuffle(f32, vector, undefined, [_]i32{ 15, 31, 47, 63, 79, 95, 111, 127 });
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn storeArrayOfMatrices(self: *const Matrix4x4x8, array: *[8]vm.Matrix4x4) void {
|
|
||||||
const vector: @Vector(128, f32) = self.ix ++ self.iy ++ self.iz ++ self.iw ++ self.jx ++ self.jy ++ self.jz ++ self.jw ++ self.kx ++ self.ky ++ self.kz ++ self.kw ++ self.tx ++ self.ty ++ self.tz ++ self.tw;
|
|
||||||
@as(*[128]f32, @ptrCast(array)).* = @shuffle(f32, vector, undefined, [_]i32{
|
|
||||||
0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120,
|
|
||||||
1, 9, 17, 25, 33, 41, 49, 57, 65, 73, 81, 89, 97, 105, 113, 121,
|
|
||||||
2, 10, 18, 26, 34, 42, 50, 58, 66, 74, 82, 90, 98, 106, 114, 122,
|
|
||||||
3, 11, 19, 27, 35, 43, 51, 59, 67, 75, 83, 91, 99, 107, 115, 123,
|
|
||||||
4, 12, 20, 28, 36, 44, 52, 60, 68, 76, 84, 92, 100, 108, 116, 124,
|
|
||||||
5, 13, 21, 29, 37, 45, 53, 61, 69, 77, 85, 93, 101, 109, 117, 125,
|
|
||||||
6, 14, 22, 30, 38, 46, 54, 62, 70, 78, 86, 94, 102, 110, 118, 126,
|
|
||||||
7, 15, 23, 31, 39, 47, 55, 63, 71, 79, 87, 95, 103, 111, 119, 127,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- ACCESSORS -----------------------------------------------------------
|
// --- ACCESSORS -----------------------------------------------------------
|
||||||
|
|
||||||
pub inline fn getIVersor(self: Matrix4x4x8) vm.Vector4 {
|
pub inline fn getIVersor(self: Matrix4x4x8) vm.Vector4 {
|
||||||
|
|||||||
@@ -20,21 +20,21 @@ pub const Complex = extern struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initArray(array: Array) Complex {
|
pub inline fn initArray(array: Array) Complex {
|
||||||
return @bitCast(array);
|
return @as(*const Complex, @ptrCast(&array)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initVector2(vector: vm.Vector2) Complex {
|
pub inline fn initVector2(vector: vm.Vector2) Complex {
|
||||||
return @bitCast(vector);
|
return @as(*const Complex, @ptrCast(&vector)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- CONVERSION ----------------------------------------------------------
|
// --- CONVERSION ----------------------------------------------------------
|
||||||
|
|
||||||
pub inline fn asArray(self: Complex) Array {
|
pub inline fn asArray(self: Complex) Array {
|
||||||
return @bitCast(self);
|
return @as(*const Array, @ptrCast(&self)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn asVector2(self: Complex) vm.Vector2 {
|
pub inline fn asVector2(self: Complex) vm.Vector2 {
|
||||||
return @bitCast(self);
|
return @as(*const vm.Vector2, @ptrCast(&self)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- COMPONENT-WISE ------------------------------------------------------
|
// --- COMPONENT-WISE ------------------------------------------------------
|
||||||
|
|||||||
@@ -26,60 +26,16 @@ pub const Complex_x8 = struct {
|
|||||||
return .{ .re = vm.ps(complex.re), .im = vm.ps(complex.im) };
|
return .{ .re = vm.ps(complex.re), .im = vm.ps(complex.im) };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initArrayOfComplex(complex: [8]vm.Complex) Complex_x8 {
|
|
||||||
const vector: @Vector(16, f32) = @as([16]f32, @bitCast(complex));
|
|
||||||
return .{
|
|
||||||
.re = @shuffle(f32, vector, undefined, [_]i32{ 0, 2, 4, 6, 8, 10, 12, 14 }),
|
|
||||||
.im = @shuffle(f32, vector, undefined, [_]i32{ 1, 3, 5, 7, 9, 11, 13, 15 }),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn splat(complex: vm.Complex) Complex_x8 {
|
pub inline fn splat(complex: vm.Complex) Complex_x8 {
|
||||||
return .{ .re = vm.ps(complex.re), .im = vm.ps(complex.im) };
|
return .{ .re = vm.ps(complex.re), .im = vm.ps(complex.im) };
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- CONVERSION ----------------------------------------------------------
|
// --- CONVERSION ----------------------------------------------------------
|
||||||
|
|
||||||
pub inline fn asArrayOfComplex(self: Complex_x8) [8]vm.Complex {
|
|
||||||
const vector: @Vector(16, f32) = self.re ++ self.im;
|
|
||||||
return @bitCast(@as([16]f32, @shuffle(f32, vector, undefined, [_]i32{
|
|
||||||
0, 8,
|
|
||||||
1, 9,
|
|
||||||
2, 10,
|
|
||||||
3, 11,
|
|
||||||
4, 12,
|
|
||||||
5, 13,
|
|
||||||
6, 14,
|
|
||||||
7, 15,
|
|
||||||
})));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn unpack(self: Complex_x8) [2]vm.f32x8 {
|
pub inline fn unpack(self: Complex_x8) [2]vm.f32x8 {
|
||||||
return .{ self.re, self.im };
|
return .{ self.re, self.im };
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- LOAD AND STORE ------------------------------------------------------
|
|
||||||
|
|
||||||
pub inline fn loadArrayOfComplex(self: *Complex_x8, array: *const [8]vm.Complex) void {
|
|
||||||
const vector: @Vector(16, f32) = @as(*const [16]f32, @ptrCast(array)).*;
|
|
||||||
self.re = @shuffle(f32, vector, undefined, [_]i32{ 0, 2, 4, 6, 8, 10, 12, 14 });
|
|
||||||
self.im = @shuffle(f32, vector, undefined, [_]i32{ 1, 3, 5, 7, 9, 11, 13, 15 });
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn storeArrayOfComplex(self: *const Complex_x8, array: *[8]vm.Complex) void {
|
|
||||||
const vector: @Vector(16, f32) = self.re ++ self.im;
|
|
||||||
@as(*[16]f32, @ptrCast(array)).* = @shuffle(f32, vector, undefined, [_]i32{
|
|
||||||
0, 8,
|
|
||||||
1, 9,
|
|
||||||
2, 10,
|
|
||||||
3, 11,
|
|
||||||
4, 12,
|
|
||||||
5, 13,
|
|
||||||
6, 14,
|
|
||||||
7, 15,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- COMPONENT-WISE ------------------------------------------------------
|
// --- COMPONENT-WISE ------------------------------------------------------
|
||||||
|
|
||||||
pub inline fn add(self: Complex_x8, other: Complex_x8) Complex_x8 {
|
pub inline fn add(self: Complex_x8, other: Complex_x8) Complex_x8 {
|
||||||
|
|||||||
@@ -36,21 +36,21 @@ pub const Quaternion = extern struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initArray(array: Array) Quaternion {
|
pub inline fn initArray(array: Array) Quaternion {
|
||||||
return @bitCast(array);
|
return @as(*Quaternion, @ptrCast(&array)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initVector4(vector: vm.Vector4) Quaternion {
|
pub inline fn initVector4(vector: vm.Vector4) Quaternion {
|
||||||
return @bitCast(vector);
|
return @as(*Quaternion, @ptrCast(&vector)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- CONVERSION ----------------------------------------------------------
|
// --- CONVERSION ----------------------------------------------------------
|
||||||
|
|
||||||
pub inline fn asArray(self: Quaternion) Array {
|
pub inline fn asArray(self: Quaternion) Array {
|
||||||
return @bitCast(self);
|
return @as(*Array, @ptrCast(self)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn asVector4(self: Quaternion) vm.Vector4 {
|
pub inline fn asVector4(self: Quaternion) vm.Vector4 {
|
||||||
return @bitCast(self);
|
return @as(*vm.Vector4, @ptrCast(self)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- ACCESSORS -----------------------------------------------------------
|
// --- ACCESSORS -----------------------------------------------------------
|
||||||
|
|||||||
@@ -55,16 +55,6 @@ pub const Quaternion_x8 = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initArrayOfQuaternions(quaternions: [8]vm.Quaternion) Quaternion_x8 {
|
|
||||||
const vector: @Vector(32, f32) = @as([32]f32, @bitCast(quaternions));
|
|
||||||
return .{
|
|
||||||
.x = @shuffle(f32, vector, undefined, [_]i32{ 0, 4, 8, 12, 16, 20, 24, 28 }),
|
|
||||||
.y = @shuffle(f32, vector, undefined, [_]i32{ 1, 5, 9, 13, 17, 21, 25, 29 }),
|
|
||||||
.z = @shuffle(f32, vector, undefined, [_]i32{ 2, 6, 10, 14, 18, 22, 26, 30 }),
|
|
||||||
.w = @shuffle(f32, vector, undefined, [_]i32{ 3, 7, 11, 15, 19, 23, 27, 31 }),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn splat(quaternion: vm.Quaternion) Quaternion_x8 {
|
pub inline fn splat(quaternion: vm.Quaternion) Quaternion_x8 {
|
||||||
return .{
|
return .{
|
||||||
.x = vm.ps(quaternion.x),
|
.x = vm.ps(quaternion.x),
|
||||||
@@ -76,48 +66,10 @@ pub const Quaternion_x8 = struct {
|
|||||||
|
|
||||||
// --- CONVERSION ----------------------------------------------------------
|
// --- CONVERSION ----------------------------------------------------------
|
||||||
|
|
||||||
pub inline fn asArrayOfQuaternions(self: Quaternion_x8) [8]vm.Quaternion {
|
|
||||||
const vector: @Vector(32, f32) = self.x ++ self.y ++ self.z ++ self.w;
|
|
||||||
return @bitCast(@as([32]f32, @shuffle(f32, vector, undefined, [_]i32{
|
|
||||||
0, 8, 16, 24,
|
|
||||||
1, 9, 17, 25,
|
|
||||||
2, 10, 18, 26,
|
|
||||||
3, 11, 19, 27,
|
|
||||||
4, 12, 20, 28,
|
|
||||||
5, 13, 21, 29,
|
|
||||||
6, 14, 22, 30,
|
|
||||||
7, 15, 23, 31,
|
|
||||||
})));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn unpack(self: Quaternion_x8) [4]vm.f32x8 {
|
pub inline fn unpack(self: Quaternion_x8) [4]vm.f32x8 {
|
||||||
return .{ self.x, self.y, self.z, self.w };
|
return .{ self.x, self.y, self.z, self.w };
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- LOAD AND STORE ------------------------------------------------------
|
|
||||||
|
|
||||||
pub inline fn loadArrayOfQuaternions(self: *Quaternion_x8, array: *const [8]vm.Quaternion) void {
|
|
||||||
const vector: @Vector(32, f32) = @as(*const [32]f32, @ptrCast(array)).*;
|
|
||||||
self.x = @shuffle(f32, vector, undefined, [_]i32{ 0, 4, 8, 12, 16, 20, 24, 28 });
|
|
||||||
self.y = @shuffle(f32, vector, undefined, [_]i32{ 1, 5, 9, 13, 17, 21, 25, 29 });
|
|
||||||
self.z = @shuffle(f32, vector, undefined, [_]i32{ 2, 6, 10, 14, 18, 22, 26, 30 });
|
|
||||||
self.w = @shuffle(f32, vector, undefined, [_]i32{ 3, 7, 11, 15, 19, 23, 27, 31 });
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn storeArrayOfQuaternions(self: *const Quaternion_x8, array: *[8]vm.Quaternion) void {
|
|
||||||
const vector: @Vector(32, f32) = self.x ++ self.y ++ self.z ++ self.w;
|
|
||||||
@as(*[32]f32, @ptrCast(array)).* = @shuffle(f32, vector, undefined, [_]i32{
|
|
||||||
0, 8, 16, 24,
|
|
||||||
1, 9, 17, 25,
|
|
||||||
2, 10, 18, 26,
|
|
||||||
3, 11, 19, 27,
|
|
||||||
4, 12, 20, 28,
|
|
||||||
5, 13, 21, 29,
|
|
||||||
6, 14, 22, 30,
|
|
||||||
7, 15, 23, 31,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- ACCESSORS -----------------------------------------------------------
|
// --- ACCESSORS -----------------------------------------------------------
|
||||||
|
|
||||||
pub inline fn getVector(self: Quaternion_x8) vm.Vector3x8 {
|
pub inline fn getVector(self: Quaternion_x8) vm.Vector3x8 {
|
||||||
|
|||||||
@@ -147,15 +147,24 @@ test sin_x8 {
|
|||||||
|
|
||||||
pub fn cossin(angle_turns: f32) vm.Complex {
|
pub fn cossin(angle_turns: f32) vm.Complex {
|
||||||
@setFloatMode(.optimized);
|
@setFloatMode(.optimized);
|
||||||
|
// zig fmt: off
|
||||||
// Taylor series expansion for f(x)=cos(xπ/2)
|
// Taylor series expansion for f(x)=cos(xπ/2)
|
||||||
const term_cos_0: f32 = 1.0;
|
const term_cos_0: f32 = 1.000000000e-0; // 1
|
||||||
const term_cos_2: f32 = -1.23370055; // -π²/8
|
const term_cos_2: f32 = -1.233700550e-0; // -π² /8
|
||||||
const term_cos_4: f32 = 0.253669508; // π⁴/384
|
const term_cos_4: f32 = 2.536695079e-1; // π⁴ /384
|
||||||
const term_cos_6: f32 = -0.020863481; // -π⁶/46080
|
const term_cos_6: f32 = -2.086348076e-2; // -π⁶ /46080
|
||||||
|
const term_cos_8: f32 = 9.192602748e-4; // π⁸ /10321920
|
||||||
|
const term_cos_10: f32 = -2.520204237e-5; // -π¹⁰/3715891200
|
||||||
|
const term_cos_12: f32 = 4.710874778e-7; // π¹²/1961990553600
|
||||||
// Taylor series expansion for f(x)=sin(xπ/2)
|
// Taylor series expansion for f(x)=sin(xπ/2)
|
||||||
const term_sin_1: f32 = 1.570796327; // π/2
|
const term_sin_1: f32 = 1.570796326e-0; // π /2
|
||||||
const term_sin_3: f32 = -0.645964098; // -π³/48
|
const term_sin_3: f32 = -6.459640975e-1; // -π³ /48
|
||||||
const term_sin_5: f32 = 0.079692626; // π⁵/3840
|
const term_sin_5: f32 = 7.969262624e-2; // π⁵ /3840
|
||||||
|
const term_sin_7: f32 = -4.681754135e-3; // -π⁷ /645120
|
||||||
|
const term_sin_9: f32 = 1.604411847e-4; // π⁹ /185794560
|
||||||
|
const term_sin_11: f32 = -3.598843235e-6; // -π¹¹/81749606400
|
||||||
|
const term_sin_13: f32 = 5.692172921e-8; // π¹³/51011754393600
|
||||||
|
// zig fmt: on
|
||||||
|
|
||||||
const angle_01 = angle_turns - @floor(angle_turns);
|
const angle_01 = angle_turns - @floor(angle_turns);
|
||||||
const angle_04 = 4.0 * angle_01;
|
const angle_04 = 4.0 * angle_01;
|
||||||
@@ -168,8 +177,8 @@ pub fn cossin(angle_turns: f32) vm.Complex {
|
|||||||
const x = angle_04 - @floor(angle_04);
|
const x = angle_04 - @floor(angle_04);
|
||||||
const x2 = x * x;
|
const x2 = x * x;
|
||||||
|
|
||||||
const c: u32 = @bitCast(((term_cos_6 * x2 + term_cos_4) * x2 + term_cos_2) * x2 + term_cos_0);
|
const c: u32 = @bitCast((((((term_cos_12 * x2 + term_cos_10) * x2 + term_cos_8) * x2 + term_cos_6) * x2 + term_cos_4) * x2 + term_cos_2) * x2 + term_cos_0);
|
||||||
const s: u32 = @bitCast(((term_sin_5 * x2 + term_sin_3) * x2 + term_sin_1) * x);
|
const s: u32 = @bitCast(((((((term_sin_13 * x2 + term_sin_11) * x2 + term_sin_9) * x2 + term_sin_7) * x2 + term_sin_5) * x2 + term_sin_3) * x2 + term_sin_1) * x);
|
||||||
|
|
||||||
const result_cos: f32 = @bitCast(((s & quadrant_odd) | (c & ~quadrant_odd)) ^ sign_mask_cos);
|
const result_cos: f32 = @bitCast(((s & quadrant_odd) | (c & ~quadrant_odd)) ^ sign_mask_cos);
|
||||||
const result_sin: f32 = @bitCast(((c & quadrant_odd) | (s & ~quadrant_odd)) ^ sign_mask_sin);
|
const result_sin: f32 = @bitCast(((c & quadrant_odd) | (s & ~quadrant_odd)) ^ sign_mask_sin);
|
||||||
@@ -190,15 +199,24 @@ test cossin {
|
|||||||
|
|
||||||
pub fn cossin_x8(angle_turns: vm.f32x8) vm.Complex_x8 {
|
pub fn cossin_x8(angle_turns: vm.f32x8) vm.Complex_x8 {
|
||||||
@setFloatMode(.optimized);
|
@setFloatMode(.optimized);
|
||||||
|
// zig fmt: off
|
||||||
// Taylor series expansion for f(x)=cos(xπ/2)
|
// Taylor series expansion for f(x)=cos(xπ/2)
|
||||||
const term_cos_0 = vm.ps(1.0);
|
const term_cos_0 = vm.ps( 1.000000000e-0); // 1
|
||||||
const term_cos_2 = vm.ps(-1.23370055); // -π²/8
|
const term_cos_2 = vm.ps(-1.233700550e-0); // -π² /8
|
||||||
const term_cos_4 = vm.ps(0.253669508); // π⁴/384
|
const term_cos_4 = vm.ps( 2.536695079e-1); // π⁴ /384
|
||||||
const term_cos_6 = vm.ps(-0.020863481); // -π⁶/46080
|
const term_cos_6 = vm.ps(-2.086348076e-2); // -π⁶ /46080
|
||||||
|
const term_cos_8 = vm.ps( 9.192602748e-4); // π⁸ /10321920
|
||||||
|
const term_cos_10 = vm.ps(-2.520204237e-5); // -π¹⁰/3715891200
|
||||||
|
const term_cos_12 = vm.ps( 4.710874778e-7); // π¹²/1961990553600
|
||||||
// Taylor series expansion for f(x)=sin(xπ/2)
|
// Taylor series expansion for f(x)=sin(xπ/2)
|
||||||
const term_sin_1 = vm.ps(1.570796327); // π/2
|
const term_sin_1 = vm.ps( 1.570796326e-0); // π /2
|
||||||
const term_sin_3 = vm.ps(-0.645964098); // -π³/48
|
const term_sin_3 = vm.ps(-6.459640975e-1); // -π³ /48
|
||||||
const term_sin_5 = vm.ps(0.079692626); // π⁵/3840
|
const term_sin_5 = vm.ps( 7.969262624e-2); // π⁵ /3840
|
||||||
|
const term_sin_7 = vm.ps(-4.681754135e-3); // -π⁷ /645120
|
||||||
|
const term_sin_9 = vm.ps( 1.604411847e-4); // π⁹ /185794560
|
||||||
|
const term_sin_11 = vm.ps(-3.598843235e-6); // -π¹¹/81749606400
|
||||||
|
const term_sin_13 = vm.ps( 5.692172921e-8); // π¹³/51011754393600
|
||||||
|
// zig fmt: on
|
||||||
|
|
||||||
const angle_01 = angle_turns - @floor(angle_turns);
|
const angle_01 = angle_turns - @floor(angle_turns);
|
||||||
const angle_04 = vm.ps(4.0) * angle_01;
|
const angle_04 = vm.ps(4.0) * angle_01;
|
||||||
@@ -211,8 +229,8 @@ pub fn cossin_x8(angle_turns: vm.f32x8) vm.Complex_x8 {
|
|||||||
const x = angle_04 - @floor(angle_04);
|
const x = angle_04 - @floor(angle_04);
|
||||||
const x2 = x * x;
|
const x2 = x * x;
|
||||||
|
|
||||||
const c: vm.u32x8 = @bitCast(((term_cos_6 * x2 + term_cos_4) * x2 + term_cos_2) * x2 + term_cos_0);
|
const c: vm.u32x8 = @bitCast((((((term_cos_12 * x2 + term_cos_10) * x2 + term_cos_8) * x2 + term_cos_6) * x2 + term_cos_4) * x2 + term_cos_2) * x2 + term_cos_0);
|
||||||
const s: vm.u32x8 = @bitCast(((term_sin_5 * x2 + term_sin_3) * x2 + term_sin_1) * x);
|
const s: vm.u32x8 = @bitCast(((((((term_sin_13 * x2 + term_sin_11) * x2 + term_sin_9) * x2 + term_sin_7) * x2 + term_sin_5) * x2 + term_sin_3) * x2 + term_sin_1) * x);
|
||||||
|
|
||||||
const result_cos: vm.f32x8 = @bitCast(@select(u32, quadrant_odd, s, c) ^ sign_mask_cos);
|
const result_cos: vm.f32x8 = @bitCast(@select(u32, quadrant_odd, s, c) ^ sign_mask_cos);
|
||||||
const result_sin: vm.f32x8 = @bitCast(@select(u32, quadrant_odd, c, s) ^ sign_mask_sin);
|
const result_sin: vm.f32x8 = @bitCast(@select(u32, quadrant_odd, c, s) ^ sign_mask_sin);
|
||||||
@@ -222,17 +240,20 @@ pub fn cossin_x8(angle_turns: vm.f32x8) vm.Complex_x8 {
|
|||||||
|
|
||||||
test cossin_x8 {
|
test cossin_x8 {
|
||||||
try std.testing.expectEqual(
|
try std.testing.expectEqual(
|
||||||
vm.Complex_x8.initArrayOfComplex(.{
|
vm.Complex_x8.init(
|
||||||
.initVector2(.unit_x),
|
.{ 1, 0, -1, 0, 1, 0, -1, 0 },
|
||||||
.initVector2(.unit_y),
|
.{ 0, 1, 0, -1, 0, 1, 0, -1 },
|
||||||
.initVector2(.unit_nx),
|
),
|
||||||
.initVector2(.unit_ny),
|
cossin_x8(.{
|
||||||
.initVector2(.unit_x),
|
-1,
|
||||||
.initVector2(.unit_y),
|
-0.75,
|
||||||
.initVector2(.unit_nx),
|
-0.5,
|
||||||
.initVector2(.unit_ny),
|
-0.25,
|
||||||
|
0,
|
||||||
|
0.25,
|
||||||
|
0.5,
|
||||||
|
0.75,
|
||||||
}),
|
}),
|
||||||
cossin_x8(.{ -1, -0.75, -0.5, -0.25, 0, 0.25, 0.5, 0.75 }),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ pub const Vector2 = extern struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initArray(array: Array) Vector2 {
|
pub inline fn initArray(array: Array) Vector2 {
|
||||||
return @bitCast(array);
|
return @as(*const Vector2, @ptrCast(&array)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- CONVERSION ----------------------------------------------------------
|
// --- CONVERSION ----------------------------------------------------------
|
||||||
|
|
||||||
pub inline fn asArray(self: Vector2) Array {
|
pub inline fn asArray(self: Vector2) Array {
|
||||||
return @bitCast(self);
|
return @as(*const Array, @ptrCast(self)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn asInt(self: Vector2) vm.Vector2Int {
|
pub inline fn asInt(self: Vector2) vm.Vector2Int {
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ pub const Vector2Int = extern struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initArray(array: Array) Vector2Int {
|
pub inline fn initArray(array: Array) Vector2Int {
|
||||||
return @bitCast(array);
|
return @as(*const Vector2Int, @ptrCast(&array)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- CONVERSION ----------------------------------------------------------
|
// --- CONVERSION ----------------------------------------------------------
|
||||||
|
|
||||||
pub inline fn asArray(self: Vector2Int) Array {
|
pub inline fn asArray(self: Vector2Int) Array {
|
||||||
return @bitCast(self);
|
return @as(*const Array, @ptrCast(self)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn asFloat(self: Vector2Int) vm.Vector2 {
|
pub inline fn asFloat(self: Vector2Int) vm.Vector2 {
|
||||||
|
|||||||
@@ -30,14 +30,6 @@ pub const Vector2Int_x8 = struct {
|
|||||||
return .{ .x = vm.epi32(scalar), .y = vm.epi32(scalar) };
|
return .{ .x = vm.epi32(scalar), .y = vm.epi32(scalar) };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initArrayOfVectors(vectors: [8]vm.Vector2Int) Vector2Int_x8 {
|
|
||||||
const vector: @Vector(16, i32) = @as([16]i32, @bitCast(vectors));
|
|
||||||
return .{
|
|
||||||
.x = @shuffle(i32, vector, undefined, [_]i32{ 0, 2, 4, 6, 8, 10, 12, 14 }),
|
|
||||||
.y = @shuffle(i32, vector, undefined, [_]i32{ 1, 3, 5, 7, 9, 11, 13, 15 }),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn splat(vector: vm.Vector2Int) Vector2Int_x8 {
|
pub inline fn splat(vector: vm.Vector2Int) Vector2Int_x8 {
|
||||||
return .{ .x = vm.epi32(vector.x), .y = vm.epi32(vector.y) };
|
return .{ .x = vm.epi32(vector.x), .y = vm.epi32(vector.y) };
|
||||||
}
|
}
|
||||||
@@ -56,46 +48,10 @@ pub const Vector2Int_x8 = struct {
|
|||||||
return .{ .x = self.x, .y = self.y, .z = z, .w = w };
|
return .{ .x = self.x, .y = self.y, .z = z, .w = w };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn asArrayOfVectors(self: Vector2Int_x8) [8]vm.Vector2Int {
|
|
||||||
const vector: @Vector(16, i32) = self.x ++ self.y;
|
|
||||||
return @bitCast(@as([16]i32, @shuffle(i32, vector, undefined, [_]i32{
|
|
||||||
0, 8,
|
|
||||||
1, 9,
|
|
||||||
2, 10,
|
|
||||||
3, 11,
|
|
||||||
4, 12,
|
|
||||||
5, 13,
|
|
||||||
6, 14,
|
|
||||||
7, 15,
|
|
||||||
})));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn unpack(self: Vector2Int_x8) [2]vm.i32x8 {
|
pub inline fn unpack(self: Vector2Int_x8) [2]vm.i32x8 {
|
||||||
return .{ self.x, self.y };
|
return .{ self.x, self.y };
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- LOAD AND STORE ------------------------------------------------------
|
|
||||||
|
|
||||||
pub inline fn loadArrayOfVectors(self: *Vector2Int_x8, array: *const [8]vm.Vector2Int) void {
|
|
||||||
const vector: @Vector(16, i32) = @as(*const [16]i32, @ptrCast(array)).*;
|
|
||||||
self.x = @shuffle(i32, vector, undefined, [_]i32{ 0, 2, 4, 6, 8, 10, 12, 14 });
|
|
||||||
self.y = @shuffle(i32, vector, undefined, [_]i32{ 1, 3, 5, 7, 9, 11, 13, 15 });
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn storeArrayOfVectors(self: *const Vector2Int_x8, array: *[8]vm.Vector2Int) void {
|
|
||||||
const vector: @Vector(16, i32) = self.x ++ self.y;
|
|
||||||
@as(*[16]i32, @ptrCast(array)).* = @shuffle(i32, vector, undefined, [_]i32{
|
|
||||||
0, 8,
|
|
||||||
1, 9,
|
|
||||||
2, 10,
|
|
||||||
3, 11,
|
|
||||||
4, 12,
|
|
||||||
5, 13,
|
|
||||||
6, 14,
|
|
||||||
7, 15,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- COMPONENT-WISE ------------------------------------------------------
|
// --- COMPONENT-WISE ------------------------------------------------------
|
||||||
|
|
||||||
pub inline fn add(self: Vector2Int_x8, other: Vector2Int_x8) Vector2Int_x8 {
|
pub inline fn add(self: Vector2Int_x8, other: Vector2Int_x8) Vector2Int_x8 {
|
||||||
|
|||||||
@@ -30,14 +30,6 @@ pub const Vector2x8 = struct {
|
|||||||
return .{ .x = vm.ps(scalar), .y = vm.ps(scalar) };
|
return .{ .x = vm.ps(scalar), .y = vm.ps(scalar) };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initArrayOfVectors(vectors: [8]vm.Vector2) Vector2x8 {
|
|
||||||
const vector: @Vector(16, f32) = @as([16]f32, @bitCast(vectors));
|
|
||||||
return .{
|
|
||||||
.x = @shuffle(f32, vector, undefined, [_]i32{ 0, 2, 4, 6, 8, 10, 12, 14 }),
|
|
||||||
.y = @shuffle(f32, vector, undefined, [_]i32{ 1, 3, 5, 7, 9, 11, 13, 15 }),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn splat(vector: vm.Vector2) Vector2x8 {
|
pub inline fn splat(vector: vm.Vector2) Vector2x8 {
|
||||||
return .{ .x = vm.ps(vector.x), .y = vm.ps(vector.y) };
|
return .{ .x = vm.ps(vector.x), .y = vm.ps(vector.y) };
|
||||||
}
|
}
|
||||||
@@ -56,46 +48,10 @@ pub const Vector2x8 = struct {
|
|||||||
return .{ .x = self.x, .y = self.y, .z = z, .w = w };
|
return .{ .x = self.x, .y = self.y, .z = z, .w = w };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn asArrayOfVectors(self: Vector2x8) [8]vm.Vector2 {
|
|
||||||
const vector: @Vector(16, f32) = self.x ++ self.y;
|
|
||||||
return @bitCast(@as([16]f32, @shuffle(f32, vector, undefined, [_]i32{
|
|
||||||
0, 8,
|
|
||||||
1, 9,
|
|
||||||
2, 10,
|
|
||||||
3, 11,
|
|
||||||
4, 12,
|
|
||||||
5, 13,
|
|
||||||
6, 14,
|
|
||||||
7, 15,
|
|
||||||
})));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn unpack(self: Vector2x8) [2]vm.f32x8 {
|
pub inline fn unpack(self: Vector2x8) [2]vm.f32x8 {
|
||||||
return .{ self.x, self.y };
|
return .{ self.x, self.y };
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- LOAD AND STORE ------------------------------------------------------
|
|
||||||
|
|
||||||
pub inline fn loadArrayOfVectors(self: *Vector2x8, array: *const [8]vm.Vector2) void {
|
|
||||||
const vector: @Vector(16, f32) = @as(*const [16]f32, @ptrCast(array)).*;
|
|
||||||
self.x = @shuffle(f32, vector, undefined, [_]i32{ 0, 2, 4, 6, 8, 10, 12, 14 });
|
|
||||||
self.y = @shuffle(f32, vector, undefined, [_]i32{ 1, 3, 5, 7, 9, 11, 13, 15 });
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn storeArrayOfVectors(self: *const Vector2x8, array: *[8]vm.Vector2) void {
|
|
||||||
const vector: @Vector(16, f32) = self.x ++ self.y;
|
|
||||||
@as(*[16]f32, @ptrCast(array)).* = @shuffle(f32, vector, undefined, [_]i32{
|
|
||||||
0, 8,
|
|
||||||
1, 9,
|
|
||||||
2, 10,
|
|
||||||
3, 11,
|
|
||||||
4, 12,
|
|
||||||
5, 13,
|
|
||||||
6, 14,
|
|
||||||
7, 15,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- COMPONENT-WISE ------------------------------------------------------
|
// --- COMPONENT-WISE ------------------------------------------------------
|
||||||
|
|
||||||
pub inline fn add(self: Vector2x8, other: Vector2x8) Vector2x8 {
|
pub inline fn add(self: Vector2x8, other: Vector2x8) Vector2x8 {
|
||||||
|
|||||||
@@ -28,13 +28,13 @@ pub const Vector3 = extern struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initArray(array: Array) Vector3 {
|
pub inline fn initArray(array: Array) Vector3 {
|
||||||
return @bitCast(array);
|
return @as(*const Vector3, @ptrCast(&array)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- CONVERSION ----------------------------------------------------------
|
// --- CONVERSION ----------------------------------------------------------
|
||||||
|
|
||||||
pub inline fn asArray(self: Vector3) Array {
|
pub inline fn asArray(self: Vector3) Array {
|
||||||
return @bitCast(self);
|
return @as(*const Array, @ptrCast(self)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn asInt(self: Vector3) vm.Vector3Int {
|
pub inline fn asInt(self: Vector3) vm.Vector3Int {
|
||||||
|
|||||||
@@ -28,13 +28,13 @@ pub const Vector3Int = extern struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initArray(array: Array) Vector3Int {
|
pub inline fn initArray(array: Array) Vector3Int {
|
||||||
return @bitCast(array);
|
return @as(*const Vector3Int, @ptrCast(&array)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- CONVERSION ----------------------------------------------------------
|
// --- CONVERSION ----------------------------------------------------------
|
||||||
|
|
||||||
pub inline fn asArray(self: Vector3Int) Array {
|
pub inline fn asArray(self: Vector3Int) Array {
|
||||||
return @bitCast(self);
|
return @as(*const Array, @ptrCast(self)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn asFloat(self: Vector3Int) vm.Vector3 {
|
pub inline fn asFloat(self: Vector3Int) vm.Vector3 {
|
||||||
|
|||||||
@@ -33,15 +33,6 @@ pub const Vector3Int_x8 = struct {
|
|||||||
return .{ .x = vm.epi32(scalar), .y = vm.epi32(scalar), .z = vm.epi32(scalar) };
|
return .{ .x = vm.epi32(scalar), .y = vm.epi32(scalar), .z = vm.epi32(scalar) };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initArrayOfVectors(vectors: [8]vm.Vector3Int) Vector3Int_x8 {
|
|
||||||
const vector: @Vector(24, i32) = @as([24]i32, @bitCast(vectors));
|
|
||||||
return .{
|
|
||||||
.x = @shuffle(i32, vector, undefined, [_]i32{ 0, 3, 6, 9, 12, 15, 18, 21 }),
|
|
||||||
.y = @shuffle(i32, vector, undefined, [_]i32{ 1, 4, 7, 10, 13, 16, 19, 22 }),
|
|
||||||
.z = @shuffle(i32, vector, undefined, [_]i32{ 2, 5, 8, 11, 14, 17, 20, 23 }),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn splat(vector: vm.Vector3Int) Vector3Int_x8 {
|
pub inline fn splat(vector: vm.Vector3Int) Vector3Int_x8 {
|
||||||
return .{ .x = vm.epi32(vector.x), .y = vm.epi32(vector.y), .z = vm.epi32(vector.z) };
|
return .{ .x = vm.epi32(vector.x), .y = vm.epi32(vector.y), .z = vm.epi32(vector.z) };
|
||||||
}
|
}
|
||||||
@@ -60,47 +51,10 @@ pub const Vector3Int_x8 = struct {
|
|||||||
return .{ .x = self.x, .y = self.y, .z = self.z, .w = w };
|
return .{ .x = self.x, .y = self.y, .z = self.z, .w = w };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn asArrayOfVectors(self: Vector3Int_x8) [8]vm.Vector3Int {
|
|
||||||
const vector: @Vector(24, i32) = self.x ++ self.y ++ self.z;
|
|
||||||
return @bitCast(@as([16]i32, @shuffle(i32, vector, undefined, [_]i32{
|
|
||||||
0, 8, 16,
|
|
||||||
1, 9, 17,
|
|
||||||
2, 10, 18,
|
|
||||||
3, 11, 19,
|
|
||||||
4, 12, 20,
|
|
||||||
5, 13, 21,
|
|
||||||
6, 14, 22,
|
|
||||||
7, 15, 23,
|
|
||||||
})));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn unpack(self: Vector3Int_x8) [3]vm.i32x8 {
|
pub inline fn unpack(self: Vector3Int_x8) [3]vm.i32x8 {
|
||||||
return .{ self.x, self.y, self.z };
|
return .{ self.x, self.y, self.z };
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- LOAD AND STORE ------------------------------------------------------
|
|
||||||
|
|
||||||
pub inline fn loadArrayTranspose(self: *Vector3Int_x8, array: *const [8]vm.Vector3Int) void {
|
|
||||||
const vector: @Vector(24, i32) = @as(*const [24]i32, @ptrCast(array)).*;
|
|
||||||
self.x = @shuffle(i32, vector, undefined, [_]i32{ 0, 3, 6, 9, 12, 15, 18, 21 });
|
|
||||||
self.y = @shuffle(i32, vector, undefined, [_]i32{ 1, 4, 7, 10, 13, 16, 19, 22 });
|
|
||||||
self.z = @shuffle(i32, vector, undefined, [_]i32{ 2, 5, 8, 11, 14, 17, 20, 23 });
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn storeArrayOfVectors(self: *const Vector3Int_x8, array: *[8]vm.Vector3Int) void {
|
|
||||||
const vector: @Vector(24, i32) = self.x ++ self.y ++ self.z;
|
|
||||||
@as(*[24]i32, @ptrCast(array)).* = @shuffle(f32, vector, undefined, [_]i32{
|
|
||||||
0, 8, 16,
|
|
||||||
1, 9, 17,
|
|
||||||
2, 10, 18,
|
|
||||||
3, 11, 19,
|
|
||||||
4, 12, 20,
|
|
||||||
5, 13, 21,
|
|
||||||
6, 14, 22,
|
|
||||||
7, 15, 23,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- COMPONENT-WISE ------------------------------------------------------
|
// --- COMPONENT-WISE ------------------------------------------------------
|
||||||
|
|
||||||
pub inline fn add(self: Vector3Int_x8, other: Vector3Int_x8) Vector3Int_x8 {
|
pub inline fn add(self: Vector3Int_x8, other: Vector3Int_x8) Vector3Int_x8 {
|
||||||
|
|||||||
@@ -33,15 +33,6 @@ pub const Vector3x8 = struct {
|
|||||||
return .{ .x = vm.ps(scalar), .y = vm.ps(scalar), .z = vm.ps(scalar) };
|
return .{ .x = vm.ps(scalar), .y = vm.ps(scalar), .z = vm.ps(scalar) };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initArrayOfVectors(vectors: [8]vm.Vector3) Vector3x8 {
|
|
||||||
const vector: @Vector(24, f32) = @as([24]f32, @bitCast(vectors));
|
|
||||||
return .{
|
|
||||||
.x = @shuffle(f32, vector, undefined, [_]i32{ 0, 3, 6, 9, 12, 15, 18, 21 }),
|
|
||||||
.y = @shuffle(f32, vector, undefined, [_]i32{ 1, 4, 7, 10, 13, 16, 19, 22 }),
|
|
||||||
.z = @shuffle(f32, vector, undefined, [_]i32{ 2, 5, 8, 11, 14, 17, 20, 23 }),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn splat(vector: vm.Vector3) Vector3x8 {
|
pub inline fn splat(vector: vm.Vector3) Vector3x8 {
|
||||||
return .{ .x = vm.ps(vector.x), .y = vm.ps(vector.y), .z = vm.ps(vector.z) };
|
return .{ .x = vm.ps(vector.x), .y = vm.ps(vector.y), .z = vm.ps(vector.z) };
|
||||||
}
|
}
|
||||||
@@ -60,47 +51,10 @@ pub const Vector3x8 = struct {
|
|||||||
return .{ .x = self.x, .y = self.y, .z = self.z, .w = w };
|
return .{ .x = self.x, .y = self.y, .z = self.z, .w = w };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn asArrayOfVectors(self: Vector3x8) [8]vm.Vector3 {
|
|
||||||
const vector: @Vector(24, f32) = self.x ++ self.y ++ self.z;
|
|
||||||
return @bitCast(@as([16]f32, @shuffle(f32, vector, undefined, [_]i32{
|
|
||||||
0, 8, 16,
|
|
||||||
1, 9, 17,
|
|
||||||
2, 10, 18,
|
|
||||||
3, 11, 19,
|
|
||||||
4, 12, 20,
|
|
||||||
5, 13, 21,
|
|
||||||
6, 14, 22,
|
|
||||||
7, 15, 23,
|
|
||||||
})));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn unpack(self: Vector3x8) [3]vm.f32x8 {
|
pub inline fn unpack(self: Vector3x8) [3]vm.f32x8 {
|
||||||
return .{ self.x, self.y, self.z };
|
return .{ self.x, self.y, self.z };
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- LOAD AND STORE ------------------------------------------------------
|
|
||||||
|
|
||||||
pub inline fn loadArrayTranspose(self: *Vector3x8, array: *const [8]vm.Vector3) void {
|
|
||||||
const vector: @Vector(24, f32) = @as(*const [24]f32, @ptrCast(array)).*;
|
|
||||||
self.x = @shuffle(f32, vector, undefined, [_]i32{ 0, 3, 6, 9, 12, 15, 18, 21 });
|
|
||||||
self.y = @shuffle(f32, vector, undefined, [_]i32{ 1, 4, 7, 10, 13, 16, 19, 22 });
|
|
||||||
self.z = @shuffle(f32, vector, undefined, [_]i32{ 2, 5, 8, 11, 14, 17, 20, 23 });
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn storeArrayOfVectors(self: *const Vector3x8, array: *[8]vm.Vector3) void {
|
|
||||||
const vector: @Vector(24, f32) = self.x ++ self.y ++ self.z;
|
|
||||||
@as(*[24]f32, @ptrCast(array)).* = @shuffle(f32, vector, undefined, [_]i32{
|
|
||||||
0, 8, 16,
|
|
||||||
1, 9, 17,
|
|
||||||
2, 10, 18,
|
|
||||||
3, 11, 19,
|
|
||||||
4, 12, 20,
|
|
||||||
5, 13, 21,
|
|
||||||
6, 14, 22,
|
|
||||||
7, 15, 23,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- COMPONENT-WISE ------------------------------------------------------
|
// --- COMPONENT-WISE ------------------------------------------------------
|
||||||
|
|
||||||
pub inline fn add(self: Vector3x8, other: Vector3x8) Vector3x8 {
|
pub inline fn add(self: Vector3x8, other: Vector3x8) Vector3x8 {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ pub const Vector4 = extern struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initArray(array: Array) Vector4 {
|
pub inline fn initArray(array: Array) Vector4 {
|
||||||
return @bitCast(array);
|
return @as(*const Vector4, @ptrCast(&array)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- CONVERSION ----------------------------------------------------------
|
// --- CONVERSION ----------------------------------------------------------
|
||||||
@@ -41,7 +41,7 @@ pub const Vector4 = extern struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn asArray(self: Vector4) Array {
|
pub inline fn asArray(self: Vector4) Array {
|
||||||
return @bitCast(self);
|
return @as(*const Array, @ptrCast(self)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn dropW(self: Vector4) vm.Vector3 {
|
pub inline fn dropW(self: Vector4) vm.Vector3 {
|
||||||
|
|||||||
@@ -31,13 +31,13 @@ pub const Vector4Int = extern struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initArray(array: Array) Vector4Int {
|
pub inline fn initArray(array: Array) Vector4Int {
|
||||||
return @bitCast(array);
|
return @as(*const Vector4Int, @ptrCast(&array)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- CONVERSION ----------------------------------------------------------
|
// --- CONVERSION ----------------------------------------------------------
|
||||||
|
|
||||||
pub inline fn asArray(self: Vector4Int) Array {
|
pub inline fn asArray(self: Vector4Int) Array {
|
||||||
return @bitCast(self);
|
return @as(*const Array, @ptrCast(self)).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn asFloat(self: Vector4Int) vm.Vector4 {
|
pub inline fn asFloat(self: Vector4Int) vm.Vector4 {
|
||||||
|
|||||||
@@ -36,16 +36,6 @@ pub const Vector4Int_x8 = struct {
|
|||||||
return .{ .x = vm.epi32(scalar), .y = vm.epi32(scalar), .z = vm.epi32(scalar), .w = vm.epi32(scalar) };
|
return .{ .x = vm.epi32(scalar), .y = vm.epi32(scalar), .z = vm.epi32(scalar), .w = vm.epi32(scalar) };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initArrayOfVectors(vectors: [8]vm.Vector4Int) Vector4Int_x8 {
|
|
||||||
const vector: @Vector(32, i32) = @as([32]i32, @bitCast(vectors));
|
|
||||||
return .{
|
|
||||||
.x = @shuffle(i32, vector, undefined, [_]i32{ 0, 4, 8, 12, 16, 20, 24, 28 }),
|
|
||||||
.y = @shuffle(i32, vector, undefined, [_]i32{ 1, 5, 9, 13, 17, 21, 25, 29 }),
|
|
||||||
.z = @shuffle(i32, vector, undefined, [_]i32{ 2, 6, 10, 14, 18, 22, 26, 30 }),
|
|
||||||
.w = @shuffle(i32, vector, undefined, [_]i32{ 3, 7, 11, 15, 19, 23, 27, 31 }),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn initSplat(vector: vm.Vector4Int) Vector4Int_x8 {
|
pub inline fn initSplat(vector: vm.Vector4Int) Vector4Int_x8 {
|
||||||
return .{ .x = vm.epi32(vector.x), .y = vm.epi32(vector.y), .z = vm.epi32(vector.z), .w = vm.epi32(vector.w) };
|
return .{ .x = vm.epi32(vector.x), .y = vm.epi32(vector.y), .z = vm.epi32(vector.z), .w = vm.epi32(vector.w) };
|
||||||
}
|
}
|
||||||
@@ -64,48 +54,10 @@ pub const Vector4Int_x8 = struct {
|
|||||||
return .{ .x = self.x, .y = self.y };
|
return .{ .x = self.x, .y = self.y };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn asArrayOfVectors(self: Vector4Int_x8) [8]vm.Vector4 {
|
|
||||||
const vector: @Vector(32, i32) = self.x ++ self.y ++ self.z ++ self.w;
|
|
||||||
return @bitCast(@as([32]i32, @shuffle(i32, vector, undefined, [_]i32{
|
|
||||||
0, 8, 16, 24,
|
|
||||||
1, 9, 17, 25,
|
|
||||||
2, 10, 18, 26,
|
|
||||||
3, 11, 19, 27,
|
|
||||||
4, 12, 20, 28,
|
|
||||||
5, 13, 21, 29,
|
|
||||||
6, 14, 22, 30,
|
|
||||||
7, 15, 23, 31,
|
|
||||||
})));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn unpack(self: Vector4Int_x8) [4]vm.i32x8 {
|
pub inline fn unpack(self: Vector4Int_x8) [4]vm.i32x8 {
|
||||||
return .{ self.x, self.y, self.z, self.w };
|
return .{ self.x, self.y, self.z, self.w };
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- LOAD AND STORE ------------------------------------------------------
|
|
||||||
|
|
||||||
pub inline fn loadArrayOfVectors(self: *Vector4Int_x8, array: *const [8]vm.Vector4Int) void {
|
|
||||||
const vector: @Vector(32, i32) = @as(*const [32]i32, @ptrCast(array)).*;
|
|
||||||
self.x = @shuffle(i32, vector, undefined, [_]i32{ 0, 4, 8, 12, 16, 20, 24, 28 });
|
|
||||||
self.y = @shuffle(i32, vector, undefined, [_]i32{ 1, 5, 9, 13, 17, 21, 25, 29 });
|
|
||||||
self.z = @shuffle(i32, vector, undefined, [_]i32{ 2, 6, 10, 14, 18, 22, 26, 30 });
|
|
||||||
self.w = @shuffle(i32, vector, undefined, [_]i32{ 3, 7, 11, 15, 19, 23, 27, 31 });
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn storeArrayOfVectors(self: *const Vector4Int_x8, array: *[8]vm.Vector4Int) void {
|
|
||||||
const vector: @Vector(32, i32) = self.x ++ self.y ++ self.z ++ self.w;
|
|
||||||
@as(*[32]i32, @ptrCast(array)).* = @shuffle(i32, vector, undefined, [_]i32{
|
|
||||||
0, 8, 16, 24,
|
|
||||||
1, 9, 17, 25,
|
|
||||||
2, 10, 18, 26,
|
|
||||||
3, 11, 19, 27,
|
|
||||||
4, 12, 20, 28,
|
|
||||||
5, 13, 21, 29,
|
|
||||||
6, 14, 22, 30,
|
|
||||||
7, 15, 23, 31,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- COMPONENT-WISE ------------------------------------------------------
|
// --- COMPONENT-WISE ------------------------------------------------------
|
||||||
|
|
||||||
pub inline fn add(self: Vector4Int_x8, other: Vector4Int_x8) Vector4Int_x8 {
|
pub inline fn add(self: Vector4Int_x8, other: Vector4Int_x8) Vector4Int_x8 {
|
||||||
|
|||||||
@@ -36,16 +36,6 @@ pub const Vector4x8 = struct {
|
|||||||
return .{ .x = vm.ps(scalar), .y = vm.ps(scalar), .z = vm.ps(scalar), .w = vm.ps(scalar) };
|
return .{ .x = vm.ps(scalar), .y = vm.ps(scalar), .z = vm.ps(scalar), .w = vm.ps(scalar) };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn initArrayOfVectors(vectors: [8]vm.Vector4) Vector4x8 {
|
|
||||||
const vector: @Vector(32, f32) = @as([32]f32, @bitCast(vectors));
|
|
||||||
return .{
|
|
||||||
.x = @shuffle(f32, vector, undefined, [_]i32{ 0, 4, 8, 12, 16, 20, 24, 28 }),
|
|
||||||
.y = @shuffle(f32, vector, undefined, [_]i32{ 1, 5, 9, 13, 17, 21, 25, 29 }),
|
|
||||||
.z = @shuffle(f32, vector, undefined, [_]i32{ 2, 6, 10, 14, 18, 22, 26, 30 }),
|
|
||||||
.w = @shuffle(f32, vector, undefined, [_]i32{ 3, 7, 11, 15, 19, 23, 27, 31 }),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn splat(vector: vm.Vector4) Vector4x8 {
|
pub inline fn splat(vector: vm.Vector4) Vector4x8 {
|
||||||
return .{ .x = vm.ps(vector.x), .y = vm.ps(vector.y), .z = vm.ps(vector.z), .w = vm.ps(vector.w) };
|
return .{ .x = vm.ps(vector.x), .y = vm.ps(vector.y), .z = vm.ps(vector.z), .w = vm.ps(vector.w) };
|
||||||
}
|
}
|
||||||
@@ -64,48 +54,10 @@ pub const Vector4x8 = struct {
|
|||||||
return .{ .x = self.x, .y = self.y };
|
return .{ .x = self.x, .y = self.y };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn asArrayOfVectors(self: Vector4x8) [8]vm.Vector4 {
|
|
||||||
const vector: @Vector(32, f32) = self.x ++ self.y ++ self.z ++ self.w;
|
|
||||||
return @bitCast(@as([32]f32, @shuffle(f32, vector, undefined, [_]i32{
|
|
||||||
0, 8, 16, 24,
|
|
||||||
1, 9, 17, 25,
|
|
||||||
2, 10, 18, 26,
|
|
||||||
3, 11, 19, 27,
|
|
||||||
4, 12, 20, 28,
|
|
||||||
5, 13, 21, 29,
|
|
||||||
6, 14, 22, 30,
|
|
||||||
7, 15, 23, 31,
|
|
||||||
})));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn unpack(self: Vector4x8) [4]vm.f32x8 {
|
pub inline fn unpack(self: Vector4x8) [4]vm.f32x8 {
|
||||||
return .{ self.x, self.y, self.z, self.w };
|
return .{ self.x, self.y, self.z, self.w };
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- LOAD AND STORE ------------------------------------------------------
|
|
||||||
|
|
||||||
pub inline fn loadArrayOfVectors(self: *Vector4x8, array: *const [8]vm.Vector4) void {
|
|
||||||
const vector: @Vector(32, f32) = @as(*const [32]f32, @ptrCast(array)).*;
|
|
||||||
self.x = @shuffle(f32, vector, undefined, [_]i32{ 0, 4, 8, 12, 16, 20, 24, 28 });
|
|
||||||
self.y = @shuffle(f32, vector, undefined, [_]i32{ 1, 5, 9, 13, 17, 21, 25, 29 });
|
|
||||||
self.z = @shuffle(f32, vector, undefined, [_]i32{ 2, 6, 10, 14, 18, 22, 26, 30 });
|
|
||||||
self.w = @shuffle(f32, vector, undefined, [_]i32{ 3, 7, 11, 15, 19, 23, 27, 31 });
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn storeArrayOfVectors(self: *const Vector4x8, array: *[8]vm.Vector4) void {
|
|
||||||
const vector: @Vector(32, f32) = self.x ++ self.y ++ self.z ++ self.w;
|
|
||||||
@as(*[32]f32, @ptrCast(array)).* = @shuffle(f32, vector, undefined, [_]i32{
|
|
||||||
0, 8, 16, 24,
|
|
||||||
1, 9, 17, 25,
|
|
||||||
2, 10, 18, 26,
|
|
||||||
3, 11, 19, 27,
|
|
||||||
4, 12, 20, 28,
|
|
||||||
5, 13, 21, 29,
|
|
||||||
6, 14, 22, 30,
|
|
||||||
7, 15, 23, 31,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- COMPONENT-WISE ------------------------------------------------------
|
// --- COMPONENT-WISE ------------------------------------------------------
|
||||||
|
|
||||||
pub inline fn add(self: Vector4x8, other: Vector4x8) Vector4x8 {
|
pub inline fn add(self: Vector4x8, other: Vector4x8) Vector4x8 {
|
||||||
|
|||||||
@@ -4,6 +4,14 @@ pub fn build(b: *std.Build) void {
|
|||||||
const target = b.standardTargetOptions(.{});
|
const target = b.standardTargetOptions(.{});
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
|
const vulkan_dep = b.dependency("vulkan_zig", .{
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.registry = b.path("vendor/vk.xml"),
|
||||||
|
});
|
||||||
|
|
||||||
|
const vulkan_mod = vulkan_dep.module("vulkan-zig");
|
||||||
|
|
||||||
const mod = b.addModule("xcb", .{
|
const mod = b.addModule("xcb", .{
|
||||||
.root_source_file = b.path("src/root.zig"),
|
.root_source_file = b.path("src/root.zig"),
|
||||||
.target = target,
|
.target = target,
|
||||||
@@ -27,6 +35,7 @@ pub fn build(b: *std.Build) void {
|
|||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
.imports = &.{
|
.imports = &.{
|
||||||
|
.{ .name = "vulkan", .module = vulkan_mod },
|
||||||
.{ .name = "xcb", .module = mod },
|
.{ .name = "xcb", .module = mod },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,6 +2,12 @@
|
|||||||
.name = .xcb,
|
.name = .xcb,
|
||||||
.version = "0.0.0",
|
.version = "0.0.0",
|
||||||
.minimum_zig_version = "0.16.0",
|
.minimum_zig_version = "0.16.0",
|
||||||
|
.dependencies = .{
|
||||||
|
.vulkan_zig = .{
|
||||||
|
.url = "git+https://github.com/Snektron/vulkan-zig#b496a6a561ffbbeb530b0f9ed4e059f88c0723a5",
|
||||||
|
.hash = "vulkan-0.0.0-r7Ytx7N9AwD7IZt5_XNHtkJ4G9qY0pCH-cpcOsbL8wzD",
|
||||||
|
},
|
||||||
|
},
|
||||||
.paths = .{
|
.paths = .{
|
||||||
"src",
|
"src",
|
||||||
"build.zig",
|
"build.zig",
|
||||||
|
|||||||
176
packages/xcb/sample/Vulkan.zig
Normal file
176
packages/xcb/sample/Vulkan.zig
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
const Vulkan = @This();
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const vk = @import("vulkan");
|
||||||
|
const xcb = @import("xcb");
|
||||||
|
|
||||||
|
vulkan_loader: *DynamicLibrary,
|
||||||
|
|
||||||
|
base: vk.BaseWrapper,
|
||||||
|
instance: vk.InstanceProxy,
|
||||||
|
surface: vk.SurfaceKHR,
|
||||||
|
device: vk.DeviceProxy,
|
||||||
|
|
||||||
|
queue_family: u32,
|
||||||
|
queue: vk.Queue,
|
||||||
|
command_pool: vk.CommandPool,
|
||||||
|
|
||||||
|
pub fn init(allocator: std.mem.Allocator, connection: *xcb.Connection, window: xcb.Window) !Vulkan {
|
||||||
|
const vulkan_loader = try DynamicLibrary.open("libvulkan.so.1");
|
||||||
|
errdefer vulkan_loader.close();
|
||||||
|
|
||||||
|
const vkGetInstanceProcAddr = try vulkan_loader.sym(vk.PfnGetInstanceProcAddr, "vkGetInstanceProcAddr");
|
||||||
|
|
||||||
|
const base = vk.BaseWrapper.load(vkGetInstanceProcAddr);
|
||||||
|
|
||||||
|
const instance_handle = blk: {
|
||||||
|
const enabled_layers: []const [*:0]const u8 = &.{};
|
||||||
|
const enabled_extensions: []const [*:0]const u8 = &.{
|
||||||
|
vk.extensions.khr_surface.name,
|
||||||
|
vk.extensions.khr_xcb_surface.name,
|
||||||
|
};
|
||||||
|
|
||||||
|
break :blk try base.createInstance(&.{
|
||||||
|
.p_application_info = &.{
|
||||||
|
.p_application_name = "xcb_sample",
|
||||||
|
.application_version = vk.makeApiVersion(0, 0, 0, 0).toU32(),
|
||||||
|
.p_engine_name = "xcb_sample",
|
||||||
|
.engine_version = vk.makeApiVersion(0, 0, 0, 0).toU32(),
|
||||||
|
.api_version = vk.API_VERSION_1_0.toU32(),
|
||||||
|
},
|
||||||
|
.enabled_layer_count = @intCast(enabled_layers.len),
|
||||||
|
.pp_enabled_layer_names = enabled_layers.ptr,
|
||||||
|
.enabled_extension_count = @intCast(enabled_extensions.len),
|
||||||
|
.pp_enabled_extension_names = enabled_extensions.ptr,
|
||||||
|
}, null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const instance_wrapper_ptr = try allocator.create(vk.InstanceWrapper);
|
||||||
|
errdefer allocator.destroy(instance_wrapper_ptr);
|
||||||
|
|
||||||
|
instance_wrapper_ptr.* = .load(instance_handle, vkGetInstanceProcAddr);
|
||||||
|
const instance = vk.InstanceProxy.init(instance_handle, instance_wrapper_ptr);
|
||||||
|
errdefer instance.destroyInstance(null);
|
||||||
|
|
||||||
|
const surface = try instance.createXcbSurfaceKHR(&.{
|
||||||
|
.connection = connection,
|
||||||
|
.window = window,
|
||||||
|
}, null);
|
||||||
|
errdefer instance.destroySurfaceKHR(surface, null);
|
||||||
|
|
||||||
|
const physical_device = blk: {
|
||||||
|
const physical_devices = try instance.enumeratePhysicalDevicesAlloc(allocator);
|
||||||
|
defer allocator.free(physical_devices);
|
||||||
|
|
||||||
|
if (physical_devices.len > 0) {
|
||||||
|
break :blk physical_devices[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return error.NoDevice;
|
||||||
|
};
|
||||||
|
|
||||||
|
const queue_family: u32 = blk: {
|
||||||
|
const queue_families_properties = try instance.getPhysicalDeviceQueueFamilyPropertiesAlloc(physical_device, allocator);
|
||||||
|
defer allocator.free(queue_families_properties);
|
||||||
|
|
||||||
|
// Look for the first family that has the `graphics_bit` set and
|
||||||
|
// supports presentation to a given surface.
|
||||||
|
|
||||||
|
for (queue_families_properties, 0..) |queue_family_properties, i| {
|
||||||
|
const graphics_bit = queue_family_properties.queue_flags.graphics_bit;
|
||||||
|
const supports_presentation = try instance.getPhysicalDeviceSurfaceSupportKHR(physical_device, @intCast(i), surface) != .false;
|
||||||
|
|
||||||
|
if (graphics_bit and supports_presentation) {
|
||||||
|
break :blk @intCast(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return error.NoQueue;
|
||||||
|
};
|
||||||
|
|
||||||
|
const device_handle = blk: {
|
||||||
|
const queue_create_infos: []const vk.DeviceQueueCreateInfo = &.{
|
||||||
|
.{
|
||||||
|
.queue_family_index = queue_family,
|
||||||
|
.queue_count = 1,
|
||||||
|
.p_queue_priorities = &.{0},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const enabled_extensions: []const [*:0]const u8 = &.{
|
||||||
|
vk.extensions.khr_swapchain.name,
|
||||||
|
};
|
||||||
|
|
||||||
|
break :blk try instance.createDevice(physical_device, &.{
|
||||||
|
.queue_create_info_count = @intCast(queue_create_infos.len),
|
||||||
|
.p_queue_create_infos = queue_create_infos.ptr,
|
||||||
|
.enabled_extension_count = @intCast(enabled_extensions.len),
|
||||||
|
.pp_enabled_extension_names = enabled_extensions.ptr,
|
||||||
|
}, null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const device_wrapper_ptr = try allocator.create(vk.DeviceWrapper);
|
||||||
|
errdefer allocator.destroy(device_wrapper_ptr);
|
||||||
|
|
||||||
|
device_wrapper_ptr.* = .load(device_handle, instance.wrapper.dispatch.vkGetDeviceProcAddr.?);
|
||||||
|
const device = vk.DeviceProxy.init(device_handle, device_wrapper_ptr);
|
||||||
|
errdefer device.destroyDevice(null);
|
||||||
|
|
||||||
|
const queue = device.getDeviceQueue(queue_family, 0);
|
||||||
|
|
||||||
|
const command_pool = try device.createCommandPool(&.{
|
||||||
|
.flags = .{ .transient_bit = true },
|
||||||
|
.queue_family_index = queue_family,
|
||||||
|
}, null);
|
||||||
|
errdefer device.destroyCommandPool(command_pool, null);
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.vulkan_loader = vulkan_loader,
|
||||||
|
|
||||||
|
.base = base,
|
||||||
|
.instance = instance,
|
||||||
|
.surface = surface,
|
||||||
|
.device = device,
|
||||||
|
|
||||||
|
.queue_family = queue_family,
|
||||||
|
.queue = queue,
|
||||||
|
.command_pool = command_pool,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *Vulkan, allocator: std.mem.Allocator) void {
|
||||||
|
self.device.destroyCommandPool(self.command_pool, null);
|
||||||
|
|
||||||
|
self.device.destroyDevice(null);
|
||||||
|
allocator.destroy(self.device.wrapper);
|
||||||
|
self.instance.destroySurfaceKHR(self.surface, null);
|
||||||
|
self.instance.destroyInstance(null);
|
||||||
|
allocator.destroy(self.instance.wrapper);
|
||||||
|
|
||||||
|
self.vulkan_loader.close();
|
||||||
|
|
||||||
|
self.* = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const DynamicLibrary = opaque {
|
||||||
|
fn open(path: [*:0]const u8) !*DynamicLibrary {
|
||||||
|
const ptr = std.c.dlopen(path, .{ .NOW = true }) orelse {
|
||||||
|
std.debug.print("{s}\n", .{std.c.dlerror().?});
|
||||||
|
return error.DlOpen;
|
||||||
|
};
|
||||||
|
|
||||||
|
return @ptrCast(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn close(self: *DynamicLibrary) void {
|
||||||
|
_ = std.c.dlclose(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sym(self: *DynamicLibrary, comptime Ptr: type, symbol: [*:0]const u8) !Ptr {
|
||||||
|
const ptr = std.c.dlsym(self, symbol) orelse {
|
||||||
|
std.debug.print("{s}\n", .{std.c.dlerror().?});
|
||||||
|
return error.DlSym;
|
||||||
|
};
|
||||||
|
|
||||||
|
return @ptrCast(@alignCast(ptr));
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,9 +1,15 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const xcb = @import("xcb");
|
const xcb = @import("xcb");
|
||||||
|
|
||||||
pub fn main(init: std.process.Init) !void {
|
const Vulkan = @import("Vulkan.zig");
|
||||||
_ = init;
|
|
||||||
|
|
||||||
|
// Declarations picked up by "vulkan" module
|
||||||
|
|
||||||
|
pub const xcb_connection_t = xcb.Connection;
|
||||||
|
pub const xcb_visualid_t = xcb.Visualid;
|
||||||
|
pub const xcb_window_t = xcb.Window;
|
||||||
|
|
||||||
|
pub fn main(init: std.process.Init) !void {
|
||||||
const connection = xcb.Connection.connect(null, null);
|
const connection = xcb.Connection.connect(null, null);
|
||||||
defer connection.disconnect();
|
defer connection.disconnect();
|
||||||
|
|
||||||
@@ -64,6 +70,9 @@ pub fn main(init: std.process.Init) !void {
|
|||||||
_ = connection.mapWindow(window);
|
_ = connection.mapWindow(window);
|
||||||
_ = connection.flush();
|
_ = connection.flush();
|
||||||
|
|
||||||
|
var vulkan = try Vulkan.init(init.gpa, connection, window);
|
||||||
|
defer vulkan.deinit(init.gpa);
|
||||||
|
|
||||||
var running = true;
|
var running = true;
|
||||||
while (running) {
|
while (running) {
|
||||||
if (connection.waitForEvent()) |event| {
|
if (connection.waitForEvent()) |event| {
|
||||||
|
|||||||
35719
packages/xcb/vendor/vk.xml
vendored
Normal file
35719
packages/xcb/vendor/vk.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user