adding bitsize to primitive values
Build / build (push) Successful in 1m43s
Test / build (push) Successful in 4m37s

This commit is contained in:
2026-02-15 02:06:15 +01:00
parent ac4f41ddd4
commit 2ea707ea57
5 changed files with 320 additions and 208 deletions
+210 -115
View File
@@ -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;
}