From d010954abb46d76b24cec46a0c9cde67720326bb Mon Sep 17 00:00:00 2001 From: Lorenzo Torres Date: Sat, 9 Aug 2025 18:51:11 +0200 Subject: [PATCH] Rransforms are all sent to the gpu with one buffer --- assets/shaders/shader.vert | 8 +++++++- src/rendering/Device.zig | 3 +-- src/rendering/GraphicsPipeline.zig | 14 +++++++++++--- src/rendering/Renderer.zig | 13 ++++++++++--- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/assets/shaders/shader.vert b/assets/shaders/shader.vert index b2d181e..a483346 100644 --- a/assets/shaders/shader.vert +++ b/assets/shaders/shader.vert @@ -4,6 +4,7 @@ struct Transform { mat4 translation; mat4 scale; mat4 rotation; + vec4 quaternion; }; layout(location = 0) in vec3 vertPos; @@ -26,8 +27,13 @@ layout(location = 2) out vec3 Normal; layout(location = 3) out vec3 FragPos; layout(location = 4) out vec2 TexCoords; +layout(push_constant) uniform pc { + layout(offset = 4) int transform_index; +} pushConstants; + void main() { - mat4 transformation = transform.transforms[0].translation * transform.transforms[0].scale * transform.transforms[0].rotation; + int transform_index = pushConstants.transform_index; + mat4 transformation = transform.transforms[transform_index].translation * transform.transforms[transform_index].scale * transform.transforms[transform_index].rotation; vec4 out_vec = proj.proj * view.view * transformation * vec4(vertPos, 1.0); FragPos = vec3(transformation * vec4(vertPos, 1.0)); diff --git a/src/rendering/Device.zig b/src/rendering/Device.zig index cfffd8a..972fc56 100644 --- a/src/rendering/Device.zig +++ b/src/rendering/Device.zig @@ -315,8 +315,7 @@ pub fn initShader(self: Self, comptime name: []const u8) !c.VkShaderModule { } pub fn pushConstant(self: Self, pipeline: vk.GraphicsPipeline, stage: u32, offset: u32, size: u32, data: [*c]u8, frame: usize) void { - _ = stage; - c.vkCmdPushConstants(self.command_buffers[frame], pipeline.layout, c.VK_SHADER_STAGE_FRAGMENT_BIT, offset, size, data); + c.vkCmdPushConstants(self.command_buffers[frame], pipeline.layout, stage, offset, size, data); } pub fn deinitShader(self: Self, shader: c.VkShaderModule) void { diff --git a/src/rendering/GraphicsPipeline.zig b/src/rendering/GraphicsPipeline.zig index c3a33f1..1c0d701 100644 --- a/src/rendering/GraphicsPipeline.zig +++ b/src/rendering/GraphicsPipeline.zig @@ -366,18 +366,26 @@ pub fn init(allocator: Allocator, device: vk.Device, swapchain: vk.Swapchain, re var set_layouts = [_]c.VkDescriptorSetLayout{descriptor_set_layout, texture_descriptor_set_layout}; - const range: c.VkPushConstantRange = .{ + const lights_range: c.VkPushConstantRange = .{ .stageFlags = c.VK_SHADER_STAGE_FRAGMENT_BIT, .offset = 0, .size = 4, }; + const transform_range: c.VkPushConstantRange = .{ + .stageFlags = c.VK_SHADER_STAGE_VERTEX_BIT, + .offset = 4, + .size = 4, + }; + + const range: [2]c.VkPushConstantRange = .{lights_range, transform_range}; + const layout_info: c.VkPipelineLayoutCreateInfo = .{ .sType = c.VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, .setLayoutCount = 2, .pSetLayouts = set_layouts[0..].ptr, - .pushConstantRangeCount = 1, - .pPushConstantRanges = &range, + .pushConstantRangeCount = 2, + .pPushConstantRanges = range[0..].ptr, }; var layout: c.VkPipelineLayout = undefined; diff --git a/src/rendering/Renderer.zig b/src/rendering/Renderer.zig index 4a57998..58fd7c3 100644 --- a/src/rendering/Renderer.zig +++ b/src/rendering/Renderer.zig @@ -2,6 +2,7 @@ const math = @import("math"); const ecs = @import("ecs"); const std = @import("std"); const vk = @import("vulkan.zig"); +const c = vk.c; const Mesh = @import("Mesh.zig"); const Texture = vk.Texture; const Camera = @import("Camera.zig"); @@ -83,8 +84,8 @@ pub fn init(allocator: Allocator, instance_handle: vk.c.VkInstance, surface_hand .swapchain = swapchain, .graphics_pipeline = graphics_pipeline, .current_frame = 0, - .transform = math.Transform.init(.{0.0, 0.0, 0.0}, .{1.0, 1.0, 1.0}, .{0.0, 0.0, 0.0}), - .transform2 = math.Transform.init(.{0.0, 3.0, 3.0}, .{0.5, 0.5, 0.5}, .{0.0, 0.0, 0.0}), + .transform = math.Transform.init(.{0.5, 0.0, 0.0}, .{0.5, 0.5, 0.5}, .{0.0, 0.0, 0.0}), + .transform2 = math.Transform.init(.{-1.0, 0.0, 0.0}, .{0.5, 0.5, 0.5}, .{0.0, 0.0, 0.0}), .previous_time = try std.time.Instant.now(), .mesh = mesh, }; @@ -120,6 +121,7 @@ pub fn render(pool: *ecs.Pool) anyerror!void { const transform_memory = renderer.graphics_pipeline.transform_buffer.mapped_memory; transform_memory[0] = renderer.transform; + transform_memory[1] = renderer.transform2; try renderer.device.waitFence(renderer.current_frame); const image = try renderer.swapchain.nextImage(renderer.device, renderer.current_frame); @@ -131,7 +133,12 @@ pub fn render(pool: *ecs.Pool) anyerror!void { renderer.device.bindIndexBuffer(renderer.graphics_pipeline.index_buffer, renderer.current_frame); renderer.device.bindDescriptorSets(renderer.graphics_pipeline, renderer.current_frame, 0); var lights: u32 = 2; - renderer.device.pushConstant(renderer.graphics_pipeline, 0, 0, 4, @ptrCast(&lights), renderer.current_frame); + renderer.device.pushConstant(renderer.graphics_pipeline, c.VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4, @ptrCast(&lights), renderer.current_frame); + var transform: u32 = 0; + renderer.device.pushConstant(renderer.graphics_pipeline, c.VK_SHADER_STAGE_VERTEX_BIT, 4, 4, @ptrCast(&transform), renderer.current_frame); + renderer.device.draw(renderer.mesh.index_count, renderer.current_frame, renderer.mesh); + transform = 1; + renderer.device.pushConstant(renderer.graphics_pipeline, c.VK_SHADER_STAGE_VERTEX_BIT, 4, 4, @ptrCast(&transform), renderer.current_frame); renderer.device.draw(renderer.mesh.index_count, renderer.current_frame, renderer.mesh); renderer.render_pass.end(renderer.device, renderer.current_frame); try renderer.device.endCommand(renderer.current_frame);