adding bitsize to primitive values
This commit is contained in:
@@ -31,12 +31,12 @@ pub fn main() !void {
|
||||
var input: Input = .{};
|
||||
var output: Output = .{};
|
||||
|
||||
try rt.writeDescriptorSet(Input, allocator, &input, 0, 0);
|
||||
try rt.writeDescriptorSet(Output, allocator, &output, 0, 1);
|
||||
try rt.writeDescriptorSet(allocator, std.mem.asBytes(&input), 0, 0);
|
||||
try rt.writeDescriptorSet(allocator, std.mem.asBytes(&output), 0, 1);
|
||||
|
||||
try rt.callEntryPoint(allocator, entry);
|
||||
|
||||
try rt.readDescriptorSet(Output, allocator, &output, 0, 1);
|
||||
try rt.readDescriptorSet(std.mem.asBytes(&output), 0, 1);
|
||||
|
||||
std.log.info("Output: {any}", .{output});
|
||||
|
||||
|
||||
@@ -80,7 +80,9 @@ const Decoration = struct {
|
||||
pub const Value = union(Type) {
|
||||
Void: struct {},
|
||||
Bool: bool,
|
||||
Int: extern union {
|
||||
Int: struct {
|
||||
bit_count: usize,
|
||||
value: extern union {
|
||||
sint8: i8,
|
||||
sint16: i16,
|
||||
sint32: i32,
|
||||
@@ -90,11 +92,15 @@ pub const Value = union(Type) {
|
||||
uint32: u32,
|
||||
uint64: u64,
|
||||
},
|
||||
Float: extern union {
|
||||
},
|
||||
Float: struct {
|
||||
bit_count: usize,
|
||||
value: extern union {
|
||||
float16: f16,
|
||||
float32: f32,
|
||||
float64: f64,
|
||||
},
|
||||
},
|
||||
Vector: []Value,
|
||||
Vector4f32: Vec4f32,
|
||||
Vector3f32: Vec3f32,
|
||||
@@ -116,7 +122,7 @@ pub const Value = union(Type) {
|
||||
Pointer: union(enum) {
|
||||
common: *Value,
|
||||
f32_ptr: *f32,
|
||||
i32_ptr: *i32, //< For vectors specializations
|
||||
i32_ptr: *i32, //< For vector specializations
|
||||
u32_ptr: *u32,
|
||||
},
|
||||
|
||||
@@ -135,8 +141,14 @@ pub const Value = union(Type) {
|
||||
return switch (resolved.variant.?) {
|
||||
.Type => |t| switch (t) {
|
||||
.Bool => .{ .Bool = false },
|
||||
.Int => .{ .Int = .{ .uint64 = 0 } },
|
||||
.Float => .{ .Float = .{ .float64 = 0.0 } },
|
||||
.Int => |i| .{ .Int = .{
|
||||
.bit_count = i.bit_length,
|
||||
.value = .{ .uint64 = 0 },
|
||||
} },
|
||||
.Float => |f| .{ .Float = .{
|
||||
.bit_count = f.bit_length,
|
||||
.value = .{ .float64 = 0 },
|
||||
} },
|
||||
.Vector => |v| blk: {
|
||||
var self: Value = .{ .Vector = allocator.alloc(Value, member_count) catch return RuntimeError.OutOfMemory };
|
||||
errdefer self.deinit(allocator);
|
||||
@@ -529,7 +541,7 @@ pub fn resolveSign(target_type: TypeData, rt: *const Runtime) RuntimeError!enum
|
||||
.Vector4u32 => .unsigned,
|
||||
.Vector3u32 => .unsigned,
|
||||
.Vector2u32 => .unsigned,
|
||||
else => .unsinged,
|
||||
else => .unsigned,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -573,8 +585,14 @@ pub fn initValue(allocator: std.mem.Allocator, member_count: usize, results: []c
|
||||
.Type => |t| switch (t) {
|
||||
.Void => .{ .Void = .{} },
|
||||
.Bool => .{ .Bool = false },
|
||||
.Int => .{ .Int = .{ .uint64 = 0 } },
|
||||
.Float => .{ .Float = .{ .float64 = 0.0 } },
|
||||
.Int => |i| .{ .Int = .{
|
||||
.bit_count = i.bit_length,
|
||||
.value = .{ .uint64 = 0 },
|
||||
} },
|
||||
.Float => |f| .{ .Float = .{
|
||||
.bit_count = f.bit_length,
|
||||
.value = .{ .float64 = 0 },
|
||||
} },
|
||||
.Vector => |v| blk: {
|
||||
const value: Value = .{ .Vector = allocator.alloc(Value, member_count) catch return RuntimeError.OutOfMemory };
|
||||
errdefer allocator.free(value.Vector);
|
||||
@@ -609,7 +627,6 @@ pub fn initValue(allocator: std.mem.Allocator, member_count: usize, results: []c
|
||||
break :blk value;
|
||||
},
|
||||
.RuntimeArray => |a| blk: {
|
||||
std.debug.print("test {d}\n", .{member_count});
|
||||
if (member_count == 0) {
|
||||
break :blk Value{ .RuntimeArray = null };
|
||||
}
|
||||
|
||||
367
src/Runtime.zig
367
src/Runtime.zig
@@ -150,43 +150,58 @@ pub fn callEntryPoint(self: *Self, allocator: std.mem.Allocator, entry_point_ind
|
||||
//}) catch return RuntimeError.OutOfMemory;
|
||||
}
|
||||
|
||||
pub fn readDescriptorSet(self: *const Self, comptime T: type, output: *T, set: SpvWord, binding: SpvWord) RuntimeError!void {
|
||||
pub fn readDescriptorSet(self: *const Self, output: []u8, set: SpvWord, binding: SpvWord) RuntimeError!void {
|
||||
if (set < lib.SPIRV_MAX_SET and binding < lib.SPIRV_MAX_SET_BINDINGS) {
|
||||
try self.readValue(T, output, &self.results[self.mod.bindings[set][binding]].variant.?.Variable.value);
|
||||
_ = try self.readValue(output, &self.results[self.mod.bindings[set][binding]].variant.?.Variable.value);
|
||||
} else {
|
||||
return RuntimeError.NotFound;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn writeDescriptorSet(self: *const Self, comptime T: type, allocator: std.mem.Allocator, input: *const T, set: SpvWord, binding: SpvWord) RuntimeError!void {
|
||||
pub fn writeDescriptorSet(self: *const Self, allocator: std.mem.Allocator, input: []const u8, set: SpvWord, binding: SpvWord) RuntimeError!void {
|
||||
if (set < lib.SPIRV_MAX_SET and binding < lib.SPIRV_MAX_SET_BINDINGS) {
|
||||
const variable = &self.results[self.mod.bindings[set][binding]].variant.?.Variable;
|
||||
switch (variable.value) {
|
||||
|
||||
const helper = struct {
|
||||
fn init(allocator2: std.mem.Allocator, len: usize, value: *Result.Value, type_word: SpvWord, results: []Result) RuntimeError!void {
|
||||
const resolved = results[type_word].resolveType(results);
|
||||
|
||||
switch (value.*) {
|
||||
.RuntimeArray => {
|
||||
const resolved = self.results[variable.type_word].resolveType(self.results);
|
||||
variable.value = try Result.initValue(allocator, input.len, self.results, resolved);
|
||||
value.* = try Result.initValue(allocator2, len, results, resolved);
|
||||
},
|
||||
.Vector, .Matrix, .Array, .Structure => |v| {
|
||||
_ = v;
|
||||
.Structure => |*s| for (s.*, 0..) |*elem, i| {
|
||||
try @This().init(allocator2, len, elem, resolved.variant.?.Type.Structure.members_type_word[i], results);
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
try self.writeValue(T, input, &variable.value);
|
||||
}
|
||||
};
|
||||
try helper.init(allocator, input.len, &variable.value, variable.type_word, self.results);
|
||||
|
||||
@import("pretty").print(allocator, variable, .{
|
||||
.tab_size = 4,
|
||||
.max_depth = 0,
|
||||
.struct_max_len = 0,
|
||||
.array_max_len = 0,
|
||||
}) catch return RuntimeError.OutOfMemory;
|
||||
_ = try self.writeValue(input, &variable.value);
|
||||
} else {
|
||||
return RuntimeError.NotFound;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn readOutput(self: *const Self, comptime T: type, output: []T, result: SpvWord) RuntimeError!void {
|
||||
pub fn readOutput(self: *const Self, output: []u8, result: SpvWord) RuntimeError!void {
|
||||
if (std.mem.indexOf(SpvWord, &self.mod.output_locations, &.{result})) |_| {
|
||||
try self.readValue(T, output, &self.results[result].variant.?.Variable.value);
|
||||
_ = try self.readValue(output, &self.results[result].variant.?.Variable.value);
|
||||
} else {
|
||||
return RuntimeError.NotFound;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn writeInput(self: *const Self, comptime T: type, input: []const T, result: SpvWord) RuntimeError!void {
|
||||
pub fn writeInput(self: *const Self, input: []const u8, result: SpvWord) RuntimeError!void {
|
||||
if (std.mem.indexOf(SpvWord, &self.mod.input_locations, &.{result})) |_| {
|
||||
try self.writeValue(T, input, &self.results[result].variant.?.Variable.value);
|
||||
_ = try self.writeValue(input, &self.results[result].variant.?.Variable.value);
|
||||
} else {
|
||||
return RuntimeError.NotFound;
|
||||
}
|
||||
@@ -197,144 +212,224 @@ fn reset(self: *Self) void {
|
||||
self.current_function = null;
|
||||
}
|
||||
|
||||
fn readValue(self: *const Self, comptime T: type, output: []T, value: *const Result.Value) RuntimeError!void {
|
||||
fn readValue(self: *const Self, output: []u8, value: *const Result.Value) RuntimeError!usize {
|
||||
switch (value.*) {
|
||||
.Bool => |b| {
|
||||
if (T == bool) {
|
||||
output[0] = b;
|
||||
} else {
|
||||
return RuntimeError.InvalidValueType;
|
||||
}
|
||||
output[0] = if (b == true) 1 else 0;
|
||||
return 1;
|
||||
},
|
||||
.Int => |i| {
|
||||
switch (T) {
|
||||
i8 => output[0] = i.sint8,
|
||||
i16 => output[0] = i.sint16,
|
||||
i32 => output[0] = i.sint32,
|
||||
i64 => output[0] = i.sint64,
|
||||
u8 => output[0] = i.uint8,
|
||||
u16 => output[0] = i.uint16,
|
||||
u32 => output[0] = i.uint32,
|
||||
u64 => output[0] = i.uint64,
|
||||
inline else => return RuntimeError.InvalidValueType,
|
||||
switch (i.bit_count) {
|
||||
8 => output[0] = @bitCast(i.value.uint8),
|
||||
16 => std.mem.copyForwards(u8, output[0..], std.mem.asBytes(&i.value.uint16)),
|
||||
32 => std.mem.copyForwards(u8, output[0..], std.mem.asBytes(&i.value.uint32)),
|
||||
64 => std.mem.copyForwards(u8, output[0..], std.mem.asBytes(&i.value.uint64)),
|
||||
else => return RuntimeError.InvalidValueType,
|
||||
}
|
||||
return @divExact(i.bit_count, 8);
|
||||
},
|
||||
.Float => |f| {
|
||||
switch (T) {
|
||||
f16 => output[0] = f.float16,
|
||||
f32 => output[0] = f.float32,
|
||||
f64 => output[0] = f.float64,
|
||||
inline else => return RuntimeError.InvalidValueType,
|
||||
}
|
||||
},
|
||||
.Vector4f32 => |vec| inline for (0..4) |i| switch (T) {
|
||||
f32 => output[i] = vec[i],
|
||||
inline else => return RuntimeError.InvalidValueType,
|
||||
},
|
||||
.Vector3f32 => |vec| inline for (0..3) |i| switch (T) {
|
||||
f32 => output[i] = vec[i],
|
||||
inline else => return RuntimeError.InvalidValueType,
|
||||
},
|
||||
.Vector2f32 => |vec| inline for (0..2) |i| switch (T) {
|
||||
f32 => output[i] = vec[i],
|
||||
inline else => return RuntimeError.InvalidValueType,
|
||||
},
|
||||
.Vector4i32 => |vec| inline for (0..4) |i| switch (T) {
|
||||
i32 => output[i] = vec[i],
|
||||
inline else => return RuntimeError.InvalidValueType,
|
||||
},
|
||||
.Vector3i32 => |vec| inline for (0..3) |i| switch (T) {
|
||||
i32 => output[i] = vec[i],
|
||||
inline else => return RuntimeError.InvalidValueType,
|
||||
},
|
||||
.Vector2i32 => |vec| inline for (0..2) |i| switch (T) {
|
||||
i32 => output[i] = vec[i],
|
||||
inline else => return RuntimeError.InvalidValueType,
|
||||
},
|
||||
.Vector4u32 => |vec| inline for (0..4) |i| switch (T) {
|
||||
u32 => output[i] = vec[i],
|
||||
inline else => return RuntimeError.InvalidValueType,
|
||||
},
|
||||
.Vector3u32 => |vec| inline for (0..3) |i| switch (T) {
|
||||
u32 => output[i] = vec[i],
|
||||
inline else => return RuntimeError.InvalidValueType,
|
||||
},
|
||||
.Vector2u32 => |vec| inline for (0..2) |i| switch (T) {
|
||||
u32 => output[i] = vec[i],
|
||||
inline else => return RuntimeError.InvalidValueType,
|
||||
},
|
||||
.Vector, .Matrix, .Array, .Structure => |values| for (values, 0..) |v, i| try self.readValue(T, output[i..], &v),
|
||||
switch (f.bit_count) {
|
||||
16 => std.mem.copyForwards(u8, output[0..], std.mem.asBytes(&f.value.float16)),
|
||||
32 => std.mem.copyForwards(u8, output[0..], std.mem.asBytes(&f.value.float32)),
|
||||
64 => std.mem.copyForwards(u8, output[0..], std.mem.asBytes(&f.value.float64)),
|
||||
else => return RuntimeError.InvalidValueType,
|
||||
}
|
||||
return @divExact(f.bit_count, 8);
|
||||
},
|
||||
.Vector4f32 => |vec| {
|
||||
inline for (0..4) |i| {
|
||||
std.mem.copyForwards(u8, output[(i * 4)..], std.mem.asBytes(&vec[i]));
|
||||
}
|
||||
return 4 * 4;
|
||||
},
|
||||
.Vector3f32 => |vec| {
|
||||
inline for (0..3) |i| {
|
||||
std.mem.copyForwards(u8, output[(i * 4)..], std.mem.asBytes(&vec[i]));
|
||||
}
|
||||
return 3 * 4;
|
||||
},
|
||||
.Vector2f32 => |vec| {
|
||||
inline for (0..2) |i| {
|
||||
std.mem.copyForwards(u8, output[(i * 4)..], std.mem.asBytes(&vec[i]));
|
||||
}
|
||||
return 2 * 4;
|
||||
},
|
||||
.Vector4i32 => |vec| {
|
||||
inline for (0..4) |i| {
|
||||
std.mem.copyForwards(u8, output[(i * 4)..], std.mem.asBytes(&vec[i]));
|
||||
}
|
||||
return 4 * 4;
|
||||
},
|
||||
.Vector3i32 => |vec| {
|
||||
inline for (0..3) |i| {
|
||||
std.mem.copyForwards(u8, output[(i * 4)..], std.mem.asBytes(&vec[i]));
|
||||
}
|
||||
return 3 * 4;
|
||||
},
|
||||
.Vector2i32 => |vec| {
|
||||
inline for (0..2) |i| {
|
||||
std.mem.copyForwards(u8, output[(i * 4)..], std.mem.asBytes(&vec[i]));
|
||||
}
|
||||
return 2 * 4;
|
||||
},
|
||||
.Vector4u32 => |vec| {
|
||||
inline for (0..4) |i| {
|
||||
std.mem.copyForwards(u8, output[(i * 4)..], std.mem.asBytes(&vec[i]));
|
||||
}
|
||||
return 4 * 4;
|
||||
},
|
||||
.Vector3u32 => |vec| {
|
||||
inline for (0..3) |i| {
|
||||
std.mem.copyForwards(u8, output[(i * 4)..], std.mem.asBytes(&vec[i]));
|
||||
}
|
||||
return 3 * 4;
|
||||
},
|
||||
.Vector2u32 => |vec| {
|
||||
inline for (0..2) |i| {
|
||||
std.mem.copyForwards(u8, output[(i * 4)..], std.mem.asBytes(&vec[i]));
|
||||
}
|
||||
return 2 * 4;
|
||||
},
|
||||
.Vector,
|
||||
.Matrix,
|
||||
.Array,
|
||||
.Structure,
|
||||
=> |values| {
|
||||
var offset: usize = 0;
|
||||
for (values) |v| {
|
||||
offset += try self.readValue(output[offset..], &v);
|
||||
}
|
||||
return offset;
|
||||
},
|
||||
.RuntimeArray => |opt_values| if (opt_values) |values| {
|
||||
var offset: usize = 0;
|
||||
for (values) |v| {
|
||||
offset += try self.readValue(output[offset..], &v);
|
||||
}
|
||||
return offset;
|
||||
},
|
||||
else => return RuntimeError.InvalidValueType,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
fn writeValue(self: *const Self, comptime T: type, input: []const T, value: *Result.Value) RuntimeError!void {
|
||||
fn writeValue(self: *const Self, input: []const u8, value: *Result.Value) RuntimeError!usize {
|
||||
switch (value.*) {
|
||||
.Bool => |*b| {
|
||||
if (T == bool) {
|
||||
b.* = input[0];
|
||||
} else {
|
||||
return RuntimeError.InvalidValueType;
|
||||
}
|
||||
b.* = if (input[0] != 0) true else false;
|
||||
return 1;
|
||||
},
|
||||
.Int => |*i| {
|
||||
switch (T) {
|
||||
i8 => i.sint8 = input[0],
|
||||
i16 => i.sint16 = input[0],
|
||||
i32 => i.sint32 = input[0],
|
||||
i64 => i.sint64 = input[0],
|
||||
u8 => i.uint8 = input[0],
|
||||
u16 => i.uint16 = input[0],
|
||||
u32 => i.uint32 = input[0],
|
||||
u64 => i.uint64 = input[0],
|
||||
inline else => return RuntimeError.InvalidValueType,
|
||||
}
|
||||
},
|
||||
.Float => |*f| {
|
||||
switch (T) {
|
||||
f16 => f.float16 = input[0],
|
||||
f32 => f.float32 = input[0],
|
||||
f64 => f.float64 = input[0],
|
||||
inline else => return RuntimeError.InvalidValueType,
|
||||
}
|
||||
},
|
||||
.Vector4f32 => |*vec| inline for (0..4) |i| switch (T) {
|
||||
f32 => vec[i] = input[i],
|
||||
inline else => return RuntimeError.InvalidValueType,
|
||||
},
|
||||
.Vector3f32 => |*vec| inline for (0..3) |i| switch (T) {
|
||||
f32 => vec[i] = input[i],
|
||||
inline else => return RuntimeError.InvalidValueType,
|
||||
},
|
||||
.Vector2f32 => |*vec| inline for (0..2) |i| switch (T) {
|
||||
f32 => vec[i] = input[i],
|
||||
inline else => return RuntimeError.InvalidValueType,
|
||||
},
|
||||
.Vector4i32 => |*vec| inline for (0..4) |i| switch (T) {
|
||||
i32 => vec[i] = input[i],
|
||||
inline else => return RuntimeError.InvalidValueType,
|
||||
},
|
||||
.Vector3i32 => |*vec| inline for (0..3) |i| switch (T) {
|
||||
i32 => vec[i] = input[i],
|
||||
inline else => return RuntimeError.InvalidValueType,
|
||||
},
|
||||
.Vector2i32 => |*vec| inline for (0..2) |i| switch (T) {
|
||||
i32 => vec[i] = input[i],
|
||||
inline else => return RuntimeError.InvalidValueType,
|
||||
},
|
||||
.Vector4u32 => |*vec| inline for (0..4) |i| switch (T) {
|
||||
u32 => vec[i] = input[i],
|
||||
inline else => return RuntimeError.InvalidValueType,
|
||||
},
|
||||
.Vector3u32 => |*vec| inline for (0..3) |i| switch (T) {
|
||||
u32 => vec[i] = input[i],
|
||||
inline else => return RuntimeError.InvalidValueType,
|
||||
},
|
||||
.Vector2u32 => |*vec| inline for (0..2) |i| switch (T) {
|
||||
u32 => vec[i] = input[i],
|
||||
inline else => return RuntimeError.InvalidValueType,
|
||||
},
|
||||
.Vector, .Matrix, .Array, .Structure => |*values| for (values.*, 0..) |*v, i| try self.writeValue(T, input[i..], v),
|
||||
switch (i.bit_count) {
|
||||
8 => i.value.uint8 = @bitCast(input[0]),
|
||||
16 => std.mem.copyForwards(u8, std.mem.asBytes(&i.value.uint16), input[0..2]),
|
||||
32 => std.mem.copyForwards(u8, std.mem.asBytes(&i.value.uint32), input[0..4]),
|
||||
64 => std.mem.copyForwards(u8, std.mem.asBytes(&i.value.uint64), input[0..8]),
|
||||
else => return RuntimeError.InvalidValueType,
|
||||
}
|
||||
return @divExact(i.bit_count, 8);
|
||||
},
|
||||
.Float => |*f| {
|
||||
switch (f.bit_count) {
|
||||
16 => std.mem.copyForwards(u8, std.mem.asBytes(&f.value.float16), input[0..2]),
|
||||
32 => std.mem.copyForwards(u8, std.mem.asBytes(&f.value.float32), input[0..4]),
|
||||
64 => std.mem.copyForwards(u8, std.mem.asBytes(&f.value.float64), input[0..8]),
|
||||
else => return RuntimeError.InvalidValueType,
|
||||
}
|
||||
return @divExact(f.bit_count, 8);
|
||||
},
|
||||
.Vector4f32 => |*vec| {
|
||||
inline for (0..4) |i| {
|
||||
const start = i * 4;
|
||||
const end = (i + 1) * 4;
|
||||
std.mem.copyForwards(u8, std.mem.asBytes(&vec[i]), input[start..end]);
|
||||
}
|
||||
return 4 * 4;
|
||||
},
|
||||
.Vector3f32 => |*vec| {
|
||||
inline for (0..3) |i| {
|
||||
const start = i * 4;
|
||||
const end = (i + 1) * 4;
|
||||
std.mem.copyForwards(u8, std.mem.asBytes(&vec[i]), input[start..end]);
|
||||
}
|
||||
return 3 * 4;
|
||||
},
|
||||
.Vector2f32 => |*vec| {
|
||||
inline for (0..2) |i| {
|
||||
const start = i * 4;
|
||||
const end = (i + 1) * 4;
|
||||
std.mem.copyForwards(u8, std.mem.asBytes(&vec[i]), input[start..end]);
|
||||
}
|
||||
return 2 * 4;
|
||||
},
|
||||
.Vector4i32 => |*vec| {
|
||||
inline for (0..4) |i| {
|
||||
const start = i * 4;
|
||||
const end = (i + 1) * 4;
|
||||
std.mem.copyForwards(u8, std.mem.asBytes(&vec[i]), input[start..end]);
|
||||
}
|
||||
return 4 * 4;
|
||||
},
|
||||
.Vector3i32 => |*vec| {
|
||||
inline for (0..3) |i| {
|
||||
const start = i * 4;
|
||||
const end = (i + 1) * 4;
|
||||
std.mem.copyForwards(u8, std.mem.asBytes(&vec[i]), input[start..end]);
|
||||
}
|
||||
return 3 * 4;
|
||||
},
|
||||
.Vector2i32 => |*vec| {
|
||||
inline for (0..2) |i| {
|
||||
const start = i * 4;
|
||||
const end = (i + 1) * 4;
|
||||
std.mem.copyForwards(u8, std.mem.asBytes(&vec[i]), input[start..end]);
|
||||
}
|
||||
return 2 * 4;
|
||||
},
|
||||
.Vector4u32 => |*vec| {
|
||||
inline for (0..4) |i| {
|
||||
const start = i * 4;
|
||||
const end = (i + 1) * 4;
|
||||
std.mem.copyForwards(u8, std.mem.asBytes(&vec[i]), input[start..end]);
|
||||
}
|
||||
return 4 * 4;
|
||||
},
|
||||
.Vector3u32 => |*vec| {
|
||||
inline for (0..3) |i| {
|
||||
const start = i * 4;
|
||||
const end = (i + 1) * 4;
|
||||
std.mem.copyForwards(u8, std.mem.asBytes(&vec[i]), input[start..end]);
|
||||
}
|
||||
return 3 * 4;
|
||||
},
|
||||
.Vector2u32 => |*vec| {
|
||||
inline for (0..2) |i| {
|
||||
const start = i * 4;
|
||||
const end = (i + 1) * 4;
|
||||
std.mem.copyForwards(u8, std.mem.asBytes(&vec[i]), input[start..end]);
|
||||
}
|
||||
return 2 * 4;
|
||||
},
|
||||
.Vector,
|
||||
.Matrix,
|
||||
.Array,
|
||||
.Structure,
|
||||
=> |*values| {
|
||||
var offset: usize = 0;
|
||||
for (values.*) |*v| {
|
||||
offset += try self.writeValue(input[offset..], v);
|
||||
}
|
||||
return offset;
|
||||
},
|
||||
.RuntimeArray => |opt_values| if (opt_values) |*values| {
|
||||
var offset: usize = 0;
|
||||
for (values.*) |*v| {
|
||||
offset += try self.writeValue(input[offset..], v);
|
||||
}
|
||||
return offset;
|
||||
},
|
||||
else => return RuntimeError.InvalidValueType,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
134
src/opcodes.zig
134
src/opcodes.zig
@@ -316,17 +316,17 @@ fn BitOperator(comptime T: ValueType, comptime Op: BitOp) type {
|
||||
.BitFieldInsert => blk: {
|
||||
const offset = try rt.results[try rt.it.next()].getValue();
|
||||
const count = try rt.results[try rt.it.next()].getValue();
|
||||
break :blk bitInsert(TT, op1, op2, offset.Int.uint64, count.Int.uint64);
|
||||
break :blk bitInsert(TT, op1, op2, offset.Int.value.uint64, count.Int.value.uint64);
|
||||
},
|
||||
.BitFieldSExtract => blk: {
|
||||
if (T == .UInt) return RuntimeError.InvalidSpirV;
|
||||
const count = try rt.results[try rt.it.next()].getValue();
|
||||
break :blk bitExtract(TT, op1, op2, count.Int.uint64);
|
||||
break :blk bitExtract(TT, op1, op2, count.Int.value.uint64);
|
||||
},
|
||||
.BitFieldUExtract => blk: {
|
||||
if (T == .SInt) return RuntimeError.InvalidSpirV;
|
||||
const count = try rt.results[try rt.it.next()].getValue();
|
||||
break :blk bitExtract(TT, op1, op2, count.Int.uint64);
|
||||
break :blk bitExtract(TT, op1, op2, count.Int.value.uint64);
|
||||
},
|
||||
|
||||
.BitwiseAnd => op1 & op2,
|
||||
@@ -728,7 +728,7 @@ fn MathEngine(comptime T: ValueType, comptime Op: MathOp) type {
|
||||
|
||||
inline fn applyVectorTimesScalarF32(d: []Result.Value, l: []const Result.Value, r: f32) void {
|
||||
for (d, l) |*d_v, l_v| {
|
||||
d_v.Float.float32 = l_v.Float.float32 * r;
|
||||
d_v.Float.value.float32 = l_v.Float.value.float32 * r;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -746,7 +746,7 @@ fn MathEngine(comptime T: ValueType, comptime Op: MathOp) type {
|
||||
|
||||
inline fn applySIMDVectorf32(comptime N: usize, d: *@Vector(N, f32), l: *const @Vector(N, f32), r: *const Result.Value) RuntimeError!void {
|
||||
switch (Op) {
|
||||
.VectorTimesScalar => applyVectorSIMDTimesScalarF32(N, d, l, r.Float.float32),
|
||||
.VectorTimesScalar => applyVectorSIMDTimesScalarF32(N, d, l, r.Float.value.float32),
|
||||
else => {
|
||||
const rh: *const @Vector(N, f32) = switch (N) {
|
||||
2 => &r.Vector2f32,
|
||||
@@ -764,7 +764,7 @@ fn MathEngine(comptime T: ValueType, comptime Op: MathOp) type {
|
||||
.Int, .Float => try operator.applyScalar(lane_bits, dst, lhs, rhs),
|
||||
|
||||
.Vector => |dst_vec| switch (Op) {
|
||||
.VectorTimesScalar => operator.applyVectorTimesScalarF32(dst_vec, lhs.Vector, rhs.Float.float32),
|
||||
.VectorTimesScalar => operator.applyVectorTimesScalarF32(dst_vec, lhs.Vector, rhs.Float.value.float32),
|
||||
else => for (dst_vec, lhs.Vector, rhs.Vector) |*d_lane, *l_lane, *r_lane| {
|
||||
try operator.applyScalar(lane_bits, d_lane, l_lane, r_lane);
|
||||
},
|
||||
@@ -845,14 +845,14 @@ fn opBitcast(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||
/// Asumes that values passed are primitives ints or floats
|
||||
fn cast(to: *Result.Value, from: *const Result.Value) RuntimeError!void {
|
||||
const from_bytes: u64 = switch (from.*) {
|
||||
.Float => |f| @bitCast(f.float64),
|
||||
.Int => |i| i.uint64,
|
||||
.Float => |f| @bitCast(f.value.float64),
|
||||
.Int => |i| i.value.uint64,
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
};
|
||||
|
||||
switch (to.*) {
|
||||
.Float => |*f| f.float64 = @bitCast(from_bytes),
|
||||
.Int => |*i| i.uint64 = from_bytes,
|
||||
.Float => |*f| f.value.float64 = @bitCast(from_bytes),
|
||||
.Int => |*i| i.value.uint64 = from_bytes,
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
}
|
||||
}
|
||||
@@ -887,12 +887,12 @@ fn copyValue(dst: *Result.Value, src: *const Result.Value) void {
|
||||
.Pointer => |src_ptr| switch (src_ptr) {
|
||||
.f32_ptr => |src_f32_ptr| dst_f32_ptr.* = src_f32_ptr.*,
|
||||
.common => |src_val_ptr| switch (src_val_ptr.*) {
|
||||
.Float => |f| dst_f32_ptr.* = f.float32,
|
||||
.Float => |f| dst_f32_ptr.* = f.value.float32,
|
||||
else => unreachable,
|
||||
},
|
||||
else => unreachable,
|
||||
},
|
||||
.Float => |f| dst_f32_ptr.* = f.float32,
|
||||
.Float => |f| dst_f32_ptr.* = f.value.float32,
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
@@ -902,12 +902,12 @@ fn copyValue(dst: *Result.Value, src: *const Result.Value) void {
|
||||
.Pointer => |src_ptr| switch (src_ptr) {
|
||||
.i32_ptr => |src_i32_ptr| dst_i32_ptr.* = src_i32_ptr.*,
|
||||
.common => |src_val_ptr| switch (src_val_ptr.*) {
|
||||
.Int => |i| dst_i32_ptr.* = i.sint32,
|
||||
.Int => |i| dst_i32_ptr.* = i.value.sint32,
|
||||
else => unreachable,
|
||||
},
|
||||
else => unreachable,
|
||||
},
|
||||
.Int => |i| dst_i32_ptr.* = i.sint32,
|
||||
.Int => |i| dst_i32_ptr.* = i.value.sint32,
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
@@ -917,12 +917,12 @@ fn copyValue(dst: *Result.Value, src: *const Result.Value) void {
|
||||
.Pointer => |src_ptr| switch (src_ptr) {
|
||||
.u32_ptr => |src_u32_ptr| dst_u32_ptr.* = src_u32_ptr.*,
|
||||
.common => |src_val_ptr| switch (src_val_ptr.*) {
|
||||
.Int => |i| dst_u32_ptr.* = i.uint32,
|
||||
.Int => |i| dst_u32_ptr.* = i.value.uint32,
|
||||
else => unreachable,
|
||||
},
|
||||
else => unreachable,
|
||||
},
|
||||
.Int => |i| dst_u32_ptr.* = i.uint32,
|
||||
.Int => |i| dst_u32_ptr.* = i.value.uint32,
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
@@ -987,15 +987,15 @@ pub fn getValuePrimitiveField(comptime T: ValueType, comptime BitCount: SpvWord,
|
||||
return switch (T) {
|
||||
.Bool => &v.Bool,
|
||||
.Float => switch (BitCount) {
|
||||
inline 16, 32, 64 => |i| &@field(v.Float, std.fmt.comptimePrint("float{}", .{i})),
|
||||
inline 16, 32, 64 => |i| &@field(v.Float.value, std.fmt.comptimePrint("float{}", .{i})),
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
.SInt => switch (BitCount) {
|
||||
inline 8, 16, 32, 64 => |i| &@field(v.Int, std.fmt.comptimePrint("sint{}", .{i})),
|
||||
inline 8, 16, 32, 64 => |i| &@field(v.Int.value, std.fmt.comptimePrint("sint{}", .{i})),
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
.UInt => switch (BitCount) {
|
||||
inline 8, 16, 32, 64 => |i| &@field(v.Int, std.fmt.comptimePrint("uint{}", .{i})),
|
||||
inline 8, 16, 32, 64 => |i| &@field(v.Int.value, std.fmt.comptimePrint("uint{}", .{i})),
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
};
|
||||
@@ -1034,48 +1034,48 @@ fn opAccessChain(_: std.mem.Allocator, word_count: SpvWord, rt: *Runtime) Runtim
|
||||
.Int => |i| {
|
||||
switch (value_ptr.*) {
|
||||
.Vector, .Matrix, .Array, .Structure => |v| {
|
||||
if (i.uint32 > v.len) return RuntimeError.InvalidSpirV;
|
||||
value_ptr = &v[i.uint32];
|
||||
if (i.value.uint32 > v.len) return RuntimeError.InvalidSpirV;
|
||||
value_ptr = &v[i.value.uint32];
|
||||
},
|
||||
.RuntimeArray => |opt_v| if (opt_v) |v| {
|
||||
if (i.uint32 > v.len) return RuntimeError.InvalidSpirV;
|
||||
value_ptr = &v[i.uint32];
|
||||
if (i.value.uint32 > v.len) return RuntimeError.InvalidSpirV;
|
||||
value_ptr = &v[i.value.uint32];
|
||||
} else return RuntimeError.InvalidSpirV,
|
||||
.Vector4f32 => |*v| {
|
||||
if (i.uint32 > 4) return RuntimeError.InvalidSpirV;
|
||||
break :blk .{ .Pointer = .{ .f32_ptr = &v[i.uint32] } };
|
||||
if (i.value.uint32 > 4) return RuntimeError.InvalidSpirV;
|
||||
break :blk .{ .Pointer = .{ .f32_ptr = &v[i.value.uint32] } };
|
||||
},
|
||||
.Vector3f32 => |*v| {
|
||||
if (i.uint32 > 3) return RuntimeError.InvalidSpirV;
|
||||
break :blk .{ .Pointer = .{ .f32_ptr = &v[i.uint32] } };
|
||||
if (i.value.uint32 > 3) return RuntimeError.InvalidSpirV;
|
||||
break :blk .{ .Pointer = .{ .f32_ptr = &v[i.value.uint32] } };
|
||||
},
|
||||
.Vector2f32 => |*v| {
|
||||
if (i.uint32 > 2) return RuntimeError.InvalidSpirV;
|
||||
break :blk .{ .Pointer = .{ .f32_ptr = &v[i.uint32] } };
|
||||
if (i.value.uint32 > 2) return RuntimeError.InvalidSpirV;
|
||||
break :blk .{ .Pointer = .{ .f32_ptr = &v[i.value.uint32] } };
|
||||
},
|
||||
.Vector4i32 => |*v| {
|
||||
if (i.uint32 > 4) return RuntimeError.InvalidSpirV;
|
||||
break :blk .{ .Pointer = .{ .i32_ptr = &v[i.uint32] } };
|
||||
if (i.value.uint32 > 4) return RuntimeError.InvalidSpirV;
|
||||
break :blk .{ .Pointer = .{ .i32_ptr = &v[i.value.uint32] } };
|
||||
},
|
||||
.Vector3i32 => |*v| {
|
||||
if (i.uint32 > 3) return RuntimeError.InvalidSpirV;
|
||||
break :blk .{ .Pointer = .{ .i32_ptr = &v[i.uint32] } };
|
||||
if (i.value.uint32 > 3) return RuntimeError.InvalidSpirV;
|
||||
break :blk .{ .Pointer = .{ .i32_ptr = &v[i.value.uint32] } };
|
||||
},
|
||||
.Vector2i32 => |*v| {
|
||||
if (i.uint32 > 2) return RuntimeError.InvalidSpirV;
|
||||
break :blk .{ .Pointer = .{ .i32_ptr = &v[i.uint32] } };
|
||||
if (i.value.uint32 > 2) return RuntimeError.InvalidSpirV;
|
||||
break :blk .{ .Pointer = .{ .i32_ptr = &v[i.value.uint32] } };
|
||||
},
|
||||
.Vector4u32 => |*v| {
|
||||
if (i.uint32 > 4) return RuntimeError.InvalidSpirV;
|
||||
break :blk .{ .Pointer = .{ .u32_ptr = &v[i.uint32] } };
|
||||
if (i.value.uint32 > 4) return RuntimeError.InvalidSpirV;
|
||||
break :blk .{ .Pointer = .{ .u32_ptr = &v[i.value.uint32] } };
|
||||
},
|
||||
.Vector3u32 => |*v| {
|
||||
if (i.uint32 > 3) return RuntimeError.InvalidSpirV;
|
||||
break :blk .{ .Pointer = .{ .u32_ptr = &v[i.uint32] } };
|
||||
if (i.value.uint32 > 3) return RuntimeError.InvalidSpirV;
|
||||
break :blk .{ .Pointer = .{ .u32_ptr = &v[i.value.uint32] } };
|
||||
},
|
||||
.Vector2u32 => |*v| {
|
||||
if (i.uint32 > 2) return RuntimeError.InvalidSpirV;
|
||||
break :blk .{ .Pointer = .{ .u32_ptr = &v[i.uint32] } };
|
||||
if (i.value.uint32 > 2) return RuntimeError.InvalidSpirV;
|
||||
break :blk .{ .Pointer = .{ .u32_ptr = &v[i.value.uint32] } };
|
||||
},
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
}
|
||||
@@ -1134,31 +1134,31 @@ fn opCompositeConstruct(_: std.mem.Allocator, word_count: SpvWord, rt: *Runtime)
|
||||
|
||||
switch (value.*) {
|
||||
.Vector4f32 => |*vec| inline for (0..4) |i| {
|
||||
vec[i] = (try rt.results[try rt.it.next()].getVariant()).Constant.value.Float.float32;
|
||||
vec[i] = (try rt.results[try rt.it.next()].getVariant()).Constant.value.Float.value.float32;
|
||||
},
|
||||
.Vector3f32 => |*vec| inline for (0..3) |i| {
|
||||
vec[i] = (try rt.results[try rt.it.next()].getVariant()).Constant.value.Float.float32;
|
||||
vec[i] = (try rt.results[try rt.it.next()].getVariant()).Constant.value.Float.value.float32;
|
||||
},
|
||||
.Vector2f32 => |*vec| inline for (0..2) |i| {
|
||||
vec[i] = (try rt.results[try rt.it.next()].getVariant()).Constant.value.Float.float32;
|
||||
vec[i] = (try rt.results[try rt.it.next()].getVariant()).Constant.value.Float.value.float32;
|
||||
},
|
||||
.Vector4i32 => |*vec| inline for (0..4) |i| {
|
||||
vec[i] = (try rt.results[try rt.it.next()].getVariant()).Constant.value.Int.sint32;
|
||||
vec[i] = (try rt.results[try rt.it.next()].getVariant()).Constant.value.Int.value.sint32;
|
||||
},
|
||||
.Vector3i32 => |*vec| inline for (0..3) |i| {
|
||||
vec[i] = (try rt.results[try rt.it.next()].getVariant()).Constant.value.Int.sint32;
|
||||
vec[i] = (try rt.results[try rt.it.next()].getVariant()).Constant.value.Int.value.sint32;
|
||||
},
|
||||
.Vector2i32 => |*vec| inline for (0..2) |i| {
|
||||
vec[i] = (try rt.results[try rt.it.next()].getVariant()).Constant.value.Int.sint32;
|
||||
vec[i] = (try rt.results[try rt.it.next()].getVariant()).Constant.value.Int.value.sint32;
|
||||
},
|
||||
.Vector4u32 => |*vec| inline for (0..4) |i| {
|
||||
vec[i] = (try rt.results[try rt.it.next()].getVariant()).Constant.value.Int.uint32;
|
||||
vec[i] = (try rt.results[try rt.it.next()].getVariant()).Constant.value.Int.value.uint32;
|
||||
},
|
||||
.Vector3u32 => |*vec| inline for (0..3) |i| {
|
||||
vec[i] = (try rt.results[try rt.it.next()].getVariant()).Constant.value.Int.uint32;
|
||||
vec[i] = (try rt.results[try rt.it.next()].getVariant()).Constant.value.Int.value.uint32;
|
||||
},
|
||||
.Vector2u32 => |*vec| inline for (0..2) |i| {
|
||||
vec[i] = (try rt.results[try rt.it.next()].getVariant()).Constant.value.Int.uint32;
|
||||
vec[i] = (try rt.results[try rt.it.next()].getVariant()).Constant.value.Int.value.uint32;
|
||||
},
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
}
|
||||
@@ -1186,15 +1186,15 @@ fn opCompositeExtract(allocator: std.mem.Allocator, word_count: SpvWord, rt: *Ru
|
||||
continue;
|
||||
}
|
||||
switch (composite) {
|
||||
.Vector4f32 => |v| break :blk .{ .Float = .{ .float32 = v[member_id] } },
|
||||
.Vector3f32 => |v| break :blk .{ .Float = .{ .float32 = v[member_id] } },
|
||||
.Vector2f32 => |v| break :blk .{ .Float = .{ .float32 = v[member_id] } },
|
||||
.Vector4i32 => |v| break :blk .{ .Int = .{ .sint32 = v[member_id] } },
|
||||
.Vector3i32 => |v| break :blk .{ .Int = .{ .sint32 = v[member_id] } },
|
||||
.Vector2i32 => |v| break :blk .{ .Int = .{ .sint32 = v[member_id] } },
|
||||
.Vector4u32 => |v| break :blk .{ .Int = .{ .uint32 = v[member_id] } },
|
||||
.Vector3u32 => |v| break :blk .{ .Int = .{ .uint32 = v[member_id] } },
|
||||
.Vector2u32 => |v| break :blk .{ .Int = .{ .uint32 = v[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, .value = .{ .sint32 = v[member_id] } } },
|
||||
.Vector3i32 => |v| break :blk .{ .Int = .{ .bit_count = 32, .value = .{ .sint32 = v[member_id] } } },
|
||||
.Vector2i32 => |v| break :blk .{ .Int = .{ .bit_count = 32, .value = .{ .sint32 = v[member_id] } } },
|
||||
.Vector4u32 => |v| break :blk .{ .Int = .{ .bit_count = 32, .value = .{ .uint32 = v[member_id] } } },
|
||||
.Vector3u32 => |v| break :blk .{ .Int = .{ .bit_count = 32, .value = .{ .uint32 = v[member_id] } } },
|
||||
.Vector2u32 => |v| break :blk .{ .Int = .{ .bit_count = 32, .value = .{ .uint32 = v[member_id] } } },
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
}
|
||||
}
|
||||
@@ -1212,18 +1212,18 @@ fn opConstant(allocator: std.mem.Allocator, word_count: SpvWord, rt: *Runtime) R
|
||||
if (word_count - 2 != 1) {
|
||||
const low = @as(u64, try rt.it.next());
|
||||
const high = @as(u64, try rt.it.next());
|
||||
i.uint64 = (high << 32) | low;
|
||||
i.value.uint64 = (high << 32) | low;
|
||||
} else {
|
||||
i.uint32 = try rt.it.next();
|
||||
i.value.uint32 = try rt.it.next();
|
||||
}
|
||||
},
|
||||
.Float => |*f| {
|
||||
if (word_count - 2 != 1) {
|
||||
const low = @as(u64, try rt.it.next());
|
||||
const high = @as(u64, try rt.it.next());
|
||||
f.float64 = @bitCast((high << 32) | low);
|
||||
f.value.float64 = @bitCast((high << 32) | low);
|
||||
} else {
|
||||
f.float32 = @bitCast(try rt.it.next());
|
||||
f.value.float32 = @bitCast(try rt.it.next());
|
||||
}
|
||||
},
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
@@ -1260,7 +1260,7 @@ fn opDot(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
};
|
||||
|
||||
value.Float.float64 = 0.0;
|
||||
value.Float.value.float64 = 0.0;
|
||||
|
||||
switch (op1_value.*) {
|
||||
.Vector => |vec| for (vec, op2_value.Vector) |*op1_v, *op2_v| {
|
||||
@@ -1271,14 +1271,14 @@ fn opDot(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
}
|
||||
},
|
||||
.Vector4f32 => |vec| value.Float.float32 = zm.dot4(vec, op2_value.Vector4f32)[0],
|
||||
.Vector4f32 => |vec| value.Float.value.float32 = zm.dot4(vec, op2_value.Vector4f32)[0],
|
||||
.Vector3f32 => |vec| {
|
||||
const op2_vec = op2_value.Vector3f32;
|
||||
value.Float.float32 = zm.dot3(zm.f32x4(vec[0], vec[1], vec[2], 0.0), zm.f32x4(op2_vec[0], op2_vec[1], op2_vec[2], 0.0))[0];
|
||||
value.Float.value.float32 = zm.dot3(zm.f32x4(vec[0], vec[1], vec[2], 0.0), zm.f32x4(op2_vec[0], op2_vec[1], op2_vec[2], 0.0))[0];
|
||||
},
|
||||
.Vector2f32 => |vec| {
|
||||
const op2_vec = op2_value.Vector2f32;
|
||||
value.Float.float32 = zm.dot2(zm.f32x4(vec[0], vec[1], 0.0, 0.0), zm.f32x4(op2_vec[0], op2_vec[1], 0.0, 0.0))[0];
|
||||
value.Float.value.float32 = zm.dot2(zm.f32x4(vec[0], vec[1], 0.0, 0.0), zm.f32x4(op2_vec[0], op2_vec[1], 0.0, 0.0))[0];
|
||||
},
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ pub const case = struct {
|
||||
|
||||
try rt.callEntryPoint(allocator, try rt.getEntryPointByName("main"));
|
||||
var output: [len]T = undefined;
|
||||
try rt.readOutput(T, output[0..len], try rt.getResultByName(output_name));
|
||||
try rt.readOutput(std.mem.sliceAsBytes(output[0..]), try rt.getResultByName(output_name));
|
||||
|
||||
try std.testing.expectEqualSlices(T, expected, &output);
|
||||
}
|
||||
@@ -67,11 +67,11 @@ pub const case = struct {
|
||||
var rt = try spv.Runtime.init(allocator, &module);
|
||||
defer rt.deinit(allocator);
|
||||
|
||||
try rt.writeInput(T, input[0..len], try rt.getResultByName(input_name));
|
||||
try rt.writeInput(std.mem.sliceAsBytes(input[0..len]), try rt.getResultByName(input_name));
|
||||
|
||||
try rt.callEntryPoint(allocator, try rt.getEntryPointByName("main"));
|
||||
var output: [len]T = undefined;
|
||||
try rt.readOutput(T, output[0..len], try rt.getResultByName(output_name));
|
||||
try rt.readOutput(std.mem.sliceAsBytes(output[0..]), try rt.getResultByName(output_name));
|
||||
|
||||
try std.testing.expectEqualSlices(T, expected, &output);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user