fixing runtime array access chain
This commit is contained in:
+112
-44
@@ -120,8 +120,16 @@ pub const Value = union(Type) {
|
||||
i32_ptr: *i32, //< For vector specializations
|
||||
u32_ptr: *u32,
|
||||
},
|
||||
is_owner_of_uniform_slice: bool = false,
|
||||
|
||||
/// Exact byte window in externally visible descriptor storage that
|
||||
/// corresponds to this pointer. For a pointer to struct member N this
|
||||
/// starts at the member offset, not at the containing struct.
|
||||
uniform_slice_window: ?[]u8 = null,
|
||||
|
||||
/// Heap-owned value that backs a pointer into a materialized runtime
|
||||
/// array element. This may differ from ptr.common when the pointer is
|
||||
/// to a child/member of that materialized value.
|
||||
uniform_backing_value: ?*Self = null,
|
||||
},
|
||||
|
||||
pub inline fn getCompositeDataOrNull(self: *const Self) ?[]Self {
|
||||
@@ -404,18 +412,13 @@ pub const Value = union(Type) {
|
||||
return offset;
|
||||
},
|
||||
.Structure => |s| {
|
||||
var offset: usize = 0;
|
||||
var end_offset: usize = 0;
|
||||
for (s.values, 0..) |v, i| {
|
||||
const read_size = try v.read(output[offset..]);
|
||||
if (i + 1 < s.offsets.len) {
|
||||
if (s.offsets[i + 1]) |o| {
|
||||
offset = o;
|
||||
continue;
|
||||
const member_offset: usize = @intCast(s.offsets[i] orelse end_offset);
|
||||
const read_size = try v.read(output[member_offset..]);
|
||||
end_offset = @max(end_offset, member_offset + read_size);
|
||||
}
|
||||
}
|
||||
offset += read_size;
|
||||
}
|
||||
return offset;
|
||||
return end_offset;
|
||||
},
|
||||
else => return RuntimeError.InvalidValueType,
|
||||
}
|
||||
@@ -548,18 +551,13 @@ pub const Value = union(Type) {
|
||||
return offset;
|
||||
},
|
||||
.Structure => |s| {
|
||||
var offset: usize = 0;
|
||||
var end_offset: usize = 0;
|
||||
for (s.values, 0..) |*v, i| {
|
||||
const write_size = try v.write(input[offset..]);
|
||||
if (i + 1 < s.offsets.len) {
|
||||
if (s.offsets[i + 1]) |o| {
|
||||
offset = o;
|
||||
continue;
|
||||
const member_offset: usize = @intCast(s.offsets[i] orelse end_offset);
|
||||
const write_size = try v.write(input[member_offset..]);
|
||||
end_offset = @max(end_offset, member_offset + write_size);
|
||||
}
|
||||
}
|
||||
offset += write_size;
|
||||
}
|
||||
return offset;
|
||||
return end_offset;
|
||||
},
|
||||
.RuntimeArray => |*arr| arr.data = input[0..],
|
||||
.Image => |*img| img.driver_image = @ptrFromInt(std.mem.bytesToValue(usize, input[0..])),
|
||||
@@ -587,13 +585,8 @@ pub const Value = union(Type) {
|
||||
.Structure => |s| blk: {
|
||||
var size: usize = 0;
|
||||
for (s.values, 0..) |v, i| {
|
||||
if (i + 1 < s.offsets.len) {
|
||||
if (s.offsets[i + 1]) |o| {
|
||||
size = o;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
size += try v.getPlainMemorySize();
|
||||
const member_offset: usize = @intCast(s.offsets[i] orelse size);
|
||||
size = @max(size, member_offset + try v.getPlainMemorySize());
|
||||
}
|
||||
break :blk size;
|
||||
},
|
||||
@@ -644,12 +637,27 @@ pub const Value = union(Type) {
|
||||
switch (p.ptr) {
|
||||
.common => |ptr| {
|
||||
_ = try ptr.read(window);
|
||||
ptr.deinit(allocator);
|
||||
if (p.is_owner_of_uniform_slice)
|
||||
allocator.destroy(ptr);
|
||||
},
|
||||
else => {},
|
||||
.f32_ptr => |ptr| {
|
||||
if (window.len < @sizeOf(f32)) return RuntimeError.OutOfBounds;
|
||||
std.mem.copyForwards(u8, window[0..@sizeOf(f32)], std.mem.asBytes(ptr));
|
||||
},
|
||||
.i32_ptr => |ptr| {
|
||||
if (window.len < @sizeOf(i32)) return RuntimeError.OutOfBounds;
|
||||
std.mem.copyForwards(u8, window[0..@sizeOf(i32)], std.mem.asBytes(ptr));
|
||||
},
|
||||
.u32_ptr => |ptr| {
|
||||
if (window.len < @sizeOf(u32)) return RuntimeError.OutOfBounds;
|
||||
std.mem.copyForwards(u8, window[0..@sizeOf(u32)], std.mem.asBytes(ptr));
|
||||
},
|
||||
}
|
||||
|
||||
if (p.uniform_backing_value) |backing| {
|
||||
backing.deinit(allocator);
|
||||
allocator.destroy(backing);
|
||||
p.uniform_backing_value = null;
|
||||
}
|
||||
|
||||
p.uniform_slice_window = null;
|
||||
}
|
||||
},
|
||||
@@ -685,28 +693,64 @@ pub const Value = union(Type) {
|
||||
.Vector => |lanes| (try getPrimitiveField(T, bits, &lanes[lane_index])).*,
|
||||
|
||||
.Vector2i32 => |*vec| switch (lane_index) {
|
||||
inline 0...1 => |i| if (bits == 32) @as(TT, @bitCast(vec[i])) else return RuntimeError.InvalidSpirV,
|
||||
inline 0...1 => |i| blk: {
|
||||
if (bits == 32) {
|
||||
break :blk @as(TT, @bitCast(vec[i]));
|
||||
} else {
|
||||
return RuntimeError.InvalidSpirV;
|
||||
}
|
||||
},
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
.Vector3i32 => |*vec| switch (lane_index) {
|
||||
inline 0...2 => |i| if (bits == 32) @as(TT, @bitCast(vec[i])) else return RuntimeError.InvalidSpirV,
|
||||
inline 0...2 => |i| blk: {
|
||||
if (bits == 32) {
|
||||
break :blk @as(TT, @bitCast(vec[i]));
|
||||
} else {
|
||||
return RuntimeError.InvalidSpirV;
|
||||
}
|
||||
},
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
.Vector4i32 => |*vec| switch (lane_index) {
|
||||
inline 0...3 => |i| if (bits == 32) @as(TT, @bitCast(vec[i])) else return RuntimeError.InvalidSpirV,
|
||||
inline 0...3 => |i| blk: {
|
||||
if (bits == 32) {
|
||||
break :blk @as(TT, @bitCast(vec[i]));
|
||||
} else {
|
||||
return RuntimeError.InvalidSpirV;
|
||||
}
|
||||
},
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
|
||||
.Vector2u32 => |*vec| switch (lane_index) {
|
||||
inline 0...1 => |i| if (bits == 32) @as(TT, @bitCast(vec[i])) else return RuntimeError.InvalidSpirV,
|
||||
inline 0...1 => |i| blk: {
|
||||
if (bits == 32) {
|
||||
break :blk @as(TT, @bitCast(vec[i]));
|
||||
} else {
|
||||
return RuntimeError.InvalidSpirV;
|
||||
}
|
||||
},
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
.Vector3u32 => |*vec| switch (lane_index) {
|
||||
inline 0...2 => |i| if (bits == 32) @as(TT, @bitCast(vec[i])) else return RuntimeError.InvalidSpirV,
|
||||
inline 0...2 => |i| blk: {
|
||||
if (bits == 32) {
|
||||
break :blk @as(TT, @bitCast(vec[i]));
|
||||
} else {
|
||||
return RuntimeError.InvalidSpirV;
|
||||
}
|
||||
},
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
.Vector4u32 => |*vec| switch (lane_index) {
|
||||
inline 0...3 => |i| if (bits == 32) @as(TT, @bitCast(vec[i])) else return RuntimeError.InvalidSpirV,
|
||||
inline 0...3 => |i| blk: {
|
||||
if (bits == 32) {
|
||||
break :blk @as(TT, @bitCast(vec[i]));
|
||||
} else {
|
||||
return RuntimeError.InvalidSpirV;
|
||||
}
|
||||
},
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
|
||||
@@ -721,28 +765,52 @@ pub const Value = union(Type) {
|
||||
.Vector => |lanes| try setScalarLaneValue(T, bits, &lanes[lane_index], value),
|
||||
|
||||
.Vector2i32 => |*vec| switch (lane_index) {
|
||||
inline 0...1 => |i| vec[i] = if (bits == 32) @bitCast(value) else return RuntimeError.InvalidSpirV,
|
||||
inline 0...1 => |i| if (bits == 32) {
|
||||
vec[i] = @bitCast(value);
|
||||
} else {
|
||||
return RuntimeError.InvalidSpirV;
|
||||
},
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
.Vector3i32 => |*vec| switch (lane_index) {
|
||||
inline 0...2 => |i| vec[i] = if (bits == 32) @bitCast(value) else return RuntimeError.InvalidSpirV,
|
||||
inline 0...2 => |i| if (bits == 32) {
|
||||
vec[i] = @bitCast(value);
|
||||
} else {
|
||||
return RuntimeError.InvalidSpirV;
|
||||
},
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
.Vector4i32 => |*vec| switch (lane_index) {
|
||||
inline 0...3 => |i| vec[i] = if (bits == 32) @bitCast(value) else return RuntimeError.InvalidSpirV,
|
||||
inline 0...3 => |i| if (bits == 32) {
|
||||
vec[i] = @bitCast(value);
|
||||
} else {
|
||||
return RuntimeError.InvalidSpirV;
|
||||
},
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
|
||||
.Vector2u32 => |*vec| switch (lane_index) {
|
||||
inline 0...1 => |i| vec[i] = if (bits == 32) @bitCast(value) else return RuntimeError.InvalidSpirV,
|
||||
inline 0...1 => |i| if (bits == 32) {
|
||||
vec[i] = @bitCast(value);
|
||||
} else {
|
||||
return RuntimeError.InvalidSpirV;
|
||||
},
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
.Vector3u32 => |*vec| switch (lane_index) {
|
||||
inline 0...2 => |i| vec[i] = if (bits == 32) @bitCast(value) else return RuntimeError.InvalidSpirV,
|
||||
inline 0...2 => |i| if (bits == 32) {
|
||||
vec[i] = @bitCast(value);
|
||||
} else {
|
||||
return RuntimeError.InvalidSpirV;
|
||||
},
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
.Vector4u32 => |*vec| switch (lane_index) {
|
||||
inline 0...3 => |i| vec[i] = if (bits == 32) @bitCast(value) else return RuntimeError.InvalidSpirV,
|
||||
inline 0...3 => |i| if (bits == 32) {
|
||||
vec[i] = @bitCast(value);
|
||||
} else {
|
||||
return RuntimeError.InvalidSpirV;
|
||||
},
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
|
||||
|
||||
+132
-39
@@ -1304,9 +1304,6 @@ fn opAccessChain(allocator: std.mem.Allocator, word_count: SpvWord, rt: *Runtime
|
||||
const base = &rt.results[base_id];
|
||||
var value_ptr = try base.getValue();
|
||||
|
||||
var arena = std.heap.ArenaAllocator.init(allocator);
|
||||
defer arena.deinit();
|
||||
|
||||
const index_count: usize = @intCast(word_count - 3);
|
||||
|
||||
const indexes, const free_responsability = blk: {
|
||||
@@ -1332,11 +1329,38 @@ fn opAccessChain(allocator: std.mem.Allocator, word_count: SpvWord, rt: *Runtime
|
||||
.base = base_id,
|
||||
.indexes = indexes,
|
||||
.value = blk: {
|
||||
var is_owner_of_uniform_slice = false;
|
||||
const helpers = struct {
|
||||
fn advanceWindow(window: ?[]u8, offset: usize) RuntimeError!?[]u8 {
|
||||
if (window) |w| {
|
||||
if (offset > w.len) return RuntimeError.OutOfBounds;
|
||||
return w[offset..];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
fn advanceWindowSized(window: ?[]u8, offset: usize, size: usize) RuntimeError!?[]u8 {
|
||||
if (window) |w| {
|
||||
if (offset > w.len or size > w.len - offset) return RuntimeError.OutOfBounds;
|
||||
return w[offset .. offset + size];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
var uniform_slice_window: ?[]u8 = null;
|
||||
var uniform_backing_value: ?*Value = null;
|
||||
|
||||
if (std.meta.activeTag(value_ptr.*) == .Pointer) {
|
||||
const ptr = value_ptr.Pointer;
|
||||
uniform_slice_window = ptr.uniform_slice_window;
|
||||
uniform_backing_value = ptr.uniform_backing_value;
|
||||
switch (ptr.ptr) {
|
||||
.common => |common| value_ptr = common,
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
}
|
||||
}
|
||||
|
||||
for (0..index_count) |index| {
|
||||
const is_last = (index == index_count - 1);
|
||||
const index_id = try rt.it.next();
|
||||
indexes[index] = index_id;
|
||||
const member = &rt.results[index_id];
|
||||
@@ -1349,63 +1373,135 @@ fn opAccessChain(allocator: std.mem.Allocator, word_count: SpvWord, rt: *Runtime
|
||||
switch (member_value.*) {
|
||||
.Int => |i| {
|
||||
if (std.meta.activeTag(value_ptr.*) == .Pointer) {
|
||||
value_ptr = value_ptr.Pointer.ptr.common; // Don't know if I should check for specialized pointers
|
||||
const ptr = value_ptr.Pointer;
|
||||
uniform_slice_window = ptr.uniform_slice_window;
|
||||
uniform_backing_value = ptr.uniform_backing_value;
|
||||
switch (ptr.ptr) {
|
||||
.common => |common| value_ptr = common,
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
}
|
||||
}
|
||||
|
||||
const component_index: usize = @intCast(i.value.uint32);
|
||||
|
||||
switch (value_ptr.*) {
|
||||
.Vector, .Matrix => |v| {
|
||||
if (i.value.uint32 >= v.len) return RuntimeError.OutOfBounds;
|
||||
value_ptr = &v[i.value.uint32];
|
||||
if (component_index >= v.len) return RuntimeError.OutOfBounds;
|
||||
var offset: usize = 0;
|
||||
for (v[0..component_index]) |*element| {
|
||||
offset += try element.getPlainMemorySize();
|
||||
}
|
||||
uniform_slice_window = try helpers.advanceWindow(uniform_slice_window, offset);
|
||||
value_ptr = &v[component_index];
|
||||
},
|
||||
.Array => |a| {
|
||||
if (i.value.uint32 >= a.values.len) return RuntimeError.OutOfBounds;
|
||||
value_ptr = &a.values[i.value.uint32];
|
||||
if (component_index >= a.values.len) return RuntimeError.OutOfBounds;
|
||||
uniform_slice_window = try helpers.advanceWindow(uniform_slice_window, component_index * a.stride);
|
||||
value_ptr = &a.values[component_index];
|
||||
},
|
||||
.Structure => |s| {
|
||||
if (i.value.uint32 >= s.values.len) return RuntimeError.OutOfBounds;
|
||||
value_ptr = &s.values[i.value.uint32];
|
||||
if (component_index >= s.values.len) return RuntimeError.OutOfBounds;
|
||||
var end_offset: usize = 0;
|
||||
for (s.values[0..component_index], 0..) |*field, field_index| {
|
||||
const field_offset: usize = @intCast(s.offsets[field_index] orelse end_offset);
|
||||
end_offset = @max(end_offset, field_offset + try field.getPlainMemorySize());
|
||||
}
|
||||
const member_offset: usize = @intCast(s.offsets[component_index] orelse end_offset);
|
||||
uniform_slice_window = try helpers.advanceWindow(uniform_slice_window, member_offset);
|
||||
value_ptr = &s.values[component_index];
|
||||
},
|
||||
.RuntimeArray => |*arr| {
|
||||
if (i.value.uint32 >= arr.getLen()) return RuntimeError.OutOfBounds;
|
||||
value_ptr = try arr.createValueFromIndex(if (is_last) allocator else arena.allocator(), rt.results, i.value.uint32);
|
||||
if (is_last)
|
||||
is_owner_of_uniform_slice = true;
|
||||
uniform_slice_window = arr.data[arr.getOffsetOfIndex(i.value.uint32)..];
|
||||
if (component_index >= arr.getLen()) return RuntimeError.OutOfBounds;
|
||||
|
||||
const element_offset = arr.getOffsetOfIndex(component_index);
|
||||
if (element_offset > arr.data.len or arr.stride > arr.data.len - element_offset)
|
||||
return RuntimeError.OutOfBounds;
|
||||
|
||||
const backing = try arr.createValueFromIndex(allocator, rt.results, component_index);
|
||||
errdefer {
|
||||
backing.deinit(allocator);
|
||||
allocator.destroy(backing);
|
||||
}
|
||||
|
||||
if (uniform_backing_value) |old_backing| {
|
||||
old_backing.deinit(allocator);
|
||||
allocator.destroy(old_backing);
|
||||
}
|
||||
|
||||
value_ptr = backing;
|
||||
uniform_backing_value = backing;
|
||||
uniform_slice_window = arr.data[element_offset .. element_offset + arr.stride];
|
||||
},
|
||||
.Vector4f32 => |*v| switch (i.value.uint32) {
|
||||
inline 0...3 => |idx| break :blk .{ .Pointer = .{ .ptr = .{ .f32_ptr = &v[idx] } } },
|
||||
.Vector4f32 => |*v| switch (component_index) {
|
||||
inline 0...3 => |idx| break :blk .{ .Pointer = .{
|
||||
.ptr = .{ .f32_ptr = &v[idx] },
|
||||
.uniform_slice_window = try helpers.advanceWindowSized(uniform_slice_window, idx * @sizeOf(f32), @sizeOf(f32)),
|
||||
.uniform_backing_value = uniform_backing_value,
|
||||
} },
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
.Vector3f32 => |*v| switch (i.value.uint32) {
|
||||
inline 0...2 => |idx| break :blk .{ .Pointer = .{ .ptr = .{ .f32_ptr = &v[idx] } } },
|
||||
.Vector3f32 => |*v| switch (component_index) {
|
||||
inline 0...2 => |idx| break :blk .{ .Pointer = .{
|
||||
.ptr = .{ .f32_ptr = &v[idx] },
|
||||
.uniform_slice_window = try helpers.advanceWindowSized(uniform_slice_window, idx * @sizeOf(f32), @sizeOf(f32)),
|
||||
.uniform_backing_value = uniform_backing_value,
|
||||
} },
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
.Vector2f32 => |*v| switch (i.value.uint32) {
|
||||
inline 0...1 => |idx| break :blk .{ .Pointer = .{ .ptr = .{ .f32_ptr = &v[idx] } } },
|
||||
.Vector2f32 => |*v| switch (component_index) {
|
||||
inline 0...1 => |idx| break :blk .{ .Pointer = .{
|
||||
.ptr = .{ .f32_ptr = &v[idx] },
|
||||
.uniform_slice_window = try helpers.advanceWindowSized(uniform_slice_window, idx * @sizeOf(f32), @sizeOf(f32)),
|
||||
.uniform_backing_value = uniform_backing_value,
|
||||
} },
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
.Vector4i32 => |*v| switch (i.value.uint32) {
|
||||
inline 0...3 => |idx| break :blk .{ .Pointer = .{ .ptr = .{ .i32_ptr = &v[idx] } } },
|
||||
.Vector4i32 => |*v| switch (component_index) {
|
||||
inline 0...3 => |idx| break :blk .{ .Pointer = .{
|
||||
.ptr = .{ .i32_ptr = &v[idx] },
|
||||
.uniform_slice_window = try helpers.advanceWindowSized(uniform_slice_window, idx * @sizeOf(i32), @sizeOf(i32)),
|
||||
.uniform_backing_value = uniform_backing_value,
|
||||
} },
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
.Vector3i32 => |*v| switch (i.value.uint32) {
|
||||
inline 0...2 => |idx| break :blk .{ .Pointer = .{ .ptr = .{ .i32_ptr = &v[idx] } } },
|
||||
.Vector3i32 => |*v| switch (component_index) {
|
||||
inline 0...2 => |idx| break :blk .{ .Pointer = .{
|
||||
.ptr = .{ .i32_ptr = &v[idx] },
|
||||
.uniform_slice_window = try helpers.advanceWindowSized(uniform_slice_window, idx * @sizeOf(i32), @sizeOf(i32)),
|
||||
.uniform_backing_value = uniform_backing_value,
|
||||
} },
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
.Vector2i32 => |*v| switch (i.value.uint32) {
|
||||
inline 0...1 => |idx| break :blk .{ .Pointer = .{ .ptr = .{ .i32_ptr = &v[idx] } } },
|
||||
.Vector2i32 => |*v| switch (component_index) {
|
||||
inline 0...1 => |idx| break :blk .{ .Pointer = .{
|
||||
.ptr = .{ .i32_ptr = &v[idx] },
|
||||
.uniform_slice_window = try helpers.advanceWindowSized(uniform_slice_window, idx * @sizeOf(i32), @sizeOf(i32)),
|
||||
.uniform_backing_value = uniform_backing_value,
|
||||
} },
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
.Vector4u32 => |*v| switch (i.value.uint32) {
|
||||
inline 0...3 => |idx| break :blk .{ .Pointer = .{ .ptr = .{ .u32_ptr = &v[idx] } } },
|
||||
.Vector4u32 => |*v| switch (component_index) {
|
||||
inline 0...3 => |idx| break :blk .{ .Pointer = .{
|
||||
.ptr = .{ .u32_ptr = &v[idx] },
|
||||
.uniform_slice_window = try helpers.advanceWindowSized(uniform_slice_window, idx * @sizeOf(u32), @sizeOf(u32)),
|
||||
.uniform_backing_value = uniform_backing_value,
|
||||
} },
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
.Vector3u32 => |*v| switch (i.value.uint32) {
|
||||
inline 0...2 => |idx| break :blk .{ .Pointer = .{ .ptr = .{ .u32_ptr = &v[idx] } } },
|
||||
.Vector3u32 => |*v| switch (component_index) {
|
||||
inline 0...2 => |idx| break :blk .{ .Pointer = .{
|
||||
.ptr = .{ .u32_ptr = &v[idx] },
|
||||
.uniform_slice_window = try helpers.advanceWindowSized(uniform_slice_window, idx * @sizeOf(u32), @sizeOf(u32)),
|
||||
.uniform_backing_value = uniform_backing_value,
|
||||
} },
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
.Vector2u32 => |*v| switch (i.value.uint32) {
|
||||
inline 0...1 => |idx| break :blk .{ .Pointer = .{ .ptr = .{ .u32_ptr = &v[idx] } } },
|
||||
.Vector2u32 => |*v| switch (component_index) {
|
||||
inline 0...1 => |idx| break :blk .{ .Pointer = .{
|
||||
.ptr = .{ .u32_ptr = &v[idx] },
|
||||
.uniform_slice_window = try helpers.advanceWindowSized(uniform_slice_window, idx * @sizeOf(u32), @sizeOf(u32)),
|
||||
.uniform_backing_value = uniform_backing_value,
|
||||
} },
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
},
|
||||
else => return RuntimeError.InvalidSpirV,
|
||||
@@ -1417,15 +1513,14 @@ fn opAccessChain(allocator: std.mem.Allocator, word_count: SpvWord, rt: *Runtime
|
||||
break :blk .{
|
||||
.Pointer = .{
|
||||
.ptr = .{ .common = value_ptr },
|
||||
.is_owner_of_uniform_slice = is_owner_of_uniform_slice,
|
||||
.uniform_slice_window = uniform_slice_window,
|
||||
.uniform_backing_value = uniform_backing_value,
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
fn opAtomicStore(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void {
|
||||
const ptr_id = try rt.it.next();
|
||||
_ = rt.it.skip(); // scope
|
||||
@@ -1905,8 +2000,6 @@ fn opMulExtended(comptime is_signed: bool, rt: *Runtime) RuntimeError!void {
|
||||
const low: UIntT = @truncate(product_bits);
|
||||
const high: UIntT = @truncate(product_bits >> bits);
|
||||
|
||||
std.debug.print("test 0x{X} - 0x{X}\n", .{ high, low });
|
||||
|
||||
try writeMulExtendedBits(bits, low_dst, lane_index, low);
|
||||
try writeMulExtendedBits(bits, high_dst, lane_index, high);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user