Skip to content

Commit efd28df

Browse files
committed
impriving architecture
1 parent e2b7fa5 commit efd28df

12 files changed

Lines changed: 342 additions & 102 deletions

File tree

.gdb_history

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
run
2+
bt
3+
q
4+
run
5+
bt
6+
q
7+
rim
8+
run
9+
bt
10+
q
11+
run
12+
bt
13+
q
14+
run
15+
bt
16+
run
17+
bt
18+
q
19+
c
20+
start
21+
n
22+
n
23+
n
24+
n
25+
s
26+
n
27+
n
28+
s
29+
n
30+
p vkDestroyInstance
31+
p vkDestroyInstance
32+
start
33+
n
34+
n
35+
n
36+
n
37+
s
38+
n
39+
s
40+
s
41+
start
42+
n
43+
n
44+
n
45+
s
46+
n
47+
s
48+
s
49+
q
50+
run
51+
q
52+
run
53+
bt
54+
p name
55+
c
56+
p name
57+
n
58+
bt
59+
q
60+
r
61+
bt
62+
c
63+
bt
64+
w
65+
y
66+
q
67+
run
68+
bt
69+
q
70+
run
71+
bt
72+
q
73+
q
74+
run
75+
bt
76+
q
77+
run
78+
bt
79+
q
80+
q
81+
q
82+
q
83+
run
84+
bt
85+
q
86+
q
87+
run
88+
bt
89+
q
90+
run
91+
bt
92+
q
93+
q
94+
run
95+
bt
96+
q

build.zig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub fn build(b: *std.Build) void {
2121
.root_source_file = b.path("src/vulkan/lib.zig"),
2222
.target = target,
2323
.optimize = optimize,
24+
.link_libc = true,
2425
});
2526

