From 34ca91f6f77f0d80f952c6b8a037e5bc929b33f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Gasi=C7=B9ski?= Date: Fri, 28 Jun 2024 22:35:32 +0200 Subject: [PATCH] Start implementing the graphics pipeline --- build.zig | 10 ++++++++++ src/shaders/shader.frag | 11 +++++++++++ src/shaders/shader.vert | 23 +++++++++++++++++++++++ src/vulkan_renderer.zig | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+) create mode 100644 src/shaders/shader.frag create mode 100644 src/shaders/shader.vert diff --git a/build.zig b/build.zig index f51b0fc..7796f98 100644 --- a/build.zig +++ b/build.zig @@ -1,5 +1,6 @@ const std = @import("std"); const sdl = @import("sdl"); +const vkgen = @import("vulkan_zig"); // Although this function looks imperative, note that its job is to // declaratively construct a build graph that will be executed by an external @@ -29,6 +30,15 @@ pub fn build(b: *std.Build) void { const vkzig_bindings = vkzig_dep.module("vulkan-zig"); exe.root_module.addImport("vulkan", vkzig_bindings); + const shader_comp = vkgen.ShaderCompileStep.create( + b, + &[_][]const u8{ "glslc", "--target-env=vulkan1.3" }, + "-o", + ); + shader_comp.add("shader_frag", "src/shaders/shader.frag", .{}); + shader_comp.add("shader_vert", "src/shaders/shader.vert", .{}); + exe.root_module.addImport("shaders", shader_comp.getModule()); + const sdl_sdk = sdl.init(b, null); sdl_sdk.link(exe, .dynamic); diff --git a/src/shaders/shader.frag b/src/shaders/shader.frag new file mode 100644 index 0000000..edeac14 --- /dev/null +++ b/src/shaders/shader.frag @@ -0,0 +1,11 @@ +#version 450 + +// Interpolated colour from vertex (location must match) +layout(location = 0) in vec3 fragColour; + +// Final output output (must also have location) +layout(location = 0) out vec4 outColour; + +void main() { + outColour = vec4(fragColour, 1.0); +} diff --git a/src/shaders/shader.vert b/src/shaders/shader.vert new file mode 100644 index 0000000..7a51229 --- /dev/null +++ b/src/shaders/shader.vert @@ -0,0 +1,23 @@ +#version 450 + +// Output colour for vertex (location is required) +layout(location = 0) out vec3 fragColour; + +// Triangle vertex positions +vec3 positions[3] = vec3[]( + vec3(0.0, -0.4, 0.0), + vec3(0.4, 0.4, 0.0), + vec3(-0.4, 0.4, 0.0) + ); + +// Triangle vertex colours +vec3 colours[3] = vec3[]( + vec3(1.0, 0.0, 0.0), + vec3(0.0, 1.0, 0.0), + vec3(0.0, 0.0, 1.0) + ); + +void main() { + gl_Position = vec4(positions[gl_VertexIndex], 1.0); + fragColour = colours[gl_VertexIndex]; +} diff --git a/src/vulkan_renderer.zig b/src/vulkan_renderer.zig index 72fff8a..5263ba8 100644 --- a/src/vulkan_renderer.zig +++ b/src/vulkan_renderer.zig @@ -2,6 +2,7 @@ const std = @import("std"); const sdl = @import("sdl2"); const vk = @import("vulkan"); const builtin = @import("builtin"); +const shaders = @import("shaders"); const Utilities = @import("utilities.zig"); const QueueFamilyIndices = Utilities.QueueFamilyIndices; @@ -71,6 +72,7 @@ pub const VulkanRenderer = struct { try self.getPhysicalDevice(); try self.createLogicalDevice(); try self.createSwapchain(); + try self.createGraphicsPipeline(); return self; } @@ -248,6 +250,43 @@ pub const VulkanRenderer = struct { } } + fn createGraphicsPipeline(self: *Self) !void { + // Create shader modules + const vert = try self.device.createShaderModule(&.{ + .code_size = shaders.shader_vert.len, + .p_code = @ptrCast(&shaders.shader_vert), + }, null); + defer self.device.destroyShaderModule(vert, null); + + const frag = try self.device.createShaderModule(&.{ + .code_size = shaders.shader_frag.len, + .p_code = @ptrCast(&shaders.shader_frag), + }, null); + defer self.device.destroyShaderModule(frag, null); + + // -- Shader stage creation information + + // Vertex stage creation information + const vertex_shader_create_info: vk.PipelineShaderStageCreateInfo = .{ + .stage = .{ .vertex_bit = true }, + .module = vert, + .p_name = "main", + }; + + // Fragment stage creation information + const fragment_shader_create_info: vk.PipelineShaderStageCreateInfo = .{ + .stage = .{ .fragment_bit = true }, + .module = frag, + .p_name = "main", + }; + + const shader_create_infos = [_]vk.PipelineShaderStageCreateInfo{ + vertex_shader_create_info, + fragment_shader_create_info, + }; + _ = shader_create_infos; + } + fn getPhysicalDevice(self: *Self) !void { var pdev_count: u32 = 0; _ = try self.instance.enumeratePhysicalDevices(&pdev_count, null);