improving value read/write, improving cond engine
Build / build (push) Successful in 1m35s
Test / build (push) Successful in 9m14s

This commit is contained in:
2026-05-18 18:18:39 +02:00
parent a765246ee9
commit b82d37e7b6
3 changed files with 182 additions and 247 deletions
+6 -6
View File
@@ -247,7 +247,7 @@ pub fn populatePushConstants(self: *Self, blob: []const u8) RuntimeError!void {
const variable = &result.variant.?.Variable;
if (variable.storage_class != .PushConstant)
continue;
_ = try variable.value.writeConst(blob);
_ = try variable.value.write(blob);
}
}
@@ -258,12 +258,12 @@ pub fn writeDescriptorSet(self: *const Self, input: []const u8, set: SpvWord, bi
.Array => |arr| {
if (descriptor_index >= arr.values.len)
return RuntimeError.NotFound;
_ = try arr.values[descriptor_index].writeConst(input);
_ = try arr.values[descriptor_index].write(input);
},
else => {
if (descriptor_index != 0)
return RuntimeError.NotFound;
_ = try value.writeConst(input);
_ = try value.write(input);
},
}
} else {
@@ -291,15 +291,15 @@ fn readResultValue(self: *const Self, output: []u8, result: SpvWord) RuntimeErro
fn writeResultValue(self: *const Self, input: []const u8, result: SpvWord) RuntimeError!void {
if (self.results[result].variant) |*variant| {
switch (variant.*) {
.Variable => |*v| _ = try v.value.writeConst(input),
.Variable => |*v| _ = try v.value.write(input),
.AccessChain => |*a| switch (a.value) {
.Pointer => |ptr| switch (ptr.ptr) {
.common => |value_ptr| _ = try value_ptr.writeConst(input),
.common => |value_ptr| _ = try value_ptr.write(input),
.f32_ptr => |value_ptr| std.mem.copyForwards(u8, std.mem.asBytes(value_ptr), input[0..@sizeOf(f32)]),
.i32_ptr => |value_ptr| std.mem.copyForwards(u8, std.mem.asBytes(value_ptr), input[0..@sizeOf(i32)]),
.u32_ptr => |value_ptr| std.mem.copyForwards(u8, std.mem.asBytes(value_ptr), input[0..@sizeOf(u32)]),
},
else => _ = try a.value.writeConst(input),
else => _ = try a.value.write(input),
},
else => return RuntimeError.InvalidSpirV,
}
+67 -173
View File
@@ -83,14 +83,14 @@ pub const Value = union(Type) {
errdefer allocator.destroy(value);
value.* = try Value.init(allocator, results, self.type_word, false);
_ = try value.writeConst(self.data[self.getOffsetOfIndex(index)..]);
_ = try value.write(self.data[self.getOffsetOfIndex(index)..]);
return value;
}
pub inline fn createLocalValueFromIndex(self: *const @This(), allocator: std.mem.Allocator, results: []const Result, index: usize) RuntimeError!Value {
var value = try Value.init(allocator, results, self.type_word, false);
_ = try value.writeConst(self.data[self.getOffsetOfIndex(index)..]);
_ = try value.write(self.data[self.getOffsetOfIndex(index)..]);
return value;
}
@@ -172,13 +172,13 @@ pub const Value = union(Type) {
}
break :blk self;
},
.Vector4f32 => .{ .Vector4f32 = Vec4f32{ 0.0, 0.0, 0.0, 0.0 } },
.Vector4f32 => .{ .Vector4f32 = Vec4f32{ 0.0, 0.0, 0.0, 1.0 } },
.Vector3f32 => .{ .Vector3f32 = Vec3f32{ 0.0, 0.0, 0.0 } },
.Vector2f32 => .{ .Vector2f32 = Vec2f32{ 0.0, 0.0 } },
.Vector4i32 => .{ .Vector4i32 = Vec4i32{ 0, 0, 0, 0 } },
.Vector4i32 => .{ .Vector4i32 = Vec4i32{ 0, 0, 0, 1 } },
.Vector3i32 => .{ .Vector3i32 = Vec3i32{ 0, 0, 0 } },
.Vector2i32 => .{ .Vector2i32 = Vec2i32{ 0, 0 } },
.Vector4u32 => .{ .Vector4u32 = Vec4u32{ 0, 0, 0, 0 } },
.Vector4u32 => .{ .Vector4u32 = Vec4u32{ 0, 0, 0, 1 } },
.Vector3u32 => .{ .Vector3u32 = Vec3u32{ 0, 0, 0 } },
.Vector2u32 => .{ .Vector2u32 = Vec2u32{ 0, 0 } },
.Matrix => |m| blk: {
@@ -303,6 +303,23 @@ pub const Value = union(Type) {
}
pub fn read(self: *const Self, output: []u8) RuntimeError!usize {
const vecRoutine = struct {
inline fn routine(comptime T: type, vec: T, out: []u8) RuntimeError!usize {
const size = @typeInfo(T).vector.len * 4;
if (size >= out.len) {
const range = @typeInfo(T).vector.len;
inline for (0..range) |i| {
const start = i * 4;
const end = (i + 1) * 4;
if (start >= out.len or end > out.len) return i * 4;
@memcpy(out[start..end], std.mem.asBytes(&vec[i]));
}
}
std.mem.bytesAsValue(T, out[0..]).* = vec;
return size;
}
}.routine;
switch (self.*) {
.Bool => |b| {
output[0] = if (b == true) 1 else 0;
@@ -327,87 +344,19 @@ pub const Value = union(Type) {
}
return @divExact(f.bit_count, 8);
},
.Vector4f32 => |vec| {
inline for (0..4) |i| {
const start = i * 4;
const end = (i + 1) * 4;
if (start >= output.len or end > output.len) return RuntimeError.OutOfBounds;
@memcpy(output[start..end], std.mem.asBytes(&vec[i]));
}
return 4 * 4;
},
.Vector3f32 => |vec| {
inline for (0..3) |i| {
const start = i * 4;
const end = (i + 1) * 4;
if (start >= output.len or end > output.len) return RuntimeError.OutOfBounds;
@memcpy(output[start..end], std.mem.asBytes(&vec[i]));
}
return 3 * 4;
},
.Vector2f32 => |vec| {
inline for (0..2) |i| {
const start = i * 4;
const end = (i + 1) * 4;
if (start >= output.len or end > output.len) return RuntimeError.OutOfBounds;
@memcpy(output[start..end], std.mem.asBytes(&vec[i]));
}
return 2 * 4;
},
.Vector4i32 => |vec| {
inline for (0..4) |i| {
const start = i * 4;
const end = (i + 1) * 4;
if (start >= output.len or end > output.len) return RuntimeError.OutOfBounds;
@memcpy(output[start..end], std.mem.asBytes(&vec[i]));
}
return 4 * 4;
},
.Vector3i32 => |vec| {
inline for (0..3) |i| {
const start = i * 4;
const end = (i + 1) * 4;
if (start >= output.len or end > output.len) return RuntimeError.OutOfBounds;
@memcpy(output[start..end], std.mem.asBytes(&vec[i]));
}
return 3 * 4;
},
.Vector2i32 => |vec| {
inline for (0..2) |i| {
const start = i * 4;
const end = (i + 1) * 4;
if (start >= output.len or end > output.len) return RuntimeError.OutOfBounds;
@memcpy(output[start..end], std.mem.asBytes(&vec[i]));
}
return 2 * 4;
},
.Vector4u32 => |vec| {
inline for (0..4) |i| {
const start = i * 4;
const end = (i + 1) * 4;
if (start >= output.len or end > output.len) return RuntimeError.OutOfBounds;
@memcpy(output[start..end], std.mem.asBytes(&vec[i]));
}
return 4 * 4;
},
.Vector3u32 => |vec| {
inline for (0..3) |i| {
const start = i * 4;
const end = (i + 1) * 4;
if (start >= output.len or end > output.len) return RuntimeError.OutOfBounds;
@memcpy(output[start..end], std.mem.asBytes(&vec[i]));
}
return 3 * 4;
},
.Vector2u32 => |vec| {
inline for (0..2) |i| {
const start = i * 4;
const end = (i + 1) * 4;
if (start >= output.len or end > output.len) return RuntimeError.OutOfBounds;
@memcpy(output[start..end], std.mem.asBytes(&vec[i]));
}
return 2 * 4;
},
.Vector4f32 => |vec| return vecRoutine(@TypeOf(vec), vec, output),
.Vector3f32 => |vec| return vecRoutine(@TypeOf(vec), vec, output),
.Vector2f32 => |vec| return vecRoutine(@TypeOf(vec), vec, output),
.Vector4i32 => |vec| return vecRoutine(@TypeOf(vec), vec, output),
.Vector3i32 => |vec| return vecRoutine(@TypeOf(vec), vec, output),
.Vector2i32 => |vec| return vecRoutine(@TypeOf(vec), vec, output),
.Vector4u32 => |vec| return vecRoutine(@TypeOf(vec), vec, output),
.Vector3u32 => |vec| return vecRoutine(@TypeOf(vec), vec, output),
.Vector2u32 => |vec| return vecRoutine(@TypeOf(vec), vec, output),
.Vector, .Matrix => |values| {
var offset: usize = 0;
for (values) |v| {
@@ -438,11 +387,24 @@ pub const Value = union(Type) {
return 0;
}
pub fn writeConst(self: *Self, input: []const u8) RuntimeError!usize {
return self.write(@constCast(input));
}
pub fn write(self: *Self, input: []const u8) RuntimeError!usize {
const vecRoutine = struct {
inline fn routine(comptime T: type, vec: *T, in: []const u8) RuntimeError!usize {
const size = @typeInfo(T).vector.len * 4;
if (size >= in.len) {
const range = @typeInfo(T).vector.len;
inline for (0..range) |i| {
const start = i * 4;
const end = (i + 1) * 4;
if (start >= in.len or end > in.len) return i * 4;
@memcpy(std.mem.asBytes(&vec[i]), in[start..end]);
}
}
vec.* = std.mem.bytesToValue(T, in[0..]);
return size;
}
}.routine;
pub fn write(self: *Self, input: []u8) RuntimeError!usize {
switch (self.*) {
.Bool => |*b| {
b.* = if (input[0] != 0) true else false;
@@ -467,87 +429,19 @@ pub const Value = union(Type) {
}
return @divExact(f.bit_count, 8);
},
.Vector4f32 => |*vec| {
inline for (0..4) |i| {
const start = i * 4;
const end = (i + 1) * 4;
if (start >= input.len or end > input.len) return RuntimeError.OutOfBounds;
@memcpy(std.mem.asBytes(&vec[i]), input[start..end]);
}
return 4 * 4;
},
.Vector3f32 => |*vec| {
inline for (0..3) |i| {
const start = i * 4;
const end = (i + 1) * 4;
if (start >= input.len or end > input.len) return RuntimeError.OutOfBounds;
@memcpy(std.mem.asBytes(&vec[i]), input[start..end]);
}
return 3 * 4;
},
.Vector2f32 => |*vec| {
inline for (0..2) |i| {
const start = i * 4;
const end = (i + 1) * 4;
if (start >= input.len or end > input.len) return RuntimeError.OutOfBounds;
@memcpy(std.mem.asBytes(&vec[i]), input[start..end]);
}
return 2 * 4;
},
.Vector4i32 => |*vec| {
inline for (0..4) |i| {
const start = i * 4;
const end = (i + 1) * 4;
if (start >= input.len or end > input.len) return RuntimeError.OutOfBounds;
@memcpy(std.mem.asBytes(&vec[i]), input[start..end]);
}
return 4 * 4;
},
.Vector3i32 => |*vec| {
inline for (0..3) |i| {
const start = i * 4;
const end = (i + 1) * 4;
if (start >= input.len or end > input.len) return RuntimeError.OutOfBounds;
@memcpy(std.mem.asBytes(&vec[i]), input[start..end]);
}
return 3 * 4;
},
.Vector2i32 => |*vec| {
inline for (0..2) |i| {
const start = i * 4;
const end = (i + 1) * 4;
if (start >= input.len or end > input.len) return RuntimeError.OutOfBounds;
@memcpy(std.mem.asBytes(&vec[i]), input[start..end]);
}
return 2 * 4;
},
.Vector4u32 => |*vec| {
inline for (0..4) |i| {
const start = i * 4;
const end = (i + 1) * 4;
if (start >= input.len or end > input.len) return RuntimeError.OutOfBounds;
@memcpy(std.mem.asBytes(&vec[i]), input[start..end]);
}
return 4 * 4;
},
.Vector3u32 => |*vec| {
inline for (0..3) |i| {
const start = i * 4;
const end = (i + 1) * 4;
if (start >= input.len or end > input.len) return RuntimeError.OutOfBounds;
@memcpy(std.mem.asBytes(&vec[i]), input[start..end]);
}
return 3 * 4;
},
.Vector2u32 => |*vec| {
inline for (0..2) |i| {
const start = i * 4;
const end = (i + 1) * 4;
if (start >= input.len or end > input.len) return RuntimeError.OutOfBounds;
@memcpy(std.mem.asBytes(&vec[i]), input[start..end]);
}
return 2 * 4;
},
.Vector4f32 => |*vec| return vecRoutine(@TypeOf(vec.*), vec, input),
.Vector3f32 => |*vec| return vecRoutine(@TypeOf(vec.*), vec, input),
.Vector2f32 => |*vec| return vecRoutine(@TypeOf(vec.*), vec, input),
.Vector4i32 => |*vec| return vecRoutine(@TypeOf(vec.*), vec, input),
.Vector3i32 => |*vec| return vecRoutine(@TypeOf(vec.*), vec, input),
.Vector2i32 => |*vec| return vecRoutine(@TypeOf(vec.*), vec, input),
.Vector4u32 => |*vec| return vecRoutine(@TypeOf(vec.*), vec, input),
.Vector3u32 => |*vec| return vecRoutine(@TypeOf(vec.*), vec, input),
.Vector2u32 => |*vec| return vecRoutine(@TypeOf(vec.*), vec, input),
.Vector, .Matrix => |*values| {
var offset: usize = 0;
for (values.*) |*v| {
@@ -570,10 +464,10 @@ pub const Value = union(Type) {
const write_size = try v.write(input[member_offset..]);
end_offset = @max(end_offset, member_offset + write_size);
}
s.external_data = input[0..end_offset];
s.external_data = @constCast(input[0..end_offset]);
return end_offset;
},
.RuntimeArray => |*arr| arr.data = input[0..],
.RuntimeArray => |*arr| arr.data = @constCast(input[0..]),
.Image => |*img| img.driver_image = @ptrFromInt(std.mem.bytesToValue(usize, input[0..])),
else => return RuntimeError.InvalidValueType,
}
+109 -68
View File
@@ -588,8 +588,8 @@ fn CondOperator(comptime T: PrimitiveType, comptime Op: CondOp) type {
};
}
inline fn operationBinary(comptime TT: type, a: TT, b: TT) RuntimeError!bool {
if (comptime TT == bool) {
inline fn operationBinary(comptime TT: type, a: TT, b: anytype) RuntimeError!bool {
if (comptime TT == bool and @TypeOf(b) == bool) {
switch (Op) {
.LogicalAnd => return a and b,
.LogicalOr => return a or b,
@@ -614,13 +614,16 @@ fn CondOperator(comptime T: PrimitiveType, comptime Op: CondOp) type {
else => {},
}
}
return switch (Op) {
.IsFinite => std.math.isFinite(a),
.IsInf => std.math.isInf(a),
.IsNan => std.math.isNan(a),
.IsNormal => std.math.isNormal(a),
else => RuntimeError.InvalidSpirV,
};
if (comptime std.meta.activeTag(@typeInfo(TT)) == .float) {
switch (Op) {
.IsFinite => return std.math.isFinite(a),
.IsInf => return std.math.isInf(a),
.IsNan => return std.math.isNan(a),
.IsNormal => return std.math.isNormal(a),
else => {},
}
}
return RuntimeError.InvalidSpirV;
}
fn applyScalarBits(bit_count: SpvWord, dst_bool: *Value, a_v: *const Value, b_v: ?*const Value) RuntimeError!void {
@@ -654,9 +657,58 @@ fn CondOperator(comptime T: PrimitiveType, comptime Op: CondOp) type {
comptime N: usize,
dst: []Value,
op1: *@Vector(N, ElemT),
op2: *@Vector(N, ElemT),
op2: *const Value,
) RuntimeError!void {
inline for (0..N) |i| dst[i].Bool = try operationBinary(ElemT, op1[i], op2[i]);
inline for (0..N) |i| {
dst[i].Bool = switch (op2.*) {
.Vector4f32 => |vec| if (comptime std.meta.activeTag(@typeInfo(ElemT)) == .float and i < 4)
try operationBinary(ElemT, op1[i], vec[i])
else
return RuntimeError.InvalidSpirV,
.Vector3f32 => |vec| if (comptime std.meta.activeTag(@typeInfo(ElemT)) == .float and i < 3)
try operationBinary(ElemT, op1[i], vec[i])
else
return RuntimeError.InvalidSpirV,
.Vector2f32 => |vec| if (comptime std.meta.activeTag(@typeInfo(ElemT)) == .float and i < 2)
try operationBinary(ElemT, op1[i], vec[i])
else
return RuntimeError.InvalidSpirV,
.Vector4i32 => |vec| if (comptime std.meta.activeTag(@typeInfo(ElemT)) == .int and i < 4)
try operationBinary(ElemT, op1[i], vec[i])
else
return RuntimeError.InvalidSpirV,
.Vector3i32 => |vec| if (comptime std.meta.activeTag(@typeInfo(ElemT)) == .int and i < 3)
try operationBinary(ElemT, op1[i], vec[i])
else
return RuntimeError.InvalidSpirV,
.Vector2i32 => |vec| if (comptime std.meta.activeTag(@typeInfo(ElemT)) == .int and i < 2)
try operationBinary(ElemT, op1[i], vec[i])
else
return RuntimeError.InvalidSpirV,
.Vector4u32 => |vec| if (comptime std.meta.activeTag(@typeInfo(ElemT)) == .int and i < 4)
try operationBinary(ElemT, op1[i], vec[i])
else
return RuntimeError.InvalidSpirV,
.Vector3u32 => |vec| if (comptime std.meta.activeTag(@typeInfo(ElemT)) == .int and i < 3)
try operationBinary(ElemT, op1[i], vec[i])
else
return RuntimeError.InvalidSpirV,
.Vector2u32 => |vec| if (comptime std.meta.activeTag(@typeInfo(ElemT)) == .int and i < 2)
try operationBinary(ElemT, op1[i], vec[i])
else
return RuntimeError.InvalidSpirV,
else => return RuntimeError.InvalidValueType,
};
}
}
inline fn applyFixedVectorUnary(
@@ -701,62 +753,51 @@ fn CondEngine(comptime T: PrimitiveType, comptime Op: CondOp) type {
try operator.applyScalarBits(lane_bits, d_lane, &a_lane, b_ptr);
},
.Vector4f32 => |*op1_vec| {
if (comptime operator.isUnaryOp())
try operator.applyFixedVectorUnary(f32, 4, dst_vec, op1_vec)
else
try operator.applyFixedVectorBinary(f32, 4, dst_vec, op1_vec, &op2_value.?.Vector4f32);
},
.Vector3f32 => |*op1_vec| {
if (comptime operator.isUnaryOp())
try operator.applyFixedVectorUnary(f32, 3, dst_vec, op1_vec)
else
try operator.applyFixedVectorBinary(f32, 3, dst_vec, op1_vec, &op2_value.?.Vector3f32);
},
.Vector2f32 => |*op1_vec| {
if (comptime operator.isUnaryOp())
try operator.applyFixedVectorUnary(f32, 2, dst_vec, op1_vec)
else
try operator.applyFixedVectorBinary(f32, 2, dst_vec, op1_vec, &op2_value.?.Vector2f32);
},
.Vector4f32 => |*op1_vec| if (comptime operator.isUnaryOp())
try operator.applyFixedVectorUnary(f32, 4, dst_vec, op1_vec)
else
try operator.applyFixedVectorBinary(f32, 4, dst_vec, op1_vec, op2_value.?),
//.Vector4i32 => |*op1_vec| {
// if (comptime operator.isUnaryOp())
// try operator.applyFixedVectorUnary(i32, 4, dst_vec, op1_vec)
// else
// try operator.applyFixedVectorBinary(i32, 4, dst_vec, op1_vec, &op2_value.?.Vector4i32);
//},
//.Vector3i32 => |*op1_vec| {
// if (comptime operator.isUnaryOp())
// try operator.applyFixedVectorUnary(i32, 3, dst_vec, op1_vec)
// else
// try operator.applyFixedVectorBinary(i32, 3, dst_vec, op1_vec, &op2_value.?.Vector3i32);
//},
//.Vector2i32 => |*op1_vec| {
// if (comptime operator.isUnaryOp())
// try operator.applyFixedVectorUnary(i32, 2, dst_vec, op1_vec)
// else
// try operator.applyFixedVectorBinary(i32, 2, dst_vec, op1_vec, &op2_value.?.Vector2i32);
//},
.Vector3f32 => |*op1_vec| if (comptime operator.isUnaryOp())
try operator.applyFixedVectorUnary(f32, 3, dst_vec, op1_vec)
else
try operator.applyFixedVectorBinary(f32, 3, dst_vec, op1_vec, op2_value.?),
.Vector2f32 => |*op1_vec| if (comptime operator.isUnaryOp())
try operator.applyFixedVectorUnary(f32, 2, dst_vec, op1_vec)
else
try operator.applyFixedVectorBinary(f32, 2, dst_vec, op1_vec, op2_value.?),
.Vector4i32 => |*op1_vec| if (comptime operator.isUnaryOp())
try operator.applyFixedVectorUnary(i32, 4, dst_vec, op1_vec)
else
try operator.applyFixedVectorBinary(i32, 4, dst_vec, op1_vec, op2_value.?),
.Vector3i32 => |*op1_vec| if (comptime operator.isUnaryOp())
try operator.applyFixedVectorUnary(i32, 3, dst_vec, op1_vec)
else
try operator.applyFixedVectorBinary(i32, 3, dst_vec, op1_vec, op2_value.?),
.Vector2i32 => |*op1_vec| if (comptime operator.isUnaryOp())
try operator.applyFixedVectorUnary(i32, 2, dst_vec, op1_vec)
else
try operator.applyFixedVectorBinary(i32, 2, dst_vec, op1_vec, op2_value.?),
.Vector4u32 => |*op1_vec| if (comptime operator.isUnaryOp())
try operator.applyFixedVectorUnary(u32, 4, dst_vec, op1_vec)
else
try operator.applyFixedVectorBinary(u32, 4, dst_vec, op1_vec, op2_value.?),
.Vector3u32 => |*op1_vec| if (comptime operator.isUnaryOp())
try operator.applyFixedVectorUnary(u32, 3, dst_vec, op1_vec)
else
try operator.applyFixedVectorBinary(u32, 3, dst_vec, op1_vec, op2_value.?),
.Vector2u32 => |*op1_vec| if (comptime operator.isUnaryOp())
try operator.applyFixedVectorUnary(u32, 2, dst_vec, op1_vec)
else
try operator.applyFixedVectorBinary(u32, 2, dst_vec, op1_vec, op2_value.?),
//.Vector4u32 => |*op1_vec| {
// if (comptime operator.isUnaryOp())
// try operator.applyFixedVectorUnary(u32, 4, dst_vec, op1_vec)
// else
// try operator.applyFixedVectorBinary(u32, 4, dst_vec, op1_vec, &op2_value.?.Vector4u32);
//},
//.Vector3u32 => |*op1_vec| {
// if (comptime operator.isUnaryOp())
// try operator.applyFixedVectorUnary(u32, 3, dst_vec, op1_vec)
// else
// try operator.applyFixedVectorBinary(u32, 3, dst_vec, op1_vec, &op2_value.?.Vector3u32);
//},
//.Vector2u32 => |*op1_vec| {
// if (comptime operator.isUnaryOp())
// try operator.applyFixedVectorUnary(u32, 2, dst_vec, op1_vec)
// else
// try operator.applyFixedVectorBinary(u32, 2, dst_vec, op1_vec, &op2_value.?.Vector2u32);
//},
else => return RuntimeError.InvalidSpirV,
}
},
@@ -2188,7 +2229,7 @@ fn opSpecConstant(allocator: std.mem.Allocator, word_count: SpvWord, rt: *Runtim
for (result.decorations.items) |decoration| {
if (decoration.rtype == .SpecId) {
if (rt.specialization_constants.get(decoration.literal_1)) |data| {
_ = try (try result.getValue()).writeConst(data);
_ = try (try result.getValue()).write(data);
}
}
}
@@ -2204,7 +2245,7 @@ fn opSpecConstantTrue(allocator: std.mem.Allocator, _: SpvWord, rt: *Runtime) Ru
for (target.decorations.items) |decoration| {
if (decoration.rtype == .SpecId) {
if (rt.specialization_constants.get(decoration.literal_1)) |data| {
_ = try (try target.getValue()).writeConst(data);
_ = try (try target.getValue()).write(data);
}
}
}
@@ -2220,7 +2261,7 @@ fn opSpecConstantFalse(allocator: std.mem.Allocator, _: SpvWord, rt: *Runtime) R
for (target.decorations.items) |decoration| {
if (decoration.rtype == .SpecId) {
if (rt.specialization_constants.get(decoration.literal_1)) |data| {
_ = try (try target.getValue()).writeConst(data);
_ = try (try target.getValue()).write(data);
}
}
}