diff --git a/src/soft/Executor.zig b/src/soft/Executor.zig index a1642b9..40c948a 100644 --- a/src/soft/Executor.zig +++ b/src/soft/Executor.zig @@ -39,6 +39,8 @@ fn clearColorImage(data: *const cmd.CommandClearColorImage) VkError!void { _ = range; _ = &memory_map; + std.log.scoped(.commandExecutor).warn("FIXME: implement image clear", .{}); + memory.unmap(); } } @@ -60,6 +62,7 @@ fn copyBuffer(data: *const cmd.CommandCopyBuffer) VkError!void { fn copyImage(data: *const cmd.CommandCopyImage) VkError!void { _ = data; + std.log.scoped(.commandExecutor).warn("FIXME: implement image to image copy", .{}); } fn fillBuffer(data: *const cmd.CommandFillBuffer) VkError!void { diff --git a/src/soft/SoftDevice.zig b/src/soft/SoftDevice.zig index 8622c22..ddf0f87 100644 --- a/src/soft/SoftDevice.zig +++ b/src/soft/SoftDevice.zig @@ -12,6 +12,7 @@ const SoftBuffer = @import("SoftBuffer.zig"); const SoftDeviceMemory = @import("SoftDeviceMemory.zig"); const SoftFence = @import("SoftFence.zig"); const SoftImage = @import("SoftImage.zig"); +const SoftImageView = @import("SoftImageView.zig"); const VkError = base.VkError; @@ -41,6 +42,7 @@ pub fn create(physical_device: *base.PhysicalDevice, allocator: std.mem.Allocato .createCommandPool = createCommandPool, .createFence = createFence, .createImage = createImage, + .createImageView = createImageView, .destroy = destroy, }; @@ -98,3 +100,8 @@ pub fn createImage(interface: *Interface, allocator: std.mem.Allocator, info: *c const image = try SoftImage.create(interface, allocator, info); return &image.interface; } + +pub fn createImageView(interface: *Interface, allocator: std.mem.Allocator, info: *const vk.ImageViewCreateInfo) VkError!*base.ImageView { + const image_view = try SoftImageView.create(interface, allocator, info); + return &image_view.interface; +} diff --git a/src/soft/SoftImageView.zig b/src/soft/SoftImageView.zig new file mode 100644 index 0000000..fe175b6 --- /dev/null +++ b/src/soft/SoftImageView.zig @@ -0,0 +1,34 @@ +const std = @import("std"); +const vk = @import("vulkan"); +const base = @import("base"); + +const lib = @import("lib.zig"); + +const VkError = base.VkError; +const Device = base.Device; + +const Self = @This(); +pub const Interface = base.ImageView; + +interface: Interface, + +pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const vk.ImageViewCreateInfo) VkError!*Self { + const self = allocator.create(Self) catch return VkError.OutOfHostMemory; + errdefer allocator.destroy(self); + + var interface = try Interface.init(device, allocator, info); + + interface.vtable = &.{ + .destroy = destroy, + }; + + self.* = .{ + .interface = interface, + }; + return self; +} + +pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void { + const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); + allocator.destroy(self); +} diff --git a/src/soft/lib.zig b/src/soft/lib.zig index 801f945..fd358cb 100644 --- a/src/soft/lib.zig +++ b/src/soft/lib.zig @@ -15,6 +15,7 @@ pub const SoftCommandPool = @import("SoftCommandPool.zig"); pub const SoftDeviceMemory = @import("SoftDeviceMemory.zig"); pub const SoftFence = @import("SoftFence.zig"); pub const SoftImage = @import("SoftImage.zig"); +pub const SoftImageView = @import("SoftImageView.zig"); pub const Instance = SoftInstance; diff --git a/src/vulkan/Device.zig b/src/vulkan/Device.zig index 5f0d511..1868059 100644 --- a/src/vulkan/Device.zig +++ b/src/vulkan/Device.zig @@ -15,6 +15,7 @@ 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"); const Self = @This(); pub const ObjectType: vk.ObjectType = .device; @@ -37,6 +38,7 @@ pub const DispatchTable = struct { 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, + createImageView: *const fn (*Self, std.mem.Allocator, *const vk.ImageViewCreateInfo) VkError!*ImageView, destroy: *const fn (*Self, std.mem.Allocator) VkError!void, }; @@ -105,3 +107,7 @@ pub inline fn createCommandPool(self: *Self, allocator: std.mem.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); } + +pub inline fn createImageView(self: *Self, allocator: std.mem.Allocator, info: *const vk.ImageViewCreateInfo) VkError!*ImageView { + return self.dispatch_table.createImageView(self, allocator, info); +} diff --git a/src/vulkan/Image.zig b/src/vulkan/Image.zig index 44ada1d..90a3a53 100644 --- a/src/vulkan/Image.zig +++ b/src/vulkan/Image.zig @@ -3,9 +3,11 @@ const vk = @import("vulkan"); const lib = @import("lib.zig"); const VkError = @import("error_set.zig").VkError; -const DeviceMemory = @import("DeviceMemory.zig"); + const Device = @import("Device.zig"); +const DeviceMemory = @import("DeviceMemory.zig"); + const Self = @This(); pub const ObjectType: vk.ObjectType = .image; diff --git a/src/vulkan/ImageView.zig b/src/vulkan/ImageView.zig new file mode 100644 index 0000000..a82d8d8 --- /dev/null +++ b/src/vulkan/ImageView.zig @@ -0,0 +1,44 @@ +const std = @import("std"); +const vk = @import("vulkan"); +const lib = @import("lib.zig"); + +const VkError = @import("error_set.zig").VkError; +const NonDispatchable = @import("NonDispatchable.zig").NonDispatchable; + +const Device = @import("Device.zig"); + +const DeviceMemory = @import("DeviceMemory.zig"); +const Image = @import("Image.zig"); + +const Self = @This(); +pub const ObjectType: vk.ObjectType = .image; + +owner: *Device, +image: *Image, +view_type: vk.ImageViewType, +format: vk.Format, +components: vk.ComponentMapping, +subresource_range: vk.ImageSubresourceRange, + +vtable: *const VTable, + +pub const VTable = struct { + destroy: *const fn (*Self, std.mem.Allocator) void, +}; + +pub fn init(device: *Device, allocator: std.mem.Allocator, info: *const vk.ImageViewCreateInfo) VkError!Self { + _ = allocator; + return .{ + .owner = device, + .image = try NonDispatchable(Image).fromHandleObject(info.image), + .view_type = info.view_type, + .format = info.format, + .components = info.components, + .subresource_range = info.subresource_range, + .vtable = undefined, + }; +} + +pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void { + self.vtable.destroy(self, allocator); +} diff --git a/src/vulkan/lib.zig b/src/vulkan/lib.zig index 862a7e2..3232d89 100644 --- a/src/vulkan/lib.zig +++ b/src/vulkan/lib.zig @@ -27,6 +27,7 @@ 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 ImageView = @import("ImageView.zig"); pub const VULKAN_VENDOR_ID = @typeInfo(vk.VendorId).@"enum".fields[@typeInfo(vk.VendorId).@"enum".fields.len - 1].value + 1; diff --git a/src/vulkan/lib_vulkan.zig b/src/vulkan/lib_vulkan.zig index 6a9247d..bd08643 100644 --- a/src/vulkan/lib_vulkan.zig +++ b/src/vulkan/lib_vulkan.zig @@ -28,6 +28,7 @@ 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)}); @@ -100,11 +101,13 @@ const device_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{ functionMapEntryPoint("vkCreateBuffer"), functionMapEntryPoint("vkCreateFence"), functionMapEntryPoint("vkCreateImage"), + functionMapEntryPoint("vkCreateImageView"), functionMapEntryPoint("vkDestroyBuffer"), functionMapEntryPoint("vkDestroyCommandPool"), functionMapEntryPoint("vkDestroyDevice"), functionMapEntryPoint("vkDestroyFence"), functionMapEntryPoint("vkDestroyImage"), + functionMapEntryPoint("vkDestroyImageView"), functionMapEntryPoint("vkEndCommandBuffer"), functionMapEntryPoint("vkFreeCommandBuffers"), functionMapEntryPoint("vkFreeMemory"), @@ -538,6 +541,21 @@ pub export fn strollCreateImage(p_device: vk.Device, p_info: ?*const vk.ImageCre return .success; } +pub export fn strollCreateImageView(p_device: vk.Device, p_info: ?*const vk.ImageViewCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_image_view: *vk.ImageView) callconv(vk.vulkan_call_conv) vk.Result { + entryPointBeginLogTrace(.vkCreateImageView); + defer entryPointEndLogTrace(); + + const info = p_info orelse return .error_validation_failed; + 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(); @@ -595,6 +613,17 @@ pub export fn strollDestroyImage(p_device: vk.Device, p_image: vk.Image, callbac 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(); diff --git a/src/vulkan/logger.zig b/src/vulkan/logger.zig index 7f0c55e..1816d2b 100644 --- a/src/vulkan/logger.zig +++ b/src/vulkan/logger.zig @@ -63,11 +63,11 @@ pub fn log(comptime level: std.log.Level, comptime scope: @Type(.enum_literal), std.fmt.comptimePrint("({s}): ", .{scope_name}); }; - const prefix = std.fmt.comptimePrint("{s: <8}", .{"[" ++ comptime level.asText() ++ "] "}); + const prefix = std.fmt.comptimePrint("{s: <10}", .{"[" ++ comptime level.asText() ++ "] "}); const level_color: std.Io.tty.Color = switch (level) { .info, .debug => .blue, - .warn => .yellow, + .warn => .magenta, .err => .red, }; @@ -104,7 +104,11 @@ pub fn log(comptime level: std.log.Level, comptime scope: @Type(.enum_literal), out_config.setColor(&writer, level_color) catch {}; writer.print(prefix, .{}) catch {}; - out_config.setColor(&writer, if (level == .err) .red else .green) catch {}; + out_config.setColor(&writer, switch (level) { + .err => .red, + .warn => .magenta, + else => .green, + }) catch {}; writer.print("{s: >30}", .{scope_prefix}) catch {}; out_config.setColor(&writer, .reset) catch {}; diff --git a/test/c/main.c b/test/c/main.c index fc17a8c..1dc33b7 100644 --- a/test/c/main.c +++ b/test/c/main.c @@ -85,6 +85,8 @@ int main(void) VkDeviceMemory memory; CreateAndBindMemoryToImage(physical_device, device, image, &memory, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + VkImageView image_view = kvfCreateImageView(device, image, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, 1); + VkQueue queue = kvfGetDeviceQueue(device, KVF_GRAPHICS_QUEUE); VkFence fence = kvfCreateFence(device); VkCommandBuffer cmd = kvfCreateCommandBuffer(device); @@ -93,16 +95,6 @@ int main(void) kvfBeginCommandBuffer(cmd, 0); { - VkClearColorValue color = {0}; - color.uint32[0] = 0xFF; - color.uint32[1] = 0x00; - color.uint32[2] = 0x00; - color.uint32[3] = 0xFF; - VkImageSubresourceRange range = {0}; - range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - range.levelCount = 1; - range.layerCount = 1; - vkCmdClearColorImage(cmd, image, VK_IMAGE_LAYOUT_GENERAL, &color, 1, &range); } kvfEndCommandBuffer(cmd); @@ -117,6 +109,7 @@ int main(void) kvfDestroyFence(device, fence); + kvfDestroyImageView(device, image_view); kvfDestroyImage(device, image); vkFreeMemory(device, memory, NULL);