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
+53 -14
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;
if (self.child_allocator.rawResize(ptr, alignment, new_len, ret_addr))
return true;
self.release(delta);
return false;
_ = self.total_bytes_allocated.fetchAdd(new_len, .monotonic);
}
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)
return null;
_ = self.total_bytes_allocated.fetchAdd(new_len, .monotonic);
return self.child_allocator.rawRemap(ptr, alignment, new_len, ret_addr);
if (new_len > ptr.len) {
const delta = new_len - ptr.len;
if (!self.reserve(delta))
return null;
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);
+6 -21
View File
@@ -216,20 +216,13 @@ 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;
return depthTestAndUpdateAtOffset(depth, depth_offset, z, depth_state);
}
fn depthTestAndUpdateAtOffset(depth: *RenderTargetAccess, offset: usize, z: f32, state: vk.PipelineDepthStencilStateCreateInfo) bool {
@@ -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);
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;
}
depth_passed = depthTestAndUpdateAtOffset(depth, depth_offset, z, depth_stencil_state.?);
if (!depth_passed.? and stencil_state == null)
continue;
}
if (stencil_attachment_access) |stencil| {