adding builtin support
This commit is contained in:
@@ -74,6 +74,7 @@ geometry_output: SpvWord,
|
||||
input_locations: [lib.SPIRV_MAX_INPUT_LOCATIONS]SpvWord,
|
||||
output_locations: [lib.SPIRV_MAX_OUTPUT_LOCATIONS]SpvWord,
|
||||
bindings: [lib.SPIRV_MAX_SET][lib.SPIRV_MAX_SET_BINDINGS]SpvWord,
|
||||
builtins: std.EnumMap(spv.SpvBuiltIn, SpvWord),
|
||||
push_constants: []Value,
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator, source: []const SpvWord, options: ModuleOptions) ModuleError!Self {
|
||||
@@ -216,8 +217,14 @@ fn populateMaps(self: *Self) ModuleError!void {
|
||||
for (result.decorations.items) |decoration| {
|
||||
switch (result.variant.?.Variable.storage_class) {
|
||||
.Input => {
|
||||
if (decoration.rtype == .Location)
|
||||
self.input_locations[decoration.literal_1] = @intCast(id);
|
||||
switch (decoration.rtype) {
|
||||
.BuiltIn => self.builtins.put(
|
||||
std.enums.fromInt(spv.SpvBuiltIn, decoration.literal_1) orelse return ModuleError.InvalidSpirV,
|
||||
@intCast(id),
|
||||
),
|
||||
.Location => self.input_locations[decoration.literal_1] = @intCast(id),
|
||||
else => {},
|
||||
}
|
||||
},
|
||||
.Output => {
|
||||
if (decoration.rtype == .Location)
|
||||
|
||||
@@ -316,6 +316,29 @@ pub const TypeData = union(Type) {
|
||||
storage_class: spv.SpvStorageClass,
|
||||
target: SpvWord,
|
||||
},
|
||||
|
||||
pub fn getSize(self: *const TypeData, results: []const Self) usize {
|
||||
return switch (self.*) {
|
||||
.Bool => 1,
|
||||
.Int => |i| @divExact(i.bit_length, 8),
|
||||
.Float => |f| @divExact(f.bit_length, 8),
|
||||
.Vector => |v| results[v.components_type_word].variant.?.Type.getSize(results),
|
||||
.Array => |a| results[a.components_type_word].variant.?.Type.getSize(results),
|
||||
.Matrix => |m| results[m.column_type_word].variant.?.Type.getSize(results),
|
||||
.RuntimeArray => |a| results[a.components_type_word].variant.?.Type.getSize(results),
|
||||
.Structure => |s| blk: {
|
||||
var total: usize = 0;
|
||||
for (s.members_type_word) |type_word| {
|
||||
total += results[type_word].variant.?.Type.getSize(results);
|
||||
}
|
||||
break :blk total;
|
||||
},
|
||||
.Vector4f32, .Vector4i32, .Vector4u32 => 4 * 4,
|
||||
.Vector3f32, .Vector3i32, .Vector3u32 => 3 * 4,
|
||||
.Vector2f32, .Vector2i32, .Vector2u32 => 2 * 4,
|
||||
else => 0,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const VariantData = union(Variant) {
|
||||
|
||||
@@ -24,6 +24,7 @@ pub const RuntimeError = error{
|
||||
Killed,
|
||||
NotFound,
|
||||
OutOfMemory,
|
||||
OutOfBounds,
|
||||
ToDo,
|
||||
Unreachable,
|
||||
UnsupportedSpirV,
|
||||
@@ -167,8 +168,9 @@ pub fn writeDescriptorSet(self: *const Self, allocator: std.mem.Allocator, input
|
||||
const resolved = results[type_word].resolveType(results);
|
||||
|
||||
switch (value.*) {
|
||||
.RuntimeArray => {
|
||||
value.* = try Result.initValue(allocator2, len, results, resolved);
|
||||
.RuntimeArray => |a| if (a == null) {
|
||||
const elem_size = resolved.variant.?.Type.getSize(results);
|
||||
value.* = try Result.initValue(allocator2, @divExact(len, elem_size), results, resolved);
|
||||
},
|
||||
.Structure => |*s| for (s.*, 0..) |*elem, i| {
|
||||
try @This().init(allocator2, len, elem, resolved.variant.?.Type.Structure.members_type_word[i], results);
|
||||
@@ -179,12 +181,12 @@ pub fn writeDescriptorSet(self: *const Self, allocator: std.mem.Allocator, input
|
||||
};
|
||||
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;
|
||||
//@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;
|
||||
@@ -192,7 +194,7 @@ pub fn writeDescriptorSet(self: *const Self, allocator: std.mem.Allocator, input
|
||||
}
|
||||
|
||||
pub fn readOutput(self: *const Self, output: []u8, result: SpvWord) RuntimeError!void {
|
||||
if (std.mem.indexOf(SpvWord, &self.mod.output_locations, &.{result})) |_| {
|
||||
if (std.mem.indexOfScalar(SpvWord, &self.mod.output_locations, result)) |_| {
|
||||
_ = try self.readValue(output, &self.results[result].variant.?.Variable.value);
|
||||
} else {
|
||||
return RuntimeError.NotFound;
|
||||
@@ -200,7 +202,15 @@ pub fn readOutput(self: *const Self, output: []u8, result: SpvWord) RuntimeError
|
||||
}
|
||||
|
||||
pub fn writeInput(self: *const Self, input: []const u8, result: SpvWord) RuntimeError!void {
|
||||
if (std.mem.indexOf(SpvWord, &self.mod.input_locations, &.{result})) |_| {
|
||||
if (std.mem.indexOfScalar(SpvWord, &self.mod.input_locations, result)) |_| {
|
||||
_ = try self.writeValue(input, &self.results[result].variant.?.Variable.value);
|
||||
} else {
|
||||
return RuntimeError.NotFound;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn writeBuiltIn(self: *const Self, input: []const u8, builtin: spv.SpvBuiltIn) RuntimeError!void {
|
||||
if (self.mod.builtins.get(builtin)) |result| {
|
||||
_ = try self.writeValue(input, &self.results[result].variant.?.Variable.value);
|
||||
} else {
|
||||
return RuntimeError.NotFound;
|
||||
|
||||
@@ -1030,51 +1030,56 @@ fn opAccessChain(_: std.mem.Allocator, word_count: SpvWord, rt: *Runtime) Runtim
|
||||
.Variable => |v| &v.value,
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
};
|
||||
|
||||
switch (member_value.*) {
|
||||
.Int => |i| {
|
||||
if (std.meta.activeTag(value_ptr.*) == .Pointer) {
|
||||
value_ptr = value_ptr.Pointer.common; // Don't know if I should check for specialized pointers
|
||||
}
|
||||
|
||||
switch (value_ptr.*) {
|
||||
.Vector, .Matrix, .Array, .Structure => |v| {
|
||||
if (i.value.uint32 > v.len) return RuntimeError.InvalidSpirV;
|
||||
if (i.value.uint32 >= v.len) return RuntimeError.OutOfBounds;
|
||||
value_ptr = &v[i.value.uint32];
|
||||
},
|
||||
.RuntimeArray => |opt_v| if (opt_v) |v| {
|
||||
if (i.value.uint32 > v.len) return RuntimeError.InvalidSpirV;
|
||||
value_ptr = &v[i.value.uint32];
|
||||
.RuntimeArray => |opt_a| if (opt_a) |a| {
|
||||
if (i.value.uint32 >= a.len) return RuntimeError.OutOfBounds;
|
||||
value_ptr = &a[i.value.uint32];
|
||||
} else return RuntimeError.InvalidSpirV,
|
||||
.Vector4f32 => |*v| {
|
||||
if (i.value.uint32 > 4) return RuntimeError.InvalidSpirV;
|
||||
if (i.value.uint32 > 4) return RuntimeError.OutOfBounds;
|
||||
break :blk .{ .Pointer = .{ .f32_ptr = &v[i.value.uint32] } };
|
||||
},
|
||||
.Vector3f32 => |*v| {
|
||||
if (i.value.uint32 > 3) return RuntimeError.InvalidSpirV;
|
||||
if (i.value.uint32 > 3) return RuntimeError.OutOfBounds;
|
||||
break :blk .{ .Pointer = .{ .f32_ptr = &v[i.value.uint32] } };
|
||||
},
|
||||
.Vector2f32 => |*v| {
|
||||
if (i.value.uint32 > 2) return RuntimeError.InvalidSpirV;
|
||||
if (i.value.uint32 > 2) return RuntimeError.OutOfBounds;
|
||||
break :blk .{ .Pointer = .{ .f32_ptr = &v[i.value.uint32] } };
|
||||
},
|
||||
.Vector4i32 => |*v| {
|
||||
if (i.value.uint32 > 4) return RuntimeError.InvalidSpirV;
|
||||
if (i.value.uint32 > 4) return RuntimeError.OutOfBounds;
|
||||
break :blk .{ .Pointer = .{ .i32_ptr = &v[i.value.uint32] } };
|
||||
},
|
||||
.Vector3i32 => |*v| {
|
||||
if (i.value.uint32 > 3) return RuntimeError.InvalidSpirV;
|
||||
if (i.value.uint32 > 3) return RuntimeError.OutOfBounds;
|
||||
break :blk .{ .Pointer = .{ .i32_ptr = &v[i.value.uint32] } };
|
||||
},
|
||||
.Vector2i32 => |*v| {
|
||||
if (i.value.uint32 > 2) return RuntimeError.InvalidSpirV;
|
||||
if (i.value.uint32 > 2) return RuntimeError.OutOfBounds;
|
||||
break :blk .{ .Pointer = .{ .i32_ptr = &v[i.value.uint32] } };
|
||||
},
|
||||
.Vector4u32 => |*v| {
|
||||
if (i.value.uint32 > 4) return RuntimeError.InvalidSpirV;
|
||||
if (i.value.uint32 > 4) return RuntimeError.OutOfBounds;
|
||||
break :blk .{ .Pointer = .{ .u32_ptr = &v[i.value.uint32] } };
|
||||
},
|
||||
.Vector3u32 => |*v| {
|
||||
if (i.value.uint32 > 3) return RuntimeError.InvalidSpirV;
|
||||
if (i.value.uint32 > 3) return RuntimeError.OutOfBounds;
|
||||
break :blk .{ .Pointer = .{ .u32_ptr = &v[i.value.uint32] } };
|
||||
},
|
||||
.Vector2u32 => |*v| {
|
||||
if (i.value.uint32 > 2) return RuntimeError.InvalidSpirV;
|
||||
if (i.value.uint32 > 2) return RuntimeError.OutOfBounds;
|
||||
break :blk .{ .Pointer = .{ .u32_ptr = &v[i.value.uint32] } };
|
||||
},
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
|
||||
Reference in New Issue
Block a user