Files
VulkanDriver/src/vulkan/lib_vulkan.zig

1034 lines
46 KiB
Zig

//! This file contains all exported Vulkan entrypoints.
const std = @import("std");
const vk = @import("vulkan");
const root = @import("root");
const lib = @import("lib.zig");
const builtin = @import("builtin");
const logger = @import("logger.zig");
const error_set = @import("error_set.zig");
const VkError = error_set.VkError;
const toVkResult = error_set.toVkResult;
const errorLogger = error_set.errorLogger;
const Dispatchable = @import("Dispatchable.zig").Dispatchable;
const NonDispatchable = @import("NonDispatchable.zig").NonDispatchable;
const VulkanAllocator = @import("VulkanAllocator.zig");
const Instance = @import("Instance.zig");
const Device = @import("Device.zig");
const PhysicalDevice = @import("PhysicalDevice.zig");
const Queue = @import("Queue.zig");
const Buffer = @import("Buffer.zig");
const CommandBuffer = @import("CommandBuffer.zig");
const CommandPool = @import("CommandPool.zig");
const DeviceMemory = @import("DeviceMemory.zig");
const Fence = @import("Fence.zig");
const Image = @import("Image.zig");
const ImageView = @import("ImageView.zig");
fn entryPointBeginLogTrace(comptime scope: @Type(.enum_literal)) void {
std.log.scoped(scope).debug("Calling {s}...", .{@tagName(scope)});
logger.indent();
}
fn entryPointEndLogTrace() void {
logger.unindent();
}
fn entryPointNotFoundErrorLog(comptime scope: @Type(.enum_literal), name: []const u8) void {
if (lib.getLogVerboseLevel() != .TooMuch) return;
std.log.scoped(scope).err("Could not find function {s}", .{name});
}
inline fn notImplementedWarning() void {
logger.nestedFixme("function not yet implemented", .{});
}
fn functionMapEntryPoint(comptime name: []const u8) struct { []const u8, vk.PfnVoidFunction } {
// Mapping 'vkFnName' to 'strollFnName'
const stroll_name = std.fmt.comptimePrint("stroll{s}", .{name[2..]});
return if (std.meta.hasFn(@This(), name))
.{ name, @as(vk.PfnVoidFunction, @ptrCast(&@field(@This(), name))) }
else if (std.meta.hasFn(@This(), stroll_name))
.{ name, @as(vk.PfnVoidFunction, @ptrCast(&@field(@This(), stroll_name))) }
else
@compileError("Invalid entry point name");
}
const icd_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{
functionMapEntryPoint("vk_icdGetInstanceProcAddr"),
functionMapEntryPoint("vk_icdGetPhysicalDeviceProcAddr"),
functionMapEntryPoint("vk_icdNegotiateLoaderICDInterfaceVersion"),
});
const global_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{
functionMapEntryPoint("vkCreateInstance"),
functionMapEntryPoint("vkEnumerateInstanceExtensionProperties"),
functionMapEntryPoint("vkEnumerateInstanceVersion"),
functionMapEntryPoint("vkGetInstanceProcAddr"),
});
const instance_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{
functionMapEntryPoint("vkDestroyInstance"),
functionMapEntryPoint("vkEnumeratePhysicalDevices"),
functionMapEntryPoint("vkGetDeviceProcAddr"),
});
const physical_device_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{
functionMapEntryPoint("vkCreateDevice"),
functionMapEntryPoint("vkEnumerateDeviceExtensionProperties"),
functionMapEntryPoint("vkGetPhysicalDeviceFeatures"),
functionMapEntryPoint("vkGetPhysicalDeviceFormatProperties"),
functionMapEntryPoint("vkGetPhysicalDeviceImageFormatProperties"),
functionMapEntryPoint("vkGetPhysicalDeviceMemoryProperties"),
functionMapEntryPoint("vkGetPhysicalDeviceProperties"),
functionMapEntryPoint("vkGetPhysicalDeviceQueueFamilyProperties"),
functionMapEntryPoint("vkGetPhysicalDeviceSparseImageFormatProperties"),
});
const device_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{
functionMapEntryPoint("vkAllocateCommandBuffers"),
functionMapEntryPoint("vkAllocateDescriptorSets"),
functionMapEntryPoint("vkAllocateMemory"),
functionMapEntryPoint("vkBeginCommandBuffer"),
functionMapEntryPoint("vkBindBufferMemory"),
functionMapEntryPoint("vkBindImageMemory"),
functionMapEntryPoint("vkCmdBeginQuery"),
functionMapEntryPoint("vkCmdBeginRenderPass"),
functionMapEntryPoint("vkCmdBindDescriptorSets"),
functionMapEntryPoint("vkCmdBindIndexBuffer"),
functionMapEntryPoint("vkCmdBindPipeline"),
functionMapEntryPoint("vkCmdBindVertexBuffers"),
functionMapEntryPoint("vkCmdBlitImage"),
functionMapEntryPoint("vkCmdClearAttachments"),
functionMapEntryPoint("vkCmdClearColorImage"),
functionMapEntryPoint("vkCmdClearDepthStencilImage"),
functionMapEntryPoint("vkCmdCopyBuffer"),
functionMapEntryPoint("vkCmdCopyBufferToImage"),
functionMapEntryPoint("vkCmdCopyImage"),
functionMapEntryPoint("vkCmdFillBuffer"),
functionMapEntryPoint("vkCreateBuffer"),
functionMapEntryPoint("vkCreateCommandPool"),
functionMapEntryPoint("vkCreateFence"),
functionMapEntryPoint("vkCreateImage"),
functionMapEntryPoint("vkCreateImageView"),
functionMapEntryPoint("vkDestroyBuffer"),
functionMapEntryPoint("vkDestroyCommandPool"),
functionMapEntryPoint("vkDestroyDevice"),
functionMapEntryPoint("vkDestroyFence"),
functionMapEntryPoint("vkDestroyImage"),
functionMapEntryPoint("vkDestroyImageView"),
functionMapEntryPoint("vkEndCommandBuffer"),
functionMapEntryPoint("vkFreeCommandBuffers"),
functionMapEntryPoint("vkFreeMemory"),
functionMapEntryPoint("vkGetBufferMemoryRequirements"),
functionMapEntryPoint("vkGetDeviceQueue"),
functionMapEntryPoint("vkGetFenceStatus"),
functionMapEntryPoint("vkGetImageMemoryRequirements"),
functionMapEntryPoint("vkMapMemory"),
functionMapEntryPoint("vkQueueBindSparse"),
functionMapEntryPoint("vkQueueSubmit"),
functionMapEntryPoint("vkQueueWaitIdle"),
functionMapEntryPoint("vkResetCommandBuffer"),
functionMapEntryPoint("vkResetFences"),
functionMapEntryPoint("vkUnmapMemory"),
functionMapEntryPoint("vkWaitForFences"),
});
// ICD Interface =============================================================================================================================================
pub export fn stroll_icdNegotiateLoaderICDInterfaceVersion(p_version: *u32) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vk_icdNegociateLoaderICDInterfaceVersion);
defer entryPointEndLogTrace();
p_version.* = 7;
return .success;
}
pub export fn vk_icdGetInstanceProcAddr(p_instance: vk.Instance, p_name: ?[*:0]const u8) callconv(vk.vulkan_call_conv) vk.PfnVoidFunction {
if (lib.getLogVerboseLevel() == .TooMuch) {
entryPointBeginLogTrace(.vk_icdGetInstanceProcAddr);
}
defer entryPointEndLogTrace();
if (p_name == null) return null;
const name = std.mem.span(p_name.?);
if (icd_pfn_map.get(name)) |pfn| return pfn;
return vkGetInstanceProcAddr(p_instance, p_name);
}
pub export fn stroll_icdGetPhysicalDeviceProcAddr(_: vk.Instance, p_name: ?[*:0]const u8) callconv(vk.vulkan_call_conv) vk.PfnVoidFunction {
if (lib.getLogVerboseLevel() == .TooMuch) {
entryPointBeginLogTrace(.vk_icdGetPhysicalDeviceProcAddr);
}
defer entryPointEndLogTrace();
if (p_name == null) return null;
const name = std.mem.span(p_name.?);
if (physical_device_pfn_map.get(name)) |pfn| return pfn;
entryPointNotFoundErrorLog(.vk_icdGetPhysicalDeviceProcAddr, name);
return null;
}
// Global functions ==========================================================================================================================================
pub export fn vkGetInstanceProcAddr(p_instance: vk.Instance, p_name: ?[*:0]const u8) callconv(vk.vulkan_call_conv) vk.PfnVoidFunction {
if (lib.getLogVerboseLevel() == .TooMuch) {
entryPointBeginLogTrace(.vkGetInstanceProcAddr);
}
defer entryPointEndLogTrace();
if (p_name == null) return null;
const name = std.mem.span(p_name.?);
if (global_pfn_map.get(name)) |pfn| return pfn;
if (p_instance == .null_handle) {
entryPointNotFoundErrorLog(.vkGetInstanceProcAddr, name);
return null;
}
if (instance_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;
entryPointNotFoundErrorLog(.vkGetInstanceProcAddr, name);
return null;
}
pub export fn strollCreateInstance(info: *const vk.InstanceCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_instance: *vk.Instance) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkCreateInstance);
defer entryPointEndLogTrace();
if (info.s_type != .instance_create_info) {
return .error_validation_failed;
}
const allocator = VulkanAllocator.init(callbacks, .instance).allocator();
var instance: *lib.Instance = undefined;
if (!builtin.is_test) {
// Will call impl instead of interface as root refs the impl module
instance = root.Instance.create(allocator, info) catch |err| return toVkResult(err);
}
instance.requestPhysicalDevices(allocator) catch |err| return toVkResult(err);
p_instance.* = (Dispatchable(Instance).wrap(allocator, instance) catch |err| return toVkResult(err)).toVkHandle(vk.Instance);
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 {
entryPointBeginLogTrace(.vkEnumerateInstanceExtensionProperties);
defer entryPointEndLogTrace();
var name: ?[]const u8 = null;
if (p_layer_name) |layer_name| {
name = std.mem.span(layer_name);
}
Instance.enumerateExtensionProperties(name, property_count, properties) catch |err| return toVkResult(err);
return .success;
}
pub export fn strollEnumerateInstanceVersion(version: *u32) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkEnumerateInstanceVersion);
defer entryPointEndLogTrace();
Instance.enumerateVersion(version) catch |err| return toVkResult(err);
return .success;
}
// Instance functions ========================================================================================================================================
pub export fn strollDestroyInstance(p_instance: vk.Instance, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void {
defer logger.freeInnerDebugStack();
entryPointBeginLogTrace(.vkDestroyInstance);
defer entryPointEndLogTrace();
const allocator = VulkanAllocator.init(callbacks, .instance).allocator();
const dispatchable = Dispatchable(Instance).fromHandle(p_instance) catch |err| return errorLogger(err);
dispatchable.object.deinit(allocator) catch |err| return errorLogger(err);
dispatchable.destroy(allocator);
if (std.process.hasEnvVarConstant(lib.DRIVER_DEBUG_ALLOCATOR_ENV_NAME) or builtin.mode == std.builtin.OptimizeMode.Debug) {
// All host memory allocations should've been freed by now
if (!VulkanAllocator.debug_allocator.detectLeaks()) {
std.log.scoped(.vkDestroyInstance).debug("No memory leaks detected", .{});
}
}
}
pub export fn strollEnumeratePhysicalDevices(p_instance: vk.Instance, count: *u32, p_devices: ?[*]vk.PhysicalDevice) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkEnumeratePhysicalDevices);
defer entryPointEndLogTrace();
const instance = Dispatchable(Instance).fromHandleObject(p_instance) catch |err| return toVkResult(err);
count.* = @intCast(instance.physical_devices.items.len);
if (p_devices) |devices| {
for (0..count.*) |i| {
devices[i] = instance.physical_devices.items[i].toVkHandle(vk.PhysicalDevice);
}
}
return .success;
}
// Physical Device functions =================================================================================================================================
pub export fn strollCreateDevice(p_physical_device: vk.PhysicalDevice, info: *const vk.DeviceCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_device: *vk.Device) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkCreateDevice);
defer entryPointEndLogTrace();
if (info.s_type != .device_create_info) {
return .error_validation_failed;
}
const allocator = VulkanAllocator.init(callbacks, .device).allocator();
const physical_device = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch |err| return toVkResult(err);
std.log.scoped(.vkCreateDevice).debug("Using VkPhysicalDevice named {s}", .{physical_device.props.device_name});
const device = physical_device.createDevice(allocator, info) catch |err| return toVkResult(err);
p_device.* = (Dispatchable(Device).wrap(allocator, device) catch |err| return toVkResult(err)).toVkHandle(vk.Device);
return .success;
}
pub export fn strollEnumerateDeviceExtensionProperties(p_physical_device: vk.PhysicalDevice, p_layer_name: ?[*:0]const u8, property_count: *u32, properties: ?*vk.ExtensionProperties) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkEnumerateDeviceExtensionProperties);
defer entryPointEndLogTrace();
var name: ?[]const u8 = null;
if (p_layer_name) |layer_name| {
name = std.mem.span(layer_name);
}
_ = p_physical_device;
property_count.* = 0;
_ = properties;
return .success;
}
pub export fn strollGetPhysicalDeviceFormatProperties(p_physical_device: vk.PhysicalDevice, format: vk.Format, properties: *vk.FormatProperties) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkGetPhysicalDeviceFormatProperties);
defer entryPointEndLogTrace();
const physical_device = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch |err| return errorLogger(err);
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 {
entryPointBeginLogTrace(.vkGetPhysicalDeviceFeatures);
defer entryPointEndLogTrace();
const physical_device = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch |err| return errorLogger(err);
features.* = physical_device.features;
}
pub export fn strollGetPhysicalDeviceImageFormatProperties(
p_physical_device: vk.PhysicalDevice,
format: vk.Format,
image_type: vk.ImageType,
tiling: vk.ImageTiling,
usage: vk.ImageUsageFlags,
flags: vk.ImageCreateFlags,
properties: *vk.ImageFormatProperties,
) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkGetPhysicalDeviceImageFormatProperties);
defer entryPointEndLogTrace();
const physical_device = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch |err| return toVkResult(err);
properties.* = physical_device.getImageFormatProperties(format, image_type, tiling, usage, 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 {
entryPointBeginLogTrace(.vkGetPhysicalDeviceProperties);
defer entryPointEndLogTrace();
const physical_device = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch |err| return errorLogger(err);
properties.* = physical_device.props;
}
pub export fn strollGetPhysicalDeviceMemoryProperties(p_physical_device: vk.PhysicalDevice, properties: *vk.PhysicalDeviceMemoryProperties) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkGetPhysicalDeviceMemoryProperties);
defer entryPointEndLogTrace();
const physical_device = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch |err| return errorLogger(err);
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 {
entryPointBeginLogTrace(.vkGetPhysicalDeviceQueueFamilyProperties);
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) |props| {
@memcpy(props[0..count.*], physical_device.queue_family_props.items[0..count.*]);
}
}
pub export fn strollGetPhysicalDeviceSparseImageFormatProperties(
p_physical_device: vk.PhysicalDevice,
format: vk.Format,
image_type: vk.ImageType,
samples: vk.SampleCountFlags,
tiling: vk.ImageTiling,
usage: vk.ImageUsageFlags,
flags: vk.ImageCreateFlags,
properties: *vk.SparseImageFormatProperties,
) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkGetPhysicalDeviceSparseImageFormatProperties);
defer entryPointEndLogTrace();
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);
return .success;
}
// Queue functions ===========================================================================================================================================
pub export fn strollQueueBindSparse(p_queue: vk.Queue, count: u32, info: [*]vk.BindSparseInfo, p_fence: vk.Fence) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkQueueBindSparse);
defer entryPointEndLogTrace();
const queue = Dispatchable(Queue).fromHandleObject(p_queue) catch |err| return toVkResult(err);
const fence = if (p_fence != .null_handle) NonDispatchable(Fence).fromHandleObject(p_fence) catch |err| return toVkResult(err) else null;
queue.bindSparse(info[0..count], fence) catch |err| return toVkResult(err);
return .success;
}
pub export fn strollQueueSubmit(p_queue: vk.Queue, count: u32, info: [*]const vk.SubmitInfo, p_fence: vk.Fence) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkQueueSubmit);
defer entryPointEndLogTrace();
if (count == 0) return .success;
const queue = Dispatchable(Queue).fromHandleObject(p_queue) catch |err| return toVkResult(err);
const fence = if (p_fence != .null_handle) NonDispatchable(Fence).fromHandleObject(p_fence) catch |err| return toVkResult(err) else null;
queue.submit(info[0..count], fence) catch |err| return toVkResult(err);
return .success;
}
pub export fn strollQueueWaitIdle(p_queue: vk.Queue) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkQueueWaitIdle);
defer entryPointEndLogTrace();
const queue = Dispatchable(Queue).fromHandleObject(p_queue) catch |err| return toVkResult(err);
queue.waitIdle() catch |err| return toVkResult(err);
return .success;
}
// Device functions ==========================================================================================================================================
pub export fn strollAllocateCommandBuffers(p_device: vk.Device, info: *const vk.CommandBufferAllocateInfo, p_cmds: [*]vk.CommandBuffer) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkAllocateCommandBuffers);
defer entryPointEndLogTrace();
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return toVkResult(err);
if (info.s_type != .command_buffer_allocate_info) {
return .error_validation_failed;
}
const pool = NonDispatchable(CommandPool).fromHandleObject(info.command_pool) catch |err| return toVkResult(err);
const cmds = pool.allocateCommandBuffers(info) catch |err| return toVkResult(err);
for (cmds[0..info.command_buffer_count], 0..) |cmd, i| {
p_cmds[i] = cmd.toVkHandle(vk.CommandBuffer);
}
return .success;
}
pub export fn strollAllocateDescriptorSets(p_device: vk.Device, info: *const vk.DescriptorSetAllocateInfo, p_set: *vk.DescriptorSet) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkAllocateCommandBuffers);
defer entryPointEndLogTrace();
if (info.s_type != .descriptor_set_allocate_info) {
return .error_validation_failed;
}
const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err);
notImplementedWarning();
_ = device;
_ = p_set;
return .success;
}
pub export fn strollAllocateMemory(p_device: vk.Device, info: *const vk.MemoryAllocateInfo, callbacks: ?*const vk.AllocationCallbacks, p_memory: *vk.DeviceMemory) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkAllocateMemory);
defer entryPointEndLogTrace();
if (info.s_type != .memory_allocate_info) {
return .error_validation_failed;
}
std.log.scoped(.vkAllocateMemory).debug("Allocating {d} bytes from device 0x{X}", .{ info.allocation_size, @intFromEnum(p_device) });
const allocator = VulkanAllocator.init(callbacks, .object).allocator();
const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err);
const device_memory = device.allocateMemory(allocator, info) catch |err| return toVkResult(err);
p_memory.* = (NonDispatchable(DeviceMemory).wrap(allocator, device_memory) catch |err| return toVkResult(err)).toVkHandle(vk.DeviceMemory);
return .success;
}
pub export fn strollBindBufferMemory(p_device: vk.Device, p_buffer: vk.Buffer, p_memory: vk.DeviceMemory, offset: vk.DeviceSize) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkBindBufferMemory);
defer entryPointEndLogTrace();
std.log.scoped(.vkBindBufferMemory).debug("Binding device memory 0x{X} to buffer 0x{X}", .{ @intFromEnum(p_memory), @intFromEnum(p_buffer) });
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return toVkResult(err);
const buffer = NonDispatchable(Buffer).fromHandleObject(p_buffer) catch |err| return toVkResult(err);
const memory = NonDispatchable(DeviceMemory).fromHandleObject(p_memory) catch |err| return toVkResult(err);
buffer.bindMemory(memory, offset) catch |err| return toVkResult(err);
return .success;
}
pub export fn strollBindImageMemory(p_device: vk.Device, p_image: vk.Image, p_memory: vk.DeviceMemory, offset: vk.DeviceSize) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkBindImageMemory);
defer entryPointEndLogTrace();
std.log.scoped(.vkBindImageMemory).debug("Binding device memory 0x{X} to image 0x{X}", .{ @intFromEnum(p_memory), @intFromEnum(p_image) });
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return toVkResult(err);
const image = NonDispatchable(Image).fromHandleObject(p_image) catch |err| return toVkResult(err);
const memory = NonDispatchable(DeviceMemory).fromHandleObject(p_memory) catch |err| return toVkResult(err);
image.bindMemory(memory, offset) catch |err| return toVkResult(err);
return .success;
}
pub export fn strollCreateBuffer(p_device: vk.Device, info: *const vk.BufferCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_buffer: *vk.Buffer) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkCreateBuffer);
defer entryPointEndLogTrace();
if (info.s_type != .buffer_create_info) {
return .error_validation_failed;
}
const allocator = VulkanAllocator.init(callbacks, .object).allocator();
const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err);
const buffer = device.createBuffer(allocator, info) catch |err| return toVkResult(err);
p_buffer.* = (NonDispatchable(Buffer).wrap(allocator, buffer) catch |err| return toVkResult(err)).toVkHandle(vk.Buffer);
return .success;
}
pub export fn strollCreateCommandPool(p_device: vk.Device, info: *const vk.CommandPoolCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_pool: *vk.CommandPool) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkCreateCommandPool);
defer entryPointEndLogTrace();
if (info.s_type != .command_pool_create_info) {
return .error_validation_failed;
}
const allocator = VulkanAllocator.init(callbacks, .object).allocator();
const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err);
const pool = device.createCommandPool(allocator, info) catch |err| return toVkResult(err);
p_pool.* = (NonDispatchable(CommandPool).wrap(allocator, pool) catch |err| return toVkResult(err)).toVkHandle(vk.CommandPool);
return .success;
}
pub export fn strollCreateFence(p_device: vk.Device, info: *const vk.FenceCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_fence: *vk.Fence) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkCreateFence);
defer entryPointEndLogTrace();
if (info.s_type != .fence_create_info) {
return .error_validation_failed;
}
const allocator = VulkanAllocator.init(callbacks, .object).allocator();
const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err);
const fence = device.createFence(allocator, info) catch |err| return toVkResult(err);
p_fence.* = (NonDispatchable(Fence).wrap(allocator, fence) catch |err| return toVkResult(err)).toVkHandle(vk.Fence);
return .success;
}
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 {
entryPointBeginLogTrace(.vkCreateImage);
defer entryPointEndLogTrace();
if (info.s_type != .image_create_info) {
return .error_validation_failed;
}
const allocator = VulkanAllocator.init(callbacks, .object).allocator();
const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err);
const image = device.createImage(allocator, info) catch |err| return toVkResult(err);
p_image.* = (NonDispatchable(Image).wrap(allocator, image) catch |err| return toVkResult(err)).toVkHandle(vk.Image);
return .success;
}
pub export fn strollCreateImageView(p_device: vk.Device, info: *const vk.ImageViewCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_image_view: *vk.ImageView) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkCreateImageView);
defer entryPointEndLogTrace();
if (info.s_type != .image_view_create_info) {
return .error_validation_failed;
}
const allocator = VulkanAllocator.init(callbacks, .object).allocator();
const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err);
const image_view = device.createImageView(allocator, info) catch |err| return toVkResult(err);
p_image_view.* = (NonDispatchable(ImageView).wrap(allocator, image_view) catch |err| return toVkResult(err)).toVkHandle(vk.ImageView);
return .success;
}
pub export fn strollDestroyBuffer(p_device: vk.Device, p_buffer: vk.Buffer, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkDestroyBuffer);
defer entryPointEndLogTrace();
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err);
const allocator = VulkanAllocator.init(callbacks, .object).allocator();
const non_dispatchable = NonDispatchable(Buffer).fromHandle(p_buffer) catch |err| return errorLogger(err);
non_dispatchable.intrusiveDestroy(allocator);
}
pub export fn strollDestroyCommandPool(p_device: vk.Device, p_pool: vk.CommandPool, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkDestroyCommandPool);
defer entryPointEndLogTrace();
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err);
const allocator = VulkanAllocator.init(callbacks, .object).allocator();
const non_dispatchable = NonDispatchable(CommandPool).fromHandle(p_pool) catch |err| return errorLogger(err);
non_dispatchable.intrusiveDestroy(allocator);
}
pub export fn strollDestroyDevice(p_device: vk.Device, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkDestroyDevice);
defer entryPointEndLogTrace();
const allocator = VulkanAllocator.init(callbacks, .object).allocator();
const dispatchable = Dispatchable(Device).fromHandle(p_device) catch |err| return errorLogger(err);
std.log.scoped(.vkDestroyDevice).debug("Destroying VkDevice created from {s}", .{dispatchable.object.physical_device.props.device_name});
dispatchable.object.destroy(allocator) catch |err| return errorLogger(err);
dispatchable.destroy(allocator);
}
pub export fn strollDestroyFence(p_device: vk.Device, p_fence: vk.Fence, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkDestroyFence);
defer entryPointEndLogTrace();
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err);
const allocator = VulkanAllocator.init(callbacks, .object).allocator();
const non_dispatchable = NonDispatchable(Fence).fromHandle(p_fence) catch |err| return errorLogger(err);
non_dispatchable.intrusiveDestroy(allocator);
}
pub export fn strollDestroyImage(p_device: vk.Device, p_image: vk.Image, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkDestroyImage);
defer entryPointEndLogTrace();
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err);
const allocator = VulkanAllocator.init(callbacks, .object).allocator();
const non_dispatchable = NonDispatchable(Image).fromHandle(p_image) catch |err| return errorLogger(err);
non_dispatchable.intrusiveDestroy(allocator);
}
pub export fn strollDestroyImageView(p_device: vk.Device, p_image_view: vk.ImageView, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkDestroyImageView);
defer entryPointEndLogTrace();
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err);
const allocator = VulkanAllocator.init(callbacks, .object).allocator();
const non_dispatchable = NonDispatchable(ImageView).fromHandle(p_image_view) catch |err| return errorLogger(err);
non_dispatchable.intrusiveDestroy(allocator);
}
pub export fn strollFreeCommandBuffers(p_device: vk.Device, p_pool: vk.CommandPool, count: u32, p_cmds: [*]const vk.CommandBuffer) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkFreeCommandBuffers);
defer entryPointEndLogTrace();
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err);
const pool = NonDispatchable(CommandPool).fromHandleObject(p_pool) catch |err| return errorLogger(err);
const cmds: [*]*Dispatchable(CommandBuffer) = @ptrCast(@constCast(p_cmds));
pool.freeCommandBuffers(cmds[0..count]) catch |err| return errorLogger(err);
}
pub export fn strollFreeMemory(p_device: vk.Device, p_memory: vk.DeviceMemory, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkFreeMemory);
defer entryPointEndLogTrace();
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err);
const allocator = VulkanAllocator.init(callbacks, .object).allocator();
const non_dispatchable = NonDispatchable(DeviceMemory).fromHandle(p_memory) catch |err| return errorLogger(err);
non_dispatchable.intrusiveDestroy(allocator);
}
pub export fn strollGetBufferMemoryRequirements(p_device: vk.Device, p_buffer: vk.Buffer, requirements: *vk.MemoryRequirements) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkGetBufferMemoryRequirements);
defer entryPointEndLogTrace();
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err);
const buffer = NonDispatchable(Buffer).fromHandleObject(p_buffer) catch |err| return errorLogger(err);
buffer.getMemoryRequirements(requirements);
}
pub export fn strollGetDeviceProcAddr(p_device: vk.Device, p_name: ?[*:0]const u8) callconv(vk.vulkan_call_conv) vk.PfnVoidFunction {
if (lib.getLogVerboseLevel() == .TooMuch) {
entryPointBeginLogTrace(.vkGetDeviceProcAddr);
}
defer entryPointEndLogTrace();
if (p_name == null) return null;
const name = std.mem.span(p_name.?);
if (p_device == .null_handle) return null;
if (device_pfn_map.get(name)) |pfn| return pfn;
entryPointNotFoundErrorLog(.vkGetDeviceProcAddr, name);
return null;
}
pub export fn strollGetDeviceQueue(p_device: vk.Device, queue_family_index: u32, queue_index: u32, p_queue: *vk.Queue) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkGetDeviceQueue);
defer entryPointEndLogTrace();
p_queue.* = .null_handle;
const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return errorLogger(err);
if (device.queues.get(queue_family_index)) |family| {
if (queue_index >= family.items.len) return;
const dispatchable_queue = family.items[queue_index];
const queue = dispatchable_queue.object;
// https://docs.vulkan.org/refpages/latest/refpages/source/vkGetDeviceQueue.html#VUID-vkGetDeviceQueue-flags-01841
if (queue.flags != @TypeOf(queue.flags){}) return;
p_queue.* = dispatchable_queue.toVkHandle(vk.Queue);
}
}
pub export fn strollGetFenceStatus(p_device: vk.Device, p_fence: vk.Fence) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkGetFenceStatus);
defer entryPointEndLogTrace();
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return toVkResult(err);
const fence = NonDispatchable(Fence).fromHandleObject(p_fence) catch |err| return toVkResult(err);
fence.getStatus() catch |err| return toVkResult(err);
return .success;
}
pub export fn strollGetImageMemoryRequirements(p_device: vk.Device, p_image: vk.Image, requirements: *vk.MemoryRequirements) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkGetImageMemoryRequirements);
defer entryPointEndLogTrace();
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err);
const image = NonDispatchable(Image).fromHandleObject(p_image) catch |err| return errorLogger(err);
image.getMemoryRequirements(requirements);
}
pub export fn strollMapMemory(p_device: vk.Device, p_memory: vk.DeviceMemory, offset: vk.DeviceSize, size: vk.DeviceSize, _: vk.MemoryMapFlags, pp_data: *?*anyopaque) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkMapMemory);
defer entryPointEndLogTrace();
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return toVkResult(err);
const device_memory = NonDispatchable(DeviceMemory).fromHandleObject(p_memory) catch |err| return toVkResult(err);
pp_data.* = device_memory.map(offset, size) catch |err| return toVkResult(err);
return .success;
}
pub export fn strollUnmapMemory(p_device: vk.Device, p_memory: vk.DeviceMemory) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkUnmapMemory);
defer entryPointEndLogTrace();
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err);
const device_memory = NonDispatchable(DeviceMemory).fromHandleObject(p_memory) catch |err| return errorLogger(err);
device_memory.unmap();
}
pub export fn strollResetFences(p_device: vk.Device, count: u32, p_fences: [*]const vk.Fence) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkResetFences);
defer entryPointEndLogTrace();
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return toVkResult(err);
for (p_fences, 0..count) |p_fence, _| {
const fence = NonDispatchable(Fence).fromHandleObject(p_fence) catch |err| return toVkResult(err);
fence.reset() catch |err| return toVkResult(err);
}
return .success;
}
pub export fn strollWaitForFences(p_device: vk.Device, count: u32, p_fences: [*]const vk.Fence, waitForAll: vk.Bool32, timeout: u64) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkWaitForFences);
defer entryPointEndLogTrace();
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return toVkResult(err);
loop: for (p_fences, 0..count) |p_fence, _| {
const fence = NonDispatchable(Fence).fromHandleObject(p_fence) catch |err| return toVkResult(err);
fence.wait(timeout) catch |err| return toVkResult(err);
if (waitForAll == .false) break :loop;
}
return .success;
}
// Command Buffer functions ===================================================================================================================================
pub export fn strollBeginCommandBuffer(p_cmd: vk.CommandBuffer, info: *const vk.CommandBufferBeginInfo) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkBeginCommandBuffer);
defer entryPointEndLogTrace();
if (info.s_type != .command_buffer_begin_info) {
return .error_validation_failed;
}
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return toVkResult(err);
cmd.begin(info) catch |err| return toVkResult(err);
return .success;
}
pub export fn strollCmdBeginQuery(p_cmd: vk.CommandBuffer, p_pool: vk.QueryPool, query: u32, flags: vk.QueryControlFlags) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkCmdBeginQuery);
defer entryPointEndLogTrace();
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
notImplementedWarning();
_ = cmd;
_ = p_pool;
_ = query;
_ = flags;
}
pub export fn strollCmdBeginRenderPass(p_cmd: vk.CommandBuffer, info: *const vk.RenderPassBeginInfo, contents: vk.SubpassContents) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkCmdBeginRenderPass);
defer entryPointEndLogTrace();
if (info.s_type != .render_pass_begin_info) {
return errorLogger(VkError.ValidationFailed);
}
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
notImplementedWarning();
_ = cmd;
_ = contents;
}
pub export fn strollCmdBindDescriptorSets(
p_cmd: vk.CommandBuffer,
bind_point: vk.PipelineBindPoint,
layout: vk.PipelineLayout,
first: u32,
count: u32,
sets: [*]const vk.DescriptorSet,
dynamic_offset_count: u32,
dynamic_offsets: [*]const u32,
) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkCmdBindDescriptorSets);
defer entryPointEndLogTrace();
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
notImplementedWarning();
_ = cmd;
_ = bind_point;
_ = layout;
_ = first;
_ = count;
_ = sets;
_ = dynamic_offsets;
_ = dynamic_offset_count;
}
pub export fn strollCmdBindIndexBuffer(p_cmd: vk.CommandBuffer, p_buffer: vk.Buffer, offset: vk.DeviceSize, index_type: vk.IndexType) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkCmdBindIndexBuffer);
defer entryPointEndLogTrace();
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
const buffer = NonDispatchable(Buffer).fromHandleObject(p_buffer) catch |err| return errorLogger(err);
notImplementedWarning();
_ = cmd;
_ = buffer;
_ = offset;
_ = index_type;
}
pub export fn strollCmdBindPipeline(p_cmd: vk.CommandBuffer, bind_point: vk.PipelineBindPoint, p_pipeline: vk.Pipeline) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkCmdBindPipeline);
defer entryPointEndLogTrace();
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
notImplementedWarning();
_ = cmd;
_ = bind_point;
_ = p_pipeline;
}
pub export fn strollCmdBindVertexBuffers(p_cmd: vk.CommandBuffer, first: u32, count: u32, p_buffers: [*]const vk.Buffer, offsets: [*]const vk.DeviceSize) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkCmdBindVertexBuffer);
defer entryPointEndLogTrace();
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
notImplementedWarning();
_ = cmd;
_ = first;
_ = count;
_ = p_buffers;
_ = offsets;
}
pub export fn strollCmdBlitImage(
p_cmd: vk.CommandBuffer,
p_src_image: vk.Image,
src_layout: vk.ImageLayout,
p_dst_image: vk.Image,
dst_layout: vk.ImageLayout,
count: u32,
regions: [*]const vk.ImageBlit,
filter: vk.Filter,
) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkCmdBlitImage);
defer entryPointEndLogTrace();
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
const src = NonDispatchable(Image).fromHandleObject(p_src_image) catch |err| return errorLogger(err);
const dst = NonDispatchable(Image).fromHandleObject(p_dst_image) catch |err| return errorLogger(err);
notImplementedWarning();
_ = cmd;
_ = src;
_ = src_layout;
_ = dst;
_ = dst_layout;
_ = count;
_ = regions;
_ = filter;
}
pub export fn strollCmdClearAttachments(p_cmd: vk.CommandBuffer, attachment_count: u32, attachments: [*]const vk.ClearAttachment, rect_count: u32, rects: [*]const vk.ClearRect) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkCmdClearAttachments);
defer entryPointEndLogTrace();
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
notImplementedWarning();
_ = cmd;
_ = attachment_count;
_ = attachments;
_ = rect_count;
_ = rects;
}
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);
defer entryPointEndLogTrace();
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
const image = NonDispatchable(Image).fromHandleObject(p_image) catch |err| return errorLogger(err);
cmd.clearColorImage(image, layout, color, ranges[0..count]) catch |err| return errorLogger(err);
}
pub export fn strollCmdClearDepthStencilImage(p_cmd: vk.CommandBuffer, p_image: vk.Image, layout: vk.ImageLayout, stencil: *const vk.ClearDepthStencilValue, count: u32, ranges: [*]const vk.ImageSubresourceRange) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkCmdClearDepthStencilImage);
defer entryPointEndLogTrace();
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
const image = NonDispatchable(Image).fromHandleObject(p_image) catch |err| return errorLogger(err);
notImplementedWarning();
_ = cmd;
_ = image;
_ = layout;
_ = stencil;
_ = count;
_ = ranges;
}
pub export fn strollCmdCopyBuffer(p_cmd: vk.CommandBuffer, p_src: vk.Buffer, p_dst: vk.Buffer, count: u32, regions: [*]const vk.BufferCopy) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkCmdCopyBuffer);
defer entryPointEndLogTrace();
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
const src = NonDispatchable(Buffer).fromHandleObject(p_src) catch |err| return errorLogger(err);
const dst = NonDispatchable(Buffer).fromHandleObject(p_dst) catch |err| return errorLogger(err);
cmd.copyBuffer(src, dst, regions[0..count]) catch |err| return errorLogger(err);
}
pub export fn strollCmdCopyBufferToImage(p_cmd: vk.CommandBuffer, p_src: vk.Buffer, p_dst: vk.Image, layout: vk.ImageLayout, count: u32, regions: [*]const vk.BufferImageCopy) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkCmdCopyBufferToImage);
defer entryPointEndLogTrace();
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
const src = NonDispatchable(Buffer).fromHandleObject(p_src) catch |err| return errorLogger(err);
const dst = NonDispatchable(Image).fromHandleObject(p_dst) catch |err| return errorLogger(err);
notImplementedWarning();
_ = cmd;
_ = src;
_ = dst;
_ = layout;
_ = count;
_ = 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 {
entryPointBeginLogTrace(.vkCmdCopyImage);
defer entryPointEndLogTrace();
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 dst = NonDispatchable(Image).fromHandleObject(p_dst) catch |err| return errorLogger(err);
cmd.copyImage(src, dst, regions[0..count]) catch |err| return errorLogger(err);
}
pub export fn strollCmdFillBuffer(p_cmd: vk.CommandBuffer, p_buffer: vk.Buffer, offset: vk.DeviceSize, size: vk.DeviceSize, data: u32) callconv(vk.vulkan_call_conv) void {
entryPointBeginLogTrace(.vkCmdFillBuffer);
defer entryPointEndLogTrace();
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
const buffer = NonDispatchable(Buffer).fromHandleObject(p_buffer) catch |err| return errorLogger(err);
cmd.fillBuffer(buffer, offset, size, data) catch |err| return errorLogger(err);
}
pub export fn strollEndCommandBuffer(p_cmd: vk.CommandBuffer) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkEndCommandBuffer);
defer entryPointEndLogTrace();
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return toVkResult(err);
cmd.end() catch |err| return toVkResult(err);
return .success;
}
pub export fn strollResetCommandBuffer(p_cmd: vk.CommandBuffer, flags: vk.CommandBufferResetFlags) callconv(vk.vulkan_call_conv) vk.Result {
entryPointBeginLogTrace(.vkResetCommandBuffer);
defer entryPointEndLogTrace();
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return toVkResult(err);
cmd.reset(flags) catch |err| return toVkResult(err);
return .success;
}