architectural rework
This commit is contained in:
23
.gdb_history
23
.gdb_history
@@ -97,3 +97,26 @@ q
|
||||
run
|
||||
bt
|
||||
q
|
||||
run
|
||||
bt
|
||||
q
|
||||
run
|
||||
b
|
||||
bt
|
||||
q
|
||||
run
|
||||
bt
|
||||
q
|
||||
run
|
||||
bt
|
||||
q
|
||||
run
|
||||
bt
|
||||
q
|
||||
run
|
||||
bt
|
||||
q
|
||||
run
|
||||
bt
|
||||
q
|
||||
q
|
||||
|
||||
21
build.zig
21
build.zig
@@ -15,33 +15,25 @@ const implementations = [_]ImplementationDesc{
|
||||
},
|
||||
};
|
||||
|
||||
pub fn build(b: *std.Build) !void {
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const common_mod = b.createModule(.{
|
||||
const base_mod = b.createModule(.{
|
||||
.root_source_file = b.path("src/vulkan/lib.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.link_libc = true,
|
||||
});
|
||||
|
||||
const interface_dependency = b.dependency("interface", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
const vulkan_headers = b.dependency("vulkan_headers", .{});
|
||||
|
||||
const vulkan = b.dependency("vulkan_zig", .{
|
||||
.registry = vulkan_headers.path("registry/vk.xml"),
|
||||
}).module("vulkan-zig");
|
||||
|
||||
const interface_mod = interface_dependency.module("interface");
|
||||
|
||||
common_mod.addImport("vulkan", vulkan);
|
||||
common_mod.addImport("interface", interface_mod);
|
||||
common_mod.addSystemIncludePath(vulkan_headers.path("include"));
|
||||
base_mod.addImport("vulkan", vulkan);
|
||||
base_mod.addSystemIncludePath(vulkan_headers.path("include"));
|
||||
|
||||
for (implementations) |impl| {
|
||||
const lib_mod = b.createModule(.{
|
||||
@@ -50,16 +42,15 @@ pub fn build(b: *std.Build) !void {
|
||||
.link_libc = true,
|
||||
.optimize = optimize,
|
||||
.imports = &.{
|
||||
.{ .name = "common", .module = common_mod },
|
||||
.{ .name = "base", .module = base_mod },
|
||||
.{ .name = "vulkan", .module = vulkan },
|
||||
.{ .name = "interface", .module = interface_mod },
|
||||
},
|
||||
});
|
||||
|
||||
lib_mod.addSystemIncludePath(vulkan_headers.path("include"));
|
||||
|
||||
if (impl.custom) |custom| {
|
||||
try custom(b, lib_mod);
|
||||
custom(b, lib_mod) catch continue;
|
||||
}
|
||||
|
||||
const lib = b.addLibrary(.{
|
||||
|
||||
@@ -18,10 +18,6 @@
|
||||
.hash = "cpuinfo-0.1.0-V7dMLcghAADJuG7dkd3MnwDPZ232pBK_8uGjxY43eP5u",
|
||||
.lazy = true,
|
||||
},
|
||||
.interface = .{
|
||||
.url = "git+https://github.com/nilslice/zig-interface#19f2c937b77e42b15bc8cacaa2894ce5b783d94d",
|
||||
.hash = "interface-0.0.2-GFlWJ7KOAQAkHikqZU0XV86AhX7R9jCyGza85lTIqcEU",
|
||||
},
|
||||
},
|
||||
|
||||
.paths = .{
|
||||
|
||||
0
compile_commands.json
git.filemode.normal_file
0
compile_commands.json
git.filemode.normal_file
@@ -1,55 +1,40 @@
|
||||
const std = @import("std");
|
||||
const vk = @import("vulkan");
|
||||
const common = @import("common");
|
||||
const base = @import("base");
|
||||
const PhysicalDevice = @import("PhysicalDevice.zig");
|
||||
|
||||
const dispatchable = common.dispatchable;
|
||||
const dispatchable = base.dispatchable;
|
||||
const VulkanAllocator = base.VulkanAllocator;
|
||||
|
||||
const Self = @This();
|
||||
pub const ObjectType: vk.ObjectType = .instance;
|
||||
|
||||
common_instance: common.Instance,
|
||||
physical_device: vk.PhysicalDevice, // Software driver only has one physical device (CPU)
|
||||
export fn __vkImplInstanceInit(base_instance: *base.Instance, allocator: *const std.mem.Allocator) ?*anyopaque {
|
||||
return realVkImplInstanceInit(base_instance, allocator.*) catch return null;
|
||||
}
|
||||
|
||||
pub fn create(p_infos: ?*const vk.InstanceCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_instance: *vk.Instance) callconv(vk.vulkan_call_conv) vk.Result {
|
||||
const allocator = std.heap.c_allocator;
|
||||
|
||||
const dispatchable_instance = dispatchable.Dispatchable(Self).create(allocator) catch return .error_out_of_host_memory;
|
||||
const instance = dispatchable_instance.object;
|
||||
common.Instance.init(&instance.common_instance, p_infos, callbacks) catch return .error_initialization_failed;
|
||||
|
||||
instance.common_instance.vtable = .{
|
||||
.destroyInstance = destroy,
|
||||
.enumeratePhysicalDevices = enumeratePhysicalDevices,
|
||||
// Pure Zig implementation to leverage `errdefer` and avoid memory leaks or complex resources handling
|
||||
fn realVkImplInstanceInit(base_instance: *base.Instance, allocator: std.mem.Allocator) !?*anyopaque {
|
||||
base_instance.dispatch_table = .{
|
||||
.destroyInstance = deinit,
|
||||
.enumerateInstanceVersion = null,
|
||||
//.enumerateInstanceLayerProperties = null,
|
||||
.enumerateInstanceExtensionProperties = null,
|
||||
.getPhysicalDeviceProperties = PhysicalDevice.getProperties,
|
||||
};
|
||||
|
||||
const dispatchable_physical_device = dispatchable.Dispatchable(PhysicalDevice).create(allocator) catch return .error_out_of_host_memory;
|
||||
PhysicalDevice.init(dispatchable_physical_device.object) catch return .error_initialization_failed;
|
||||
instance.physical_device = @enumFromInt(dispatchable_physical_device.toHandle());
|
||||
// Software driver only has one physical device (the CPU)
|
||||
const dispatchable_physical_device = try PhysicalDevice.init(base_instance, allocator);
|
||||
errdefer dispatchable_physical_device.destroy(allocator);
|
||||
|
||||
p_instance.* = @enumFromInt(dispatchable_instance.toHandle());
|
||||
return .success;
|
||||
try base_instance.physical_devices.append(allocator, @enumFromInt(dispatchable_physical_device.toHandle()));
|
||||
|
||||
const self = try allocator.create(Self);
|
||||
errdefer allocator.destroy(self);
|
||||
return @ptrCast(self);
|
||||
}
|
||||
|
||||
pub fn enumeratePhysicalDevices(p_instance: vk.Instance, count: *u32, p_devices: ?[*]vk.PhysicalDevice) callconv(vk.vulkan_call_conv) vk.Result {
|
||||
const instance = dispatchable.fromHandleObject(Self, @intFromEnum(p_instance)) catch return .error_initialization_failed;
|
||||
count.* = 1;
|
||||
if (p_devices) |devices| {
|
||||
devices[0] = instance.physical_device;
|
||||
pub fn deinit(base_instance: *const base.Instance, allocator: std.mem.Allocator) !void {
|
||||
for (base_instance.physical_devices.items) |physical_device| {
|
||||
const dispatchable_physical_device = try dispatchable.fromHandle(base.PhysicalDevice, @intFromEnum(physical_device));
|
||||
dispatchable_physical_device.destroy(allocator);
|
||||
}
|
||||
return .success;
|
||||
}
|
||||
|
||||
pub fn destroy(p_instance: vk.Instance, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void {
|
||||
const allocator = std.heap.c_allocator;
|
||||
_ = callbacks;
|
||||
|
||||
const dispatchable_instance = dispatchable.fromHandle(Self, @intFromEnum(p_instance)) catch return;
|
||||
const dispatchable_physical_device = dispatchable.fromHandle(PhysicalDevice, @intFromEnum(dispatchable_instance.object.physical_device)) catch return;
|
||||
dispatchable_physical_device.destroy(allocator);
|
||||
dispatchable_instance.destroy(allocator);
|
||||
}
|
||||
|
||||
@@ -1,41 +1,30 @@
|
||||
const std = @import("std");
|
||||
const vk = @import("vulkan");
|
||||
const Instance = @import("Instance.zig");
|
||||
const common = @import("common");
|
||||
const base = @import("base");
|
||||
const root = @import("root");
|
||||
const cpuinfo = @import("cpuinfo");
|
||||
|
||||
const dispatchable = common.dispatchable;
|
||||
const dispatchable = base.dispatchable;
|
||||
|
||||
const Self = @This();
|
||||
pub const ObjectType: vk.ObjectType = .physical_device;
|
||||
|
||||
instance: *const Instance,
|
||||
common_physical_device: common.PhysicalDevice,
|
||||
pub fn init(instance: *const base.Instance, allocator: std.mem.Allocator) !*dispatchable.Dispatchable(base.PhysicalDevice) {
|
||||
const dispatchable_physical_device = try base.PhysicalDevice.init(instance, allocator);
|
||||
errdefer dispatchable_physical_device.destroy(allocator);
|
||||
|
||||
pub fn init(self: *Self) !void {
|
||||
const allocator = std.heap.c_allocator;
|
||||
const base_physical_device = dispatchable_physical_device.object;
|
||||
|
||||
self.common_physical_device.props = .{
|
||||
.api_version = @bitCast(root.VULKAN_VERSION),
|
||||
.driver_version = @bitCast(root.DRIVER_VERSION),
|
||||
.vendor_id = common.VULKAN_VENDOR_ID,
|
||||
.device_id = root.DEVICE_ID,
|
||||
.device_type = .cpu,
|
||||
.device_name = [_]u8{0} ** vk.MAX_PHYSICAL_DEVICE_NAME_SIZE,
|
||||
.pipeline_cache_uuid = undefined,
|
||||
.limits = undefined,
|
||||
.sparse_properties = undefined,
|
||||
};
|
||||
base_physical_device.props.api_version = @bitCast(root.VULKAN_VERSION);
|
||||
base_physical_device.props.driver_version = @bitCast(root.DRIVER_VERSION);
|
||||
base_physical_device.props.device_id = root.DEVICE_ID;
|
||||
base_physical_device.props.device_type = .cpu;
|
||||
|
||||
const info = try cpuinfo.get(allocator);
|
||||
defer info.deinit(allocator);
|
||||
|
||||
var writer = std.io.Writer.fixed(self.common_physical_device.props.device_name[0 .. vk.MAX_PHYSICAL_DEVICE_NAME_SIZE - 1]);
|
||||
var writer = std.io.Writer.fixed(base_physical_device.props.device_name[0 .. vk.MAX_PHYSICAL_DEVICE_NAME_SIZE - 1]);
|
||||
try writer.print("{s} [Soft Vulkan Driver]", .{info.name});
|
||||
}
|
||||
|
||||
pub fn getProperties(p_physical_device: vk.PhysicalDevice, properties: *vk.PhysicalDeviceProperties) callconv(vk.vulkan_call_conv) void {
|
||||
const physical_device = dispatchable.fromHandleObject(Self, @intFromEnum(p_physical_device)) catch return;
|
||||
properties.* = physical_device.common_physical_device.props;
|
||||
return dispatchable_physical_device;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const std = @import("std");
|
||||
const vk = @import("vulkan");
|
||||
const common = @import("common");
|
||||
const base = @import("base");
|
||||
|
||||
const Instance = @import("Instance.zig");
|
||||
|
||||
@@ -8,15 +8,7 @@ pub const VULKAN_VERSION = vk.makeApiVersion(0, 1, 0, 0);
|
||||
pub const DRIVER_VERSION = vk.makeApiVersion(0, 0, 0, 1);
|
||||
pub const DEVICE_ID = 0x600DCAFE;
|
||||
|
||||
const global_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{
|
||||
.{ "vkGetInstanceProcAddr", @as(vk.PfnVoidFunction, @ptrCast(&common.icd.getInstanceProcAddr)) },
|
||||
.{ "vkCreateInstance", @as(vk.PfnVoidFunction, @ptrCast(&Instance.create)) },
|
||||
});
|
||||
|
||||
pub export fn vkGetInstanceProcAddr(p_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 common.icd.getInstanceProcAddr(global_pfn_map, p_instance, name);
|
||||
comptime {
|
||||
_ = base;
|
||||
_ = Instance;
|
||||
}
|
||||
|
||||
@@ -1,48 +1,85 @@
|
||||
const std = @import("std");
|
||||
const vk = @import("vulkan");
|
||||
const root = @import("lib.zig");
|
||||
const dispatchable = @import("dispatchable.zig");
|
||||
const VulkanAllocator = @import("VulkanAllocator.zig");
|
||||
const PhysicalDevice = @import("PhysicalDevice.zig");
|
||||
|
||||
extern fn __vkImplInstanceInit(*Self, *const std.mem.Allocator) ?*anyopaque;
|
||||
|
||||
const Self = @This();
|
||||
pub const ObjectType: vk.ObjectType = .instance;
|
||||
|
||||
alloc_callbacks: vk.AllocationCallbacks,
|
||||
alloc_callbacks: ?vk.AllocationCallbacks,
|
||||
physical_devices: std.ArrayList(vk.PhysicalDevice),
|
||||
dispatch_table: DispatchTable,
|
||||
driver_data: ?*anyopaque,
|
||||
|
||||
vtable: VTable,
|
||||
pub const DispatchTable = struct {
|
||||
destroyInstance: ?*const fn (*const Self, std.mem.Allocator) anyerror!void = null,
|
||||
enumerateInstanceVersion: ?vk.PfnEnumerateInstanceVersion = null,
|
||||
//enumerateInstanceLayerProperties: vk.PfnEnumerateInstanceProperties = null,
|
||||
enumerateInstanceExtensionProperties: ?vk.PfnEnumerateInstanceExtensionProperties = null,
|
||||
};
|
||||
|
||||
pub fn init(self: *Self, p_infos: ?*const vk.InstanceCreateInfo, callbacks: ?*const vk.AllocationCallbacks) !void {
|
||||
const infos = p_infos orelse return error.NullCreateInfos;
|
||||
pub fn create(p_infos: ?*const vk.InstanceCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_instance: *vk.Instance) callconv(vk.vulkan_call_conv) vk.Result {
|
||||
const infos = p_infos orelse return .error_initialization_failed;
|
||||
if (infos.s_type != .instance_create_info) {
|
||||
return error.InvalidCreateInfos;
|
||||
return .error_initialization_failed;
|
||||
}
|
||||
|
||||
self.vtable = .{};
|
||||
const deref_callbacks = if (callbacks) |c| c.* else null;
|
||||
|
||||
if (callbacks) |c| {
|
||||
self.alloc_callbacks = c.*;
|
||||
const allocator = VulkanAllocator.init(deref_callbacks, .instance).allocator();
|
||||
|
||||
const dispatchable_instance = dispatchable.Dispatchable(Self).create(allocator) catch return .error_out_of_host_memory;
|
||||
const self = dispatchable_instance.object;
|
||||
self.dispatch_table = .{};
|
||||
|
||||
self.alloc_callbacks = deref_callbacks;
|
||||
self.physical_devices = .empty;
|
||||
|
||||
self.driver_data = __vkImplInstanceInit(self, &allocator) orelse return .error_initialization_failed;
|
||||
std.debug.assert(self.physical_devices.items.len != 0);
|
||||
|
||||
p_instance.* = @enumFromInt(dispatchable_instance.toHandle());
|
||||
return .success;
|
||||
}
|
||||
|
||||
pub fn destroy(p_instance: vk.Instance, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void {
|
||||
const allocator = VulkanAllocator.init(if (callbacks) |c| c.* else null, .instance).allocator();
|
||||
|
||||
const dispatchable_instance = dispatchable.fromHandle(Self, @intFromEnum(p_instance)) catch return;
|
||||
defer dispatchable_instance.destroy(allocator);
|
||||
|
||||
const self: *const Self = @ptrCast(dispatchable_instance.object);
|
||||
if (self.dispatch_table.destroyInstance) |pfnDestroyInstance| {
|
||||
pfnDestroyInstance(self, allocator) catch return;
|
||||
} else if (std.process.hasEnvVar(allocator, root.DRIVER_LOGS_ENV_NAME) catch false) {
|
||||
std.log.scoped(.vkDestroyInstance).warn("Missing dispatch implementation", .{});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getProcAddr(self: *const Self, name: []const u8) vk.PfnVoidFunction {
|
||||
pub fn enumeratePhysicalDevices(p_instance: vk.Instance, count: *u32, p_devices: ?[*]vk.PhysicalDevice) callconv(vk.vulkan_call_conv) vk.Result {
|
||||
const self = dispatchable.fromHandleObject(Self, @intFromEnum(p_instance)) catch return .error_unknown;
|
||||
count.* = @intCast(self.physical_devices.items.len);
|
||||
if (p_devices) |devices| {
|
||||
@memcpy(devices[0..self.physical_devices.items.len], self.physical_devices.items);
|
||||
}
|
||||
return .success;
|
||||
}
|
||||
|
||||
pub fn getProcAddr(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) },
|
||||
.{ "vkGetPhysicalDeviceProperties", @ptrCast(self.vtable.getPhysicalDeviceProperties) },
|
||||
.{ "vkDestroyInstance", @ptrCast(&destroy) },
|
||||
.{ "vkEnumeratePhysicalDevices", @ptrCast(&enumeratePhysicalDevices) },
|
||||
//.{ "vkGetPhysicalDeviceProperties", @ptrCast(self.dispatch_table.getPhysicalDeviceProperties) },
|
||||
}, allocator) catch return null;
|
||||
defer pfn_map.deinit(allocator);
|
||||
|
||||
return if (pfn_map.get(name)) |pfn| pfn else null;
|
||||
// Falling back on PhysicalDevice's getProcAddr which will return null if not found
|
||||
return if (pfn_map.get(name)) |pfn| pfn else PhysicalDevice.getProcAddr(name);
|
||||
}
|
||||
|
||||
pub const VTable = struct {
|
||||
destroyInstance: ?vk.PfnDestroyInstance = null,
|
||||
enumeratePhysicalDevices: ?vk.PfnEnumeratePhysicalDevices = null,
|
||||
enumerateInstanceVersion: ?vk.PfnEnumerateInstanceVersion = null,
|
||||
//enumerateInstanceLayerProperties: vk.PfnEnumerateInstanceProperties = null,
|
||||
enumerateInstanceExtensionProperties: ?vk.PfnEnumerateInstanceExtensionProperties = null,
|
||||
getPhysicalDeviceProperties: ?vk.PfnGetPhysicalDeviceProperties = null,
|
||||
};
|
||||
|
||||
@@ -1,8 +1,57 @@
|
||||
const std = @import("std");
|
||||
const vk = @import("vulkan");
|
||||
const root = @import("lib.zig");
|
||||
const Instance = @import("Instance.zig");
|
||||
const dispatchable = @import("dispatchable.zig");
|
||||
|
||||
const Self = @This();
|
||||
pub const ObjectType: vk.ObjectType = .physical_device;
|
||||
|
||||
props: vk.PhysicalDeviceProperties,
|
||||
queue_families: [3]vk.QueueFamilyProperties,
|
||||
instance: *const Instance,
|
||||
dispatch_table: DispatchTable,
|
||||
driver_data: ?*anyopaque,
|
||||
|
||||
pub const DispatchTable = struct {};
|
||||
|
||||
pub fn init(instance: *const Instance, allocator: std.mem.Allocator) !*dispatchable.Dispatchable(Self) {
|
||||
const dispatchable_physical_device = try dispatchable.Dispatchable(Self).create(allocator);
|
||||
errdefer dispatchable_physical_device.destroy(allocator);
|
||||
|
||||
const self = dispatchable_physical_device.object;
|
||||
|
||||
self.props = .{
|
||||
.api_version = undefined,
|
||||
.driver_version = undefined,
|
||||
.vendor_id = root.VULKAN_VENDOR_ID,
|
||||
.device_id = undefined,
|
||||
.device_type = undefined,
|
||||
.device_name = [_]u8{0} ** vk.MAX_PHYSICAL_DEVICE_NAME_SIZE,
|
||||
.pipeline_cache_uuid = undefined,
|
||||
.limits = undefined,
|
||||
.sparse_properties = undefined,
|
||||
};
|
||||
|
||||
self.driver_data = null;
|
||||
self.instance = instance;
|
||||
self.dispatch_table = .{};
|
||||
|
||||
return dispatchable_physical_device;
|
||||
}
|
||||
|
||||
pub fn getProperties(p_physical_device: vk.PhysicalDevice, properties: *vk.PhysicalDeviceProperties) callconv(vk.vulkan_call_conv) void {
|
||||
const self = dispatchable.fromHandleObject(Self, @intFromEnum(p_physical_device)) catch return;
|
||||
properties.* = self.props;
|
||||
}
|
||||
|
||||
pub fn getProcAddr(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{
|
||||
.{ "vkGetPhysicalDeviceProperties", @ptrCast(&getProperties) },
|
||||
}, allocator) catch return null;
|
||||
defer pfn_map.deinit(allocator);
|
||||
|
||||
return if (pfn_map.get(name)) |pfn| pfn else null;
|
||||
}
|
||||
|
||||
65
src/vulkan/VulkanAllocator.zig
git.filemode.normal_file
65
src/vulkan/VulkanAllocator.zig
git.filemode.normal_file
@@ -0,0 +1,65 @@
|
||||
const std = @import("std");
|
||||
const vk = @import("vulkan");
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Alignment = std.mem.Alignment;
|
||||
|
||||
/// A Zig allocator from VkAllocationCallbacks.
|
||||
/// Falls back on c_allocator if callbacks passed are null
|
||||
const Self = @This();
|
||||
|
||||
callbacks: ?vk.AllocationCallbacks,
|
||||
scope: vk.SystemAllocationScope,
|
||||
|
||||
pub fn init(callbacks: ?vk.AllocationCallbacks, scope: vk.SystemAllocationScope) Self {
|
||||
return .{
|
||||
.callbacks = callbacks,
|
||||
.scope = scope,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn allocator(self: *const Self) Allocator {
|
||||
if (self.callbacks == null) {
|
||||
return std.heap.c_allocator; // TODO: fallback on a better allocator
|
||||
}
|
||||
return .{
|
||||
.ptr = @constCast(self),
|
||||
.vtable = &.{
|
||||
.alloc = alloc,
|
||||
.resize = resize,
|
||||
.remap = remap,
|
||||
.free = free,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
fn alloc(context: *anyopaque, len: usize, alignment: Alignment, _: usize) ?[*]u8 {
|
||||
const self: *Self = @ptrCast(@alignCast(context));
|
||||
if (self.callbacks.?.pfn_allocation) |pfn_allocation| {
|
||||
return @ptrCast(pfn_allocation(self.callbacks.?.p_user_data, len, alignment.toByteUnits(), self.scope));
|
||||
}
|
||||
@panic("Null PFN_vkAllocationFunction passed to VkAllocationCallbacks");
|
||||
}
|
||||
|
||||
fn resize(context: *anyopaque, ptr: []u8, alignment: Alignment, new_len: usize, _: usize) bool {
|
||||
_ = alignment;
|
||||
_ = context;
|
||||
return new_len <= ptr.len;
|
||||
}
|
||||
|
||||
fn remap(context: *anyopaque, ptr: []u8, alignment: Alignment, new_len: usize, _: usize) ?[*]u8 {
|
||||
const self: *Self = @ptrCast(@alignCast(context));
|
||||
if (self.callbacks.?.pfn_reallocation) |pfn_reallocation| {
|
||||
return @ptrCast(pfn_reallocation(self.callbacks.?.p_user_data, ptr.ptr, new_len, alignment.toByteUnits(), self.scope));
|
||||
}
|
||||
@panic("Null PFN_vkReallocationFunction passed to VkAllocationCallbacks");
|
||||
}
|
||||
|
||||
fn free(context: *anyopaque, ptr: []u8, alignment: Alignment, _: usize) void {
|
||||
_ = alignment;
|
||||
const self: *Self = @ptrCast(@alignCast(context));
|
||||
if (self.callbacks.?.pfn_free) |pfn_free| {
|
||||
return pfn_free(self.callbacks.?.p_user_data, ptr.ptr);
|
||||
}
|
||||
@panic("Null PFN_vkFreeFunction passed to VkAllocationCallbacks");
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
const std = @import("std");
|
||||
const vk = @import("vulkan");
|
||||
const root = @import("lib.zig");
|
||||
const c = @cImport({
|
||||
@cInclude("vulkan/vk_icd.h");
|
||||
});
|
||||
@@ -11,18 +12,20 @@ pub fn getInstanceProcAddr(global_pfn_map: std.StaticStringMap(vk.PfnVoidFunctio
|
||||
const allocator = std.heap.c_allocator;
|
||||
const get_proc_log = std.log.scoped(.vkGetInstanceProcAddr);
|
||||
|
||||
if (std.process.hasEnvVar(allocator, "DRIVER_LOGS") catch false) {
|
||||
if (std.process.hasEnvVar(allocator, root.DRIVER_LOGS_ENV_NAME) catch false) {
|
||||
get_proc_log.info("Loading {s}...", .{name});
|
||||
}
|
||||
|
||||
if (global_pfn_map.get(name)) |pfn| {
|
||||
return pfn;
|
||||
}
|
||||
const instance = dispatchable.fromHandle(Instance, @intFromEnum(p_instance)) catch |e| {
|
||||
if (std.process.hasEnvVar(allocator, "DRIVER_LOGS") catch false) {
|
||||
|
||||
// Checks if instance is NULL
|
||||
_ = dispatchable.fromHandle(Instance, @intFromEnum(p_instance)) catch |e| {
|
||||
if (std.process.hasEnvVar(allocator, root.DRIVER_LOGS_ENV_NAME) catch false) {
|
||||
get_proc_log.err("{any}", .{e});
|
||||
}
|
||||
return null;
|
||||
};
|
||||
return instance.object.getProcAddr(name);
|
||||
return Instance.getProcAddr(name);
|
||||
}
|
||||
|
||||
@@ -6,8 +6,10 @@ pub const dispatchable = @import("dispatchable.zig");
|
||||
|
||||
pub const Instance = @import("Instance.zig");
|
||||
pub const PhysicalDevice = @import("PhysicalDevice.zig");
|
||||
pub const VulkanAllocator = @import("VulkanAllocator.zig");
|
||||
|
||||
pub const VULKAN_VENDOR_ID = @typeInfo(vk.VendorId).@"enum".fields[@typeInfo(vk.VendorId).@"enum".fields.len - 1].value + 1;
|
||||
pub const DRIVER_LOGS_ENV_NAME = "DRIVER_LOGS";
|
||||
|
||||
pub const std_options: std.Options = .{
|
||||
.log_level = .info,
|
||||
@@ -23,6 +25,29 @@ pub fn logFn(comptime level: std.log.Level, comptime scope: @Type(.enum_literal)
|
||||
nosuspend stderr.print(format ++ "\n", args) catch return;
|
||||
}
|
||||
|
||||
pub fn retrieveDriverDataAs(handle: anytype, comptime T: type) !*T {
|
||||
comptime {
|
||||
switch (@typeInfo(@TypeOf(handle))) {
|
||||
.pointer => |p| std.debug.assert(@hasField(p.child, "driver_data")),
|
||||
else => @compileError("Invalid type passed to 'retrieveDriverDataAs': " ++ @typeName(@TypeOf(handle))),
|
||||
}
|
||||
}
|
||||
return @ptrCast(@alignCast(@field(handle, "driver_data")));
|
||||
}
|
||||
|
||||
const global_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{
|
||||
.{ "vkGetInstanceProcAddr", @as(vk.PfnVoidFunction, @ptrCast(&icd.getInstanceProcAddr)) },
|
||||
.{ "vkCreateInstance", @as(vk.PfnVoidFunction, @ptrCast(&Instance.create)) },
|
||||
});
|
||||
|
||||
pub export fn vkGetInstanceProcAddr(p_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(global_pfn_map, p_instance, name);
|
||||
}
|
||||
|
||||
test {
|
||||
std.testing.refAllDeclsRecursive(@This());
|
||||
}
|
||||
|
||||
@@ -21,8 +21,13 @@
|
||||
|
||||
int main(void)
|
||||
{
|
||||
puts("openning ./zig-out/lib/lib" LIBVK ".so");
|
||||
void* lib = dlopen("./zig-out/lib/lib" LIBVK ".so", RTLD_NOW | RTLD_LOCAL);
|
||||
if(!lib)
|
||||
{
|
||||
fprintf(stderr, "Could not open driver lib: %s\n", dlerror());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
puts("openned ./zig-out/lib/lib" LIBVK ".so");
|
||||
|
||||
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = dlsym(lib, "vkGetInstanceProcAddr");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user