fixing wsi crashes
Build / build (push) Successful in 2m19s
Test / build_and_test (push) Successful in 1m54s

This commit is contained in:
2026-07-01 13:56:47 +02:00
parent 762d414d54
commit 5b182580a7
11 changed files with 118 additions and 47 deletions
+2 -1
View File
@@ -432,7 +432,8 @@ fn addMultithreadedCTS(b: *std.Build, target: std.Build.ResolvedTarget, impl: *c
}
run.addArg("run");
run.addArg("--verbose");
run.addArg("--timeout");
run.addArg("300");
run.addArg("--deqp");
run.addArg(cts_exe_path);
run.addArg("--caselist");
+2 -2
View File
@@ -32,8 +32,8 @@
// Soft dependencies
.SPIRV_Interpreter = .{
.url = "git+https://github.com/Kbz-8/SPIRV-Interpreter#18f910f38a6a9c8a00294947ac545bbffdc55477",
.hash = "SPIRV_Interpreter-0.0.1-ajmpn9wmCQAuq_IL_yvnqUJgHnWyGAtYomv0x8HjTaRh",
.url = "git+https://github.com/Kbz-8/SPIRV-Interpreter#9b6f409bffdbb9105d32d73fa3c3025134b0e7f0",
.hash = "SPIRV_Interpreter-0.0.1-ajmpn_U2CQArCKl6BQ5HxvEE9bslrF21gzZVufvTHkJe",
.lazy = true,
},
//.SPIRV_Interpreter = .{
+52 -13
View File
@@ -42,36 +42,75 @@ pub inline fn queryPeakFootprint(self: *Self) usize {
return self.peak_concurrent_bytes_allocated.load(.monotonic);
}
fn reserve(self: *Self, len: usize) bool {
while (true) {
const current = self.current_bytes_allocated.load(.monotonic);
if (len > self.bound -| current)
return false;
const new_current = current + len;
if (self.current_bytes_allocated.cmpxchgWeak(current, new_current, .monotonic, .monotonic) == null) {
_ = self.total_bytes_allocated.fetchAdd(len, .monotonic);
while (true) {
const peak = self.peak_concurrent_bytes_allocated.load(.monotonic);
if (new_current <= peak)
break;
if (self.peak_concurrent_bytes_allocated.cmpxchgWeak(peak, new_current, .monotonic, .monotonic) == null)
break;
}
return true;
}
}
}
fn release(self: *Self, len: usize) void {
while (true) {
const current = self.current_bytes_allocated.load(.monotonic);
const new_current = current -| len;
if (self.current_bytes_allocated.cmpxchgWeak(current, new_current, .monotonic, .monotonic) == null)
return;
}
}
fn alloc(context: *anyopaque, len: usize, alignment: Alignment, ret_addr: usize) ?[*]u8 {
const self: *Self = @ptrCast(@alignCast(context));
if (self.current_bytes_allocated.fetchAdd(len, .monotonic) >= self.bound)
if (!self.reserve(len))
return null;
_ = self.total_bytes_allocated.fetchAdd(len, .monotonic);
if (self.current_bytes_allocated.load(.monotonic) > self.peak_concurrent_bytes_allocated.load(.monotonic))
self.peak_concurrent_bytes_allocated.store(self.current_bytes_allocated.load(.monotonic), .monotonic);
return self.child_allocator.rawAlloc(len, alignment, ret_addr);
return self.child_allocator.rawAlloc(len, alignment, ret_addr) orelse {
self.release(len);
return null;
};
}
fn resize(context: *anyopaque, ptr: []u8, alignment: Alignment, new_len: usize, ret_addr: usize) bool {
const self: *Self = @ptrCast(@alignCast(context));
_ = self.current_bytes_allocated.fetchSub(ptr.len, .monotonic);
if (self.current_bytes_allocated.fetchAdd(new_len, .monotonic) >= self.bound)
if (new_len > ptr.len) {
const delta = new_len - ptr.len;
if (!self.reserve(delta))
return false;
_ = self.total_bytes_allocated.fetchAdd(new_len, .monotonic);
if (self.child_allocator.rawResize(ptr, alignment, new_len, ret_addr))
return true;
self.release(delta);
return false;
}
return self.child_allocator.rawResize(ptr, alignment, new_len, ret_addr);
}
fn remap(context: *anyopaque, ptr: []u8, alignment: Alignment, new_len: usize, ret_addr: usize) ?[*]u8 {
const self: *Self = @ptrCast(@alignCast(context));
_ = self.current_bytes_allocated.fetchSub(ptr.len, .monotonic);
if (self.current_bytes_allocated.fetchAdd(new_len, .monotonic) >= self.bound)
if (new_len > ptr.len) {
const delta = new_len - ptr.len;
if (!self.reserve(delta))
return null;
_ = self.total_bytes_allocated.fetchAdd(new_len, .monotonic);
return self.child_allocator.rawRemap(ptr, alignment, new_len, ret_addr);
return self.child_allocator.rawRemap(ptr, alignment, new_len, ret_addr) orelse {
self.release(delta);
return null;
};
}
return self.child_allocator.rawRemap(ptr, alignment, new_len, ret_addr) orelse null;
}
fn free(context: *anyopaque, ptr: []u8, alignment: Alignment, ret_addr: usize) void {
const self: *Self = @ptrCast(@alignCast(context));
_ = self.current_bytes_allocated.fetchSub(ptr.len, .monotonic);
self.release(ptr.len);
return self.child_allocator.rawFree(ptr, alignment, ret_addr);
}
+2 -3
View File
@@ -118,11 +118,10 @@ fn writeDescriptorSet(rt: *spv.Runtime, payload: DescriptorPayload, set: u32, bi
for (rt.mod.bindings.items) |entry| {
if (entry.set != set or entry.binding != binding)
continue;
const variable = switch (rt.results[entry.result].variant orelse continue) {
const variable = if (rt.results[entry.result].variant) |*variant| switch (variant.*) {
.Variable => |*variable| variable,
else => continue,
};
} else continue;
writeDescriptorValue(&variable.value, payload, descriptor_index) catch |err| switch (err) {
spv.Runtime.RuntimeError.InvalidValueType,
+9
View File
@@ -82,6 +82,11 @@ pub fn shaderInvocation(
SpvRuntimeError.NotFound => {},
else => return err,
};
const helper_invocation = false;
rt.writeBuiltIn(allocator, std.mem.asBytes(&helper_invocation), .HelperInvocation) catch |err| switch (err) {
SpvRuntimeError.NotFound => {},
else => return err,
};
const SoftPipeline = @import("../SoftPipeline.zig");
const previous_fragment_coord = SoftPipeline.current_fragment_coord;
@@ -157,6 +162,10 @@ pub fn shaderInvocation(
},
else => return err,
};
if (rt.helper_invocation) {
try rt.flushDescriptorSets(allocator);
return SpvRuntimeError.Killed;
}
var outputs = std.mem.zeroes([spv.SPIRV_MAX_OUTPUT_LOCATIONS][@sizeOf(zm.F32x4)]u8);
+3 -18
View File
@@ -216,22 +216,15 @@ pub fn depthTestSampleAndUpdate(
z: f32,
state: ?vk.PipelineDepthStencilStateCreateInfo,
) VkError!bool {
const depth_state = state orelse return true;
const depth_offset = targetSampleOffset(depth.*, x, y, sample_index) orelse return false;
depth.mutex.lock(io) catch return VkError.DeviceLost;
defer depth.mutex.unlock(io);
if (state) |depth_state| {
return depthTestAndUpdateAtOffset(depth, depth_offset, z, depth_state);
}
const depth_value = blitter.readFloat4(depth.base[depth_offset..], depth.format);
if (z >= depth_value[0])
return false;
blitter.writeFloat4(zm.f32x4s(z), depth.base[depth_offset..], depth.format);
return true;
}
fn depthTestAndUpdateAtOffset(depth: *RenderTargetAccess, offset: usize, z: f32, state: vk.PipelineDepthStencilStateCreateInfo) bool {
const reference = quantizeDepthForFormat(depth.format, z);
if (state.depth_bounds_test_enable == .true and
@@ -589,24 +582,16 @@ pub fn writeToTargets(
// After work depth test to avoid overwritten depth pixels during fragment invocations.
var depth_passed: ?bool = null;
if (!depth_already_applied and depth_attachment_access != null) {
if (!depth_already_applied and depth_attachment_access != null and depth_stencil_state != null) {
const depth = depth_attachment_access.?;
const depth_offset = targetSampleOffset(depth.*, x, y, sample_index) orelse continue;
depth.mutex.lock(io) catch return VkError.DeviceLost;
defer depth.mutex.unlock(io);
if (depth_stencil_state) |state| {
depth_passed = depthTestAndUpdateAtOffset(depth, depth_offset, z, state);
depth_passed = depthTestAndUpdateAtOffset(depth, depth_offset, z, depth_stencil_state.?);
if (!depth_passed.? and stencil_state == null)
continue;
} else {
const depth_value = blitter.readFloat4(depth.base[depth_offset..], depth.format);
if (z >= depth_value[0])
continue;
blitter.writeFloat4(zm.f32x4s(z), depth.base[depth_offset..], depth.format);
depth_passed = true;
}
}
if (stencil_attachment_access) |stencil| {
+12 -4
View File
@@ -164,21 +164,29 @@ pub fn getSurfaceCapabilitiesKHR(_: *Self, surface: *SurfaceKHR, capabilities: *
pub fn getSurfaceFormatsKHR(_: *Self, _: *SurfaceKHR, count: *u32, p_formats: ?[*]vk.SurfaceFormatKHR) VkError!void {
const surface_formats = SurfaceKHR.getFormats();
count.* = surface_formats.len;
if (p_formats) |formats| {
for (formats[0..], surface_formats[0..]) |*format, surface_format| {
const write_count = @min(count.*, surface_formats.len);
for (formats[0..write_count], surface_formats[0..write_count]) |*format, surface_format| {
format.* = surface_format;
}
count.* = @intCast(write_count);
if (write_count < surface_formats.len) return VkError.Incomplete;
} else {
count.* = @intCast(surface_formats.len);
}
}
pub fn getSurfacePresentModesKHR(_: *Self, _: *SurfaceKHR, count: *u32, p_modes: ?[*]vk.PresentModeKHR) VkError!void {
const surface_modes = SurfaceKHR.getPresentModes();
count.* = surface_modes.len;
if (p_modes) |modes| {
for (modes[0..], surface_modes[0..]) |*mode, surface_mode| {
const write_count = @min(count.*, surface_modes.len);
for (modes[0..write_count], surface_modes[0..write_count]) |*mode, surface_mode| {
mode.* = surface_mode;
}
count.* = @intCast(write_count);
if (write_count < surface_modes.len) return VkError.Incomplete;
} else {
count.* = @intCast(surface_modes.len);
}
}
+4
View File
@@ -149,7 +149,11 @@ pub fn presentKHR(_: *Self, info: *const vk.PresentInfoKHR) VkError!void {
}
else
cmd_err = err;
continue;
};
if (info.p_results) |results| {
results[i] = .success;
}
}
if (cmd_err) |err|
+6 -2
View File
@@ -2458,11 +2458,15 @@ pub export fn apeGetSwapchainImagesKHR(p_device: vk.Device, p_swapchain: vk.Swap
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return toVkResult(err);
const swapchain = NonDispatchable(SwapchainKHR).fromHandleObject(p_swapchain) catch |err| return toVkResult(err);
count.* = @intCast(swapchain.images.len);
if (p_images) |images| {
for (images[0..], swapchain.images[0..]) |*image, *swapchain_image| {
const write_count = @min(count.*, swapchain.images.len);
for (images[0..write_count], swapchain.images[0..write_count]) |*image, *swapchain_image| {
image.* = swapchain_image.non_dispatchable_image.toVkHandle(vk.Image);
}
count.* = @intCast(write_count);
if (write_count < swapchain.images.len) return .incomplete;
} else {
count.* = @intCast(swapchain.images.len);
}
return .success;
+1
View File
@@ -17,6 +17,7 @@ const formats = [_]vk.SurfaceFormatKHR{
};
const present_modes = [_]vk.PresentModeKHR{
.fifo_khr,
.immediate_khr,
};
+21
View File
@@ -18,7 +18,19 @@ owner: *Device,
surface: ?*SurfaceKHR,
images: []PresentImage,
fn validateImageAllocationSize(info: *const vk.SwapchainCreateInfoKHR) VkError!void {
if (info.image_extent.width == 0 or info.image_extent.height == 0 or info.image_array_layers == 0)
return VkError.OutOfDeviceMemory;
const texel_size = lib.format.texelSize(info.image_format);
var size = std.math.mul(usize, texel_size, info.image_extent.width) catch return VkError.OutOfDeviceMemory;
size = std.math.mul(usize, size, info.image_extent.height) catch return VkError.OutOfDeviceMemory;
_ = std.math.mul(usize, size, info.image_array_layers) catch return VkError.OutOfDeviceMemory;
}
pub fn create(device: *Device, allocator: std.mem.Allocator, surface: *SurfaceKHR, info: *const vk.SwapchainCreateInfoKHR) VkError!*Self {
try validateImageAllocationSize(info);
const self = allocator.create(Self) catch return VkError.OutOfHostMemory;
errdefer allocator.destroy(self);
@@ -27,6 +39,14 @@ pub fn create(device: *Device, allocator: std.mem.Allocator, surface: *SurfaceKH
allocator.free(images);
}
var initialized_image_count: usize = 0;
errdefer {
for (images[0..initialized_image_count]) |*image| {
surface.detachImage(allocator, image) catch {};
image.deinit(allocator);
}
}
for (images) |*image| {
image.* = try .init(device, allocator, &.{
.format = info.image_format,
@@ -46,6 +66,7 @@ pub fn create(device: *Device, allocator: std.mem.Allocator, surface: *SurfaceKH
.queue_family_index_count = info.queue_family_index_count,
.initial_layout = .general,
});
initialized_image_count += 1;
try surface.attachImage(allocator, image);
}