updating to Zig 0.16
Some checks failed
Build / build (push) Failing after 32s
Test / build (push) Successful in 7m50s

This commit is contained in:
2026-04-16 01:50:42 +02:00
parent 9f586ae9c0
commit 4bd688cf07
9 changed files with 330 additions and 378 deletions

1
.gitignore vendored
View File

@@ -1,5 +1,6 @@
.zig-cache/
zig-out/
zig-pkg/
.gdb_history
*.o
vgcore*

View File

@@ -30,7 +30,7 @@ pub fn build(b: *std.Build) void {
const no_example = b.option(bool, "no-example", "skips example dependencies fetch") orelse false;
if (!no_example) {
if (!no_example and false) {
const sdl3 = b.lazyDependency("sdl3", .{ .target = target, .optimize = optimize }) orelse return;
const example_exe = b.addExecutable(.{
.name = "spirv_interpreter_example",

View File

@@ -6,22 +6,22 @@
.url = "git+https://github.com/zig-gamedev/zmath.git#3a5955b2b72cd081563fbb084eff05bffd1e3fbb",
.hash = "zmath-0.11.0-dev-wjwivdMsAwD-xaLj76YHUq3t9JDH-X16xuMTmnDzqbu2",
},
.pretty = .{ // For debugging purposes
.url = "git+https://github.com/Kbz-8/pretty#117674465efd4d07d5ae9d9d8ca59c2c323a65ba",
.hash = "pretty-0.10.6-Tm65r99UAQDEJMgZysD10qE8dinBHr064fPM6YkxVPfB",
},
.NZSL = .{ // For unit tests
.url = "git+https://git.kbz8.me/kbz_8/NZigSL#5377dbdf9935b0de767f76ea4650e7aba4516b32",
.hash = "NZSL-1.1.2-N0xSVMt6AAC1ncQHA_RafnclWolDA477iTnFmZgdvxd-",
.url = "git+https://git.kbz8.me/kbz_8/NZigSL#ab95fc3734da46079fda2a4cd0f14143d92bf633",
.hash = "NZSL-1.1.2-N0xSVCR7AACeI_Wa6JPggJzy9_MPCpWC-2OHkMowwX-7",
.lazy = true,
},
.sdl3 = .{
.url = "git+https://codeberg.org/7Games/zig-sdl3?ref=v0.1.6#9c1842246c59f03f87ba59b160ca7e3d5e5ce972",
.hash = "sdl3-0.1.6-NmT1Q5sQJgCzT6hLj7WOSrwxE0Qsef1wIkDopbOOFru0",
.lazy = true,
//.sdl3 = .{
// .url = "git+https://codeberg.org/7Games/zig-sdl3?ref=v0.1.6#9c1842246c59f03f87ba59b160ca7e3d5e5ce972",
// .hash = "sdl3-0.1.6-NmT1Q5sQJgCzT6hLj7WOSrwxE0Qsef1wIkDopbOOFru0",
// .lazy = true,
//},
.pretty = .{
.url = "git+https://github.com/Kbz-8/pretty#d87459a829fe0ae82b408155053e1933e2a16a15",
.hash = "pretty-0.10.6-Tm65rw5VAQDqJ-sbE6eoU-yOAr7kzUmAUrUQd7Wzaa9Q",
},
},
.minimum_zig_version = "0.15.2",
.minimum_zig_version = "0.16.0",
.paths = .{
"build.zig",
"build.zig.zon",

View File

@@ -127,45 +127,6 @@ pub fn init(allocator: std.mem.Allocator, source: []const SpvWord, options: Modu
try self.pass(allocator); // Setup pass
try self.applyDecorations();
if (std.process.hasEnvVarConstant("SPIRV_INTERPRETER_DEBUG_LOGS")) {
var capability_set_names: std.ArrayList([]const u8) = .empty;
defer capability_set_names.deinit(allocator);
var it = self.capabilities.iterator();
while (it.next()) |cap| {
capability_set_names.append(allocator, @tagName(cap)) catch return ModuleError.OutOfMemory;
}
const capabilities = std.mem.join(allocator, ", ", capability_set_names.items) catch return ModuleError.OutOfMemory;
defer allocator.free(capabilities);
var entry_points_names = std.ArrayList([]const u8).initCapacity(allocator, self.entry_points.items.len) catch return ModuleError.OutOfMemory;
defer entry_points_names.deinit(allocator);
for (self.entry_points.items) |entry_point| {
entry_points_names.appendAssumeCapacity(entry_point.name);
}
const entry_points = std.mem.join(allocator, ", ", entry_points_names.items) catch return ModuleError.OutOfMemory;
defer allocator.free(entry_points);
std.log.scoped(.SPIRV_Interpreter).debug(
\\Loaded shader module with infos:
\\ SPIR-V version: {d}.{d}
\\ Generator: {s} (ID {d}), encoded version 0x{X}
\\ Capabilities: [{s}]
\\ Entry points: [{s}]
, .{
self.version_major,
self.version_minor,
spv.vendorName(self.generator_id),
self.generator_id,
self.generator_version,
capabilities,
entry_points,
});
}
return self;
}

View File

@@ -667,13 +667,31 @@ pub const Value = union(Type) {
.Vector => |lanes| (try getPrimitiveField(T, bits, &lanes[lane_index])).*,
.Vector4i32 => |vec| if (bits == 32) @as(TT, @bitCast(vec[lane_index])) else return RuntimeError.InvalidSpirV,
.Vector3i32 => |vec| if (bits == 32) @as(TT, @bitCast(vec[lane_index])) else return RuntimeError.InvalidSpirV,
.Vector2i32 => |vec| if (bits == 32) @as(TT, @bitCast(vec[lane_index])) else return RuntimeError.InvalidSpirV,
.Vector2i32 => |*vec| switch (lane_index) {
inline 0...1 => |i| if (bits == 32) @as(TT, @bitCast(vec[i])) else return RuntimeError.InvalidSpirV,
else => return RuntimeError.InvalidSpirV,
},
.Vector3i32 => |*vec| switch (lane_index) {
inline 0...2 => |i| if (bits == 32) @as(TT, @bitCast(vec[i])) else return RuntimeError.InvalidSpirV,
else => return RuntimeError.InvalidSpirV,
},
.Vector4i32 => |*vec| switch (lane_index) {
inline 0...3 => |i| if (bits == 32) @as(TT, @bitCast(vec[i])) else return RuntimeError.InvalidSpirV,
else => return RuntimeError.InvalidSpirV,
},
.Vector4u32 => |vec| if (bits == 32) @as(TT, @bitCast(vec[lane_index])) else return RuntimeError.InvalidSpirV,
.Vector3u32 => |vec| if (bits == 32) @as(TT, @bitCast(vec[lane_index])) else return RuntimeError.InvalidSpirV,
.Vector2u32 => |vec| if (bits == 32) @as(TT, @bitCast(vec[lane_index])) else return RuntimeError.InvalidSpirV,
.Vector2u32 => |*vec| switch (lane_index) {
inline 0...1 => |i| if (bits == 32) @as(TT, @bitCast(vec[i])) else return RuntimeError.InvalidSpirV,
else => return RuntimeError.InvalidSpirV,
},
.Vector3u32 => |*vec| switch (lane_index) {
inline 0...2 => |i| if (bits == 32) @as(TT, @bitCast(vec[i])) else return RuntimeError.InvalidSpirV,
else => return RuntimeError.InvalidSpirV,
},
.Vector4u32 => |*vec| switch (lane_index) {
inline 0...3 => |i| if (bits == 32) @as(TT, @bitCast(vec[i])) else return RuntimeError.InvalidSpirV,
else => return RuntimeError.InvalidSpirV,
},
else => RuntimeError.InvalidSpirV,
};
@@ -685,13 +703,31 @@ pub const Value = union(Type) {
.Vector => |lanes| try setScalarLaneValue(T, bits, &lanes[lane_index], value),
.Vector2i32 => |*vec| vec[lane_index] = if (bits == 32) @bitCast(value) else return RuntimeError.InvalidSpirV,
.Vector3i32 => |*vec| vec[lane_index] = if (bits == 32) @bitCast(value) else return RuntimeError.InvalidSpirV,
.Vector4i32 => |*vec| vec[lane_index] = if (bits == 32) @bitCast(value) else return RuntimeError.InvalidSpirV,
.Vector2i32 => |*vec| switch (lane_index) {
inline 0...1 => |i| vec[i] = if (bits == 32) @bitCast(value) else return RuntimeError.InvalidSpirV,
else => return RuntimeError.InvalidSpirV,
},
.Vector3i32 => |*vec| switch (lane_index) {
inline 0...2 => |i| vec[i] = if (bits == 32) @bitCast(value) else return RuntimeError.InvalidSpirV,
else => return RuntimeError.InvalidSpirV,
},
.Vector4i32 => |*vec| switch (lane_index) {
inline 0...3 => |i| vec[i] = if (bits == 32) @bitCast(value) else return RuntimeError.InvalidSpirV,
else => return RuntimeError.InvalidSpirV,
},
.Vector2u32 => |*vec| vec[lane_index] = if (bits == 32) @bitCast(value) else return RuntimeError.InvalidSpirV,
.Vector3u32 => |*vec| vec[lane_index] = if (bits == 32) @bitCast(value) else return RuntimeError.InvalidSpirV,
.Vector4u32 => |*vec| vec[lane_index] = if (bits == 32) @bitCast(value) else return RuntimeError.InvalidSpirV,
.Vector2u32 => |*vec| switch (lane_index) {
inline 0...1 => |i| vec[i] = if (bits == 32) @bitCast(value) else return RuntimeError.InvalidSpirV,
else => return RuntimeError.InvalidSpirV,
},
.Vector3u32 => |*vec| switch (lane_index) {
inline 0...2 => |i| vec[i] = if (bits == 32) @bitCast(value) else return RuntimeError.InvalidSpirV,
else => return RuntimeError.InvalidSpirV,
},
.Vector4u32 => |*vec| switch (lane_index) {
inline 0...3 => |i| vec[i] = if (bits == 32) @bitCast(value) else return RuntimeError.InvalidSpirV,
else => return RuntimeError.InvalidSpirV,
},
else => return RuntimeError.InvalidSpirV,
}

View File

@@ -646,8 +646,8 @@ fn CondOperator(comptime T: PrimitiveType, comptime Op: CondOp) type {
comptime ElemT: type,
comptime N: usize,
dst: []Value,
op1: *[N]ElemT,
op2: *[N]ElemT,
op1: *@Vector(N, ElemT),
op2: *@Vector(N, ElemT),
) RuntimeError!void {
inline for (0..N) |i| dst[i].Bool = try operationBinary(ElemT, op1[i], op2[i]);
}
@@ -656,7 +656,7 @@ fn CondOperator(comptime T: PrimitiveType, comptime Op: CondOp) type {
comptime ElemT: type,
comptime N: usize,
dst: []Value,
op1: *[N]ElemT,
op1: *@Vector(N, ElemT),
) RuntimeError!void {
inline for (0..N) |i| dst[i].Bool = try operationUnary(ElemT, op1[i]);
}
@@ -796,11 +796,11 @@ fn ConversionEngine(comptime from_kind: PrimitiveType, comptime to_kind: Primiti
}
}
fn castSIMDVector(comptime ToT: type, comptime N: usize, dst_arr: *[N]ToT, src_arr: *const [N]ToT) void {
fn castSIMDVector(comptime ToT: type, comptime N: usize, dst_arr: *@Vector(N, ToT), src_arr: *const @Vector(N, ToT)) void {
inline for (0..N) |i| dst_arr[i] = std.math.lossyCast(ToT, src_arr[i]);
}
fn castSIMDVectorFromOther(comptime ToT: type, comptime FromT: type, comptime N: usize, dst_arr: *[N]ToT, src_arr: *const [N]FromT) void {
fn castSIMDVectorFromOther(comptime ToT: type, comptime FromT: type, comptime N: usize, dst_arr: *@Vector(N, ToT), src_arr: *const @Vector(N, FromT)) void {
inline for (0..N) |i| dst_arr[i] = std.math.lossyCast(ToT, src_arr[i]);
}
};
@@ -1320,41 +1320,41 @@ fn opAccessChain(allocator: std.mem.Allocator, word_count: SpvWord, rt: *Runtime
is_owner_of_uniform_slice = true;
uniform_slice_window = arr.data[arr.getOffsetOfIndex(i.value.uint32)..];
},
.Vector4f32 => |*v| {
if (i.value.uint32 >= 4) return RuntimeError.OutOfBounds;
break :blk .{ .Pointer = .{ .ptr = .{ .f32_ptr = &v[i.value.uint32] } } };
.Vector4f32 => |*v| switch (i.value.uint32) {
inline 0...3 => |idx| break :blk .{ .Pointer = .{ .ptr = .{ .f32_ptr = &v[idx] } } },
else => return RuntimeError.InvalidSpirV,
},
.Vector3f32 => |*v| {
if (i.value.uint32 >= 3) return RuntimeError.OutOfBounds;
break :blk .{ .Pointer = .{ .ptr = .{ .f32_ptr = &v[i.value.uint32] } } };
.Vector3f32 => |*v| switch (i.value.uint32) {
inline 0...2 => |idx| break :blk .{ .Pointer = .{ .ptr = .{ .f32_ptr = &v[idx] } } },
else => return RuntimeError.InvalidSpirV,
},
.Vector2f32 => |*v| {
if (i.value.uint32 >= 2) return RuntimeError.OutOfBounds;
break :blk .{ .Pointer = .{ .ptr = .{ .f32_ptr = &v[i.value.uint32] } } };
.Vector2f32 => |*v| switch (i.value.uint32) {
inline 0...1 => |idx| break :blk .{ .Pointer = .{ .ptr = .{ .f32_ptr = &v[idx] } } },
else => return RuntimeError.InvalidSpirV,
},
.Vector4i32 => |*v| {
if (i.value.uint32 >= 4) return RuntimeError.OutOfBounds;
break :blk .{ .Pointer = .{ .ptr = .{ .i32_ptr = &v[i.value.uint32] } } };
.Vector4i32 => |*v| switch (i.value.uint32) {
inline 0...3 => |idx| break :blk .{ .Pointer = .{ .ptr = .{ .i32_ptr = &v[idx] } } },
else => return RuntimeError.InvalidSpirV,
},
.Vector3i32 => |*v| {
if (i.value.uint32 >= 3) return RuntimeError.OutOfBounds;
break :blk .{ .Pointer = .{ .ptr = .{ .i32_ptr = &v[i.value.uint32] } } };
.Vector3i32 => |*v| switch (i.value.uint32) {
inline 0...2 => |idx| break :blk .{ .Pointer = .{ .ptr = .{ .i32_ptr = &v[idx] } } },
else => return RuntimeError.InvalidSpirV,
},
.Vector2i32 => |*v| {
if (i.value.uint32 >= 2) return RuntimeError.OutOfBounds;
break :blk .{ .Pointer = .{ .ptr = .{ .i32_ptr = &v[i.value.uint32] } } };
.Vector2i32 => |*v| switch (i.value.uint32) {
inline 0...1 => |idx| break :blk .{ .Pointer = .{ .ptr = .{ .i32_ptr = &v[idx] } } },
else => return RuntimeError.InvalidSpirV,
},
.Vector4u32 => |*v| {
if (i.value.uint32 >= 4) return RuntimeError.OutOfBounds;
break :blk .{ .Pointer = .{ .ptr = .{ .u32_ptr = &v[i.value.uint32] } } };
.Vector4u32 => |*v| switch (i.value.uint32) {
inline 0...3 => |idx| break :blk .{ .Pointer = .{ .ptr = .{ .u32_ptr = &v[idx] } } },
else => return RuntimeError.InvalidSpirV,
},
.Vector3u32 => |*v| {
if (i.value.uint32 >= 3) return RuntimeError.OutOfBounds;
break :blk .{ .Pointer = .{ .ptr = .{ .u32_ptr = &v[i.value.uint32] } } };
.Vector3u32 => |*v| switch (i.value.uint32) {
inline 0...2 => |idx| break :blk .{ .Pointer = .{ .ptr = .{ .u32_ptr = &v[idx] } } },
else => return RuntimeError.InvalidSpirV,
},
.Vector2u32 => |*v| {
if (i.value.uint32 >= 2) return RuntimeError.OutOfBounds;
break :blk .{ .Pointer = .{ .ptr = .{ .u32_ptr = &v[i.value.uint32] } } };
.Vector2u32 => |*v| switch (i.value.uint32) {
inline 0...1 => |idx| break :blk .{ .Pointer = .{ .ptr = .{ .u32_ptr = &v[idx] } } },
else => return RuntimeError.InvalidSpirV,
},
else => return RuntimeError.InvalidSpirV,
}
@@ -1512,15 +1512,42 @@ fn opCompositeExtract(allocator: std.mem.Allocator, word_count: SpvWord, rt: *Ru
}
switch (composite) {
.RuntimeArray => |arr| composite = try arr.createLocalValueFromIndex(arena_allocator, rt.results, member_id),
.Vector4f32 => |v| break :blk .{ .Float = .{ .bit_count = 32, .value = .{ .float32 = v[member_id] } } },
.Vector3f32 => |v| break :blk .{ .Float = .{ .bit_count = 32, .value = .{ .float32 = v[member_id] } } },
.Vector2f32 => |v| break :blk .{ .Float = .{ .bit_count = 32, .value = .{ .float32 = v[member_id] } } },
.Vector4i32 => |v| break :blk .{ .Int = .{ .bit_count = 32, .is_signed = true, .value = .{ .sint32 = v[member_id] } } },
.Vector3i32 => |v| break :blk .{ .Int = .{ .bit_count = 32, .is_signed = true, .value = .{ .sint32 = v[member_id] } } },
.Vector2i32 => |v| break :blk .{ .Int = .{ .bit_count = 32, .is_signed = true, .value = .{ .sint32 = v[member_id] } } },
.Vector4u32 => |v| break :blk .{ .Int = .{ .bit_count = 32, .is_signed = false, .value = .{ .uint32 = v[member_id] } } },
.Vector3u32 => |v| break :blk .{ .Int = .{ .bit_count = 32, .is_signed = false, .value = .{ .uint32 = v[member_id] } } },
.Vector2u32 => |v| break :blk .{ .Int = .{ .bit_count = 32, .is_signed = false, .value = .{ .uint32 = v[member_id] } } },
.Vector4f32 => |v| break :blk .{ .Float = .{ .bit_count = 32, .value = .{ .float32 = switch (member_id) {
inline 0...3 => |idx| v[idx],
else => return RuntimeError.OutOfBounds,
} } } },
.Vector3f32 => |v| break :blk .{ .Float = .{ .bit_count = 32, .value = .{ .float32 = switch (member_id) {
inline 0...2 => |idx| v[idx],
else => return RuntimeError.OutOfBounds,
} } } },
.Vector2f32 => |v| break :blk .{ .Float = .{ .bit_count = 32, .value = .{ .float32 = switch (member_id) {
inline 0...1 => |idx| v[idx],
else => return RuntimeError.OutOfBounds,
} } } },
.Vector4i32 => |v| break :blk .{ .Int = .{ .bit_count = 32, .is_signed = true, .value = .{ .sint32 = switch (member_id) {
inline 0...3 => |idx| v[idx],
else => return RuntimeError.OutOfBounds,
} } } },
.Vector3i32 => |v| break :blk .{ .Int = .{ .bit_count = 32, .is_signed = true, .value = .{ .sint32 = switch (member_id) {
inline 0...2 => |idx| v[idx],
else => return RuntimeError.OutOfBounds,
} } } },
.Vector2i32 => |v| break :blk .{ .Int = .{ .bit_count = 32, .is_signed = true, .value = .{ .sint32 = switch (member_id) {
inline 0...1 => |idx| v[idx],
else => return RuntimeError.OutOfBounds,
} } } },
.Vector4u32 => |v| break :blk .{ .Int = .{ .bit_count = 32, .is_signed = false, .value = .{ .uint32 = switch (member_id) {
inline 0...3 => |idx| v[idx],
else => return RuntimeError.OutOfBounds,
} } } },
.Vector3u32 => |v| break :blk .{ .Int = .{ .bit_count = 32, .is_signed = false, .value = .{ .uint32 = switch (member_id) {
inline 0...2 => |idx| v[idx],
else => return RuntimeError.OutOfBounds,
} } } },
.Vector2u32 => |v| break :blk .{ .Int = .{ .bit_count = 32, .is_signed = false, .value = .{ .uint32 = switch (member_id) {
inline 0...1 => |idx| v[idx],
else => return RuntimeError.OutOfBounds,
} } } },
else => return RuntimeError.InvalidValueType,
}
}
@@ -1586,43 +1613,43 @@ fn opCompositeInsert(allocator: std.mem.Allocator, word_count: SpvWord, rt: *Run
_ = try elem_value.read(arr.data[elem_offset..]);
},
.Vector4f32 => |*v| {
if (index >= 4 or indices.len != 1) return RuntimeError.InvalidSpirV;
v[index] = (try Value.getPrimitiveField(.Float, 32, @constCast(object_value))).*;
.Vector4f32 => |*v| switch (index) {
inline 0...3 => |i| v[i] = (try Value.getPrimitiveField(.Float, 32, @constCast(object_value))).*,
else => return RuntimeError.InvalidSpirV,
},
.Vector3f32 => |*v| {
if (index >= 3 or indices.len != 1) return RuntimeError.InvalidSpirV;
v[index] = (try Value.getPrimitiveField(.Float, 32, @constCast(object_value))).*;
.Vector3f32 => |*v| switch (index) {
inline 0...2 => |i| v[i] = (try Value.getPrimitiveField(.Float, 32, @constCast(object_value))).*,
else => return RuntimeError.InvalidSpirV,
},
.Vector2f32 => |*v| {
if (index >= 2 or indices.len != 1) return RuntimeError.InvalidSpirV;
v[index] = (try Value.getPrimitiveField(.Float, 32, @constCast(object_value))).*;
.Vector2f32 => |*v| switch (index) {
inline 0...1 => |i| v[i] = (try Value.getPrimitiveField(.Float, 32, @constCast(object_value))).*,
else => return RuntimeError.InvalidSpirV,
},
.Vector4i32 => |*v| {
if (index >= 4 or indices.len != 1) return RuntimeError.InvalidSpirV;
v[index] = (try Value.getPrimitiveField(.SInt, 32, @constCast(object_value))).*;
.Vector4i32 => |*v| switch (index) {
inline 0...3 => |i| v[i] = (try Value.getPrimitiveField(.SInt, 32, @constCast(object_value))).*,
else => return RuntimeError.InvalidSpirV,
},
.Vector3i32 => |*v| {
if (index >= 3 or indices.len != 1) return RuntimeError.InvalidSpirV;
v[index] = (try Value.getPrimitiveField(.SInt, 32, @constCast(object_value))).*;
.Vector3i32 => |*v| switch (index) {
inline 0...2 => |i| v[i] = (try Value.getPrimitiveField(.SInt, 32, @constCast(object_value))).*,
else => return RuntimeError.InvalidSpirV,
},
.Vector2i32 => |*v| {
if (index >= 2 or indices.len != 1) return RuntimeError.InvalidSpirV;
v[index] = (try Value.getPrimitiveField(.SInt, 32, @constCast(object_value))).*;
.Vector2i32 => |*v| switch (index) {
inline 0...1 => |i| v[i] = (try Value.getPrimitiveField(.SInt, 32, @constCast(object_value))).*,
else => return RuntimeError.InvalidSpirV,
},
.Vector4u32 => |*v| {
if (index >= 4 or indices.len != 1) return RuntimeError.InvalidSpirV;
v[index] = (try Value.getPrimitiveField(.UInt, 32, @constCast(object_value))).*;
.Vector4u32 => |*v| switch (index) {
inline 0...3 => |i| v[i] = (try Value.getPrimitiveField(.UInt, 32, @constCast(object_value))).*,
else => return RuntimeError.InvalidSpirV,
},
.Vector3u32 => |*v| {
if (index >= 3 or indices.len != 1) return RuntimeError.InvalidSpirV;
v[index] = (try Value.getPrimitiveField(.UInt, 32, @constCast(object_value))).*;
.Vector3u32 => |*v| switch (index) {
inline 0...2 => |i| v[i] = (try Value.getPrimitiveField(.UInt, 32, @constCast(object_value))).*,
else => return RuntimeError.InvalidSpirV,
},
.Vector2u32 => |*v| {
if (index >= 2 or indices.len != 1) return RuntimeError.InvalidSpirV;
v[index] = (try Value.getPrimitiveField(.UInt, 32, @constCast(object_value))).*;
.Vector2u32 => |*v| switch (index) {
inline 0...1 => |i| v[i] = (try Value.getPrimitiveField(.UInt, 32, @constCast(object_value))).*,
else => return RuntimeError.InvalidSpirV,
},
else => return RuntimeError.InvalidValueType,
@@ -2609,95 +2636,77 @@ fn opVectorShuffle(allocator: std.mem.Allocator, _: SpvWord, rt: *Runtime) Runti
return lanes[lane_index];
},
.Vector2f32 => |lanes| {
if (lane_index >= 2) return RuntimeError.InvalidSpirV;
return .{
.Float = .{
.Vector2f32 => |lanes| return .{ .Float = .{
.bit_count = 32,
.value = .{ .float32 = lanes[lane_index] },
},
};
},
.Vector3f32 => |lanes| {
if (lane_index >= 3) return RuntimeError.InvalidSpirV;
return .{
.Float = .{
.value = .{ .float32 = switch (lane_index) {
inline 0...1 => |idx| lanes[idx],
else => return RuntimeError.OutOfBounds,
} },
} },
.Vector3f32 => |lanes| return .{ .Float = .{
.bit_count = 32,
.value = .{ .float32 = lanes[lane_index] },
},
};
},
.Vector4f32 => |lanes| {
if (lane_index >= 4) return RuntimeError.InvalidSpirV;
return .{
.Float = .{
.value = .{ .float32 = switch (lane_index) {
inline 0...2 => |idx| lanes[idx],
else => return RuntimeError.OutOfBounds,
} },
} },
.Vector4f32 => |lanes| return .{ .Float = .{
.bit_count = 32,
.value = .{ .float32 = lanes[lane_index] },
},
};
},
.value = .{ .float32 = switch (lane_index) {
inline 0...3 => |idx| lanes[idx],
else => return RuntimeError.OutOfBounds,
} },
} },
.Vector2i32 => |lanes| {
if (lane_index >= 2) return RuntimeError.InvalidSpirV;
return .{
.Int = .{
.Vector2i32 => |lanes| return .{ .Int = .{
.bit_count = 32,
.is_signed = true,
.value = .{ .sint32 = lanes[lane_index] },
},
};
},
.Vector3i32 => |lanes| {
if (lane_index >= 3) return RuntimeError.InvalidSpirV;
return .{
.Int = .{
.value = .{ .sint32 = switch (lane_index) {
inline 0...1 => |idx| lanes[idx],
else => return RuntimeError.OutOfBounds,
} },
} },
.Vector3i32 => |lanes| return .{ .Int = .{
.bit_count = 32,
.is_signed = true,
.value = .{ .sint32 = lanes[lane_index] },
},
};
},
.Vector4i32 => |lanes| {
if (lane_index >= 4) return RuntimeError.InvalidSpirV;
return .{
.Int = .{
.value = .{ .sint32 = switch (lane_index) {
inline 0...2 => |idx| lanes[idx],
else => return RuntimeError.OutOfBounds,
} },
} },
.Vector4i32 => |lanes| return .{ .Int = .{
.bit_count = 32,
.is_signed = true,
.value = .{ .sint32 = lanes[lane_index] },
},
};
},
.value = .{ .sint32 = switch (lane_index) {
inline 0...3 => |idx| lanes[idx],
else => return RuntimeError.OutOfBounds,
} },
} },
.Vector2u32 => |lanes| {
if (lane_index >= 2) return RuntimeError.InvalidSpirV;
return .{
.Int = .{
.Vector2u32 => |lanes| return .{ .Int = .{
.bit_count = 32,
.is_signed = false,
.value = .{ .uint32 = lanes[lane_index] },
},
};
},
.Vector3u32 => |lanes| {
if (lane_index >= 3) return RuntimeError.InvalidSpirV;
return .{
.Int = .{
.value = .{ .uint32 = switch (lane_index) {
inline 0...1 => |idx| lanes[idx],
else => return RuntimeError.OutOfBounds,
} },
} },
.Vector3u32 => |lanes| return .{ .Int = .{
.bit_count = 32,
.is_signed = false,
.value = .{ .uint32 = lanes[lane_index] },
},
};
},
.Vector4u32 => |lanes| {
if (lane_index >= 4) return RuntimeError.InvalidSpirV;
return .{
.Int = .{
.value = .{ .uint32 = switch (lane_index) {
inline 0...2 => |idx| lanes[idx],
else => return RuntimeError.OutOfBounds,
} },
} },
.Vector4u32 => |lanes| return .{ .Int = .{
.bit_count = 32,
.is_signed = false,
.value = .{ .uint32 = lanes[lane_index] },
},
};
},
.value = .{ .uint32 = switch (lane_index) {
inline 0...3 => |idx| lanes[idx],
else => return RuntimeError.OutOfBounds,
} },
} },
else => return RuntimeError.InvalidSpirV,
};
@@ -2710,98 +2719,98 @@ fn opVectorShuffle(allocator: std.mem.Allocator, _: SpvWord, rt: *Runtime) Runti
lanes[lane_index] = lane_value;
},
.Vector2f32 => |*lanes| {
if (lane_index >= 2) return RuntimeError.InvalidSpirV;
switch (lane_value) {
.Vector2f32 => |*lanes| switch (lane_value) {
.Float => |f| {
if (f.bit_count != 32) return RuntimeError.InvalidSpirV;
lanes[lane_index] = f.value.float32;
},
switch (lane_index) {
inline 0...1 => |i| lanes[i] = f.value.float32,
else => return RuntimeError.InvalidSpirV,
}
},
.Vector3f32 => |*lanes| {
if (lane_index >= 3) return RuntimeError.InvalidSpirV;
switch (lane_value) {
else => return RuntimeError.InvalidSpirV,
},
.Vector3f32 => |*lanes| switch (lane_value) {
.Float => |f| {
if (f.bit_count != 32) return RuntimeError.InvalidSpirV;
lanes[lane_index] = f.value.float32;
},
switch (lane_index) {
inline 0...2 => |i| lanes[i] = f.value.float32,
else => return RuntimeError.InvalidSpirV,
}
},
.Vector4f32 => |*lanes| {
if (lane_index >= 4) return RuntimeError.InvalidSpirV;
switch (lane_value) {
else => return RuntimeError.InvalidSpirV,
},
.Vector4f32 => |*lanes| switch (lane_value) {
.Float => |f| {
if (f.bit_count != 32) return RuntimeError.InvalidSpirV;
lanes[lane_index] = f.value.float32;
},
switch (lane_index) {
inline 0...3 => |i| lanes[i] = f.value.float32,
else => return RuntimeError.InvalidSpirV,
}
},
else => return RuntimeError.InvalidSpirV,
},
.Vector2i32 => |*lanes| {
if (lane_index >= 2) return RuntimeError.InvalidSpirV;
switch (lane_value) {
.Vector2i32 => |*lanes| switch (lane_value) {
.Int => |i| {
if (i.bit_count != 32) return RuntimeError.InvalidSpirV;
lanes[lane_index] = i.value.sint32;
},
switch (lane_index) {
inline 0...1 => |idx| lanes[idx] = i.value.sint32,
else => return RuntimeError.InvalidSpirV,
}
},
.Vector3i32 => |*lanes| {
if (lane_index >= 3) return RuntimeError.InvalidSpirV;
switch (lane_value) {
else => return RuntimeError.InvalidSpirV,
},
.Vector3i32 => |*lanes| switch (lane_value) {
.Int => |i| {
if (i.bit_count != 32) return RuntimeError.InvalidSpirV;
lanes[lane_index] = i.value.sint32;
},
switch (lane_index) {
inline 0...2 => |idx| lanes[idx] = i.value.sint32,
else => return RuntimeError.InvalidSpirV,
}
},
.Vector4i32 => |*lanes| {
if (lane_index >= 4) return RuntimeError.InvalidSpirV;
switch (lane_value) {
else => return RuntimeError.InvalidSpirV,
},
.Vector4i32 => |*lanes| switch (lane_value) {
.Int => |i| {
if (i.bit_count != 32) return RuntimeError.InvalidSpirV;
lanes[lane_index] = i.value.sint32;
},
switch (lane_index) {
inline 0...3 => |idx| lanes[idx] = i.value.sint32,
else => return RuntimeError.InvalidSpirV,
}
},
else => return RuntimeError.InvalidSpirV,
},
.Vector2u32 => |*lanes| {
if (lane_index >= 2) return RuntimeError.InvalidSpirV;
switch (lane_value) {
.Vector2u32 => |*lanes| switch (lane_value) {
.Int => |i| {
if (i.bit_count != 32) return RuntimeError.InvalidSpirV;
lanes[lane_index] = i.value.uint32;
},
switch (lane_index) {
inline 0...1 => |idx| lanes[idx] = i.value.uint32,
else => return RuntimeError.InvalidSpirV,
}
},
.Vector3u32 => |*lanes| {
if (lane_index >= 3) return RuntimeError.InvalidSpirV;
switch (lane_value) {
else => return RuntimeError.InvalidSpirV,
},
.Vector3u32 => |*lanes| switch (lane_value) {
.Int => |i| {
if (i.bit_count != 32) return RuntimeError.InvalidSpirV;
lanes[lane_index] = i.value.uint32;
},
switch (lane_index) {
inline 0...2 => |idx| lanes[idx] = i.value.uint32,
else => return RuntimeError.InvalidSpirV,
}
},
.Vector4u32 => |*lanes| {
if (lane_index >= 4) return RuntimeError.InvalidSpirV;
switch (lane_value) {
else => return RuntimeError.InvalidSpirV,
},
.Vector4u32 => |*lanes| switch (lane_value) {
.Int => |i| {
if (i.bit_count != 32) return RuntimeError.InvalidSpirV;
lanes[lane_index] = i.value.uint32;
},
switch (lane_index) {
inline 0...3 => |idx| lanes[idx] = i.value.uint32,
else => return RuntimeError.InvalidSpirV,
}
},
else => return RuntimeError.InvalidSpirV,
},
else => return RuntimeError.InvalidSpirV,
}

View File

@@ -101,7 +101,7 @@ test "Bitwise vectors" {
inline for (types) |T| {
const op1: case.Vec(L, T) = .{ .val = case.random(@Vector(L, T)) };
var op2: case.Vec(L, T) = .{ .val = case.random(@Vector(L, T)) };
for (0..L) |i| op2.val[i] = @mod(op2.val[i], @bitSizeOf(T));
inline for (0..L) |i| op2.val[i] = @mod(op2.val[i], @bitSizeOf(T));
const expected = switch (op.key) {
.BitwiseAnd => op1.val & op2.val,
.BitwiseOr => op1.val | op2.val,

View File

@@ -78,7 +78,7 @@ pub const case = struct {
}
pub fn random(comptime T: type) T {
var prng: std.Random.DefaultPrng = .init(@intCast(std.time.microTimestamp()));
var prng: std.Random.DefaultPrng = .init(@intCast(std.Io.Timestamp.now(std.testing.io, .real).toMicroseconds()));
const rand = prng.random();
return switch (@typeInfo(T)) {
@@ -86,7 +86,7 @@ pub const case = struct {
.float => rand.float(T),
.vector => |v| blk: {
var vec: @Vector(v.len, v.child) = undefined;
for (0..v.len) |i| {
inline for (0..v.len) |i| {
vec[i] = random(v.child);
}
break :blk vec;

View File

@@ -16,11 +16,8 @@ pub fn main() !void {
const allocator = fba.allocator();
const env = Env.init(allocator);
defer env.deinit(allocator);
var slowest = SlowTracker.init(allocator, 5);
defer slowest.deinit();
defer slowest.deinit(allocator);
var pass: usize = 0;
var fail: usize = 0;
@@ -46,13 +43,6 @@ pub fn main() !void {
var status = Status.pass;
slowest.startTiming();
const is_unnamed_test = isUnnamed(t);
if (env.filter) |f| {
if (!is_unnamed_test and std.mem.indexOf(u8, t.name, f) == null) {
continue;
}
}
const friendly_name = blk: {
const name = t.name;
var it = std.mem.splitScalar(u8, name, '.');
@@ -70,7 +60,7 @@ pub fn main() !void {
const result = t.func();
current_test = null;
const ns_taken = slowest.endTiming(friendly_name);
const ns_taken = slowest.endTiming(allocator, friendly_name);
if (std.testing.allocator_instance.deinit() == .leak) {
leak += 1;
@@ -89,20 +79,13 @@ pub fn main() !void {
fail += 1;
Printer.status(.fail, "\n{s}\n\"{s}\" - {s}\n{s}\n", .{ BORDER, friendly_name, @errorName(err), BORDER });
if (@errorReturnTrace()) |trace| {
std.debug.dumpStackTrace(trace.*);
}
if (env.fail_first) {
break;
std.debug.dumpErrorReturnTrace(trace);
}
},
}
if (env.verbose) {
const ms = @as(f64, @floatFromInt(ns_taken)) / 1_000_000.0;
Printer.status(status, "\x1b[35m[{d: >10.2} ms]\x1b[0m {s: <30}", .{ ms, friendly_name });
} else {
Printer.status(status, ".", .{});
}
}
for (builtin.test_functions) |t| {
@@ -126,7 +109,7 @@ pub fn main() !void {
Printer.fmt("\n", .{});
try slowest.display();
Printer.fmt("\n", .{});
std.posix.exit(if (fail == 0) 0 else 1);
std.process.exit(if (fail == 0) 0 else 1);
}
const Printer = struct {
@@ -155,42 +138,41 @@ const SlowTracker = struct {
const SlowestQueue = std.PriorityDequeue(TestInfo, void, compareTiming);
max: usize,
slowest: SlowestQueue,
timer: std.time.Timer,
timer: std.Io.Timestamp,
fn init(allocator: Allocator, count: u32) SlowTracker {
const timer = std.time.Timer.start() catch @panic("failed to start timer");
var slowest = SlowestQueue.init(allocator, {});
slowest.ensureTotalCapacity(count) catch @panic("OOM");
var slowest = SlowestQueue.empty;
slowest.ensureTotalCapacity(allocator, count) catch @panic("OOM");
return .{
.max = count,
.timer = timer,
.timer = std.Io.Timestamp.now(std.testing.io, .real),
.slowest = slowest,
};
}
const TestInfo = struct {
ns: u64,
ns: i96,
name: []const u8,
};
fn deinit(self: SlowTracker) void {
self.slowest.deinit();
fn deinit(self: *SlowTracker, allocator: std.mem.Allocator) void {
self.slowest.deinit(allocator);
}
fn startTiming(self: *SlowTracker) void {
self.timer.reset();
self.timer = std.Io.Timestamp.now(std.testing.io, .real);
}
fn endTiming(self: *SlowTracker, test_name: []const u8) u64 {
var timer = self.timer;
const ns = timer.lap();
fn endTiming(self: *SlowTracker, allocator: std.mem.Allocator, test_name: []const u8) i96 {
const duration = self.timer.untilNow(std.testing.io, .real);
const ns = duration.toNanoseconds();
var slowest = &self.slowest;
if (slowest.count() < self.max) {
// Capacity is fixed to the # of slow tests we want to track
// If we've tracked fewer tests than this capacity, than always add
slowest.add(TestInfo{ .ns = ns, .name = test_name }) catch @panic("failed to track test timing");
slowest.push(allocator, TestInfo{ .ns = ns, .name = test_name }) catch @panic("failed to track test timing");
return ns;
}
@@ -205,8 +187,8 @@ const SlowTracker = struct {
}
// the previous fastest of our slow tests, has been pushed off.
_ = slowest.removeMin();
slowest.add(TestInfo{ .ns = ns, .name = test_name }) catch @panic("failed to track test timing");
_ = slowest.popMin();
slowest.push(allocator, TestInfo{ .ns = ns, .name = test_name }) catch @panic("failed to track test timing");
return ns;
}
@@ -214,7 +196,7 @@ const SlowTracker = struct {
var slowest = self.slowest;
const count = slowest.count();
Printer.fmt("Slowest {d} test{s}: \n", .{ count, if (count != 1) "s" else "" });
while (slowest.removeMinOrNull()) |info| {
while (slowest.popMin()) |info| {
const ms = @as(f64, @floatFromInt(info.ns)) / 1_000_000.0;
Printer.fmt(" {d:.2}ms\t{s}\n", .{ ms, info.name });
}
@@ -226,43 +208,6 @@ const SlowTracker = struct {
}
};
const Env = struct {
verbose: bool,
fail_first: bool,
filter: ?[]const u8,
fn init(allocator: Allocator) Env {
return .{
.verbose = readEnvBool(allocator, "TEST_VERBOSE", true),
.fail_first = readEnvBool(allocator, "TEST_FAIL_FIRST", false),
.filter = readEnv(allocator, "TEST_FILTER"),
};
}
fn deinit(self: Env, allocator: Allocator) void {
if (self.filter) |f| {
allocator.free(f);
}
}
fn readEnv(allocator: Allocator, key: []const u8) ?[]const u8 {
const v = std.process.getEnvVarOwned(allocator, key) catch |err| {
if (err == error.EnvironmentVariableNotFound) {
return null;
}
std.log.warn("failed to get env var {s} due to err {}", .{ key, err });
return null;
};
return v;
}
fn readEnvBool(allocator: Allocator, key: []const u8, deflt: bool) bool {
const value = readEnv(allocator, key) orelse return deflt;
defer allocator.free(value);
return std.ascii.eqlIgnoreCase(value, "true");
}
};
pub const panic = std.debug.FullPanic(struct {
pub fn panicFn(msg: []const u8, first_trace_addr: ?usize) noreturn {
if (current_test) |ct| {