2627
const vulkan_headers = b.dependency("vulkan_headers", .{});
@@ -36,6 +37,7 @@ pub fn build(b: *std.Build) void {
3637
const lib_mod = b.createModule(.{
3738
.root_source_file = b.path(impl.root_source_file),
3839
.target = target,
40+
.link_libc = true,
3941
.optimize = optimize,
4042
.imports = &.{
4143
.{ .name = "common", .module = common_mod },
@@ -72,6 +74,8 @@ pub fn build(b: *std.Build) void {
7274
.flags = &.{b.fmt("-DLIBVK=\"{s}\"", .{lib.name})},
7375
});
7476

77+
b.installArtifact(c_test_exe);
78+
7579
const run_c_test = b.addRunArtifact(c_test_exe);
7680
const test_c_step = b.step(b.fmt("test-c-{s}", .{impl.name}), b.fmt("Run lib{s} C test", .{impl.name}));
7781
test_c_step.dependOn(b.getInstallStep());

src/soft/Instance.zig

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
const std = @import("std");
2+
const vk = @import("vulkan");
3+
const common = @import("common");
4+
const PhysicalDevice = @import("PhysicalDevice.zig");
5+
6+
const dispatchable = common.dispatchable;
7+
8+
const Self = @This();
9+
pub const ObjectType: vk.ObjectType = .instance;
10+
11+
common_instance: common.Instance,
12+
physical_device: dispatchable.Dispatchable(PhysicalDevice), // Software driver only has one physical device (CPU)
13+
14+
pub fn create(p_infos: ?*const vk.InstanceCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_instance: *vk.Instance) callconv(vk.vulkan_call_conv) vk.Result {
15+
const allocator = std.heap.c_allocator;
16+
17+
const dispatchable_object = dispatchable.Dispatchable(Self).create(allocator, ObjectType) catch return .error_out_of_host_memory;
18+
common.Instance.init(&dispatchable_object.object.common_instance, p_infos, callbacks) catch return .error_initialization_failed;
19+
20+
dispatchable_object.object.common_instance.vtable = .{
21+
.destroyInstance = destroy,
22+
.enumeratePhysicalDevices = enumeratePhysicalDevices,
23+
.enumerateInstanceVersion = null,
24+
//.enumerateInstanceLayerProperties = null,
25+
.enumerateInstanceExtensionProperties = null,
26+
};
27+
28+
dispatchable_object.object.physical_device.init() catch return .error_initialization_failed;
29+
30+
p_instance.* = @enumFromInt(dispatchable.toHandle(Self, dispatchable_object));
31+
return .success;
32+
}
33+
34+
pub fn enumeratePhysicalDevices(p_instance: vk.Instance, count: *u32, devices: *vk.PhysicalDevice) callconv(vk.vulkan_call_conv) vk.Result {
35+
const dispatchable_object = common.dispatchable.fromHandle(Self, @intFromEnum(p_instance)) catch return .error_initialization_failed;
36+
_ = dispatchable_object;
37+
_ = count;
38+
_ = devices;
39+
return .success;
40+
}
41+
42+
pub fn destroy(p_instance: vk.Instance, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void {
43+
const allocator = std.heap.c_allocator;
44+
_ = callbacks;
45+
46+
const dispatchable_object = common.dispatchable.fromHandle(Self, @intFromEnum(p_instance)) catch return;
47+
dispatchable_object.destroy(allocator);
48+
}

src/soft/PhysicalDevice.zig

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const std = @import("std");
2+
const vk = @import("vulkan");
3+
const Instance = @import("Instance.zig");
4+
const common = @import("common");
5+
6+
const dispatchable = common.dispatchable;
7+
8+
const Self = @This();
9+
const ObjectType: vk.ObjectType = .physical_device;
10+
11+
instance: *const Instance,
12+
common_physical_device: common.PhysicalDevice,
13+
14+
pub fn init(self: *Self) !void {
15+
self.common_physical_device.props = .{
16+
.apiVersion = ,
17+
.driverVersion = VKD_DRIVER_VERSION,
18+
.vendorID = 0x0601,
19+
.deviceID = 0x060103,
20+
.deviceType = VK_PHYSICAL_DEVICE_TYPE_CPU,
21+
.deviceName = {},
22+
.pipelineCacheUUID = {},
23+
.limits = {},
24+
.sparseProperties = {},
25+
};
26+
}

src/soft/lib.zig

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@ const std = @import("std");
22
const vk = @import("vulkan");
33
const common = @import("common");
44

5-
export fn libVulkanExport() void {
6-
_ = common;
5+
const Instance = @import("Instance.zig");
6+
7+
const global_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{
8+
.{ "vkGetInstanceProcAddr", @as(vk.PfnVoidFunction, @ptrCast(&common.icd.getInstanceProcAddr)) },
9+
.{ "vkCreateInstance", @as(vk.PfnVoidFunction, @ptrCast(&Instance.create)) },
10+
});
11+
12+
pub export fn vkGetInstanceProcAddr(p_instance: vk.Instance, pName: ?[*:0]const u8) callconv(vk.vulkan_call_conv) vk.PfnVoidFunction {
13+
if (pName == null) {
14+
return null;
15+
}
16+
const name = std.mem.span(pName.?);
17+
return common.icd.getInstanceProcAddr(global_pfn_map, p_instance, name);
718
}

src/vulkan/Instance.zig

Lines changed: 48 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,52 @@
11
const std = @import("std");
22
const vk = @import("vulkan");
3-
const PhysicalDevice = @import("PhysicalDevice.zig").PhysicalDevice;
4-
const Object = @import("object.zig").Object;
5-
6-
pub const Instance = extern struct {
7-
const Self = @This();
8-
pub const ObjectType: vk.ObjectType = .instance;
9-
pub const vtable: VTable = .{};
10-
11-
object: Object,
12-
//physical_devices: std.ArrayList(*PhysicalDevice),
13-
alloc_callbacks: vk.AllocationCallbacks,
14-
15-
pub const VTable = struct {
16-
createInstance: ?vk.PfnCreateInstance = null,
17-
destroyInstance: ?vk.PfnDestroyInstance = null,
18-
enumeratePhysicalDevices: ?vk.PfnEnumeratePhysicalDevices = null,
19-
getInstanceProcAddr: ?vk.PfnGetInstanceProcAddr = null,
20-
enumerateInstanceVersion: ?vk.PfnEnumerateInstanceVersion = null,
21-
//enumerateInstanceLayerProperties: vk.PfnEnumerateInstanceProperties = null,
22-
enumerateInstanceExtensionProperties: ?vk.PfnEnumerateInstanceExtensionProperties = null,
3+
const dispatchable = @import("dispatchable.zig");
4+
5+
const Self = @This();
6+
pub const ObjectType: vk.ObjectType = .instance;
7+
8+
alloc_callbacks: vk.AllocationCallbacks,
9+
10+
vtable: VTable,
11+
12+
pub fn init(self: *Self, p_infos: ?*const vk.InstanceCreateInfo, callbacks: ?*const vk.AllocationCallbacks) !void {
13+
const infos = p_infos orelse return error.NullCreateInfos;
14+
if (infos.s_type != .instance_create_info) {
15+
return error.InvalidCreateInfos;
16+
}
17+
18+
self.vtable = .{
19+
.destroyInstance = null,
20+
.enumeratePhysicalDevices = null,
21+
.enumerateInstanceVersion = null,
22+
//.enumerateInstanceLayerProperties = null,
23+
.enumerateInstanceExtensionProperties = null,
2324
};
25+
26+
if (callbacks) |c| {
27+
self.alloc_callbacks = c.*;
28+
}
29+
}
30+
31+
pub fn getProcAddr(self: *const Self, name: []const u8) vk.PfnVoidFunction {
32+
const allocator = std.heap.c_allocator;
33+
34+
const KV = struct { []const u8, vk.PfnVoidFunction };
35+
const pfn_map = std.StaticStringMap(vk.PfnVoidFunction).init([_]KV{
36+
.{ "vkDestroyInstance", @ptrCast(self.vtable.destroyInstance) },
37+
.{ "vkEnumeratePhysicalDevices", @ptrCast(self.vtable.enumeratePhysicalDevices) },
38+
.{ "vkEnumerateInstanceVersion", @ptrCast(self.vtable.enumerateInstanceVersion) },
39+
.{ "vkEnumerateInstanceExtensionProperties", @ptrCast(self.vtable.enumerateInstanceExtensionProperties) },
40+
}, allocator) catch return null;
41+
defer pfn_map.deinit(allocator);
42+
43+
return if (pfn_map.get(name)) |pfn| pfn else null;
44+
}
45+
46+
pub const VTable = struct {
47+
destroyInstance: ?vk.PfnDestroyInstance,
48+
enumeratePhysicalDevices: ?vk.PfnEnumeratePhysicalDevices,
49+
enumerateInstanceVersion: ?vk.PfnEnumerateInstanceVersion,
50+
//enumerateInstanceLayerProperties: vk.PfnEnumerateInstanceProperties,
51+
enumerateInstanceExtensionProperties: ?vk.PfnEnumerateInstanceExtensionProperties,
2452
};

src/vulkan/PhysicalDevice.zig

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
const vk = @import("vulkan");
2-
const Instance = @import("Instance.zig").Instance;
3-
const Object = @import("object.zig").Object;
2+
const Instance = @import("Instance.zig");
43

5-
pub const PhysicalDevice = extern struct {
6-
const Self = @This();
7-
const ObjectType: vk.ObjectType = .physical_device;
4+
const Self = @This();
5+
const ObjectType: vk.ObjectType = .physical_device;
86

9-
object: Object,
10-
11-
instance: *Instance,
12-
props: vk.PhysicalDeviceProperties,
13-
queue_families: [3]vk.QueueFamilyProperties,
14-
};
7+
props: vk.PhysicalDeviceProperties,
8+
queue_families: [3]vk.QueueFamilyProperties,

src/vulkan/dispatchable.zig

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
const std = @import("std");
2+
const vk = @import("vulkan");
3+
const c = @cImport({
4+
@cInclude("vulkan/vk_icd.h");
5+
});
6+
7+
pub fn Dispatchable(comptime T: type) type {
8+
return extern struct {
9+
const Self = @This();
10+
11+
loader_data: c.VK_LOADER_DATA,
12+
object_type: vk.ObjectType,
13+
object: *T,
14+
15+
pub fn create(allocator: std.mem.Allocator, object_type: vk.ObjectType) !*Self {
16+
const object = try allocator.create(Self);
17+
object.* = .{
18+
.loader_data = .{ .loaderMagic = c.ICD_LOADER_MAGIC },
19+
.object_type = object_type,
20+
.object = try allocator.create(T),
21+
};
22+
return object;
23+
}
24+
25+
pub fn destroy(self: *Self, allocator: std.mem.Allocator) void {
26+
allocator.destroy(self.object);
27+
allocator.destroy(self);
28+
}
29+
};
30+
}
31+
32+
pub inline fn fromHandle(comptime T: type, handle: usize) !*Dispatchable(T) {
33+
if (handle == 0) {
34+
return error.NullHandle;
35+
}
36+
const dispatchable: *Dispatchable(T) = @ptrFromInt(handle);
37+
if (dispatchable.object_type != T.ObjectType) {
38+
return error.InvalidType;
39+
}
40+
return dispatchable;
41+
}
42+
43+
pub inline fn toHandle(comptime T: type, handle: *Dispatchable(T)) usize {
44+
return @intFromPtr(handle);
45+
}

src/vulkan/icd.zig

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,25 @@ const c = @cImport({
44
@cInclude("vulkan/vk_icd.h");
55
});
66

7-
const Instance = @import("Instance.zig").Instance;
8-
const fromHandle = @import("object.zig").fromHandle;
7+
const Instance = @import("Instance.zig");
8+
const dispatchable = @import("dispatchable.zig");
99

10-
const global_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{
11-
.{ "vkGetInstanceProcAddr", @as(vk.PfnVoidFunction, @ptrCast(&getInstanceProcAddr)) },
12-
.{ "vkCreateInstance", @as(vk.PfnVoidFunction, @ptrCast(&Instance.vtable.createInstance)) },
13-
});
10+
pub fn getInstanceProcAddr(global_pfn_map: std.StaticStringMap(vk.PfnVoidFunction), p_instance: vk.Instance, name: []const u8) vk.PfnVoidFunction {
11+
const allocator = std.heap.c_allocator;
12+
const get_proc_log = std.log.scoped(.vkGetInstanceProcAddr);
13+
14+
if (std.process.hasEnvVar(allocator, "DRIVER_LOGS") catch false) {
15+
get_proc_log.info("Loading {s}...", .{name});
16+
}
1417

15-
pub fn getInstanceProcAddr(instance: vk.Instance, name: []const u8) vk.PfnVoidFunction {
1618
if (global_pfn_map.get(name)) |pfn| {
1719
return pfn;
1820
}
19-
if (instance != .null_handle) {}
20-
return null;
21+
const instance = dispatchable.fromHandle(Instance, @intFromEnum(p_instance)) catch |e| {
22+
if (std.process.hasEnvVar(allocator, "DRIVER_LOGS") catch false) {
23+
get_proc_log.err("{any}", .{e});
24+
}
25+
return null;
26+
};
27+
return instance.object.getProcAddr(name);
2128
}

0 commit comments

Comments
 (0)