diff options
author | Lorenzo Torres <lorenzotorres@outlook.it> | 2025-03-12 19:56:19 +0100 |
---|---|---|
committer | Lorenzo Torres <lorenzotorres@outlook.it> | 2025-03-12 19:56:19 +0100 |
commit | 4f45899a3c28440724ffcaa3a604ad48f18a25c8 (patch) | |
tree | cecd79da4e3e3cb17ffd86ec1a58d6e77a44cb83 /src/render/renderer_vulkan.zig | |
parent | fc39b277155044366f1647b238a415fab4028d83 (diff) |
base code
Diffstat (limited to 'src/render/renderer_vulkan.zig')
-rw-r--r-- | src/render/renderer_vulkan.zig | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/render/renderer_vulkan.zig b/src/render/renderer_vulkan.zig new file mode 100644 index 0000000..93088c9 --- /dev/null +++ b/src/render/renderer_vulkan.zig @@ -0,0 +1,94 @@ +const c = @import("../c.zig"); +const std = @import("std"); +const vk = @import("vulkan.zig"); +const window = @import("window.zig"); +const mesh = @import("mesh.zig"); +const Allocator = std.mem.Allocator; + +const Renderer = @This(); + +instance: vk.Instance, +surface: vk.Surface, +physical_device: vk.PhysicalDevice, +device: vk.Device(2), +render_pass: vk.RenderPass(2), +swapchain: vk.Swapchain(2), +graphics_pipeline: vk.GraphicsPipeline(2), +current_frame: u32, +vertex_buffer: vk.Buffer, +index_buffer: vk.Buffer, + +pub fn create(allocator: Allocator, w: window.Window) !Renderer { + const instance = try vk.Instance.create(); + + const surface = try vk.Surface.create(instance, w); + + var physical_device = try vk.PhysicalDevice.pick(allocator, instance); + const device = try physical_device.create_device(surface, allocator, 2); + + const vertex_shader = try device.createShader("shader_vert"); + defer device.destroyShader(vertex_shader); + const fragment_shader = try device.createShader("shader_frag"); + defer device.destroyShader(fragment_shader); + + const render_pass = try vk.RenderPass(2).create(allocator, device, surface, physical_device); + + const swapchain = try vk.Swapchain(2).create(allocator, surface, device, physical_device, w, render_pass); + + const graphics_pipeline = try vk.GraphicsPipeline(2).create(device, swapchain, render_pass, vertex_shader, fragment_shader); + + // TODO: I think the renderer shouldn't have to interact with buffers. I think the API should change to + // something along the lines of + // renderer.begin() + // renderer.render(triangle); + // renderer.render(some_other_thing); + // ... + // renderer.submit() + const triangle = try mesh.Mesh.create(device); + + return Renderer{ + .instance = instance, + .surface = surface, + .physical_device = physical_device, + .device = device, + .render_pass = render_pass, + .swapchain = swapchain, + .graphics_pipeline = graphics_pipeline, + .current_frame = 0, + // TODO: Why are we storing the buffer and not the Mesh? + .vertex_buffer = triangle.vertex_buffer, + .index_buffer = triangle.index_buffer, + }; +} + +pub fn destroy(self: Renderer) !void { + try self.device.waitIdle(); + self.index_buffer.destroy(self.device.handle); + self.vertex_buffer.destroy(self.device.handle); + self.graphics_pipeline.destroy(self.device); + self.swapchain.destroy(self.device); + self.render_pass.destroy(self.device); + self.device.destroy(); + self.surface.destroy(self.instance); + self.instance.destroy(); +} + +// TODO: tick is maybe a bad name? something like present() or submit() is better? +pub fn tick(self: *Renderer) !void { + try self.device.waitFence(self.current_frame); + const image = try self.swapchain.nextImage(self.device, self.current_frame); + try self.device.resetCommand(self.current_frame); + try self.device.beginCommand(self.current_frame); + self.render_pass.begin(self.swapchain, self.device, image, self.current_frame); + self.graphics_pipeline.bind(self.device, self.current_frame); + self.device.bindVertexBuffer(self.vertex_buffer, self.current_frame); + self.device.bindIndexBuffer(self.index_buffer, self.current_frame); + self.device.bindDescriptorSets(self.graphics_pipeline, self.current_frame); + self.device.draw(@intCast(self.index_buffer.size / @sizeOf(u16)), self.current_frame); + self.render_pass.end(self.device, self.current_frame); + try self.device.endCommand(self.current_frame); + + try self.device.submit(self.swapchain, image, self.current_frame); + + self.current_frame = (self.current_frame + 1) % 2; +} |