This commit is contained in:
+23
-6
@@ -180,7 +180,7 @@ fn resolveConstantWord(self: *const Self, id: SpvWord) ?SpvWord {
|
||||
}
|
||||
|
||||
fn findAccessChainToMember(self: *const Self, base_id: SpvWord, member_index: SpvWord) ?SpvWord {
|
||||
for (self.results, 0..) |result, id| {
|
||||
for (self.results, 0..) |*result, id| {
|
||||
const variant = result.variant orelse continue;
|
||||
|
||||
switch (variant) {
|
||||
@@ -265,7 +265,7 @@ fn applyDecorations(self: *Self) ModuleError!void {
|
||||
var binding: ?usize = null;
|
||||
|
||||
for (result.decorations.items) |decoration| {
|
||||
switch (result.variant.?) {
|
||||
if (result.variant) |*variant| switch (variant.*) {
|
||||
.Variable => |v| {
|
||||
try self.applyInterfaceDecoration(v.storage_class, decoration, @intCast(id));
|
||||
|
||||
@@ -294,13 +294,30 @@ fn applyDecorations(self: *Self) ModuleError!void {
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
switch (result.variant.?) {
|
||||
.Variable => |v| try self.applyStructMemberInterfaceDecorations(v.storage_class, v.type_word, @intCast(id)),
|
||||
if (result.variant) |*variant| switch (variant.*) {
|
||||
.Variable => |*v| {
|
||||
try self.applyStructMemberInterfaceDecorations(v.storage_class, v.type_word, @intCast(id));
|
||||
switch (v.storage_class) {
|
||||
.StorageBuffer,
|
||||
.Uniform,
|
||||
.PushConstant,
|
||||
=> if (v.value == .Structure) {
|
||||
if (self.results[v.type_word].variant) |type_variant| switch (type_variant) {
|
||||
.Type => |type_data| switch (type_data) {
|
||||
.Structure => |s| @memcpy(@constCast(v.value.Structure.offsets), s.members_offsets),
|
||||
else => {},
|
||||
},
|
||||
else => {},
|
||||
};
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
};
|
||||
|
||||
if (set != null and binding != null) {
|
||||
self.bindings[set.?][binding.?] = @intCast(id);
|
||||
|
||||
+30
-2
@@ -18,6 +18,7 @@ const WordIterator = @import("WordIterator.zig");
|
||||
const Self = @This();
|
||||
|
||||
pub const RuntimeError = error{
|
||||
Barrier,
|
||||
DivisionByZero,
|
||||
InvalidEntryPoint,
|
||||
InvalidSpirV,
|
||||
@@ -33,6 +34,11 @@ pub const RuntimeError = error{
|
||||
Unknown,
|
||||
};
|
||||
|
||||
pub const EntryPointStatus = enum {
|
||||
completed,
|
||||
barrier,
|
||||
};
|
||||
|
||||
pub const SpecializationEntry = struct {
|
||||
id: SpvWord,
|
||||
offset: usize,
|
||||
@@ -119,6 +125,17 @@ pub fn addSpecializationInfo(self: *Self, allocator: std.mem.Allocator, entry: S
|
||||
self.specialization_constants.put(allocator, entry.id, slice) catch return RuntimeError.OutOfMemory;
|
||||
}
|
||||
|
||||
pub fn copySpecializationConstantsFrom(self: *Self, allocator: std.mem.Allocator, other: *const Self) RuntimeError!void {
|
||||
var it = other.specialization_constants.iterator();
|
||||
while (it.next()) |entry| {
|
||||
const slice = allocator.dupe(u8, entry.value_ptr.*) catch return RuntimeError.OutOfMemory;
|
||||
self.specialization_constants.put(allocator, entry.key_ptr.*, slice) catch {
|
||||
allocator.free(slice);
|
||||
return RuntimeError.OutOfMemory;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getEntryPointByName(self: *const Self, name: []const u8) RuntimeError!SpvWord {
|
||||
for (self.mod.entry_points.items, 0..) |entry_point, i| {
|
||||
if (blk: {
|
||||
@@ -176,8 +193,11 @@ pub fn dumpResultsTable(self: *Self, allocator: std.mem.Allocator, writer: *std.
|
||||
|
||||
/// 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 {
|
||||
self.reset();
|
||||
_ = try self.beginEntryPoint(allocator, entry_point_index);
|
||||
}
|
||||
|
||||
pub fn beginEntryPoint(self: *Self, allocator: std.mem.Allocator, entry_point_index: SpvWord) RuntimeError!EntryPointStatus {
|
||||
self.reset();
|
||||
if (entry_point_index > self.mod.entry_points.items.len)
|
||||
return RuntimeError.InvalidEntryPoint;
|
||||
|
||||
@@ -212,7 +232,15 @@ pub fn callEntryPoint(self: *Self, allocator: std.mem.Allocator, entry_point_ind
|
||||
}
|
||||
|
||||
// Execution pass
|
||||
try self.pass(allocator, null);
|
||||
return self.continueEntryPoint(allocator);
|
||||
}
|
||||
|
||||
pub fn continueEntryPoint(self: *Self, allocator: std.mem.Allocator) RuntimeError!EntryPointStatus {
|
||||
self.pass(allocator, null) catch |err| switch (err) {
|
||||
RuntimeError.Barrier => return .barrier,
|
||||
else => return err,
|
||||
};
|
||||
return .completed;
|
||||
}
|
||||
|
||||
fn pass(self: *Self, allocator: std.mem.Allocator, op_set: ?std.EnumSet(spv.SpvOp)) RuntimeError!void {
|
||||
|
||||
+17
-1
@@ -290,6 +290,7 @@ pub fn initRuntimeDispatcher() void {
|
||||
runtime_dispatcher[@intFromEnum(spv.SpvOp.CompositeConstruct)] = opCompositeConstruct;
|
||||
runtime_dispatcher[@intFromEnum(spv.SpvOp.CompositeExtract)] = opCompositeExtract;
|
||||
runtime_dispatcher[@intFromEnum(spv.SpvOp.CompositeInsert)] = opCompositeInsert;
|
||||
runtime_dispatcher[@intFromEnum(spv.SpvOp.ControlBarrier)] = opControlBarrier;
|
||||
runtime_dispatcher[@intFromEnum(spv.SpvOp.ConvertFToS)] = ConversionEngine(.Float, .SInt).op;
|
||||
runtime_dispatcher[@intFromEnum(spv.SpvOp.ConvertFToU)] = ConversionEngine(.Float, .UInt).op;
|
||||
runtime_dispatcher[@intFromEnum(spv.SpvOp.ConvertSToF)] = ConversionEngine(.SInt, .Float).op;
|
||||
@@ -349,6 +350,7 @@ pub fn initRuntimeDispatcher() void {
|
||||
runtime_dispatcher[@intFromEnum(spv.SpvOp.MatrixTimesMatrix)] = MathEngine(.Float, .MatrixTimesMatrix, false).op;
|
||||
runtime_dispatcher[@intFromEnum(spv.SpvOp.MatrixTimesScalar)] = MathEngine(.Float, .MatrixTimesScalar, false).op; // TODO
|
||||
runtime_dispatcher[@intFromEnum(spv.SpvOp.MatrixTimesVector)] = MathEngine(.Float, .MatrixTimesVector, false).op;
|
||||
runtime_dispatcher[@intFromEnum(spv.SpvOp.MemoryBarrier)] = opMemoryBarrier;
|
||||
runtime_dispatcher[@intFromEnum(spv.SpvOp.Not)] = BitEngine(.UInt, .Not).op;
|
||||
runtime_dispatcher[@intFromEnum(spv.SpvOp.Phi)] = opPhi;
|
||||
runtime_dispatcher[@intFromEnum(spv.SpvOp.Return)] = opReturn;
|
||||
@@ -1966,6 +1968,8 @@ fn MathEngine(comptime T: PrimitiveType, comptime Op: MathOp, comptime IsAtomic:
|
||||
fn addDecoration(allocator: std.mem.Allocator, rt: *Runtime, target: SpvWord, decoration_type: spv.SpvDecoration, member: ?SpvWord) RuntimeError!void {
|
||||
var decoration = rt.results[target].decorations.addOne(allocator) catch return RuntimeError.OutOfMemory;
|
||||
decoration.rtype = decoration_type;
|
||||
decoration.literal_1 = 0;
|
||||
decoration.literal_2 = null;
|
||||
decoration.index = if (member) |memb| memb else 0;
|
||||
|
||||
switch (decoration_type) {
|
||||
@@ -2332,7 +2336,7 @@ fn opAccessChain(allocator: std.mem.Allocator, word_count: SpvWord, rt: *Runtime
|
||||
if (uniform_slice_window != null) {
|
||||
uniform_slice_window = try helpers.advanceWindow(uniform_slice_window, member_offset);
|
||||
} else if (s.external_data) |data| {
|
||||
uniform_slice_window = data[0..];
|
||||
uniform_slice_window = try helpers.advanceWindow(data, member_offset);
|
||||
}
|
||||
|
||||
value_ptr = &s.values[component_index];
|
||||
@@ -2502,6 +2506,13 @@ fn opCapability(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!voi
|
||||
rt.mod.capabilities.insert(try rt.it.nextAs(spv.SpvCapability));
|
||||
}
|
||||
|
||||
fn opControlBarrier(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||
_ = rt.it.skip(); // execution scope
|
||||
_ = rt.it.skip(); // memory scope
|
||||
_ = rt.it.skip(); // memory semantics
|
||||
return RuntimeError.Barrier;
|
||||
}
|
||||
|
||||
fn opCompositeConstruct(_: std.mem.Allocator, word_count: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||
_ = rt.it.skip();
|
||||
const id = try rt.it.next();
|
||||
@@ -3498,6 +3509,11 @@ fn opMemoryModel(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!vo
|
||||
rt.mod.memory_model = try rt.it.nextAs(spv.SpvMemoryModel);
|
||||
}
|
||||
|
||||
fn opMemoryBarrier(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||
_ = rt.it.skip(); // memory scope
|
||||
_ = rt.it.skip(); // memory semantics
|
||||
}
|
||||
|
||||
fn opName(allocator: std.mem.Allocator, word_count: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||
const id = try rt.it.next();
|
||||
var result = &rt.results[id];
|
||||
|
||||
Reference in New Issue
Block a user