adding VK_KHR_device_group functions; adding single ICD output lib for all backends
This commit is contained in:
@@ -48,6 +48,7 @@ Assume thou that functions lacking in this array are, for now, not intended to b
|
|||||||
|
|
||||||
Name | Status
|
Name | Status
|
||||||
-------------------------------------------------|--------
|
-------------------------------------------------|--------
|
||||||
|
vkAcquireNextImage2KHR | ✅ Implemented
|
||||||
vkAcquireNextImageKHR | ✅ Implemented
|
vkAcquireNextImageKHR | ✅ Implemented
|
||||||
vkAllocateCommandBuffers | ✅ Implemented
|
vkAllocateCommandBuffers | ✅ Implemented
|
||||||
vkAllocateDescriptorSets | ✅ Implemented
|
vkAllocateDescriptorSets | ✅ Implemented
|
||||||
@@ -71,6 +72,7 @@ vkCmdCopyImage | ✅ Implemented
|
|||||||
vkCmdCopyImageToBuffer | ✅ Implemented
|
vkCmdCopyImageToBuffer | ✅ Implemented
|
||||||
vkCmdCopyQueryPoolResults | ✅ Implemented
|
vkCmdCopyQueryPoolResults | ✅ Implemented
|
||||||
vkCmdDispatch | ✅ Implemented
|
vkCmdDispatch | ✅ Implemented
|
||||||
|
vkCmdDispatchBaseKHR | ✅ Implemented
|
||||||
vkCmdDispatchIndirect | ✅ Implemented
|
vkCmdDispatchIndirect | ✅ Implemented
|
||||||
vkCmdDraw | ✅ Implemented
|
vkCmdDraw | ✅ Implemented
|
||||||
vkCmdDrawIndexed | ✅ Implemented
|
vkCmdDrawIndexed | ✅ Implemented
|
||||||
@@ -89,6 +91,7 @@ vkCmdResolveImage | ✅ Implemented
|
|||||||
vkCmdSetBlendConstants | ✅ Implemented
|
vkCmdSetBlendConstants | ✅ Implemented
|
||||||
vkCmdSetDepthBias | ⚙️ WIP
|
vkCmdSetDepthBias | ⚙️ WIP
|
||||||
vkCmdSetDepthBounds | ⚙️ WIP
|
vkCmdSetDepthBounds | ⚙️ WIP
|
||||||
|
vkCmdSetDeviceMaskKHR | ✅ Implemented
|
||||||
vkCmdSetEvent | ✅ Implemented
|
vkCmdSetEvent | ✅ Implemented
|
||||||
vkCmdSetLineWidth | ⚙️ WIP
|
vkCmdSetLineWidth | ⚙️ WIP
|
||||||
vkCmdSetScissor | ✅ Implemented
|
vkCmdSetScissor | ✅ Implemented
|
||||||
@@ -153,13 +156,16 @@ vkEnumerateDeviceExtensionProperties | ✅ Implemented
|
|||||||
vkEnumerateDeviceLayerProperties | ✅ Implemented
|
vkEnumerateDeviceLayerProperties | ✅ Implemented
|
||||||
vkEnumerateInstanceExtensionProperties | ✅ Implemented
|
vkEnumerateInstanceExtensionProperties | ✅ Implemented
|
||||||
vkEnumerateInstanceLayerProperties | ✅ Implemented
|
vkEnumerateInstanceLayerProperties | ✅ Implemented
|
||||||
vkEnumeratePhysicalDevices | ✅ Implemented
|
|
||||||
vkEnumeratePhysicalDeviceGroupsKHR | ✅ Implemented
|
vkEnumeratePhysicalDeviceGroupsKHR | ✅ Implemented
|
||||||
|
vkEnumeratePhysicalDevices | ✅ Implemented
|
||||||
vkFlushMappedMemoryRanges | ✅ Implemented
|
vkFlushMappedMemoryRanges | ✅ Implemented
|
||||||
vkFreeCommandBuffers | ✅ Implemented
|
vkFreeCommandBuffers | ✅ Implemented
|
||||||
vkFreeDescriptorSets | ✅ Implemented
|
vkFreeDescriptorSets | ✅ Implemented
|
||||||
vkFreeMemory | ✅ Implemented
|
vkFreeMemory | ✅ Implemented
|
||||||
vkGetBufferMemoryRequirements | ✅ Implemented
|
vkGetBufferMemoryRequirements | ✅ Implemented
|
||||||
|
vkGetDeviceGroupPeerMemoryFeaturesKHR | ✅ Implemented
|
||||||
|
vkGetDeviceGroupPresentCapabilitiesKHR | ✅ Implemented
|
||||||
|
vkGetDeviceGroupSurfacePresentModesKHR | ✅ Implemented
|
||||||
vkGetDeviceMemoryCommitment | ⚙️ WIP
|
vkGetDeviceMemoryCommitment | ⚙️ WIP
|
||||||
vkGetDeviceProcAddr | ✅ Implemented
|
vkGetDeviceProcAddr | ✅ Implemented
|
||||||
vkGetDeviceQueue | ✅ Implemented
|
vkGetDeviceQueue | ✅ Implemented
|
||||||
|
|||||||
@@ -4,24 +4,37 @@ const builtin = @import("builtin");
|
|||||||
|
|
||||||
const ImplementationDesc = struct {
|
const ImplementationDesc = struct {
|
||||||
name: []const u8,
|
name: []const u8,
|
||||||
|
icd_name: ?[]const u8 = null,
|
||||||
root_source_file: []const u8,
|
root_source_file: []const u8,
|
||||||
vulkan_version: std.SemanticVersion,
|
vulkan_version: std.SemanticVersion,
|
||||||
custom: ?*const fn (
|
custom: ?*const fn (
|
||||||
*std.Build,
|
*std.Build,
|
||||||
*Step.Compile,
|
*Step.Compile,
|
||||||
|
*std.Build.Module,
|
||||||
|
*std.Build.Module,
|
||||||
|
*std.Build.Module,
|
||||||
|
*std.Build.Module,
|
||||||
std.Build.ResolvedTarget,
|
std.Build.ResolvedTarget,
|
||||||
std.builtin.OptimizeMode,
|
std.builtin.OptimizeMode,
|
||||||
*Step.Options,
|
|
||||||
bool,
|
bool,
|
||||||
) anyerror!void = null,
|
) anyerror!void = null,
|
||||||
|
options: ?*const fn (*std.Build, *Step.Options) anyerror!void = null,
|
||||||
};
|
};
|
||||||
|
|
||||||
const implementations = [_]ImplementationDesc{
|
const implementations = [_]ImplementationDesc{
|
||||||
|
.{
|
||||||
|
.name = "ape",
|
||||||
|
.icd_name = "ape",
|
||||||
|
.root_source_file = "src/ape/lib.zig",
|
||||||
|
.vulkan_version = .{ .major = 1, .minor = 0, .patch = 0 },
|
||||||
|
.custom = customApe,
|
||||||
|
},
|
||||||
.{
|
.{
|
||||||
.name = "soft",
|
.name = "soft",
|
||||||
.root_source_file = "src/soft/lib.zig",
|
.root_source_file = "src/soft/lib.zig",
|
||||||
.vulkan_version = .{ .major = 1, .minor = 0, .patch = 0 },
|
.vulkan_version = .{ .major = 1, .minor = 0, .patch = 0 },
|
||||||
.custom = customSoft,
|
.custom = customSoft,
|
||||||
|
.options = optionsSoft,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -79,7 +92,8 @@ pub fn build(b: *std.Build) !void {
|
|||||||
base_c_includes.link_libc = true;
|
base_c_includes.link_libc = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
base_mod.addImport("base_c", base_c_includes.createModule());
|
const base_c_mod = base_c_includes.createModule();
|
||||||
|
base_mod.addImport("base_c", base_c_mod);
|
||||||
|
|
||||||
const use_llvm = b.option(bool, "use-llvm", "LLVM build") orelse (b.release_mode != .off);
|
const use_llvm = b.option(bool, "use-llvm", "LLVM build") orelse (b.release_mode != .off);
|
||||||
|
|
||||||
@@ -104,12 +118,22 @@ pub fn build(b: *std.Build) !void {
|
|||||||
.use_llvm = use_llvm,
|
.use_llvm = use_llvm,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (impl.custom) |custom| {
|
if (impl.custom) |func| {
|
||||||
custom(b, lib, target, optimize, options, use_llvm) catch continue;
|
func(b, lib, lib_mod, base_mod, vulkan, base_c_mod, target, optimize, use_llvm) catch continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (impl.options) |func| {
|
||||||
|
func(b, options) catch continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const icd_file = b.addWriteFile(
|
const icd_file = b.addWriteFile(
|
||||||
b.getInstallPath(.lib, b.fmt("vk_ape_{s}.json", .{impl.name})),
|
b.getInstallPath(
|
||||||
|
.lib,
|
||||||
|
if (impl.icd_name) |icd_name|
|
||||||
|
b.fmt("vk_{s}.json", .{icd_name})
|
||||||
|
else
|
||||||
|
b.fmt("vk_ape_{s}.json", .{impl.name}),
|
||||||
|
),
|
||||||
b.fmt(
|
b.fmt(
|
||||||
\\{{
|
\\{{
|
||||||
\\ "file_format_version": "1.0.1",
|
\\ "file_format_version": "1.0.1",
|
||||||
@@ -171,12 +195,48 @@ pub fn build(b: *std.Build) !void {
|
|||||||
docs_step.dependOn(&install_docs.step);
|
docs_step.dependOn(&install_docs.step);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn customSoft(
|
fn customApe(
|
||||||
b: *std.Build,
|
b: *std.Build,
|
||||||
lib: *Step.Compile,
|
lib: *Step.Compile,
|
||||||
|
lib_mod: *std.Build.Module,
|
||||||
|
base_mod: *std.Build.Module,
|
||||||
|
vulkan: *std.Build.Module,
|
||||||
|
base_c_mod: *std.Build.Module,
|
||||||
|
target: std.Build.ResolvedTarget,
|
||||||
|
optimize: std.builtin.OptimizeMode,
|
||||||
|
use_llvm: bool,
|
||||||
|
) !void {
|
||||||
|
for (implementations) |impl| {
|
||||||
|
if (std.mem.eql(u8, impl.name, "ape"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const mod = b.createModule(.{
|
||||||
|
.root_source_file = b.path(impl.root_source_file),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.imports = &.{
|
||||||
|
.{ .name = "base", .module = base_mod },
|
||||||
|
.{ .name = "vulkan", .module = vulkan },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (impl.custom) |func| {
|
||||||
|
func(b, lib, mod, base_mod, vulkan, base_c_mod, target, optimize, use_llvm) catch continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
lib_mod.addImport(impl.name, mod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn customSoft(
|
||||||
|
b: *std.Build,
|
||||||
|
_: *Step.Compile,
|
||||||
|
lib_mod: *std.Build.Module,
|
||||||
|
_: *std.Build.Module,
|
||||||
|
_: *std.Build.Module,
|
||||||
|
base_c_mod: *std.Build.Module,
|
||||||
_: std.Build.ResolvedTarget,
|
_: std.Build.ResolvedTarget,
|
||||||
_: std.builtin.OptimizeMode,
|
_: std.builtin.OptimizeMode,
|
||||||
options: *Step.Options,
|
|
||||||
use_llvm: bool,
|
use_llvm: bool,
|
||||||
) !void {
|
) !void {
|
||||||
const spv = b.lazyDependency("SPIRV_Interpreter", .{
|
const spv = b.lazyDependency("SPIRV_Interpreter", .{
|
||||||
@@ -184,23 +244,25 @@ fn customSoft(
|
|||||||
.@"no-test" = true,
|
.@"no-test" = true,
|
||||||
.@"use-llvm" = use_llvm,
|
.@"use-llvm" = use_llvm,
|
||||||
}) orelse return error.UnresolvedDependency;
|
}) orelse return error.UnresolvedDependency;
|
||||||
lib.root_module.addImport("spv", spv.module("spv"));
|
|
||||||
|
|
||||||
const single_threaded_option = b.option(bool, "single-threaded", "Single threaded runtime mode") orelse false;
|
lib_mod.addImport("soft_c", base_c_mod);
|
||||||
const debug_allocator_option = b.option(bool, "debug-allocator", "Debug device allocator") orelse false;
|
lib_mod.addImport("spv", spv.module("spv"));
|
||||||
const shaders_simd_option = b.option(bool, "shader-simd", "Shaders SIMD acceleration") orelse true;
|
}
|
||||||
const single_threaded_compute_option = b.option(bool, "single-threaded-compute", "Single threaded compute shaders execution") orelse true;
|
|
||||||
const compute_dump_early_results_table_option = b.option(u32, "compute-dump-early-results-table", "Dump compute shaders results table before invocation");
|
|
||||||
const compute_dump_final_results_table_option = b.option(u32, "compute-dump-final-results-table", "Dump compute shaders results table after invocation");
|
|
||||||
const approxiamte_rgb_option = b.option(bool, "approximates-rgb", "Approximate sRGB <-> RGB conversions") orelse true;
|
|
||||||
|
|
||||||
options.addOption(bool, "single_threaded", single_threaded_option);
|
fn optionsSoft(b: *std.Build, options: *Step.Options) !void {
|
||||||
options.addOption(bool, "debug_allocator", debug_allocator_option);
|
const single_threaded_option = b.option(bool, "soft-single-threaded", "Single threaded runtime mode") orelse false;
|
||||||
options.addOption(bool, "shaders_simd", shaders_simd_option);
|
const debug_allocator_option = b.option(bool, "soft-debug-allocator", "Debug device allocator") orelse false;
|
||||||
options.addOption(bool, "single_threaded_compute", single_threaded_compute_option);
|
const shaders_simd_option = b.option(bool, "soft-shader-simd", "Shaders SIMD acceleration") orelse true;
|
||||||
options.addOption(?u32, "compute_dump_early_results_table", compute_dump_early_results_table_option);
|
const compute_dump_early_results_table_option = b.option(u32, "soft-compute-dump-early-results-table", "Dump compute shaders results table before invocation");
|
||||||
options.addOption(?u32, "compute_dump_final_results_table", compute_dump_final_results_table_option);
|
const compute_dump_final_results_table_option = b.option(u32, "soft-compute-dump-final-results-table", "Dump compute shaders results table after invocation");
|
||||||
options.addOption(bool, "approximates_rgb", approxiamte_rgb_option);
|
const approxiamte_rgb_option = b.option(bool, "soft-approximates-rgb", "Approximate sRGB <-> RGB conversions") orelse true;
|
||||||
|
|
||||||
|
options.addOption(bool, "soft_single_threaded", single_threaded_option);
|
||||||
|
options.addOption(bool, "soft_debug_allocator", debug_allocator_option);
|
||||||
|
options.addOption(bool, "soft_shaders_simd", shaders_simd_option);
|
||||||
|
options.addOption(?u32, "soft_compute_dump_early_results_table", compute_dump_early_results_table_option);
|
||||||
|
options.addOption(?u32, "soft_compute_dump_final_results_table", compute_dump_final_results_table_option);
|
||||||
|
options.addOption(bool, "soft_approximates_rgb", approxiamte_rgb_option);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn addCTS(b: *std.Build, target: std.Build.ResolvedTarget, impl: *const ImplementationDesc, impl_lib: *Step.Compile, comptime mode: RunningMode) !*Step {
|
fn addCTS(b: *std.Build, target: std.Build.ResolvedTarget, impl: *const ImplementationDesc, impl_lib: *Step.Compile, comptime mode: RunningMode) !*Step {
|
||||||
|
|||||||
+1
-1
@@ -26,7 +26,7 @@
|
|||||||
.hash = "N-V-__8AAF9uOh0I4P_99za7N822J3JwsDaqONrFVrcEQo59",
|
.hash = "N-V-__8AAF9uOh0I4P_99za7N822J3JwsDaqONrFVrcEQo59",
|
||||||
},
|
},
|
||||||
.SPIRV_Interpreter = .{
|
.SPIRV_Interpreter = .{
|
||||||
.url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#52ded6b490a47d843ad401cbd2c41b4dbdc7dca1",
|
.url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#42554a5cc1069e8174b377e95ce2ac2d802a44ff",
|
||||||
.hash = "SPIRV_Interpreter-0.0.1-ajmpn0GXBwD01BnmV_Kf8EeNqTDoyuq7UvHVaq-WoBP0",
|
.hash = "SPIRV_Interpreter-0.0.1-ajmpn0GXBwD01BnmV_Kf8EeNqTDoyuq7UvHVaq-WoBP0",
|
||||||
.lazy = true,
|
.lazy = true,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const vk = @import("vulkan");
|
||||||
|
const base = @import("base");
|
||||||
|
const soft = @import("soft");
|
||||||
|
|
||||||
|
const Dispatchable = base.Dispatchable;
|
||||||
|
const VkError = base.VkError;
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
pub const Interface = base.Instance;
|
||||||
|
|
||||||
|
interface: Interface,
|
||||||
|
backend_instances: std.ArrayList(*Interface),
|
||||||
|
|
||||||
|
pub const EXTENSIONS = soft.Instance.EXTENSIONS;
|
||||||
|
|
||||||
|
pub fn create(allocator: std.mem.Allocator, infos: *const vk.InstanceCreateInfo) VkError!*Interface {
|
||||||
|
const self = allocator.create(Self) catch return VkError.OutOfHostMemory;
|
||||||
|
errdefer allocator.destroy(self);
|
||||||
|
|
||||||
|
self.* = .{
|
||||||
|
.interface = try base.Instance.init(allocator, infos),
|
||||||
|
.backend_instances = .empty,
|
||||||
|
};
|
||||||
|
errdefer destroyBackendInstances(self, allocator);
|
||||||
|
|
||||||
|
self.interface.dispatch_table = &.{
|
||||||
|
.destroy = destroy,
|
||||||
|
};
|
||||||
|
self.interface.vtable = &.{
|
||||||
|
.requestPhysicalDevices = requestPhysicalDevices,
|
||||||
|
.releasePhysicalDevices = releasePhysicalDevices,
|
||||||
|
.io = io,
|
||||||
|
};
|
||||||
|
|
||||||
|
const soft_instance = try soft.Instance.create(allocator, infos);
|
||||||
|
errdefer soft_instance.deinit(allocator) catch {};
|
||||||
|
self.backend_instances.append(allocator, soft_instance) catch return VkError.OutOfHostMemory;
|
||||||
|
|
||||||
|
return &self.interface;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn destroy(interface: *Interface, allocator: std.mem.Allocator) VkError!void {
|
||||||
|
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||||
|
destroyBackendInstances(self, allocator);
|
||||||
|
self.backend_instances.deinit(allocator);
|
||||||
|
allocator.destroy(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn requestPhysicalDevices(interface: *Interface, allocator: std.mem.Allocator) VkError!void {
|
||||||
|
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||||
|
|
||||||
|
for (self.backend_instances.items) |backend| {
|
||||||
|
try appendBackendPhysicalDevices(self, allocator, backend);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn appendBackendPhysicalDevices(self: *Self, allocator: std.mem.Allocator, backend: *Interface) VkError!void {
|
||||||
|
try backend.requestPhysicalDevices(allocator);
|
||||||
|
errdefer backend.releasePhysicalDevices(allocator) catch {};
|
||||||
|
|
||||||
|
self.interface.physical_devices.appendSlice(allocator, backend.physical_devices.items) catch return VkError.OutOfHostMemory;
|
||||||
|
backend.physical_devices.deinit(allocator);
|
||||||
|
backend.physical_devices = .empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn releasePhysicalDevices(interface: *Interface, allocator: std.mem.Allocator) VkError!void {
|
||||||
|
for (interface.physical_devices.items) |physical_device| {
|
||||||
|
try physical_device.object.releasePhysicalDevice(allocator);
|
||||||
|
physical_device.destroy(allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface.physical_devices.deinit(allocator);
|
||||||
|
interface.physical_devices = .empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn destroyBackendInstances(self: *Self, allocator: std.mem.Allocator) void {
|
||||||
|
for (self.backend_instances.items) |backend| {
|
||||||
|
backend.dispatch_table.destroy(backend, allocator) catch |err| {
|
||||||
|
base.errors.errorLogger(err);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
self.backend_instances.clearRetainingCapacity();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn io(interface: *Interface) std.Io {
|
||||||
|
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||||
|
if (self.backend_instances.items.len != 0) {
|
||||||
|
return self.backend_instances.items[0].io();
|
||||||
|
}
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const vk = @import("vulkan");
|
||||||
|
pub const base = @import("base");
|
||||||
|
pub const soft = @import("soft");
|
||||||
|
|
||||||
|
pub const c = base.c;
|
||||||
|
|
||||||
|
pub const ApeInstance = @import("ApeInstance.zig");
|
||||||
|
|
||||||
|
pub const Instance = ApeInstance;
|
||||||
|
|
||||||
|
pub const DRIVER_NAME = "Ape";
|
||||||
|
|
||||||
|
pub const VULKAN_VERSION = vk.makeApiVersion(0, 1, 0, 0);
|
||||||
|
pub const DRIVER_VERSION = vk.makeApiVersion(0, 0, 0, 1);
|
||||||
|
|
||||||
|
pub const std_options = base.std_options;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
_ = base;
|
||||||
|
_ = soft;
|
||||||
|
}
|
||||||
|
|
||||||
|
test {
|
||||||
|
std.testing.refAllDecls(ApeInstance);
|
||||||
|
std.testing.refAllDecls(soft);
|
||||||
|
std.testing.refAllDecls(base);
|
||||||
|
}
|
||||||
@@ -61,6 +61,7 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v
|
|||||||
.copyImageToBuffer = copyImageToBuffer,
|
.copyImageToBuffer = copyImageToBuffer,
|
||||||
.copyQueryPoolResults = copyQueryPoolResults,
|
.copyQueryPoolResults = copyQueryPoolResults,
|
||||||
.dispatch = dispatch,
|
.dispatch = dispatch,
|
||||||
|
.dispatchBase = dispatchBase,
|
||||||
.dispatchIndirect = dispatchIndirect,
|
.dispatchIndirect = dispatchIndirect,
|
||||||
.draw = draw,
|
.draw = draw,
|
||||||
.drawIndexed = drawIndexed,
|
.drawIndexed = drawIndexed,
|
||||||
@@ -80,6 +81,7 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v
|
|||||||
.resolveImage = resolveImage,
|
.resolveImage = resolveImage,
|
||||||
.setEvent = setEvent,
|
.setEvent = setEvent,
|
||||||
.setBlendConstants = setBlendConstants,
|
.setBlendConstants = setBlendConstants,
|
||||||
|
.setDeviceMask = setDeviceMask,
|
||||||
.setScissor = setScissor,
|
.setScissor = setScissor,
|
||||||
.setStencilCompareMask = setStencilCompareMask,
|
.setStencilCompareMask = setStencilCompareMask,
|
||||||
.setStencilReference = setStencilReference,
|
.setStencilReference = setStencilReference,
|
||||||
@@ -782,25 +784,35 @@ pub fn copyQueryPoolResults(interface: *Interface, pool: *base.QueryPool, first:
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn dispatch(interface: *Interface, group_count_x: u32, group_count_y: u32, group_count_z: u32) VkError!void {
|
pub fn dispatch(interface: *Interface, group_count_x: u32, group_count_y: u32, group_count_z: u32) VkError!void {
|
||||||
|
try dispatchBase(interface, 0, 0, 0, group_count_x, group_count_y, group_count_z);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn dispatchBase(interface: *Interface, base_group_x: u32, base_group_y: u32, base_group_z: u32, group_count_x: u32, group_count_y: u32, group_count_z: u32) VkError!void {
|
||||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||||
const allocator = self.command_allocator.allocator();
|
const allocator = self.command_allocator.allocator();
|
||||||
|
|
||||||
const CommandImpl = struct {
|
const CommandImpl = struct {
|
||||||
const Impl = @This();
|
const Impl = @This();
|
||||||
|
|
||||||
|
base_group_x: u32,
|
||||||
|
base_group_y: u32,
|
||||||
|
base_group_z: u32,
|
||||||
group_count_x: u32,
|
group_count_x: u32,
|
||||||
group_count_y: u32,
|
group_count_y: u32,
|
||||||
group_count_z: u32,
|
group_count_z: u32,
|
||||||
|
|
||||||
pub fn execute(context: *anyopaque, device: *ExecutionDevice) VkError!void {
|
pub fn execute(context: *anyopaque, device: *ExecutionDevice) VkError!void {
|
||||||
const impl: *Impl = @ptrCast(@alignCast(context));
|
const impl: *Impl = @ptrCast(@alignCast(context));
|
||||||
try device.compute.dispatch(impl.group_count_x, impl.group_count_y, impl.group_count_z);
|
try device.compute.dispatchBase(impl.base_group_x, impl.base_group_y, impl.base_group_z, impl.group_count_x, impl.group_count_y, impl.group_count_z);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const cmd = allocator.create(CommandImpl) catch return VkError.OutOfHostMemory;
|
const cmd = allocator.create(CommandImpl) catch return VkError.OutOfHostMemory;
|
||||||
errdefer allocator.destroy(cmd);
|
errdefer allocator.destroy(cmd);
|
||||||
cmd.* = .{
|
cmd.* = .{
|
||||||
|
.base_group_x = base_group_x,
|
||||||
|
.base_group_y = base_group_y,
|
||||||
|
.base_group_z = base_group_z,
|
||||||
.group_count_x = group_count_x,
|
.group_count_x = group_count_x,
|
||||||
.group_count_y = group_count_y,
|
.group_count_y = group_count_y,
|
||||||
.group_count_z = group_count_z,
|
.group_count_z = group_count_z,
|
||||||
@@ -808,6 +820,10 @@ pub fn dispatch(interface: *Interface, group_count_x: u32, group_count_y: u32, g
|
|||||||
self.commands.append(allocator, .{ .ptr = cmd, .vtable = &.{ .execute = CommandImpl.execute } }) catch return VkError.OutOfHostMemory;
|
self.commands.append(allocator, .{ .ptr = cmd, .vtable = &.{ .execute = CommandImpl.execute } }) catch return VkError.OutOfHostMemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn setDeviceMask(_: *Interface, device_mask: u32) VkError!void {
|
||||||
|
if (device_mask != 1) return VkError.ValidationFailed;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn dispatchIndirect(interface: *Interface, buffer: *base.Buffer, offset: vk.DeviceSize) VkError!void {
|
pub fn dispatchIndirect(interface: *Interface, buffer: *base.Buffer, offset: vk.DeviceSize) VkError!void {
|
||||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||||
const allocator = self.command_allocator.allocator();
|
const allocator = self.command_allocator.allocator();
|
||||||
|
|||||||
+28
-3
@@ -42,7 +42,7 @@ const DeviceAllocator = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
interface: Interface,
|
interface: Interface,
|
||||||
device_allocator: if (config.debug_allocator) std.heap.DebugAllocator(.{}) else DeviceAllocator,
|
device_allocator: if (config.soft_debug_allocator) std.heap.DebugAllocator(.{}) else DeviceAllocator,
|
||||||
|
|
||||||
pub fn create(instance: *base.Instance, physical_device: *base.PhysicalDevice, allocator: std.mem.Allocator, info: *const vk.DeviceCreateInfo) VkError!*Self {
|
pub fn create(instance: *base.Instance, physical_device: *base.PhysicalDevice, allocator: std.mem.Allocator, info: *const vk.DeviceCreateInfo) VkError!*Self {
|
||||||
const self = allocator.create(Self) catch return VkError.OutOfHostMemory;
|
const self = allocator.create(Self) catch return VkError.OutOfHostMemory;
|
||||||
@@ -84,11 +84,14 @@ pub fn create(instance: *base.Instance, physical_device: *base.PhysicalDevice, a
|
|||||||
.createSemaphore = createSemaphore,
|
.createSemaphore = createSemaphore,
|
||||||
.createShaderModule = createShaderModule,
|
.createShaderModule = createShaderModule,
|
||||||
.destroy = destroy,
|
.destroy = destroy,
|
||||||
|
.getDeviceGroupPeerMemoryFeatures = getDeviceGroupPeerMemoryFeatures,
|
||||||
|
.getDeviceGroupPresentCapabilitiesKHR = getDeviceGroupPresentCapabilitiesKHR,
|
||||||
|
.getDeviceGroupSurfacePresentModesKHR = getDeviceGroupSurfacePresentModesKHR,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.interface = interface,
|
.interface = interface,
|
||||||
.device_allocator = if (config.debug_allocator) .init else .{},
|
.device_allocator = if (config.soft_debug_allocator) .init else .{},
|
||||||
};
|
};
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
|
||||||
@@ -99,7 +102,7 @@ pub fn create(instance: *base.Instance, physical_device: *base.PhysicalDevice, a
|
|||||||
pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) VkError!void {
|
pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) VkError!void {
|
||||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||||
|
|
||||||
if (config.debug_allocator) {
|
if (config.soft_debug_allocator) {
|
||||||
// All device memory allocations should've been freed by now
|
// All device memory allocations should've been freed by now
|
||||||
const leaks = self.device_allocator.detectLeaks();
|
const leaks = self.device_allocator.detectLeaks();
|
||||||
if (leaks != 0)
|
if (leaks != 0)
|
||||||
@@ -212,3 +215,25 @@ pub fn createShaderModule(interface: *Interface, allocator: std.mem.Allocator, i
|
|||||||
const module = try SoftShaderModule.create(interface, allocator, info);
|
const module = try SoftShaderModule.create(interface, allocator, info);
|
||||||
return &module.interface;
|
return &module.interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn getDeviceGroupPeerMemoryFeatures(interface: *Interface, heap_index: u32, local_device_index: u32, remote_device_index: u32) VkError!vk.PeerMemoryFeatureFlags {
|
||||||
|
if (heap_index >= interface.physical_device.mem_props.memory_heap_count) return VkError.ValidationFailed;
|
||||||
|
if (local_device_index != 0 or remote_device_index != 0) return VkError.ValidationFailed;
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.copy_src_bit = true,
|
||||||
|
.copy_dst_bit = true,
|
||||||
|
.generic_src_bit = true,
|
||||||
|
.generic_dst_bit = true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getDeviceGroupPresentCapabilitiesKHR(_: *Interface, capabilities: *vk.DeviceGroupPresentCapabilitiesKHR) VkError!void {
|
||||||
|
capabilities.present_mask = @splat(0);
|
||||||
|
capabilities.present_mask[0] = 1;
|
||||||
|
capabilities.modes = .{ .local_bit_khr = true };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getDeviceGroupSurfacePresentModesKHR(_: *Interface, _: *base.SurfaceKHR) VkError!vk.DeviceGroupPresentModeFlagsKHR {
|
||||||
|
return .{ .local_bit_khr = true };
|
||||||
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ pub fn create(allocator: std.mem.Allocator, infos: *const vk.InstanceCreateInfo)
|
|||||||
errdefer allocator.destroy(self);
|
errdefer allocator.destroy(self);
|
||||||
|
|
||||||
self.allocator = std.heap.smp_allocator;
|
self.allocator = std.heap.smp_allocator;
|
||||||
self.threaded = if (comptime base.config.single_threaded) .init_single_threaded else std.Io.Threaded.init(self.allocator, .{});
|
self.threaded = if (comptime base.config.soft_single_threaded) .init_single_threaded else std.Io.Threaded.init(self.allocator, .{});
|
||||||
self.io_impl = self.threaded.io();
|
self.io_impl = self.threaded.io();
|
||||||
|
|
||||||
self.interface = try base.Instance.init(allocator, infos);
|
self.interface = try base.Instance.init(allocator, infos);
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ fn castExtension(comptime ext: vk.ApiInfo) vk.ExtensionProperties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub const EXTENSIONS = [_]vk.ExtensionProperties{
|
pub const EXTENSIONS = [_]vk.ExtensionProperties{
|
||||||
|
castExtension(vk.extensions.khr_device_group),
|
||||||
castExtension(vk.extensions.khr_swapchain),
|
castExtension(vk.extensions.khr_swapchain),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v
|
|||||||
self.* = .{
|
self.* = .{
|
||||||
.interface = interface,
|
.interface = interface,
|
||||||
.module = spv.Module.init(device_allocator, code, .{
|
.module = spv.Module.init(device_allocator, code, .{
|
||||||
.use_simd_vectors_specializations = base.config.shaders_simd,
|
.use_simd_vectors_specializations = base.config.soft_shaders_simd,
|
||||||
}) catch |err| switch (err) {
|
}) catch |err| switch (err) {
|
||||||
spv.Module.ModuleError.OutOfMemory => return VkError.OutOfHostMemory,
|
spv.Module.ModuleError.OutOfMemory => return VkError.OutOfHostMemory,
|
||||||
else => {
|
else => {
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ const RunData = struct {
|
|||||||
self: *Self,
|
self: *Self,
|
||||||
batch_id: usize,
|
batch_id: usize,
|
||||||
group_count: usize,
|
group_count: usize,
|
||||||
|
base_group_x: usize,
|
||||||
|
base_group_y: usize,
|
||||||
|
base_group_z: usize,
|
||||||
group_count_x: usize,
|
group_count_x: usize,
|
||||||
group_count_y: usize,
|
group_count_y: usize,
|
||||||
group_count_z: usize,
|
group_count_z: usize,
|
||||||
@@ -41,12 +44,16 @@ pub fn init(device: *SoftDevice, state: *PipelineState) Self {
|
|||||||
.state = state,
|
.state = state,
|
||||||
.batch_size = 0,
|
.batch_size = 0,
|
||||||
.invocation_index = .init(0),
|
.invocation_index = .init(0),
|
||||||
.early_dump = base.config.compute_dump_early_results_table,
|
.early_dump = base.config.soft_compute_dump_early_results_table,
|
||||||
.final_dump = base.config.compute_dump_final_results_table,
|
.final_dump = base.config.soft_compute_dump_final_results_table,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dispatch(self: *Self, group_count_x: u32, group_count_y: u32, group_count_z: u32) VkError!void {
|
pub fn dispatch(self: *Self, group_count_x: u32, group_count_y: u32, group_count_z: u32) VkError!void {
|
||||||
|
try self.dispatchBase(0, 0, 0, group_count_x, group_count_y, group_count_z);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn dispatchBase(self: *Self, base_group_x: u32, base_group_y: u32, base_group_z: u32, group_count_x: u32, group_count_y: u32, group_count_z: u32) VkError!void {
|
||||||
const group_count_xy = std.math.mul(usize, group_count_x, group_count_y) catch return VkError.ValidationFailed;
|
const group_count_xy = std.math.mul(usize, group_count_x, group_count_y) catch return VkError.ValidationFailed;
|
||||||
const group_count = std.math.mul(usize, group_count_xy, group_count_z) catch return VkError.ValidationFailed;
|
const group_count = std.math.mul(usize, group_count_xy, group_count_z) catch return VkError.ValidationFailed;
|
||||||
|
|
||||||
@@ -73,6 +80,9 @@ pub fn dispatch(self: *Self, group_count_x: u32, group_count_y: u32, group_count
|
|||||||
.self = self,
|
.self = self,
|
||||||
.batch_id = batch_id,
|
.batch_id = batch_id,
|
||||||
.group_count = group_count,
|
.group_count = group_count,
|
||||||
|
.base_group_x = @as(usize, @intCast(base_group_x)),
|
||||||
|
.base_group_y = @as(usize, @intCast(base_group_y)),
|
||||||
|
.base_group_z = @as(usize, @intCast(base_group_z)),
|
||||||
.group_count_x = @as(usize, @intCast(group_count_x)),
|
.group_count_x = @as(usize, @intCast(group_count_x)),
|
||||||
.group_count_y = @as(usize, @intCast(group_count_y)),
|
.group_count_y = @as(usize, @intCast(group_count_y)),
|
||||||
.group_count_z = @as(usize, @intCast(group_count_z)),
|
.group_count_z = @as(usize, @intCast(group_count_z)),
|
||||||
@@ -80,10 +90,7 @@ pub fn dispatch(self: *Self, group_count_x: u32, group_count_y: u32, group_count
|
|||||||
.pipeline = pipeline,
|
.pipeline = pipeline,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (comptime base.config.single_threaded_compute)
|
wg.async(self.device.interface.io(), runWrapper, .{run_data});
|
||||||
runWrapper(run_data)
|
|
||||||
else
|
|
||||||
wg.async(self.device.interface.io(), runWrapper, .{run_data});
|
|
||||||
}
|
}
|
||||||
wg.await(self.device.interface.io()) catch return VkError.DeviceLost;
|
wg.await(self.device.interface.io()) catch return VkError.DeviceLost;
|
||||||
}
|
}
|
||||||
@@ -151,9 +158,9 @@ inline fn run(data: RunData) !void {
|
|||||||
@as(u32, @intCast(data.group_count_z)),
|
@as(u32, @intCast(data.group_count_z)),
|
||||||
};
|
};
|
||||||
const group_id_vec = @Vector(3, u32){
|
const group_id_vec = @Vector(3, u32){
|
||||||
@as(u32, @intCast(group_x)),
|
@as(u32, @intCast(data.base_group_x + group_x)),
|
||||||
@as(u32, @intCast(group_y)),
|
@as(u32, @intCast(data.base_group_y + group_y)),
|
||||||
@as(u32, @intCast(group_z)),
|
@as(u32, @intCast(data.base_group_z + group_z)),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (uses_control_barrier) {
|
if (uses_control_barrier) {
|
||||||
@@ -168,9 +175,9 @@ inline fn run(data: RunData) !void {
|
|||||||
const invocation_index = data.self.invocation_index.fetchAdd(1, .monotonic);
|
const invocation_index = data.self.invocation_index.fetchAdd(1, .monotonic);
|
||||||
|
|
||||||
try setupSubgroupBuiltins(data.self, rt, .{
|
try setupSubgroupBuiltins(data.self, rt, .{
|
||||||
@as(u32, @intCast(group_x)),
|
@as(u32, @intCast(data.base_group_x + group_x)),
|
||||||
@as(u32, @intCast(group_y)),
|
@as(u32, @intCast(data.base_group_y + group_y)),
|
||||||
@as(u32, @intCast(group_z)),
|
@as(u32, @intCast(data.base_group_z + group_z)),
|
||||||
}, i);
|
}, i);
|
||||||
|
|
||||||
if (data.self.early_dump != null and data.self.early_dump.? == invocation_index) {
|
if (data.self.early_dump != null and data.self.early_dump.? == invocation_index) {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ pool: *CommandPool,
|
|||||||
state: State,
|
state: State,
|
||||||
begin_info: ?vk.CommandBufferBeginInfo,
|
begin_info: ?vk.CommandBufferBeginInfo,
|
||||||
usage_flags: vk.CommandBufferUsageFlags,
|
usage_flags: vk.CommandBufferUsageFlags,
|
||||||
|
device_mask: u32,
|
||||||
host_allocator: VulkanAllocator,
|
host_allocator: VulkanAllocator,
|
||||||
state_mutex: std.Io.Mutex,
|
state_mutex: std.Io.Mutex,
|
||||||
|
|
||||||
@@ -57,6 +58,7 @@ pub const DispatchTable = struct {
|
|||||||
copyImageToBuffer: *const fn (*Self, *Image, vk.ImageLayout, *Buffer, []const vk.BufferImageCopy) VkError!void,
|
copyImageToBuffer: *const fn (*Self, *Image, vk.ImageLayout, *Buffer, []const vk.BufferImageCopy) VkError!void,
|
||||||
copyQueryPoolResults: *const fn (*Self, *QueryPool, u32, u32, *Buffer, vk.DeviceSize, vk.DeviceSize, vk.QueryResultFlags) VkError!void,
|
copyQueryPoolResults: *const fn (*Self, *QueryPool, u32, u32, *Buffer, vk.DeviceSize, vk.DeviceSize, vk.QueryResultFlags) VkError!void,
|
||||||
dispatch: *const fn (*Self, u32, u32, u32) VkError!void,
|
dispatch: *const fn (*Self, u32, u32, u32) VkError!void,
|
||||||
|
dispatchBase: *const fn (*Self, u32, u32, u32, u32, u32, u32) VkError!void,
|
||||||
dispatchIndirect: *const fn (*Self, *Buffer, vk.DeviceSize) VkError!void,
|
dispatchIndirect: *const fn (*Self, *Buffer, vk.DeviceSize) VkError!void,
|
||||||
draw: *const fn (*Self, usize, usize, usize, usize) VkError!void,
|
draw: *const fn (*Self, usize, usize, usize, usize) VkError!void,
|
||||||
drawIndexed: *const fn (*Self, usize, usize, usize, i32, usize) VkError!void,
|
drawIndexed: *const fn (*Self, usize, usize, usize, i32, usize) VkError!void,
|
||||||
@@ -76,6 +78,7 @@ pub const DispatchTable = struct {
|
|||||||
resolveImage: *const fn (*Self, *Image, vk.ImageLayout, *Image, vk.ImageLayout, vk.ImageResolve) VkError!void,
|
resolveImage: *const fn (*Self, *Image, vk.ImageLayout, *Image, vk.ImageLayout, vk.ImageResolve) VkError!void,
|
||||||
setEvent: *const fn (*Self, *Event, vk.PipelineStageFlags) VkError!void,
|
setEvent: *const fn (*Self, *Event, vk.PipelineStageFlags) VkError!void,
|
||||||
setBlendConstants: *const fn (*Self, [4]f32) VkError!void,
|
setBlendConstants: *const fn (*Self, [4]f32) VkError!void,
|
||||||
|
setDeviceMask: *const fn (*Self, u32) VkError!void,
|
||||||
setScissor: *const fn (*Self, u32, []const vk.Rect2D) VkError!void,
|
setScissor: *const fn (*Self, u32, []const vk.Rect2D) VkError!void,
|
||||||
setStencilCompareMask: *const fn (*Self, vk.StencilFaceFlags, u32) VkError!void,
|
setStencilCompareMask: *const fn (*Self, vk.StencilFaceFlags, u32) VkError!void,
|
||||||
setStencilReference: *const fn (*Self, vk.StencilFaceFlags, u32) VkError!void,
|
setStencilReference: *const fn (*Self, vk.StencilFaceFlags, u32) VkError!void,
|
||||||
@@ -96,6 +99,7 @@ pub fn init(device: *Device, allocator: std.mem.Allocator, info: *const vk.Comma
|
|||||||
.state = .Initial,
|
.state = .Initial,
|
||||||
.begin_info = null,
|
.begin_info = null,
|
||||||
.usage_flags = .{},
|
.usage_flags = .{},
|
||||||
|
.device_mask = 1,
|
||||||
.host_allocator = VulkanAllocator.from(allocator).cloneWithScope(.object),
|
.host_allocator = VulkanAllocator.from(allocator).cloneWithScope(.object),
|
||||||
.state_mutex = .init,
|
.state_mutex = .init,
|
||||||
.vtable = undefined,
|
.vtable = undefined,
|
||||||
@@ -152,6 +156,7 @@ pub fn resetFromPool(self: *Self, flags: vk.CommandBufferResetFlags) VkError!voi
|
|||||||
try self.dispatch_table.reset(self, flags);
|
try self.dispatch_table.reset(self, flags);
|
||||||
self.begin_info = null;
|
self.begin_info = null;
|
||||||
self.usage_flags = .{};
|
self.usage_flags = .{};
|
||||||
|
self.device_mask = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn submit(self: *Self) VkError!void {
|
pub fn submit(self: *Self) VkError!void {
|
||||||
@@ -247,6 +252,10 @@ pub inline fn dispatch(self: *Self, group_count_x: u32, group_count_y: u32, grou
|
|||||||
try self.dispatch_table.dispatch(self, group_count_x, group_count_y, group_count_z);
|
try self.dispatch_table.dispatch(self, group_count_x, group_count_y, group_count_z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub inline fn dispatchBase(self: *Self, base_group_x: u32, base_group_y: u32, base_group_z: u32, group_count_x: u32, group_count_y: u32, group_count_z: u32) VkError!void {
|
||||||
|
try self.dispatch_table.dispatchBase(self, base_group_x, base_group_y, base_group_z, group_count_x, group_count_y, group_count_z);
|
||||||
|
}
|
||||||
|
|
||||||
pub inline fn dispatchIndirect(self: *Self, buffer: *Buffer, offset: vk.DeviceSize) VkError!void {
|
pub inline fn dispatchIndirect(self: *Self, buffer: *Buffer, offset: vk.DeviceSize) VkError!void {
|
||||||
try self.dispatch_table.dispatchIndirect(self, buffer, offset);
|
try self.dispatch_table.dispatchIndirect(self, buffer, offset);
|
||||||
}
|
}
|
||||||
@@ -329,6 +338,13 @@ pub inline fn setBlendConstants(self: *Self, constants: [4]f32) VkError!void {
|
|||||||
try self.dispatch_table.setBlendConstants(self, constants);
|
try self.dispatch_table.setBlendConstants(self, constants);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub inline fn setDeviceMask(self: *Self, device_mask: u32) VkError!void {
|
||||||
|
if (device_mask != 1)
|
||||||
|
return VkError.ValidationFailed;
|
||||||
|
self.device_mask = device_mask;
|
||||||
|
try self.dispatch_table.setDeviceMask(self, device_mask);
|
||||||
|
}
|
||||||
|
|
||||||
pub inline fn setScissor(self: *Self, first: u32, scissor: []const vk.Rect2D) VkError!void {
|
pub inline fn setScissor(self: *Self, first: u32, scissor: []const vk.Rect2D) VkError!void {
|
||||||
try self.dispatch_table.setScissor(self, first, scissor);
|
try self.dispatch_table.setScissor(self, first, scissor);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,9 @@ pub const DispatchTable = struct {
|
|||||||
createSemaphore: *const fn (*Self, std.mem.Allocator, *const vk.SemaphoreCreateInfo) VkError!*BinarySemaphore,
|
createSemaphore: *const fn (*Self, std.mem.Allocator, *const vk.SemaphoreCreateInfo) VkError!*BinarySemaphore,
|
||||||
createShaderModule: *const fn (*Self, std.mem.Allocator, *const vk.ShaderModuleCreateInfo) VkError!*ShaderModule,
|
createShaderModule: *const fn (*Self, std.mem.Allocator, *const vk.ShaderModuleCreateInfo) VkError!*ShaderModule,
|
||||||
destroy: *const fn (*Self, std.mem.Allocator) VkError!void,
|
destroy: *const fn (*Self, std.mem.Allocator) VkError!void,
|
||||||
|
getDeviceGroupPeerMemoryFeatures: *const fn (*Self, u32, u32, u32) VkError!vk.PeerMemoryFeatureFlags,
|
||||||
|
getDeviceGroupPresentCapabilitiesKHR: *const fn (*Self, *vk.DeviceGroupPresentCapabilitiesKHR) VkError!void,
|
||||||
|
getDeviceGroupSurfacePresentModesKHR: *const fn (*Self, *SurfaceKHR) VkError!vk.DeviceGroupPresentModeFlagsKHR,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator, instance: *Instance, physical_device: *const PhysicalDevice, _: *const vk.DeviceCreateInfo) VkError!Self {
|
pub fn init(allocator: std.mem.Allocator, instance: *Instance, physical_device: *const PhysicalDevice, _: *const vk.DeviceCreateInfo) VkError!Self {
|
||||||
@@ -215,3 +218,15 @@ pub fn waitIdle(self: *Self) VkError!void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub inline fn getDeviceGroupPeerMemoryFeatures(self: *Self, heap_index: u32, local_device_index: u32, remote_device_index: u32) VkError!vk.PeerMemoryFeatureFlags {
|
||||||
|
return self.dispatch_table.getDeviceGroupPeerMemoryFeatures(self, heap_index, local_device_index, remote_device_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn getDeviceGroupPresentCapabilitiesKHR(self: *Self, capabilities: *vk.DeviceGroupPresentCapabilitiesKHR) VkError!void {
|
||||||
|
try self.dispatch_table.getDeviceGroupPresentCapabilitiesKHR(self, capabilities);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn getDeviceGroupSurfacePresentModesKHR(self: *Self, surface: *SurfaceKHR) VkError!vk.DeviceGroupPresentModeFlagsKHR {
|
||||||
|
return self.dispatch_table.getDeviceGroupSurfacePresentModesKHR(self, surface);
|
||||||
|
}
|
||||||
|
|||||||
+118
-19
@@ -137,6 +137,7 @@ const device_pfn_map = block: {
|
|||||||
@setEvalBranchQuota(65535);
|
@setEvalBranchQuota(65535);
|
||||||
break :block std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{
|
break :block std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{
|
||||||
functionMapEntryPoint("vkAcquireNextImageKHR"),
|
functionMapEntryPoint("vkAcquireNextImageKHR"),
|
||||||
|
functionMapEntryPoint("vkAcquireNextImage2KHR"),
|
||||||
functionMapEntryPoint("vkAllocateCommandBuffers"),
|
functionMapEntryPoint("vkAllocateCommandBuffers"),
|
||||||
functionMapEntryPoint("vkAllocateDescriptorSets"),
|
functionMapEntryPoint("vkAllocateDescriptorSets"),
|
||||||
functionMapEntryPoint("vkAllocateDescriptorSets"),
|
functionMapEntryPoint("vkAllocateDescriptorSets"),
|
||||||
@@ -160,6 +161,8 @@ const device_pfn_map = block: {
|
|||||||
functionMapEntryPoint("vkCmdCopyImageToBuffer"),
|
functionMapEntryPoint("vkCmdCopyImageToBuffer"),
|
||||||
functionMapEntryPoint("vkCmdCopyQueryPoolResults"),
|
functionMapEntryPoint("vkCmdCopyQueryPoolResults"),
|
||||||
functionMapEntryPoint("vkCmdDispatch"),
|
functionMapEntryPoint("vkCmdDispatch"),
|
||||||
|
functionMapEntryPoint("vkCmdDispatchBase"),
|
||||||
|
functionMapEntryPoint("vkCmdDispatchBaseKHR"),
|
||||||
functionMapEntryPoint("vkCmdDispatchIndirect"),
|
functionMapEntryPoint("vkCmdDispatchIndirect"),
|
||||||
functionMapEntryPoint("vkCmdDraw"),
|
functionMapEntryPoint("vkCmdDraw"),
|
||||||
functionMapEntryPoint("vkCmdDrawIndexed"),
|
functionMapEntryPoint("vkCmdDrawIndexed"),
|
||||||
@@ -178,6 +181,8 @@ const device_pfn_map = block: {
|
|||||||
functionMapEntryPoint("vkCmdSetBlendConstants"),
|
functionMapEntryPoint("vkCmdSetBlendConstants"),
|
||||||
functionMapEntryPoint("vkCmdSetDepthBias"),
|
functionMapEntryPoint("vkCmdSetDepthBias"),
|
||||||
functionMapEntryPoint("vkCmdSetDepthBounds"),
|
functionMapEntryPoint("vkCmdSetDepthBounds"),
|
||||||
|
functionMapEntryPoint("vkCmdSetDeviceMask"),
|
||||||
|
functionMapEntryPoint("vkCmdSetDeviceMaskKHR"),
|
||||||
functionMapEntryPoint("vkCmdSetEvent"),
|
functionMapEntryPoint("vkCmdSetEvent"),
|
||||||
functionMapEntryPoint("vkCmdSetLineWidth"),
|
functionMapEntryPoint("vkCmdSetLineWidth"),
|
||||||
functionMapEntryPoint("vkCmdSetScissor"),
|
functionMapEntryPoint("vkCmdSetScissor"),
|
||||||
@@ -236,6 +241,10 @@ const device_pfn_map = block: {
|
|||||||
functionMapEntryPoint("vkFreeMemory"),
|
functionMapEntryPoint("vkFreeMemory"),
|
||||||
functionMapEntryPoint("vkGetBufferMemoryRequirements"),
|
functionMapEntryPoint("vkGetBufferMemoryRequirements"),
|
||||||
functionMapEntryPoint("vkGetDeviceMemoryCommitment"),
|
functionMapEntryPoint("vkGetDeviceMemoryCommitment"),
|
||||||
|
functionMapEntryPoint("vkGetDeviceGroupPeerMemoryFeatures"),
|
||||||
|
functionMapEntryPoint("vkGetDeviceGroupPeerMemoryFeaturesKHR"),
|
||||||
|
functionMapEntryPoint("vkGetDeviceGroupPresentCapabilitiesKHR"),
|
||||||
|
functionMapEntryPoint("vkGetDeviceGroupSurfacePresentModesKHR"),
|
||||||
functionMapEntryPoint("vkGetDeviceProcAddr"),
|
functionMapEntryPoint("vkGetDeviceProcAddr"),
|
||||||
functionMapEntryPoint("vkGetDeviceQueue"),
|
functionMapEntryPoint("vkGetDeviceQueue"),
|
||||||
functionMapEntryPoint("vkGetEventStatus"),
|
functionMapEntryPoint("vkGetEventStatus"),
|
||||||
@@ -402,16 +411,12 @@ pub export fn apeEnumeratePhysicalDevices(p_instance: vk.Instance, count: *u32,
|
|||||||
return .success;
|
return .success;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub export fn apeEnumeratePhysicalDeviceGroups(
|
pub export fn apeEnumeratePhysicalDeviceGroups(p_instance: vk.Instance, count: *u32, p_groups: ?[*]vk.PhysicalDeviceGroupProperties) callconv(vk.vulkan_call_conv) vk.Result {
|
||||||
p_instance: vk.Instance,
|
|
||||||
count: *u32,
|
|
||||||
p_groups: ?[*]vk.PhysicalDeviceGroupProperties,
|
|
||||||
) callconv(vk.vulkan_call_conv) vk.Result {
|
|
||||||
entryPointBeginLogTrace(.vkEnumeratePhysicalDeviceGroups);
|
entryPointBeginLogTrace(.vkEnumeratePhysicalDeviceGroups);
|
||||||
defer entryPointEndLogTrace();
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
const instance = Dispatchable(Instance).fromHandleObject(p_instance) catch |err| return toVkResult(err);
|
const instance = Dispatchable(Instance).fromHandleObject(p_instance) catch |err| return toVkResult(err);
|
||||||
const available: u32 = 1;
|
const available: u32 = @intCast(instance.physical_devices.items.len);
|
||||||
|
|
||||||
if (p_groups) |groups| {
|
if (p_groups) |groups| {
|
||||||
const write_count = @min(count.*, available);
|
const write_count = @min(count.*, available);
|
||||||
@@ -420,16 +425,15 @@ pub export fn apeEnumeratePhysicalDeviceGroups(
|
|||||||
return .incomplete;
|
return .incomplete;
|
||||||
}
|
}
|
||||||
|
|
||||||
var group = groups[0];
|
for (groups[0..write_count], instance.physical_devices.items[0..write_count]) |*group, physical_device| {
|
||||||
group.physical_device_count = @intCast(instance.physical_devices.items.len);
|
group.physical_device_count = 1;
|
||||||
group.physical_devices = @splat(.null_handle);
|
group.physical_devices = @splat(.null_handle);
|
||||||
for (instance.physical_devices.items, 0..) |physical_device, i| {
|
group.physical_devices[0] = physical_device.toVkHandle(vk.PhysicalDevice);
|
||||||
group.physical_devices[i] = physical_device.toVkHandle(vk.PhysicalDevice);
|
group.subset_allocation = .false;
|
||||||
}
|
}
|
||||||
group.subset_allocation = .false;
|
|
||||||
groups[0] = group;
|
|
||||||
|
|
||||||
count.* = write_count;
|
count.* = write_count;
|
||||||
|
if (write_count < available) return .incomplete;
|
||||||
return .success;
|
return .success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,12 +441,8 @@ pub export fn apeEnumeratePhysicalDeviceGroups(
|
|||||||
return .success;
|
return .success;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub export fn apeEnumeratePhysicalDeviceGroupsKHR(
|
pub export fn apeEnumeratePhysicalDeviceGroupsKHR(p_instance: vk.Instance, count: *u32, p_groups: ?[*]vk.PhysicalDeviceGroupProperties) callconv(vk.vulkan_call_conv) vk.Result {
|
||||||
p_instance: vk.Instance,
|
return @call(.always_inline, apeEnumeratePhysicalDeviceGroups, .{ p_instance, count, p_groups });
|
||||||
count: *u32,
|
|
||||||
p_groups: ?[*]vk.PhysicalDeviceGroupProperties,
|
|
||||||
) callconv(vk.vulkan_call_conv) vk.Result {
|
|
||||||
return apeEnumeratePhysicalDeviceGroups(p_instance, count, p_groups);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Physical Device functions =================================================================================================================================
|
// Physical Device functions =================================================================================================================================
|
||||||
@@ -1412,6 +1412,60 @@ pub export fn apeGetDeviceMemoryCommitment(p_device: vk.Device, p_memory: vk.Dev
|
|||||||
_ = committed_memory;
|
_ = committed_memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub export fn apeGetDeviceGroupPeerMemoryFeatures(
|
||||||
|
p_device: vk.Device,
|
||||||
|
heap_index: u32,
|
||||||
|
local_device_index: u32,
|
||||||
|
remote_device_index: u32,
|
||||||
|
p_peer_memory_features: *vk.PeerMemoryFeatureFlags,
|
||||||
|
) callconv(vk.vulkan_call_conv) void {
|
||||||
|
entryPointBeginLogTrace(.vkGetDeviceGroupPeerMemoryFeatures);
|
||||||
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
|
const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return errorLogger(err);
|
||||||
|
p_peer_memory_features.* = device.getDeviceGroupPeerMemoryFeatures(heap_index, local_device_index, remote_device_index) catch |err| return errorLogger(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub export fn apeGetDeviceGroupPeerMemoryFeaturesKHR(
|
||||||
|
p_device: vk.Device,
|
||||||
|
heap_index: u32,
|
||||||
|
local_device_index: u32,
|
||||||
|
remote_device_index: u32,
|
||||||
|
p_peer_memory_features: *vk.PeerMemoryFeatureFlags,
|
||||||
|
) callconv(vk.vulkan_call_conv) void {
|
||||||
|
apeGetDeviceGroupPeerMemoryFeatures(p_device, heap_index, local_device_index, remote_device_index, p_peer_memory_features);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub export fn apeGetDeviceGroupPresentCapabilitiesKHR(
|
||||||
|
p_device: vk.Device,
|
||||||
|
p_device_group_present_capabilities: *vk.DeviceGroupPresentCapabilitiesKHR,
|
||||||
|
) callconv(vk.vulkan_call_conv) vk.Result {
|
||||||
|
entryPointBeginLogTrace(.vkGetDeviceGroupPresentCapabilitiesKHR);
|
||||||
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
|
if (p_device_group_present_capabilities.s_type != .device_group_present_capabilities_khr) {
|
||||||
|
return .error_validation_failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err);
|
||||||
|
device.getDeviceGroupPresentCapabilitiesKHR(p_device_group_present_capabilities) catch |err| return toVkResult(err);
|
||||||
|
return .success;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub export fn apeGetDeviceGroupSurfacePresentModesKHR(
|
||||||
|
p_device: vk.Device,
|
||||||
|
p_surface: vk.SurfaceKHR,
|
||||||
|
p_modes: *vk.DeviceGroupPresentModeFlagsKHR,
|
||||||
|
) callconv(vk.vulkan_call_conv) vk.Result {
|
||||||
|
entryPointBeginLogTrace(.vkGetDeviceGroupSurfacePresentModesKHR);
|
||||||
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
|
const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err);
|
||||||
|
const surface = NonDispatchable(SurfaceKHR).fromHandleObject(p_surface) catch |err| return toVkResult(err);
|
||||||
|
p_modes.* = device.getDeviceGroupSurfacePresentModesKHR(surface) catch |err| return toVkResult(err);
|
||||||
|
return .success;
|
||||||
|
}
|
||||||
|
|
||||||
pub export fn apeGetDeviceProcAddr(p_device: vk.Device, p_name: ?[*:0]const u8) callconv(vk.vulkan_call_conv) vk.PfnVoidFunction {
|
pub export fn apeGetDeviceProcAddr(p_device: vk.Device, p_name: ?[*:0]const u8) callconv(vk.vulkan_call_conv) vk.PfnVoidFunction {
|
||||||
defer entryPointEndLogTrace();
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
@@ -1876,6 +1930,18 @@ pub export fn apeCmdDispatch(p_cmd: vk.CommandBuffer, group_count_x: u32, group_
|
|||||||
cmd.dispatch(group_count_x, group_count_y, group_count_z) catch |err| return errorLogger(err);
|
cmd.dispatch(group_count_x, group_count_y, group_count_z) catch |err| return errorLogger(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub export fn apeCmdDispatchBase(p_cmd: vk.CommandBuffer, base_group_x: u32, base_group_y: u32, base_group_z: u32, group_count_x: u32, group_count_y: u32, group_count_z: u32) callconv(vk.vulkan_call_conv) void {
|
||||||
|
entryPointBeginLogTrace(.vkCmdDispatchBase);
|
||||||
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
|
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
|
||||||
|
cmd.dispatchBase(base_group_x, base_group_y, base_group_z, group_count_x, group_count_y, group_count_z) catch |err| return errorLogger(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub export fn apeCmdDispatchBaseKHR(p_cmd: vk.CommandBuffer, base_group_x: u32, base_group_y: u32, base_group_z: u32, group_count_x: u32, group_count_y: u32, group_count_z: u32) callconv(vk.vulkan_call_conv) void {
|
||||||
|
@call(.always_inline, apeCmdDispatchBase, .{ p_cmd, base_group_x, base_group_y, base_group_z, group_count_x, group_count_y, group_count_z });
|
||||||
|
}
|
||||||
|
|
||||||
pub export fn apeCmdDispatchIndirect(p_cmd: vk.CommandBuffer, p_buffer: vk.Buffer, offset: vk.DeviceSize) callconv(vk.vulkan_call_conv) void {
|
pub export fn apeCmdDispatchIndirect(p_cmd: vk.CommandBuffer, p_buffer: vk.Buffer, offset: vk.DeviceSize) callconv(vk.vulkan_call_conv) void {
|
||||||
entryPointBeginLogTrace(.vkCmdDispatchIndirect);
|
entryPointBeginLogTrace(.vkCmdDispatchIndirect);
|
||||||
defer entryPointEndLogTrace();
|
defer entryPointEndLogTrace();
|
||||||
@@ -2073,6 +2139,18 @@ pub export fn apeCmdSetDepthBounds(p_cmd: vk.CommandBuffer, min: f32, max: f32)
|
|||||||
_ = max;
|
_ = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub export fn apeCmdSetDeviceMask(p_cmd: vk.CommandBuffer, device_mask: u32) callconv(vk.vulkan_call_conv) void {
|
||||||
|
entryPointBeginLogTrace(.vkCmdSetDeviceMask);
|
||||||
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
|
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
|
||||||
|
cmd.setDeviceMask(device_mask) catch |err| return errorLogger(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub export fn apeCmdSetDeviceMaskKHR(p_cmd: vk.CommandBuffer, device_mask: u32) callconv(vk.vulkan_call_conv) void {
|
||||||
|
@call(.always_inline, apeCmdSetDeviceMask, .{ p_cmd, device_mask });
|
||||||
|
}
|
||||||
|
|
||||||
pub export fn apeCmdSetEvent(p_cmd: vk.CommandBuffer, p_event: vk.Event, stage_mask: vk.PipelineStageFlags) callconv(vk.vulkan_call_conv) void {
|
pub export fn apeCmdSetEvent(p_cmd: vk.CommandBuffer, p_event: vk.Event, stage_mask: vk.PipelineStageFlags) callconv(vk.vulkan_call_conv) void {
|
||||||
entryPointBeginLogTrace(.vkCmdSetEvent);
|
entryPointBeginLogTrace(.vkCmdSetEvent);
|
||||||
defer entryPointEndLogTrace();
|
defer entryPointEndLogTrace();
|
||||||
@@ -2221,6 +2299,27 @@ pub export fn apeAcquireNextImageKHR(p_device: vk.Device, p_swapchain: vk.Swapch
|
|||||||
return .success;
|
return .success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub export fn apeAcquireNextImage2KHR(p_device: vk.Device, p_acquire_info: *const vk.AcquireNextImageInfoKHR, image_index: *u32) callconv(vk.vulkan_call_conv) vk.Result {
|
||||||
|
entryPointBeginLogTrace(.vkAcquireNextImage2KHR);
|
||||||
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
|
if (p_acquire_info.s_type != .acquire_next_image_info_khr) {
|
||||||
|
return .error_validation_failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_acquire_info.device_mask != 1) {
|
||||||
|
return .error_validation_failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return toVkResult(err);
|
||||||
|
|
||||||
|
const swapchain = NonDispatchable(SwapchainKHR).fromHandleObject(p_acquire_info.swapchain) catch |err| return toVkResult(err);
|
||||||
|
const semaphore = if (p_acquire_info.semaphore != .null_handle) NonDispatchable(BinarySemaphore).fromHandleObject(p_acquire_info.semaphore) catch |err| return toVkResult(err) else null;
|
||||||
|
const fence = if (p_acquire_info.fence != .null_handle) NonDispatchable(Fence).fromHandleObject(p_acquire_info.fence) catch |err| return toVkResult(err) else null;
|
||||||
|
swapchain.getNextImage(p_acquire_info.timeout, semaphore, fence, image_index) catch |err| return toVkResult(err);
|
||||||
|
return .success;
|
||||||
|
}
|
||||||
|
|
||||||
pub export fn apeCreateSwapchainKHR(p_device: vk.Device, info: *const vk.SwapchainCreateInfoKHR, callbacks: ?*const vk.AllocationCallbacks, p_swapchain: *vk.SwapchainKHR) callconv(vk.vulkan_call_conv) vk.Result {
|
pub export fn apeCreateSwapchainKHR(p_device: vk.Device, info: *const vk.SwapchainCreateInfoKHR, callbacks: ?*const vk.AllocationCallbacks, p_swapchain: *vk.SwapchainKHR) callconv(vk.vulkan_call_conv) vk.Result {
|
||||||
entryPointBeginLogTrace(.vkCreateSwapchainKHR);
|
entryPointBeginLogTrace(.vkCreateSwapchainKHR);
|
||||||
defer entryPointEndLogTrace();
|
defer entryPointEndLogTrace();
|
||||||
|
|||||||
Reference in New Issue
Block a user