fixing lots of copy tests issues
Test / build_and_test (push) Successful in 33s
Build / build (push) Successful in 1m0s

This commit is contained in:
2026-05-24 22:04:10 +02:00
parent bd2774b7f9
commit 5a91956939
10 changed files with 64 additions and 51 deletions
+2 -2
View File
@@ -31,8 +31,8 @@
.lazy = true, .lazy = true,
}, },
.SPIRV_Interpreter = .{ .SPIRV_Interpreter = .{
.url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#a8372ce736066734532e7fbc99579b15cbe09cad", .url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#1ffa20d07c59da34300dd97e16b72a7320f5af6c",
.hash = "SPIRV_Interpreter-0.0.1-ajmpn-FmBQA35w-G9sNA8hKNcK7oaOhvTmB_QWgpfrig", .hash = "SPIRV_Interpreter-0.0.1-ajmpn25qBQByByo4yetC7ZS63JxLvuwXMknTMWnbaYAb",
.lazy = true, .lazy = true,
}, },
//.SPIRV_Interpreter = .{ //.SPIRV_Interpreter = .{
+2
View File
@@ -99,9 +99,11 @@ pub fn execute(self: *Self, device: *ExecutionDevice) void {
for (self.commands.items) |command| { for (self.commands.items) |command| {
command.vtable.execute(@ptrCast(command.ptr), device) catch |err| { command.vtable.execute(@ptrCast(command.ptr), device) catch |err| {
base.errors.errorLoggerContext(err, "the software execution device"); base.errors.errorLoggerContext(err, "the software execution device");
if (comptime base.config.logs == .verbose) {
if (@errorReturnTrace()) |trace| { if (@errorReturnTrace()) |trace| {
std.debug.dumpErrorReturnTrace(trace); std.debug.dumpErrorReturnTrace(trace);
} }
}
return; // Should we return or continue ? Maybe device lost ? return; // Should we return or continue ? Maybe device lost ?
}; };
} }
+22 -25
View File
@@ -104,7 +104,7 @@ pub fn copyToImageSingleAspect(self: *const Self, dst: *Self, region: vk.ImageCo
const bytes_per_block = base.format.texelSize(src_format); const bytes_per_block = base.format.texelSize(src_format);
const src_extent = self.getMipLevelExtent(region.src_subresource.mip_level); const src_extent = self.getMipLevelExtent(region.src_subresource.mip_level);
const dst_extent = dst.getMipLevelExtent(region.src_subresource.mip_level); const dst_extent = dst.getMipLevelExtent(region.dst_subresource.mip_level);
const one_is_3D = (self.interface.image_type == .@"3d") != (dst.interface.image_type == .@"3d"); const one_is_3D = (self.interface.image_type == .@"3d") != (dst.interface.image_type == .@"3d");
const both_are_3D = (self.interface.image_type == .@"3d") and (dst.interface.image_type == .@"3d"); const both_are_3D = (self.interface.image_type == .@"3d") and (dst.interface.image_type == .@"3d");
@@ -120,24 +120,13 @@ pub fn copyToImageSingleAspect(self: *const Self, dst: *Self, region: vk.ImageCo
const src_layer_pitch = if (self.interface.image_type == .@"3d") src_depth_pitch_bytes else src_array_pitch; const src_layer_pitch = if (self.interface.image_type == .@"3d") src_depth_pitch_bytes else src_array_pitch;
const dst_layer_pitch = if (dst.interface.image_type == .@"3d") dst_depth_pitch_bytes else dst_array_pitch; const dst_layer_pitch = if (dst.interface.image_type == .@"3d") dst_depth_pitch_bytes else dst_array_pitch;
// If one image is 3D, extent.depth must match the layer count. If both images are 2D,
// depth is 1 but the source and destination subresource layer count must match.
const layer_count = if (one_is_3D) region.extent.depth else region.src_subresource.layer_count; const layer_count = if (one_is_3D) region.extent.depth else region.src_subresource.layer_count;
// Copies between 2D and 3D images are treated as layers, so only use depth as the slice count when both images are 3D.
const slice_count = if (both_are_3D) region.extent.depth else self.interface.samples.toInt(); const slice_count = if (both_are_3D) region.extent.depth else self.interface.samples.toInt();
const is_single_slice = (slice_count == 1); const is_single_slice = (slice_count == 1);
const is_single_row = (region.extent.height == 1) and is_single_slice; const is_single_row = (region.extent.height == 1) and is_single_slice;
// In order to copy multiple rows using a single memcpy call, we
// have to make sure that we need to copy the entire row and that
// both source and destination rows have the same size in bytes
const is_entire_row = (region.extent.width == src_extent.width) and (region.extent.width == dst_extent.width); const is_entire_row = (region.extent.width == src_extent.width) and (region.extent.width == dst_extent.width);
// In order to copy multiple slices using a single memcpy call, we
// have to make sure that we need to copy the entire slice and that
// both source and destination slices have the same size in bytes
const is_entire_slice = is_entire_row and const is_entire_slice = is_entire_row and
(region.extent.height == src_extent.height) and (region.extent.height == src_extent.height) and
(region.extent.height == dst_extent.height) and (region.extent.height == dst_extent.height) and
@@ -148,16 +137,14 @@ pub fn copyToImageSingleAspect(self: *const Self, dst: *Self, region: vk.ImageCo
.mip_level = region.src_subresource.mip_level, .mip_level = region.src_subresource.mip_level,
.array_layer = region.src_subresource.base_array_layer, .array_layer = region.src_subresource.base_array_layer,
}); });
const src_size = try self.interface.getTotalSizeForAspect(region.src_subresource.aspect_mask); var src_map = try self.mapAsSliceWithAddedOffset(u8, src_texel_offset, vk.WHOLE_SIZE);
var src_map = try self.mapAsSliceWithAddedOffset(u8, src_texel_offset, src_size);
const dst_texel_offset = try dst.getTexelMemoryOffset(region.dst_offset, .{ const dst_texel_offset = try dst.getTexelMemoryOffset(region.dst_offset, .{
.aspect_mask = region.dst_subresource.aspect_mask, .aspect_mask = region.dst_subresource.aspect_mask,
.mip_level = region.dst_subresource.mip_level, .mip_level = region.dst_subresource.mip_level,
.array_layer = region.dst_subresource.base_array_layer, .array_layer = region.dst_subresource.base_array_layer,
}); });
const dst_size = try dst.interface.getTotalSizeForAspect(region.dst_subresource.aspect_mask); var dst_map = try dst.mapAsSliceWithAddedOffset(u8, dst_texel_offset, vk.WHOLE_SIZE);
var dst_map = try dst.mapAsSliceWithAddedOffset(u8, dst_texel_offset, dst_size);
for (0..layer_count) |_| { for (0..layer_count) |_| {
if (is_single_row) { if (is_single_row) {
@@ -203,6 +190,9 @@ pub fn copyToImageSingleAspect(self: *const Self, dst: *Self, region: vk.ImageCo
src_row_memory = if (src_row_memory.len < src_row_pitch_bytes) break else src_row_memory[src_row_pitch_bytes..]; src_row_memory = if (src_row_memory.len < src_row_pitch_bytes) break else src_row_memory[src_row_pitch_bytes..];
dst_row_memory = if (dst_row_memory.len < dst_row_pitch_bytes) break else dst_row_memory[dst_row_pitch_bytes..]; dst_row_memory = if (dst_row_memory.len < dst_row_pitch_bytes) break else dst_row_memory[dst_row_pitch_bytes..];
} }
src_slice_memory = if (src_slice_memory.len < src_depth_pitch_bytes) break else src_slice_memory[src_depth_pitch_bytes..];
dst_slice_memory = if (dst_slice_memory.len < dst_depth_pitch_bytes) break else dst_slice_memory[dst_depth_pitch_bytes..];
} }
} }
@@ -212,34 +202,36 @@ pub fn copyToImageSingleAspect(self: *const Self, dst: *Self, region: vk.ImageCo
} }
pub fn copyToBuffer(self: *const Self, dst: *SoftBuffer, region: vk.BufferImageCopy) VkError!void { pub fn copyToBuffer(self: *const Self, dst: *SoftBuffer, region: vk.BufferImageCopy) VkError!void {
const dst_size = dst.interface.size - region.buffer_offset;
const dst_offset = dst.interface.offset + region.buffer_offset; const dst_offset = dst.interface.offset + region.buffer_offset;
const dst_map = try dst.mapAsSliceWithOffset(u8, dst_offset, dst_size); const dst_map = try dst.mapAsSliceWithOffset(u8, dst_offset, vk.WHOLE_SIZE);
try self.copy( try self.copy(
null, null,
dst_map, dst_map,
region.image_subresource, region.image_subresource,
region.image_offset, region.image_offset,
region.image_extent, region.image_extent,
region.buffer_row_length,
region.buffer_image_height,
); );
} }
pub fn copyFromBuffer(self: *const Self, src: *const SoftBuffer, region: vk.BufferImageCopy) VkError!void { pub fn copyFromBuffer(self: *const Self, src: *const SoftBuffer, region: vk.BufferImageCopy) VkError!void {
const src_size = src.interface.size - region.buffer_offset;
const src_offset = src.interface.offset + region.buffer_offset; const src_offset = src.interface.offset + region.buffer_offset;
const src_map = try src.mapAsSliceWithOffset(u8, src_offset, src_size); const src_map = try src.mapAsSliceWithOffset(u8, src_offset, vk.WHOLE_SIZE);
try self.copy( try self.copy(
src_map, src_map,
null, null,
region.image_subresource, region.image_subresource,
region.image_offset, region.image_offset,
region.image_extent, region.image_extent,
region.buffer_row_length,
region.buffer_image_height,
); );
} }
pub fn copyToMemory(interface: *const Interface, memory: []u8, subresource: vk.ImageSubresourceLayers) VkError!void { pub fn copyToMemory(interface: *const Interface, memory: []u8, subresource: vk.ImageSubresourceLayers) VkError!void {
const self: *const Self = @alignCast(@fieldParentPtr("interface", interface)); const self: *const Self = @alignCast(@fieldParentPtr("interface", interface));
try self.copy(null, memory, subresource, .{ .x = 0, .y = 0, .z = 0 }, interface.extent); try self.copy(null, memory, subresource, .{ .x = 0, .y = 0, .z = 0 }, interface.extent, 0, 0);
} }
/// Based on SwiftShader vk::Image::copy /// Based on SwiftShader vk::Image::copy
@@ -250,6 +242,8 @@ pub fn copy(
image_subresource: vk.ImageSubresourceLayers, image_subresource: vk.ImageSubresourceLayers,
image_offset: vk.Offset3D, image_offset: vk.Offset3D,
image_extent: vk.Extent3D, image_extent: vk.Extent3D,
row_length: u32,
image_height: u32,
) VkError!void { ) VkError!void {
std.debug.assert((base_src_memory == null) != (base_dst_memory == null)); std.debug.assert((base_src_memory == null) != (base_dst_memory == null));
@@ -266,15 +260,18 @@ pub fn copy(
const format = self.interface.formatFromAspect(image_subresource.aspect_mask); const format = self.interface.formatFromAspect(image_subresource.aspect_mask);
// TODO: handle extent of compressed formats
if (image_extent.width == 0 or image_extent.height == 0 or image_extent.depth == 0) { if (image_extent.width == 0 or image_extent.height == 0 or image_extent.depth == 0) {
return; return;
} }
const extent: vk.Extent2D = .{
.width = if (row_length == 0) image_extent.width else row_length,
.height = if (image_height == 0) image_extent.height else image_height,
};
const bytes_per_block = base.format.texelSize(format); const bytes_per_block = base.format.texelSize(format);
const memory_row_pitch_bytes = image_extent.width * bytes_per_block; const memory_row_pitch_bytes = extent.width * bytes_per_block;
const memory_slice_pitch_bytes = image_extent.height * memory_row_pitch_bytes; const memory_slice_pitch_bytes = extent.height * memory_row_pitch_bytes;
const image_texel_offset = try self.getTexelMemoryOffset(image_offset, .{ const image_texel_offset = try self.getTexelMemoryOffset(image_offset, .{
.aspect_mask = image_subresource.aspect_mask, .aspect_mask = image_subresource.aspect_mask,
+2
View File
@@ -47,9 +47,11 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v
spv.Module.ModuleError.OutOfMemory => return VkError.OutOfHostMemory, spv.Module.ModuleError.OutOfMemory => return VkError.OutOfHostMemory,
else => { else => {
std.log.scoped(.@"SPIR-V module").err("module creation catched a '{s}'", .{@errorName(err)}); std.log.scoped(.@"SPIR-V module").err("module creation catched a '{s}'", .{@errorName(err)});
if (comptime base.config.logs == .verbose) {
if (@errorReturnTrace()) |trace| { if (@errorReturnTrace()) |trace| {
std.debug.dumpErrorReturnTrace(trace); std.debug.dumpErrorReturnTrace(trace);
} }
}
return VkError.ValidationFailed; return VkError.ValidationFailed;
}, },
}, },
+2
View File
@@ -82,9 +82,11 @@ pub fn dispatch(self: *Self, group_count_x: u32, group_count_y: u32, group_count
fn runWrapper(data: RunData) void { fn runWrapper(data: RunData) void {
@call(.always_inline, run, .{data}) catch |err| { @call(.always_inline, run, .{data}) catch |err| {
std.log.scoped(.@"SPIR-V runtime").err("SPIR-V runtime catched a '{s}'", .{@errorName(err)}); std.log.scoped(.@"SPIR-V runtime").err("SPIR-V runtime catched a '{s}'", .{@errorName(err)});
if (comptime base.config.logs == .verbose) {
if (@errorReturnTrace()) |trace| { if (@errorReturnTrace()) |trace| {
std.debug.dumpErrorReturnTrace(trace); std.debug.dumpErrorReturnTrace(trace);
} }
}
}; };
} }
+3
View File
@@ -192,9 +192,12 @@ fn drawCall(self: *Self, bounded_allocator: *BoundedAllocator, vertex_count: usi
self.vertexShaderStage(allocator, &draw_call, vertex_count, instance_count, first_vertex, first_instance, indices) catch |err| { self.vertexShaderStage(allocator, &draw_call, vertex_count, instance_count, first_vertex, first_instance, indices) catch |err| {
std.log.scoped(.@"Vertex stage").err("catched a '{s}'", .{@errorName(err)}); std.log.scoped(.@"Vertex stage").err("catched a '{s}'", .{@errorName(err)});
if (comptime base.config.logs == .verbose) {
if (@errorReturnTrace()) |trace| { if (@errorReturnTrace()) |trace| {
std.debug.dumpErrorReturnTrace(trace); std.debug.dumpErrorReturnTrace(trace);
} }
}
return VkError.Unknown; return VkError.Unknown;
}; };
+5
View File
@@ -112,9 +112,11 @@ fn bresenhamYAtStep(y0: i32, d_x: i32, d_err: i32, y_step: i32, step: usize) i32
fn runWrapper(data: RunData) void { fn runWrapper(data: RunData) void {
@call(.always_inline, run, .{data}) catch |err| { @call(.always_inline, run, .{data}) catch |err| {
std.log.scoped(.@"Rasterization stage").err("line fill mode catched a '{s}'", .{@errorName(err)}); std.log.scoped(.@"Rasterization stage").err("line fill mode catched a '{s}'", .{@errorName(err)});
if (comptime base.config.logs == .verbose) {
if (@errorReturnTrace()) |trace| { if (@errorReturnTrace()) |trace| {
std.debug.dumpErrorReturnTrace(trace); std.debug.dumpErrorReturnTrace(trace);
} }
}
}; };
} }
@@ -146,9 +148,12 @@ inline fn run(data: RunData) !void {
try common.interpolateLineOutputs(data.allocator, data.start_vertex, data.end_vertex, t), try common.interpolateLineOutputs(data.allocator, data.start_vertex, data.end_vertex, t),
) catch |err| { ) catch |err| {
std.log.scoped(.@"Fragment stage").err("catched a '{s}'", .{@errorName(err)}); std.log.scoped(.@"Fragment stage").err("catched a '{s}'", .{@errorName(err)});
if (comptime base.config.logs == .verbose) {
if (@errorReturnTrace()) |trace| { if (@errorReturnTrace()) |trace| {
std.debug.dumpErrorReturnTrace(trace); std.debug.dumpErrorReturnTrace(trace);
} }
}
return; return;
}; };
@@ -115,9 +115,11 @@ inline fn edgeFunction(a: F32x4, b: F32x4, p: F32x4) f32 {
fn runWrapper(data: RunData) void { fn runWrapper(data: RunData) void {
@call(.always_inline, run, .{data}) catch |err| { @call(.always_inline, run, .{data}) catch |err| {
std.log.scoped(.@"Rasterization stage").err("triangle fill mode catched a '{s}'", .{@errorName(err)}); std.log.scoped(.@"Rasterization stage").err("triangle fill mode catched a '{s}'", .{@errorName(err)});
if (comptime base.config.logs == .verbose) {
if (@errorReturnTrace()) |trace| { if (@errorReturnTrace()) |trace| {
std.debug.dumpErrorReturnTrace(trace); std.debug.dumpErrorReturnTrace(trace);
} }
}
}; };
} }
@@ -167,9 +169,12 @@ inline fn run(data: RunData) !void {
try common.interpolateVertexOutputs(data.allocator, &data.v0, &data.v1, &data.v2, b0, b1, b2), try common.interpolateVertexOutputs(data.allocator, &data.v0, &data.v1, &data.v2, b0, b1, b2),
) catch |err| { ) catch |err| {
std.log.scoped(.@"Fragment stage").err("catched a '{s}'", .{@errorName(err)}); std.log.scoped(.@"Fragment stage").err("catched a '{s}'", .{@errorName(err)});
if (comptime base.config.logs == .verbose) {
if (@errorReturnTrace()) |trace| { if (@errorReturnTrace()) |trace| {
std.debug.dumpErrorReturnTrace(trace); std.debug.dumpErrorReturnTrace(trace);
} }
}
return; return;
}; };
+2
View File
@@ -27,9 +27,11 @@ pub const RunData = struct {
pub fn runWrapper(data: RunData) void { pub fn runWrapper(data: RunData) void {
@call(.always_inline, run, .{data}) catch |err| { @call(.always_inline, run, .{data}) catch |err| {
std.log.scoped(.@"SPIR-V runtime").err("SPIR-V runtime catched a '{s}'", .{@errorName(err)}); std.log.scoped(.@"SPIR-V runtime").err("SPIR-V runtime catched a '{s}'", .{@errorName(err)});
if (comptime base.config.logs == .verbose) {
if (@errorReturnTrace()) |trace| { if (@errorReturnTrace()) |trace| {
std.debug.dumpErrorReturnTrace(trace); std.debug.dumpErrorReturnTrace(trace);
} }
}
}; };
} }
+1 -6
View File
@@ -891,12 +891,7 @@ pub export fn strollCreateGraphicsPipelines(p_device: vk.Device, p_cache: vk.Pip
// error code. The implementation will attempt to create all pipelines, and // error code. The implementation will attempt to create all pipelines, and
// only return VK_NULL_HANDLE values for those that actually failed." // only return VK_NULL_HANDLE values for those that actually failed."
p_pipeline.*, const local_res = blk: { p_pipeline.*, const local_res = blk: {
const pipeline = device.createGraphicsPipeline(allocator, cache, info) catch |err| { const pipeline = device.createGraphicsPipeline(allocator, cache, info) catch |err| break :blk .{ .null_handle, toVkResult(err) };
if (@errorReturnTrace()) |trace| {
std.debug.dumpErrorReturnTrace(trace);
}
break :blk .{ .null_handle, toVkResult(err) };
};
const handle = NonDispatchable(Pipeline).wrap(allocator, pipeline) catch |err| { const handle = NonDispatchable(Pipeline).wrap(allocator, pipeline) catch |err| {
pipeline.destroy(allocator); pipeline.destroy(allocator);
break :blk .{ .null_handle, toVkResult(err) }; break :blk .{ .null_handle, toVkResult(err) };