diff --git a/src/soft/SoftBinarySemaphore.zig b/src/soft/SoftBinarySemaphore.zig new file mode 100644 index 0000000..880d694 --- /dev/null +++ b/src/soft/SoftBinarySemaphore.zig @@ -0,0 +1,32 @@ +const std = @import("std"); +const vk = @import("vulkan"); +const base = @import("base"); + +const VkError = base.VkError; +const Device = base.Device; + +const Self = @This(); +pub const Interface = base.BinarySemaphore; + +interface: Interface, + +pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const vk.SemaphoreCreateInfo) 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/SoftBufferView.zig b/src/soft/SoftBufferView.zig new file mode 100644 index 0000000..046a07a --- /dev/null +++ b/src/soft/SoftBufferView.zig @@ -0,0 +1,32 @@ +const std = @import("std"); +const vk = @import("vulkan"); +const base = @import("base"); + +const VkError = base.VkError; +const Device = base.Device; + +const Self = @This(); +pub const Interface = base.BufferView; + +interface: Interface, + +pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const vk.BufferViewCreateInfo) 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/SoftDevice.zig b/src/soft/SoftDevice.zig index a719aeb..f69d545 100644 --- a/src/soft/SoftDevice.zig +++ b/src/soft/SoftDevice.zig @@ -5,16 +5,28 @@ const builtin = @import("builtin"); const Debug = std.builtin.OptimizeMode.Debug; -const SoftCommandPool = @import("SoftCommandPool.zig"); const SoftQueue = @import("SoftQueue.zig"); -const SoftBuffer = @import("SoftBuffer.zig"); -const SoftDeviceMemory = @import("SoftDeviceMemory.zig"); -const SoftDescriptorPool = @import("SoftDescriptorPool.zig"); -const SoftDescriptorSetLayout = @import("SoftDescriptorSetLayout.zig"); -const SoftFence = @import("SoftFence.zig"); -const SoftImage = @import("SoftImage.zig"); -const SoftImageView = @import("SoftImageView.zig"); +pub const SoftBinarySemaphore = @import("SoftBinarySemaphore.zig"); +pub const SoftBuffer = @import("SoftBuffer.zig"); +pub const SoftBufferView = @import("SoftBufferView.zig"); +pub const SoftCommandBuffer = @import("SoftCommandBuffer.zig"); +pub const SoftCommandPool = @import("SoftCommandPool.zig"); +pub const SoftDescriptorPool = @import("SoftDescriptorPool.zig"); +pub const SoftDescriptorSetLayout = @import("SoftDescriptorSetLayout.zig"); +pub const SoftDeviceMemory = @import("SoftDeviceMemory.zig"); +pub const SoftEvent = @import("SoftEvent.zig"); +pub const SoftFence = @import("SoftFence.zig"); +pub const SoftFramebuffer = @import("SoftFramebuffer.zig"); +pub const SoftImage = @import("SoftImage.zig"); +pub const SoftImageView = @import("SoftImageView.zig"); +pub const SoftPipeline = @import("SoftPipeline.zig"); +pub const SoftPipelineCache = @import("SoftPipelineCache.zig"); +pub const SoftPipelineLayout = @import("SoftPipelineLayout.zig"); +pub const SoftQueryPool = @import("SoftQueryPool.zig"); +pub const SoftRenderPass = @import("SoftRenderPass.zig"); +pub const SoftSampler = @import("SoftSampler.zig"); +pub const SoftShaderModule = @import("SoftShaderModule.zig"); const VkError = base.VkError; @@ -41,12 +53,24 @@ pub fn create(physical_device: *base.PhysicalDevice, allocator: std.mem.Allocato interface.dispatch_table = &.{ .allocateMemory = allocateMemory, .createBuffer = createBuffer, + .createBufferView = createBufferView, .createCommandPool = createCommandPool, + .createComputePipeline = createComputePipeline, .createDescriptorPool = createDescriptorPool, .createDescriptorSetLayout = createDescriptorSetLayout, + .createEvent = createEvent, .createFence = createFence, + .createFramebuffer = createFramebuffer, + .createGraphicsPipeline = createGraphicsPipeline, .createImage = createImage, .createImageView = createImageView, + .createPipelineCache = createPipelineCache, + .createPipelineLayout = createPipelineLayout, + .createQueryPool = createQueryPool, + .createRenderPass = createRenderPass, + .createSampler = createSampler, + .createSemaphore = createSemaphore, + .createShaderModule = createShaderModule, .destroy = destroy, }; @@ -116,6 +140,66 @@ pub fn createImage(interface: *Interface, allocator: std.mem.Allocator, info: *c } 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; + const view = try SoftImageView.create(interface, allocator, info); + return &view.interface; +} + +pub fn createBufferView(interface: *Interface, allocator: std.mem.Allocator, info: *const vk.BufferViewCreateInfo) VkError!*base.BufferView { + const view = try SoftBufferView.create(interface, allocator, info); + return &view.interface; +} + +pub fn createComputePipeline(interface: *Interface, allocator: std.mem.Allocator, cache: ?*base.PipelineCache, info: *const vk.ComputePipelineCreateInfo) VkError!*base.Pipeline { + const pipeline = try SoftPipeline.createCompute(interface, allocator, cache, info); + return &pipeline.interface; +} + +pub fn createEvent(interface: *Interface, allocator: std.mem.Allocator, info: *const vk.EventCreateInfo) VkError!*base.Event { + const event = try SoftEvent.create(interface, allocator, info); + return &event.interface; +} + +pub fn createFramebuffer(interface: *Interface, allocator: std.mem.Allocator, info: *const vk.FramebufferCreateInfo) VkError!*base.Framebuffer { + const framebuffer = try SoftFramebuffer.create(interface, allocator, info); + return &framebuffer.interface; +} + +pub fn createGraphicsPipeline(interface: *Interface, allocator: std.mem.Allocator, cache: ?*base.PipelineCache, info: *const vk.GraphicsPipelineCreateInfo) VkError!*base.Pipeline { + const pipeline = try SoftPipeline.createGraphics(interface, allocator, cache, info); + return &pipeline.interface; +} + +pub fn createPipelineCache(interface: *Interface, allocator: std.mem.Allocator, info: *const vk.PipelineCacheCreateInfo) VkError!*base.PipelineCache { + const cache = try SoftPipelineCache.create(interface, allocator, info); + return &cache.interface; +} + +pub fn createPipelineLayout(interface: *Interface, allocator: std.mem.Allocator, info: *const vk.PipelineLayoutCreateInfo) VkError!*base.PipelineLayout { + const layout = try SoftPipelineLayout.create(interface, allocator, info); + return &layout.interface; +} + +pub fn createQueryPool(interface: *Interface, allocator: std.mem.Allocator, info: *const vk.QueryPoolCreateInfo) VkError!*base.QueryPool { + const pool = try SoftQueryPool.create(interface, allocator, info); + return &pool.interface; +} + +pub fn createRenderPass(interface: *Interface, allocator: std.mem.Allocator, info: *const vk.RenderPassCreateInfo) VkError!*base.RenderPass { + const pass = try SoftRenderPass.create(interface, allocator, info); + return &pass.interface; +} + +pub fn createSampler(interface: *Interface, allocator: std.mem.Allocator, info: *const vk.SamplerCreateInfo) VkError!*base.Sampler { + const sampler = try SoftSampler.create(interface, allocator, info); + return &sampler.interface; +} + +pub fn createSemaphore(interface: *Interface, allocator: std.mem.Allocator, info: *const vk.SemaphoreCreateInfo) VkError!*base.BinarySemaphore { + const semaphore = try SoftBinarySemaphore.create(interface, allocator, info); + return &semaphore.interface; +} + +pub fn createShaderModule(interface: *Interface, allocator: std.mem.Allocator, info: *const vk.ShaderModuleCreateInfo) VkError!*base.ShaderModule { + const module = try SoftShaderModule.create(interface, allocator, info); + return &module.interface; } diff --git a/src/soft/SoftEvent.zig b/src/soft/SoftEvent.zig new file mode 100644 index 0000000..8eec713 --- /dev/null +++ b/src/soft/SoftEvent.zig @@ -0,0 +1,32 @@ +const std = @import("std"); +const vk = @import("vulkan"); +const base = @import("base"); + +const VkError = base.VkError; +const Device = base.Device; + +const Self = @This(); +pub const Interface = base.Event; + +interface: Interface, + +pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const vk.EventCreateInfo) 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/SoftFramebuffer.zig b/src/soft/SoftFramebuffer.zig new file mode 100644 index 0000000..3129654 --- /dev/null +++ b/src/soft/SoftFramebuffer.zig @@ -0,0 +1,32 @@ +const std = @import("std"); +const vk = @import("vulkan"); +const base = @import("base"); + +const VkError = base.VkError; +const Device = base.Device; + +const Self = @This(); +pub const Interface = base.Framebuffer; + +interface: Interface, + +pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const vk.FramebufferCreateInfo) 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/SoftPipeline.zig b/src/soft/SoftPipeline.zig new file mode 100644 index 0000000..1acfb96 --- /dev/null +++ b/src/soft/SoftPipeline.zig @@ -0,0 +1,48 @@ +const std = @import("std"); +const vk = @import("vulkan"); +const base = @import("base"); + +const VkError = base.VkError; +const Device = base.Device; + +const Self = @This(); +pub const Interface = base.Pipeline; + +interface: Interface, + +pub fn createCompute(device: *base.Device, allocator: std.mem.Allocator, cache: ?*base.PipelineCache, info: *const vk.ComputePipelineCreateInfo) VkError!*Self { + const self = allocator.create(Self) catch return VkError.OutOfHostMemory; + errdefer allocator.destroy(self); + + var interface = try Interface.initCompute(device, allocator, cache, info); + + interface.vtable = &.{ + .destroy = destroy, + }; + + self.* = .{ + .interface = interface, + }; + return self; +} + +pub fn createGraphics(device: *base.Device, allocator: std.mem.Allocator, cache: ?*base.PipelineCache, info: *const vk.GraphicsPipelineCreateInfo) VkError!*Self { + const self = allocator.create(Self) catch return VkError.OutOfHostMemory; + errdefer allocator.destroy(self); + + var interface = try Interface.initGraphics(device, allocator, cache, 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/SoftPipelineCache.zig b/src/soft/SoftPipelineCache.zig new file mode 100644 index 0000000..927872e --- /dev/null +++ b/src/soft/SoftPipelineCache.zig @@ -0,0 +1,32 @@ +const std = @import("std"); +const vk = @import("vulkan"); +const base = @import("base"); + +const VkError = base.VkError; +const Device = base.Device; + +const Self = @This(); +pub const Interface = base.PipelineCache; + +interface: Interface, + +pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const vk.PipelineCacheCreateInfo) 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/SoftPipelineLayout.zig b/src/soft/SoftPipelineLayout.zig new file mode 100644 index 0000000..3f0bfc7 --- /dev/null +++ b/src/soft/SoftPipelineLayout.zig @@ -0,0 +1,32 @@ +const std = @import("std"); +const vk = @import("vulkan"); +const base = @import("base"); + +const VkError = base.VkError; +const Device = base.Device; + +const Self = @This(); +pub const Interface = base.PipelineLayout; + +interface: Interface, + +pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const vk.PipelineLayoutCreateInfo) 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/SoftQueryPool.zig b/src/soft/SoftQueryPool.zig new file mode 100644 index 0000000..2fe0d41 --- /dev/null +++ b/src/soft/SoftQueryPool.zig @@ -0,0 +1,32 @@ +const std = @import("std"); +const vk = @import("vulkan"); +const base = @import("base"); + +const VkError = base.VkError; +const Device = base.Device; + +const Self = @This(); +pub const Interface = base.QueryPool; + +interface: Interface, + +pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const vk.QueryPoolCreateInfo) 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/SoftQueue.zig b/src/soft/SoftQueue.zig index 195edc3..0240cda 100644 --- a/src/soft/SoftQueue.zig +++ b/src/soft/SoftQueue.zig @@ -73,7 +73,8 @@ pub fn submit(interface: *Interface, infos: []Interface.SubmitInfo, p_fence: ?*b pub fn waitIdle(interface: *Interface) VkError!void { const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); - self.wait_group.wait(); + if (!self.wait_group.isDone()) + self.wait_group.wait(); } fn taskRunner(self: *Self, info: Interface.SubmitInfo, p_fence: ?*base.Fence) void { diff --git a/src/soft/SoftRenderPass.zig b/src/soft/SoftRenderPass.zig new file mode 100644 index 0000000..cab27b3 --- /dev/null +++ b/src/soft/SoftRenderPass.zig @@ -0,0 +1,32 @@ +const std = @import("std"); +const vk = @import("vulkan"); +const base = @import("base"); + +const VkError = base.VkError; +const Device = base.Device; + +const Self = @This(); +pub const Interface = base.RenderPass; + +interface: Interface, + +pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const vk.RenderPassCreateInfo) 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/SoftSampler.zig b/src/soft/SoftSampler.zig new file mode 100644 index 0000000..a9c85df --- /dev/null +++ b/src/soft/SoftSampler.zig @@ -0,0 +1,32 @@ +const std = @import("std"); +const vk = @import("vulkan"); +const base = @import("base"); + +const VkError = base.VkError; +const Device = base.Device; + +const Self = @This(); +pub const Interface = base.Sampler; + +interface: Interface, + +pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const vk.SamplerCreateInfo) 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/SoftShaderModule.zig b/src/soft/SoftShaderModule.zig new file mode 100644 index 0000000..3dadf3d --- /dev/null +++ b/src/soft/SoftShaderModule.zig @@ -0,0 +1,32 @@ +const std = @import("std"); +const vk = @import("vulkan"); +const base = @import("base"); + +const VkError = base.VkError; +const Device = base.Device; + +const Self = @This(); +pub const Interface = base.ShaderModule; + +interface: Interface, + +pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const vk.ShaderModuleCreateInfo) 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 58095de..e5734fb 100644 --- a/src/soft/lib.zig +++ b/src/soft/lib.zig @@ -9,15 +9,26 @@ pub const SoftDevice = @import("SoftDevice.zig"); pub const SoftPhysicalDevice = @import("SoftPhysicalDevice.zig"); pub const SoftQueue = @import("SoftQueue.zig"); +pub const SoftBinarySemaphore = @import("SoftBinarySemaphore.zig"); pub const SoftBuffer = @import("SoftBuffer.zig"); +pub const SoftBufferView = @import("SoftBufferView.zig"); pub const SoftCommandBuffer = @import("SoftCommandBuffer.zig"); pub const SoftCommandPool = @import("SoftCommandPool.zig"); -pub const SoftDeviceMemory = @import("SoftDeviceMemory.zig"); pub const SoftDescriptorPool = @import("SoftDescriptorPool.zig"); pub const SoftDescriptorSetLayout = @import("SoftDescriptorSetLayout.zig"); +pub const SoftDeviceMemory = @import("SoftDeviceMemory.zig"); +pub const SoftEvent = @import("SoftEvent.zig"); pub const SoftFence = @import("SoftFence.zig"); +pub const SoftFramebuffer = @import("SoftFramebuffer.zig"); pub const SoftImage = @import("SoftImage.zig"); pub const SoftImageView = @import("SoftImageView.zig"); +pub const SoftPipeline = @import("SoftPipeline.zig"); +pub const SoftPipelineCache = @import("SoftPipelineCache.zig"); +pub const SoftPipelineLayout = @import("SoftPipelineLayout.zig"); +pub const SoftQueryPool = @import("SoftQueryPool.zig"); +pub const SoftRenderPass = @import("SoftRenderPass.zig"); +pub const SoftSampler = @import("SoftSampler.zig"); +pub const SoftShaderModule = @import("SoftShaderModule.zig"); pub const Instance = SoftInstance; @@ -50,17 +61,30 @@ comptime { } test { - std.testing.refAllDecls(base); - std.testing.refAllDecls(SoftInstance); - std.testing.refAllDecls(SoftDevice); - std.testing.refAllDecls(SoftPhysicalDevice); - std.testing.refAllDecls(SoftQueue); + std.testing.refAllDecls(Executor); + std.testing.refAllDecls(SoftBinarySemaphore); std.testing.refAllDecls(SoftBuffer); + std.testing.refAllDecls(SoftBufferView); std.testing.refAllDecls(SoftCommandBuffer); std.testing.refAllDecls(SoftCommandPool); + std.testing.refAllDecls(SoftDescriptorPool); + std.testing.refAllDecls(SoftDescriptorSetLayout); + std.testing.refAllDecls(SoftDevice); std.testing.refAllDecls(SoftDeviceMemory); + std.testing.refAllDecls(SoftEvent); std.testing.refAllDecls(SoftFence); + std.testing.refAllDecls(SoftFramebuffer); std.testing.refAllDecls(SoftImage); std.testing.refAllDecls(SoftImageView); - std.testing.refAllDecls(Executor); + std.testing.refAllDecls(SoftInstance); + std.testing.refAllDecls(SoftPhysicalDevice); + std.testing.refAllDecls(SoftPipeline); + std.testing.refAllDecls(SoftPipelineCache); + std.testing.refAllDecls(SoftPipelineLayout); + std.testing.refAllDecls(SoftQueryPool); + std.testing.refAllDecls(SoftQueue); + std.testing.refAllDecls(SoftRenderPass); + std.testing.refAllDecls(SoftSampler); + std.testing.refAllDecls(SoftShaderModule); + std.testing.refAllDecls(base); } diff --git a/src/vulkan/BinarySemaphore.zig b/src/vulkan/BinarySemaphore.zig new file mode 100644 index 0000000..4a913bc --- /dev/null +++ b/src/vulkan/BinarySemaphore.zig @@ -0,0 +1,32 @@ +const std = @import("std"); +const vk = @import("vulkan"); + +const NonDispatchable = @import("NonDispatchable.zig"); + +const VkError = @import("error_set.zig").VkError; + +const Device = @import("Device.zig"); + +const Self = @This(); +pub const ObjectType: vk.ObjectType = .semaphore; + +owner: *Device, + +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.SemaphoreCreateInfo) VkError!Self { + _ = allocator; + _ = info; + return .{ + .owner = device, + .vtable = undefined, + }; +} + +pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void { + self.vtable.destroy(self, allocator); +} diff --git a/src/vulkan/BufferView.zig b/src/vulkan/BufferView.zig new file mode 100644 index 0000000..9b2ccb7 --- /dev/null +++ b/src/vulkan/BufferView.zig @@ -0,0 +1,32 @@ +const std = @import("std"); +const vk = @import("vulkan"); + +const NonDispatchable = @import("NonDispatchable.zig"); + +const VkError = @import("error_set.zig").VkError; + +const Device = @import("Device.zig"); + +const Self = @This(); +pub const ObjectType: vk.ObjectType = .buffer_view; + +owner: *Device, + +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.BufferViewCreateInfo) VkError!Self { + _ = allocator; + _ = info; + return .{ + .owner = device, + .vtable = undefined, + }; +} + +pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void { + self.vtable.destroy(self, allocator); +} diff --git a/src/vulkan/Device.zig b/src/vulkan/Device.zig index 5d8db6a..8edb661 100644 --- a/src/vulkan/Device.zig +++ b/src/vulkan/Device.zig @@ -9,16 +9,26 @@ const VkError = @import("error_set.zig").VkError; const PhysicalDevice = @import("PhysicalDevice.zig"); const Queue = @import("Queue.zig"); +const BinarySemaphore = @import("BinarySemaphore.zig"); const Buffer = @import("Buffer.zig"); -const CommandBuffer = @import("CommandBuffer.zig"); +const BufferView = @import("BufferView.zig"); const CommandPool = @import("CommandPool.zig"); -const DeviceMemory = @import("DeviceMemory.zig"); const DescriptorPool = @import("DescriptorPool.zig"); const DescriptorSet = @import("DescriptorSet.zig"); const DescriptorSetLayout = @import("DescriptorSetLayout.zig"); +const DeviceMemory = @import("DeviceMemory.zig"); +const Event = @import("Event.zig"); const Fence = @import("Fence.zig"); +const Framebuffer = @import("Framebuffer.zig"); const Image = @import("Image.zig"); const ImageView = @import("ImageView.zig"); +const Pipeline = @import("Pipeline.zig"); +const PipelineCache = @import("PipelineCache.zig"); +const PipelineLayout = @import("PipelineLayout.zig"); +const QueryPool = @import("QueryPool.zig"); +const RenderPass = @import("RenderPass.zig"); +const Sampler = @import("Sampler.zig"); +const ShaderModule = @import("ShaderModule.zig"); const Self = @This(); pub const ObjectType: vk.ObjectType = .device; @@ -38,12 +48,24 @@ pub const VTable = struct { pub const DispatchTable = struct { allocateMemory: *const fn (*Self, std.mem.Allocator, *const vk.MemoryAllocateInfo) VkError!*DeviceMemory, createBuffer: *const fn (*Self, std.mem.Allocator, *const vk.BufferCreateInfo) VkError!*Buffer, + createBufferView: *const fn (*Self, std.mem.Allocator, *const vk.BufferViewCreateInfo) VkError!*BufferView, createCommandPool: *const fn (*Self, std.mem.Allocator, *const vk.CommandPoolCreateInfo) VkError!*CommandPool, + createComputePipeline: *const fn (*Self, std.mem.Allocator, ?*PipelineCache, *const vk.ComputePipelineCreateInfo) VkError!*Pipeline, createDescriptorPool: *const fn (*Self, std.mem.Allocator, *const vk.DescriptorPoolCreateInfo) VkError!*DescriptorPool, createDescriptorSetLayout: *const fn (*Self, std.mem.Allocator, *const vk.DescriptorSetLayoutCreateInfo) VkError!*DescriptorSetLayout, + createEvent: *const fn (*Self, std.mem.Allocator, *const vk.EventCreateInfo) VkError!*Event, createFence: *const fn (*Self, std.mem.Allocator, *const vk.FenceCreateInfo) VkError!*Fence, + createFramebuffer: *const fn (*Self, std.mem.Allocator, *const vk.FramebufferCreateInfo) VkError!*Framebuffer, + createGraphicsPipeline: *const fn (*Self, std.mem.Allocator, ?*PipelineCache, *const vk.GraphicsPipelineCreateInfo) VkError!*Pipeline, createImage: *const fn (*Self, std.mem.Allocator, *const vk.ImageCreateInfo) VkError!*Image, createImageView: *const fn (*Self, std.mem.Allocator, *const vk.ImageViewCreateInfo) VkError!*ImageView, + createPipelineCache: *const fn (*Self, std.mem.Allocator, *const vk.PipelineCacheCreateInfo) VkError!*PipelineCache, + createPipelineLayout: *const fn (*Self, std.mem.Allocator, *const vk.PipelineLayoutCreateInfo) VkError!*PipelineLayout, + createQueryPool: *const fn (*Self, std.mem.Allocator, *const vk.QueryPoolCreateInfo) VkError!*QueryPool, + createRenderPass: *const fn (*Self, std.mem.Allocator, *const vk.RenderPassCreateInfo) VkError!*RenderPass, + createSampler: *const fn (*Self, std.mem.Allocator, *const vk.SamplerCreateInfo) VkError!*Sampler, + createSemaphore: *const fn (*Self, std.mem.Allocator, *const vk.SemaphoreCreateInfo) VkError!*BinarySemaphore, + createShaderModule: *const fn (*Self, std.mem.Allocator, *const vk.ShaderModuleCreateInfo) VkError!*ShaderModule, destroy: *const fn (*Self, std.mem.Allocator) VkError!void, }; @@ -124,3 +146,60 @@ pub inline fn createImage(self: *Self, allocator: std.mem.Allocator, info: *cons pub inline fn createImageView(self: *Self, allocator: std.mem.Allocator, info: *const vk.ImageViewCreateInfo) VkError!*ImageView { return self.dispatch_table.createImageView(self, allocator, info); } + +pub inline fn createBufferView(self: *Self, allocator: std.mem.Allocator, info: *const vk.BufferViewCreateInfo) VkError!*BufferView { + return self.dispatch_table.createBufferView(self, allocator, info); +} + +pub inline fn createComputePipeline(self: *Self, allocator: std.mem.Allocator, cache: ?*PipelineCache, info: *const vk.ComputePipelineCreateInfo) VkError!*Pipeline { + return self.dispatch_table.createComputePipeline(self, allocator, cache, info); +} + +pub inline fn createEvent(self: *Self, allocator: std.mem.Allocator, info: *const vk.EventCreateInfo) VkError!*Event { + return self.dispatch_table.createEvent(self, allocator, info); +} + +pub inline fn createFramebuffer(self: *Self, allocator: std.mem.Allocator, info: *const vk.FramebufferCreateInfo) VkError!*Framebuffer { + return self.dispatch_table.createFramebuffer(self, allocator, info); +} + +pub inline fn createGraphicsPipeline(self: *Self, allocator: std.mem.Allocator, cache: ?*PipelineCache, info: *const vk.GraphicsPipelineCreateInfo) VkError!*Pipeline { + return self.dispatch_table.createGraphicsPipeline(self, allocator, cache, info); +} + +pub inline fn createPipelineCache(self: *Self, allocator: std.mem.Allocator, info: *const vk.PipelineCacheCreateInfo) VkError!*PipelineCache { + return self.dispatch_table.createPipelineCache(self, allocator, info); +} + +pub inline fn createPipelineLayout(self: *Self, allocator: std.mem.Allocator, info: *const vk.PipelineLayoutCreateInfo) VkError!*PipelineLayout { + return self.dispatch_table.createPipelineLayout(self, allocator, info); +} + +pub inline fn createQueryPool(self: *Self, allocator: std.mem.Allocator, info: *const vk.QueryPoolCreateInfo) VkError!*QueryPool { + return self.dispatch_table.createQueryPool(self, allocator, info); +} + +pub inline fn createRenderPass(self: *Self, allocator: std.mem.Allocator, info: *const vk.RenderPassCreateInfo) VkError!*RenderPass { + return self.dispatch_table.createRenderPass(self, allocator, info); +} + +pub inline fn createSampler(self: *Self, allocator: std.mem.Allocator, info: *const vk.SamplerCreateInfo) VkError!*Sampler { + return self.dispatch_table.createSampler(self, allocator, info); +} + +pub inline fn createSemaphore(self: *Self, allocator: std.mem.Allocator, info: *const vk.SemaphoreCreateInfo) VkError!*BinarySemaphore { + return self.dispatch_table.createSemaphore(self, allocator, info); +} + +pub inline fn createShaderModule(self: *Self, allocator: std.mem.Allocator, info: *const vk.ShaderModuleCreateInfo) VkError!*ShaderModule { + return self.dispatch_table.createShaderModule(self, allocator, info); +} + +pub inline fn waitIdle(self: *Self) VkError!void { + var it = self.queues.iterator(); + while (it.next()) |family| { + for (family.value_ptr.items) |queue| { + try queue.object.waitIdle(); + } + } +} diff --git a/src/vulkan/Event.zig b/src/vulkan/Event.zig new file mode 100644 index 0000000..b3af327 --- /dev/null +++ b/src/vulkan/Event.zig @@ -0,0 +1,32 @@ +const std = @import("std"); +const vk = @import("vulkan"); + +const NonDispatchable = @import("NonDispatchable.zig"); + +const VkError = @import("error_set.zig").VkError; + +const Device = @import("Device.zig"); + +const Self = @This(); +pub const ObjectType: vk.ObjectType = .event; + +owner: *Device, + +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.EventCreateInfo) VkError!Self { + _ = allocator; + _ = info; + return .{ + .owner = device, + .vtable = undefined, + }; +} + +pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void { + self.vtable.destroy(self, allocator); +} diff --git a/src/vulkan/Framebuffer.zig b/src/vulkan/Framebuffer.zig new file mode 100644 index 0000000..bf6d55c --- /dev/null +++ b/src/vulkan/Framebuffer.zig @@ -0,0 +1,32 @@ +const std = @import("std"); +const vk = @import("vulkan"); + +const NonDispatchable = @import("NonDispatchable.zig"); + +const VkError = @import("error_set.zig").VkError; + +const Device = @import("Device.zig"); + +const Self = @This(); +pub const ObjectType: vk.ObjectType = .framebuffer; + +owner: *Device, + +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.FramebufferCreateInfo) VkError!Self { + _ = allocator; + _ = info; + return .{ + .owner = device, + .vtable = undefined, + }; +} + +pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void { + self.vtable.destroy(self, allocator); +} diff --git a/src/vulkan/Pipeline.zig b/src/vulkan/Pipeline.zig new file mode 100644 index 0000000..fe600b6 --- /dev/null +++ b/src/vulkan/Pipeline.zig @@ -0,0 +1,44 @@ +const std = @import("std"); +const vk = @import("vulkan"); + +const NonDispatchable = @import("NonDispatchable.zig"); + +const VkError = @import("error_set.zig").VkError; + +const Device = @import("Device.zig"); +const PipelineCache = @import("PipelineCache.zig"); + +const Self = @This(); +pub const ObjectType: vk.ObjectType = .pipeline; + +owner: *Device, + +vtable: *const VTable, + +pub const VTable = struct { + destroy: *const fn (*Self, std.mem.Allocator) void, +}; + +pub fn initCompute(device: *Device, allocator: std.mem.Allocator, cache: ?*PipelineCache, info: *const vk.ComputePipelineCreateInfo) VkError!Self { + _ = allocator; + _ = cache; + _ = info; + return .{ + .owner = device, + .vtable = undefined, + }; +} + +pub fn initGraphics(device: *Device, allocator: std.mem.Allocator, cache: ?*PipelineCache, info: *const vk.GraphicsPipelineCreateInfo) VkError!Self { + _ = allocator; + _ = cache; + _ = info; + return .{ + .owner = device, + .vtable = undefined, + }; +} + +pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void { + self.vtable.destroy(self, allocator); +} diff --git a/src/vulkan/PipelineCache.zig b/src/vulkan/PipelineCache.zig new file mode 100644 index 0000000..33bbf09 --- /dev/null +++ b/src/vulkan/PipelineCache.zig @@ -0,0 +1,32 @@ +const std = @import("std"); +const vk = @import("vulkan"); + +const NonDispatchable = @import("NonDispatchable.zig"); + +const VkError = @import("error_set.zig").VkError; + +const Device = @import("Device.zig"); + +const Self = @This(); +pub const ObjectType: vk.ObjectType = .pipeline_cache; + +owner: *Device, + +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.PipelineCacheCreateInfo) VkError!Self { + _ = allocator; + _ = info; + return .{ + .owner = device, + .vtable = undefined, + }; +} + +pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void { + self.vtable.destroy(self, allocator); +} diff --git a/src/vulkan/PipelineLayout.zig b/src/vulkan/PipelineLayout.zig new file mode 100644 index 0000000..8e12f8e --- /dev/null +++ b/src/vulkan/PipelineLayout.zig @@ -0,0 +1,32 @@ +const std = @import("std"); +const vk = @import("vulkan"); + +const NonDispatchable = @import("NonDispatchable.zig"); + +const VkError = @import("error_set.zig").VkError; + +const Device = @import("Device.zig"); + +const Self = @This(); +pub const ObjectType: vk.ObjectType = .pipeline_layout; + +owner: *Device, + +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.PipelineLayoutCreateInfo) VkError!Self { + _ = allocator; + _ = info; + return .{ + .owner = device, + .vtable = undefined, + }; +} + +pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void { + self.vtable.destroy(self, allocator); +} diff --git a/src/vulkan/QueryPool.zig b/src/vulkan/QueryPool.zig new file mode 100644 index 0000000..61a33de --- /dev/null +++ b/src/vulkan/QueryPool.zig @@ -0,0 +1,32 @@ +const std = @import("std"); +const vk = @import("vulkan"); + +const NonDispatchable = @import("NonDispatchable.zig"); + +const VkError = @import("error_set.zig").VkError; + +const Device = @import("Device.zig"); + +const Self = @This(); +pub const ObjectType: vk.ObjectType = .query_pool; + +owner: *Device, + +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.QueryPoolCreateInfo) VkError!Self { + _ = allocator; + _ = info; + return .{ + .owner = device, + .vtable = undefined, + }; +} + +pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void { + self.vtable.destroy(self, allocator); +} diff --git a/src/vulkan/RenderPass.zig b/src/vulkan/RenderPass.zig new file mode 100644 index 0000000..d0e5885 --- /dev/null +++ b/src/vulkan/RenderPass.zig @@ -0,0 +1,32 @@ +const std = @import("std"); +const vk = @import("vulkan"); + +const NonDispatchable = @import("NonDispatchable.zig"); + +const VkError = @import("error_set.zig").VkError; + +const Device = @import("Device.zig"); + +const Self = @This(); +pub const ObjectType: vk.ObjectType = .render_pass; + +owner: *Device, + +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.RenderPassCreateInfo) VkError!Self { + _ = allocator; + _ = info; + return .{ + .owner = device, + .vtable = undefined, + }; +} + +pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void { + self.vtable.destroy(self, allocator); +} diff --git a/src/vulkan/Sampler.zig b/src/vulkan/Sampler.zig new file mode 100644 index 0000000..a3c160e --- /dev/null +++ b/src/vulkan/Sampler.zig @@ -0,0 +1,32 @@ +const std = @import("std"); +const vk = @import("vulkan"); + +const NonDispatchable = @import("NonDispatchable.zig"); + +const VkError = @import("error_set.zig").VkError; + +const Device = @import("Device.zig"); + +const Self = @This(); +pub const ObjectType: vk.ObjectType = .sampler; + +owner: *Device, + +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.SamplerCreateInfo) VkError!Self { + _ = allocator; + _ = info; + return .{ + .owner = device, + .vtable = undefined, + }; +} + +pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void { + self.vtable.destroy(self, allocator); +} diff --git a/src/vulkan/ShaderModule.zig b/src/vulkan/ShaderModule.zig new file mode 100644 index 0000000..eeb0964 --- /dev/null +++ b/src/vulkan/ShaderModule.zig @@ -0,0 +1,32 @@ +const std = @import("std"); +const vk = @import("vulkan"); + +const NonDispatchable = @import("NonDispatchable.zig"); + +const VkError = @import("error_set.zig").VkError; + +const Device = @import("Device.zig"); + +const Self = @This(); +pub const ObjectType: vk.ObjectType = .shader_module; + +owner: *Device, + +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.ShaderModuleCreateInfo) VkError!Self { + _ = allocator; + _ = info; + return .{ + .owner = device, + .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 8da8c58..5217ede 100644 --- a/src/vulkan/lib.zig +++ b/src/vulkan/lib.zig @@ -7,35 +7,46 @@ pub const vku = @cImport({ }); pub const commands = @import("commands.zig"); +pub const errors = @import("error_set.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 = errors.VkError; pub const VulkanAllocator = @import("VulkanAllocator.zig"); -pub const Instance = @import("Instance.zig"); +pub const CommandBuffer = @import("CommandBuffer.zig"); pub const Device = @import("Device.zig"); +pub const Instance = @import("Instance.zig"); pub const PhysicalDevice = @import("PhysicalDevice.zig"); pub const Queue = @import("Queue.zig"); +pub const BinarySemaphore = @import("BinarySemaphore.zig"); pub const Buffer = @import("Buffer.zig"); -pub const CommandBuffer = @import("CommandBuffer.zig"); +pub const BufferView = @import("BufferView.zig"); pub const CommandPool = @import("CommandPool.zig"); pub const DescriptorPool = @import("DescriptorPool.zig"); pub const DescriptorSet = @import("DescriptorSet.zig"); pub const DescriptorSetLayout = @import("DescriptorSetLayout.zig"); pub const DeviceMemory = @import("DeviceMemory.zig"); +pub const Event = @import("Event.zig"); pub const Fence = @import("Fence.zig"); +pub const Framebuffer = @import("Framebuffer.zig"); pub const Image = @import("Image.zig"); pub const ImageView = @import("ImageView.zig"); +pub const Pipeline = @import("Pipeline.zig"); +pub const PipelineCache = @import("PipelineCache.zig"); +pub const PipelineLayout = @import("PipelineLayout.zig"); +pub const QueryPool = @import("QueryPool.zig"); +pub const RenderPass = @import("RenderPass.zig"); +pub const Sampler = @import("Sampler.zig"); +pub const ShaderModule = @import("ShaderModule.zig"); pub const VULKAN_VENDOR_ID = @typeInfo(vk.VendorId).@"enum".fields[@typeInfo(vk.VendorId).@"enum".fields.len - 1].value + 1; -pub const DRIVER_LOGS_ENV_NAME = "STROLL_LOGS_LEVEL"; pub const DRIVER_DEBUG_ALLOCATOR_ENV_NAME = "STROLL_DEBUG_ALLOCATOR"; +pub const DRIVER_LOGS_ENV_NAME = "STROLL_LOGS_LEVEL"; /// Default driver name pub const DRIVER_NAME = "Unnamed Driver"; diff --git a/src/vulkan/lib_vulkan.zig b/src/vulkan/lib_vulkan.zig index 44e6d88..06ca140 100644 --- a/src/vulkan/lib_vulkan.zig +++ b/src/vulkan/lib_vulkan.zig @@ -17,21 +17,32 @@ 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"); +pub const CommandBuffer = @import("CommandBuffer.zig"); +pub const Device = @import("Device.zig"); +pub const Instance = @import("Instance.zig"); +pub const PhysicalDevice = @import("PhysicalDevice.zig"); +pub 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 DescriptorPool = @import("DescriptorPool.zig"); -const DescriptorSet = @import("DescriptorSet.zig"); -const DescriptorSetLayout = @import("DescriptorSetLayout.zig"); -const Fence = @import("Fence.zig"); -const Image = @import("Image.zig"); -const ImageView = @import("ImageView.zig"); +pub const BinarySemaphore = @import("BinarySemaphore.zig"); +pub const Buffer = @import("Buffer.zig"); +pub const BufferView = @import("BufferView.zig"); +pub const CommandPool = @import("CommandPool.zig"); +pub const DescriptorPool = @import("DescriptorPool.zig"); +pub const DescriptorSet = @import("DescriptorSet.zig"); +pub const DescriptorSetLayout = @import("DescriptorSetLayout.zig"); +pub const DeviceMemory = @import("DeviceMemory.zig"); +pub const Event = @import("Event.zig"); +pub const Fence = @import("Fence.zig"); +pub const Framebuffer = @import("Framebuffer.zig"); +pub const Image = @import("Image.zig"); +pub const ImageView = @import("ImageView.zig"); +pub const Pipeline = @import("Pipeline.zig"); +pub const PipelineCache = @import("PipelineCache.zig"); +pub const PipelineLayout = @import("PipelineLayout.zig"); +pub const QueryPool = @import("QueryPool.zig"); +pub const RenderPass = @import("RenderPass.zig"); +pub const Sampler = @import("Sampler.zig"); +pub const ShaderModule = @import("ShaderModule.zig"); fn entryPointBeginLogTrace(comptime scope: @Type(.enum_literal)) void { std.log.scoped(scope).debug("Calling {s}...", .{@tagName(scope)}); @@ -216,7 +227,7 @@ const device_pfn_map = block: { functionMapEntryPoint("vkResetFences"), functionMapEntryPoint("vkSetEvent"), functionMapEntryPoint("vkUnmapMemory"), - functionMapEntryPoint("vkUpdateDescriptorSets"), // + functionMapEntryPoint("vkUpdateDescriptorSets"), functionMapEntryPoint("vkWaitForFences"), }); }; @@ -612,15 +623,9 @@ pub export fn strollCreateBufferView(p_device: vk.Device, info: *const vk.Buffer } const allocator = VulkanAllocator.init(callbacks, .object).allocator(); const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err); - - notImplementedWarning(); - - _ = allocator; - _ = device; - - p_view.* = .null_handle; - - return .error_unknown; + const view = device.createBufferView(allocator, info) catch |err| return toVkResult(err); + p_view.* = (NonDispatchable(BufferView).wrap(allocator, view) catch |err| return toVkResult(err)).toVkHandle(vk.BufferView); + 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 { @@ -644,21 +649,16 @@ pub export fn strollCreateComputePipelines(p_device: vk.Device, p_cache: vk.Pipe const allocator = VulkanAllocator.init(callbacks, .object).allocator(); const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err); + const cache = if (p_cache == .null_handle) null else NonDispatchable(PipelineCache).fromHandleObject(p_cache) catch |err| return toVkResult(err); - notImplementedWarning(); - - for (p_pipelines, infos, 0..count) |*p_pipeline, info, _| { + for (p_pipelines, infos, 0..count) |*p_pipeline, *info, _| { if (info.s_type != .compute_pipeline_create_info) { return .error_validation_failed; } - p_pipeline.* = .null_handle; + const pipeline = device.createComputePipeline(allocator, cache, info) catch |err| return toVkResult(err); + p_pipeline.* = (NonDispatchable(Pipeline).wrap(allocator, pipeline) catch |err| return toVkResult(err)).toVkHandle(vk.Pipeline); } - - _ = allocator; - _ = device; - _ = p_cache; - - return .error_unknown; + return .success; } pub export fn strollCreateDescriptorPool(p_device: vk.Device, info: *const vk.DescriptorPoolCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_pool: *vk.DescriptorPool) callconv(vk.vulkan_call_conv) vk.Result { @@ -699,17 +699,11 @@ pub export fn strollCreateEvent(p_device: vk.Device, info: *const vk.EventCreate return .error_validation_failed; } - notImplementedWarning(); - const allocator = VulkanAllocator.init(callbacks, .object).allocator(); const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err); - - p_event.* = .null_handle; - - _ = device; - _ = allocator; - - return .error_unknown; + const event = device.createEvent(allocator, info) catch |err| return toVkResult(err); + p_event.* = (NonDispatchable(Event).wrap(allocator, event) catch |err| return toVkResult(err)).toVkHandle(vk.Event); + 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 { @@ -735,17 +729,11 @@ pub export fn strollCreateFramebuffer(p_device: vk.Device, info: *const vk.Frame return .error_validation_failed; } - notImplementedWarning(); - const allocator = VulkanAllocator.init(callbacks, .object).allocator(); const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err); - - p_framebuffer.* = .null_handle; - - _ = device; - _ = allocator; - - return .error_unknown; + const framebuffer = device.createFramebuffer(allocator, info) catch |err| return toVkResult(err); + p_framebuffer.* = (NonDispatchable(Framebuffer).wrap(allocator, framebuffer) catch |err| return toVkResult(err)).toVkHandle(vk.Framebuffer); + return .success; } pub export fn strollCreateGraphicsPipelines(p_device: vk.Device, p_cache: vk.PipelineCache, count: u32, infos: [*]const vk.GraphicsPipelineCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_pipelines: [*]vk.Pipeline) callconv(vk.vulkan_call_conv) vk.Result { @@ -754,21 +742,16 @@ pub export fn strollCreateGraphicsPipelines(p_device: vk.Device, p_cache: vk.Pip const allocator = VulkanAllocator.init(callbacks, .object).allocator(); const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err); + const cache = if (p_cache == .null_handle) null else NonDispatchable(PipelineCache).fromHandleObject(p_cache) catch |err| return toVkResult(err); - notImplementedWarning(); - - for (p_pipelines, infos, 0..count) |*p_pipeline, info, _| { + for (p_pipelines, infos, 0..count) |*p_pipeline, *info, _| { if (info.s_type != .graphics_pipeline_create_info) { return .error_validation_failed; } - p_pipeline.* = .null_handle; + const pipeline = device.createGraphicsPipeline(allocator, cache, info) catch |err| return toVkResult(err); + p_pipeline.* = (NonDispatchable(Pipeline).wrap(allocator, pipeline) catch |err| return toVkResult(err)).toVkHandle(vk.Pipeline); } - - _ = allocator; - _ = device; - _ = p_cache; - - return .error_unknown; + 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 { @@ -807,17 +790,11 @@ pub export fn strollCreatePipelineCache(p_device: vk.Device, info: *const vk.Pip return .error_validation_failed; } - notImplementedWarning(); - const allocator = VulkanAllocator.init(callbacks, .object).allocator(); const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err); - - p_cache.* = .null_handle; - - _ = device; - _ = allocator; - - return .error_unknown; + const cache = device.createPipelineCache(allocator, info) catch |err| return toVkResult(err); + p_cache.* = (NonDispatchable(PipelineCache).wrap(allocator, cache) catch |err| return toVkResult(err)).toVkHandle(vk.PipelineCache); + return .success; } pub export fn strollCreatePipelineLayout(p_device: vk.Device, info: *const vk.PipelineLayoutCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_layout: *vk.PipelineLayout) callconv(vk.vulkan_call_conv) vk.Result { @@ -828,17 +805,11 @@ pub export fn strollCreatePipelineLayout(p_device: vk.Device, info: *const vk.Pi return .error_validation_failed; } - notImplementedWarning(); - const allocator = VulkanAllocator.init(callbacks, .object).allocator(); const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err); - - p_layout.* = .null_handle; - - _ = device; - _ = allocator; - - return .error_unknown; + const layout = device.createPipelineLayout(allocator, info) catch |err| return toVkResult(err); + p_layout.* = (NonDispatchable(PipelineLayout).wrap(allocator, layout) catch |err| return toVkResult(err)).toVkHandle(vk.PipelineLayout); + return .success; } pub export fn strollCreateQueryPool(p_device: vk.Device, info: *const vk.QueryPoolCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_pool: *vk.QueryPool) callconv(vk.vulkan_call_conv) vk.Result { @@ -849,17 +820,11 @@ pub export fn strollCreateQueryPool(p_device: vk.Device, info: *const vk.QueryPo return .error_validation_failed; } - notImplementedWarning(); - const allocator = VulkanAllocator.init(callbacks, .object).allocator(); const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err); - - p_pool.* = .null_handle; - - _ = device; - _ = allocator; - - return .error_unknown; + const pool = device.createQueryPool(allocator, info) catch |err| return toVkResult(err); + p_pool.* = (NonDispatchable(QueryPool).wrap(allocator, pool) catch |err| return toVkResult(err)).toVkHandle(vk.QueryPool); + return .success; } pub export fn strollCreateRenderPass(p_device: vk.Device, info: *const vk.RenderPassCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_pass: *vk.RenderPass) callconv(vk.vulkan_call_conv) vk.Result { @@ -870,17 +835,11 @@ pub export fn strollCreateRenderPass(p_device: vk.Device, info: *const vk.Render return .error_validation_failed; } - notImplementedWarning(); - const allocator = VulkanAllocator.init(callbacks, .object).allocator(); const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err); - - p_pass.* = .null_handle; - - _ = device; - _ = allocator; - - return .error_unknown; + const pass = device.createRenderPass(allocator, info) catch |err| return toVkResult(err); + p_pass.* = (NonDispatchable(RenderPass).wrap(allocator, pass) catch |err| return toVkResult(err)).toVkHandle(vk.RenderPass); + return .success; } pub export fn strollCreateSampler(p_device: vk.Device, info: *const vk.SamplerCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_sampler: *vk.Sampler) callconv(vk.vulkan_call_conv) vk.Result { @@ -891,17 +850,11 @@ pub export fn strollCreateSampler(p_device: vk.Device, info: *const vk.SamplerCr return .error_validation_failed; } - notImplementedWarning(); - const allocator = VulkanAllocator.init(callbacks, .object).allocator(); const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err); - - p_sampler.* = .null_handle; - - _ = device; - _ = allocator; - - return .error_unknown; + const sampler = device.createSampler(allocator, info) catch |err| return toVkResult(err); + p_sampler.* = (NonDispatchable(Sampler).wrap(allocator, sampler) catch |err| return toVkResult(err)).toVkHandle(vk.Sampler); + return .success; } pub export fn strollCreateSemaphore(p_device: vk.Device, info: *const vk.SemaphoreCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_semaphore: *vk.Semaphore) callconv(vk.vulkan_call_conv) vk.Result { @@ -912,17 +865,11 @@ pub export fn strollCreateSemaphore(p_device: vk.Device, info: *const vk.Semapho return .error_validation_failed; } - notImplementedWarning(); - const allocator = VulkanAllocator.init(callbacks, .object).allocator(); const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err); - - p_semaphore.* = .null_handle; - - _ = device; - _ = allocator; - - return .error_unknown; + const semaphore = device.createSemaphore(allocator, info) catch |err| return toVkResult(err); + p_semaphore.* = (NonDispatchable(BinarySemaphore).wrap(allocator, semaphore) catch |err| return toVkResult(err)).toVkHandle(vk.Semaphore); + return .success; } pub export fn strollCreateShaderModule(p_device: vk.Device, info: *const vk.ShaderModuleCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_module: *vk.ShaderModule) callconv(vk.vulkan_call_conv) vk.Result { @@ -933,17 +880,11 @@ pub export fn strollCreateShaderModule(p_device: vk.Device, info: *const vk.Shad return .error_validation_failed; } - notImplementedWarning(); - const allocator = VulkanAllocator.init(callbacks, .object).allocator(); const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err); - - p_module.* = .null_handle; - - _ = device; - _ = allocator; - - return .error_unknown; + const module = device.createShaderModule(allocator, info) catch |err| return toVkResult(err); + p_module.* = (NonDispatchable(ShaderModule).wrap(allocator, module) catch |err| return toVkResult(err)).toVkHandle(vk.ShaderModule); + return .success; } pub export fn strollDestroyBuffer(p_device: vk.Device, p_buffer: vk.Buffer, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void { @@ -964,11 +905,8 @@ pub export fn strollDestroyBufferView(p_device: vk.Device, p_view: vk.BufferView Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err); const allocator = VulkanAllocator.init(callbacks, .object).allocator(); - - notImplementedWarning(); - - _ = p_view; - _ = allocator; + const non_dispatchable = NonDispatchable(BufferView).fromHandle(p_view) 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 { @@ -1024,11 +962,8 @@ pub export fn strollDestroyEvent(p_device: vk.Device, p_event: vk.Event, callbac Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err); const allocator = VulkanAllocator.init(callbacks, .object).allocator(); - - notImplementedWarning(); - - _ = p_event; - _ = allocator; + const non_dispatchable = NonDispatchable(Event).fromHandle(p_event) catch |err| return errorLogger(err); + non_dispatchable.intrusiveDestroy(allocator); } pub export fn strollDestroyFence(p_device: vk.Device, p_fence: vk.Fence, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void { @@ -1049,11 +984,8 @@ pub export fn strollDestroyFramebuffer(p_device: vk.Device, p_framebuffer: vk.Fr Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err); const allocator = VulkanAllocator.init(callbacks, .object).allocator(); - - notImplementedWarning(); - - _ = p_framebuffer; - _ = allocator; + const non_dispatchable = NonDispatchable(Framebuffer).fromHandle(p_framebuffer) 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 { @@ -1085,11 +1017,8 @@ pub export fn strollDestroyPipeline(p_device: vk.Device, p_pipeline: vk.Pipeline Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err); const allocator = VulkanAllocator.init(callbacks, .object).allocator(); - - notImplementedWarning(); - - _ = p_pipeline; - _ = allocator; + const non_dispatchable = NonDispatchable(Pipeline).fromHandle(p_pipeline) catch |err| return errorLogger(err); + non_dispatchable.intrusiveDestroy(allocator); } pub export fn strollDestroyPipelineCache(p_device: vk.Device, p_cache: vk.PipelineCache, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void { @@ -1099,11 +1028,8 @@ pub export fn strollDestroyPipelineCache(p_device: vk.Device, p_cache: vk.Pipeli Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err); const allocator = VulkanAllocator.init(callbacks, .object).allocator(); - - notImplementedWarning(); - - _ = p_cache; - _ = allocator; + const non_dispatchable = NonDispatchable(PipelineCache).fromHandle(p_cache) catch |err| return errorLogger(err); + non_dispatchable.intrusiveDestroy(allocator); } pub export fn strollDestroyPipelineLayout(p_device: vk.Device, p_layout: vk.PipelineLayout, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void { @@ -1113,11 +1039,8 @@ pub export fn strollDestroyPipelineLayout(p_device: vk.Device, p_layout: vk.Pipe Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err); const allocator = VulkanAllocator.init(callbacks, .object).allocator(); - - notImplementedWarning(); - - _ = p_layout; - _ = allocator; + const non_dispatchable = NonDispatchable(PipelineLayout).fromHandle(p_layout) catch |err| return errorLogger(err); + non_dispatchable.intrusiveDestroy(allocator); } pub export fn strollDestroyQueryPool(p_device: vk.Device, p_pool: vk.QueryPool, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void { @@ -1127,11 +1050,8 @@ pub export fn strollDestroyQueryPool(p_device: vk.Device, p_pool: vk.QueryPool, Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err); const allocator = VulkanAllocator.init(callbacks, .object).allocator(); - - notImplementedWarning(); - - _ = p_pool; - _ = allocator; + const non_dispatchable = NonDispatchable(QueryPool).fromHandle(p_pool) catch |err| return errorLogger(err); + non_dispatchable.intrusiveDestroy(allocator); } pub export fn strollDestroyRenderPass(p_device: vk.Device, p_pass: vk.RenderPass, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void { @@ -1141,11 +1061,8 @@ pub export fn strollDestroyRenderPass(p_device: vk.Device, p_pass: vk.RenderPass Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err); const allocator = VulkanAllocator.init(callbacks, .object).allocator(); - - notImplementedWarning(); - - _ = p_pass; - _ = allocator; + const non_dispatchable = NonDispatchable(RenderPass).fromHandle(p_pass) catch |err| return errorLogger(err); + non_dispatchable.intrusiveDestroy(allocator); } pub export fn strollDestroySampler(p_device: vk.Device, p_sampler: vk.Sampler, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void { @@ -1155,11 +1072,8 @@ pub export fn strollDestroySampler(p_device: vk.Device, p_sampler: vk.Sampler, c Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err); const allocator = VulkanAllocator.init(callbacks, .object).allocator(); - - notImplementedWarning(); - - _ = p_sampler; - _ = allocator; + const non_dispatchable = NonDispatchable(Sampler).fromHandle(p_sampler) catch |err| return errorLogger(err); + non_dispatchable.intrusiveDestroy(allocator); } pub export fn strollDestroySemaphore(p_device: vk.Device, p_semaphore: vk.Semaphore, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void { @@ -1169,11 +1083,8 @@ pub export fn strollDestroySemaphore(p_device: vk.Device, p_semaphore: vk.Semaph Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err); const allocator = VulkanAllocator.init(callbacks, .object).allocator(); - - notImplementedWarning(); - - _ = p_semaphore; - _ = allocator; + const non_dispatchable = NonDispatchable(BinarySemaphore).fromHandle(p_semaphore) catch |err| return errorLogger(err); + non_dispatchable.intrusiveDestroy(allocator); } pub export fn strollDestroyShaderModule(p_device: vk.Device, p_module: vk.ShaderModule, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void { @@ -1183,11 +1094,8 @@ pub export fn strollDestroyShaderModule(p_device: vk.Device, p_module: vk.Shader Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err); const allocator = VulkanAllocator.init(callbacks, .object).allocator(); - - notImplementedWarning(); - - _ = p_module; - _ = allocator; + const non_dispatchable = NonDispatchable(ShaderModule).fromHandle(p_module) catch |err| return errorLogger(err); + non_dispatchable.intrusiveDestroy(allocator); } pub export fn strollDeviceWaitIdle(p_device: vk.Device) callconv(vk.vulkan_call_conv) vk.Result { @@ -1195,12 +1103,8 @@ pub export fn strollDeviceWaitIdle(p_device: vk.Device) callconv(vk.vulkan_call_ defer entryPointEndLogTrace(); const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err); - - notImplementedWarning(); - - _ = device; - - return .error_unknown; + device.waitIdle() catch |err| return toVkResult(err); + return .success; } pub export fn strollFlushMappedMemoryRanges(p_device: vk.Device, count: u32, p_ranges: [*]const vk.MappedMemoryRange) callconv(vk.vulkan_call_conv) vk.Result { diff --git a/test/c/main.c b/test/c/main.c index 5686adb..62c86ff 100644 --- a/test/c/main.c +++ b/test/c/main.c @@ -23,6 +23,56 @@ #define STB_IMAGE_WRITE_IMPLEMENTATION #include +static const uint32_t vertex_shader[] = { + 0x07230203,0x00010000,0x000d000b,0x00000036,0x00000000,0x00020011,0x00000001,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e, + 0x00000000,0x0003000e,0x00000000,0x00000001,0x0008000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x00000022,0x00000026,0x00000031, + 0x00030003,0x00000002,0x000001c2,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365, + 0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d, + 0x00000000,0x00050005,0x0000000c,0x69736f70,0x6e6f6974,0x00000073,0x00040005,0x00000017,0x6f6c6f63,0x00007372,0x00060005,0x00000020, + 0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006,0x00000020,0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x00000020, + 0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006,0x00000020,0x00000002,0x435f6c67,0x4470696c,0x61747369,0x0065636e, + 0x00070006,0x00000020,0x00000003,0x435f6c67,0x446c6c75,0x61747369,0x0065636e,0x00030005,0x00000022,0x00000000,0x00060005,0x00000026, + 0x565f6c67,0x65747265,0x646e4978,0x00007865,0x00050005,0x00000031,0x67617266,0x6f6c6f43,0x00000072,0x00050048,0x00000020,0x00000000, + 0x0000000b,0x00000000,0x00050048,0x00000020,0x00000001,0x0000000b,0x00000001,0x00050048,0x00000020,0x00000002,0x0000000b,0x00000003, + 0x00050048,0x00000020,0x00000003,0x0000000b,0x00000004,0x00030047,0x00000020,0x00000002,0x00040047,0x00000026,0x0000000b,0x0000002a, + 0x00040047,0x00000031,0x0000001e,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020, + 0x00040017,0x00000007,0x00000006,0x00000002,0x00040015,0x00000008,0x00000020,0x00000000,0x0004002b,0x00000008,0x00000009,0x00000003, + 0x0004001c,0x0000000a,0x00000007,0x00000009,0x00040020,0x0000000b,0x00000006,0x0000000a,0x0004003b,0x0000000b,0x0000000c,0x00000006, + 0x0004002b,0x00000006,0x0000000d,0x00000000,0x0004002b,0x00000006,0x0000000e,0xbf000000,0x0005002c,0x00000007,0x0000000f,0x0000000d, + 0x0000000e,0x0004002b,0x00000006,0x00000010,0x3f000000,0x0005002c,0x00000007,0x00000011,0x00000010,0x00000010,0x0005002c,0x00000007, + 0x00000012,0x0000000e,0x00000010,0x0006002c,0x0000000a,0x00000013,0x0000000f,0x00000011,0x00000012,0x00040017,0x00000014,0x00000006, + 0x00000003,0x0004001c,0x00000015,0x00000014,0x00000009,0x00040020,0x00000016,0x00000006,0x00000015,0x0004003b,0x00000016,0x00000017, + 0x00000006,0x0004002b,0x00000006,0x00000018,0x3f800000,0x0006002c,0x00000014,0x00000019,0x00000018,0x0000000d,0x0000000d,0x0006002c, + 0x00000014,0x0000001a,0x0000000d,0x00000018,0x0000000d,0x0006002c,0x00000014,0x0000001b,0x0000000d,0x0000000d,0x00000018,0x0006002c, + 0x00000015,0x0000001c,0x00000019,0x0000001a,0x0000001b,0x00040017,0x0000001d,0x00000006,0x00000004,0x0004002b,0x00000008,0x0000001e, + 0x00000001,0x0004001c,0x0000001f,0x00000006,0x0000001e,0x0006001e,0x00000020,0x0000001d,0x00000006,0x0000001f,0x0000001f,0x00040020, + 0x00000021,0x00000003,0x00000020,0x0004003b,0x00000021,0x00000022,0x00000003,0x00040015,0x00000023,0x00000020,0x00000001,0x0004002b, + 0x00000023,0x00000024,0x00000000,0x00040020,0x00000025,0x00000001,0x00000023,0x0004003b,0x00000025,0x00000026,0x00000001,0x00040020, + 0x00000028,0x00000006,0x00000007,0x00040020,0x0000002e,0x00000003,0x0000001d,0x00040020,0x00000030,0x00000003,0x00000014,0x0004003b, + 0x00000030,0x00000031,0x00000003,0x00040020,0x00000033,0x00000006,0x00000014,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003, + 0x000200f8,0x00000005,0x0003003e,0x0000000c,0x00000013,0x0003003e,0x00000017,0x0000001c,0x0004003d,0x00000023,0x00000027,0x00000026, + 0x00050041,0x00000028,0x00000029,0x0000000c,0x00000027,0x0004003d,0x00000007,0x0000002a,0x00000029,0x00050051,0x00000006,0x0000002b, + 0x0000002a,0x00000000,0x00050051,0x00000006,0x0000002c,0x0000002a,0x00000001,0x00070050,0x0000001d,0x0000002d,0x0000002b,0x0000002c, + 0x0000000d,0x00000018,0x00050041,0x0000002e,0x0000002f,0x00000022,0x00000024,0x0003003e,0x0000002f,0x0000002d,0x0004003d,0x00000023, + 0x00000032,0x00000026,0x00050041,0x00000033,0x00000034,0x00000017,0x00000032,0x0004003d,0x00000014,0x00000035,0x00000034,0x0003003e, + 0x00000031,0x00000035,0x000100fd,0x00010038 +}; + +static const uint32_t fragment_shader[] = { + 0x07230203,0x00010000,0x000d000b,0x00000013,0x00000000,0x00020011,0x00000001,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e, + 0x00000000,0x0003000e,0x00000000,0x00000001,0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000009,0x0000000c,0x00030010, + 0x00000004,0x00000007,0x00030003,0x00000002,0x000001c2,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c, + 0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005, + 0x00000004,0x6e69616d,0x00000000,0x00050005,0x00000009,0x4374756f,0x726f6c6f,0x00000000,0x00050005,0x0000000c,0x67617266,0x6f6c6f43, + 0x00000072,0x00040047,0x00000009,0x0000001e,0x00000000,0x00040047,0x0000000c,0x0000001e,0x00000000,0x00020013,0x00000002,0x00030021, + 0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040020,0x00000008,0x00000003, + 0x00000007,0x0004003b,0x00000008,0x00000009,0x00000003,0x00040017,0x0000000a,0x00000006,0x00000003,0x00040020,0x0000000b,0x00000001, + 0x0000000a,0x0004003b,0x0000000b,0x0000000c,0x00000001,0x0004002b,0x00000006,0x0000000e,0x3f800000,0x00050036,0x00000002,0x00000004, + 0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x0000000a,0x0000000d,0x0000000c,0x00050051,0x00000006,0x0000000f,0x0000000d, + 0x00000000,0x00050051,0x00000006,0x00000010,0x0000000d,0x00000001,0x00050051,0x00000006,0x00000011,0x0000000d,0x00000002,0x00070050, + 0x00000007,0x00000012,0x0000000f,0x00000010,0x00000011,0x0000000e,0x0003003e,0x00000009,0x00000012,0x000100fd,0x00010038 +}; + VkDeviceMemory CreateAndBindMemoryToBuffer(VkPhysicalDevice physical_device, VkDevice device, VkBuffer buffer, VkMemoryPropertyFlags props) { VkMemoryRequirements requirements; @@ -83,28 +133,64 @@ int main(void) volkLoadInstance(instance); VkPhysicalDevice physical_device = kvfPickGoodPhysicalDevice(instance, VK_NULL_HANDLE, NULL, 0); - VkDevice device = kvfCreateDevice(physical_device, NULL, 0, NULL); volkLoadDevice(device); - VkImage image = kvfCreateImage(device, 256, 256, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TILING_LINEAR, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, KVF_IMAGE_COLOR); + VkImage image = kvfCreateImage(device, 600, 400, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TILING_LINEAR, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, KVF_IMAGE_COLOR); VkDeviceMemory memory = CreateAndBindMemoryToImage(physical_device, device, image, 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); + VkAttachmentDescription attachment = kvfBuildAttachmentDescription(KVF_IMAGE_COLOR, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true, VK_SAMPLE_COUNT_1_BIT); + VkRenderPass renderpass = kvfCreateRenderPass(device, &attachment, 1, VK_PIPELINE_BIND_POINT_GRAPHICS); + + VkFramebuffer framebuffer = kvfCreateFramebuffer(device, renderpass, &image_view, 1, (VkExtent2D){ .width = 600, .height = 400 }); + + VkShaderModule vertex_shader_module = kvfCreateShaderModule(device, (uint32_t*)vertex_shader, sizeof(vertex_shader) / sizeof(uint32_t)); + VkShaderModule fragment_shader_module = kvfCreateShaderModule(device, (uint32_t*)fragment_shader, sizeof(fragment_shader) / sizeof(uint32_t)); + + VkPipelineLayout pipeline_layout = kvfCreatePipelineLayout(device, NULL, 0, NULL, 0); + + KvfGraphicsPipelineBuilder* builder = kvfCreateGPipelineBuilder(); + kvfGPipelineBuilderSetInputTopology(builder, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST); + kvfGPipelineBuilderSetPolygonMode(builder, VK_POLYGON_MODE_FILL, 1.0f); + kvfGPipelineBuilderSetCullMode(builder, VK_CULL_MODE_NONE, VK_FRONT_FACE_CLOCKWISE); + kvfGPipelineBuilderSetMultisampling(builder, VK_SAMPLE_COUNT_1_BIT); + kvfGPipelineBuilderAddShaderStage(builder, VK_SHADER_STAGE_VERTEX_BIT, vertex_shader_module, "main"); + kvfGPipelineBuilderAddShaderStage(builder, VK_SHADER_STAGE_FRAGMENT_BIT, fragment_shader_module, "main"); + kvfGPipelineBuilderDisableDepthTest(builder); + kvfGPipelineBuilderDisableBlending(builder); + + VkPipeline pipeline = kvfCreateGraphicsPipeline(device, VK_NULL_HANDLE, pipeline_layout, builder, renderpass); + + kvfDestroyGPipelineBuilder(builder); + kvfDestroyShaderModule(device, vertex_shader_module); + kvfDestroyShaderModule(device, fragment_shader_module); + VkCommandBuffer cmd = kvfCreateCommandBuffer(device); kvfCheckVk(vkResetCommandBuffer(cmd, 0)); kvfBeginCommandBuffer(cmd, 0); { + vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + VkClearValue clear_color = {{{0.0f, 0.0f, 0.0f, 1.0f}}}; + kvfBeginRenderPass(renderpass, cmd, framebuffer, (VkExtent2D){ .width = 600, .height = 400 }, &clear_color, 1); + VkViewport viewport = { 0 }; + viewport.width = 600; + viewport.height = 400; + viewport.maxDepth = 1.0f; + vkCmdSetViewport(cmd, 0, 1, &viewport); + VkRect2D scissor = { 0 }; + scissor.extent = (VkExtent2D){ .width = 600, .height = 400 }; + vkCmdSetScissor(cmd, 0, 1, &scissor); + vkCmdDraw(cmd, 3, 1, 0, 0); + vkCmdEndRenderPass(cmd); } kvfEndCommandBuffer(cmd); - kvfSubmitCommandBuffer(device, cmd, KVF_GRAPHICS_QUEUE, VK_NULL_HANDLE, VK_NULL_HANDLE, fence, NULL); - kvfWaitForFence(device, fence); + VkPipelineStageFlags wait_stages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; + kvfSubmitCommandBuffer(device, cmd, KVF_GRAPHICS_QUEUE, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, wait_stages); + vkDeviceWaitIdle(device); void* map = NULL; kvfCheckVk(vkMapMemory(device, memory, 0, VK_WHOLE_SIZE, 0, &map)); @@ -112,11 +198,14 @@ int main(void) fprintf(stderr, "Failed to write result image to file\n"); vkUnmapMemory(device, memory); - kvfDestroyFence(device, fence); - + vkDeviceWaitIdle(device); + kvfDestroyPipelineLayout(device, pipeline_layout); + kvfDestroyPipeline(device, pipeline); + kvfDestroyRenderPass(device, renderpass); kvfDestroyImageView(device, image_view); kvfDestroyImage(device, image); vkFreeMemory(device, memory, NULL); + kvfDestroyFramebuffer(device, framebuffer); kvfDestroyDevice(device); kvfDestroyInstance(instance);