From b9ce18ca8ee6fae5dc1ba0ce5ab386245f0bc575 Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Wed, 29 Apr 2026 23:53:27 +0200 Subject: [PATCH] implementing imulextend and umulextend --- build.zig | 10 ++++++++-- build.zig.zon | 4 ++-- src/soft/SoftPipeline.zig | 22 +++++++++++++++------- src/soft/SoftShaderModule.zig | 21 ++++++++++++++++----- src/soft/device/Renderer.zig | 2 +- src/vulkan/VulkanAllocator.zig | 5 ++++- src/vulkan/error_set.zig | 11 +++++++++++ src/vulkan/logger.zig | 4 ++-- 8 files changed, 59 insertions(+), 20 deletions(-) diff --git a/build.zig b/build.zig index 7d455ae..f9d118d 100644 --- a/build.zig +++ b/build.zig @@ -24,6 +24,12 @@ const RunningMode = enum { valgrind, }; +const LogType = enum { + none, + standard, + verbose, +}; + pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); @@ -43,10 +49,10 @@ pub fn build(b: *std.Build) !void { const zmath = b.dependency("zmath", .{}).module("root"); - const logs_option = b.option(bool, "logs", "Driver logs") orelse false; + const logs_option: LogType = b.option(LogType, "logs", "Driver logs") orelse .none; const options = b.addOptions(); - options.addOption(bool, "logs", logs_option); + options.addOption(LogType, "logs", logs_option); base_mod.addImport("zmath", zmath); base_mod.addImport("vulkan", vulkan); diff --git a/build.zig.zon b/build.zig.zon index 0ec7b31..ed06482 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -31,8 +31,8 @@ .hash = "zmath-0.11.0-dev-wjwivdMsAwD-xaLj76YHUq3t9JDH-X16xuMTmnDzqbu2", }, .SPIRV_Interpreter = .{ - .url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#046b1c8f9e9a6f61498c58fa39fde8ec3d044d58", - .hash = "SPIRV_Interpreter-0.0.1-ajmpn-blBAAmIOGIbqCR3BWWY7QDcrsdZHdse-4OBxNF", + .url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#ce172090044354d5ea70f1bf79bd077fb6722e29", + .hash = "SPIRV_Interpreter-0.0.1-ajmpn2cbBQA67LOLx5fml7Uf7iRw32jwOZh0ZIX4YJyh", .lazy = true, }, //.SPIRV_Interpreter = .{ diff --git a/src/soft/SoftPipeline.zig b/src/soft/SoftPipeline.zig index b7841aa..906b285 100644 --- a/src/soft/SoftPipeline.zig +++ b/src/soft/SoftPipeline.zig @@ -77,7 +77,7 @@ pub fn createCompute(device: *base.Device, allocator: std.mem.Allocator, cache: soft_module.ref(); shader.module = soft_module; - const runtimes = runtimes_allocator.alloc(spv.Runtime, runtimes_count) catch return VkError.OutOfHostMemory; + const runtimes = runtimes_allocator.alloc(spv.Runtime, runtimes_count) catch return VkError.OutOfDeviceMemory; for (runtimes) |*runtime| { runtime.* = spv.Runtime.init( @@ -97,18 +97,22 @@ pub fn createCompute(device: *base.Device, allocator: std.mem.Allocator, cache: if (specialization.p_map_entries) |map| { const data: []const u8 = @as([*]const u8, @ptrCast(@alignCast(specialization.p_data)))[0..specialization.data_size]; for (map[0..], 0..specialization.map_entry_count) |entry, _| { - runtime.addSpecializationInfo(runtimes_allocator, .{ - .id = @intCast(entry.constant_id), - .offset = @intCast(entry.offset), - .size = @intCast(entry.size), - }, data) catch return VkError.OutOfHostMemory; + runtime.addSpecializationInfo( + runtimes_allocator, + .{ + .id = @intCast(entry.constant_id), + .offset = @intCast(entry.offset), + .size = @intCast(entry.size), + }, + data, + ) catch return VkError.OutOfDeviceMemory; } } } } shader.runtimes = runtimes; - shader.entry = runtimes_allocator.dupe(u8, std.mem.span(info.stage.p_name)) catch return VkError.OutOfHostMemory; + shader.entry = runtimes_allocator.dupe(u8, std.mem.span(info.stage.p_name)) catch return VkError.OutOfDeviceMemory; std.log.scoped(.ComputePipeline).debug("Created {d} runtimes for compute stage", .{runtimes_count}); break :blk shader; @@ -224,6 +228,10 @@ pub fn createGraphics(device: *base.Device, allocator: std.mem.Allocator, cache: pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void { const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); + var it = self.stages.iterator(); + while (it.next()) |entry| { + entry.value.module.unref(allocator); + } self.runtimes_allocator.deinit(); allocator.destroy(self); } diff --git a/src/soft/SoftShaderModule.zig b/src/soft/SoftShaderModule.zig index ae6fd0b..f0193e9 100644 --- a/src/soft/SoftShaderModule.zig +++ b/src/soft/SoftShaderModule.zig @@ -7,11 +7,14 @@ const lib = @import("lib.zig"); const VkError = base.VkError; const Device = base.Device; +const SoftDevice = @import("SoftDevice.zig"); + const Self = @This(); pub const Interface = base.ShaderModule; interface: Interface, module: spv.Module, +module_allocator: std.heap.ArenaAllocator, /// Pipelines need SPIR-V module reference so shader module may not /// be destroy on call to `vkDestroyShaderModule` @@ -23,6 +26,13 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v var interface = try Interface.init(device, allocator, info); + const soft_device: *SoftDevice = @alignCast(@fieldParentPtr("interface", device)); + const device_allocator = soft_device.device_allocator.allocator(); + + var module_allocator_arena: std.heap.ArenaAllocator = .init(device_allocator); + errdefer module_allocator_arena.deinit(); + const module_allocator = module_allocator_arena.allocator(); + interface.vtable = &.{ .destroy = destroy, }; @@ -31,7 +41,7 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v self.* = .{ .interface = interface, - .module = spv.Module.init(allocator, code, .{ + .module = spv.Module.init(module_allocator, code, .{ .use_simd_vectors_specializations = base.config.shaders_simd, }) catch |err| switch (err) { spv.Module.ModuleError.OutOfMemory => return VkError.OutOfHostMemory, @@ -43,6 +53,7 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v return VkError.ValidationFailed; }, }, + .module_allocator = module_allocator_arena, .ref_count = std.atomic.Value(usize).init(1), }; return self; @@ -53,16 +64,16 @@ pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void { self.unref(allocator); } -pub inline fn drop(self: *Self, allocator: std.mem.Allocator) void { - self.module.deinit(allocator); +pub fn drop(self: *Self, allocator: std.mem.Allocator) void { + self.module_allocator.deinit(); allocator.destroy(self); } -pub inline fn ref(self: *Self) void { +pub fn ref(self: *Self) void { _ = self.ref_count.fetchAdd(1, .monotonic); } -pub inline fn unref(self: *Self, allocator: std.mem.Allocator) void { +pub fn unref(self: *Self, allocator: std.mem.Allocator) void { if (self.ref_count.fetchSub(1, .release) == 1) { self.drop(allocator); } diff --git a/src/soft/device/Renderer.zig b/src/soft/device/Renderer.zig index 7228ce3..92372cd 100644 --- a/src/soft/device/Renderer.zig +++ b/src/soft/device/Renderer.zig @@ -89,7 +89,7 @@ pub fn draw(self: *Self, vertex_count: usize, instance_count: usize, first_verte const allocator = arena.allocator(); const timer = std.Io.Timestamp.now(io, .real); - defer if (comptime base.config.logs) { + defer if (comptime base.config.logs != .none) { const duration = timer.untilNow(io, .real); const ms = duration.toMicroseconds(); std.log.scoped(.SoftwareRenderer).debug("Drawcall stats:\n> Took {d}us\n> Allocated {d} KB", .{ ms, @divTrunc(arena.queryCapacity(), 1000) }); diff --git a/src/vulkan/VulkanAllocator.zig b/src/vulkan/VulkanAllocator.zig index 11e3ebe..2a8c1da 100644 --- a/src/vulkan/VulkanAllocator.zig +++ b/src/vulkan/VulkanAllocator.zig @@ -62,7 +62,10 @@ fn alloc(context: *anyopaque, len: usize, alignment: Alignment, ret_addr: usize) if (self.callbacks) |callbacks| { if (callbacks.pfn_allocation) |pfn_allocation| { - return @ptrCast(pfn_allocation(self.callbacks.?.p_user_data, len, alignment.toByteUnits(), self.scope)); + const ptr: ?[*]u8 = @ptrCast(pfn_allocation(self.callbacks.?.p_user_data, len, alignment.toByteUnits(), self.scope)); + //std.debug.print("test {*}\n", .{ptr}); + //std.debug.dumpCurrentStackTrace(.{}); + return ptr; } } diff --git a/src/vulkan/error_set.zig b/src/vulkan/error_set.zig index eeb57b4..5b2beb6 100644 --- a/src/vulkan/error_set.zig +++ b/src/vulkan/error_set.zig @@ -1,5 +1,6 @@ const std = @import("std"); const vk = @import("vulkan"); +const lib = @import("lib.zig"); pub const VkError = error{ NotReady, @@ -58,10 +59,20 @@ pub const VkError = error{ pub inline fn errorLogger(err: VkError) void { std.log.scoped(.errorLogger).err("Error logger catched a '{s}'", .{@errorName(err)}); + if (comptime lib.config.logs == .verbose) { + if (@errorReturnTrace()) |trace| { + std.debug.dumpErrorReturnTrace(trace); + } + } } pub inline fn errorLoggerContext(err: VkError, context: []const u8) void { std.log.scoped(.errorLogger).err("Error logger catched a '{s}' in {s}", .{ @errorName(err), context }); + if (comptime lib.config.logs == .verbose) { + if (@errorReturnTrace()) |trace| { + std.debug.dumpErrorReturnTrace(trace); + } + } } pub inline fn toVkResult(err: VkError) vk.Result { diff --git a/src/vulkan/logger.zig b/src/vulkan/logger.zig index 022e380..0825eea 100644 --- a/src/vulkan/logger.zig +++ b/src/vulkan/logger.zig @@ -14,14 +14,14 @@ comptime { var mutex: std.Io.Mutex = .init; pub inline fn fixme(comptime format: []const u8, args: anytype) void { - if (comptime !lib.config.logs) { + if (comptime lib.config.logs == .none) { return; } std.log.scoped(.FIXME).warn("FIXME: " ++ format, args); } pub fn log(comptime level: std.log.Level, comptime scope: @EnumLiteral(), comptime format: []const u8, args: anytype) void { - if (comptime !lib.config.logs) { + if (comptime lib.config.logs == .none) { return; }