adding pipeline dynamic state and vertex output interpollation
Build / build (push) Successful in 2m40s
Test / build_and_test (push) Successful in 33m34s

This commit is contained in:
2026-04-27 19:39:49 +02:00
parent f35bce907e
commit 02bb54b841
12 changed files with 286 additions and 80 deletions
+5
View File
@@ -60,6 +60,7 @@ pub const DispatchTable = struct {
reset: *const fn (*Self, vk.CommandBufferResetFlags) VkError!void,
resetEvent: *const fn (*Self, *Event, vk.PipelineStageFlags) VkError!void,
setEvent: *const fn (*Self, *Event, vk.PipelineStageFlags) VkError!void,
setViewport: *const fn (*Self, u32, []const vk.Viewport) VkError!void,
waitEvents: *const fn (*Self, []*const Event, vk.PipelineStageFlags, vk.PipelineStageFlags, []const vk.MemoryBarrier, []const vk.BufferMemoryBarrier, []const vk.ImageMemoryBarrier) VkError!void,
};
@@ -227,6 +228,10 @@ pub inline fn setEvent(self: *Self, event: *Event, stage: vk.PipelineStageFlags)
try self.dispatch_table.setEvent(self, event, stage);
}
pub inline fn setViewport(self: *Self, first: u32, viewports: []const vk.Viewport) VkError!void {
try self.dispatch_table.setViewport(self, first, viewports);
}
pub inline fn waitEvents(self: *Self, events: []*const Event, src_stage: vk.PipelineStageFlags, dst_stage: vk.PipelineStageFlags, memory_barriers: []const vk.MemoryBarrier, buffer_barriers: []const vk.BufferMemoryBarrier, image_barriers: []const vk.ImageMemoryBarrier) VkError!void {
try self.dispatch_table.waitEvents(self, events, src_stage, dst_stage, memory_barriers, buffer_barriers, image_barriers);
}
+41 -4
View File
@@ -11,6 +11,18 @@ const PipelineCache = @import("PipelineCache.zig");
const Self = @This();
pub const ObjectType: vk.ObjectType = .pipeline;
const DynamicState = struct {
viewport: bool = false,
scissor: bool = false,
line_width: bool = false,
depth_bias: bool = false,
blend_constants: bool = false,
depth_bounds: bool = false,
stencil_compare_mask: bool = false,
stencil_write_mask: bool = false,
stencil_reference: bool = false,
};
owner: *Device,
vtable: *const VTable,
@@ -25,8 +37,8 @@ mode: union(enum) {
topology: vk.PrimitiveTopology,
},
viewport_state: struct {
viewports: []vk.Viewport,
scissor: []vk.Rect2D,
viewports: ?[]vk.Viewport,
scissor: ?[]vk.Rect2D,
},
rasterization: struct {
polygon_mode: vk.PolygonMode,
@@ -34,6 +46,7 @@ mode: union(enum) {
front_face: vk.FrontFace,
line_width: f32,
},
dynamic_state: DynamicState,
},
},
@@ -101,7 +114,7 @@ pub fn initGraphics(device: *Device, allocator: std.mem.Allocator, cache: ?*Pipe
break :blk allocator.dupe(vk.Viewport, viewports[0..viewport_state.viewport_count]) catch return VkError.OutOfHostMemory;
}
}
return VkError.ValidationFailed;
break :blk null;
},
.scissor = blk: {
if (info.p_viewport_state) |viewport_state| {
@@ -109,7 +122,7 @@ pub fn initGraphics(device: *Device, allocator: std.mem.Allocator, cache: ?*Pipe
break :blk allocator.dupe(vk.Rect2D, scissors[0..viewport_state.scissor_count]) catch return VkError.OutOfHostMemory;
}
}
return VkError.ValidationFailed;
break :blk null;
},
},
.rasterization = .{
@@ -118,6 +131,30 @@ pub fn initGraphics(device: *Device, allocator: std.mem.Allocator, cache: ?*Pipe
.front_face = if (info.p_rasterization_state) |state| state.front_face else return VkError.ValidationFailed,
.line_width = if (info.p_rasterization_state) |state| state.line_width else return VkError.ValidationFailed,
},
.dynamic_state = blk: {
var state: DynamicState = .{};
if (info.p_dynamic_state) |dynamic_state| {
if (dynamic_state.p_dynamic_states) |states| {
for (states[0..], 0..dynamic_state.dynamic_state_count) |info_state, _| {
switch (info_state) {
.viewport => state.viewport = true,
.scissor => state.scissor = true,
.line_width => state.line_width = true,
.depth_bias => state.depth_bias = true,
.blend_constants => state.blend_constants = true,
.depth_bounds => state.depth_bounds = true,
.stencil_compare_mask => state.stencil_compare_mask = true,
.stencil_write_mask => state.stencil_write_mask = true,
.stencil_reference => state.stencil_reference = true,
else => return VkError.Unknown,
}
}
}
}
break :blk state;
},
},
},
};
+7 -8
View File
@@ -856,7 +856,12 @@ pub export fn strollCreateGraphicsPipelines(p_device: vk.Device, p_cache: vk.Pip
// error code. The implementation will attempt to create all pipelines, and
// only return VK_NULL_HANDLE values for those that actually failed."
p_pipeline.*, const local_res = blk: {
const pipeline = device.createGraphicsPipeline(allocator, cache, info) catch |err| break :blk .{ .null_handle, toVkResult(err) };
const pipeline = device.createGraphicsPipeline(allocator, cache, info) catch |err| {
if (@errorReturnTrace()) |trace| {
std.debug.dumpErrorReturnTrace(trace);
}
break :blk .{ .null_handle, toVkResult(err) };
};
const handle = NonDispatchable(Pipeline).wrap(allocator, pipeline) catch |err| {
pipeline.destroy(allocator);
break :blk .{ .null_handle, toVkResult(err) };
@@ -2133,13 +2138,7 @@ pub export fn strollCmdSetViewport(p_cmd: vk.CommandBuffer, first: u32, count: u
defer entryPointEndLogTrace();
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
notImplementedWarning();
_ = cmd;
_ = first;
_ = count;
_ = viewports;
cmd.setViewport(first, viewports[0..count]) catch |err| return errorLogger(err);
}
pub export fn strollCmdUpdateBuffer(p_cmd: vk.CommandBuffer, p_buffer: vk.Buffer, offset: vk.DeviceSize, size: vk.DeviceSize, data: *const anyopaque) callconv(vk.vulkan_call_conv) void {
+10 -9
View File
@@ -55,12 +55,13 @@ pub fn log(comptime level: std.log.Level, comptime scope: @EnumLiteral(), compti
file.lock(io, .exclusive) catch {};
defer file.unlock(io);
const now = std.Io.Timestamp.now(io, .cpu_process).toMilliseconds();
const now = std.Io.Timestamp.now(io, .cpu_process).toMicroseconds();
const now_ms: u16 = @intCast(@mod(now, std.time.ms_per_s));
const now_sec: u8 = @intCast(@mod(@divTrunc(now, std.time.ms_per_s), std.time.s_per_min));
const now_min: u8 = @intCast(@mod(@divTrunc(now, std.time.ms_per_min), 60));
const now_hour: u8 = @intCast(@mod(@divTrunc(now, std.time.ms_per_hour), 24));
const now_us: u16 = @intCast(@mod(now, 1000));
const now_ms: u16 = @intCast(@mod(@divTrunc(now, 1000), std.time.ms_per_s));
const now_sec: u8 = @intCast(@mod(@divTrunc(now, std.time.us_per_s), std.time.s_per_min));
const now_min: u8 = @intCast(@mod(@divTrunc(now, std.time.us_per_min), 60));
const now_hour: u8 = @intCast(@mod(@divTrunc(now, std.time.us_per_hour), 24));
var fmt_buffer = std.mem.zeroes([4096]u8);
var fmt_writer = std.Io.Writer.fixed(&fmt_buffer);
@@ -82,15 +83,15 @@ pub fn log(comptime level: std.log.Level, comptime scope: @EnumLiteral(), compti
};
term.setColor(.magenta) catch {};
writer.print("[StrollDriver ", .{}) catch continue;
writer.writeAll("[StrollDriver") catch continue;
if (!builtin.is_test) {
term.setColor(.cyan) catch {};
writer.print(root.DRIVER_NAME, .{}) catch continue;
writer.writeAll(" " ++ root.DRIVER_NAME ++ " ") catch continue;
}
term.setColor(.yellow) catch {};
writer.print(" {d}:{d}:{d}.{d:0>3}", .{ now_hour, now_min, now_sec, now_ms }) catch continue;
writer.print("{d}:{d}:{d}.{d:0>3}.{d:0>3}", .{ now_hour, now_min, now_sec, now_ms, now_us }) catch continue;
term.setColor(.magenta) catch {};
writer.print("]", .{}) catch continue;
writer.writeAll("]") catch continue;
term.setColor(.cyan) catch {};
writer.print("[Thread {d: >8}]", .{std.Thread.getCurrentId()}) catch continue;