diff --git a/sandbox/main.zig b/sandbox/main.zig index 4176ab6..388f295 100644 --- a/sandbox/main.zig +++ b/sandbox/main.zig @@ -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}); diff --git a/src/Result.zig b/src/Result.zig index f0451a5..b687f2b 100644 --- a/src/Result.zig +++ b/src/Result.zig @@ -80,20 +80,26 @@ const Decoration = struct { pub const Value = union(Type) { Void: struct {}, Bool: bool, - Int: extern union { - sint8: i8, - sint16: i16, - sint32: i32, - sint64: i64, - uint8: u8, - uint16: u16, - uint32: u32, - uint64: u64, + Int: struct { + bit_count: usize, + value: extern union { + sint8: i8, + sint16: i16, + sint32: i32, + sint64: i64, + uint8: u8, + uint16: u16, + uint32: u32, + uint64: u64, + }, }, - Float: extern union { - float16: f16, - float32: f32, - float64: f64, + Float: struct { + bit_count: usize, + value: extern union { + float16: f16, + float32: f32, + float64: f64, + }, }, Vector: []Value, Vector4f32: Vec4f32, @@ -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 }; } diff --git a/src/Runtime.zig b/src/Runtime.zig index e38882c..319b594 100644 --- a/src/Runtime.zig +++ b/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) { - .RuntimeArray => { - const resolved = self.results[variable.type_word].resolveType(self.results); - variable.value = try Result.initValue(allocator, input.len, self.results, resolved); - }, - .Vector, .Matrix, .Array, .Structure => |v| { - _ = v; - }, - } - try self.writeValue(T, input, &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 => { + value.* = try Result.initValue(allocator2, len, results, resolved); + }, + .Structure => |*s| for (s.*, 0..) |*elem, i| { + try @This().init(allocator2, len, elem, resolved.variant.?.Type.Structure.members_type_word[i], results); + }, + else => {}, + } + } + }; + 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, + 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| switch (T) { - f32 => output[i] = vec[i], - inline else => return RuntimeError.InvalidValueType, + .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| switch (T) { - f32 => output[i] = vec[i], - inline else => return RuntimeError.InvalidValueType, + .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| switch (T) { - f32 => output[i] = vec[i], - inline else => return RuntimeError.InvalidValueType, + .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| switch (T) { - i32 => output[i] = vec[i], - inline else => return RuntimeError.InvalidValueType, + .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| switch (T) { - i32 => output[i] = vec[i], - inline else => return RuntimeError.InvalidValueType, + .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| switch (T) { - i32 => output[i] = vec[i], - inline else => return RuntimeError.InvalidValueType, + .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| switch (T) { - u32 => output[i] = vec[i], - inline else => return RuntimeError.InvalidValueType, + .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| switch (T) { - u32 => output[i] = vec[i], - inline else => return RuntimeError.InvalidValueType, + .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| switch (T) { - u32 => output[i] = vec[i], - inline else => return RuntimeError.InvalidValueType, + .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; }, - .Vector, .Matrix, .Array, .Structure => |values| for (values, 0..) |v, i| try self.readValue(T, output[i..], &v), 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, + 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 (T) { - f16 => f.float16 = input[0], - f32 => f.float32 = input[0], - f64 => f.float64 = input[0], - inline else => return RuntimeError.InvalidValueType, + 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| switch (T) { - f32 => vec[i] = input[i], - inline else => return RuntimeError.InvalidValueType, + .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| switch (T) { - f32 => vec[i] = input[i], - inline else => return RuntimeError.InvalidValueType, + .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| switch (T) { - f32 => vec[i] = input[i], - inline else => return RuntimeError.InvalidValueType, + .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| switch (T) { - i32 => vec[i] = input[i], - inline else => return RuntimeError.InvalidValueType, + .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| switch (T) { - i32 => vec[i] = input[i], - inline else => return RuntimeError.InvalidValueType, + .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| switch (T) { - i32 => vec[i] = input[i], - inline else => return RuntimeError.InvalidValueType, + .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| switch (T) { - u32 => vec[i] = input[i], - inline else => return RuntimeError.InvalidValueType, + .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| switch (T) { - u32 => vec[i] = input[i], - inline else => return RuntimeError.InvalidValueType, + .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| switch (T) { - u32 => vec[i] = input[i], - inline else => return RuntimeError.InvalidValueType, + .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; }, - .Vector, .Matrix, .Array, .Structure => |*values| for (values.*, 0..) |*v, i| try self.writeValue(T, input[i..], v), else => return RuntimeError.InvalidValueType, } + return 0; } diff --git a/src/opcodes.zig b/src/opcodes.zig index f90bd58..c02f026 100644 --- a/src/opcodes.zig +++ b/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, } diff --git a/test/root.zig b/test/root.zig index 8a12d25..dc52187 100644 --- a/test/root.zig +++ b/test/root.zig @@ -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); }