restoring read/write values of runtime
All checks were successful
Build / build (push) Successful in 1m39s
Test / build (push) Successful in 4m59s

This commit is contained in:
2026-02-08 19:19:42 +01:00
parent 61513f20d5
commit ac4f41ddd4
2 changed files with 58 additions and 67 deletions

View File

@@ -150,22 +150,6 @@ pub fn callEntryPoint(self: *Self, allocator: std.mem.Allocator, entry_point_ind
//}) catch return RuntimeError.OutOfMemory; //}) catch return RuntimeError.OutOfMemory;
} }
pub fn readOutput(self: *const Self, output: []u8, result: SpvWord) RuntimeError!void {
if (std.mem.indexOfScalar(SpvWord, &self.mod.output_locations, result)) |_| {
try self.readValue(output, &self.results[result]);
} else {
return RuntimeError.NotFound;
}
}
pub fn writeInput(self: *const Self, comptime T: type, input: []const T, result: SpvWord) RuntimeError!void {
if (std.mem.indexOfScalar(SpvWord, &self.mod.input_locations, result)) |_| {
try self.writeValue(T, input, &self.results[result].variant.?.Variable.value);
} else {
return RuntimeError.NotFound;
}
}
pub fn readDescriptorSet(self: *const Self, comptime T: type, output: *T, set: SpvWord, binding: SpvWord) RuntimeError!void { pub fn readDescriptorSet(self: *const Self, comptime T: type, output: *T, set: SpvWord, binding: SpvWord) RuntimeError!void {
if (set < lib.SPIRV_MAX_SET and binding < lib.SPIRV_MAX_SET_BINDINGS) { 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(T, output, &self.results[self.mod.bindings[set][binding]].variant.?.Variable.value);
@@ -192,80 +176,94 @@ pub fn writeDescriptorSet(self: *const Self, comptime T: type, allocator: std.me
} }
} }
pub fn readOutput(self: *const Self, comptime T: type, output: []T, 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);
} else {
return RuntimeError.NotFound;
}
}
pub fn writeInput(self: *const Self, comptime T: type, input: []const T, 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);
} else {
return RuntimeError.NotFound;
}
}
fn reset(self: *Self) void { fn reset(self: *Self) void {
self.function_stack.clearRetainingCapacity(); self.function_stack.clearRetainingCapacity();
self.current_function = null; self.current_function = null;
} }
fn readValue(self: *const Self, output: []u8, value: *const Result.Value) RuntimeError!void { fn readValue(self: *const Self, comptime T: type, output: []T, value: *const Result.Value) RuntimeError!void {
const type_word = try result.getValueTypeWord();
const value = try result.getValue();
const lane_bits = try Result.resolveLaneBitWidth((try self.results[type_word].getVariant()).Type, self);
switch (value.*) { switch (value.*) {
.Bool => |b| output[0] = if (b == true) 1 else 0, .Bool => |b| {
if (T == bool) {
output[0] = b;
} else {
return RuntimeError.InvalidValueType;
}
},
.Int => |i| { .Int => |i| {
switch (lane_bits) { switch (T) {
8 => output[0] = @bitCast(i.uint8), i8 => output[0] = i.sint8,
16 => std.mem.copyForward(u8, output[0..], std.mem.asBytes(i.uint16)), i16 => output[0] = i.sint16,
32 => std.mem.copyForward(u8, output[0..], std.mem.asBytes(i.uint32)), i32 => output[0] = i.sint32,
64 => std.mem.copyForward(u8, output[0..], std.mem.asBytes(i.uint64)), 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, inline else => return RuntimeError.InvalidValueType,
} }
}, },
.Float => |f| { .Float => |f| {
switch (lane_bits) { switch (T) {
16 => std.mem.copyForward(u8, output[0..], std.mem.asBytes(f.float16)), f16 => output[0] = f.float16,
32 => std.mem.copyForward(u8, output[0..], std.mem.asBytes(f.float32)), f32 => output[0] = f.float32,
64 => std.mem.copyForward(u8, output[0..], std.mem.asBytes(f.float64)), f64 => output[0] = f.float64,
inline else => return RuntimeError.InvalidValueType, inline else => return RuntimeError.InvalidValueType,
} }
}, },
.Vector4f32 => |vec| inline for (0..4) |i| switch (lane_bits) { .Vector4f32 => |vec| inline for (0..4) |i| switch (T) {
32 => std.mem.copyForward(u8, output[0..], std.mem.asBytes(vec[i])), f32 => output[i] = vec[i],
inline else => return RuntimeError.InvalidValueType, inline else => return RuntimeError.InvalidValueType,
}, },
.Vector3f32 => |vec| inline for (0..3) |i| switch (lane_bits) { .Vector3f32 => |vec| inline for (0..3) |i| switch (T) {
32 => std.mem.copyForward(u8, output[0..], std.mem.asBytes(vec[i])), f32 => output[i] = vec[i],
inline else => return RuntimeError.InvalidValueType, inline else => return RuntimeError.InvalidValueType,
}, },
.Vector2f32 => |vec| inline for (0..2) |i| switch (lane_bits) { .Vector2f32 => |vec| inline for (0..2) |i| switch (T) {
32 => std.mem.copyForward(u8, output[0..], std.mem.asBytes(vec[i])), f32 => output[i] = vec[i],
inline else => return RuntimeError.InvalidValueType, inline else => return RuntimeError.InvalidValueType,
}, },
.Vector4i32 => |vec| inline for (0..4) |i| switch (lane_bits) { .Vector4i32 => |vec| inline for (0..4) |i| switch (T) {
32 => std.mem.copyForward(u8, output[0..], std.mem.asBytes(vec[i])), i32 => output[i] = vec[i],
inline else => return RuntimeError.InvalidValueType, inline else => return RuntimeError.InvalidValueType,
}, },
.Vector3i32 => |vec| inline for (0..3) |i| switch (lane_bits) { .Vector3i32 => |vec| inline for (0..3) |i| switch (T) {
32 => std.mem.copyForward(u8, output[0..], std.mem.asBytes(vec[i])), i32 => output[i] = vec[i],
inline else => return RuntimeError.InvalidValueType, inline else => return RuntimeError.InvalidValueType,
}, },
.Vector2i32 => |vec| inline for (0..2) |i| switch (lane_bits) { .Vector2i32 => |vec| inline for (0..2) |i| switch (T) {
32 => std.mem.copyForward(u8, output[0..], std.mem.asBytes(vec[i])), i32 => output[i] = vec[i],
inline else => return RuntimeError.InvalidValueType, inline else => return RuntimeError.InvalidValueType,
}, },
.Vector4u32 => |vec| inline for (0..4) |i| switch (lane_bits) { .Vector4u32 => |vec| inline for (0..4) |i| switch (T) {
32 => std.mem.copyForward(u8, output[0..], std.mem.asBytes(vec[i])), u32 => output[i] = vec[i],
inline else => return RuntimeError.InvalidValueType, inline else => return RuntimeError.InvalidValueType,
}, },
.Vector3u32 => |vec| inline for (0..3) |i| switch (lane_bits) { .Vector3u32 => |vec| inline for (0..3) |i| switch (T) {
32 => std.mem.copyForward(u8, output[0..], std.mem.asBytes(vec[i])), u32 => output[i] = vec[i],
inline else => return RuntimeError.InvalidValueType, inline else => return RuntimeError.InvalidValueType,
}, },
.Vector2u32 => |vec| inline for (0..2) |i| switch (lane_bits) { .Vector2u32 => |vec| inline for (0..2) |i| switch (T) {
32 => std.mem.copyForward(u8, output[0..], std.mem.asBytes(vec[i])), u32 => output[i] = vec[i],
inline else => return RuntimeError.InvalidValueType, inline else => return RuntimeError.InvalidValueType,
}, },
.Array, .Vector, .Matrix, .Array, .Structure => |values| for (values, 0..) |v, i| try self.readValue(T, output[i..], &v),
.Matrix,
.Structure,
.Vector,
=> |values| for (values, 0..) |v, i| try self.readValue(T, output[i..], &v),
.RuntimeArray => |opt_values| if (opt_values) |values| {
for (values, 0..) |v, i|
try self.readValue(output[i..], result);
},
else => return RuntimeError.InvalidValueType, else => return RuntimeError.InvalidValueType,
} }
} }
@@ -336,15 +334,7 @@ fn writeValue(self: *const Self, comptime T: type, input: []const T, value: *Res
u32 => vec[i] = input[i], u32 => vec[i] = input[i],
inline else => return RuntimeError.InvalidValueType, inline else => return RuntimeError.InvalidValueType,
}, },
.Array, .Vector, .Matrix, .Array, .Structure => |*values| for (values.*, 0..) |*v, i| try self.writeValue(T, input[i..], v),
.Matrix,
.Structure,
.Vector,
=> |*values| for (values.*, 0..) |*v, i| try self.writeValue(T, input[i..], v),
.RuntimeArray => |opt_values| if (opt_values) |*values| {
for (values.*, 0..) |*v, i|
try self.writeValue(T, input[i..], v);
},
else => return RuntimeError.InvalidValueType, else => return RuntimeError.InvalidValueType,
} }
} }

View File

@@ -50,6 +50,7 @@ pub const case = struct {
pub fn expectOutputWithInput(comptime T: type, comptime len: usize, source: []const u32, output_name: []const u8, expected: []const T, input_name: []const u8, input: []const T) !void { pub fn expectOutputWithInput(comptime T: type, comptime len: usize, source: []const u32, output_name: []const u8, expected: []const T, input_name: []const u8, input: []const T) !void {
const allocator = std.testing.allocator; const allocator = std.testing.allocator;
// To test with all important module options
const module_options = [_]spv.Module.ModuleOptions{ const module_options = [_]spv.Module.ModuleOptions{
.{ .{
.use_simd_vectors_specializations = true, .use_simd_vectors_specializations = true,