fixing FFI, removing division by zero error, fixing fmod/rem
Build / build (push) Successful in 1m24s
Test / build (push) Successful in 9m59s

This commit is contained in:
2026-06-30 01:50:21 +02:00
parent e49383f07e
commit b79282878e
7 changed files with 188 additions and 62 deletions
+14 -14
View File
@@ -418,20 +418,19 @@ typedef enum
SPV_RESULT_SUCCESS = 0, SPV_RESULT_SUCCESS = 0,
SPV_RESULT_BARRIER = 1, SPV_RESULT_BARRIER = 1,
SPV_RESULT_KILLED = 2, SPV_RESULT_KILLED = 2,
SPV_RESULT_DIVISION_BY_ZERO = -1, SPV_RESULT_INVALID_ENTRY_POINT = -1,
SPV_RESULT_INVALID_ENTRY_POINT = -2, SPV_RESULT_INVALID_SPIRV = -2,
SPV_RESULT_INVALID_SPIRV = -3, SPV_RESULT_INVALID_VALUE_TYPE = -3,
SPV_RESULT_INVALID_VALUE_TYPE = -4, SPV_RESULT_NOT_FOUND = -4,
SPV_RESULT_NOT_FOUND = -5, SPV_RESULT_OUT_OF_MEMORY = -5,
SPV_RESULT_OUT_OF_MEMORY = -6, SPV_RESULT_OUT_OF_BOUNDS = -6,
SPV_RESULT_OUT_OF_BOUNDS = -7, SPV_RESULT_TODO = -7,
SPV_RESULT_TODO = -8, SPV_RESULT_UNREACHABLE = -8,
SPV_RESULT_UNREACHABLE = -9, SPV_RESULT_UNSUPPORTED_SPIRV = -9,
SPV_RESULT_UNSUPPORTED_SPIRV = -10, SPV_RESULT_UNSUPPORTED_EXTENSION = -10,
SPV_RESULT_UNSUPPORTED_EXTENSION = -11, SPV_RESULT_UNSUPPORTED_ENDIANNESS = -11,
SPV_RESULT_UNSUPPORTED_ENDIANNESS = -12, SPV_RESULT_INVALID_MAGIC = -12,
SPV_RESULT_INVALID_MAGIC = -13, SPV_RESULT_UNKNOWN = -13
SPV_RESULT_UNKNOWN = -14
} SpvResult; } SpvResult;
typedef struct typedef struct
@@ -538,6 +537,7 @@ typedef struct
int x; int x;
int y; int y;
int z; int z;
float w;
float lod; float lod;
SpvBool has_lod; SpvBool has_lod;
SpvImageOffset offset; SpvImageOffset offset;
+13 -14
View File
@@ -8,20 +8,19 @@ pub const Result = enum(c_int) {
Success = 0, Success = 0,
Barrier = 1, Barrier = 1,
Killed = 2, Killed = 2,
DivisionByZero = -1, InvalidEntryPoint = -1,
InvalidEntryPoint = -2, InvalidSpirV = -2,
InvalidSpirV = -3, InvalidValueType = -3,
InvalidValueType = -4, NotFound = -4,
NotFound = -5, OutOfMemory = -5,
OutOfMemory = -6, OutOfBounds = -6,
OutOfBounds = -7, ToDo = -7,
ToDo = -8, Unreachable = -8,
Unreachable = -9, UnsupportedSpirV = -9,
UnsupportedSpirV = -10, UnsupportedExtension = -10,
UnsupportedExtension = -11, UnsupportedEndianness = -11,
UnsupportedEndianness = -12, InvalidMagic = -12,
InvalidMagic = -13, Unknown = -13,
Unknown = -14,
}; };
comptime { comptime {
+7 -7
View File
@@ -75,6 +75,7 @@ const SampleImageInfo = extern struct {
x: f32, x: f32,
y: f32, y: f32,
z: f32, z: f32,
w: f32,
lod: f32, lod: f32,
has_lod: ffi.SpvCBool, has_lod: ffi.SpvCBool,
offset: ImageOffset, offset: ImageOffset,
@@ -124,7 +125,6 @@ const ImageAPI = extern struct {
fn toCResult(err: spv.Runtime.RuntimeError) ffi.Result { fn toCResult(err: spv.Runtime.RuntimeError) ffi.Result {
return switch (err) { return switch (err) {
spv.Runtime.RuntimeError.Barrier => ffi.Result.Barrier, spv.Runtime.RuntimeError.Barrier => ffi.Result.Barrier,
spv.Runtime.RuntimeError.DivisionByZero => ffi.Result.DivisionByZero,
spv.Runtime.RuntimeError.InvalidEntryPoint => ffi.Result.InvalidEntryPoint, spv.Runtime.RuntimeError.InvalidEntryPoint => ffi.Result.InvalidEntryPoint,
spv.Runtime.RuntimeError.InvalidSpirV => ffi.Result.InvalidSpirV, spv.Runtime.RuntimeError.InvalidSpirV => ffi.Result.InvalidSpirV,
spv.Runtime.RuntimeError.InvalidValueType => ffi.Result.InvalidValueType, spv.Runtime.RuntimeError.InvalidValueType => ffi.Result.InvalidValueType,
@@ -143,7 +143,6 @@ fn toCResult(err: spv.Runtime.RuntimeError) ffi.Result {
fn fromCResult(res: ffi.Result) spv.Runtime.RuntimeError!void { fn fromCResult(res: ffi.Result) spv.Runtime.RuntimeError!void {
return switch (res) { return switch (res) {
ffi.Result.Barrier => spv.Runtime.RuntimeError.Barrier, ffi.Result.Barrier => spv.Runtime.RuntimeError.Barrier,
ffi.Result.DivisionByZero => spv.Runtime.RuntimeError.DivisionByZero,
ffi.Result.InvalidEntryPoint => spv.Runtime.RuntimeError.InvalidEntryPoint, ffi.Result.InvalidEntryPoint => spv.Runtime.RuntimeError.InvalidEntryPoint,
ffi.Result.InvalidSpirV => spv.Runtime.RuntimeError.InvalidSpirV, ffi.Result.InvalidSpirV => spv.Runtime.RuntimeError.InvalidSpirV,
ffi.Result.InvalidValueType => spv.Runtime.RuntimeError.InvalidValueType, ffi.Result.InvalidValueType => spv.Runtime.RuntimeError.InvalidValueType,
@@ -205,7 +204,7 @@ const ImageAPIBridge = struct {
}; };
} }
fn sampleImageInfo(driver_image: *anyopaque, driver_sampler: *anyopaque, dim: spv.spv.SpvDim, x: f32, y: f32, z: f32, lod: ?f32, offset: spv.Runtime.ImageOffset) SampleImageInfo { fn sampleImageInfo(driver_image: *anyopaque, driver_sampler: *anyopaque, dim: spv.spv.SpvDim, x: f32, y: f32, z: f32, w: f32, lod: ?f32, offset: spv.Runtime.ImageOffset) SampleImageInfo {
return .{ return .{
.driver_image = driver_image, .driver_image = driver_image,
.driver_sampler = driver_sampler, .driver_sampler = driver_sampler,
@@ -213,6 +212,7 @@ const ImageAPIBridge = struct {
.x = x, .x = x,
.y = y, .y = y,
.z = z, .z = z,
.w = w,
.lod = lod orelse 0.0, .lod = lod orelse 0.0,
.has_lod = if (lod == null) 0 else 1, .has_lod = if (lod == null) 0 else 1,
.offset = toCImageOffset(offset), .offset = toCImageOffset(offset),
@@ -279,7 +279,7 @@ const ImageAPIBridge = struct {
const image_api = try getImageAPI(); const image_api = try getImageAPI();
var dst: Vec4f = undefined; var dst: Vec4f = undefined;
const result = image_api.sampleImageFloat4(sampleImageInfo(driver_image, driver_sampler, dim, x, y, z, lod, offset), &dst); const result = image_api.sampleImageFloat4(sampleImageInfo(driver_image, driver_sampler, dim, x, y, z, 1.0, lod, offset), &dst);
try fromCResult(result); try fromCResult(result);
@@ -295,7 +295,7 @@ const ImageAPIBridge = struct {
const image_api = try getImageAPI(); const image_api = try getImageAPI();
var dst: Vec4u = undefined; var dst: Vec4u = undefined;
const result = image_api.sampleImageInt4(sampleImageInfo(driver_image, driver_sampler, dim, x, y, z, lod, offset), &dst); const result = image_api.sampleImageInt4(sampleImageInfo(driver_image, driver_sampler, dim, x, y, z, 1.0, lod, offset), &dst);
try fromCResult(result); try fromCResult(result);
@@ -307,11 +307,11 @@ const ImageAPIBridge = struct {
}; };
} }
fn sampleImageDref(driver_image: *anyopaque, driver_sampler: *anyopaque, dim: spv.spv.SpvDim, x: f32, y: f32, z: f32, dref: f32, lod: ?f32, offset: spv.Runtime.ImageOffset) spv.Runtime.RuntimeError!f32 { fn sampleImageDref(driver_image: *anyopaque, driver_sampler: *anyopaque, dim: spv.spv.SpvDim, x: f32, y: f32, z: f32, w: f32, dref: f32, lod: ?f32, offset: spv.Runtime.ImageOffset) spv.Runtime.RuntimeError!f32 {
const image_api = try getImageAPI(); const image_api = try getImageAPI();
var dst: f32 = undefined; var dst: f32 = undefined;
const result = image_api.sampleImageDref(sampleImageInfo(driver_image, driver_sampler, dim, x, y, z, lod, offset), dref, &dst); const result = image_api.sampleImageDref(sampleImageInfo(driver_image, driver_sampler, dim, x, y, z, w, lod, offset), dref, &dst);
try fromCResult(result); try fromCResult(result);
+62 -7
View File
@@ -889,11 +889,8 @@ fn opModfStruct(_: std.mem.Allocator, _: SpvWord, id: SpvWord, _: SpvWord, rt: *
} }
fn frexpScalar(comptime T: type, x: T) struct { sig: T, exp: i32 } { fn frexpScalar(comptime T: type, x: T) struct { sig: T, exp: i32 } {
if (x == 0.0) const result = std.math.frexp(x);
return .{ .sig = 0.0, .exp = 0 }; return .{ .sig = result.significand, .exp = result.exponent };
const exp = @as(i32, @intFromFloat(@floor(@log2(@abs(x))))) + 1;
return .{ .sig = x / @exp2(@as(T, @floatFromInt(exp))), .exp = exp };
} }
fn opFrexp(_: std.mem.Allocator, target_type_id: SpvWord, id: SpvWord, _: SpvWord, rt: *Runtime) RuntimeError!void { fn opFrexp(_: std.mem.Allocator, target_type_id: SpvWord, id: SpvWord, _: SpvWord, rt: *Runtime) RuntimeError!void {
@@ -951,8 +948,9 @@ fn opLdexp(_: std.mem.Allocator, target_type_id: SpvWord, id: SpvWord, _: SpvWor
inline 16, 32, 64 => |bits| for (0..lane_count) |lane_index| { inline 16, 32, 64 => |bits| for (0..lane_count) |lane_index| {
const exp_lane = if (exp_lane_count == 1) 0 else lane_index; const exp_lane = if (exp_lane_count == 1) 0 else lane_index;
const exponent = try readIntegralLaneAsI32(exp_value, exp_lane); const exponent = try readIntegralLaneAsI32(exp_value, exp_lane);
const scale = @exp2(@as(std.meta.Float(bits), @floatFromInt(exponent))); const value = try Value.readLane(.Float, bits, x, lane_index);
try writeFloatLane(bits, dst, lane_index, try Value.readLane(.Float, bits, x, lane_index) * scale); const result = if (value == 0.0) value else std.math.ldexp(value, exponent);
try writeFloatLane(bits, dst, lane_index, result);
}, },
else => return RuntimeError.InvalidSpirV, else => return RuntimeError.InvalidSpirV,
} }
@@ -1121,7 +1119,51 @@ fn matrixSize(matrix: *const Value) RuntimeError!usize {
}; };
} }
fn determinant3Values(comptime T: type, a00: T, a01: T, a02: T, a10: T, a11: T, a12: T, a20: T, a21: T, a22: T) T {
return a00 * ((a11 * a22) - (a12 * a21)) -
a01 * ((a10 * a22) - (a12 * a20)) +
a02 * ((a10 * a21) - (a11 * a20));
}
fn determinant(comptime bits: u32, src: *const Value, n: usize) RuntimeError!std.meta.Float(bits) { fn determinant(comptime bits: u32, src: *const Value, n: usize) RuntimeError!std.meta.Float(bits) {
const FloatT = std.meta.Float(bits);
if (n == 2) {
const a00 = try readMatrixElement(bits, src, 0, 0);
const a01 = try readMatrixElement(bits, src, 0, 1);
const a10 = try readMatrixElement(bits, src, 1, 0);
const a11 = try readMatrixElement(bits, src, 1, 1);
return (a00 * a11) - (a10 * a01);
}
if (n == 3) {
return determinant3Values(
FloatT,
try readMatrixElement(bits, src, 0, 0),
try readMatrixElement(bits, src, 0, 1),
try readMatrixElement(bits, src, 0, 2),
try readMatrixElement(bits, src, 1, 0),
try readMatrixElement(bits, src, 1, 1),
try readMatrixElement(bits, src, 1, 2),
try readMatrixElement(bits, src, 2, 0),
try readMatrixElement(bits, src, 2, 1),
try readMatrixElement(bits, src, 2, 2),
);
}
if (n == 4) {
var m: [4][4]FloatT = undefined;
for (0..4) |row| {
for (0..4) |col| {
m[row][col] = try readMatrixElement(bits, src, row, col);
}
}
return m[0][0] * determinant3Values(FloatT, m[1][1], m[1][2], m[1][3], m[2][1], m[2][2], m[2][3], m[3][1], m[3][2], m[3][3]) -
m[0][1] * determinant3Values(FloatT, m[1][0], m[1][2], m[1][3], m[2][0], m[2][2], m[2][3], m[3][0], m[3][2], m[3][3]) +
m[0][2] * determinant3Values(FloatT, m[1][0], m[1][1], m[1][3], m[2][0], m[2][1], m[2][3], m[3][0], m[3][1], m[3][3]) -
m[0][3] * determinant3Values(FloatT, m[1][0], m[1][1], m[1][2], m[2][0], m[2][1], m[2][2], m[3][0], m[3][1], m[3][2]);
}
var m: [16]std.meta.Float(bits) = undefined; var m: [16]std.meta.Float(bits) = undefined;
for (0..n) |row| { for (0..n) |row| {
for (0..n) |col| { for (0..n) |col| {
@@ -1186,6 +1228,19 @@ fn opMatrixInverse(_: std.mem.Allocator, target_type_id: SpvWord, id: SpvWord, _
switch (lane_bits) { switch (lane_bits) {
inline 16, 32, 64 => |bits| { inline 16, 32, 64 => |bits| {
if (n == 2) {
const a00 = try readMatrixElement(bits, src, 0, 0);
const a01 = try readMatrixElement(bits, src, 0, 1);
const a10 = try readMatrixElement(bits, src, 1, 0);
const a11 = try readMatrixElement(bits, src, 1, 1);
const inv_det = 1.0 / ((a00 * a11) - (a10 * a01));
try writeMatrixElement(bits, dst, 0, 0, a11 * inv_det);
try writeMatrixElement(bits, dst, 0, 1, -a01 * inv_det);
try writeMatrixElement(bits, dst, 1, 0, -a10 * inv_det);
try writeMatrixElement(bits, dst, 1, 1, a00 * inv_det);
return;
}
var aug: [32]std.meta.Float(bits) = undefined; var aug: [32]std.meta.Float(bits) = undefined;
const width = n * 2; const width = n * 2;
for (0..n) |row| { for (0..n) |row| {
+2 -1
View File
@@ -21,7 +21,6 @@ const Self = @This();
pub const RuntimeError = error{ pub const RuntimeError = error{
Barrier, Barrier,
DivisionByZero,
InvalidEntryPoint, InvalidEntryPoint,
InvalidSpirV, InvalidSpirV,
InvalidValueType, InvalidValueType,
@@ -428,6 +427,8 @@ pub fn setDerivativeFromMemory(self: *Self, allocator: std.mem.Allocator, result
var dx_value = try Value.init(allocator, self.results, target_type, false); var dx_value = try Value.init(allocator, self.results, target_type, false);
defer dx_value.deinit(allocator); defer dx_value.deinit(allocator);
const memory_size = try dx_value.getPlainMemorySize();
if (dx.len < memory_size or dy.len < memory_size) return RuntimeError.OutOfBounds;
_ = try dx_value.write(dx); _ = try dx_value.write(dx);
var dy_value = try Value.init(allocator, self.results, target_type, false); var dy_value = try Value.init(allocator, self.results, target_type, false);
+78 -7
View File
@@ -1849,9 +1849,21 @@ fn ImageEngine(comptime Op: ImageOp) type {
} }
} }
fn explicitSampleLod(rt: *Runtime, driver_image: *anyopaque, driver_sampler: *anyopaque, dim: spv.SpvDim, parsed: ParsedImageOperands) RuntimeError!?f32 { fn explicitSampleLod(rt: *Runtime, driver_image: *anyopaque, driver_sampler: *anyopaque, dim: spv.SpvDim, x: f32, y: f32, z: f32, parsed: ParsedImageOperands) RuntimeError!?f32 {
if (parsed.grad) |derivatives| { if (parsed.grad) |derivatives| {
const lod = try rt.image_api.queryImageLod(driver_image, driver_sampler, dim, derivatives); const lod_dim, const lod_derivatives = if (dim == .Cube) blk: {
const center = cubeFaceCoord(x, y, z);
const dx = cubeFaceCoordForFace(center.face, x + derivatives.dx.x, y + derivatives.dx.y, z + derivatives.dx.z);
const dy = cubeFaceCoordForFace(center.face, x + derivatives.dy.x, y + derivatives.dy.y, z + derivatives.dy.z);
break :blk .{
spv.SpvDim.@"2D",
Runtime.ImageDerivatives{
.dx = .{ .x = dx.u - center.u, .y = dx.v - center.v, .z = 0.0, .w = 0.0 },
.dy = .{ .x = dy.u - center.u, .y = dy.v - center.v, .z = 0.0, .w = 0.0 },
},
};
} else .{ dim, derivatives };
const lod = try rt.image_api.queryImageLod(driver_image, driver_sampler, lod_dim, lod_derivatives);
return lod.y; return lod.y;
} }
return parsed.lod; return parsed.lod;
@@ -2054,7 +2066,34 @@ fn ImageEngine(comptime Op: ImageOp) type {
fn queryImageLod(rt: *Runtime, dst: *Value, coordinate_id: SpvWord, image_operand: SampledImageOperand) RuntimeError!void { fn queryImageLod(rt: *Runtime, dst: *Value, coordinate_id: SpvWord, image_operand: SampledImageOperand) RuntimeError!void {
const coord_derivative = rt.derivatives.get(coordinate_id) orelse return RuntimeError.InvalidValueType; const coord_derivative = rt.derivatives.get(coordinate_id) orelse return RuntimeError.InvalidValueType;
const lod = try rt.image_api.queryImageLod(image_operand.driver_image, image_operand.driver_sampler, image_operand.dim, .{ const coord = try rt.results[coordinate_id].getValue();
const dim, const derivatives = if (image_operand.dim == .Cube) blk: {
const x = try readSampleCoordLane(coord, 0);
const y = try readSampleCoordLane(coord, 1);
const z = try readSampleCoordLane(coord, 2);
const center = cubeFaceCoord(x, y, z);
const dx = cubeFaceCoordForFace(
center.face,
x + try readSampleCoordLane(&coord_derivative.dx, 0),
y + (readSampleCoordLane(&coord_derivative.dx, 1) catch 0.0),
z + (readSampleCoordLane(&coord_derivative.dx, 2) catch 0.0),
);
const dy = cubeFaceCoordForFace(
center.face,
x + try readSampleCoordLane(&coord_derivative.dy, 0),
y + (readSampleCoordLane(&coord_derivative.dy, 1) catch 0.0),
z + (readSampleCoordLane(&coord_derivative.dy, 2) catch 0.0),
);
break :blk .{
spv.SpvDim.@"2D",
Runtime.ImageDerivatives{
.dx = .{ .x = dx.u - center.u, .y = dx.v - center.v, .z = 0.0, .w = 0.0 },
.dy = .{ .x = dy.u - center.u, .y = dy.v - center.v, .z = 0.0, .w = 0.0 },
},
};
} else .{
image_operand.dim,
Runtime.ImageDerivatives{
.dx = .{ .dx = .{
.x = try readSampleCoordLane(&coord_derivative.dx, 0), .x = try readSampleCoordLane(&coord_derivative.dx, 0),
.y = readSampleCoordLane(&coord_derivative.dx, 1) catch 0.0, .y = readSampleCoordLane(&coord_derivative.dx, 1) catch 0.0,
@@ -2067,7 +2106,9 @@ fn ImageEngine(comptime Op: ImageOp) type {
.z = readSampleCoordLane(&coord_derivative.dy, 2) catch 0.0, .z = readSampleCoordLane(&coord_derivative.dy, 2) catch 0.0,
.w = readSampleCoordLane(&coord_derivative.dy, 3) catch 0.0, .w = readSampleCoordLane(&coord_derivative.dy, 3) catch 0.0,
}, },
}); },
};
const lod = try rt.image_api.queryImageLod(image_operand.driver_image, image_operand.driver_sampler, dim, derivatives);
switch (dst.*) { switch (dst.*) {
.Vector2f32 => |*v| v.* = .{ lod.x, lod.y }, .Vector2f32 => |*v| v.* = .{ lod.x, lod.y },
@@ -2302,6 +2343,9 @@ fn ImageEngine(comptime Op: ImageOp) type {
sampled_image_operand.driver_image, sampled_image_operand.driver_image,
sampled_image_operand.driver_sampler, sampled_image_operand.driver_sampler,
sampled_image_operand.dim, sampled_image_operand.dim,
coords.x,
coords.y,
coords.z,
parsed_operands, parsed_operands,
), ),
parsed_operands.offset, parsed_operands.offset,
@@ -2345,6 +2389,9 @@ fn ImageEngine(comptime Op: ImageOp) type {
sampled_image_operand.driver_image, sampled_image_operand.driver_image,
sampled_image_operand.driver_sampler, sampled_image_operand.driver_sampler,
sampled_image_operand.dim, sampled_image_operand.dim,
coords.x,
coords.y,
coords.z,
parsed_operands, parsed_operands,
), ),
parsed_operands.offset, parsed_operands.offset,
@@ -2695,6 +2742,30 @@ fn MathEngine(comptime T: PrimitiveType, comptime Op: MathOp, comptime IsAtomic:
fn operation(comptime TT: type, op1: TT, op2: TT) RuntimeError!TT { fn operation(comptime TT: type, op1: TT, op2: TT) RuntimeError!TT {
const is_int = @typeInfo(TT) == .int or (@typeInfo(TT) == .vector and @typeInfo(std.meta.Child(TT)) == .int); const is_int = @typeInfo(TT) == .int or (@typeInfo(TT) == .vector and @typeInfo(std.meta.Child(TT)) == .int);
const op2_is_zero = if (@typeInfo(TT) == .vector) std.simd.countElementsWithValue(op2, 0) != 0 else op2 == 0; const op2_is_zero = if (@typeInfo(TT) == .vector) std.simd.countElementsWithValue(op2, 0) != 0 else op2 == 0;
const zero: TT = switch (@typeInfo(TT)) {
.vector => @splat(0),
else => 0,
};
if (@typeInfo(TT) == .vector) {
switch (Op) {
.Div, .Mod, .Rem => {
var result: TT = undefined;
inline for (0..@typeInfo(TT).vector.len) |i| {
result[i] = if (op2[i] == 0)
0
else switch (Op) {
.Div => if (comptime is_int) @divTrunc(op1[i], op2[i]) else op1[i] / op2[i],
.Mod => @mod(op1[i], op2[i]),
.Rem => @rem(op1[i], op2[i]),
else => unreachable,
};
}
return result;
},
else => {},
}
}
return switch (Op) { return switch (Op) {
.Add => if (comptime is_int) @addWithOverflow(op1, op2)[0] else op1 + op2, .Add => if (comptime is_int) @addWithOverflow(op1, op2)[0] else op1 + op2,
@@ -2707,12 +2778,12 @@ fn MathEngine(comptime T: PrimitiveType, comptime Op: MathOp, comptime IsAtomic:
=> if (comptime is_int) @mulWithOverflow(op1, op2)[0] else op1 * op2, => if (comptime is_int) @mulWithOverflow(op1, op2)[0] else op1 * op2,
.Div => blk: { .Div => blk: {
if (comptime is_int) { if (comptime is_int) {
if (op2_is_zero) return RuntimeError.DivisionByZero; if (op2_is_zero) return zero;
} }
break :blk if (comptime is_int) @divTrunc(op1, op2) else op1 / op2; break :blk if (comptime is_int) @divTrunc(op1, op2) else op1 / op2;
}, },
.Mod => if (op2_is_zero) return RuntimeError.DivisionByZero else @mod(op1, op2), .Mod => if (op2_is_zero) zero else @mod(op1, op2),
.Rem => if (op2_is_zero) return RuntimeError.DivisionByZero else @rem(op1, op2), .Rem => if (op2_is_zero) zero else @rem(op1, op2),
else => return RuntimeError.InvalidSpirV, else => return RuntimeError.InvalidSpirV,
}; };
} }
+1 -1
View File
@@ -48,7 +48,7 @@ fn sampleImageInt4(_: *anyopaque, _: *anyopaque, _: spv.spv.SpvDim, _: f32, _: f
return spv.Runtime.RuntimeError.UnsupportedSpirV; return spv.Runtime.RuntimeError.UnsupportedSpirV;
} }
fn sampleImageDref(driver_image: *anyopaque, driver_sampler: *anyopaque, _: spv.spv.SpvDim, x: f32, y: f32, z: f32, dref: f32, lod: ?f32, offset: spv.Runtime.ImageOffset) spv.Runtime.RuntimeError!f32 { fn sampleImageDref(driver_image: *anyopaque, driver_sampler: *anyopaque, _: spv.spv.SpvDim, x: f32, y: f32, z: f32, _: f32, dref: f32, lod: ?f32, offset: spv.Runtime.ImageOffset) spv.Runtime.RuntimeError!f32 {
const state: *ImageState = @ptrCast(@alignCast(driver_image)); const state: *ImageState = @ptrCast(@alignCast(driver_image));
if (state.expected_sampler != driver_sampler) return spv.Runtime.RuntimeError.InvalidSpirV; if (state.expected_sampler != driver_sampler) return spv.Runtime.RuntimeError.InvalidSpirV;
state.dref_calls += 1; state.dref_calls += 1;