adding VK_KHR_get_physical_device_properties2 and bug fixes

This commit is contained in:
2025-12-17 17:39:20 +01:00
parent 48af5e31f0
commit 64af182ecc
13 changed files with 290 additions and 72 deletions

View File

@@ -31,6 +31,7 @@ pub fn build(b: *std.Build) !void {
}); });
const zdt = b.dependency("zdt", .{}).module("zdt"); const zdt = b.dependency("zdt", .{}).module("zdt");
const zigrc = b.dependency("zigrc", .{}).module("zigrc");
const vulkan_headers = b.dependency("vulkan_headers", .{}); const vulkan_headers = b.dependency("vulkan_headers", .{});
const vulkan_utility_libraries = b.dependency("vulkan_utility_libraries", .{}); const vulkan_utility_libraries = b.dependency("vulkan_utility_libraries", .{});
@@ -39,6 +40,7 @@ pub fn build(b: *std.Build) !void {
}).module("vulkan-zig"); }).module("vulkan-zig");
base_mod.addImport("zdt", zdt); base_mod.addImport("zdt", zdt);
base_mod.addImport("zigrc", zigrc);
base_mod.addImport("vulkan", vulkan); base_mod.addImport("vulkan", vulkan);
base_mod.addSystemIncludePath(vulkan_headers.path("include")); base_mod.addSystemIncludePath(vulkan_headers.path("include"));
base_mod.addSystemIncludePath(vulkan_utility_libraries.path("include")); base_mod.addSystemIncludePath(vulkan_utility_libraries.path("include"));
@@ -184,7 +186,7 @@ fn addCTS(b: *std.Build, target: std.Build.ResolvedTarget, impl: *const Implemen
})); }));
const mustpass = try cts.path( const mustpass = try cts.path(
b.fmt("mustpass/{}.{}.0/vk-default.txt", .{ b.fmt("mustpass/{}.{}.2/vk-default.txt", .{
impl.vulkan_version.major, impl.vulkan_version.major,
impl.vulkan_version.minor, impl.vulkan_version.minor,
}), }),

View File

@@ -29,6 +29,10 @@
.url = "git+https://github.com/Kbz-8/Vulkan-CTS-bin#19ce2da05f8176348064a9fc6688847e5f76a46e", .url = "git+https://github.com/Kbz-8/Vulkan-CTS-bin#19ce2da05f8176348064a9fc6688847e5f76a46e",
.hash = "N-V-__8AAHDV0xtS93nAGaYd7YWxBLnvHDEplwIpC29izSGa", .hash = "N-V-__8AAHDV0xtS93nAGaYd7YWxBLnvHDEplwIpC29izSGa",
}, },
.zigrc = .{
.url = "https://github.com/Aandreba/zigrc/archive/refs/tags/1.1.0.tar.gz",
.hash = "zigrc-1.0.0-lENlWzvQAACulrbkL9PVhWjFsWSkYhi7AmfSbCM-2Xlh",
},
.cpuinfo = .{ .cpuinfo = .{
.url = "git+https://github.com/Kbz-8/cpuinfo#4883954cfcec3f6c9ca9c4aaddfc26107e08726f", .url = "git+https://github.com/Kbz-8/cpuinfo#4883954cfcec3f6c9ca9c4aaddfc26107e08726f",
.hash = "cpuinfo-0.0.1-RLgIQTLRMgF4dLo8AJ-HvnpFsJe6jmXCJjMWWjil6RF1", .hash = "cpuinfo-0.0.1-RLgIQTLRMgF4dLo8AJ-HvnpFsJe6jmXCJjMWWjil6RF1",

View File

@@ -89,11 +89,13 @@ pub fn copyBuffer(interface: *Interface, src: *base.Buffer, dst: *base.Buffer, r
_ = regions; _ = regions;
} }
pub fn copyImage(interface: *Interface, src: *base.Image, dst: *base.Image, regions: []const vk.ImageCopy) VkError!void { pub fn copyImage(interface: *Interface, src: *base.Image, src_layout: vk.ImageLayout, dst: *base.Image, dst_layout: vk.ImageLayout, regions: []const vk.ImageCopy) VkError!void {
// No-op // No-op
_ = interface; _ = interface;
_ = src; _ = src;
_ = src_layout;
_ = dst; _ = dst;
_ = dst_layout;
_ = regions; _ = regions;
} }

View File

@@ -12,13 +12,26 @@ pub const Interface = base.Instance;
interface: Interface, interface: Interface,
fn castExtension(comptime ext: vk.ApiInfo) vk.ExtensionProperties {
var props: vk.ExtensionProperties = .{
.extension_name = undefined,
.spec_version = @bitCast(ext.version),
};
@memcpy(props.extension_name[0..ext.name.len], ext.name);
return props;
}
pub const EXTENSIONS = [_]vk.ExtensionProperties{
castExtension(vk.extensions.khr_get_physical_device_properties_2),
};
pub fn create(allocator: std.mem.Allocator, infos: *const vk.InstanceCreateInfo) VkError!*Interface { pub fn create(allocator: std.mem.Allocator, infos: *const vk.InstanceCreateInfo) VkError!*Interface {
const self = allocator.create(Self) catch return VkError.OutOfHostMemory; const self = allocator.create(Self) catch return VkError.OutOfHostMemory;
errdefer allocator.destroy(self); errdefer allocator.destroy(self);
self.interface = try base.Instance.init(allocator, infos); self.interface = try base.Instance.init(allocator, infos);
self.interface.dispatch_table = &.{ self.interface.dispatch_table = &.{
.destroyInstance = destroyInstance, .destroy = destroy,
}; };
self.interface.vtable = &.{ self.interface.vtable = &.{
.requestPhysicalDevices = requestPhysicalDevices, .requestPhysicalDevices = requestPhysicalDevices,
@@ -27,6 +40,11 @@ pub fn create(allocator: std.mem.Allocator, infos: *const vk.InstanceCreateInfo)
return &self.interface; return &self.interface;
} }
fn destroy(interface: *Interface, allocator: std.mem.Allocator) VkError!void {
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
allocator.destroy(self);
}
fn requestPhysicalDevices(interface: *Interface, allocator: std.mem.Allocator) VkError!void { fn requestPhysicalDevices(interface: *Interface, allocator: std.mem.Allocator) VkError!void {
// Software driver has only one physical device (the CPU) // Software driver has only one physical device (the CPU)
const physical_device = try SoftPhysicalDevice.create(allocator, interface); const physical_device = try SoftPhysicalDevice.create(allocator, interface);
@@ -42,8 +60,3 @@ fn releasePhysicalDevices(interface: *Interface, allocator: std.mem.Allocator) V
interface.physical_devices.deinit(allocator); interface.physical_devices.deinit(allocator);
interface.physical_devices = .empty; interface.physical_devices = .empty;
} }
fn destroyInstance(interface: *Interface, allocator: std.mem.Allocator) VkError!void {
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
allocator.destroy(self);
}

View File

@@ -30,6 +30,7 @@ pub fn create(allocator: std.mem.Allocator, instance: *const base.Instance) VkEr
.getFormatProperties = getFormatProperties, .getFormatProperties = getFormatProperties,
.getImageFormatProperties = getImageFormatProperties, .getImageFormatProperties = getImageFormatProperties,
.getSparseImageFormatProperties = getSparseImageFormatProperties, .getSparseImageFormatProperties = getSparseImageFormatProperties,
.getSparseImageFormatProperties2 = getSparseImageFormatProperties2,
.release = destroy, .release = destroy,
}; };
@@ -670,6 +671,7 @@ pub fn getImageFormatProperties(
}; };
} }
/// Soft does not support sparse images.
pub fn getSparseImageFormatProperties( pub fn getSparseImageFormatProperties(
interface: *Interface, interface: *Interface,
format: vk.Format, format: vk.Format,
@@ -677,14 +679,34 @@ pub fn getSparseImageFormatProperties(
samples: vk.SampleCountFlags, samples: vk.SampleCountFlags,
tiling: vk.ImageTiling, tiling: vk.ImageTiling,
usage: vk.ImageUsageFlags, usage: vk.ImageUsageFlags,
flags: vk.ImageCreateFlags, properties: ?[*]vk.SparseImageFormatProperties,
) VkError!vk.SparseImageFormatProperties { ) VkError!u32 {
_ = interface; _ = interface;
_ = format; _ = format;
_ = image_type; _ = image_type;
_ = samples; _ = samples;
_ = tiling; _ = tiling;
_ = usage; _ = usage;
_ = flags; _ = properties;
return undefined; return 0;
}
/// Soft does not support sparse images.
pub fn getSparseImageFormatProperties2(
interface: *Interface,
format: vk.Format,
image_type: vk.ImageType,
samples: vk.SampleCountFlags,
tiling: vk.ImageTiling,
usage: vk.ImageUsageFlags,
properties: ?[*]vk.SparseImageFormatProperties2,
) VkError!u32 {
_ = interface;
_ = format;
_ = image_type;
_ = samples;
_ = tiling;
_ = usage;
_ = properties;
return 0;
} }

View File

@@ -42,7 +42,7 @@ pub const DispatchTable = struct {
begin: *const fn (*Self, *const vk.CommandBufferBeginInfo) VkError!void, begin: *const fn (*Self, *const vk.CommandBufferBeginInfo) VkError!void,
clearColorImage: *const fn (*Self, *Image, vk.ImageLayout, *const vk.ClearColorValue, []const vk.ImageSubresourceRange) VkError!void, clearColorImage: *const fn (*Self, *Image, vk.ImageLayout, *const vk.ClearColorValue, []const vk.ImageSubresourceRange) VkError!void,
copyBuffer: *const fn (*Self, *Buffer, *Buffer, []const vk.BufferCopy) VkError!void, copyBuffer: *const fn (*Self, *Buffer, *Buffer, []const vk.BufferCopy) VkError!void,
copyImage: *const fn (*Self, *Image, *Image, []const vk.ImageCopy) VkError!void, copyImage: *const fn (*Self, *Image, vk.ImageLayout, *Image, vk.ImageLayout, []const vk.ImageCopy) VkError!void,
end: *const fn (*Self) VkError!void, end: *const fn (*Self) VkError!void,
fillBuffer: *const fn (*Self, *Buffer, vk.DeviceSize, vk.DeviceSize, u32) VkError!void, fillBuffer: *const fn (*Self, *Buffer, vk.DeviceSize, vk.DeviceSize, u32) VkError!void,
reset: *const fn (*Self, vk.CommandBufferResetFlags) VkError!void, reset: *const fn (*Self, vk.CommandBufferResetFlags) VkError!void,
@@ -153,14 +153,16 @@ pub inline fn copyBuffer(self: *Self, src: *Buffer, dst: *Buffer, regions: []con
try self.dispatch_table.copyBuffer(self, src, dst, regions); try self.dispatch_table.copyBuffer(self, src, dst, regions);
} }
pub inline fn copyImage(self: *Self, src: *Image, dst: *Image, regions: []const vk.ImageCopy) VkError!void { pub inline fn copyImage(self: *Self, src: *Image, src_layout: vk.ImageLayout, dst: *Image, dst_layout: vk.ImageLayout, regions: []const vk.ImageCopy) VkError!void {
const allocator = self.host_allocator.allocator(); const allocator = self.host_allocator.allocator();
self.commands.append(allocator, .{ .CopyImage = .{ self.commands.append(allocator, .{ .CopyImage = .{
.src = src, .src = src,
.src_layout = src_layout,
.dst = dst, .dst = dst,
.dst_layout = dst_layout,
.regions = allocator.dupe(vk.ImageCopy, regions) catch return VkError.OutOfHostMemory, .regions = allocator.dupe(vk.ImageCopy, regions) catch return VkError.OutOfHostMemory,
} }) catch return VkError.OutOfHostMemory; } }) catch return VkError.OutOfHostMemory;
try self.dispatch_table.copyImage(self, src, dst, regions); try self.dispatch_table.copyImage(self, src, src_layout, dst, dst_layout, regions);
} }
pub inline fn fillBuffer(self: *Self, buffer: *Buffer, offset: vk.DeviceSize, size: vk.DeviceSize, data: u32) VkError!void { pub inline fn fillBuffer(self: *Self, buffer: *Buffer, offset: vk.DeviceSize, size: vk.DeviceSize, data: u32) VkError!void {

View File

@@ -99,8 +99,8 @@ pub fn createQueues(self: *Self, allocator: std.mem.Allocator, info: *const vk.D
const queue = try self.vtable.createQueue(allocator, self, queue_info.queue_family_index, @intCast(family_ptr.items.len), queue_info.flags); const queue = try self.vtable.createQueue(allocator, self, queue_info.queue_family_index, @intCast(family_ptr.items.len), queue_info.flags);
logger.manager.get().indent(); logger.getManager().get().indent();
defer logger.manager.get().unindent(); defer logger.getManager().get().unindent();
const dispatchable_queue = try Dispatchable(Queue).wrap(allocator, queue); const dispatchable_queue = try Dispatchable(Queue).wrap(allocator, queue);
family_ptr.append(allocator, dispatchable_queue) catch return VkError.OutOfHostMemory; family_ptr.append(allocator, dispatchable_queue) catch return VkError.OutOfHostMemory;

View File

@@ -15,6 +15,9 @@ comptime {
if (!@hasDecl(root, "VULKAN_VERSION")) { if (!@hasDecl(root, "VULKAN_VERSION")) {
@compileError("Missing VULKAN_VERSION in module root"); @compileError("Missing VULKAN_VERSION in module root");
} }
if (!@hasDecl(root.Instance, "EXTENSIONS")) {
@compileError("Missing EXTENSIONS in Instance's implementation");
}
} }
} }
@@ -31,7 +34,7 @@ pub const VTable = struct {
}; };
pub const DispatchTable = struct { pub const DispatchTable = struct {
destroyInstance: *const fn (*Self, std.mem.Allocator) VkError!void, destroy: *const fn (*Self, std.mem.Allocator) VkError!void,
}; };
pub fn init(allocator: std.mem.Allocator, infos: *const vk.InstanceCreateInfo) VkError!Self { pub fn init(allocator: std.mem.Allocator, infos: *const vk.InstanceCreateInfo) VkError!Self {
@@ -53,18 +56,19 @@ pub fn create(allocator: std.mem.Allocator, infos: *const vk.InstanceCreateInfo)
pub fn deinit(self: *Self, allocator: std.mem.Allocator) VkError!void { pub fn deinit(self: *Self, allocator: std.mem.Allocator) VkError!void {
try self.releasePhysicalDevices(allocator); try self.releasePhysicalDevices(allocator);
try self.dispatch_table.destroyInstance(self, allocator); try self.dispatch_table.destroy(self, allocator);
} }
pub fn enumerateExtensionProperties(layer_name: ?[]const u8, property_count: *u32, properties: ?*vk.ExtensionProperties) VkError!void { pub fn enumerateExtensionProperties(layer_name: ?[]const u8, count: *u32, p_properties: ?[*]vk.ExtensionProperties) VkError!void {
if (layer_name) |_| { if (layer_name) |_| {
return VkError.LayerNotPresent; return VkError.LayerNotPresent;
} }
count.* = root.Instance.EXTENSIONS.len;
_ = properties; if (p_properties) |properties| {
_ = std.StaticStringMap(vk.ExtensionProperties).initComptime(.{}); for (root.Instance.EXTENSIONS, 0..) |ext, i| {
properties[i] = ext;
property_count.* = 0; }
}
} }
pub fn enumerateVersion(version: *u32) VkError!void { pub fn enumerateVersion(version: *u32) VkError!void {
@@ -80,8 +84,8 @@ pub fn releasePhysicalDevices(self: *Self, allocator: std.mem.Allocator) VkError
} }
pub fn requestPhysicalDevices(self: *Self, allocator: std.mem.Allocator) VkError!void { pub fn requestPhysicalDevices(self: *Self, allocator: std.mem.Allocator) VkError!void {
logger.manager.get().indent(); logger.getManager().get().indent();
defer logger.manager.get().unindent(); defer logger.getManager().get().unindent();
try self.vtable.requestPhysicalDevices(self, allocator); try self.vtable.requestPhysicalDevices(self, allocator);
if (self.physical_devices.items.len == 0) { if (self.physical_devices.items.len == 0) {

View File

@@ -20,7 +20,8 @@ pub const DispatchTable = struct {
createDevice: *const fn (*Self, std.mem.Allocator, *const vk.DeviceCreateInfo) VkError!*Device, createDevice: *const fn (*Self, std.mem.Allocator, *const vk.DeviceCreateInfo) VkError!*Device,
getFormatProperties: *const fn (*Self, vk.Format) VkError!vk.FormatProperties, getFormatProperties: *const fn (*Self, vk.Format) VkError!vk.FormatProperties,
getImageFormatProperties: *const fn (*Self, vk.Format, vk.ImageType, vk.ImageTiling, vk.ImageUsageFlags, vk.ImageCreateFlags) VkError!vk.ImageFormatProperties, getImageFormatProperties: *const fn (*Self, vk.Format, vk.ImageType, vk.ImageTiling, vk.ImageUsageFlags, vk.ImageCreateFlags) VkError!vk.ImageFormatProperties,
getSparseImageFormatProperties: *const fn (*Self, vk.Format, vk.ImageType, vk.SampleCountFlags, vk.ImageTiling, vk.ImageUsageFlags, vk.ImageCreateFlags) VkError!vk.SparseImageFormatProperties, getSparseImageFormatProperties: *const fn (*Self, vk.Format, vk.ImageType, vk.SampleCountFlags, vk.ImageTiling, vk.ImageUsageFlags, ?[*]vk.SparseImageFormatProperties) VkError!u32,
getSparseImageFormatProperties2: ?*const fn (*Self, vk.Format, vk.ImageType, vk.SampleCountFlags, vk.ImageTiling, vk.ImageUsageFlags, ?[*]vk.SparseImageFormatProperties2) VkError!u32,
release: *const fn (*Self, std.mem.Allocator) VkError!void, release: *const fn (*Self, std.mem.Allocator) VkError!void,
}; };
@@ -67,7 +68,7 @@ pub fn getImageFormatProperties(
usage: vk.ImageUsageFlags, usage: vk.ImageUsageFlags,
flags: vk.ImageCreateFlags, flags: vk.ImageCreateFlags,
) VkError!vk.ImageFormatProperties { ) VkError!vk.ImageFormatProperties {
return try self.dispatch_table.getImageFormatProperties(self, format, image_type, tiling, usage, flags); return self.dispatch_table.getImageFormatProperties(self, format, image_type, tiling, usage, flags);
} }
pub fn getSparseImageFormatProperties( pub fn getSparseImageFormatProperties(
@@ -77,9 +78,24 @@ pub fn getSparseImageFormatProperties(
samples: vk.SampleCountFlags, samples: vk.SampleCountFlags,
tiling: vk.ImageTiling, tiling: vk.ImageTiling,
usage: vk.ImageUsageFlags, usage: vk.ImageUsageFlags,
flags: vk.ImageCreateFlags, properties: ?[*]vk.SparseImageFormatProperties,
) VkError!vk.SparseImageFormatProperties { ) VkError!u32 {
return try self.dispatch_table.getSparseImageFormatProperties(self, format, image_type, samples, tiling, usage, flags); return self.dispatch_table.getSparseImageFormatProperties(self, format, image_type, samples, tiling, usage, properties);
}
pub fn getSparseImageFormatProperties2(
self: *Self,
format: vk.Format,
image_type: vk.ImageType,
samples: vk.SampleCountFlags,
tiling: vk.ImageTiling,
usage: vk.ImageUsageFlags,
properties: ?[*]vk.SparseImageFormatProperties2,
) VkError!u32 {
return if (self.dispatch_table.getSparseImageFormatProperties2) |pfn|
pfn(self, format, image_type, samples, tiling, usage, properties)
else
0;
} }
pub fn releasePhysicalDevice(self: *Self, allocator: std.mem.Allocator) VkError!void { pub fn releasePhysicalDevice(self: *Self, allocator: std.mem.Allocator) VkError!void {

View File

@@ -38,7 +38,9 @@ pub const CommandCopyBuffer = struct {
}; };
pub const CommandCopyImage = struct { pub const CommandCopyImage = struct {
src: *Image, src: *Image,
src_layout: vk.ImageLayout,
dst: *Image, dst: *Image,
dst_layout: vk.ImageLayout,
regions: []const vk.ImageCopy, regions: []const vk.ImageCopy,
}; };
pub const CommandDraw = struct { pub const CommandDraw = struct {

View File

@@ -46,11 +46,11 @@ pub const ShaderModule = @import("ShaderModule.zig");
fn entryPointBeginLogTrace(comptime scope: @Type(.enum_literal)) void { fn entryPointBeginLogTrace(comptime scope: @Type(.enum_literal)) void {
std.log.scoped(scope).debug("Calling {s}...", .{@tagName(scope)}); std.log.scoped(scope).debug("Calling {s}...", .{@tagName(scope)});
logger.manager.get().indent(); logger.getManager().get().indent();
} }
fn entryPointEndLogTrace() void { fn entryPointEndLogTrace() void {
logger.manager.get().unindent(); logger.getManager().get().unindent();
} }
fn entryPointNotFoundErrorLog(comptime scope: @Type(.enum_literal), name: []const u8) void { fn entryPointNotFoundErrorLog(comptime scope: @Type(.enum_literal), name: []const u8) void {
@@ -97,12 +97,19 @@ const physical_device_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComp
functionMapEntryPoint("vkCreateDevice"), functionMapEntryPoint("vkCreateDevice"),
functionMapEntryPoint("vkEnumerateDeviceExtensionProperties"), functionMapEntryPoint("vkEnumerateDeviceExtensionProperties"),
functionMapEntryPoint("vkGetPhysicalDeviceFeatures"), functionMapEntryPoint("vkGetPhysicalDeviceFeatures"),
functionMapEntryPoint("vkGetPhysicalDeviceFeatures2KHR"),
functionMapEntryPoint("vkGetPhysicalDeviceFormatProperties"), functionMapEntryPoint("vkGetPhysicalDeviceFormatProperties"),
functionMapEntryPoint("vkGetPhysicalDeviceFormatProperties2KHR"),
functionMapEntryPoint("vkGetPhysicalDeviceImageFormatProperties"), functionMapEntryPoint("vkGetPhysicalDeviceImageFormatProperties"),
functionMapEntryPoint("vkGetPhysicalDeviceImageFormatProperties2KHR"),
functionMapEntryPoint("vkGetPhysicalDeviceMemoryProperties"), functionMapEntryPoint("vkGetPhysicalDeviceMemoryProperties"),
functionMapEntryPoint("vkGetPhysicalDeviceMemoryProperties2KHR"),
functionMapEntryPoint("vkGetPhysicalDeviceProperties"), functionMapEntryPoint("vkGetPhysicalDeviceProperties"),
functionMapEntryPoint("vkGetPhysicalDeviceProperties2KHR"),
functionMapEntryPoint("vkGetPhysicalDeviceQueueFamilyProperties"), functionMapEntryPoint("vkGetPhysicalDeviceQueueFamilyProperties"),
functionMapEntryPoint("vkGetPhysicalDeviceQueueFamilyProperties2KHR"),
functionMapEntryPoint("vkGetPhysicalDeviceSparseImageFormatProperties"), functionMapEntryPoint("vkGetPhysicalDeviceSparseImageFormatProperties"),
functionMapEntryPoint("vkGetPhysicalDeviceSparseImageFormatProperties2KHR"),
}); });
const device_pfn_map = block: { const device_pfn_map = block: {
@@ -283,14 +290,11 @@ pub export fn vkGetInstanceProcAddr(p_instance: vk.Instance, p_name: ?[*:0]const
const name = std.mem.span(p_name.?); const name = std.mem.span(p_name.?);
if (global_pfn_map.get(name)) |pfn| return pfn; if (global_pfn_map.get(name)) |pfn| return pfn;
if (p_instance == .null_handle) { if (p_instance != .null_handle) {
entryPointNotFoundErrorLog(.vkGetInstanceProcAddr, name);
return null;
}
if (instance_pfn_map.get(name)) |pfn| return pfn; if (instance_pfn_map.get(name)) |pfn| return pfn;
if (physical_device_pfn_map.get(name)) |pfn| return pfn; if (physical_device_pfn_map.get(name)) |pfn| return pfn;
if (device_pfn_map.get(name)) |pfn| return pfn; if (device_pfn_map.get(name)) |pfn| return pfn;
}
entryPointNotFoundErrorLog(.vkGetInstanceProcAddr, name); entryPointNotFoundErrorLog(.vkGetInstanceProcAddr, name);
return null; return null;
} }
@@ -315,7 +319,7 @@ pub export fn strollCreateInstance(info: *const vk.InstanceCreateInfo, callbacks
return .success; return .success;
} }
pub export fn strollEnumerateInstanceExtensionProperties(p_layer_name: ?[*:0]const u8, property_count: *u32, properties: ?*vk.ExtensionProperties) callconv(vk.vulkan_call_conv) vk.Result { pub export fn strollEnumerateInstanceExtensionProperties(p_layer_name: ?[*:0]const u8, property_count: *u32, properties: ?[*]vk.ExtensionProperties) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkEnumerateInstanceExtensionProperties); entryPointBeginLogTrace(.vkEnumerateInstanceExtensionProperties);
defer entryPointEndLogTrace(); defer entryPointEndLogTrace();
@@ -338,7 +342,7 @@ pub export fn strollEnumerateInstanceVersion(version: *u32) callconv(vk.vulkan_c
// Instance functions ======================================================================================================================================== // Instance functions ========================================================================================================================================
pub export fn strollDestroyInstance(p_instance: vk.Instance, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void { pub export fn strollDestroyInstance(p_instance: vk.Instance, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void {
//defer logger.manager.deinit(); defer logger.getManager().deinit();
entryPointBeginLogTrace(.vkDestroyInstance); entryPointBeginLogTrace(.vkDestroyInstance);
defer entryPointEndLogTrace(); defer entryPointEndLogTrace();
@@ -405,6 +409,16 @@ pub export fn strollGetPhysicalDeviceFormatProperties(p_physical_device: vk.Phys
properties.* = physical_device.getFormatProperties(format) catch |err| return errorLogger(err); properties.* = physical_device.getFormatProperties(format) catch |err| return errorLogger(err);
} }
pub export fn strollGetPhysicalDeviceFormatProperties2KHR(p_physical_device: vk.PhysicalDevice, format: vk.Format, properties: *vk.FormatProperties2KHR) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkGetPhysicalDeviceFormatProperties2KHR);
defer entryPointEndLogTrace();
if (properties.s_type != .format_properties_2) return;
const physical_device = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch |err| return errorLogger(err);
properties.format_properties = physical_device.getFormatProperties(format) catch |err| return errorLogger(err);
}
pub export fn strollGetPhysicalDeviceFeatures(p_physical_device: vk.PhysicalDevice, features: *vk.PhysicalDeviceFeatures) callconv(vk.vulkan_call_conv) void { pub export fn strollGetPhysicalDeviceFeatures(p_physical_device: vk.PhysicalDevice, features: *vk.PhysicalDeviceFeatures) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkGetPhysicalDeviceFeatures); entryPointBeginLogTrace(.vkGetPhysicalDeviceFeatures);
defer entryPointEndLogTrace(); defer entryPointEndLogTrace();
@@ -413,6 +427,16 @@ pub export fn strollGetPhysicalDeviceFeatures(p_physical_device: vk.PhysicalDevi
features.* = physical_device.features; features.* = physical_device.features;
} }
pub export fn strollGetPhysicalDeviceFeatures2KHR(p_physical_device: vk.PhysicalDevice, features: *vk.PhysicalDeviceFeatures2KHR) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkGetPhysicalDeviceFeatures2KHR);
defer entryPointEndLogTrace();
if (features.s_type != .physical_device_features_2) return;
const physical_device = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch |err| return errorLogger(err);
features.features = physical_device.features;
}
pub export fn strollGetPhysicalDeviceImageFormatProperties( pub export fn strollGetPhysicalDeviceImageFormatProperties(
p_physical_device: vk.PhysicalDevice, p_physical_device: vk.PhysicalDevice,
format: vk.Format, format: vk.Format,
@@ -430,6 +454,24 @@ pub export fn strollGetPhysicalDeviceImageFormatProperties(
return .success; return .success;
} }
pub export fn strollGetPhysicalDeviceImageFormatProperties2KHR(p_physical_device: vk.PhysicalDevice, format_info: *vk.PhysicalDeviceImageFormatInfo2KHR, properties: *vk.ImageFormatProperties2KHR) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkGetPhysicalDeviceImageFormatProperties2KHR);
defer entryPointEndLogTrace();
if (format_info.s_type != .physical_device_image_format_info_2) return .error_validation_failed;
if (properties.s_type != .image_format_properties_2) return .error_validation_failed;
const physical_device = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch |err| return toVkResult(err);
properties.image_format_properties = physical_device.getImageFormatProperties(
format_info.format,
format_info.type,
format_info.tiling,
format_info.usage,
format_info.flags,
) catch |err| return toVkResult(err);
return .success;
}
pub export fn strollGetPhysicalDeviceProperties(p_physical_device: vk.PhysicalDevice, properties: *vk.PhysicalDeviceProperties) callconv(vk.vulkan_call_conv) void { pub export fn strollGetPhysicalDeviceProperties(p_physical_device: vk.PhysicalDevice, properties: *vk.PhysicalDeviceProperties) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkGetPhysicalDeviceProperties); entryPointBeginLogTrace(.vkGetPhysicalDeviceProperties);
defer entryPointEndLogTrace(); defer entryPointEndLogTrace();
@@ -438,6 +480,16 @@ pub export fn strollGetPhysicalDeviceProperties(p_physical_device: vk.PhysicalDe
properties.* = physical_device.props; properties.* = physical_device.props;
} }
pub export fn strollGetPhysicalDeviceProperties2KHR(p_physical_device: vk.PhysicalDevice, properties: *vk.PhysicalDeviceProperties2KHR) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkGetPhysicalDeviceProperties2KHR);
defer entryPointEndLogTrace();
if (properties.s_type != .physical_device_properties_2) return;
const physical_device = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch |err| return errorLogger(err);
properties.properties = physical_device.props;
}
pub export fn strollGetPhysicalDeviceMemoryProperties(p_physical_device: vk.PhysicalDevice, properties: *vk.PhysicalDeviceMemoryProperties) callconv(vk.vulkan_call_conv) void { pub export fn strollGetPhysicalDeviceMemoryProperties(p_physical_device: vk.PhysicalDevice, properties: *vk.PhysicalDeviceMemoryProperties) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkGetPhysicalDeviceMemoryProperties); entryPointBeginLogTrace(.vkGetPhysicalDeviceMemoryProperties);
defer entryPointEndLogTrace(); defer entryPointEndLogTrace();
@@ -446,6 +498,16 @@ pub export fn strollGetPhysicalDeviceMemoryProperties(p_physical_device: vk.Phys
properties.* = physical_device.mem_props; properties.* = physical_device.mem_props;
} }
pub export fn strollGetPhysicalDeviceMemoryProperties2KHR(p_physical_device: vk.PhysicalDevice, properties: *vk.PhysicalDeviceMemoryProperties2KHR) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkGetPhysicalDeviceMemoryProperties2KHR);
defer entryPointEndLogTrace();
if (properties.s_type != .physical_device_memory_properties_2) return;
const physical_device = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch |err| return errorLogger(err);
properties.memory_properties = physical_device.mem_props;
}
pub export fn strollGetPhysicalDeviceQueueFamilyProperties(p_physical_device: vk.PhysicalDevice, count: *u32, properties: ?[*]vk.QueueFamilyProperties) callconv(vk.vulkan_call_conv) void { pub export fn strollGetPhysicalDeviceQueueFamilyProperties(p_physical_device: vk.PhysicalDevice, count: *u32, properties: ?[*]vk.QueueFamilyProperties) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkGetPhysicalDeviceQueueFamilyProperties); entryPointBeginLogTrace(.vkGetPhysicalDeviceQueueFamilyProperties);
defer entryPointEndLogTrace(); defer entryPointEndLogTrace();
@@ -457,21 +519,56 @@ pub export fn strollGetPhysicalDeviceQueueFamilyProperties(p_physical_device: vk
} }
} }
pub export fn strollGetPhysicalDeviceQueueFamilyProperties2KHR(p_physical_device: vk.PhysicalDevice, count: *u32, properties: ?[*]vk.QueueFamilyProperties2KHR) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkGetPhysicalDeviceQueueFamilyProperties2KHR);
defer entryPointEndLogTrace();
const physical_device = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch |err| return errorLogger(err);
count.* = @intCast(physical_device.queue_family_props.items.len);
if (properties) |p_props| {
for (p_props[0..], physical_device.queue_family_props.items[0..], 0..count.*) |*props, device_props, _| {
if (props.s_type != .queue_family_properties_2) continue;
props.queue_family_properties = device_props;
}
}
}
pub export fn strollGetPhysicalDeviceSparseImageFormatProperties( pub export fn strollGetPhysicalDeviceSparseImageFormatProperties(
p_physical_device: vk.PhysicalDevice, p_physical_device: vk.PhysicalDevice,
format: vk.Format, format: vk.Format,
image_type: vk.ImageType, image_type: vk.ImageType,
samples: vk.SampleCountFlags, samples: vk.SampleCountFlags,
tiling: vk.ImageTiling,
usage: vk.ImageUsageFlags, usage: vk.ImageUsageFlags,
flags: vk.ImageCreateFlags, tiling: vk.ImageTiling,
properties: *vk.SparseImageFormatProperties, count: *u32,
properties: ?[*]vk.SparseImageFormatProperties,
) callconv(vk.vulkan_call_conv) vk.Result { ) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkGetPhysicalDeviceSparseImageFormatProperties); entryPointBeginLogTrace(.vkGetPhysicalDeviceSparseImageFormatProperties);
defer entryPointEndLogTrace(); defer entryPointEndLogTrace();
const physical_device = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch |err| return toVkResult(err); const physical_device = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch |err| return toVkResult(err);
properties.* = physical_device.getSparseImageFormatProperties(format, image_type, samples, tiling, usage, flags) catch |err| return toVkResult(err); count.* = physical_device.getSparseImageFormatProperties(format, image_type, samples, tiling, usage, properties) catch |err| return toVkResult(err);
return .success;
}
pub export fn strollGetPhysicalDeviceSparseImageFormatProperties2KHR(
p_physical_device: vk.PhysicalDevice,
format_info: *const vk.PhysicalDeviceSparseImageFormatInfo2KHR,
count: *u32,
properties: ?[*]vk.SparseImageFormatProperties2KHR,
) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkGetPhysicalDeviceSparseImageFormatProperties2KHR);
defer entryPointEndLogTrace();
const physical_device = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch |err| return toVkResult(err);
count.* = physical_device.getSparseImageFormatProperties2(
format_info.format,
format_info.type,
format_info.samples,
format_info.tiling,
format_info.usage,
properties,
) catch |err| return toVkResult(err);
return .success; return .success;
} }
@@ -647,14 +744,35 @@ pub export fn strollCreateComputePipelines(p_device: vk.Device, p_cache: vk.Pipe
const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err); const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err);
const cache = if (p_cache == .null_handle) null else NonDispatchable(PipelineCache).fromHandleObject(p_cache) catch |err| return toVkResult(err); const cache = if (p_cache == .null_handle) null else NonDispatchable(PipelineCache).fromHandleObject(p_cache) catch |err| return toVkResult(err);
var global_res: vk.Result = .success;
for (p_pipelines, infos, 0..count) |*p_pipeline, *info, _| { for (p_pipelines, infos, 0..count) |*p_pipeline, *info, _| {
if (info.s_type != .compute_pipeline_create_info) { if (info.s_type != .compute_pipeline_create_info) {
return .error_validation_failed; return .error_validation_failed;
} }
const pipeline = device.createComputePipeline(allocator, cache, info) catch |err| return toVkResult(err);
p_pipeline.* = (NonDispatchable(Pipeline).wrap(allocator, pipeline) catch |err| return toVkResult(err)).toVkHandle(vk.Pipeline); // According to the Vulkan spec, section 9.4. Multiple Pipeline Creation
// "When an application attempts to create many pipelines in a single command,
// it is possible that some subset may fail creation. In that case, the
// corresponding entries in the pPipelines output array will be filled with
// VK_NULL_HANDLE values. If any pipeline fails creation (for example, due to
// out of memory errors), the vkCreate*Pipelines commands will return an
// error code. The implementation will attempt to create all pipelines, and
// only return VK_NULL_HANDLE values for those that actually failed."
p_pipeline.*, const local_res = blk: {
const pipeline = device.createComputePipeline(allocator, cache, info) catch |err| break :blk .{ .null_handle, toVkResult(err) };
const handle = NonDispatchable(Pipeline).wrap(allocator, pipeline) catch |err| {
pipeline.destroy(allocator);
break :blk .{ .null_handle, toVkResult(err) };
};
break :blk .{ handle.toVkHandle(vk.Pipeline), .success };
};
if (local_res != .success) {
global_res = local_res;
} }
return .success; }
return global_res;
} }
pub export fn strollCreateDescriptorPool(p_device: vk.Device, info: *const vk.DescriptorPoolCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_pool: *vk.DescriptorPool) callconv(vk.vulkan_call_conv) vk.Result { pub export fn strollCreateDescriptorPool(p_device: vk.Device, info: *const vk.DescriptorPoolCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_pool: *vk.DescriptorPool) callconv(vk.vulkan_call_conv) vk.Result {
@@ -740,14 +858,35 @@ pub export fn strollCreateGraphicsPipelines(p_device: vk.Device, p_cache: vk.Pip
const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err); const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err);
const cache = if (p_cache == .null_handle) null else NonDispatchable(PipelineCache).fromHandleObject(p_cache) catch |err| return toVkResult(err); const cache = if (p_cache == .null_handle) null else NonDispatchable(PipelineCache).fromHandleObject(p_cache) catch |err| return toVkResult(err);
var global_res: vk.Result = .success;
for (p_pipelines, infos, 0..count) |*p_pipeline, *info, _| { for (p_pipelines, infos, 0..count) |*p_pipeline, *info, _| {
if (info.s_type != .graphics_pipeline_create_info) { if (info.s_type != .graphics_pipeline_create_info) {
return .error_validation_failed; return .error_validation_failed;
} }
const pipeline = device.createGraphicsPipeline(allocator, cache, info) catch |err| return toVkResult(err);
p_pipeline.* = (NonDispatchable(Pipeline).wrap(allocator, pipeline) catch |err| return toVkResult(err)).toVkHandle(vk.Pipeline); // According to the Vulkan spec, section 9.4. Multiple Pipeline Creation
// "When an application attempts to create many pipelines in a single command,
// it is possible that some subset may fail creation. In that case, the
// corresponding entries in the pPipelines output array will be filled with
// VK_NULL_HANDLE values. If any pipeline fails creation (for example, due to
// out of memory errors), the vkCreate*Pipelines commands will return an
// error code. The implementation will attempt to create all pipelines, and
// only return VK_NULL_HANDLE values for those that actually failed."
p_pipeline.*, const local_res = blk: {
const pipeline = device.createGraphicsPipeline(allocator, cache, info) catch |err| break :blk .{ .null_handle, toVkResult(err) };
const handle = NonDispatchable(Pipeline).wrap(allocator, pipeline) catch |err| {
pipeline.destroy(allocator);
break :blk .{ .null_handle, toVkResult(err) };
};
break :blk .{ handle.toVkHandle(vk.Pipeline), .success };
};
if (local_res != .success) {
global_res = local_res;
} }
return .success; }
return global_res;
} }
pub export fn strollCreateImage(p_device: vk.Device, info: *const vk.ImageCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_image: *vk.Image) callconv(vk.vulkan_call_conv) vk.Result { pub export fn strollCreateImage(p_device: vk.Device, info: *const vk.ImageCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_image: *vk.Image) callconv(vk.vulkan_call_conv) vk.Result {
@@ -1630,7 +1769,7 @@ pub export fn strollCmdClearAttachments(p_cmd: vk.CommandBuffer, attachment_coun
} }
pub export fn strollCmdClearColorImage(p_cmd: vk.CommandBuffer, p_image: vk.Image, layout: vk.ImageLayout, color: *const vk.ClearColorValue, count: u32, ranges: [*]const vk.ImageSubresourceRange) callconv(vk.vulkan_call_conv) void { pub export fn strollCmdClearColorImage(p_cmd: vk.CommandBuffer, p_image: vk.Image, layout: vk.ImageLayout, color: *const vk.ClearColorValue, count: u32, ranges: [*]const vk.ImageSubresourceRange) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkCmdCopyImage); entryPointBeginLogTrace(.vkCmdClearColorImage);
defer entryPointEndLogTrace(); defer entryPointEndLogTrace();
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err); const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
@@ -1683,14 +1822,14 @@ pub export fn strollCmdCopyBufferToImage(p_cmd: vk.CommandBuffer, p_src: vk.Buff
_ = regions; _ = regions;
} }
pub export fn strollCmdCopyImage(p_cmd: vk.CommandBuffer, p_src: vk.Image, p_dst: vk.Image, count: u32, regions: [*]const vk.ImageCopy) callconv(vk.vulkan_call_conv) void { pub export fn strollCmdCopyImage(p_cmd: vk.CommandBuffer, p_src: vk.Image, src_layout: vk.ImageLayout, p_dst: vk.Image, dst_layout: vk.ImageLayout, count: u32, regions: [*]const vk.ImageCopy) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkCmdCopyImage); entryPointBeginLogTrace(.vkCmdCopyImage);
defer entryPointEndLogTrace(); defer entryPointEndLogTrace();
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err); const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
const src = NonDispatchable(Image).fromHandleObject(p_src) catch |err| return errorLogger(err); const src = NonDispatchable(Image).fromHandleObject(p_src) catch |err| return errorLogger(err);
const dst = NonDispatchable(Image).fromHandleObject(p_dst) catch |err| return errorLogger(err); const dst = NonDispatchable(Image).fromHandleObject(p_dst) catch |err| return errorLogger(err);
cmd.copyImage(src, dst, regions[0..count]) catch |err| return errorLogger(err); cmd.copyImage(src, src_layout, dst, dst_layout, regions[0..count]) catch |err| return errorLogger(err);
} }
pub export fn strollCmdCopyImageToBuffer(p_cmd: vk.CommandBuffer, p_src: vk.Image, layout: vk.ImageLayout, p_dst: vk.Buffer, count: u32, regions: [*]const vk.BufferImageCopy) callconv(vk.vulkan_call_conv) void { pub export fn strollCmdCopyImageToBuffer(p_cmd: vk.CommandBuffer, p_src: vk.Image, layout: vk.ImageLayout, p_dst: vk.Buffer, count: u32, regions: [*]const vk.BufferImageCopy) callconv(vk.vulkan_call_conv) void {

View File

@@ -23,12 +23,20 @@ pub fn get(self: *Self) *Manager {
} }
pub fn deinit(self: *Self) void { pub fn deinit(self: *Self) void {
{
self.mutex.lock(); self.mutex.lock();
defer self.mutex.unlock(); defer self.mutex.unlock();
var it = self.managers.iterator(); if (self.managers.getPtr(std.Thread.getCurrentId())) |manager| {
while (it.next()) |entry| { manager.deinit();
entry.value_ptr.deinit(); _ = self.managers.orderedRemove(std.Thread.getCurrentId());
} }
}
if (self.managers.count() == 0) {
self.mutex.lock();
self.mutex.unlock();
self.managers.deinit(self.allocator.allocator()); self.managers.deinit(self.allocator.allocator());
self.* = .init;
}
} }

View File

@@ -17,11 +17,15 @@ comptime {
} }
} }
pub var manager: ThreadSafeManager = .init; var manager: ThreadSafeManager = .init;
pub inline fn getManager() *ThreadSafeManager {
return &manager;
}
pub inline fn fixme(comptime format: []const u8, args: anytype) void { pub inline fn fixme(comptime format: []const u8, args: anytype) void {
manager.get().disableIndent(); getManager().get().disableIndent();
defer manager.get().enableIndent(); defer getManager().get().enableIndent();
nestedFixme(format, args); nestedFixme(format, args);
} }
@@ -93,8 +97,8 @@ pub fn log(comptime level: std.log.Level, comptime scope: @Type(.enum_literal),
out_config.setColor(&writer, .reset) catch {}; out_config.setColor(&writer, .reset) catch {};
if (manager.get().indent_enabled) { if (getManager().get().indent_enabled) {
for (0..manager.get().indent_level) |_| { for (0..getManager().get().indent_level) |_| {
writer.print("> ", .{}) catch {}; writer.print("> ", .{}) catch {};
} }
} }
@@ -102,17 +106,17 @@ pub fn log(comptime level: std.log.Level, comptime scope: @Type(.enum_literal),
writer.flush() catch return; writer.flush() catch return;
if (level == .debug and lib.getLogVerboseLevel() == .Standard) { if (level == .debug and lib.getLogVerboseLevel() == .Standard) {
manager.get().debug_stack.pushBack(.{ getManager().get().debug_stack.pushBack(.{
.log = buffer, .log = buffer,
.indent_level = manager.get().indent_level, .indent_level = getManager().get().indent_level,
.log_level = level, .log_level = level,
}) catch return; }) catch return;
return; return;
} }
if (manager.get().indent_enabled) { if (getManager().get().indent_enabled) {
while (manager.get().debug_stack.len() != 0) { while (getManager().get().debug_stack.len() != 0) {
const elem = manager.get().debug_stack.popFront(); const elem = getManager().get().debug_stack.popFront();
switch (elem.log_level) { switch (elem.log_level) {
.info, .debug => _ = stdout_file.write(&elem.log) catch {}, .info, .debug => _ = stdout_file.write(&elem.log) catch {},
.warn, .err => _ = stderr_file.write(&elem.log) catch {}, .warn, .err => _ = stderr_file.write(&elem.log) catch {},