fixing wsi crashes
This commit is contained in:
@@ -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
@@ -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 = .{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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| {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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|
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -17,6 +17,7 @@ const formats = [_]vk.SurfaceFormatKHR{
|
||||
};
|
||||
|
||||
const present_modes = [_]vk.PresentModeKHR{
|
||||
.fifo_khr,
|
||||
.immediate_khr,
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user