adding base Image and ICD file generation
This commit is contained in:
@@ -38,6 +38,7 @@ dispatch_table: *const DispatchTable,
|
||||
|
||||
pub const DispatchTable = struct {
|
||||
begin: *const fn (*Self, *const vk.CommandBufferBeginInfo) VkError!void,
|
||||
copyBuffer: *const fn (*Self, *Buffer, *Buffer, []const vk.BufferCopy) VkError!void,
|
||||
end: *const fn (*Self) VkError!void,
|
||||
fillBuffer: *const fn (*Self, *Buffer, vk.DeviceSize, vk.DeviceSize, u32) VkError!void,
|
||||
reset: *const fn (*Self, vk.CommandBufferResetFlags) VkError!void,
|
||||
@@ -71,6 +72,7 @@ inline fn transitionState(self: *Self, target: State, from_allowed: []const Stat
|
||||
}
|
||||
|
||||
pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void {
|
||||
self.cleanCommandList();
|
||||
self.commands.deinit(allocator);
|
||||
self.vtable.destroy(self, allocator);
|
||||
}
|
||||
@@ -94,6 +96,8 @@ pub inline fn reset(self: *Self, flags: vk.CommandBufferResetFlags) VkError!void
|
||||
if (!self.pool.flags.reset_command_buffer_bit) {
|
||||
return VkError.ValidationFailed;
|
||||
}
|
||||
defer self.cleanCommandList();
|
||||
|
||||
self.transitionState(.Initial, &.{ .Initial, .Recording, .Executable, .Invalid }) catch return VkError.ValidationFailed;
|
||||
try self.dispatch_table.reset(self, flags);
|
||||
}
|
||||
@@ -107,15 +111,19 @@ pub inline fn submit(self: *Self) VkError!void {
|
||||
self.transitionState(.Pending, &.{ .Pending, .Executable }) catch return VkError.ValidationFailed;
|
||||
}
|
||||
|
||||
fn cleanCommandList(self: *Self) void {
|
||||
const allocator = self.host_allocator.allocator();
|
||||
_ = allocator;
|
||||
for (self.commands.items) |command| {
|
||||
switch (command) {
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Commands ====================================================================================================
|
||||
|
||||
pub inline fn fillBuffer(self: *Self, buffer: *Buffer, offset: vk.DeviceSize, size: vk.DeviceSize, data: u32) VkError!void {
|
||||
if (offset >= buffer.size) return VkError.ValidationFailed;
|
||||
if (size != vk.WHOLE_SIZE and (size == 0 or size > offset + buffer.size)) return VkError.ValidationFailed;
|
||||
if ((size != vk.WHOLE_SIZE and @mod(size, 4) != 0) or @mod(offset, 4) != 0) return VkError.ValidationFailed;
|
||||
if (!buffer.usage.transfer_dst_bit) return VkError.ValidationFailed;
|
||||
if (buffer.memory == null) return VkError.ValidationFailed;
|
||||
|
||||
const allocator = self.host_allocator.allocator();
|
||||
self.commands.append(allocator, .{ .FillBuffer = .{
|
||||
.buffer = buffer,
|
||||
@@ -125,3 +133,13 @@ pub inline fn fillBuffer(self: *Self, buffer: *Buffer, offset: vk.DeviceSize, si
|
||||
} }) catch return VkError.OutOfHostMemory;
|
||||
try self.dispatch_table.fillBuffer(self, buffer, offset, size, data);
|
||||
}
|
||||
|
||||
pub inline fn copyBuffer(self: *Self, src: *Buffer, dst: *Buffer, regions: []const vk.BufferCopy) VkError!void {
|
||||
const allocator = self.host_allocator.allocator();
|
||||
self.commands.append(allocator, .{ .CopyBuffer = .{
|
||||
.src = src,
|
||||
.dst = dst,
|
||||
.regions = regions,
|
||||
} }) catch return VkError.OutOfHostMemory;
|
||||
try self.dispatch_table.copyBuffer(self, src, dst, regions);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ 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 Self = @This();
|
||||
pub const ObjectType: vk.ObjectType = .device;
|
||||
@@ -35,6 +36,7 @@ pub const DispatchTable = struct {
|
||||
createBuffer: *const fn (*Self, std.mem.Allocator, *const vk.BufferCreateInfo) VkError!*Buffer,
|
||||
createCommandPool: *const fn (*Self, std.mem.Allocator, *const vk.CommandPoolCreateInfo) VkError!*CommandPool,
|
||||
createFence: *const fn (*Self, std.mem.Allocator, *const vk.FenceCreateInfo) VkError!*Fence,
|
||||
createImage: *const fn (*Self, std.mem.Allocator, *const vk.ImageCreateInfo) VkError!*Image,
|
||||
destroy: *const fn (*Self, std.mem.Allocator) VkError!void,
|
||||
};
|
||||
|
||||
@@ -84,6 +86,10 @@ pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) VkError!void {
|
||||
try self.dispatch_table.destroy(self, allocator);
|
||||
}
|
||||
|
||||
pub inline fn allocateMemory(self: *Self, allocator: std.mem.Allocator, info: *const vk.MemoryAllocateInfo) VkError!*DeviceMemory {
|
||||
return self.dispatch_table.allocateMemory(self, allocator, info);
|
||||
}
|
||||
|
||||
pub inline fn createBuffer(self: *Self, allocator: std.mem.Allocator, info: *const vk.BufferCreateInfo) VkError!*Buffer {
|
||||
return self.dispatch_table.createBuffer(self, allocator, info);
|
||||
}
|
||||
@@ -96,6 +102,6 @@ pub inline fn createCommandPool(self: *Self, allocator: std.mem.Allocator, info:
|
||||
return self.dispatch_table.createCommandPool(self, allocator, info);
|
||||
}
|
||||
|
||||
pub inline fn allocateMemory(self: *Self, allocator: std.mem.Allocator, info: *const vk.MemoryAllocateInfo) VkError!*DeviceMemory {
|
||||
return self.dispatch_table.allocateMemory(self, allocator, info);
|
||||
pub inline fn createImage(self: *Self, allocator: std.mem.Allocator, info: *const vk.ImageCreateInfo) VkError!*Image {
|
||||
return self.dispatch_table.createImage(self, allocator, info);
|
||||
}
|
||||
|
||||
71
src/vulkan/Image.zig
git.filemode.normal_file
71
src/vulkan/Image.zig
git.filemode.normal_file
@@ -0,0 +1,71 @@
|
||||
const std = @import("std");
|
||||
const vk = @import("vulkan");
|
||||
const vku = @cImport({
|
||||
@cInclude("vulkan/utility/vk_format_utils.h");
|
||||
});
|
||||
|
||||
const VkError = @import("error_set.zig").VkError;
|
||||
const DeviceMemory = @import("DeviceMemory.zig");
|
||||
const Device = @import("Device.zig");
|
||||
|
||||
const Self = @This();
|
||||
pub const ObjectType: vk.ObjectType = .image;
|
||||
|
||||
owner: *Device,
|
||||
image_type: vk.ImageType,
|
||||
format: vk.Format,
|
||||
extent: vk.Extent3D,
|
||||
mip_levels: u32,
|
||||
array_layers: u32,
|
||||
samples: vk.SampleCountFlags,
|
||||
tiling: vk.ImageTiling,
|
||||
usage: vk.ImageUsageFlags,
|
||||
memory: ?*DeviceMemory,
|
||||
memory_offset: vk.DeviceSize,
|
||||
allowed_memory_types: std.bit_set.IntegerBitSet(32),
|
||||
|
||||
vtable: *const VTable,
|
||||
|
||||
pub const VTable = struct {
|
||||
destroy: *const fn (*Self, std.mem.Allocator) void,
|
||||
getMemoryRequirements: *const fn (*Self, *vk.MemoryRequirements) void,
|
||||
};
|
||||
|
||||
pub fn init(device: *Device, allocator: std.mem.Allocator, info: *const vk.ImageCreateInfo) VkError!Self {
|
||||
_ = allocator;
|
||||
return .{
|
||||
.owner = device,
|
||||
.image_type = info.image_type,
|
||||
.format = info.format,
|
||||
.extent = info.extent,
|
||||
.mip_levels = info.mip_levels,
|
||||
.array_layers = info.array_layers,
|
||||
.samples = info.samples,
|
||||
.tiling = info.tiling,
|
||||
.usage = info.usage,
|
||||
.memory = null,
|
||||
.memory_offset = 0,
|
||||
.allowed_memory_types = std.bit_set.IntegerBitSet(32).initFull(),
|
||||
.vtable = undefined,
|
||||
};
|
||||
}
|
||||
|
||||
pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void {
|
||||
self.vtable.destroy(self, allocator);
|
||||
}
|
||||
|
||||
pub inline fn bindMemory(self: *Self, memory: *DeviceMemory, offset: vk.DeviceSize) VkError!void {
|
||||
if (offset >= self.size or !self.allowed_memory_types.isSet(memory.memory_type_index)) {
|
||||
return VkError.ValidationFailed;
|
||||
}
|
||||
self.memory = memory;
|
||||
self.offset = offset;
|
||||
}
|
||||
|
||||
pub inline fn getMemoryRequirements(self: *Self, requirements: *vk.MemoryRequirements) void {
|
||||
const pixel_size = vku.vkuFormatTexelBlockSize(@intCast(@intFromEnum(self.format)));
|
||||
|
||||
requirements.size = self.extent.width * self.extent.height * self.extent.depth * pixel_size;
|
||||
requirements.memory_type_bits = self.allowed_memory_types.mask;
|
||||
self.vtable.getMemoryRequirements(self, requirements);
|
||||
}
|
||||
@@ -17,7 +17,7 @@ pub const CommandType = enum {
|
||||
pub const CommandCopyBuffer = struct {
|
||||
src: *Buffer,
|
||||
dst: *Buffer,
|
||||
regions: []*const vk.BufferCopy,
|
||||
regions: []const vk.BufferCopy,
|
||||
};
|
||||
|
||||
pub const CommandFillBuffer = struct {
|
||||
|
||||
@@ -56,6 +56,10 @@ pub inline fn errorLogger(err: VkError) void {
|
||||
std.log.scoped(.errorLogger).err("Error logger catched a '{s}'", .{@errorName(err)});
|
||||
}
|
||||
|
||||
pub inline fn errorLoggerContext(err: VkError, context: []const u8) void {
|
||||
std.log.scoped(.errorLogger).err("Error logger catched a '{s}' in {s}", .{ @errorName(err), context });
|
||||
}
|
||||
|
||||
pub inline fn toVkResult(err: VkError) vk.Result {
|
||||
errorLogger(err);
|
||||
return switch (err) {
|
||||
|
||||
@@ -4,10 +4,11 @@ const vk = @import("vulkan");
|
||||
pub const commands = @import("commands.zig");
|
||||
pub const lib_vulkan = @import("lib_vulkan.zig");
|
||||
pub const logger = @import("logger.zig");
|
||||
pub const errors = @import("error_set.zig");
|
||||
|
||||
pub const Dispatchable = @import("Dispatchable.zig").Dispatchable;
|
||||
pub const NonDispatchable = @import("NonDispatchable.zig").NonDispatchable;
|
||||
pub const VkError = @import("error_set.zig").VkError;
|
||||
pub const VkError = errors.VkError;
|
||||
pub const VulkanAllocator = @import("VulkanAllocator.zig");
|
||||
|
||||
pub const Instance = @import("Instance.zig");
|
||||
@@ -20,6 +21,7 @@ pub const CommandBuffer = @import("CommandBuffer.zig");
|
||||
pub const CommandPool = @import("CommandPool.zig");
|
||||
pub const DeviceMemory = @import("DeviceMemory.zig");
|
||||
pub const Fence = @import("Fence.zig");
|
||||
pub const Image = @import("Image.zig");
|
||||
|
||||
pub const VULKAN_VENDOR_ID = @typeInfo(vk.VendorId).@"enum".fields[@typeInfo(vk.VendorId).@"enum".fields.len - 1].value + 1;
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ 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");
|
||||
|
||||
fn entryPointBeginLogTrace(comptime scope: @Type(.enum_literal)) void {
|
||||
std.log.scoped(scope).debug("Calling {s}...", .{@tagName(scope)});
|
||||
@@ -43,6 +44,7 @@ fn entryPointNotFoundErrorLog(comptime scope: @Type(.enum_literal), name: []cons
|
||||
}
|
||||
|
||||
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))
|
||||
@@ -89,20 +91,24 @@ const device_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{
|
||||
functionMapEntryPoint("vkAllocateMemory"),
|
||||
functionMapEntryPoint("vkBeginCommandBuffer"),
|
||||
functionMapEntryPoint("vkBindBufferMemory"),
|
||||
functionMapEntryPoint("vkCmdCopyBuffer"),
|
||||
functionMapEntryPoint("vkCmdFillBuffer"),
|
||||
functionMapEntryPoint("vkCreateCommandPool"),
|
||||
functionMapEntryPoint("vkCreateBuffer"),
|
||||
functionMapEntryPoint("vkCreateFence"),
|
||||
functionMapEntryPoint("vkCreateImage"),
|
||||
functionMapEntryPoint("vkDestroyBuffer"),
|
||||
functionMapEntryPoint("vkDestroyCommandPool"),
|
||||
functionMapEntryPoint("vkDestroyFence"),
|
||||
functionMapEntryPoint("vkDestroyDevice"),
|
||||
functionMapEntryPoint("vkDestroyFence"),
|
||||
functionMapEntryPoint("vkDestroyImage"),
|
||||
functionMapEntryPoint("vkEndCommandBuffer"),
|
||||
functionMapEntryPoint("vkFreeCommandBuffers"),
|
||||
functionMapEntryPoint("vkFreeMemory"),
|
||||
functionMapEntryPoint("vkGetBufferMemoryRequirements"),
|
||||
functionMapEntryPoint("vkGetDeviceQueue"),
|
||||
functionMapEntryPoint("vkGetFenceStatus"),
|
||||
functionMapEntryPoint("vkGetBufferMemoryRequirements"),
|
||||
functionMapEntryPoint("vkGetImageMemoryRequirements"),
|
||||
functionMapEntryPoint("vkMapMemory"),
|
||||
functionMapEntryPoint("vkUnmapMemory"),
|
||||
functionMapEntryPoint("vkResetCommandBuffer"),
|
||||
@@ -302,7 +308,15 @@ pub export fn strollGetPhysicalDeviceFeatures(p_physical_device: vk.PhysicalDevi
|
||||
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 {
|
||||
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();
|
||||
|
||||
@@ -491,6 +505,21 @@ pub export fn strollCreateFence(p_device: vk.Device, p_info: ?*const vk.FenceCre
|
||||
return .success;
|
||||
}
|
||||
|
||||
pub export fn strollCreateImage(p_device: vk.Device, p_info: ?*const vk.ImageCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_image: *vk.Image) callconv(vk.vulkan_call_conv) vk.Result {
|
||||
entryPointBeginLogTrace(.vkCreateImage);
|
||||
defer entryPointEndLogTrace();
|
||||
|
||||
const info = p_info orelse return .error_validation_failed;
|
||||
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 strollDestroyBuffer(p_device: vk.Device, p_buffer: vk.Buffer, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void {
|
||||
entryPointBeginLogTrace(.vkDestroyBuffer);
|
||||
defer entryPointEndLogTrace();
|
||||
@@ -537,6 +566,17 @@ pub export fn strollDestroyFence(p_device: vk.Device, p_fence: vk.Fence, callbac
|
||||
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 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();
|
||||
@@ -559,6 +599,16 @@ pub export fn strollFreeMemory(p_device: vk.Device, p_memory: vk.DeviceMemory, c
|
||||
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);
|
||||
@@ -605,14 +655,14 @@ pub export fn strollGetFenceStatus(p_device: vk.Device, p_fence: vk.Fence) callc
|
||||
return .success;
|
||||
}
|
||||
|
||||
pub export fn strollGetBufferMemoryRequirements(p_device: vk.Device, p_buffer: vk.Buffer, requirements: *vk.MemoryRequirements) callconv(vk.vulkan_call_conv) void {
|
||||
entryPointBeginLogTrace(.vkGetBufferMemoryRequirements);
|
||||
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 buffer = NonDispatchable(Buffer).fromHandleObject(p_buffer) catch |err| return errorLogger(err);
|
||||
buffer.getMemoryRequirements(requirements);
|
||||
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 {
|
||||
@@ -678,6 +728,16 @@ pub export fn strollBeginCommandBuffer(p_cmd: vk.CommandBuffer, p_info: ?*const
|
||||
return .success;
|
||||
}
|
||||
|
||||
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 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();
|
||||
|
||||
Reference in New Issue
Block a user