adding backend agnostic IR
Test / build_and_test (push) Successful in 5m16s
Build / build (push) Successful in 6m50s

This commit is contained in:
2026-07-20 22:07:41 +02:00
parent 2375abf688
commit 9b1b223186
70 changed files with 7358 additions and 250 deletions
+3 -3
View File
@@ -44,7 +44,7 @@ pub const DispatchTable = struct {
begin: *const fn (*Self, *const vk.CommandBufferBeginInfo) VkError!void,
beginQuery: *const fn (*Self, *QueryPool, u32, vk.QueryControlFlags) VkError!void,
beginRenderPass: *const fn (*Self, *RenderPass, *Framebuffer, vk.Rect2D, ?[]const vk.ClearValue) VkError!void,
bindDescriptorSets: *const fn (*Self, vk.PipelineBindPoint, u32, [lib.VULKAN_MAX_DESCRIPTOR_SETS]?*DescriptorSet, []const u32) VkError!void,
bindDescriptorSets: *const fn (*Self, vk.PipelineBindPoint, u32, [lib.vulkan_max_descriptor_sets]?*DescriptorSet, []const u32) VkError!void,
bindPipeline: *const fn (*Self, vk.PipelineBindPoint, *Pipeline) VkError!void,
bindIndexBuffer: *const fn (*Self, *Buffer, usize, vk.IndexType) VkError!void,
bindVertexBuffer: *const fn (*Self, usize, *Buffer, usize) VkError!void,
@@ -192,10 +192,10 @@ pub inline fn beginQuery(self: *Self, pool: *QueryPool, query: u32, flags: vk.Qu
}
pub fn bindDescriptorSets(self: *Self, bind_point: vk.PipelineBindPoint, first_set: u32, sets: []const vk.DescriptorSet, dynamic_offsets: []const u32) VkError!void {
if (sets.len > lib.VULKAN_MAX_DESCRIPTOR_SETS or first_set > lib.VULKAN_MAX_DESCRIPTOR_SETS or first_set + sets.len > lib.VULKAN_MAX_DESCRIPTOR_SETS)
if (sets.len > lib.vulkan_max_descriptor_sets or first_set > lib.vulkan_max_descriptor_sets or first_set + sets.len > lib.vulkan_max_descriptor_sets)
return VkError.ValidationFailed;
var inner_sets: [lib.VULKAN_MAX_DESCRIPTOR_SETS]?*DescriptorSet = @splat(null);
var inner_sets: [lib.vulkan_max_descriptor_sets]?*DescriptorSet = @splat(null);
for (sets, inner_sets[0..sets.len]) |set, *inner_set| {
inner_set.* = try NonDispatchable(DescriptorSet).fromHandleObject(set);
}
+3 -3
View File
@@ -13,7 +13,7 @@ pub const ObjectType: vk.ObjectType = .command_pool;
/// Base capacity of the command buffer pool.
/// Every increase of the capacity will be by this amount.
pub const BUFFER_POOL_BASE_CAPACITY = 64;
pub const buffer_pool_base_capacity = 64;
owner: *Device,
flags: vk.CommandPoolCreateFlags,
@@ -42,7 +42,7 @@ pub fn init(device: *Device, allocator: std.mem.Allocator, info: *const vk.Comma
.flags = info.flags,
.queue_family_index = info.queue_family_index,
.host_allocator = VulkanAllocator.from(allocator).clone(),
.buffers = std.ArrayList(*Dispatchable(CommandBuffer)).initCapacity(allocator, BUFFER_POOL_BASE_CAPACITY) catch return VkError.OutOfHostMemory,
.buffers = std.ArrayList(*Dispatchable(CommandBuffer)).initCapacity(allocator, buffer_pool_base_capacity) catch return VkError.OutOfHostMemory,
.first_free_buffer_index = 0,
// SAFETY: the backend assigns the vtable before returning the command pool.
.vtable = undefined,
@@ -54,7 +54,7 @@ pub fn allocateCommandBuffers(self: *Self, info: *const vk.CommandBufferAllocate
if (self.buffers.items.len < self.first_free_buffer_index + info.command_buffer_count) {
while (self.buffers.capacity < self.buffers.items.len + info.command_buffer_count) {
self.buffers.ensureUnusedCapacity(allocator, BUFFER_POOL_BASE_CAPACITY) catch return VkError.OutOfHostMemory;
self.buffers.ensureUnusedCapacity(allocator, buffer_pool_base_capacity) catch return VkError.OutOfHostMemory;
}
const original_len = self.buffers.items.len;
errdefer {
+9 -9
View File
@@ -13,8 +13,8 @@ const root = @import("root");
comptime {
if (!builtin.is_test) {
if (!@hasDecl(root, "VULKAN_VERSION")) {
@compileError("Missing VULKAN_VERSION in module root");
if (!@hasDecl(root, "vulkan_version")) {
@compileError("Missing vulkan_version in module root");
}
}
}
@@ -23,7 +23,7 @@ const Self = @This();
pub const ObjectType: vk.ObjectType = .instance;
/// Dummy
pub const EXTENSIONS = [_]vk.ExtensionProperties{};
pub const extensions = [_]vk.ExtensionProperties{};
physical_devices: std.ArrayList(*Dispatchable(PhysicalDevice)),
@@ -58,7 +58,7 @@ pub fn validateCreateInfo(info: *const vk.InstanceCreateInfo) VkError!void {
const supported: vk.Version = if (comptime builtin.is_test)
vk.API_VERSION_1_0
else
@bitCast(root.VULKAN_VERSION);
@bitCast(root.vulkan_version);
if (requested.variant != 0 or requested.major > supported.major or (requested.major == supported.major and requested.minor > supported.minor)) {
return VkError.IncompatibleDriver;
}
@@ -78,7 +78,7 @@ pub fn validateCreateInfo(info: *const vk.InstanceCreateInfo) VkError!void {
const supported_extensions = if (comptime !@hasDecl(root, "Instance"))
&[_]vk.ExtensionProperties{}
else
root.Instance.EXTENSIONS[0..];
root.Instance.extensions[0..];
for (0..info.enabled_extension_count) |i| {
const name = utils.boundedName(names[i], vk.MAX_EXTENSION_NAME_SIZE) orelse return VkError.ExtensionNotPresent;
@@ -124,11 +124,11 @@ pub fn enumerateExtensionProperties(layer_name: ?[]const u8, count: *u32, p_prop
return VkError.LayerNotPresent;
}
if (comptime !builtin.is_test and @hasDecl(root.Instance, "EXTENSIONS")) {
const available = root.Instance.EXTENSIONS.len;
if (comptime !builtin.is_test and @hasDecl(root.Instance, "extensions")) {
const available = root.Instance.extensions.len;
if (p_properties) |properties| {
const write_count = @min(count.*, available);
for (root.Instance.EXTENSIONS[0..write_count], properties[0..write_count]) |ext, *prop| {
for (root.Instance.extensions[0..write_count], properties[0..write_count]) |ext, *prop| {
prop.* = ext;
}
count.* = @intCast(write_count);
@@ -145,7 +145,7 @@ pub fn enumerateVersion(version: *u32) VkError!void {
if (comptime builtin.is_test) {
version.* = @bitCast(vk.makeApiVersion(0, 1, 0, 0));
} else {
version.* = @bitCast(root.VULKAN_VERSION);
version.* = @bitCast(root.vulkan_version);
}
}
+1 -1
View File
@@ -40,7 +40,7 @@ pub fn init(allocator: std.mem.Allocator, instance: *Instance) VkError!Self {
.props = .{
.api_version = 0,
.driver_version = 0,
.vendor_id = root.VULKAN_VENDOR_ID,
.vendor_id = root.vulkan_vendor_id,
.device_id = 0,
.device_type = .other,
.device_name = @as([vk.MAX_PHYSICAL_DEVICE_NAME_SIZE]u8, @splat(0)),
+1 -1
View File
@@ -94,7 +94,7 @@ fn makeHeader(device: *const Device) Header {
return .{
.header_size = @sizeOf(Header),
.header_version = .one,
.vendor_id = @intCast(root.VULKAN_VENDOR_ID),
.vendor_id = @intCast(root.vulkan_vendor_id),
.device_id = device.physical_device.props.device_id,
.pipeline_cache_uuid = device.physical_device.props.pipeline_cache_uuid,
};
+5 -5
View File
@@ -16,12 +16,12 @@ owner: *Device,
set_count: usize,
set_layouts: [lib.VULKAN_MAX_DESCRIPTOR_SETS]?*DescriptorSetLayout,
set_layouts: [lib.vulkan_max_descriptor_sets]?*DescriptorSetLayout,
dynamic_descriptor_offsets: [lib.VULKAN_MAX_DESCRIPTOR_SETS]usize,
dynamic_descriptor_offsets: [lib.vulkan_max_descriptor_sets]usize,
push_ranges_count: usize,
push_ranges: [lib.VULKAN_MAX_PUSH_CONSTANT_RANGES]vk.PushConstantRange,
push_ranges: [lib.vulkan_max_push_constant_ranges]vk.PushConstantRange,
ref_count: std.atomic.Value(usize),
@@ -36,8 +36,8 @@ pub fn init(device: *Device, allocator: std.mem.Allocator, info: *const vk.Pipel
var self: Self = .{
.owner = device,
.set_count = info.set_layout_count,
.set_layouts = [_]?*DescriptorSetLayout{null} ** lib.VULKAN_MAX_DESCRIPTOR_SETS,
.dynamic_descriptor_offsets = [_]usize{0} ** lib.VULKAN_MAX_DESCRIPTOR_SETS,
.set_layouts = [_]?*DescriptorSetLayout{null} ** lib.vulkan_max_descriptor_sets,
.dynamic_descriptor_offsets = [_]usize{0} ** lib.vulkan_max_descriptor_sets,
.push_ranges_count = info.push_constant_range_count,
.push_ranges = @splat(std.mem.zeroes(vk.PushConstantRange)),
.ref_count = std.atomic.Value(usize).init(1),
+6 -6
View File
@@ -52,11 +52,11 @@ pub const ShaderModule = @import("ShaderModule.zig");
pub const SurfaceKHR = @import("wsi/SurfaceKHR.zig");
pub const SwapchainKHR = @import("wsi/SwapchainKHR.zig");
pub const VULKAN_VENDOR_ID: i32 = @intFromEnum(vk.VendorId.ape);
pub const vulkan_vendor_id: i32 = @intFromEnum(vk.VendorId.ape);
/// Default driver name
pub const DRIVER_NAME = "Unnamed Ape Driver";
pub const DRIVER_VERSION = vk.makeApiVersion(
pub const driver_name = "Unnamed Ape Driver";
pub const driver_version = vk.makeApiVersion(
0,
config.driver_version.major,
config.driver_version.minor,
@@ -64,10 +64,10 @@ pub const DRIVER_VERSION = vk.makeApiVersion(
);
/// Dummy fallback
pub const VULKAN_VERSION = vk.makeApiVersion(0, 1, 0, 0);
pub const vulkan_version = vk.makeApiVersion(0, 1, 0, 0);
/// Maximum number of descriptor sets per pipeline
pub const VULKAN_MAX_DESCRIPTOR_SETS = 8;
pub const vulkan_max_descriptor_sets = 8;
/// The number of push constant ranges is effectively bounded
/// by the number of possible shader stages. Not the number of stages that can
@@ -80,7 +80,7 @@ pub const VULKAN_MAX_DESCRIPTOR_SETS = 8;
/// - VK_SHADER_STAGE_GEOMETRY_BIT
/// - VK_SHADER_STAGE_FRAGMENT_BIT
/// - VK_SHADER_STAGE_COMPUTE_BIT
pub const VULKAN_MAX_PUSH_CONSTANT_RANGES = 6;
pub const vulkan_max_push_constant_ranges = 6;
pub const std_options: std.Options = .{
.log_level = .debug,
+3 -3
View File
@@ -5,8 +5,8 @@ const lib = @import("lib.zig");
comptime {
if (!builtin.is_test) {
if (!@hasDecl(root, "DRIVER_NAME")) {
@compileError("Missing DRIVER_NAME in module root");
if (!@hasDecl(root, "driver_name")) {
@compileError("Missing driver_name in module root");
}
}
}
@@ -90,7 +90,7 @@ pub fn log(comptime level: std.log.Level, comptime scope: @EnumLiteral(), compti
writer.writeAll("[ApeDriver") catch continue;
if (!builtin.is_test) {
term.setColor(.cyan) catch @panic("Caught an error while handling an error");
writer.print(" {s} ", .{root.DRIVER_NAME}) catch continue;
writer.print(" {s} ", .{root.driver_name}) catch continue;
}
term.setColor(.yellow) catch @panic("Caught an error while handling an error");
writer.print("{d}:{d}:{d}.{d:0>3}.{d:0>3}", .{ now_hour, now_min, now_sec, now_ms, now_us }) catch continue;
+1 -1
View File
@@ -111,7 +111,7 @@ pub fn attachImage(interface: *Interface, allocator: std.mem.Allocator, image: *
const pool = wayland.wl_shm_create_pool(shm, fd, @intCast(size)) orelse return VkError.Unknown;
defer wayland.wl_shm_pool_destroy(pool);
const buffer = wayland.wl_shm_pool_create_buffer(pool, 0, @intCast(width), @intCast(height), @intCast(stride), wayland.WL_SHM_FORMAT_ARGB8888) orelse return VkError.Unknown;
const buffer = wayland.wl_shm_pool_create_buffer(pool, 0, @intCast(width), @intCast(height), @intCast(stride), wayland.wl_shm_format_argb8888) orelse return VkError.Unknown;
errdefer wayland.wl_buffer_destroy(buffer);
wl_image.* = .{
+19 -19
View File
@@ -11,16 +11,16 @@ pub const wl_registry_listener = extern struct {
global_remove: ?*const fn (data: ?*anyopaque, wl_registry: ?*wl_registry, name: u32) callconv(.c) void = null,
};
pub const WL_BUFFER_DESTROY: c_int = 0;
pub const WL_DISPLAY_GET_REGISTRY: c_int = 1;
pub const WL_REGISTRY_BIND: c_int = 0;
pub const WL_SHM_CREATE_POOL: c_int = 0;
pub const WL_SHM_FORMAT_ARGB8888: c_int = 0;
pub const WL_SHM_POOL_CREATE_BUFFER: c_int = 0;
pub const WL_SHM_POOL_DESTROY: c_int = 1;
pub const WL_SURFACE_ATTACH: c_int = 1;
pub const WL_SURFACE_COMMIT: c_int = 6;
pub const WL_SURFACE_DAMAGE: c_int = 2;
pub const wl_buffer_destroy_opcode: c_int = 0;
pub const wl_display_get_registry_opcode: c_int = 1;
pub const wl_registry_bind_opcode: c_int = 0;
pub const wl_shm_create_pool_opcode: c_int = 0;
pub const wl_shm_format_argb8888: c_int = 0;
pub const wl_shm_pool_create_buffer_opcode: c_int = 0;
pub const wl_shm_pool_destroy_opcode: c_int = 1;
pub const wl_surface_attach_opcode: c_int = 1;
pub const wl_surface_commit_opcode: c_int = 6;
pub const wl_surface_damage_opcode: c_int = 2;
pub const wl_buffer = opaque {};
pub const wl_callback = opaque {};
@@ -104,7 +104,7 @@ pub fn unload() void {
pub fn wl_registry_bind(registry: *wl_registry, name: u32, interface: *const wl_interface, version: u32) ?*wl_proxy {
return wl_proxy_marshal_flags(
@ptrCast(@alignCast(registry)),
WL_REGISTRY_BIND,
wl_registry_bind_opcode,
interface,
version,
0,
@@ -118,7 +118,7 @@ pub fn wl_registry_bind(registry: *wl_registry, name: u32, interface: *const wl_
pub fn wl_display_get_registry(display: *wl_display) ?*wl_registry {
return @ptrCast(@alignCast(wl_proxy_marshal_flags(
@ptrCast(@alignCast(display)),
WL_DISPLAY_GET_REGISTRY,
wl_display_get_registry_opcode,
wl_registry_interface,
wl_proxy_get_version(@ptrCast(@alignCast(display))),
0,
@@ -133,7 +133,7 @@ pub fn wl_registry_add_listener(registry: *wl_registry, listener: *const wl_regi
pub fn wl_shm_create_pool(shm: *wl_shm, fd: i32, size: i32) callconv(.c) ?*wl_shm_pool {
return @ptrCast(@alignCast(wl_proxy_marshal_flags(
@ptrCast(@alignCast(shm)),
WL_SHM_CREATE_POOL,
wl_shm_create_pool_opcode,
wl_shm_pool_interface,
wl_proxy_get_version(@ptrCast(@alignCast(shm))),
0,
@@ -146,7 +146,7 @@ pub fn wl_shm_create_pool(shm: *wl_shm, fd: i32, size: i32) callconv(.c) ?*wl_sh
pub fn wl_shm_pool_destroy(shm_pool: *wl_shm_pool) void {
_ = wl_proxy_marshal_flags(
@ptrCast(@alignCast(shm_pool)),
WL_SHM_POOL_DESTROY,
wl_shm_pool_destroy_opcode,
null,
wl_proxy_get_version(@ptrCast(@alignCast(shm_pool))),
@bitCast(@as(c_int, @as(c_int, 1) << @intCast(@as(c_int, 0)))),
@@ -156,7 +156,7 @@ pub fn wl_shm_pool_destroy(shm_pool: *wl_shm_pool) void {
pub fn wl_shm_pool_create_buffer(shm_pool: *wl_shm_pool, offset: i32, width: i32, height: i32, stride: i32, format: u32) ?*wl_buffer {
return @ptrCast(@alignCast(wl_proxy_marshal_flags(
@ptrCast(@alignCast(shm_pool)),
WL_SHM_POOL_CREATE_BUFFER,
wl_shm_pool_create_buffer_opcode,
wl_buffer_interface,
wl_proxy_get_version(@ptrCast(@alignCast(shm_pool))),
0,
@@ -172,7 +172,7 @@ pub fn wl_shm_pool_create_buffer(shm_pool: *wl_shm_pool, offset: i32, width: i32
pub fn wl_buffer_destroy(buffer: *wl_buffer) void {
_ = wl_proxy_marshal_flags(
@ptrCast(@alignCast(buffer)),
WL_BUFFER_DESTROY,
wl_buffer_destroy_opcode,
null,
wl_proxy_get_version(@ptrCast(@alignCast(buffer))),
@bitCast(@as(c_int, @as(c_int, 1) << @intCast(@as(c_int, 0)))),
@@ -182,7 +182,7 @@ pub fn wl_buffer_destroy(buffer: *wl_buffer) void {
pub fn wl_surface_attach(surface: *wl_surface, buffer: *wl_buffer, x: i32, y: i32) void {
_ = wl_proxy_marshal_flags(
@ptrCast(@alignCast(surface)),
WL_SURFACE_ATTACH,
wl_surface_attach_opcode,
null,
wl_proxy_get_version(@ptrCast(@alignCast(surface))),
0,
@@ -195,7 +195,7 @@ pub fn wl_surface_attach(surface: *wl_surface, buffer: *wl_buffer, x: i32, y: i3
pub fn wl_surface_damage(surface: *wl_surface, x: i32, y: i32, width: i32, height: i32) void {
_ = wl_proxy_marshal_flags(
@ptrCast(@alignCast(surface)),
WL_SURFACE_DAMAGE,
wl_surface_damage_opcode,
null,
wl_proxy_get_version(@ptrCast(@alignCast(surface))),
0,
@@ -209,7 +209,7 @@ pub fn wl_surface_damage(surface: *wl_surface, x: i32, y: i32, width: i32, heigh
pub fn wl_surface_commit(surface: *wl_surface) void {
_ = wl_proxy_marshal_flags(
@ptrCast(@alignCast(surface)),
WL_SURFACE_COMMIT,
wl_surface_commit_opcode,
null,
wl_proxy_get_version(@ptrCast(@alignCast(surface))),
0,