adding some opcodes
Some checks failed
Build / build (push) Has been cancelled
Test / build_and_test (push) Has been cancelled

This commit is contained in:
2026-03-11 01:28:33 +01:00
parent ffa1f56089
commit 857e877f33
7 changed files with 110 additions and 50 deletions

View File

@@ -59,8 +59,9 @@
.lazy = true, .lazy = true,
}, },
.SPIRV_Interpreter = .{ .SPIRV_Interpreter = .{
.url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#ad013d23fcf287d7354a05251ad0140f5fb883f7", //.url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#1a48af468d345d8786cbb9b7d9f308f8832cbcd0",
.hash = "SPIRV_Interpreter-0.0.1-ajmpnwSPAwD5VW4PJc1fUX0Q7niFovZyIHfhM7jZ2kkB", //.hash = "SPIRV_Interpreter-0.0.1-ajmpn8CQAwD6-6jsLx5nODWFc4lAUvVTuZVVHop1X3-m",
.path = "../SPIRV-Interpreter",
}, },
}, },

View File

@@ -71,18 +71,24 @@ pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void {
allocator.destroy(self); allocator.destroy(self);
} }
pub fn execute(self: *Self, device: *ExecutionDevice) VkError!void { pub fn execute(self: *Self, device: *ExecutionDevice) void {
self.interface.submit() catch return; self.interface.submit() catch return;
defer self.interface.finish() catch {}; defer self.interface.finish() catch {};
for (self.commands.items) |command| { for (self.commands.items) |command| {
try command.vtable.execute(command.ptr, device); command.vtable.execute(command.ptr, device) catch |err| {
base.errors.errorLoggerContext(err, "the software execution device");
if (@errorReturnTrace()) |trace| {
std.debug.dumpStackTrace(trace.*);
}
return; // Should we return or continue ? Maybe device lost ?
};
} }
} }
pub fn begin(interface: *Interface, _: *const vk.CommandBufferBeginInfo) VkError!void { pub fn begin(interface: *Interface, _: *const vk.CommandBufferBeginInfo) VkError!void {
const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); // No-op
_ = self.command_allocator.reset(.free_all); _ = interface;
} }
pub fn end(interface: *Interface) VkError!void { pub fn end(interface: *Interface) VkError!void {

View File

@@ -13,17 +13,22 @@ const NonDispatchable = base.NonDispatchable;
const Self = @This(); const Self = @This();
pub const Interface = base.DescriptorSet; pub const Interface = base.DescriptorSet;
const Descriptor = union(enum) { const DescriptorBuffer = struct {
buffer: struct {
object: ?*SoftBuffer, object: ?*SoftBuffer,
offset: vk.DeviceSize, offset: vk.DeviceSize,
size: vk.DeviceSize, size: vk.DeviceSize,
}, };
const Descriptor = union(enum) {
buffer: []DescriptorBuffer,
image: struct {}, image: struct {},
}; };
interface: Interface, interface: Interface,
/// Memory containing actual binding descriptors and their array
heap: []u8,
descriptors: []Descriptor, descriptors: []Descriptor,
pub fn create(device: *base.Device, allocator: std.mem.Allocator, layout: *base.DescriptorSetLayout) VkError!*Self { pub fn create(device: *base.Device, allocator: std.mem.Allocator, layout: *base.DescriptorSetLayout) VkError!*Self {
@@ -38,11 +43,38 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, layout: *base.
.write = write, .write = write,
}; };
const descriptors = allocator.alloc(Descriptor, layout.bindings.len) catch return VkError.OutOfHostMemory; const heap_size = blk: {
errdefer allocator.free(descriptors); var size: usize = layout.bindings.len * @sizeOf(Descriptor);
for (layout.bindings) |binding| {
const struct_size: usize = switch (binding.descriptor_type) {
.storage_buffer, .storage_buffer_dynamic => @sizeOf(DescriptorBuffer),
else => 0,
};
size += binding.array_size * struct_size;
}
break :blk size;
};
const heap = allocator.alloc(u8, heap_size) catch return VkError.OutOfHostMemory;
errdefer allocator.free(heap);
var local_heap = std.heap.FixedBufferAllocator.init(heap);
const local_allocator = local_heap.allocator();
const descriptors = local_allocator.alloc(Descriptor, layout.bindings.len) catch return VkError.OutOfHostMemory;
for (descriptors, layout.bindings) |*descriptor, binding| {
switch (binding.descriptor_type) {
.storage_buffer, .storage_buffer_dynamic => descriptor.* = .{
.buffer = local_allocator.alloc(DescriptorBuffer, binding.array_size) catch return VkError.OutOfHostMemory,
},
else => {},
}
}
self.* = .{ self.* = .{
.interface = interface, .interface = interface,
.heap = heap,
.descriptors = descriptors, .descriptors = descriptors,
}; };
return self; return self;
@@ -56,7 +88,7 @@ pub fn copy(interface: *Interface, copy_data: vk.CopyDescriptorSet) VkError!void
pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void { pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void {
const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
allocator.free(self.descriptors); allocator.free(self.heap);
allocator.destroy(self); allocator.destroy(self);
} }
@@ -66,19 +98,17 @@ pub fn write(interface: *Interface, write_data: vk.WriteDescriptorSet) VkError!v
switch (write_data.descriptor_type) { switch (write_data.descriptor_type) {
.storage_buffer, .storage_buffer_dynamic => { .storage_buffer, .storage_buffer_dynamic => {
for (write_data.p_buffer_info, 0..write_data.descriptor_count) |buffer_info, i| { for (write_data.p_buffer_info, 0..write_data.descriptor_count) |buffer_info, i| {
const desc = &self.descriptors[write_data.dst_binding + i]; const desc = &self.descriptors[write_data.dst_binding].buffer[i];
desc.* = .{ desc.* = .{
.buffer = .{
.object = null, .object = null,
.offset = buffer_info.offset, .offset = buffer_info.offset,
.size = buffer_info.range, .size = buffer_info.range,
},
}; };
if (buffer_info.buffer != .null_handle) { if (buffer_info.buffer != .null_handle) {
const buffer = try NonDispatchable(Buffer).fromHandleObject(buffer_info.buffer); const buffer = try NonDispatchable(Buffer).fromHandleObject(buffer_info.buffer);
desc.buffer.object = @as(*SoftBuffer, @alignCast(@fieldParentPtr("interface", buffer))); desc.object = @as(*SoftBuffer, @alignCast(@fieldParentPtr("interface", buffer)));
if (desc.buffer.size == vk.WHOLE_SIZE) { if (desc.size == vk.WHOLE_SIZE) {
desc.buffer.size = if (buffer.memory) |memory| memory.size - desc.buffer.offset else return VkError.InvalidDeviceMemoryDrv; desc.size = if (buffer.memory) |memory| memory.size - desc.offset else return VkError.InvalidDeviceMemoryDrv;
} }
} }
} }

View File

@@ -104,12 +104,7 @@ fn taskRunner(self: *Self, info: Interface.SubmitInfo, p_fence: ?*base.Fence, ru
for (info.command_buffers.items) |command_buffer| { for (info.command_buffers.items) |command_buffer| {
const soft_command_buffer: *SoftCommandBuffer = @alignCast(@fieldParentPtr("interface", command_buffer)); const soft_command_buffer: *SoftCommandBuffer = @alignCast(@fieldParentPtr("interface", command_buffer));
soft_command_buffer.execute(&execution_device) catch |err| { soft_command_buffer.execute(&execution_device);
base.errors.errorLoggerContext(err, "the software execution device");
if (@errorReturnTrace()) |trace| {
std.debug.dumpStackTrace(trace.*);
}
};
} }
if (p_fence) |fence| { if (p_fence) |fence| {

View File

@@ -35,7 +35,13 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v
.use_simd_vectors_specializations = !std.process.hasEnvVarConstant(lib.NO_SHADER_SIMD_ENV_NAME), .use_simd_vectors_specializations = !std.process.hasEnvVarConstant(lib.NO_SHADER_SIMD_ENV_NAME),
}) catch |err| switch (err) { }) catch |err| switch (err) {
spv.Module.ModuleError.OutOfMemory => return VkError.OutOfHostMemory, spv.Module.ModuleError.OutOfMemory => return VkError.OutOfHostMemory,
else => return VkError.ValidationFailed, else => {
std.log.scoped(.@"SPIR-V module").err("module creation catched a '{s}'", .{@errorName(err)});
if (@errorReturnTrace()) |trace| {
std.debug.dumpStackTrace(trace.*);
}
return VkError.ValidationFailed;
},
}, },
.ref_count = std.atomic.Value(usize).init(1), .ref_count = std.atomic.Value(usize).init(1),
}; };

View File

@@ -2,6 +2,7 @@ const std = @import("std");
const vk = @import("vulkan"); const vk = @import("vulkan");
const base = @import("base"); const base = @import("base");
const spv = @import("spv"); const spv = @import("spv");
const lib = @import("../lib.zig");
const PipelineState = @import("PipelineState.zig"); const PipelineState = @import("PipelineState.zig");
@@ -52,6 +53,22 @@ pub fn dispatch(self: *Self, group_count_x: u32, group_count_y: u32, group_count
var wg: std.Thread.WaitGroup = .{}; var wg: std.Thread.WaitGroup = .{};
for (0..@min(self.batch_size, group_count)) |batch_id| { for (0..@min(self.batch_size, group_count)) |batch_id| {
if (std.process.hasEnvVarConstant(lib.SINGLE_THREAD_COMPUTE_EXECUTION_ENV_NAME)) {
@branchHint(.cold); // Should only be reached for debugging
runWrapper(
RunData{
.self = self,
.batch_id = batch_id,
.group_count = group_count,
.group_count_x = @as(usize, @intCast(group_count_x)),
.group_count_y = @as(usize, @intCast(group_count_y)),
.group_count_z = @as(usize, @intCast(group_count_z)),
.invocations_per_workgroup = invocations_per_workgroup,
.pipeline = pipeline,
},
);
} else {
self.device.workers.spawnWg(&wg, runWrapper, .{ self.device.workers.spawnWg(&wg, runWrapper, .{
RunData{ RunData{
.self = self, .self = self,
@@ -65,6 +82,7 @@ pub fn dispatch(self: *Self, group_count_x: u32, group_count_y: u32, group_count
}, },
}); });
} }
}
self.device.workers.waitAndWork(&wg); self.device.workers.waitAndWork(&wg);
} }
@@ -135,14 +153,17 @@ fn writeDescriptorSets(self: *Self, rt: *spv.Runtime) !void {
bindings: for (set.?.descriptors[0..], 0..) |binding, binding_index| { bindings: for (set.?.descriptors[0..], 0..) |binding, binding_index| {
switch (binding) { switch (binding) {
.buffer => |buffer_data| if (buffer_data.object) |buffer| { .buffer => |buffer_data_array| for (buffer_data_array, 0..) |buffer_data, descriptor_index| {
if (buffer_data.object) |buffer| {
const memory = if (buffer.interface.memory) |memory| memory else continue :bindings; const memory = if (buffer.interface.memory) |memory| memory else continue :bindings;
const map: []u8 = @as([*]u8, @ptrCast(try memory.map(buffer_data.offset, buffer_data.size)))[0..buffer_data.size]; const map: []u8 = @as([*]u8, @ptrCast(try memory.map(buffer_data.offset, buffer_data.size)))[0..buffer_data.size];
try rt.writeDescriptorSet( try rt.writeDescriptorSet(
map, map,
@as(u32, @intCast(set_index)), @as(u32, @intCast(set_index)),
@as(u32, @intCast(binding_index)), @as(u32, @intCast(binding_index)),
@as(u32, @intCast(descriptor_index)),
); );
}
}, },
else => {}, else => {},
} }

View File

@@ -41,6 +41,7 @@ pub const DRIVER_VERSION = vk.makeApiVersion(0, 0, 0, 1);
pub const DEVICE_ID = 0x600DCAFE; pub const DEVICE_ID = 0x600DCAFE;
pub const NO_SHADER_SIMD_ENV_NAME = "STROLL_SOFT_NO_SIMD"; pub const NO_SHADER_SIMD_ENV_NAME = "STROLL_SOFT_NO_SIMD";
pub const SINGLE_THREAD_COMPUTE_EXECUTION_ENV_NAME = "STROLL_SINGLE_THREAD_COMPUTE_EXECUTION";
/// Generic system memory. /// Generic system memory.
pub const MEMORY_TYPE_GENERIC_BIT = 0; pub const MEMORY_TYPE_GENERIC_BIT = 0;