impriving architecture
This commit is contained in:
@@ -1,24 +1,52 @@
|
||||
const std = @import("std");
|
||||
const vk = @import("vulkan");
|
||||
const PhysicalDevice = @import("PhysicalDevice.zig").PhysicalDevice;
|
||||
const Object = @import("object.zig").Object;
|
||||
const dispatchable = @import("dispatchable.zig");
|
||||
|
||||
pub const Instance = extern struct {
|
||||
const Self = @This();
|
||||
pub const ObjectType: vk.ObjectType = .instance;
|
||||
pub const vtable: VTable = .{};
|
||||
const Self = @This();
|
||||
pub const ObjectType: vk.ObjectType = .instance;
|
||||
|
||||
object: Object,
|
||||
//physical_devices: std.ArrayList(*PhysicalDevice),
|
||||
alloc_callbacks: vk.AllocationCallbacks,
|
||||
alloc_callbacks: vk.AllocationCallbacks,
|
||||
|
||||
pub const VTable = struct {
|
||||
createInstance: ?vk.PfnCreateInstance = null,
|
||||
destroyInstance: ?vk.PfnDestroyInstance = null,
|
||||
enumeratePhysicalDevices: ?vk.PfnEnumeratePhysicalDevices = null,
|
||||
getInstanceProcAddr: ?vk.PfnGetInstanceProcAddr = null,
|
||||
enumerateInstanceVersion: ?vk.PfnEnumerateInstanceVersion = null,
|
||||
//enumerateInstanceLayerProperties: vk.PfnEnumerateInstanceProperties = null,
|
||||
enumerateInstanceExtensionProperties: ?vk.PfnEnumerateInstanceExtensionProperties = null,
|
||||
vtable: VTable,
|
||||
|
||||
pub fn init(self: *Self, p_infos: ?*const vk.InstanceCreateInfo, callbacks: ?*const vk.AllocationCallbacks) !void {
|
||||
const infos = p_infos orelse return error.NullCreateInfos;
|
||||
if (infos.s_type != .instance_create_info) {
|
||||
return error.InvalidCreateInfos;
|
||||
}
|
||||
|
||||
self.vtable = .{
|
||||
.destroyInstance = null,
|
||||
.enumeratePhysicalDevices = null,
|
||||
.enumerateInstanceVersion = null,
|
||||
//.enumerateInstanceLayerProperties = null,
|
||||
.enumerateInstanceExtensionProperties = null,
|
||||
};
|
||||
|
||||
if (callbacks) |c| {
|
||||
self.alloc_callbacks = c.*;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getProcAddr(self: *const Self, name: []const u8) vk.PfnVoidFunction {
|
||||
const allocator = std.heap.c_allocator;
|
||||
|
||||
const KV = struct { []const u8, vk.PfnVoidFunction };
|
||||
const pfn_map = std.StaticStringMap(vk.PfnVoidFunction).init([_]KV{
|
||||
.{ "vkDestroyInstance", @ptrCast(self.vtable.destroyInstance) },
|
||||
.{ "vkEnumeratePhysicalDevices", @ptrCast(self.vtable.enumeratePhysicalDevices) },
|
||||
.{ "vkEnumerateInstanceVersion", @ptrCast(self.vtable.enumerateInstanceVersion) },
|
||||
.{ "vkEnumerateInstanceExtensionProperties", @ptrCast(self.vtable.enumerateInstanceExtensionProperties) },
|
||||
}, allocator) catch return null;
|
||||
defer pfn_map.deinit(allocator);
|
||||
|
||||
return if (pfn_map.get(name)) |pfn| pfn else null;
|
||||
}
|
||||
|
||||
pub const VTable = struct {
|
||||
destroyInstance: ?vk.PfnDestroyInstance,
|
||||
enumeratePhysicalDevices: ?vk.PfnEnumeratePhysicalDevices,
|
||||
enumerateInstanceVersion: ?vk.PfnEnumerateInstanceVersion,
|
||||
//enumerateInstanceLayerProperties: vk.PfnEnumerateInstanceProperties,
|
||||
enumerateInstanceExtensionProperties: ?vk.PfnEnumerateInstanceExtensionProperties,
|
||||
};
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
const vk = @import("vulkan");
|
||||
const Instance = @import("Instance.zig").Instance;
|
||||
const Object = @import("object.zig").Object;
|
||||
const Instance = @import("Instance.zig");
|
||||
|
||||
pub const PhysicalDevice = extern struct {
|
||||
const Self = @This();
|
||||
const ObjectType: vk.ObjectType = .physical_device;
|
||||
const Self = @This();
|
||||
const ObjectType: vk.ObjectType = .physical_device;
|
||||
|
||||
object: Object,
|
||||
|
||||
instance: *Instance,
|
||||
props: vk.PhysicalDeviceProperties,
|
||||
queue_families: [3]vk.QueueFamilyProperties,
|
||||
};
|
||||
props: vk.PhysicalDeviceProperties,
|
||||
queue_families: [3]vk.QueueFamilyProperties,
|
||||
|
||||
45
src/vulkan/dispatchable.zig
git.filemode.normal_file
45
src/vulkan/dispatchable.zig
git.filemode.normal_file
@@ -0,0 +1,45 @@
|
||||
const std = @import("std");
|
||||
const vk = @import("vulkan");
|
||||
const c = @cImport({
|
||||
@cInclude("vulkan/vk_icd.h");
|
||||
});
|
||||
|
||||
pub fn Dispatchable(comptime T: type) type {
|
||||
return extern struct {
|
||||
const Self = @This();
|
||||
|
||||
loader_data: c.VK_LOADER_DATA,
|
||||
object_type: vk.ObjectType,
|
||||
object: *T,
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator, object_type: vk.ObjectType) !*Self {
|
||||
const object = try allocator.create(Self);
|
||||
object.* = .{
|
||||
.loader_data = .{ .loaderMagic = c.ICD_LOADER_MAGIC },
|
||||
.object_type = object_type,
|
||||
.object = try allocator.create(T),
|
||||
};
|
||||
return object;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *Self, allocator: std.mem.Allocator) void {
|
||||
allocator.destroy(self.object);
|
||||
allocator.destroy(self);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub inline fn fromHandle(comptime T: type, handle: usize) !*Dispatchable(T) {
|
||||
if (handle == 0) {
|
||||
return error.NullHandle;
|
||||
}
|
||||
const dispatchable: *Dispatchable(T) = @ptrFromInt(handle);
|
||||
if (dispatchable.object_type != T.ObjectType) {
|
||||
return error.InvalidType;
|
||||
}
|
||||
return dispatchable;
|
||||
}
|
||||
|
||||
pub inline fn toHandle(comptime T: type, handle: *Dispatchable(T)) usize {
|
||||
return @intFromPtr(handle);
|
||||
}
|
||||
@@ -4,18 +4,25 @@ const c = @cImport({
|
||||
@cInclude("vulkan/vk_icd.h");
|
||||
});
|
||||
|
||||
const Instance = @import("Instance.zig").Instance;
|
||||
const fromHandle = @import("object.zig").fromHandle;
|
||||
const Instance = @import("Instance.zig");
|
||||
const dispatchable = @import("dispatchable.zig");
|
||||
|
||||
const global_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{
|
||||
.{ "vkGetInstanceProcAddr", @as(vk.PfnVoidFunction, @ptrCast(&getInstanceProcAddr)) },
|
||||
.{ "vkCreateInstance", @as(vk.PfnVoidFunction, @ptrCast(&Instance.vtable.createInstance)) },
|
||||
});
|
||||
pub fn getInstanceProcAddr(global_pfn_map: std.StaticStringMap(vk.PfnVoidFunction), p_instance: vk.Instance, name: []const u8) vk.PfnVoidFunction {
|
||||
const allocator = std.heap.c_allocator;
|
||||
const get_proc_log = std.log.scoped(.vkGetInstanceProcAddr);
|
||||
|
||||
if (std.process.hasEnvVar(allocator, "DRIVER_LOGS") catch false) {
|
||||
get_proc_log.info("Loading {s}...", .{name});
|
||||
}
|
||||
|
||||
pub fn getInstanceProcAddr(instance: vk.Instance, name: []const u8) vk.PfnVoidFunction {
|
||||
if (global_pfn_map.get(name)) |pfn| {
|
||||
return pfn;
|
||||
}
|
||||
if (instance != .null_handle) {}
|
||||
return null;
|
||||
const instance = dispatchable.fromHandle(Instance, @intFromEnum(p_instance)) catch |e| {
|
||||
if (std.process.hasEnvVar(allocator, "DRIVER_LOGS") catch false) {
|
||||
get_proc_log.err("{any}", .{e});
|
||||
}
|
||||
return null;
|
||||
};
|
||||
return instance.object.getProcAddr(name);
|
||||
}
|
||||
|
||||
@@ -2,15 +2,23 @@ const std = @import("std");
|
||||
const vk = @import("vulkan");
|
||||
|
||||
pub const icd = @import("icd.zig");
|
||||
pub const dispatchable = @import("dispatchable.zig");
|
||||
|
||||
pub const Instance = @import("Instance.zig");
|
||||
pub const PhysicalDevice = @import("PhysicalDevice.zig");
|
||||
|
||||
pub export fn vkGetInstanceProcAddr(instance: vk.Instance, pName: ?[*:0]const u8) callconv(vk.vulkan_call_conv) vk.PfnVoidFunction {
|
||||
if (pName == null) {
|
||||
return null;
|
||||
}
|
||||
const name = std.mem.span(pName.?);
|
||||
return icd.getInstanceProcAddr(instance, name);
|
||||
pub const std_options: std.Options = .{
|
||||
.log_level = .info,
|
||||
.logFn = logFn,
|
||||
};
|
||||
|
||||
pub fn logFn(comptime level: std.log.Level, comptime scope: @Type(.enum_literal), comptime format: []const u8, args: anytype) void {
|
||||
_ = level;
|
||||
_ = scope;
|
||||
std.debug.lockStdErr();
|
||||
defer std.debug.unlockStdErr();
|
||||
const stderr = std.fs.File.stderr().deprecatedWriter();
|
||||
nosuspend stderr.print(format ++ "\n", args) catch return;
|
||||
}
|
||||
|
||||
test {
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
const vk = @import("vulkan");
|
||||
const c = @cImport({
|
||||
@cInclude("vulkan/vk_icd.h");
|
||||
});
|
||||
|
||||
pub const Object = extern struct {
|
||||
const Self = @This();
|
||||
|
||||
loader_data: c.VK_LOADER_DATA,
|
||||
kind: vk.ObjectType,
|
||||
owner: ?*anyopaque,
|
||||
// VK_EXT_debug_utils
|
||||
name: ?[*]const u8,
|
||||
|
||||
pub fn init(owner: ?*anyopaque, kind: vk.ObjectType) Self {
|
||||
return .{
|
||||
.loader_data = c.ICD_LOADER_MAGIC,
|
||||
.kind = kind,
|
||||
.owner = owner,
|
||||
.name = null,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub inline fn fromHandle(comptime T: type, comptime VkT: type, handle: VkT) !*T {
|
||||
comptime {
|
||||
if (!@hasField(T, "object") or !@hasDecl(T, "ObjectType") or @TypeOf(T.ObjectType) != vk.ObjectType) {
|
||||
@compileError("Object type \"" ++ @typeName(T) ++ "\" is malformed.");
|
||||
}
|
||||
}
|
||||
|
||||
if (handle == .null_handle) {
|
||||
return error.NullHandle;
|
||||
}
|
||||
|
||||
const dispatchable: *T = @ptrFromInt(@intFromEnum(handle));
|
||||
if (dispatchable.object.kind != T.ObjectType) {
|
||||
return error.InvalidObjectType;
|
||||
}
|
||||
return dispatchable;
|
||||
}
|
||||
|
||||
pub inline fn toHandle(comptime T: type, handle: *T) usize {
|
||||
comptime {
|
||||
if (!@hasDecl(T, "object") or !@hasDecl(T, "ObjectType") or @TypeOf(T.ObjectType) != vk.ObjectType) {
|
||||
@compileError("Object type \"" ++ @typeName(T) ++ "\" is malformed.");
|
||||
}
|
||||
}
|
||||
return @intFromPtr(handle);
|
||||
}
|
||||
Reference in New Issue
Block a user