reworking opBitcast, fixing some glsl functions
This commit is contained in:
@@ -80,6 +80,7 @@ pub fn initRuntimeDispatcher() void {
|
|||||||
runtime_dispatcher[@intFromEnum(ext.GLSLOp.Exp2)] = MathEngine(.Float, .Exp2).opSingleOperator;
|
runtime_dispatcher[@intFromEnum(ext.GLSLOp.Exp2)] = MathEngine(.Float, .Exp2).opSingleOperator;
|
||||||
runtime_dispatcher[@intFromEnum(ext.GLSLOp.FAbs)] = MathEngine(.Float, .FAbs).opSingleOperator;
|
runtime_dispatcher[@intFromEnum(ext.GLSLOp.FAbs)] = MathEngine(.Float, .FAbs).opSingleOperator;
|
||||||
runtime_dispatcher[@intFromEnum(ext.GLSLOp.FMax)] = MathEngine(.Float, .FMax).opDoubleOperators;
|
runtime_dispatcher[@intFromEnum(ext.GLSLOp.FMax)] = MathEngine(.Float, .FMax).opDoubleOperators;
|
||||||
|
runtime_dispatcher[@intFromEnum(ext.GLSLOp.FSign)] = MathEngine(.Float, .FSign).opSingleOperator;
|
||||||
runtime_dispatcher[@intFromEnum(ext.GLSLOp.Floor)] = MathEngine(.Float, .Floor).opSingleOperator;
|
runtime_dispatcher[@intFromEnum(ext.GLSLOp.Floor)] = MathEngine(.Float, .Floor).opSingleOperator;
|
||||||
runtime_dispatcher[@intFromEnum(ext.GLSLOp.Length)] = opLength;
|
runtime_dispatcher[@intFromEnum(ext.GLSLOp.Length)] = opLength;
|
||||||
runtime_dispatcher[@intFromEnum(ext.GLSLOp.Log)] = MathEngine(.Float, .Log).opSingleOperator;
|
runtime_dispatcher[@intFromEnum(ext.GLSLOp.Log)] = MathEngine(.Float, .Log).opSingleOperator;
|
||||||
@@ -87,6 +88,7 @@ pub fn initRuntimeDispatcher() void {
|
|||||||
runtime_dispatcher[@intFromEnum(ext.GLSLOp.Normalize)] = opNormalize;
|
runtime_dispatcher[@intFromEnum(ext.GLSLOp.Normalize)] = opNormalize;
|
||||||
runtime_dispatcher[@intFromEnum(ext.GLSLOp.Round)] = MathEngine(.Float, .Round).opSingleOperator;
|
runtime_dispatcher[@intFromEnum(ext.GLSLOp.Round)] = MathEngine(.Float, .Round).opSingleOperator;
|
||||||
runtime_dispatcher[@intFromEnum(ext.GLSLOp.SAbs)] = MathEngine(.SInt, .SAbs).opSingleOperator;
|
runtime_dispatcher[@intFromEnum(ext.GLSLOp.SAbs)] = MathEngine(.SInt, .SAbs).opSingleOperator;
|
||||||
|
runtime_dispatcher[@intFromEnum(ext.GLSLOp.SSign)] = MathEngine(.SInt, .SSign).opSingleOperator;
|
||||||
runtime_dispatcher[@intFromEnum(ext.GLSLOp.Sin)] = MathEngine(.Float, .Sin).opSingleOperator;
|
runtime_dispatcher[@intFromEnum(ext.GLSLOp.Sin)] = MathEngine(.Float, .Sin).opSingleOperator;
|
||||||
runtime_dispatcher[@intFromEnum(ext.GLSLOp.Sqrt)] = MathEngine(.Float, .Sqrt).opSingleOperator;
|
runtime_dispatcher[@intFromEnum(ext.GLSLOp.Sqrt)] = MathEngine(.Float, .Sqrt).opSingleOperator;
|
||||||
runtime_dispatcher[@intFromEnum(ext.GLSLOp.Tan)] = MathEngine(.Float, .Tan).opSingleOperator;
|
runtime_dispatcher[@intFromEnum(ext.GLSLOp.Tan)] = MathEngine(.Float, .Tan).opSingleOperator;
|
||||||
@@ -94,6 +96,14 @@ pub fn initRuntimeDispatcher() void {
|
|||||||
// zig fmt: on
|
// zig fmt: on
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn isFloatOrF32Vector(comptime T: type) bool {
|
||||||
|
return switch (@typeInfo(T)) {
|
||||||
|
.float => true,
|
||||||
|
.vector => |vec| vec.child == f32,
|
||||||
|
else => false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
fn MathEngine(comptime T: ValueType, comptime Op: MathOp) type {
|
fn MathEngine(comptime T: ValueType, comptime Op: MathOp) type {
|
||||||
return struct {
|
return struct {
|
||||||
fn opSingleOperator(_: std.mem.Allocator, target_type_id: SpvWord, id: SpvWord, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
fn opSingleOperator(_: std.mem.Allocator, target_type_id: SpvWord, id: SpvWord, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||||
@@ -105,24 +115,32 @@ fn MathEngine(comptime T: ValueType, comptime Op: MathOp) type {
|
|||||||
|
|
||||||
const operator = struct {
|
const operator = struct {
|
||||||
fn operation(comptime TT: type, x: TT) RuntimeError!TT {
|
fn operation(comptime TT: type, x: TT) RuntimeError!TT {
|
||||||
|
if (comptime isFloatOrF32Vector(TT)) {
|
||||||
return switch (Op) {
|
return switch (Op) {
|
||||||
.Ceil => @ceil(x),
|
.Ceil => @ceil(x),
|
||||||
.Cos => @cos(x),
|
.Cos => @cos(x),
|
||||||
.Exp => @exp(x),
|
.Exp => @exp(x),
|
||||||
.Exp2 => @exp2(x),
|
.Exp2 => @exp2(x),
|
||||||
.FAbs => @abs(x),
|
.FAbs => @abs(x),
|
||||||
|
.FSign => std.math.sign(x),
|
||||||
.Floor => @floor(x),
|
.Floor => @floor(x),
|
||||||
.Log => @log(x),
|
.Log => @log(x),
|
||||||
.Log2 => @log2(x),
|
.Log2 => @log2(x),
|
||||||
.Round => @round(x),
|
.Round => @round(x),
|
||||||
.SAbs => if (comptime @typeInfo(TT) == .int) @intCast(@abs(x)) else return RuntimeError.InvalidSpirV,
|
|
||||||
.Sin => @sin(x),
|
.Sin => @sin(x),
|
||||||
.Sqrt => @sqrt(x),
|
.Sqrt => @sqrt(x),
|
||||||
.Tan => @tan(x),
|
.Tan => @tan(x),
|
||||||
.Trunc => @trunc(x),
|
.Trunc => @trunc(x),
|
||||||
|
else => return RuntimeError.InvalidSpirV,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return switch (Op) {
|
||||||
|
.SAbs => @intCast(@abs(x)),
|
||||||
|
.SSign => std.math.sign(x),
|
||||||
else => RuntimeError.InvalidSpirV,
|
else => RuntimeError.InvalidSpirV,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn applyScalar(bit_count: SpvWord, d: *Value, s: *const Value) RuntimeError!void {
|
fn applyScalar(bit_count: SpvWord, d: *Value, s: *const Value) RuntimeError!void {
|
||||||
switch (bit_count) {
|
switch (bit_count) {
|
||||||
@@ -150,13 +168,13 @@ fn MathEngine(comptime T: ValueType, comptime Op: MathOp) type {
|
|||||||
.Vector3f32 => |*d| d.* = try operator.operation(@Vector(3, f32), src.Vector3f32),
|
.Vector3f32 => |*d| d.* = try operator.operation(@Vector(3, f32), src.Vector3f32),
|
||||||
.Vector2f32 => |*d| d.* = try operator.operation(@Vector(2, f32), src.Vector2f32),
|
.Vector2f32 => |*d| d.* = try operator.operation(@Vector(2, f32), src.Vector2f32),
|
||||||
|
|
||||||
//.Vector4i32 => |*d| d.* = try operator.operation(@Vector(4, i32), src.Vector4i32),
|
.Vector4i32 => |*d| d.* = try operator.operation(@Vector(4, i32), src.Vector4i32),
|
||||||
//.Vector3i32 => |*d| d.* = try operator.operation(@Vector(3, i32), src.Vector3i32),
|
.Vector3i32 => |*d| d.* = try operator.operation(@Vector(3, i32), src.Vector3i32),
|
||||||
//.Vector2i32 => |*d| d.* = try operator.operation(@Vector(2, i32), src.Vector2i32),
|
.Vector2i32 => |*d| d.* = try operator.operation(@Vector(2, i32), src.Vector2i32),
|
||||||
|
|
||||||
//.Vector4u32 => |*d| d.* = try operator.operation(@Vector(4, u32), src.Vector4u32),
|
.Vector4u32 => |*d| d.* = try operator.operation(@Vector(4, u32), src.Vector4u32),
|
||||||
//.Vector3u32 => |*d| d.* = try operator.operation(@Vector(3, u32), src.Vector3u32),
|
.Vector3u32 => |*d| d.* = try operator.operation(@Vector(3, u32), src.Vector3u32),
|
||||||
//.Vector2u32 => |*d| d.* = try operator.operation(@Vector(2, u32), src.Vector2u32),
|
.Vector2u32 => |*d| d.* = try operator.operation(@Vector(2, u32), src.Vector2u32),
|
||||||
|
|
||||||
else => return RuntimeError.InvalidSpirV,
|
else => return RuntimeError.InvalidSpirV,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -441,6 +441,26 @@ pub const Value = union(Type) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn getPlainMemorySize(self: *const Self) RuntimeError!usize {
|
||||||
|
return switch (self.*) {
|
||||||
|
.Bool => 1,
|
||||||
|
.Int => |i| @divExact(i.bit_count, 8),
|
||||||
|
.Float => |f| @divExact(f.bit_count, 8),
|
||||||
|
.Vector4f32, .Vector4i32, .Vector4u32 => 4 * 4,
|
||||||
|
.Vector3f32, .Vector3i32, .Vector3u32 => 3 * 4,
|
||||||
|
.Vector2f32, .Vector2i32, .Vector2u32 => 2 * 4,
|
||||||
|
.Vector, .Matrix, .Array, .Structure => |values| blk: {
|
||||||
|
var size: usize = 0;
|
||||||
|
for (values) |v| {
|
||||||
|
size += try v.getPlainMemorySize();
|
||||||
|
}
|
||||||
|
break :blk size;
|
||||||
|
},
|
||||||
|
.RuntimeArray => |arr| arr.getLen(),
|
||||||
|
else => return RuntimeError.InvalidValueType,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn flushPtr(self: *Self, allocator: std.mem.Allocator) RuntimeError!void {
|
pub fn flushPtr(self: *Self, allocator: std.mem.Allocator) RuntimeError!void {
|
||||||
switch (self.*) {
|
switch (self.*) {
|
||||||
.Pointer => |*p| {
|
.Pointer => |*p| {
|
||||||
|
|||||||
@@ -931,10 +931,6 @@ fn MathEngine(comptime T: ValueType, comptime Op: MathOp) type {
|
|||||||
d[i] = try operation(ElemT, v[i]);
|
d[i] = try operation(ElemT, v[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fn applySIMDVectorf32(comptime N: usize, d: *@Vector(N, f32), v: *const @Vector(N, f32)) RuntimeError!void {
|
|
||||||
try applySIMDVector(f32, N, d, v);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (dst.*) {
|
switch (dst.*) {
|
||||||
@@ -1010,34 +1006,19 @@ fn autoSetupConstant(allocator: std.mem.Allocator, _: SpvWord, rt: *Runtime) Run
|
|||||||
_ = try setupConstant(allocator, rt);
|
_ = try setupConstant(allocator, rt);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn opBitcast(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
fn opBitcast(allocator: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||||
_ = rt.it.skip();
|
_ = rt.it.skip();
|
||||||
const to_value = try rt.results[try rt.it.next()].getValue();
|
const to_value = try rt.results[try rt.it.next()].getValue();
|
||||||
const from_value = try rt.results[try rt.it.next()].getValue();
|
const from_value = try rt.results[try rt.it.next()].getValue();
|
||||||
|
|
||||||
const caster = struct {
|
var arena: std.heap.ArenaAllocator = .init(allocator);
|
||||||
/// Asumes that values passed are primitives ints or floats
|
defer arena.deinit();
|
||||||
fn cast(to: *Value, from: *const Value) RuntimeError!void {
|
const local_allocator = arena.allocator();
|
||||||
const from_bytes: u64 = switch (from.*) {
|
|
||||||
.Float => |f| @bitCast(f.value.float64),
|
|
||||||
.Int => |i| i.value.uint64,
|
|
||||||
else => return RuntimeError.InvalidSpirV,
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (to.*) {
|
const size = try to_value.getPlainMemorySize();
|
||||||
.Float => |*f| f.value.float64 = @bitCast(from_bytes),
|
const bytes = local_allocator.alloc(u8, size) catch return RuntimeError.OutOfMemory;
|
||||||
.Int => |*i| i.value.uint64 = from_bytes,
|
_ = try from_value.read(bytes);
|
||||||
else => return RuntimeError.InvalidSpirV,
|
_ = try to_value.write(bytes);
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (to_value.*) {
|
|
||||||
.Int, .Float => try caster.cast(to_value, from_value),
|
|
||||||
.Vector => |vec| for (vec, from_value.Vector) |*t, *f| try caster.cast(t, f),
|
|
||||||
// TODO: vectors specializations
|
|
||||||
else => return RuntimeError.InvalidSpirV,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copyValue(dst: *Value, src: *const Value) void {
|
fn copyValue(dst: *Value, src: *const Value) void {
|
||||||
|
|||||||
Reference in New Issue
Block a user