From 067db7a48a500e0951839221192004e1d249f59d Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Sun, 25 Jan 2026 17:57:17 +0100 Subject: [PATCH] adding base spv interpreter --- build.zig | 7 +++++++ build.zig.zon | 4 ++++ src/soft/SoftPipeline.zig | 1 + src/soft/SoftShaderModule.zig | 14 ++++++++++++++ src/soft/lib.zig | 2 ++ src/vulkan/Pipeline.zig | 20 ++++++++++++++++++-- src/vulkan/lib.zig | 2 +- 7 files changed, 47 insertions(+), 3 deletions(-) diff --git a/build.zig b/build.zig index 443d877..66ebe20 100644 --- a/build.zig +++ b/build.zig @@ -130,6 +130,13 @@ fn customSoft(b: *std.Build, lib: *std.Build.Step.Compile) !void { const cpuinfo = b.lazyDependency("cpuinfo", .{}) orelse return error.UnresolvedDependency; lib.addSystemIncludePath(cpuinfo.path("include")); lib.linkLibrary(cpuinfo.artifact("cpuinfo")); + + const spv = b.dependency("SPIRV_Interpreter", .{ + .@"no-example" = true, + .@"no-test" = true, + .@"use-llvm" = true, + }).module("spv"); + lib.root_module.addImport("spv", spv); } fn addCTest(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, vulkan_headers: *std.Build.Dependency, impl: *const ImplementationDesc, impl_lib: *std.Build.Step.Compile) !*std.Build.Step.Compile { diff --git a/build.zig.zon b/build.zig.zon index 89ed896..62a27d0 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -33,6 +33,10 @@ .url = "https://github.com/Aandreba/zigrc/archive/refs/tags/1.1.0.tar.gz", .hash = "zigrc-1.0.0-lENlWzvQAACulrbkL9PVhWjFsWSkYhi7AmfSbCM-2Xlh", }, + .SPIRV_Interpreter = .{ + .url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#e21d26d9975b96a222b70648ceeea9e473e9657f", + .hash = "SPIRV_Interpreter-0.0.1-ajmpn2tAAwCBI0oWa3VKlYX3MEM0OxN4iXQ-PwO6_Vhx", + }, .cpuinfo = .{ .url = "git+https://github.com/Kbz-8/cpuinfo#4883954cfcec3f6c9ca9c4aaddfc26107e08726f", .hash = "cpuinfo-0.0.1-RLgIQTLRMgF4dLo8AJ-HvnpFsJe6jmXCJjMWWjil6RF1", diff --git a/src/soft/SoftPipeline.zig b/src/soft/SoftPipeline.zig index 1acfb96..dcf57f9 100644 --- a/src/soft/SoftPipeline.zig +++ b/src/soft/SoftPipeline.zig @@ -1,6 +1,7 @@ const std = @import("std"); const vk = @import("vulkan"); const base = @import("base"); +const spv = @import("spv"); const VkError = base.VkError; const Device = base.Device; diff --git a/src/soft/SoftShaderModule.zig b/src/soft/SoftShaderModule.zig index 3dadf3d..4e66fce 100644 --- a/src/soft/SoftShaderModule.zig +++ b/src/soft/SoftShaderModule.zig @@ -1,6 +1,8 @@ const std = @import("std"); const vk = @import("vulkan"); const base = @import("base"); +const spv = @import("spv"); +const lib = @import("lib.zig"); const VkError = base.VkError; const Device = base.Device; @@ -9,6 +11,7 @@ const Self = @This(); pub const Interface = base.ShaderModule; interface: Interface, +module: spv.Module, pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const vk.ShaderModuleCreateInfo) VkError!*Self { const self = allocator.create(Self) catch return VkError.OutOfHostMemory; @@ -22,11 +25,22 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v self.* = .{ .interface = interface, + .module = spv.Module.init( + allocator, + info.p_code[0..@divExact(info.code_size, 4)], + .{ + .use_simd_vectors_specializations = !std.process.hasEnvVarConstant(lib.NO_SHADER_SIMD_ENV_NAME), + }, + ) catch |err| switch (err) { + spv.Module.ModuleError.OutOfMemory => return VkError.OutOfHostMemory, + else => return VkError.ValidationFailed, + }, }; return self; } pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void { const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); + self.module.deinit(allocator); allocator.destroy(self); } diff --git a/src/soft/lib.zig b/src/soft/lib.zig index d7a9afa..47eb56d 100644 --- a/src/soft/lib.zig +++ b/src/soft/lib.zig @@ -40,6 +40,8 @@ pub const VULKAN_VERSION = vk.makeApiVersion(0, 1, 0, 0); pub const DRIVER_VERSION = vk.makeApiVersion(0, 0, 0, 1); pub const DEVICE_ID = 0x600DCAFE; +pub const NO_SHADER_SIMD_ENV_NAME = "STROLL_SOFT_NO_SIMD"; + /// Generic system memory. pub const MEMORY_TYPE_GENERIC_BIT = 0; diff --git a/src/vulkan/Pipeline.zig b/src/vulkan/Pipeline.zig index fe600b6..5795ad2 100644 --- a/src/vulkan/Pipeline.zig +++ b/src/vulkan/Pipeline.zig @@ -14,6 +14,8 @@ pub const ObjectType: vk.ObjectType = .pipeline; owner: *Device, vtable: *const VTable, +bind_point: vk.PipelineBindPoint, +stages: vk.ShaderStageFlags, pub const VTable = struct { destroy: *const fn (*Self, std.mem.Allocator) void, @@ -22,20 +24,34 @@ pub const VTable = struct { pub fn initCompute(device: *Device, allocator: std.mem.Allocator, cache: ?*PipelineCache, info: *const vk.ComputePipelineCreateInfo) VkError!Self { _ = allocator; _ = cache; - _ = info; + + var stages: vk.ShaderStageFlags = .{}; + for (info.p_stages[0..info.stage_count]) |stage| { + stages = stages.merge(stage orelse continue); + } + return .{ .owner = device, .vtable = undefined, + .bind_point = .compute, + .stages = stages, }; } pub fn initGraphics(device: *Device, allocator: std.mem.Allocator, cache: ?*PipelineCache, info: *const vk.GraphicsPipelineCreateInfo) VkError!Self { _ = allocator; _ = cache; - _ = info; + + var stages: vk.ShaderStageFlags = .{}; + for (info.p_stages[0..info.stage_count]) |stage| { + stages = stages.merge(stage orelse continue); + } + return .{ .owner = device, .vtable = undefined, + .bind_point = .graphics, + .stages = stages, }; } diff --git a/src/vulkan/lib.zig b/src/vulkan/lib.zig index fdfc34a..93e13cd 100644 --- a/src/vulkan/lib.zig +++ b/src/vulkan/lib.zig @@ -51,7 +51,7 @@ pub const DRIVER_DEBUG_ALLOCATOR_ENV_NAME = "STROLL_DEBUG_ALLOCATOR"; pub const DRIVER_LOGS_ENV_NAME = "STROLL_LOGS_LEVEL"; /// Default driver name -pub const DRIVER_NAME = "Unnamed Driver"; +pub const DRIVER_NAME = "Unnamed Stroll Driver"; /// Default Vulkan version pub const VULKAN_VERSION = vk.makeApiVersion(0, 1, 0, 0);