adding OpFMul
This commit is contained in:
@@ -17,7 +17,7 @@ pub fn build(b: *std.Build) void {
|
|||||||
.name = "spirv_interpreter",
|
.name = "spirv_interpreter",
|
||||||
.root_module = mod,
|
.root_module = mod,
|
||||||
.linkage = .dynamic,
|
.linkage = .dynamic,
|
||||||
.use_llvm = true,
|
//.use_llvm = true,
|
||||||
});
|
});
|
||||||
const lib_install = b.addInstallArtifact(lib, .{});
|
const lib_install = b.addInstallArtifact(lib, .{});
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,9 @@ struct FragOut
|
|||||||
[entry(frag)]
|
[entry(frag)]
|
||||||
fn main() -> FragOut
|
fn main() -> FragOut
|
||||||
{
|
{
|
||||||
|
let ratio = vec4[f32](2.0, 2.0, 8.0, 0.25);
|
||||||
|
|
||||||
let output: FragOut;
|
let output: FragOut;
|
||||||
output.color = vec4[f32](4.0, 3.0, 2.0, 1.0);
|
output.color = vec4[f32](4.0, 3.0, 2.0, 1.0) * ratio;
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@@ -1,7 +1,7 @@
|
|||||||
; SPIR-V
|
; SPIR-V
|
||||||
; Version: 1.0
|
; Version: 1.0
|
||||||
; Generator: SirLynix Nazara ShaderLang Compiler; 4226
|
; Generator: SirLynix Nazara ShaderLang Compiler; 4226
|
||||||
; Bound: 23
|
; Bound: 29
|
||||||
; Schema: 0
|
; Schema: 0
|
||||||
OpCapability Shader
|
OpCapability Shader
|
||||||
OpMemoryModel Logical GLSL450
|
OpMemoryModel Logical GLSL450
|
||||||
@@ -21,23 +21,30 @@
|
|||||||
%v4float = OpTypeVector %float 4
|
%v4float = OpTypeVector %float 4
|
||||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||||
%FragOut = OpTypeStruct %v4float
|
%FragOut = OpTypeStruct %v4float
|
||||||
|
%float_2 = OpConstant %float 2
|
||||||
|
%float_8 = OpConstant %float 8
|
||||||
|
%float_0_25 = OpConstant %float 0.25
|
||||||
|
%_ptr_Function_v4float = OpTypePointer Function %v4float
|
||||||
%_ptr_Function_FragOut = OpTypePointer Function %FragOut
|
%_ptr_Function_FragOut = OpTypePointer Function %FragOut
|
||||||
%int = OpTypeInt 32 1
|
%int = OpTypeInt 32 1
|
||||||
%int_0 = OpConstant %int 0
|
%int_0 = OpConstant %int 0
|
||||||
%float_4 = OpConstant %float 4
|
%float_4 = OpConstant %float 4
|
||||||
%float_3 = OpConstant %float 3
|
%float_3 = OpConstant %float 3
|
||||||
%float_2 = OpConstant %float 2
|
|
||||||
%float_1 = OpConstant %float 1
|
%float_1 = OpConstant %float 1
|
||||||
%_ptr_Function_v4float = OpTypePointer Function %v4float
|
|
||||||
%color = OpVariable %_ptr_Output_v4float Output
|
%color = OpVariable %_ptr_Output_v4float Output
|
||||||
%main = OpFunction %void None %2
|
%main = OpFunction %void None %2
|
||||||
%16 = OpLabel
|
%19 = OpLabel
|
||||||
%17 = OpVariable %_ptr_Function_FragOut Function
|
%20 = OpVariable %_ptr_Function_v4float Function
|
||||||
%18 = OpCompositeConstruct %v4float %float_4 %float_3 %float_2 %float_1
|
%21 = OpVariable %_ptr_Function_FragOut Function
|
||||||
%19 = OpAccessChain %_ptr_Function_v4float %17 %int_0
|
%22 = OpCompositeConstruct %v4float %float_2 %float_2 %float_8 %float_0_25
|
||||||
OpStore %19 %18
|
OpStore %20 %22
|
||||||
%21 = OpLoad %FragOut %17
|
%23 = OpCompositeConstruct %v4float %float_4 %float_3 %float_2 %float_1
|
||||||
%22 = OpCompositeExtract %v4float %21 0
|
%24 = OpLoad %v4float %20
|
||||||
OpStore %color %22
|
%25 = OpFMul %v4float %23 %24
|
||||||
|
%26 = OpAccessChain %_ptr_Function_v4float %21 %int_0
|
||||||
|
OpStore %26 %25
|
||||||
|
%27 = OpLoad %FragOut %21
|
||||||
|
%28 = OpCompositeExtract %v4float %27 0
|
||||||
|
OpStore %color %28
|
||||||
OpReturn
|
OpReturn
|
||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
|
|||||||
@@ -160,7 +160,12 @@ pub fn init(allocator: std.mem.Allocator, source: []const SpvWord) ModuleError!S
|
|||||||
entry_points,
|
entry_points,
|
||||||
});
|
});
|
||||||
|
|
||||||
//@import("pretty").print(allocator, self.results, .{ .tab_size = 4, .max_depth = 0 }) catch return ModuleError.OutOfMemory;
|
//@import("pretty").print(allocator, self.results, .{
|
||||||
|
// .tab_size = 4,
|
||||||
|
// .max_depth = 0,
|
||||||
|
// .struct_max_len = 0,
|
||||||
|
// .array_max_len = 0,
|
||||||
|
//}) catch return ModuleError.OutOfMemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
|||||||
@@ -293,6 +293,14 @@ pub fn deinit(self: *Self, allocator: std.mem.Allocator) void {
|
|||||||
self.decorations.deinit(allocator);
|
self.decorations.deinit(allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn getValue(self: *Self) RuntimeError!*Value {
|
||||||
|
return switch (self.variant orelse return RuntimeError.InvalidSpirV) {
|
||||||
|
.Variable => |*v| &v.value,
|
||||||
|
.Constant => |*v| v,
|
||||||
|
else => RuntimeError.InvalidSpirV,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// Performs a deep copy
|
/// Performs a deep copy
|
||||||
pub fn dupe(self: *const Self, allocator: std.mem.Allocator) RuntimeError!Self {
|
pub fn dupe(self: *const Self, allocator: std.mem.Allocator) RuntimeError!Self {
|
||||||
return .{
|
return .{
|
||||||
@@ -330,7 +338,7 @@ pub fn dupe(self: *const Self, allocator: std.mem.Allocator) RuntimeError!Self {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
else => {},
|
else => break :blk .{ .Type = t },
|
||||||
},
|
},
|
||||||
.Variable => |v| break :blk .{
|
.Variable => |v| break :blk .{
|
||||||
.Variable = .{
|
.Variable = .{
|
||||||
|
|||||||
@@ -19,7 +19,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,
|
||||||
.CompositeConstruct = opCompositeConstructSetup,
|
.CompositeConstruct = autoSetupConstant,
|
||||||
.Constant = opConstant,
|
.Constant = opConstant,
|
||||||
.Decorate = opDecorate,
|
.Decorate = opDecorate,
|
||||||
.EntryPoint = opEntryPoint,
|
.EntryPoint = opEntryPoint,
|
||||||
@@ -27,7 +27,7 @@ pub const SetupDispatcher = block: {
|
|||||||
.Function = opFunction,
|
.Function = opFunction,
|
||||||
.FunctionEnd = opFunctionEnd,
|
.FunctionEnd = opFunctionEnd,
|
||||||
.Label = opLabel,
|
.Label = opLabel,
|
||||||
.Load = opLoadSetup,
|
.Load = autoSetupConstant,
|
||||||
.MemberDecorate = opDecorateMember,
|
.MemberDecorate = opDecorateMember,
|
||||||
.MemberName = opMemberName,
|
.MemberName = opMemberName,
|
||||||
.MemoryModel = opMemoryModel,
|
.MemoryModel = opMemoryModel,
|
||||||
@@ -44,6 +44,7 @@ pub const SetupDispatcher = block: {
|
|||||||
.TypeVector = opTypeVector,
|
.TypeVector = opTypeVector,
|
||||||
.TypeVoid = opTypeVoid,
|
.TypeVoid = opTypeVoid,
|
||||||
.Variable = opVariable,
|
.Variable = opVariable,
|
||||||
|
.FMul = autoSetupConstant,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -56,6 +57,7 @@ pub const RuntimeDispatcher = block: {
|
|||||||
.Load = opLoad,
|
.Load = opLoad,
|
||||||
.Return = opReturn,
|
.Return = opReturn,
|
||||||
.Store = opStore,
|
.Store = opStore,
|
||||||
|
.FMul = opFMul,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -272,7 +274,7 @@ fn opTypeVector(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!voi
|
|||||||
.Type = .{
|
.Type = .{
|
||||||
.Vector = .{
|
.Vector = .{
|
||||||
.components_type_word = components_type_word,
|
.components_type_word = components_type_word,
|
||||||
.components_type = switch (rt.mod.results[components_type_word].variant.?) {
|
.components_type = switch (rt.mod.results[components_type_word].variant orelse return RuntimeError.InvalidSpirV) {
|
||||||
.Type => |t| @as(Result.Type, t),
|
.Type => |t| @as(Result.Type, t),
|
||||||
else => return RuntimeError.InvalidSpirV,
|
else => return RuntimeError.InvalidSpirV,
|
||||||
},
|
},
|
||||||
@@ -289,7 +291,7 @@ fn opTypeMatrix(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!voi
|
|||||||
.Type = .{
|
.Type = .{
|
||||||
.Matrix = .{
|
.Matrix = .{
|
||||||
.column_type_word = column_type_word,
|
.column_type_word = column_type_word,
|
||||||
.column_type = switch (rt.mod.results[column_type_word].variant.?) {
|
.column_type = switch (rt.mod.results[column_type_word].variant orelse return RuntimeError.InvalidSpirV) {
|
||||||
.Type => |t| @as(Result.Type, t),
|
.Type => |t| @as(Result.Type, t),
|
||||||
else => return RuntimeError.InvalidSpirV,
|
else => return RuntimeError.InvalidSpirV,
|
||||||
},
|
},
|
||||||
@@ -459,10 +461,6 @@ fn opLabel(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn opCompositeConstructSetup(allocator: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
|
||||||
_ = try setupConstant(allocator, rt);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn opCompositeConstruct(_: std.mem.Allocator, word_count: SpvWord, rt: *Runtime) RuntimeError!void {
|
fn opCompositeConstruct(_: std.mem.Allocator, word_count: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||||
_ = rt.it.skip();
|
_ = rt.it.skip();
|
||||||
const id = try rt.it.next();
|
const id = try rt.it.next();
|
||||||
@@ -501,16 +499,7 @@ fn opAccessChain(_: std.mem.Allocator, word_count: SpvWord, rt: *Runtime) Runtim
|
|||||||
const base_id = try rt.it.next();
|
const base_id = try rt.it.next();
|
||||||
|
|
||||||
const base = &rt.results[base_id];
|
const base = &rt.results[base_id];
|
||||||
var value_ptr = blk: {
|
var value_ptr = try base.getValue();
|
||||||
if (base.variant) |variant| {
|
|
||||||
switch (variant) {
|
|
||||||
.Variable => |v| break :blk &v.value,
|
|
||||||
.Constant => |v| break :blk &v,
|
|
||||||
else => {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return RuntimeError.InvalidSpirV;
|
|
||||||
};
|
|
||||||
|
|
||||||
const index_count = word_count - 3;
|
const index_count = word_count - 3;
|
||||||
for (0..index_count) |_| {
|
for (0..index_count) |_| {
|
||||||
@@ -570,10 +559,6 @@ fn opStore(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn opLoadSetup(allocator: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
|
||||||
_ = try setupConstant(allocator, rt);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn opLoad(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
fn opLoad(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||||
_ = rt.it.skip();
|
_ = rt.it.skip();
|
||||||
const id = try rt.it.next();
|
const id = try rt.it.next();
|
||||||
@@ -605,6 +590,48 @@ fn opReturn(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn opFMul(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||||
|
const res_type = try rt.it.next();
|
||||||
|
const id = try rt.it.next();
|
||||||
|
const op1 = try rt.it.next();
|
||||||
|
const op2 = try rt.it.next();
|
||||||
|
|
||||||
|
const target_type = (rt.results[res_type].variant orelse return RuntimeError.InvalidSpirV).Type;
|
||||||
|
|
||||||
|
const target = &rt.results[id];
|
||||||
|
const value = try target.getValue();
|
||||||
|
|
||||||
|
const op1_target = &rt.results[op1];
|
||||||
|
const op1_value = try op1_target.getValue();
|
||||||
|
|
||||||
|
const op2_target = &rt.results[op2];
|
||||||
|
const op2_value = try op2_target.getValue();
|
||||||
|
|
||||||
|
const float_size = sw: switch (target_type) {
|
||||||
|
.Vector => |v| continue :sw (rt.results[v.components_type_word].variant orelse return RuntimeError.InvalidSpirV).Type,
|
||||||
|
.Float => |f| f.bit_length,
|
||||||
|
else => return RuntimeError.InvalidSpirV,
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (value.*) {
|
||||||
|
.Float => switch (float_size) {
|
||||||
|
16 => value.Float.float16 = op1_value.Float.float16 * op2_value.Float.float16,
|
||||||
|
32 => value.Float.float32 = op1_value.Float.float32 * op2_value.Float.float32,
|
||||||
|
64 => value.Float.float64 = op1_value.Float.float64 * op2_value.Float.float64,
|
||||||
|
else => return RuntimeError.InvalidSpirV,
|
||||||
|
},
|
||||||
|
.Vector => |vec| for (vec, op1_value.Vector, op2_value.Vector) |*val, op1_v, op2_v| {
|
||||||
|
switch (float_size) {
|
||||||
|
16 => val.Float.float16 = op1_v.Float.float16 * op2_v.Float.float16,
|
||||||
|
32 => val.Float.float32 = op1_v.Float.float32 * op2_v.Float.float32,
|
||||||
|
64 => val.Float.float64 = op1_v.Float.float64 * op2_v.Float.float64,
|
||||||
|
else => return RuntimeError.InvalidSpirV,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => return RuntimeError.InvalidSpirV,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn setupConstant(allocator: std.mem.Allocator, rt: *Runtime) RuntimeError!*Result {
|
fn setupConstant(allocator: std.mem.Allocator, rt: *Runtime) RuntimeError!*Result {
|
||||||
const res_type = try rt.it.next();
|
const res_type = try rt.it.next();
|
||||||
const id = try rt.it.next();
|
const id = try rt.it.next();
|
||||||
@@ -619,6 +646,10 @@ fn setupConstant(allocator: std.mem.Allocator, rt: *Runtime) RuntimeError!*Resul
|
|||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn autoSetupConstant(allocator: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||||
|
_ = try setupConstant(allocator, rt);
|
||||||
|
}
|
||||||
|
|
||||||
fn readString(allocator: std.mem.Allocator, it: *WordIterator) RuntimeError![]const u8 {
|
fn readString(allocator: std.mem.Allocator, it: *WordIterator) RuntimeError![]const u8 {
|
||||||
var str: std.ArrayList(u8) = .empty;
|
var str: std.ArrayList(u8) = .empty;
|
||||||
while (it.nextOrNull()) |word| {
|
while (it.nextOrNull()) |word| {
|
||||||
|
|||||||
Reference in New Issue
Block a user