working on results
This commit is contained in:
@@ -10,6 +10,9 @@ pub fn build(b: *std.Build) void {
|
|||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const pretty = b.dependency("pretty", .{ .target = target, .optimize = optimize });
|
||||||
|
mod.addImport("pretty", pretty.module("pretty"));
|
||||||
|
|
||||||
const lib = b.addLibrary(.{
|
const lib = b.addLibrary(.{
|
||||||
.name = "spirv_interpreter",
|
.name = "spirv_interpreter",
|
||||||
.root_module = mod,
|
.root_module = mod,
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
.{
|
.{
|
||||||
.name = .SPIRV_Interpreter,
|
.name = .SPIRV_Interpreter,
|
||||||
.version = "0.0.1",
|
.version = "0.0.1",
|
||||||
.dependencies = .{},
|
.dependencies = .{
|
||||||
|
.pretty = .{
|
||||||
|
.url = "https://github.com/timfayz/pretty/archive/refs/heads/main.tar.gz",
|
||||||
|
.hash = "pretty-0.10.6-Tm65r6lPAQCBxgwzehYPeqsCXQDT9kt2ktJuO-2tRfE6",
|
||||||
|
},
|
||||||
|
},
|
||||||
.minimum_zig_version = "0.15.2",
|
.minimum_zig_version = "0.15.2",
|
||||||
.paths = .{
|
.paths = .{
|
||||||
"build.zig",
|
"build.zig",
|
||||||
|
|||||||
@@ -4,18 +4,21 @@ const lib = @import("lib.zig");
|
|||||||
const spv = @import("spv.zig");
|
const spv = @import("spv.zig");
|
||||||
const op = @import("opcodes.zig");
|
const op = @import("opcodes.zig");
|
||||||
|
|
||||||
|
const pretty = @import("pretty");
|
||||||
|
|
||||||
const SpvVoid = spv.SpvVoid;
|
const SpvVoid = spv.SpvVoid;
|
||||||
const SpvByte = spv.SpvByte;
|
const SpvByte = spv.SpvByte;
|
||||||
const SpvWord = spv.SpvWord;
|
const SpvWord = spv.SpvWord;
|
||||||
const SpvBool = spv.SpvBool;
|
const SpvBool = spv.SpvBool;
|
||||||
|
|
||||||
const SpvMember = spv.SpvMember;
|
|
||||||
const SpvBinding = spv.SpvBinding;
|
const SpvBinding = spv.SpvBinding;
|
||||||
|
|
||||||
const Result = @import("Result.zig");
|
const Result = @import("Result.zig");
|
||||||
const Runtime = @import("Runtime.zig");
|
const Runtime = @import("Runtime.zig");
|
||||||
const WordIterator = @import("WordIterator.zig");
|
const WordIterator = @import("WordIterator.zig");
|
||||||
|
|
||||||
|
const SpvValue = Result.SpvValue;
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
const SpvEntryPoint = struct {
|
const SpvEntryPoint = struct {
|
||||||
@@ -71,10 +74,10 @@ geometry_output_count: SpvWord,
|
|||||||
geometry_input: SpvWord,
|
geometry_input: SpvWord,
|
||||||
geometry_output: SpvWord,
|
geometry_output: SpvWord,
|
||||||
|
|
||||||
input_locations: std.AutoHashMap(SpvWord, *SpvMember),
|
input_locations: std.AutoHashMap(SpvWord, *SpvValue),
|
||||||
output_locations: std.AutoHashMap(SpvWord, *SpvMember),
|
output_locations: std.AutoHashMap(SpvWord, *SpvValue),
|
||||||
bindings: std.AutoHashMap(SpvBinding, *SpvMember),
|
bindings: std.AutoHashMap(SpvBinding, *SpvValue),
|
||||||
push_constants: []SpvMember,
|
push_constants: []SpvValue,
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator, source: []const SpvWord) ModuleError!Self {
|
pub fn init(allocator: std.mem.Allocator, source: []const SpvWord) ModuleError!Self {
|
||||||
var self: Self = std.mem.zeroInit(Self, .{
|
var self: Self = std.mem.zeroInit(Self, .{
|
||||||
@@ -87,9 +90,9 @@ pub fn init(allocator: std.mem.Allocator, source: []const SpvWord) ModuleError!S
|
|||||||
.local_size_x = 1,
|
.local_size_x = 1,
|
||||||
.local_size_y = 1,
|
.local_size_y = 1,
|
||||||
.local_size_z = 1,
|
.local_size_z = 1,
|
||||||
.input_locations = std.AutoHashMap(SpvWord, *SpvMember).init(allocator),
|
.input_locations = std.AutoHashMap(SpvWord, *SpvValue).init(allocator),
|
||||||
.output_locations = std.AutoHashMap(SpvWord, *SpvMember).init(allocator),
|
.output_locations = std.AutoHashMap(SpvWord, *SpvValue).init(allocator),
|
||||||
.bindings = std.AutoHashMap(SpvBinding, *SpvMember).init(allocator),
|
.bindings = std.AutoHashMap(SpvBinding, *SpvValue).init(allocator),
|
||||||
});
|
});
|
||||||
errdefer self.deinit(allocator);
|
errdefer self.deinit(allocator);
|
||||||
|
|
||||||
@@ -162,6 +165,8 @@ pub fn init(allocator: std.mem.Allocator, source: []const SpvWord) ModuleError!S
|
|||||||
capabilities,
|
capabilities,
|
||||||
entry_points,
|
entry_points,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
pretty.print(allocator, self.results, .{ .tab_size = 4, .max_depth = 0 }) catch return ModuleError.OutOfMemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
|||||||
154
src/Result.zig
154
src/Result.zig
@@ -6,11 +6,9 @@ const SpvByte = spv.SpvByte;
|
|||||||
const SpvWord = spv.SpvWord;
|
const SpvWord = spv.SpvWord;
|
||||||
const SpvBool = spv.SpvBool;
|
const SpvBool = spv.SpvBool;
|
||||||
|
|
||||||
const Type = enum {
|
pub const Variant = enum {
|
||||||
None,
|
|
||||||
String,
|
String,
|
||||||
Extension,
|
Extension,
|
||||||
FunctionType,
|
|
||||||
Type,
|
Type,
|
||||||
Variable,
|
Variable,
|
||||||
Constant,
|
Constant,
|
||||||
@@ -20,7 +18,7 @@ const Type = enum {
|
|||||||
Label,
|
Label,
|
||||||
};
|
};
|
||||||
|
|
||||||
const ValueType = enum {
|
pub const Type = enum {
|
||||||
Void,
|
Void,
|
||||||
Bool,
|
Bool,
|
||||||
Int,
|
Int,
|
||||||
@@ -30,6 +28,7 @@ const ValueType = enum {
|
|||||||
Array,
|
Array,
|
||||||
RuntimeArray,
|
RuntimeArray,
|
||||||
Structure,
|
Structure,
|
||||||
|
Function,
|
||||||
Image,
|
Image,
|
||||||
Sampler,
|
Sampler,
|
||||||
SampledImage,
|
SampledImage,
|
||||||
@@ -53,6 +52,36 @@ const Decoration = struct {
|
|||||||
index: SpvWord,
|
index: SpvWord,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const SpvValue = union(Type) {
|
||||||
|
Void: noreturn,
|
||||||
|
Bool: bool,
|
||||||
|
Int: union {
|
||||||
|
sint8: i8,
|
||||||
|
sint16: i16,
|
||||||
|
sint32: i32,
|
||||||
|
sint64: i64,
|
||||||
|
uint8: u8,
|
||||||
|
uint16: u16,
|
||||||
|
uint32: u32,
|
||||||
|
uint64: u64,
|
||||||
|
},
|
||||||
|
Float: union {
|
||||||
|
float16: f16,
|
||||||
|
float32: f32,
|
||||||
|
float64: f64,
|
||||||
|
},
|
||||||
|
Vector: noreturn,
|
||||||
|
Matrix: noreturn,
|
||||||
|
Array: struct {},
|
||||||
|
RuntimeArray: struct {},
|
||||||
|
Structure: struct {},
|
||||||
|
Function: noreturn,
|
||||||
|
Image: struct {},
|
||||||
|
Sampler: struct {},
|
||||||
|
SampledImage: struct {},
|
||||||
|
Pointer: noreturn,
|
||||||
|
};
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
name: ?[]const u8,
|
name: ?[]const u8,
|
||||||
@@ -60,55 +89,55 @@ name: ?[]const u8,
|
|||||||
parent: ?*const Self,
|
parent: ?*const Self,
|
||||||
|
|
||||||
member_names: std.ArrayList([]const u8),
|
member_names: std.ArrayList([]const u8),
|
||||||
members: std.ArrayList(spv.SpvMember),
|
|
||||||
|
|
||||||
decorations: std.ArrayList(Decoration),
|
decorations: std.ArrayList(Decoration),
|
||||||
|
|
||||||
res_type: Type,
|
variant: ?union(Variant) {
|
||||||
type_data: union(Type) {
|
|
||||||
None: struct {},
|
|
||||||
String: []const u8,
|
String: []const u8,
|
||||||
Extension: struct {},
|
Extension: struct {},
|
||||||
FunctionType: struct {
|
Type: union(Type) {
|
||||||
return_type: SpvWord,
|
Void: struct {},
|
||||||
},
|
Bool: struct {},
|
||||||
Type: struct {
|
Int: struct {
|
||||||
value_type: ValueType,
|
bit_length: SpvWord,
|
||||||
data: union(ValueType) {
|
is_signed: bool,
|
||||||
Void: struct {},
|
},
|
||||||
Bool: struct {},
|
Float: struct {
|
||||||
Int: struct {
|
bit_length: SpvWord,
|
||||||
bit_length: SpvWord,
|
},
|
||||||
is_signed: bool,
|
Vector: struct {
|
||||||
},
|
components_type: Type,
|
||||||
Float: struct {
|
member_count: SpvWord,
|
||||||
bit_length: SpvWord,
|
},
|
||||||
},
|
Matrix: struct {
|
||||||
Vector: struct {
|
column_type: Type,
|
||||||
components_type: ValueType,
|
member_count: SpvWord,
|
||||||
},
|
},
|
||||||
Matrix: struct {
|
Array: struct {},
|
||||||
column_type: ValueType,
|
RuntimeArray: struct {},
|
||||||
},
|
Structure: struct {
|
||||||
Array: struct {},
|
/// Allocated array
|
||||||
RuntimeArray: struct {},
|
members: []const SpvWord,
|
||||||
Structure: struct {},
|
},
|
||||||
Image: struct {},
|
Function: struct {
|
||||||
Sampler: struct {},
|
return_type: SpvWord,
|
||||||
SampledImage: struct {},
|
/// Allocated array
|
||||||
Pointer: struct {
|
params: []const SpvWord,
|
||||||
storage_class: spv.SpvStorageClass,
|
},
|
||||||
},
|
Image: struct {},
|
||||||
|
Sampler: struct {},
|
||||||
|
SampledImage: struct {},
|
||||||
|
Pointer: struct {
|
||||||
|
storage_class: spv.SpvStorageClass,
|
||||||
|
target: SpvWord,
|
||||||
},
|
},
|
||||||
member_count: SpvWord = 0,
|
|
||||||
id: SpvWord = 0,
|
|
||||||
},
|
},
|
||||||
Variable: struct {},
|
Variable: struct {
|
||||||
Constant: struct {},
|
storage_class: spv.SpvStorageClass,
|
||||||
Function: struct {
|
value: SpvValue,
|
||||||
/// Allocated array
|
|
||||||
params: []SpvWord,
|
|
||||||
},
|
},
|
||||||
|
Constant: SpvValue,
|
||||||
|
Function: struct {},
|
||||||
AccessChain: struct {},
|
AccessChain: struct {},
|
||||||
FunctionParameter: struct {},
|
FunctionParameter: struct {},
|
||||||
Label: struct {},
|
Label: struct {},
|
||||||
@@ -119,10 +148,8 @@ pub fn init() Self {
|
|||||||
.name = null,
|
.name = null,
|
||||||
.parent = null,
|
.parent = null,
|
||||||
.member_names = .empty,
|
.member_names = .empty,
|
||||||
.members = .empty,
|
|
||||||
.decorations = .empty,
|
.decorations = .empty,
|
||||||
.res_type = .None,
|
.variant = null,
|
||||||
.type_data = undefined,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,12 +160,31 @@ pub fn deinit(self: *Self, allocator: std.mem.Allocator) void {
|
|||||||
for (self.member_names.items) |name| {
|
for (self.member_names.items) |name| {
|
||||||
allocator.free(name);
|
allocator.free(name);
|
||||||
}
|
}
|
||||||
// FIXME
|
if (self.variant) |variant| {
|
||||||
//switch (self.type_data) {
|
switch (variant) {
|
||||||
// .Function => |data| allocator.free(data.params),
|
.Type => |t| {
|
||||||
// else => {},
|
switch (t) {
|
||||||
//}
|
.Function => |data| allocator.free(data.params),
|
||||||
|
.Structure => |data| allocator.free(data.members),
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
self.member_names.deinit(allocator);
|
self.member_names.deinit(allocator);
|
||||||
self.members.deinit(allocator);
|
|
||||||
self.decorations.deinit(allocator);
|
self.decorations.deinit(allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn resolveType(self: *const Self, results: []const Self) *const Self {
|
||||||
|
return if (self.variant) |variant|
|
||||||
|
switch (variant) {
|
||||||
|
.Type => |t| switch (t) {
|
||||||
|
.Pointer => |ptr| &results[ptr.target],
|
||||||
|
else => self,
|
||||||
|
},
|
||||||
|
else => self,
|
||||||
|
}
|
||||||
|
else
|
||||||
|
self;
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ const Self = @This();
|
|||||||
|
|
||||||
pub const RuntimeError = error{
|
pub const RuntimeError = error{
|
||||||
InvalidSpirV,
|
InvalidSpirV,
|
||||||
|
UnsupportedSpirV,
|
||||||
OutOfMemory,
|
OutOfMemory,
|
||||||
Unreachable,
|
Unreachable,
|
||||||
Killed,
|
Killed,
|
||||||
|
|||||||
193
src/opcodes.zig
193
src/opcodes.zig
@@ -14,9 +14,6 @@ const SpvWord = spv.SpvWord;
|
|||||||
const SpvBool = spv.SpvBool;
|
const SpvBool = spv.SpvBool;
|
||||||
|
|
||||||
// DUMB INDEV OPCODES TODO :
|
// DUMB INDEV OPCODES TODO :
|
||||||
// OpTypeFunction X
|
|
||||||
// OpTypeStruct X
|
|
||||||
// OpConstant X
|
|
||||||
// OpVariable X
|
// OpVariable X
|
||||||
// OpFunction X
|
// OpFunction X
|
||||||
// OpLabel X
|
// OpLabel X
|
||||||
@@ -34,6 +31,7 @@ pub const SetupDispatcher = block: {
|
|||||||
@setEvalBranchQuota(65535);
|
@setEvalBranchQuota(65535);
|
||||||
break :block std.EnumMap(spv.SpvOp, OpCodeFunc).init(.{
|
break :block std.EnumMap(spv.SpvOp, OpCodeFunc).init(.{
|
||||||
.Capability = opCapability,
|
.Capability = opCapability,
|
||||||
|
.Constant = opConstant,
|
||||||
.Decorate = opDecorate,
|
.Decorate = opDecorate,
|
||||||
.EntryPoint = opEntryPoint,
|
.EntryPoint = opEntryPoint,
|
||||||
.ExecutionMode = opExecutionMode,
|
.ExecutionMode = opExecutionMode,
|
||||||
@@ -43,13 +41,16 @@ pub const SetupDispatcher = block: {
|
|||||||
.Name = opName,
|
.Name = opName,
|
||||||
.Source = opSource,
|
.Source = opSource,
|
||||||
.SourceExtension = opSourceExtension,
|
.SourceExtension = opSourceExtension,
|
||||||
.TypeVoid = opTypeVoid,
|
|
||||||
.TypeBool = opTypeBool,
|
.TypeBool = opTypeBool,
|
||||||
.TypeInt = opTypeInt,
|
|
||||||
.TypeFloat = opTypeFloat,
|
.TypeFloat = opTypeFloat,
|
||||||
.TypeVector = opTypeVector,
|
.TypeFunction = opTypeFunction,
|
||||||
|
.TypeInt = opTypeInt,
|
||||||
.TypeMatrix = opTypeMatrix,
|
.TypeMatrix = opTypeMatrix,
|
||||||
.TypePointer = opTypePointer,
|
.TypePointer = opTypePointer,
|
||||||
|
.TypeStruct = opTypeStruct,
|
||||||
|
.TypeVector = opTypeVector,
|
||||||
|
.TypeVoid = opTypeVoid,
|
||||||
|
.Variable = opVariable,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -203,114 +204,180 @@ fn opSourceExtension(allocator: std.mem.Allocator, word_count: SpvWord, rt: *Run
|
|||||||
|
|
||||||
fn opTypeVoid(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
fn opTypeVoid(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||||
const id = try rt.it.next();
|
const id = try rt.it.next();
|
||||||
rt.mod.results.items[id].res_type = .Type;
|
rt.mod.results.items[id].variant = .{
|
||||||
rt.mod.results.items[id].type_data = .{
|
|
||||||
.Type = .{
|
.Type = .{
|
||||||
.value_type = .Void,
|
.Void = .{},
|
||||||
.data = .{
|
|
||||||
.Void = .{},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn opTypeBool(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
fn opTypeBool(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||||
const id = try rt.it.next();
|
const id = try rt.it.next();
|
||||||
rt.mod.results.items[id].res_type = .Type;
|
rt.mod.results.items[id].variant = .{
|
||||||
rt.mod.results.items[id].type_data = .{
|
|
||||||
.Type = .{
|
.Type = .{
|
||||||
.value_type = .Bool,
|
.Bool = .{},
|
||||||
.data = .{
|
|
||||||
.Bool = .{},
|
|
||||||
},
|
|
||||||
.member_count = 1,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn opTypeInt(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
fn opTypeInt(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||||
const id = try rt.it.next();
|
const id = try rt.it.next();
|
||||||
rt.mod.results.items[id].res_type = .Type;
|
rt.mod.results.items[id].variant = .{
|
||||||
rt.mod.results.items[id].type_data = .{
|
|
||||||
.Type = .{
|
.Type = .{
|
||||||
.value_type = .Int,
|
.Int = .{
|
||||||
.data = .{
|
.bit_length = try rt.it.next(),
|
||||||
.Int = .{
|
.is_signed = if (try rt.it.next() != 0) true else false,
|
||||||
.bit_length = try rt.it.next(),
|
|
||||||
.is_signed = if (try rt.it.next() != 0) true else false,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
.member_count = 1,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn opTypeFloat(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
fn opTypeFloat(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||||
const id = try rt.it.next();
|
const id = try rt.it.next();
|
||||||
rt.mod.results.items[id].res_type = .Type;
|
rt.mod.results.items[id].variant = .{
|
||||||
rt.mod.results.items[id].type_data = .{
|
|
||||||
.Type = .{
|
.Type = .{
|
||||||
.value_type = .Float,
|
.Float = .{
|
||||||
.data = .{
|
.bit_length = try rt.it.next(),
|
||||||
.Float = .{
|
|
||||||
.bit_length = try rt.it.next(),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
.member_count = 1,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn opTypeVector(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
fn opTypeVector(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||||
const id = try rt.it.next();
|
const id = try rt.it.next();
|
||||||
rt.mod.results.items[id].res_type = .Type;
|
rt.mod.results.items[id].variant = .{
|
||||||
rt.mod.results.items[id].type_data = .{
|
|
||||||
.Type = .{
|
.Type = .{
|
||||||
.value_type = .Vector,
|
.Vector = .{
|
||||||
.data = .{
|
.components_type = switch (rt.mod.results.items[try rt.it.next()].variant.?) {
|
||||||
.Vector = .{
|
.Type => |t| @as(Result.Type, t),
|
||||||
.components_type = switch (rt.mod.results.items[try rt.it.next()].type_data) {
|
else => return RuntimeError.InvalidSpirV,
|
||||||
.Type => |data| data.value_type,
|
|
||||||
else => return RuntimeError.InvalidSpirV,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
.member_count = try rt.it.next(),
|
||||||
},
|
},
|
||||||
.member_count = try rt.it.next(),
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn opTypeMatrix(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
fn opTypeMatrix(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||||
const id = try rt.it.next();
|
const id = try rt.it.next();
|
||||||
rt.mod.results.items[id].res_type = .Type;
|
rt.mod.results.items[id].variant = .{
|
||||||
rt.mod.results.items[id].type_data = .{
|
|
||||||
.Type = .{
|
.Type = .{
|
||||||
.value_type = .Matrix,
|
.Matrix = .{
|
||||||
.data = .{
|
.column_type = switch (rt.mod.results.items[try rt.it.next()].variant.?) {
|
||||||
.Matrix = .{
|
.Type => |t| @as(Result.Type, t),
|
||||||
.column_type = switch (rt.mod.results.items[try rt.it.next()].type_data) {
|
else => return RuntimeError.InvalidSpirV,
|
||||||
.Type => |data| data.value_type,
|
|
||||||
else => return RuntimeError.InvalidSpirV,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
.member_count = try rt.it.next(),
|
||||||
},
|
},
|
||||||
.member_count = try rt.it.next(),
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn opTypePointer(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
fn opTypePointer(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||||
const id = try rt.it.next();
|
const id = try rt.it.next();
|
||||||
rt.mod.results.items[id].res_type = .Type;
|
rt.mod.results.items[id].variant = .{
|
||||||
rt.mod.results.items[id].type_data = .{
|
|
||||||
.Type = .{
|
.Type = .{
|
||||||
.value_type = .Pointer,
|
.Pointer = .{
|
||||||
.data = .{
|
.storage_class = try rt.it.nextAs(spv.SpvStorageClass),
|
||||||
.Pointer = .{
|
.target = try rt.it.next(),
|
||||||
.storage_class = try rt.it.nextAs(spv.SpvStorageClass),
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn opTypeStruct(allocator: std.mem.Allocator, word_count: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||||
|
const id = try rt.it.next();
|
||||||
|
rt.mod.results.items[id].variant = .{
|
||||||
|
.Type = .{
|
||||||
|
.Structure = .{
|
||||||
|
.members = blk: {
|
||||||
|
const members = allocator.alloc(SpvWord, word_count - 1) catch return RuntimeError.OutOfMemory;
|
||||||
|
errdefer allocator.free(members);
|
||||||
|
for (members) |*member| {
|
||||||
|
member.* = try rt.it.next();
|
||||||
|
}
|
||||||
|
break :blk members;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
.id = try rt.it.next(),
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn opTypeFunction(allocator: std.mem.Allocator, word_count: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||||
|
const id = try rt.it.next();
|
||||||
|
rt.mod.results.items[id].variant = .{
|
||||||
|
.Type = .{
|
||||||
|
.Function = .{
|
||||||
|
.return_type = try rt.it.next(),
|
||||||
|
.params = blk: {
|
||||||
|
const params = allocator.alloc(SpvWord, word_count - 2) catch return RuntimeError.OutOfMemory;
|
||||||
|
errdefer allocator.free(params);
|
||||||
|
for (params) |*param| {
|
||||||
|
param.* = try rt.it.next();
|
||||||
|
}
|
||||||
|
break :blk params;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn opConstant(_: std.mem.Allocator, word_count: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||||
|
const var_type = try rt.it.next();
|
||||||
|
const id = try rt.it.next();
|
||||||
|
rt.mod.results.items[id].variant = .{
|
||||||
|
.Constant = value: {
|
||||||
|
const resolved = rt.mod.results.items[var_type].resolveType(rt.mod.results.items);
|
||||||
|
if (resolved.variant) |variant| {
|
||||||
|
switch (variant) {
|
||||||
|
.Type => |t| switch (t) {
|
||||||
|
.Int => {
|
||||||
|
break :value if (word_count - 2 != 1) .{
|
||||||
|
.Int = .{
|
||||||
|
.uint64 = try rt.it.next() | (@as(u64, try rt.it.next()) >> 32),
|
||||||
|
},
|
||||||
|
} else .{
|
||||||
|
.Int = .{
|
||||||
|
.uint32 = try rt.it.next(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
.Float => {
|
||||||
|
break :value if (word_count - 2 != 1) .{
|
||||||
|
.Float = .{
|
||||||
|
.float64 = @bitCast(@as(u64, try rt.it.next()) | (@as(u64, try rt.it.next()) >> 32)),
|
||||||
|
},
|
||||||
|
} else .{
|
||||||
|
.Float = .{
|
||||||
|
.float32 = @bitCast(try rt.it.next()),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
else => {}, // Will fallback on error,
|
||||||
|
},
|
||||||
|
else => {}, // Will fallback on error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RuntimeError.InvalidSpirV;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn opVariable(_: std.mem.Allocator, word_count: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||||
|
const var_type = try rt.it.next();
|
||||||
|
const id = try rt.it.next();
|
||||||
|
const storage_class = try rt.it.nextAs(spv.SpvStorageClass);
|
||||||
|
const initializer: ?SpvWord = if (word_count >= 4) try rt.it.next() else null;
|
||||||
|
_ = initializer;
|
||||||
|
|
||||||
|
rt.mod.results.items[id].variant = .{
|
||||||
|
.Variable = .{
|
||||||
|
.storage_class = storage_class,
|
||||||
|
.value = value: {
|
||||||
|
const resolved = rt.mod.results.items[var_type].resolveType(rt.mod.results.items);
|
||||||
|
_ = resolved;
|
||||||
|
break :value undefined;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
14
src/spv.zig
14
src/spv.zig
@@ -68,20 +68,6 @@ pub fn vendorName(id: u32) []const u8 {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const SpvMember = struct {
|
|
||||||
type: SpvWord,
|
|
||||||
value: union {
|
|
||||||
boolean: bool,
|
|
||||||
int32: i32,
|
|
||||||
uint32: u32,
|
|
||||||
uint64: u64,
|
|
||||||
float32: f32,
|
|
||||||
float64: f64,
|
|
||||||
// TODO: sampler, image, sampledimage
|
|
||||||
},
|
|
||||||
members: []SpvMember,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const SpvBinding = struct {
|
pub const SpvBinding = struct {
|
||||||
set: SpvWord,
|
set: SpvWord,
|
||||||
binding: SpvWord,
|
binding: SpvWord,
|
||||||
|
|||||||
Reference in New Issue
Block a user