diff --git a/build.zig.zon b/build.zig.zon index 2084a29..7375b8c 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -31,8 +31,8 @@ .lazy = true, }, .SPIRV_Interpreter = .{ - .url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#dc80a6a3484667058194dc0540c2a15ba76ce2d9", - .hash = "SPIRV_Interpreter-0.0.1-ajmpnwNEBQA6scXu7V71PS-UV6wZtRut9vDh3PxrtW53", + .url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#236c6496ff567083ecd8084c792f02886b9c501a", + .hash = "SPIRV_Interpreter-0.0.1-ajmpn8pFBQCz_zQmSQ3OY_qRDfAanQDtvoNKTxxEEvpH", .lazy = true, }, //.SPIRV_Interpreter = .{ diff --git a/src/soft/SoftDescriptorSet.zig b/src/soft/SoftDescriptorSet.zig index 94e2e78..58fad72 100644 --- a/src/soft/SoftDescriptorSet.zig +++ b/src/soft/SoftDescriptorSet.zig @@ -98,18 +98,28 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, layout: *base. return self; } -pub fn copy(interface: *Interface, copy_data: vk.CopyDescriptorSet) VkError!void { - const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); - _ = self; - _ = copy_data; -} - pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void { const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); allocator.free(self.heap); allocator.destroy(self); } +pub fn copy(interface: *Interface, src_interface: *const Interface, data: vk.CopyDescriptorSet) VkError!void { + const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); + const src: *const Self = @alignCast(@fieldParentPtr("interface", src_interface)); + + for (self.descriptors[data.dst_binding..(data.dst_binding + data.descriptor_count)], src.descriptors[data.src_binding..(data.src_binding + data.descriptor_count)]) |*dst_desc, src_desc| { + switch (dst_desc.*) { + .buffer => |dst_buffer| @memcpy(dst_buffer[0..], src_desc.buffer[0..]), + .image => |dst_image| @memcpy(dst_image[0..], src_desc.image[0..]), + else => { + dst_desc.* = .{ .unsupported = .{} }; + base.unsupported("descriptor type for copy", .{}); + }, + } + } +} + pub fn write(interface: *Interface, write_data: vk.WriteDescriptorSet) VkError!void { const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); diff --git a/src/soft/device/ComputeDispatcher.zig b/src/soft/device/ComputeDispatcher.zig index 78efb99..bc117ba 100644 --- a/src/soft/device/ComputeDispatcher.zig +++ b/src/soft/device/ComputeDispatcher.zig @@ -174,8 +174,7 @@ fn writeDescriptorSets(self: *Self, rt: *spv.Runtime) !void { switch (binding) { .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 map: []u8 = @as([*]u8, @ptrCast(try memory.map(buffer_data.offset, buffer_data.size)))[0..buffer_data.size]; + const map = buffer.mapAsSliceWithOffset(u8, buffer_data.offset, buffer_data.size) catch continue :bindings; try rt.writeDescriptorSet( map, @as(u32, @intCast(set_index)), diff --git a/src/soft/device/Renderer.zig b/src/soft/device/Renderer.zig index 1d42d47..f6a95bc 100644 --- a/src/soft/device/Renderer.zig +++ b/src/soft/device/Renderer.zig @@ -179,6 +179,16 @@ fn drawCall(self: *Self, bounded_allocator: *BoundedAllocator, vertex_count: usi logger.debug(fmt, args); }; + const pipeline = self.state.pipeline orelse return VkError.InvalidPipelineDrv; + const vertex_shader = pipeline.stages.getPtrAssertContains(.vertex); + for (vertex_shader.runtimes[0..]) |*runtime| { + writeDescriptorSets(&draw_call, &runtime.rt) catch return VkError.Unknown; + } + const fragment_shader = pipeline.stages.getPtrAssertContains(.fragment); + for (fragment_shader.runtimes[0..]) |*runtime| { + writeDescriptorSets(&draw_call, &runtime.rt) catch return VkError.Unknown; + } + self.vertexShaderStage(allocator, &draw_call, vertex_count, instance_count, first_vertex, first_instance, indices) catch |err| { std.log.scoped(.@"Vertex stage").err("catched a '{s}'", .{@errorName(err)}); if (@errorReturnTrace()) |trace| { @@ -297,3 +307,38 @@ fn resolveScissor(self: *Self, scissor_index: usize) VkError!vk.Rect2D { return VkError.Unknown; } + +fn writeDescriptorSets(draw_call: *DrawCall, rt: *spv.Runtime) !void { + sets: for (draw_call.renderer.state.sets[0..], 0..) |set, set_index| { + if (set == null) + continue :sets; + + bindings: for (set.?.descriptors[0..], 0..) |binding, binding_index| { + switch (binding) { + .buffer => |buffer_data_array| for (buffer_data_array, 0..) |buffer_data, descriptor_index| { + if (buffer_data.object) |buffer| { + const map = buffer.mapAsSliceWithOffset(u8, buffer_data.offset, buffer_data.size) catch continue :bindings; + try rt.writeDescriptorSet( + map, + @as(u32, @intCast(set_index)), + @as(u32, @intCast(binding_index)), + @as(u32, @intCast(descriptor_index)), + ); + } + }, + .image => |image_data_array| for (image_data_array, 0..) |image_data, descriptor_index| { + if (image_data.object) |image_view| { + const addr: usize = @intFromPtr(image_view); + try rt.writeDescriptorSet( + std.mem.asBytes(&addr), + @as(u32, @intCast(set_index)), + @as(u32, @intCast(binding_index)), + @as(u32, @intCast(descriptor_index)), + ); + } + }, + else => {}, + } + } + } +} diff --git a/src/soft/device/fragment.zig b/src/soft/device/fragment.zig index c32df5b..eb9d649 100644 --- a/src/soft/device/fragment.zig +++ b/src/soft/device/fragment.zig @@ -48,5 +48,8 @@ pub fn shaderInvocation(allocator: std.mem.Allocator, draw_call: *Renderer.DrawC var color = zm.f32x4s(0.0); try rt.readOutput(std.mem.asBytes(&color), output_result); + + try rt.flushDescriptorSets(allocator); + return std.math.clamp(color, zm.f32x4s(0.0), zm.f32x4s(1.0)); } diff --git a/src/soft/device/vertex_dispatcher.zig b/src/soft/device/vertex_dispatcher.zig index 69bedf6..c34ed35 100644 --- a/src/soft/device/vertex_dispatcher.zig +++ b/src/soft/device/vertex_dispatcher.zig @@ -90,6 +90,8 @@ inline fn run(data: RunData) !void { }; try rt.readOutput(output.outputs[location].?.blob, result_word); } + + try rt.flushDescriptorSets(data.allocator); } } diff --git a/src/vulkan/DescriptorSet.zig b/src/vulkan/DescriptorSet.zig index a507d32..1728c51 100644 --- a/src/vulkan/DescriptorSet.zig +++ b/src/vulkan/DescriptorSet.zig @@ -18,7 +18,7 @@ layout: *DescriptorSetLayout, vtable: *const VTable, pub const VTable = struct { - copy: *const fn (*Self, vk.CopyDescriptorSet) VkError!void, + copy: *const fn (*Self, *const Self, vk.CopyDescriptorSet) VkError!void, destroy: *const fn (*Self, std.mem.Allocator) void, write: *const fn (*Self, vk.WriteDescriptorSet) VkError!void, }; @@ -33,8 +33,8 @@ pub fn init(device: *Device, allocator: std.mem.Allocator, layout: *DescriptorSe }; } -pub inline fn copy(self: *Self, copy_data: vk.CopyDescriptorSet) VkError!void { - try self.vtable.copy(self, copy_data); +pub inline fn copy(self: *Self, src: *const Self, copy_data: vk.CopyDescriptorSet) VkError!void { + try self.vtable.copy(self, src, copy_data); } pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void { diff --git a/src/vulkan/DescriptorSetLayout.zig b/src/vulkan/DescriptorSetLayout.zig index f9b23f2..a565c5a 100644 --- a/src/vulkan/DescriptorSetLayout.zig +++ b/src/vulkan/DescriptorSetLayout.zig @@ -34,19 +34,6 @@ dynamic_descriptor_count: usize, /// Shader stages affected by this descriptor set stages: vk.ShaderStageFlags, -/// Mesa's common Vulkan runtime states: -/// -/// It's often necessary to store a pointer to the descriptor set layout in -/// the descriptor so that any entrypoint which has access to a descriptor -/// set also has the layout. While layouts are often passed into various -/// entrypoints, they're notably missing from vkUpdateDescriptorSets(). In -/// order to implement descriptor writes, you either need to stash a pointer -/// to the descriptor set layout in the descriptor set or you need to copy -/// all of the relevant information. Storing a pointer is a lot cheaper. -/// -/// Because descriptor set layout lifetimes and descriptor set lifetimes are -/// not guaranteed to coincide, we have to reference count if we're going to -/// do this. ref_count: std.atomic.Value(usize), vtable: *const VTable, diff --git a/src/vulkan/lib_vulkan.zig b/src/vulkan/lib_vulkan.zig index 3e29cb5..20b2392 100644 --- a/src/vulkan/lib_vulkan.zig +++ b/src/vulkan/lib_vulkan.zig @@ -1598,8 +1598,9 @@ pub export fn strollUpdateDescriptorSets(p_device: vk.Device, write_count: u32, } for (copies, 0..copy_count) |copy, _| { - const set = NonDispatchable(DescriptorSet).fromHandleObject(copy.dst_set) catch |err| return errorLogger(err); - set.copy(copy) catch |err| return errorLogger(err); + const dst = NonDispatchable(DescriptorSet).fromHandleObject(copy.dst_set) catch |err| return errorLogger(err); + const src = NonDispatchable(DescriptorSet).fromHandleObject(copy.src_set) catch |err| return errorLogger(err); + dst.copy(src, copy) catch |err| return errorLogger(err); } }