From 2cbc6a79d207bac9e9831467cf905986da3bbb5b Mon Sep 17 00:00:00 2001 From: IntegratedQuantum Date: Fri, 9 May 2025 14:12:42 +0200 Subject: [PATCH] Add a ComputePipeline and make Shader private fixes #1417 --- src/blocks.zig | 9 +++-- src/graphics.zig | 44 +++++++++++++++++-------- src/gui/GuiWindow.zig | 1 - src/gui/components/Button.zig | 1 - src/gui/components/CheckBox.zig | 1 - src/gui/components/ContinuousSlider.zig | 1 - src/gui/components/DiscreteSlider.zig | 1 - src/gui/components/ScrollBar.zig | 1 - src/gui/windows/crosshair.zig | 1 - src/renderer.zig | 1 - src/renderer/chunk_meshing.zig | 11 +++---- 11 files changed, 39 insertions(+), 33 deletions(-) diff --git a/src/blocks.zig b/src/blocks.zig index 5c3b1667..b86e24ea 100644 --- a/src/blocks.zig +++ b/src/blocks.zig @@ -5,7 +5,6 @@ const Tag = main.Tag; const ZonElement = @import("zon.zig").ZonElement; const Neighbor = @import("chunk.zig").Neighbor; const graphics = @import("graphics.zig"); -const Shader = graphics.Shader; const SSBO = graphics.SSBO; const Image = graphics.Image; const Color = graphics.Color; @@ -448,7 +447,7 @@ pub const meshes = struct { // MARK: meshes var animatedTextureSSBO: ?SSBO = null; var fogSSBO: ?SSBO = null; - var animationShader: Shader = undefined; + var animationComputePipeline: graphics.ComputePipeline = undefined; var animationUniforms: struct { time: c_int, size: c_int, @@ -466,7 +465,7 @@ pub const meshes = struct { // MARK: meshes const emptyImage = Image{.width = 1, .height = 1, .imageData = emptyTexture[0..]}; pub fn init() void { - animationShader = Shader.initComputeAndGetUniforms("assets/cubyz/shaders/animation_pre_processing.glsl", "", &animationUniforms); + animationComputePipeline = graphics.ComputePipeline.init("assets/cubyz/shaders/animation_pre_processing.glsl", "", &animationUniforms); blockTextureArray = .init(); emissionTextureArray = .init(); reflectivityAndAbsorptionTextureArray = .init(); @@ -492,7 +491,7 @@ pub const meshes = struct { // MARK: meshes if(fogSSBO) |ssbo| { ssbo.deinit(); } - animationShader.deinit(); + animationComputePipeline.deinit(); blockTextureArray.deinit(); emissionTextureArray.deinit(); reflectivityAndAbsorptionTextureArray.deinit(); @@ -674,7 +673,7 @@ pub const meshes = struct { // MARK: meshes } pub fn preProcessAnimationData(time: u32) void { - animationShader.bind(); + animationComputePipeline.bind(); graphics.c.glUniform1ui(animationUniforms.time, time); graphics.c.glUniform1ui(animationUniforms.size, @intCast(animation.items.len)); graphics.c.glDispatchCompute(@intCast(@divFloor(animation.items.len + 63, 64)), 1, 1); // TODO: Replace with @divCeil once available diff --git a/src/graphics.zig b/src/graphics.zig index f0b0035b..23bf7e38 100644 --- a/src/graphics.zig +++ b/src/graphics.zig @@ -1282,7 +1282,7 @@ pub fn deinit() void { glslang.glslang_finalize_process(); } -pub const Shader = struct { // MARK: Shader +const Shader = struct { // MARK: Shader id: c_uint, fn compileToSpirV(allocator: NeverFailingAllocator, source: []const u8, filename: []const u8, defines: []const u8, shaderStage: glslang.glslang_stage_t) ![]c_uint { @@ -1409,28 +1409,26 @@ pub const Shader = struct { // MARK: Shader return shader; } - pub fn initCompute(compute: []const u8, defines: []const u8) Shader { + fn initCompute(compute: []const u8, defines: []const u8, uniformStruct: anytype) Shader { const shader = Shader{.id = c.glCreateProgram()}; shader.addShader(compute, defines, c.GL_COMPUTE_SHADER) catch return shader; shader.link(compute) catch return shader; + + if(@TypeOf(uniformStruct) != @TypeOf(null)) { + inline for(@typeInfo(@TypeOf(uniformStruct.*)).@"struct".fields) |field| { + if(field.type == c_int) { + @field(uniformStruct, field.name) = c.glGetUniformLocation(shader.id, field.name[0..]); + } + } + } return shader; } - pub fn initComputeAndGetUniforms(compute: []const u8, defines: []const u8, ptrToUniformStruct: anytype) Shader { - const self = Shader.initCompute(compute, defines); - inline for(@typeInfo(@TypeOf(ptrToUniformStruct.*)).@"struct".fields) |field| { - if(field.type == c_int) { - @field(ptrToUniformStruct, field.name) = c.glGetUniformLocation(self.id, field.name[0..]); - } - } - return self; - } - - pub fn bind(self: *const Shader) void { + fn bind(self: *const Shader) void { c.glUseProgram(self.id); } - pub fn deinit(self: *const Shader) void { + fn deinit(self: *const Shader) void { c.glDeleteProgram(self.id); } }; @@ -1774,6 +1772,24 @@ pub const Pipeline = struct { // MARK: Pipeline } }; +pub const ComputePipeline = struct { // MARK: ComputePipeline + shader: Shader, + + pub fn init(computePath: []const u8, defines: []const u8, uniformStruct: anytype) ComputePipeline { + return .{ + .shader = .initCompute(computePath, defines, uniformStruct), + }; + } + + pub fn deinit(self: ComputePipeline) void { + self.shader.deinit(); + } + + pub fn bind(self: ComputePipeline) void { + self.shader.bind(); + } +}; + pub const SSBO = struct { // MARK: SSBO bufferID: c_uint, pub fn init() SSBO { diff --git a/src/gui/GuiWindow.zig b/src/gui/GuiWindow.zig index fb7ad7ba..a70e8ffa 100644 --- a/src/gui/GuiWindow.zig +++ b/src/gui/GuiWindow.zig @@ -3,7 +3,6 @@ const std = @import("std"); const main = @import("main"); const graphics = main.graphics; const draw = graphics.draw; -const Shader = graphics.Shader; const Texture = graphics.Texture; const settings = main.settings; const vec = main.vec; diff --git a/src/gui/components/Button.zig b/src/gui/components/Button.zig index 1cb432dd..dc975fbb 100644 --- a/src/gui/components/Button.zig +++ b/src/gui/components/Button.zig @@ -3,7 +3,6 @@ const std = @import("std"); const main = @import("main"); const graphics = main.graphics; const draw = graphics.draw; -const Shader = graphics.Shader; const TextBuffer = graphics.TextBuffer; const Texture = graphics.Texture; const vec = main.vec; diff --git a/src/gui/components/CheckBox.zig b/src/gui/components/CheckBox.zig index b2ff8390..a0cbdad4 100644 --- a/src/gui/components/CheckBox.zig +++ b/src/gui/components/CheckBox.zig @@ -3,7 +3,6 @@ const std = @import("std"); const main = @import("main"); const graphics = main.graphics; const draw = graphics.draw; -const Shader = graphics.Shader; const TextBuffer = graphics.TextBuffer; const Texture = graphics.Texture; const random = main.random; diff --git a/src/gui/components/ContinuousSlider.zig b/src/gui/components/ContinuousSlider.zig index c1ab1378..a73aecc9 100644 --- a/src/gui/components/ContinuousSlider.zig +++ b/src/gui/components/ContinuousSlider.zig @@ -3,7 +3,6 @@ const std = @import("std"); const main = @import("main"); const graphics = main.graphics; const draw = graphics.draw; -const Shader = graphics.Shader; const TextBuffer = graphics.TextBuffer; const Texture = graphics.Texture; const random = main.random; diff --git a/src/gui/components/DiscreteSlider.zig b/src/gui/components/DiscreteSlider.zig index b9f41fcf..efd45b87 100644 --- a/src/gui/components/DiscreteSlider.zig +++ b/src/gui/components/DiscreteSlider.zig @@ -3,7 +3,6 @@ const std = @import("std"); const main = @import("main"); const graphics = main.graphics; const draw = graphics.draw; -const Shader = graphics.Shader; const TextBuffer = graphics.TextBuffer; const Texture = graphics.Texture; const random = main.random; diff --git a/src/gui/components/ScrollBar.zig b/src/gui/components/ScrollBar.zig index 9ce2c13e..371f413a 100644 --- a/src/gui/components/ScrollBar.zig +++ b/src/gui/components/ScrollBar.zig @@ -3,7 +3,6 @@ const std = @import("std"); const main = @import("main"); const graphics = main.graphics; const draw = graphics.draw; -const Shader = graphics.Shader; const TextBuffer = graphics.TextBuffer; const Texture = graphics.Texture; const random = main.random; diff --git a/src/gui/windows/crosshair.zig b/src/gui/windows/crosshair.zig index f91af8c5..6b8bbdd8 100644 --- a/src/gui/windows/crosshair.zig +++ b/src/gui/windows/crosshair.zig @@ -2,7 +2,6 @@ const std = @import("std"); const main = @import("main"); const graphics = main.graphics; -const Shader = graphics.Shader; const Texture = graphics.Texture; const Vec2f = main.vec.Vec2f; diff --git a/src/renderer.zig b/src/renderer.zig index ea95a7e0..872c4e26 100644 --- a/src/renderer.zig +++ b/src/renderer.zig @@ -6,7 +6,6 @@ const chunk = @import("chunk.zig"); const entity = @import("entity.zig"); const graphics = @import("graphics.zig"); const c = graphics.c; -const Shader = graphics.Shader; const game = @import("game.zig"); const World = game.World; const itemdrop = @import("itemdrop.zig"); diff --git a/src/renderer/chunk_meshing.zig b/src/renderer/chunk_meshing.zig index 662c6ab9..110d2fed 100644 --- a/src/renderer/chunk_meshing.zig +++ b/src/renderer/chunk_meshing.zig @@ -11,7 +11,6 @@ const QuadIndex = models.QuadIndex; const renderer = main.renderer; const graphics = main.graphics; const c = graphics.c; -const Shader = graphics.Shader; const SSBO = graphics.SSBO; const lighting = @import("lighting.zig"); const settings = main.settings; @@ -46,7 +45,7 @@ const UniformStruct = struct { }; pub var uniforms: UniformStruct = undefined; pub var transparentUniforms: UniformStruct = undefined; -pub var commandShader: Shader = undefined; +pub var commandPipeline: graphics.ComputePipeline = undefined; pub var commandUniforms: struct { chunkIDIndex: c_int, commandIndexStart: c_int, @@ -100,7 +99,7 @@ pub fn init() void { .alphaBlendOp = .add, }}}, ); - commandShader = Shader.initComputeAndGetUniforms("assets/cubyz/shaders/chunks/fillIndirectBuffer.glsl", "", &commandUniforms); + commandPipeline = graphics.ComputePipeline.init("assets/cubyz/shaders/chunks/fillIndirectBuffer.glsl", "", &commandUniforms); occlusionTestPipeline = graphics.Pipeline.init( "assets/cubyz/shaders/chunks/occlusionTestVertex.vs", "assets/cubyz/shaders/chunks/occlusionTestFragment.fs", @@ -145,7 +144,7 @@ pub fn deinit() void { pipeline.deinit(); transparentPipeline.deinit(); occlusionTestPipeline.deinit(); - commandShader.deinit(); + commandPipeline.deinit(); c.glDeleteVertexArrays(1, &vao); c.glDeleteBuffers(1, &vbo); faceBuffer.deinit(); @@ -219,7 +218,7 @@ pub fn drawChunksIndirect(chunkIDs: []const u32, projMatrix: Mat4f, ambient: Vec defer chunkIDBuffer.free(chunkIDAllocation); const allocation = commandBuffer.rawAlloc(drawCallsEstimate); defer commandBuffer.free(allocation); - commandShader.bind(); + commandPipeline.bind(); c.glUniform1f(commandUniforms.lodDistance, main.settings.@"lod0.5Distance"); c.glUniform1ui(commandUniforms.chunkIDIndex, chunkIDAllocation.start); c.glUniform1ui(commandUniforms.commandIndexStart, allocation.start); @@ -256,7 +255,7 @@ pub fn drawChunksIndirect(chunkIDs: []const u32, projMatrix: Mat4f, ambient: Vec // Draw again: gpu_performance_measuring.startQuery(if(transparent) .transparent_rendering else .chunk_rendering_new_visible); - commandShader.bind(); + commandPipeline.bind(); c.glUniform1i(commandUniforms.onlyDrawPreviouslyInvisible, 1); c.glDispatchCompute(@intCast(@divFloor(chunkIDs.len + 63, 64)), 1, 1); // TODO: Replace with @divCeil once available c.glMemoryBarrier(c.GL_SHADER_STORAGE_BARRIER_BIT | c.GL_COMMAND_BARRIER_BIT);