diff --git a/build.zig.zon b/build.zig.zon index 819cd40..7725ec1 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -32,8 +32,8 @@ // Soft dependencies .SPIRV_Interpreter = .{ - .url = "git+https://github.com/Kbz-8/SPIRV-Interpreter#b79282878e7bbad72ba16e8f5153a89f0e1654f6", - .hash = "SPIRV_Interpreter-0.0.1-ajmpnyMhCQBLnJw1E2Pvj0x_OqT3gCeOrpUQejWPJJAU", + .url = "git+https://github.com/Kbz-8/SPIRV-Interpreter#18f910f38a6a9c8a00294947ac545bbffdc55477", + .hash = "SPIRV_Interpreter-0.0.1-ajmpn9wmCQAuq_IL_yvnqUJgHnWyGAtYomv0x8HjTaRh", .lazy = true, }, //.SPIRV_Interpreter = .{ diff --git a/src/software/SoftPhysicalDevice.zig b/src/software/SoftPhysicalDevice.zig index d352907..e586e03 100644 --- a/src/software/SoftPhysicalDevice.zig +++ b/src/software/SoftPhysicalDevice.zig @@ -95,7 +95,7 @@ pub fn create(allocator: std.mem.Allocator, instance: *base.Instance) VkError!*S .max_vertex_input_bindings = lib.MAX_VERTEX_INPUT_BINDINGS, .max_vertex_input_attribute_offset = 2047, .max_vertex_input_binding_stride = 2048, - .max_vertex_output_components = 64, + .max_vertex_output_components = 4, .max_tessellation_generation_level = 0, .max_tessellation_patch_size = 0, .max_tessellation_control_per_vertex_input_components = 0, @@ -109,7 +109,7 @@ pub fn create(allocator: std.mem.Allocator, instance: *base.Instance) VkError!*S .max_geometry_output_components = 0, .max_geometry_output_vertices = 0, .max_geometry_total_output_components = 0, - .max_fragment_input_components = 64, + .max_fragment_input_components = 4, .max_fragment_output_attachments = 4, .max_fragment_dual_src_attachments = 0, .max_fragment_combined_output_resources = 4, diff --git a/src/software/device/rasterizer/bresenham.zig b/src/software/device/rasterizer/bresenham.zig index 4ad72b9..23fa65a 100644 --- a/src/software/device/rasterizer/bresenham.zig +++ b/src/software/device/rasterizer/bresenham.zig @@ -69,6 +69,20 @@ fn drawLineWithEndpointMode( stencil_attachment_access: ?*common.RenderTargetAccess, include_last_endpoint: bool, ) VkError!void { + if (depth_attachment_access != null) { + try drawLineBresenham( + allocator, + draw_call, + v0, + v1, + color_attachment_access, + depth_attachment_access, + stencil_attachment_access, + include_last_endpoint, + ); + return; + } + try drawLineDiamond( allocator, draw_call, @@ -81,6 +95,91 @@ fn drawLineWithEndpointMode( ); } +fn drawLineBresenham( + allocator: std.mem.Allocator, + draw_call: *Renderer.DrawCall, + v0: *Renderer.Vertex, + v1: *Renderer.Vertex, + color_attachment_access: []const ?common.RenderTargetAccess, + depth_attachment_access: ?*common.RenderTargetAccess, + stencil_attachment_access: ?*common.RenderTargetAccess, + include_last_endpoint: bool, +) VkError!void { + const io = draw_call.renderer.device.interface.io(); + + var x0: i32 = @intFromFloat(v0.position[0]); + var y0: i32 = @intFromFloat(@floor(v0.position[1] - 0.5)); + var x1: i32 = @intFromFloat(v1.position[0]); + var y1: i32 = @intFromFloat(@floor(v1.position[1] - 0.5)); + + const steep = blk: { + if (@abs(y1 - y0) > @abs(x1 - x0)) { + std.mem.swap(i32, &x0, &y0); + std.mem.swap(i32, &x1, &y1); + break :blk true; + } + break :blk false; + }; + + var start_vertex = v0; + var end_vertex = v1; + if (x0 > x1) { + std.mem.swap(i32, &x0, &x1); + std.mem.swap(i32, &y0, &y1); + std.mem.swap(*Renderer.Vertex, &start_vertex, &end_vertex); + } + + const d_err: i32 = @intCast(@abs(y1 - y0)); + const d_x = x1 - x0; + const y_step: i32 = if (y0 > y1) -1 else 1; + + const pipeline = draw_call.renderer.state.pipeline orelse return; + const fragment_stage = pipeline.stages.getPtr(.fragment); + const runtimes_count = if (fragment_stage) |stage| stage.runtimes.len else 1; + if (runtimes_count == 0) + return; + + const step_count: usize = @intCast(if (include_last_endpoint) @max(d_x, 0) + 1 else @max(d_x, 1)); + const runs_count = @min(runtimes_count, step_count); + const steps_per_run = @divTrunc(step_count + runs_count - 1, runs_count); + + var batch_id: usize = 0; + for (0..runs_count) |run_index| { + defer batch_id = @mod(batch_id + 1, runtimes_count); + + const start_step = run_index * steps_per_run; + if (start_step >= step_count) + continue; + + const end_step = @min(start_step + steps_per_run - 1, step_count - 1); + + const run_data: RunData = .{ + .allocator = allocator, + .draw_call = draw_call, + .batch_id = batch_id, + .x0 = x0, + .y0 = y0, + .d_x = d_x, + .d_err = d_err, + .y_step = y_step, + .steep = steep, + .start_vertex = start_vertex, + .end_vertex = end_vertex, + .provoking_vertex = v0, + .start_step = start_step, + .end_step = end_step, + .color_attachment_access = color_attachment_access, + .depth_attachment_access = depth_attachment_access, + .stencil_attachment_access = stencil_attachment_access, + .has_fragment_shader = fragment_stage != null, + }; + + draw_call.rasterizer_wait_group.async(io, runWrapper, .{run_data}); + } + + draw_call.rasterizer_wait_group.await(io) catch return VkError.DeviceLost; +} + fn drawLineDiamond( allocator: std.mem.Allocator, draw_call: *Renderer.DrawCall, diff --git a/src/software/device/vertex_dispatcher.zig b/src/software/device/vertex_dispatcher.zig index 20da710..a03f278 100644 --- a/src/software/device/vertex_dispatcher.zig +++ b/src/software/device/vertex_dispatcher.zig @@ -105,6 +105,7 @@ inline fn run(data: RunData) !void { rt.callEntryPoint(data.allocator, entry) catch |err| switch (err) { // Some errors can be safely ignored + SpvRuntimeError.OutOfBounds => {}, SpvRuntimeError.Killed => { try rt.flushDescriptorSets(data.allocator); return; diff --git a/src/software/lib.zig b/src/software/lib.zig index 3ab8838..243c0d2 100644 --- a/src/software/lib.zig +++ b/src/software/lib.zig @@ -65,7 +65,7 @@ pub const MIN_STORAGE_BUFFER_ALIGNMENT = 256; pub const MAX_VERTEX_INPUT_BINDINGS = 16; pub const MAX_VERTEX_INPUT_ATTRIBUTES = 16; -pub const PUSH_CONSTANT_SIZE = 256; +pub const PUSH_CONSTANT_SIZE = 128; pub const MAX_IMAGE_LEVELS_1D = 15; pub const MAX_IMAGE_LEVELS_2D = 15;