Add a ComputePipeline and make Shader private

fixes #1417
This commit is contained in:
IntegratedQuantum 2025-05-09 14:12:42 +02:00
parent 82675434be
commit 2cbc6a79d2
11 changed files with 39 additions and 33 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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");

View File

@ -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);