fixing pointer syncing
This commit is contained in:
@@ -4,6 +4,7 @@ const std = @import("std");
|
|||||||
const spv = @import("spv.zig");
|
const spv = @import("spv.zig");
|
||||||
const op = @import("opcodes.zig");
|
const op = @import("opcodes.zig");
|
||||||
const lib = @import("lib.zig");
|
const lib = @import("lib.zig");
|
||||||
|
const pretty = @import("pretty");
|
||||||
|
|
||||||
const SpvVoid = spv.SpvVoid;
|
const SpvVoid = spv.SpvVoid;
|
||||||
const SpvByte = spv.SpvByte;
|
const SpvByte = spv.SpvByte;
|
||||||
@@ -29,6 +30,7 @@ pub const RuntimeError = error{
|
|||||||
Unreachable,
|
Unreachable,
|
||||||
UnsupportedSpirV,
|
UnsupportedSpirV,
|
||||||
UnsupportedExtension,
|
UnsupportedExtension,
|
||||||
|
Unknown,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Function = struct {
|
pub const Function = struct {
|
||||||
@@ -100,6 +102,18 @@ pub fn getResultByName(self: *const Self, name: []const u8) error{NotFound}!SpvW
|
|||||||
return error.NotFound;
|
return error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn dumpResultsTable(self: *Self, allocator: std.mem.Allocator, writer: *std.Io.Writer) RuntimeError!void {
|
||||||
|
const dump = pretty.dump(allocator, self.results, .{
|
||||||
|
.tab_size = 4,
|
||||||
|
.max_depth = 0,
|
||||||
|
.struct_max_len = 0,
|
||||||
|
.array_max_len = 0,
|
||||||
|
}) catch return RuntimeError.OutOfMemory;
|
||||||
|
defer allocator.free(dump);
|
||||||
|
writer.print("{s}", .{dump}) catch return RuntimeError.Unknown;
|
||||||
|
writer.flush() catch return RuntimeError.Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
/// Calls an entry point, `entry_point_index` being the index of the entry point ordered by declaration in the bytecode
|
/// Calls an entry point, `entry_point_index` being the index of the entry point ordered by declaration in the bytecode
|
||||||
pub fn callEntryPoint(self: *Self, allocator: std.mem.Allocator, entry_point_index: SpvWord) RuntimeError!void {
|
pub fn callEntryPoint(self: *Self, allocator: std.mem.Allocator, entry_point_index: SpvWord) RuntimeError!void {
|
||||||
self.reset();
|
self.reset();
|
||||||
|
|||||||
@@ -72,14 +72,18 @@ pub const Value = union(Type) {
|
|||||||
errdefer allocator.destroy(value);
|
errdefer allocator.destroy(value);
|
||||||
|
|
||||||
value.* = try Value.init(allocator, results, self.type_word);
|
value.* = try Value.init(allocator, results, self.type_word);
|
||||||
_ = try value.writeConst(self.data[(try self.getOffsetOfIndex(index))..]);
|
_ = try value.writeConst(self.data[self.getOffsetOfIndex(index)..]);
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn getOffsetOfIndex(self: *const @This(), index: usize) RuntimeError!usize {
|
pub inline fn getOffsetOfIndex(self: *const @This(), index: usize) usize {
|
||||||
return self.stride * index;
|
return self.stride * index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub inline fn getLen(self: *const @This()) usize {
|
||||||
|
return @divTrunc(self.data.len, self.stride);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Structure: []Self,
|
Structure: []Self,
|
||||||
Function: noreturn,
|
Function: noreturn,
|
||||||
|
|||||||
110
src/opcodes.zig
110
src/opcodes.zig
@@ -517,7 +517,7 @@ fn CondOperator(comptime T: ValueType, comptime Op: CondOp) type {
|
|||||||
return switch (Op) {
|
return switch (Op) {
|
||||||
.IsFinite => std.math.isFinite(a),
|
.IsFinite => std.math.isFinite(a),
|
||||||
.IsInf => blk: {
|
.IsInf => blk: {
|
||||||
std.debug.print("test {s} - {d} - {s}\n", .{ @typeName(TT), a, if (std.math.isInf(a)) "true" else "false" });
|
//std.debug.print("test {s} - {d} - {s}\n", .{ @typeName(TT), a, if (std.math.isInf(a)) "true" else "false" });
|
||||||
break :blk std.math.isInf(a);
|
break :blk std.math.isInf(a);
|
||||||
},
|
},
|
||||||
.IsNan => std.math.isNan(a),
|
.IsNan => std.math.isNan(a),
|
||||||
@@ -800,7 +800,8 @@ fn MathEngine(comptime T: ValueType, comptime Op: MathOp) type {
|
|||||||
fn op(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
fn op(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||||
const target_type = (try rt.results[try rt.it.next()].getVariant()).Type;
|
const target_type = (try rt.results[try rt.it.next()].getVariant()).Type;
|
||||||
const dst = try rt.results[try rt.it.next()].getValue();
|
const dst = try rt.results[try rt.it.next()].getValue();
|
||||||
const lhs = try rt.results[try rt.it.next()].getValue();
|
const lhs_id = try rt.it.next();
|
||||||
|
const lhs = try rt.results[lhs_id].getValue();
|
||||||
const rhs = try rt.results[try rt.it.next()].getValue();
|
const rhs = try rt.results[try rt.it.next()].getValue();
|
||||||
|
|
||||||
const lane_bits = try Result.resolveLaneBitWidth(target_type, rt);
|
const lane_bits = try Result.resolveLaneBitWidth(target_type, rt);
|
||||||
@@ -1089,6 +1090,42 @@ fn copyValue(dst: *Value, src: *const Value) void {
|
|||||||
else => unreachable,
|
else => unreachable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline fn readF32(dst_v: *Value, src_f32_ptr: *const f32) void {
|
||||||
|
switch (dst_v.*) {
|
||||||
|
.Pointer => |dst_ptr| switch (dst_ptr.ptr) {
|
||||||
|
.f32_ptr => |dst_f32_ptr| dst_f32_ptr.* = src_f32_ptr.*,
|
||||||
|
.common => |dst_val_ptr| dst_val_ptr.Float.value.float32 = src_f32_ptr.*,
|
||||||
|
else => unreachable,
|
||||||
|
},
|
||||||
|
.Float => |*f| f.value.float32 = src_f32_ptr.*,
|
||||||
|
else => unreachable,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn readI32(dst_v: *Value, src_i32_ptr: *const i32) void {
|
||||||
|
switch (dst_v.*) {
|
||||||
|
.Pointer => |dst_ptr| switch (dst_ptr.ptr) {
|
||||||
|
.i32_ptr => |dst_i32_ptr| dst_i32_ptr.* = src_i32_ptr.*,
|
||||||
|
.common => |dst_val_ptr| dst_val_ptr.Int.value.sint32 = src_i32_ptr.*,
|
||||||
|
else => unreachable,
|
||||||
|
},
|
||||||
|
.Int => |*i| i.value.sint32 = src_i32_ptr.*,
|
||||||
|
else => unreachable,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn readU32(dst_v: *Value, src_u32_ptr: *const u32) void {
|
||||||
|
switch (dst_v.*) {
|
||||||
|
.Pointer => |dst_ptr| switch (dst_ptr.ptr) {
|
||||||
|
.u32_ptr => |dst_u32_ptr| dst_u32_ptr.* = src_u32_ptr.*,
|
||||||
|
.common => |dst_val_ptr| dst_val_ptr.Int.value.uint32 = src_u32_ptr.*,
|
||||||
|
else => unreachable,
|
||||||
|
},
|
||||||
|
.Int => |*i| i.value.uint32 = src_u32_ptr.*,
|
||||||
|
else => unreachable,
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (std.meta.activeTag(dst.*) == .Pointer) {
|
if (std.meta.activeTag(dst.*) == .Pointer) {
|
||||||
@@ -1100,18 +1137,9 @@ fn copyValue(dst: *Value, src: *const Value) void {
|
|||||||
},
|
},
|
||||||
else => copyValue(dst_val_ptr, src),
|
else => copyValue(dst_val_ptr, src),
|
||||||
},
|
},
|
||||||
.f32_ptr => |dst_f32_ptr| {
|
.f32_ptr => |dst_f32_ptr| helpers.writeF32(dst_f32_ptr, src),
|
||||||
helpers.writeF32(dst_f32_ptr, src);
|
.i32_ptr => |dst_i32_ptr| helpers.writeI32(dst_i32_ptr, src),
|
||||||
return;
|
.u32_ptr => |dst_u32_ptr| helpers.writeU32(dst_u32_ptr, src),
|
||||||
},
|
|
||||||
.i32_ptr => |dst_i32_ptr| {
|
|
||||||
helpers.writeI32(dst_i32_ptr, src);
|
|
||||||
return;
|
|
||||||
},
|
|
||||||
.u32_ptr => |dst_u32_ptr| {
|
|
||||||
helpers.writeU32(dst_u32_ptr, src);
|
|
||||||
return;
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1122,7 +1150,9 @@ fn copyValue(dst: *Value, src: *const Value) void {
|
|||||||
},
|
},
|
||||||
.Pointer => |ptr| switch (ptr.ptr) {
|
.Pointer => |ptr| switch (ptr.ptr) {
|
||||||
.common => |src_val_ptr| copyValue(dst, src_val_ptr),
|
.common => |src_val_ptr| copyValue(dst, src_val_ptr),
|
||||||
else => {},
|
.f32_ptr => |src_f32_ptr| helpers.readF32(dst, src_f32_ptr),
|
||||||
|
.i32_ptr => |src_i32_ptr| helpers.readI32(dst, src_i32_ptr),
|
||||||
|
.u32_ptr => |src_u32_ptr| helpers.readU32(dst, src_u32_ptr),
|
||||||
},
|
},
|
||||||
else => dst.* = src.*,
|
else => dst.* = src.*,
|
||||||
}
|
}
|
||||||
@@ -1174,8 +1204,6 @@ fn opAccessChain(allocator: std.mem.Allocator, word_count: SpvWord, rt: *Runtime
|
|||||||
var arena = std.heap.ArenaAllocator.init(allocator);
|
var arena = std.heap.ArenaAllocator.init(allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
|
|
||||||
const arena_allocator = arena.allocator();
|
|
||||||
|
|
||||||
const index_count = word_count - 3;
|
const index_count = word_count - 3;
|
||||||
|
|
||||||
if (rt.results[id].variant) |*variant| {
|
if (rt.results[id].variant) |*variant| {
|
||||||
@@ -1191,9 +1219,7 @@ fn opAccessChain(allocator: std.mem.Allocator, word_count: SpvWord, rt: *Runtime
|
|||||||
.value = blk: {
|
.value = blk: {
|
||||||
var uniform_slice_window: ?[]u8 = null;
|
var uniform_slice_window: ?[]u8 = null;
|
||||||
|
|
||||||
for (0..index_count) |index| {
|
for (0..index_count) |_| {
|
||||||
const is_last = (index == index_count - 1);
|
|
||||||
|
|
||||||
const member = &rt.results[try rt.it.next()];
|
const member = &rt.results[try rt.it.next()];
|
||||||
const member_value = switch ((try member.getVariant()).*) {
|
const member_value = switch ((try member.getVariant()).*) {
|
||||||
.Constant => |c| &c.value,
|
.Constant => |c| &c.value,
|
||||||
@@ -1209,49 +1235,48 @@ fn opAccessChain(allocator: std.mem.Allocator, word_count: SpvWord, rt: *Runtime
|
|||||||
|
|
||||||
switch (value_ptr.*) {
|
switch (value_ptr.*) {
|
||||||
.Vector, .Matrix, .Array, .Structure => |v| {
|
.Vector, .Matrix, .Array, .Structure => |v| {
|
||||||
if (i.value.uint32 >= v.len)
|
if (i.value.uint32 >= v.len) return RuntimeError.OutOfBounds;
|
||||||
return RuntimeError.OutOfBounds;
|
|
||||||
value_ptr = &v[i.value.uint32];
|
value_ptr = &v[i.value.uint32];
|
||||||
},
|
},
|
||||||
.RuntimeArray => |*arr| {
|
.RuntimeArray => |*arr| {
|
||||||
value_ptr = try arr.createValueFromIndex(if (is_last) allocator else arena_allocator, rt.results, i.value.uint32);
|
if (i.value.uint32 >= arr.getLen()) return RuntimeError.OutOfBounds;
|
||||||
if (is_last)
|
value_ptr = try arr.createValueFromIndex(allocator, rt.results, i.value.uint32);
|
||||||
uniform_slice_window = arr.data[(try arr.getOffsetOfIndex(i.value.uint32))..];
|
uniform_slice_window = arr.data[arr.getOffsetOfIndex(i.value.uint32)..];
|
||||||
},
|
},
|
||||||
.Vector4f32 => |*v| {
|
.Vector4f32 => |*v| {
|
||||||
if (i.value.uint32 > 4) return RuntimeError.OutOfBounds;
|
if (i.value.uint32 >= 4) return RuntimeError.OutOfBounds;
|
||||||
break :blk .{ .Pointer = .{ .ptr = .{ .f32_ptr = &v[i.value.uint32] } } };
|
break :blk .{ .Pointer = .{ .ptr = .{ .f32_ptr = &v[i.value.uint32] } } };
|
||||||
},
|
},
|
||||||
.Vector3f32 => |*v| {
|
.Vector3f32 => |*v| {
|
||||||
if (i.value.uint32 > 3) return RuntimeError.OutOfBounds;
|
if (i.value.uint32 >= 3) return RuntimeError.OutOfBounds;
|
||||||
break :blk .{ .Pointer = .{ .ptr = .{ .f32_ptr = &v[i.value.uint32] } } };
|
break :blk .{ .Pointer = .{ .ptr = .{ .f32_ptr = &v[i.value.uint32] } } };
|
||||||
},
|
},
|
||||||
.Vector2f32 => |*v| {
|
.Vector2f32 => |*v| {
|
||||||
if (i.value.uint32 > 2) return RuntimeError.OutOfBounds;
|
if (i.value.uint32 >= 2) return RuntimeError.OutOfBounds;
|
||||||
break :blk .{ .Pointer = .{ .ptr = .{ .f32_ptr = &v[i.value.uint32] } } };
|
break :blk .{ .Pointer = .{ .ptr = .{ .f32_ptr = &v[i.value.uint32] } } };
|
||||||
},
|
},
|
||||||
.Vector4i32 => |*v| {
|
.Vector4i32 => |*v| {
|
||||||
if (i.value.uint32 > 4) return RuntimeError.OutOfBounds;
|
if (i.value.uint32 >= 4) return RuntimeError.OutOfBounds;
|
||||||
break :blk .{ .Pointer = .{ .ptr = .{ .i32_ptr = &v[i.value.uint32] } } };
|
break :blk .{ .Pointer = .{ .ptr = .{ .i32_ptr = &v[i.value.uint32] } } };
|
||||||
},
|
},
|
||||||
.Vector3i32 => |*v| {
|
.Vector3i32 => |*v| {
|
||||||
if (i.value.uint32 > 3) return RuntimeError.OutOfBounds;
|
if (i.value.uint32 >= 3) return RuntimeError.OutOfBounds;
|
||||||
break :blk .{ .Pointer = .{ .ptr = .{ .i32_ptr = &v[i.value.uint32] } } };
|
break :blk .{ .Pointer = .{ .ptr = .{ .i32_ptr = &v[i.value.uint32] } } };
|
||||||
},
|
},
|
||||||
.Vector2i32 => |*v| {
|
.Vector2i32 => |*v| {
|
||||||
if (i.value.uint32 > 2) return RuntimeError.OutOfBounds;
|
if (i.value.uint32 >= 2) return RuntimeError.OutOfBounds;
|
||||||
break :blk .{ .Pointer = .{ .ptr = .{ .i32_ptr = &v[i.value.uint32] } } };
|
break :blk .{ .Pointer = .{ .ptr = .{ .i32_ptr = &v[i.value.uint32] } } };
|
||||||
},
|
},
|
||||||
.Vector4u32 => |*v| {
|
.Vector4u32 => |*v| {
|
||||||
if (i.value.uint32 > 4) return RuntimeError.OutOfBounds;
|
if (i.value.uint32 >= 4) return RuntimeError.OutOfBounds;
|
||||||
break :blk .{ .Pointer = .{ .ptr = .{ .u32_ptr = &v[i.value.uint32] } } };
|
break :blk .{ .Pointer = .{ .ptr = .{ .u32_ptr = &v[i.value.uint32] } } };
|
||||||
},
|
},
|
||||||
.Vector3u32 => |*v| {
|
.Vector3u32 => |*v| {
|
||||||
if (i.value.uint32 > 3) return RuntimeError.OutOfBounds;
|
if (i.value.uint32 >= 3) return RuntimeError.OutOfBounds;
|
||||||
break :blk .{ .Pointer = .{ .ptr = .{ .u32_ptr = &v[i.value.uint32] } } };
|
break :blk .{ .Pointer = .{ .ptr = .{ .u32_ptr = &v[i.value.uint32] } } };
|
||||||
},
|
},
|
||||||
.Vector2u32 => |*v| {
|
.Vector2u32 => |*v| {
|
||||||
if (i.value.uint32 > 2) return RuntimeError.OutOfBounds;
|
if (i.value.uint32 >= 2) return RuntimeError.OutOfBounds;
|
||||||
break :blk .{ .Pointer = .{ .ptr = .{ .u32_ptr = &v[i.value.uint32] } } };
|
break :blk .{ .Pointer = .{ .ptr = .{ .u32_ptr = &v[i.value.uint32] } } };
|
||||||
},
|
},
|
||||||
else => return RuntimeError.InvalidSpirV,
|
else => return RuntimeError.InvalidSpirV,
|
||||||
@@ -1384,7 +1409,7 @@ fn opCompositeExtract(allocator: std.mem.Allocator, word_count: SpvWord, rt: *Ru
|
|||||||
switch (composite) {
|
switch (composite) {
|
||||||
.RuntimeArray => |arr| {
|
.RuntimeArray => |arr| {
|
||||||
composite = try Value.init(arena_allocator, rt.results, arr.type_word);
|
composite = try Value.init(arena_allocator, rt.results, arr.type_word);
|
||||||
_ = try composite.writeConst(arr.data[(try arr.getOffsetOfIndex(member_id))..]);
|
_ = try composite.writeConst(arr.data[arr.getOffsetOfIndex(member_id)..]);
|
||||||
},
|
},
|
||||||
.Vector4f32 => |v| break :blk .{ .Float = .{ .bit_count = 32, .value = .{ .float32 = 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] } } },
|
.Vector3f32 => |v| break :blk .{ .Float = .{ .bit_count = 32, .value = .{ .float32 = v[member_id] } } },
|
||||||
@@ -1695,21 +1720,6 @@ fn opLoad(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
|||||||
_ = rt.it.skip();
|
_ = rt.it.skip();
|
||||||
const id = try rt.it.next();
|
const id = try rt.it.next();
|
||||||
const ptr_id = try rt.it.next();
|
const ptr_id = try rt.it.next();
|
||||||
|
|
||||||
//std.debug.print("\n{d} - {d}\n", .{ id, ptr_id });
|
|
||||||
//@import("pretty").print(std.heap.page_allocator, rt.results[id], .{
|
|
||||||
// .tab_size = 4,
|
|
||||||
// .max_depth = 0,
|
|
||||||
// .struct_max_len = 0,
|
|
||||||
// .array_max_len = 0,
|
|
||||||
//}) catch unreachable;
|
|
||||||
|
|
||||||
//@import("pretty").print(std.heap.page_allocator, rt.results[ptr_id], .{
|
|
||||||
// .tab_size = 4,
|
|
||||||
// .max_depth = 0,
|
|
||||||
// .struct_max_len = 0,
|
|
||||||
// .array_max_len = 0,
|
|
||||||
//}) catch unreachable;
|
|
||||||
copyValue(try rt.results[id].getValue(), try rt.results[ptr_id].getValue());
|
copyValue(try rt.results[id].getValue(), try rt.results[ptr_id].getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user