From e793cb6c3fce956637cecd6ceaa93d9cbe2ed577 Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Fri, 8 May 2026 14:23:49 +0200 Subject: [PATCH] fixing debug allocator --- .gitea/workflows/Test.yml | 14 ++------------ README.md | 15 +++++++-------- build.zig | 12 ++++++++++-- src/soft/SoftDevice.zig | 7 +++++-- src/soft/SoftPhysicalDevice.zig | 6 ++++++ src/vulkan/Instance.zig | 15 ++++++++++++++- src/vulkan/PhysicalDevice.zig | 5 +++++ src/vulkan/lib_vulkan.zig | 24 ++++++++++++++++++++++-- test/environment/Dockerfile | 2 +- 9 files changed, 72 insertions(+), 28 deletions(-) diff --git a/.gitea/workflows/Test.yml b/.gitea/workflows/Test.yml index 8a6f1ea..c913f50 100644 --- a/.gitea/workflows/Test.yml +++ b/.gitea/workflows/Test.yml @@ -61,26 +61,16 @@ jobs: which deqp-runner && deqp-runner --version || echo "deqp-runner not found" - name: Run Vulkan CTS - run: | - set +e - zig build cts-soft --release=fast -- -j1 --timeout 5 --no-progress - status=$? - echo "CTS exited with $status" - find . -name 'log.json' -o -name 'summary.csv' -o -name 'results.csv' - exit 0 + run: zig build cts-soft --release=fast -Ddebug-allocator=true -- -j1 continue-on-error: true - - name: Upload CTS runner logs if: always() uses: actions/upload-artifact@v4 with: name: cts-runner-logs path: | - **/log.json - **/summary.csv - **/results.csv - **/fails/** + cts/results.csv - name: Verify tests run: ls cts | grep "results.csv"; diff --git a/README.md b/README.md index 03c6caa..bebffc5 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Assume thou that functions lacking in this array are, for now, not intended to b Name | Status -------------------------------------------------|-------- -vkAcquireNextImageKHR | ⚙️ WIP +vkAcquireNextImageKHR | ✅ Implemented vkAllocateCommandBuffers | ✅ Implemented vkAllocateDescriptorSets | ✅ Implemented vkAllocateMemory | ✅ Implemented @@ -138,14 +138,13 @@ vkDestroySampler | ✅ Implemented vkDestroySemaphore | ✅ Implemented vkDestroyShaderModule | ✅ Implemented vkDestroySurfaceKHR | ✅ Implemented -vkDestroySwapchainKHR | ⚙️ WIP vkDestroySwapchainKHR | ✅ Implemented vkDeviceWaitIdle | ✅ Implemented vkEndCommandBuffer | ✅ Implemented -vkEnumerateDeviceExtensionProperties | ⚙️ WIP -vkEnumerateDeviceLayerProperties | ⚙️ WIP -vkEnumerateInstanceExtensionProperties | ⚙️ WIP -vkEnumerateInstanceLayerProperties | ⚙️ WIP +vkEnumerateDeviceExtensionProperties | ✅ Implemented +vkEnumerateDeviceLayerProperties | ✅ Implemented +vkEnumerateInstanceExtensionProperties | ✅ Implemented +vkEnumerateInstanceLayerProperties | ✅ Implemented vkEnumeratePhysicalDevices | ✅ Implemented vkFlushMappedMemoryRanges | ✅ Implemented vkFreeCommandBuffers | ✅ Implemented @@ -172,14 +171,14 @@ vkGetPhysicalDeviceSurfaceCapabilitiesKHR | ✅ Implemented vkGetPhysicalDeviceSurfaceFormatsKHR | ✅ Implemented vkGetPhysicalDeviceSurfacePresentModesKHR | ✅ Implemented vkGetPhysicalDeviceSurfaceSupportKHR | ✅ Implemented -vkGetPhysicalDeviceWaylandPresentationSupportKHR | ⚙️ WIP +vkGetPhysicalDeviceWaylandPresentationSupportKHR | ✅ Implemented vkGetPhysicalDeviceWin32PresentationSupportKHR | ⚙️ WIP vkGetPhysicalDeviceXcbPresentationSupportKHR | ⚙️ WIP vkGetPhysicalDeviceXlibPresentationSupportKHR | ⚙️ WIP vkGetPipelineCacheData | ⚙️ WIP vkGetQueryPoolResults | ⚙️ WIP vkGetRenderAreaGranularity | ⚙️ WIP -vkGetSwapchainImagesKHR | ⚙️ WIP +vkGetSwapchainImagesKHR | ✅ Implemented vkInvalidateMappedMemoryRanges | ✅ Implemented vkMapMemory | ✅ Implemented vkMergePipelineCaches | ⚙️ WIP diff --git a/build.zig b/build.zig index 810ba5c..1a076b0 100644 --- a/build.zig +++ b/build.zig @@ -310,7 +310,15 @@ fn addMultithreadedCTS(b: *std.Build, target: std.Build.ResolvedTarget, impl: *c } } - const mustpass_path = try cts.path("vk-default.txt").getPath3(b, null).toString(b.allocator); + var caselist_file_path: []const u8 = try cts.path("vk-default.txt").getPath3(b, null).toString(b.allocator); + if (b.args) |args| { + for (args) |arg| { + if (std.mem.startsWith(u8, arg, "--deqp-caselist-file")) { + caselist_file_path = arg["--deqp-caselist-file=".len..]; + } + } + } + const cts_exe_path = try cts_exe_name.getPath3(b, null).toString(b.allocator); const run = b.addSystemCommand(&[_][]const u8{"deqp-runner"}); @@ -320,7 +328,7 @@ fn addMultithreadedCTS(b: *std.Build, target: std.Build.ResolvedTarget, impl: *c run.addArg("--deqp"); run.addArg(cts_exe_path); run.addArg("--caselist"); - run.addArg(mustpass_path); + run.addArg(caselist_file_path); run.addArg("--output"); run.addArg("./cts"); if (jobs_count) |count| { diff --git a/src/soft/SoftDevice.zig b/src/soft/SoftDevice.zig index 22360bb..0f7dabb 100644 --- a/src/soft/SoftDevice.zig +++ b/src/soft/SoftDevice.zig @@ -93,9 +93,12 @@ pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) VkError!void if (config.debug_allocator) { // All device memory allocations should've been freed by now - if (!self.device_allocator.detectLeaks()) { + const leaks = self.device_allocator.detectLeaks(); + if (leaks != 0) + std.log.scoped(.vkDestroyDevice).err("Device was destroyed leaking {d}KB", .{@divTrunc(leaks, 1000)}) + else std.log.scoped(.vkDestroyDevice).debug("No device memory leaks detected", .{}); - } + self.device_allocator.deinitWithoutLeakChecks(); } allocator.destroy(self); diff --git a/src/soft/SoftPhysicalDevice.zig b/src/soft/SoftPhysicalDevice.zig index 3df5eb4..f8004d4 100644 --- a/src/soft/SoftPhysicalDevice.zig +++ b/src/soft/SoftPhysicalDevice.zig @@ -44,6 +44,7 @@ pub fn create(allocator: std.mem.Allocator, instance: *base.Instance) VkError!*S .getFormatProperties = getFormatProperties, .getImageFormatProperties = getImageFormatProperties, .getSparseImageFormatProperties = getSparseImageFormatProperties, + .enumerateLayerProperties = enumerateLayerProperties, .enumerateExtensionProperties = enumerateExtensionProperties, .release = destroy, @@ -248,6 +249,11 @@ pub fn createDevice(interface: *Interface, allocator: std.mem.Allocator, infos: return &device.interface; } +pub fn enumerateLayerProperties(_: *const Interface, count: *u32, p_properties: ?[*]vk.LayerProperties) VkError!void { + count.* = 0; + _ = p_properties; +} + pub fn enumerateExtensionProperties(_: *const Interface, layer_name: ?[]const u8, count: *u32, p_properties: ?[*]vk.ExtensionProperties) VkError!void { if (layer_name) |_| { return VkError.LayerNotPresent; diff --git a/src/vulkan/Instance.zig b/src/vulkan/Instance.zig index 37466d3..192c3a4 100644 --- a/src/vulkan/Instance.zig +++ b/src/vulkan/Instance.zig @@ -50,7 +50,7 @@ pub fn init(allocator: std.mem.Allocator, infos: *const vk.InstanceCreateInfo) V }; } -/// Dummy for docs creation and stuff +/// Dummy to avoid compile error in tests and doc generation pub fn create(allocator: std.mem.Allocator, infos: *const vk.InstanceCreateInfo) VkError!*Self { _ = allocator; _ = infos; @@ -62,6 +62,19 @@ pub fn deinit(self: *Self, allocator: std.mem.Allocator) VkError!void { try self.dispatch_table.destroy(self, allocator); } +pub fn enumerateLayerProperties(count: *u32, p_properties: ?[*]vk.LayerProperties) VkError!void { + if (comptime !builtin.is_test and @hasDecl(root.Instance, "LAYERS")) { + count.* = root.Instance.LAYERS.len; + if (p_properties) |properties| { + for (root.Instance.LAYERS, properties[0..]) |layer, *prop| { + prop.* = layer; + } + } + } else { + count.* = 0; + } +} + pub fn enumerateExtensionProperties(layer_name: ?[]const u8, count: *u32, p_properties: ?[*]vk.ExtensionProperties) VkError!void { if (layer_name) |_| { return VkError.LayerNotPresent; diff --git a/src/vulkan/PhysicalDevice.zig b/src/vulkan/PhysicalDevice.zig index 5cdf0d3..21aeab3 100644 --- a/src/vulkan/PhysicalDevice.zig +++ b/src/vulkan/PhysicalDevice.zig @@ -23,6 +23,7 @@ pub const DispatchTable = struct { getImageFormatProperties: *const fn (*Self, vk.Format, vk.ImageType, vk.ImageTiling, vk.ImageUsageFlags, vk.ImageCreateFlags) VkError!vk.ImageFormatProperties, getSparseImageFormatProperties: *const fn (*Self, vk.Format, vk.ImageType, vk.SampleCountFlags, vk.ImageTiling, vk.ImageUsageFlags, ?[*]vk.SparseImageFormatProperties) VkError!u32, enumerateExtensionProperties: *const fn (*const Self, ?[]const u8, *u32, ?[*]vk.ExtensionProperties) VkError!void, + enumerateLayerProperties: *const fn (*const Self, *u32, ?[*]vk.LayerProperties) VkError!void, release: *const fn (*Self, std.mem.Allocator) VkError!void, // VK_KHR_get_physical_device_properties_2 @@ -71,6 +72,10 @@ pub inline fn enumerateExtensionProperties(self: *const Self, layer_name: ?[]con return try self.dispatch_table.enumerateExtensionProperties(self, layer_name, count, p_properties); } +pub inline fn enumerateLayerProperties(self: *const Self, count: *u32, p_properties: ?[*]vk.LayerProperties) VkError!void { + return try self.dispatch_table.enumerateLayerProperties(self, count, p_properties); +} + pub inline fn getImageFormatProperties( self: *Self, format: vk.Format, diff --git a/src/vulkan/lib_vulkan.zig b/src/vulkan/lib_vulkan.zig index e0d751a..177e5cc 100644 --- a/src/vulkan/lib_vulkan.zig +++ b/src/vulkan/lib_vulkan.zig @@ -48,11 +48,11 @@ pub const SurfaceKHR = @import("wsi/SurfaceKHR.zig"); pub const SwapchainKHR = @import("wsi/SwapchainKHR.zig"); pub const WaylandSurfaceKHR = @import("wsi/WaylandSurfaceKHR.zig"); -fn entryPointBeginLogTrace(comptime scope: @EnumLiteral()) void { +inline fn entryPointBeginLogTrace(comptime scope: @EnumLiteral()) void { std.log.scoped(scope).debug("Calling {s}...", .{@tagName(scope)}); } -fn entryPointEndLogTrace() void {} +inline fn entryPointEndLogTrace() void {} inline fn notImplementedWarning() void { logger.fixme("function not yet implemented", .{}); @@ -79,6 +79,7 @@ const icd_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{ const global_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{ functionMapEntryPoint("vkCreateInstance"), functionMapEntryPoint("vkEnumerateInstanceExtensionProperties"), + functionMapEntryPoint("vkEnumerateInstanceLayerProperties"), //functionMapEntryPoint("vkEnumerateInstanceVersion"), functionMapEntryPoint("vkGetInstanceProcAddr"), }); @@ -94,6 +95,7 @@ const instance_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{ const physical_device_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{ functionMapEntryPoint("vkCreateDevice"), functionMapEntryPoint("vkEnumerateDeviceExtensionProperties"), + functionMapEntryPoint("vkEnumerateDeviceLayerProperties"), functionMapEntryPoint("vkGetPhysicalDeviceFeatures"), functionMapEntryPoint("vkGetPhysicalDeviceFeatures2KHR"), functionMapEntryPoint("vkGetPhysicalDeviceFormatProperties"), @@ -316,6 +318,14 @@ pub export fn strollCreateInstance(info: *const vk.InstanceCreateInfo, callbacks return .success; } +pub export fn strollEnumerateInstanceLayerProperties(property_count: *u32, properties: ?[*]vk.LayerProperties) callconv(vk.vulkan_call_conv) vk.Result { + entryPointBeginLogTrace(.vkEnumerateInstanceLayerProperties); + defer entryPointEndLogTrace(); + + Instance.enumerateLayerProperties(property_count, properties) catch |err| return toVkResult(err); + return .success; +} + pub export fn strollEnumerateInstanceExtensionProperties(p_layer_name: ?[*:0]const u8, property_count: *u32, properties: ?[*]vk.ExtensionProperties) callconv(vk.vulkan_call_conv) vk.Result { entryPointBeginLogTrace(.vkEnumerateInstanceExtensionProperties); defer entryPointEndLogTrace(); @@ -328,6 +338,7 @@ pub export fn strollEnumerateInstanceExtensionProperties(p_layer_name: ?[*:0]con return .success; } +/// Do not make it available to GetProcAddr until Vulkan 1.1 is implemented pub export fn strollEnumerateInstanceVersion(version: *u32) callconv(vk.vulkan_call_conv) vk.Result { entryPointBeginLogTrace(.vkEnumerateInstanceVersion); defer entryPointEndLogTrace(); @@ -382,6 +393,15 @@ pub export fn strollCreateDevice(p_physical_device: vk.PhysicalDevice, info: *co return .success; } +pub export fn strollEnumerateDeviceLayerProperties(p_physical_device: vk.PhysicalDevice, property_count: *u32, properties: ?[*]vk.LayerProperties) callconv(vk.vulkan_call_conv) vk.Result { + entryPointBeginLogTrace(.vkEnumerateDeviceLayerProperties); + defer entryPointEndLogTrace(); + + const physical_device = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch |err| return toVkResult(err); + physical_device.enumerateLayerProperties(property_count, properties) catch |err| return toVkResult(err); + return .success; +} + pub export fn strollEnumerateDeviceExtensionProperties(p_physical_device: vk.PhysicalDevice, p_layer_name: ?[*:0]const u8, property_count: *u32, properties: ?[*]vk.ExtensionProperties) callconv(vk.vulkan_call_conv) vk.Result { entryPointBeginLogTrace(.vkEnumerateDeviceExtensionProperties); defer entryPointEndLogTrace(); diff --git a/test/environment/Dockerfile b/test/environment/Dockerfile index 26f8af3..29f2878 100644 --- a/test/environment/Dockerfile +++ b/test/environment/Dockerfile @@ -2,7 +2,7 @@ FROM ubuntu:latest WORKDIR /root -RUN apt update && apt install -y git rustup clang curl libgl1 libsm6 libwayland-egl1 libwayland-cursor0 libwayland-server0; +RUN apt update && apt install -y git rustup clang curl libgl1 libsm6 libwayland-egl1 libwayland-cursor0 libwayland-server0 vim; RUN rustup default stable; RUN cargo install deqp-runner && cp $HOME/.cargo/bin/deqp-runner /usr/bin; RUN curl -L https://github.com/marler8997/anyzig/releases/latest/download/anyzig-x86_64-linux.tar.gz | tar xz && mv zig /usr/bin/;