adding software blitter base

This commit is contained in:
2025-12-20 00:00:42 +01:00
parent 084412ac1c
commit 8a641adb8e
9 changed files with 95 additions and 28 deletions

View File

@@ -2,6 +2,8 @@ const std = @import("std");
const vk = @import("vulkan");
const base = @import("base");
const SoftImage = @import("SoftImage.zig");
const cmd = base.commands;
const VkError = base.VkError;
@@ -27,22 +29,8 @@ pub fn dispatch(self: *Self, command: *const cmd.Command) VkError!void {
}
fn clearColorImage(data: *const cmd.CommandClearColorImage) VkError!void {
// TODO: use a blitter
const image = data.image;
for (data.ranges) |range| {
const image_size = image.getTotalSize();
const memory = if (image.memory) |memory| memory else return VkError.ValidationFailed;
var memory_map: []u32 = @as([*]u32, @ptrCast(@alignCast(try memory.map(0, image_size))))[0..image_size];
_ = range;
_ = &memory_map;
base.logger.fixme("Implement image clear", .{});
memory.unmap();
}
const soft_image: *SoftImage = @alignCast(@fieldParentPtr("interface", data.image));
soft_image.clearRange(data.clear_color, data.range);
}
fn copyBuffer(data: *const cmd.CommandCopyBuffer) VkError!void {

View File

@@ -63,13 +63,13 @@ pub fn reset(interface: *Interface, flags: vk.CommandBufferResetFlags) VkError!v
// Commands ====================================================================================================
pub fn clearColorImage(interface: *Interface, image: *base.Image, layout: vk.ImageLayout, color: *const vk.ClearColorValue, ranges: []const vk.ImageSubresourceRange) VkError!void {
pub fn clearColorImage(interface: *Interface, image: *base.Image, layout: vk.ImageLayout, color: *const vk.ClearColorValue, range: vk.ImageSubresourceRange) VkError!void {
// No-op
_ = interface;
_ = image;
_ = layout;
_ = color;
_ = ranges;
_ = range;
}
pub fn fillBuffer(interface: *Interface, buffer: *base.Buffer, offset: vk.DeviceSize, size: vk.DeviceSize, data: u32) VkError!void {

View File

@@ -6,6 +6,7 @@ const builtin = @import("builtin");
const Debug = std.builtin.OptimizeMode.Debug;
const SoftQueue = @import("SoftQueue.zig");
const Blitter = @import("device/Blitter.zig");
pub const SoftBinarySemaphore = @import("SoftBinarySemaphore.zig");
pub const SoftBuffer = @import("SoftBuffer.zig");
@@ -38,6 +39,7 @@ const SpawnError = std.Thread.SpawnError;
interface: Interface,
device_allocator: if (builtin.mode == Debug) std.heap.DebugAllocator(.{}) else std.heap.ThreadSafeAllocator,
workers: std.Thread.Pool,
blitter: Blitter,
pub fn create(physical_device: *base.PhysicalDevice, allocator: std.mem.Allocator, info: *const vk.DeviceCreateInfo) VkError!*Self {
const self = allocator.create(Self) catch return VkError.OutOfHostMemory;
@@ -78,6 +80,7 @@ pub fn create(physical_device: *base.PhysicalDevice, allocator: std.mem.Allocato
.interface = interface,
.device_allocator = if (builtin.mode == Debug) .init else .{ .child_allocator = std.heap.c_allocator }, // TODO: better device allocator
.workers = undefined,
.blitter = .init,
};
self.workers.init(.{ .allocator = self.device_allocator.allocator() }) catch |err| return switch (err) {

View File

@@ -7,6 +7,8 @@ const lib = @import("lib.zig");
const VkError = base.VkError;
const Device = base.Device;
const SoftDevice = @import("SoftDevice.zig");
const Self = @This();
pub const Interface = base.Image;
@@ -38,3 +40,20 @@ pub fn getMemoryRequirements(interface: *Interface, requirements: *vk.MemoryRequ
_ = interface;
requirements.alignment = lib.MEMORY_REQUIREMENTS_IMAGE_ALIGNMENT;
}
inline fn clear(self: *Self, pixel: *const anyopaque, format: vk.Format, view_format: vk.Format, range: vk.ImageSubresourceRange, area: ?vk.Rect2D) void {
const soft_device: *SoftDevice = @alignCast(@fieldParentPtr("interface", self.interface.owner));
soft_device.blitter.clear(pixel, format, self, view_format, range, area);
}
pub fn clearRange(self: *Self, color: vk.ClearColorValue, range: vk.ImageSubresourceRange) void {
std.debug.assert(range.aspect_mask == vk.ImageAspectFlags{ .color_bit = true });
const clear_format: vk.Format = if (base.vku.vkuFormatIsSINT(@intCast(@intFromEnum(self.interface.format))))
.r32g32b32a32_sint
else if (base.vku.vkuFormatIsUINT(@intCast(@intFromEnum(self.interface.format))))
.r32g32b32a32_uint
else
.r32g32b32a32_sfloat;
self.clear(@ptrCast(&color.float_32), clear_format, self.interface.format, range, null);
}

27
src/soft/device/Blitter.zig git.filemode.normal_file
View File

@@ -0,0 +1,27 @@
const std = @import("std");
const vk = @import("vulkan");
const base = @import("base");
pub const SoftImage = @import("../SoftImage.zig");
pub const SoftImageView = @import("../SoftImageView.zig");
const Self = @This();
blit_mutex: std.Thread.Mutex,
pub const init: Self = .{
.blit_mutex = .{},
};
pub fn clear(self: *Self, pixel: *const anyopaque, format: vk.Format, dest: *SoftImage, view_format: vk.Format, range: vk.ImageSubresourceRange, area: ?vk.Rect2D) void {
const dst_format = base.Image.formatFromAspect(view_format, range.aspect_mask);
if (dst_format == .undefined) {
return;
}
_ = self;
_ = pixel;
_ = format;
_ = dest;
_ = area;
}