Added Plugins [Renderer, Cache, Common]
This commit is contained in:
parent
8dc9953666
commit
5e62d2c268
10 changed files with 483 additions and 0 deletions
12
build.zig
12
build.zig
|
|
@ -48,6 +48,18 @@ pub fn build(b: *std.Build) void {
|
|||
});
|
||||
exe.root_module.addImport("app", app.module("app"));
|
||||
|
||||
const gtl = b.dependency("gtl", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
exe.root_module.addImport("gtl", gtl.module("gtl"));
|
||||
|
||||
const zla = b.dependency("zla", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
exe.root_module.addImport("zla", zla.module("zla"));
|
||||
|
||||
//
|
||||
// SYSTEM DEPENDENCIES
|
||||
//
|
||||
|
|
|
|||
|
|
@ -13,9 +13,12 @@ const App = @import("app");
|
|||
//
|
||||
|
||||
const template = @import("plugins/template/root.zig");
|
||||
const common = @import("plugins/common/root.zig");
|
||||
const platform = @import("plugins/platform/root.zig");
|
||||
const device = @import("plugins/device/root.zig");
|
||||
const window = @import("plugins/window/root.zig");
|
||||
const cache = @import("plugins/cache/root.zig");
|
||||
const renderer = @import("plugins/renderer/root.zig");
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
|
|
@ -29,6 +32,8 @@ pub fn main(init: std.process.Init) !void {
|
|||
platform.plugin,
|
||||
device.plugin,
|
||||
window.plugin,
|
||||
cache.plugin,
|
||||
renderer.plugin,
|
||||
});
|
||||
try app.plugins.build(&app);
|
||||
|
||||
|
|
|
|||
19
src/plugins/cache/resource/embeded/shaders/pbr.wgsl
vendored
Normal file
19
src/plugins/cache/resource/embeded/shaders/pbr.wgsl
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
@vertex
|
||||
fn vs_main(
|
||||
@builtin(vertex_index) in_vertex_index: u32
|
||||
) -> @builtin(position) vec4f {
|
||||
var p = vec2f(0.0, 0.0);
|
||||
if in_vertex_index == 0u {
|
||||
p = vec2f(-0.5, -0.5);
|
||||
} else if in_vertex_index == 1u {
|
||||
p = vec2f(0.5, -0.5);
|
||||
} else {
|
||||
p = vec2f(0.0, 0.5);
|
||||
}
|
||||
return vec4f(p, 0.0, 1.0);
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fs_main() -> @location(0) vec4f {
|
||||
return vec4f(0.0, 0.4, 1.0, 1.0);
|
||||
}
|
||||
131
src/plugins/cache/resource/pipeline_cache.zig
vendored
Normal file
131
src/plugins/cache/resource/pipeline_cache.zig
vendored
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
//! ----------------------------------------------------
|
||||
//! ----------------------------------------------------
|
||||
|
||||
const std = @import("std");
|
||||
const gtl = @import("gtl");
|
||||
const wgpu = @import("wgpu");
|
||||
const Self = @This();
|
||||
|
||||
const Material = @import("../../common/component/material.zig");
|
||||
const ShaderCache = @import("shader_cache.zig");
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub const GPUPipeline = struct {
|
||||
raw: *wgpu.WGPURenderPipelineImpl,
|
||||
};
|
||||
|
||||
//
|
||||
// FIELDS
|
||||
//
|
||||
|
||||
pipelines: gtl.KeyedSlotMap(Material.Unique, GPUPipeline),
|
||||
shader_cache: *ShaderCache,
|
||||
queue: *wgpu.WGPUQueueImpl,
|
||||
device: *wgpu.WGPUDeviceImpl,
|
||||
alloc: std.mem.Allocator,
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn init(
|
||||
shader_cache: *ShaderCache,
|
||||
queue: *wgpu.WGPUQueueImpl,
|
||||
device: *wgpu.WGPUDeviceImpl,
|
||||
alloc: std.mem.Allocator,
|
||||
) Self {
|
||||
return .{
|
||||
.pipelines = .init(alloc),
|
||||
.shader_cache = shader_cache,
|
||||
.queue = queue,
|
||||
.device = device,
|
||||
.alloc = alloc,
|
||||
};
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn deinit(self: *Self) void {
|
||||
// --- FREE PIPELINES ---
|
||||
for (self.pipelines.items()) |entry| {
|
||||
wgpu.wgpuRenderPipelineRelease(entry.value.raw);
|
||||
}
|
||||
|
||||
// --- # ---
|
||||
self.pipelines.deinit();
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn getOrCreate(
|
||||
self: *Self,
|
||||
key: Material.Unique,
|
||||
) !*GPUPipeline {
|
||||
return try self.pipelines.getOrPut(key, .{
|
||||
.raw = try self.createPipeline(key),
|
||||
});
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
fn createPipeline(
|
||||
self: *Self,
|
||||
key: Material.Unique,
|
||||
) !*wgpu.WGPURenderPipelineImpl {
|
||||
// --- ENSURE SHADER MODULE ---
|
||||
const shader_module = try self.shader_cache.getOrCreate(
|
||||
key.shader,
|
||||
);
|
||||
|
||||
// --- RESULT ---
|
||||
return wgpu.wgpuDeviceCreateRenderPipeline(self.device, &wgpu.WGPURenderPipelineDescriptor{
|
||||
.label = .{ .data = @tagName(key.shader), .length = wgpu.WGPU_STRLEN },
|
||||
.vertex = .{
|
||||
.module = shader_module.raw,
|
||||
.entryPoint = .{ .data = "vs_main", .length = wgpu.WGPU_STRLEN },
|
||||
},
|
||||
.fragment = &wgpu.WGPUFragmentState{
|
||||
.module = shader_module.raw,
|
||||
.entryPoint = .{ .data = "fs_main", .length = wgpu.WGPU_STRLEN },
|
||||
.targetCount = 1,
|
||||
.targets = &wgpu.WGPUColorTargetState{
|
||||
.format = 28,
|
||||
.blend = &wgpu.WGPUBlendState{
|
||||
.color = .{
|
||||
.srcFactor = wgpu.WGPUBlendFactor_SrcAlpha,
|
||||
.dstFactor = wgpu.WGPUBlendFactor_OneMinusSrcAlpha,
|
||||
.operation = wgpu.WGPUBlendOperation_Add,
|
||||
},
|
||||
.alpha = .{
|
||||
.srcFactor = wgpu.WGPUBlendFactor_Zero,
|
||||
.dstFactor = wgpu.WGPUBlendFactor_One,
|
||||
.operation = wgpu.WGPUBlendOperation_Add,
|
||||
},
|
||||
},
|
||||
.writeMask = wgpu.WGPUColorWriteMask_All,
|
||||
},
|
||||
},
|
||||
.primitive = .{
|
||||
.topology = switch (key.topology) {
|
||||
.triangle_list => wgpu.WGPUPrimitiveTopology_TriangleList,
|
||||
.point_list => wgpu.WGPUPrimitiveTopology_PointList,
|
||||
.line_list => wgpu.WGPUPrimitiveTopology_LineList,
|
||||
},
|
||||
.frontFace = switch (key.front_face) {
|
||||
.ccw => wgpu.WGPUFrontFace_CCW,
|
||||
.cw => wgpu.WGPUFrontFace_CW,
|
||||
},
|
||||
.cullMode = switch (key.cull_mode) {
|
||||
.back => wgpu.WGPUCullMode_Back,
|
||||
.front => wgpu.WGPUCullMode_Front,
|
||||
.none => wgpu.WGPUCullMode_None,
|
||||
},
|
||||
},
|
||||
.multisample = .{
|
||||
.count = 1,
|
||||
.mask = ~@as(u32, 0),
|
||||
.alphaToCoverageEnabled = 0,
|
||||
},
|
||||
}) orelse {
|
||||
return error.PipelineCreationFailed;
|
||||
};
|
||||
}
|
||||
103
src/plugins/cache/resource/shader_cache.zig
vendored
Normal file
103
src/plugins/cache/resource/shader_cache.zig
vendored
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
//! ----------------------------------------------------
|
||||
//! ----------------------------------------------------
|
||||
|
||||
const std = @import("std");
|
||||
const gtl = @import("gtl");
|
||||
const wgpu = @import("wgpu");
|
||||
const Self = @This();
|
||||
|
||||
//
|
||||
// EMBEDED
|
||||
//
|
||||
|
||||
const PBRCode = @embedFile("embeded/shaders/pbr.wgsl");
|
||||
const UnlitCode = @embedFile("embeded/shaders/pbr.wgsl");
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub const ShaderID = union(enum) {
|
||||
pbr,
|
||||
unlit,
|
||||
custom: u32,
|
||||
};
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub const GPUShader = struct {
|
||||
raw: *wgpu.WGPUShaderModuleImpl,
|
||||
};
|
||||
|
||||
//
|
||||
// FIELDS
|
||||
//
|
||||
|
||||
modules: gtl.KeyedSlotMap(ShaderID, GPUShader),
|
||||
custom_paths: std.ArrayList([]const u8),
|
||||
device: *wgpu.WGPUDeviceImpl,
|
||||
alloc: std.mem.Allocator,
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn init(
|
||||
device: *wgpu.WGPUDeviceImpl,
|
||||
alloc: std.mem.Allocator,
|
||||
) Self {
|
||||
return .{
|
||||
.modules = .init(alloc),
|
||||
.custom_paths = .empty,
|
||||
.device = device,
|
||||
.alloc = alloc,
|
||||
};
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn deinit(self: *Self) void {
|
||||
// --- FREE SHADERS ---
|
||||
for (self.modules.items()) |entry| {
|
||||
wgpu.wgpuShaderModuleRelease(entry.value.raw);
|
||||
}
|
||||
|
||||
// --- # ---
|
||||
self.modules.deinit();
|
||||
self.custom_paths.deinit(self.alloc);
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn getOrCreate(
|
||||
self: *Self,
|
||||
key: ShaderID,
|
||||
) !*GPUShader {
|
||||
return try self.modules.getOrPut(key, .{
|
||||
.raw = try self.createShader(key),
|
||||
});
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
fn createShader(
|
||||
self: *Self,
|
||||
key: ShaderID,
|
||||
) !*wgpu.WGPUShaderModuleImpl {
|
||||
// --- CODE ---
|
||||
const code: []const u8 = switch (key) {
|
||||
.pbr => PBRCode,
|
||||
.unlit => UnlitCode,
|
||||
.custom => |v| self.custom_paths.items[@intCast(v)], // TODO: Handle out of bounds
|
||||
};
|
||||
|
||||
// --- SOURCE ---
|
||||
var source: wgpu.WGPUShaderSourceWGSL = .{
|
||||
.chain = .{ .sType = wgpu.WGPUSType_ShaderSourceWGSL },
|
||||
.code = .{ .data = code.ptr, .length = wgpu.WGPU_STRLEN },
|
||||
};
|
||||
|
||||
// --- RESULT ---
|
||||
return wgpu.wgpuDeviceCreateShaderModule(self.device, &wgpu.WGPUShaderModuleDescriptor{
|
||||
.label = .{ .data = @tagName(key), .length = wgpu.WGPU_STRLEN },
|
||||
.nextInChain = &source.chain,
|
||||
}) orelse {
|
||||
return error.ShaderModuleCreationFailed;
|
||||
};
|
||||
}
|
||||
33
src/plugins/cache/root.zig
vendored
Normal file
33
src/plugins/cache/root.zig
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
//! ----------------------------------------------------
|
||||
//! ----------------------------------------------------
|
||||
|
||||
//
|
||||
// PRIVATE
|
||||
//
|
||||
|
||||
const App = @import("app");
|
||||
const lifetime = @import("system/lifetime.zig");
|
||||
|
||||
//
|
||||
// PUBLIC
|
||||
//
|
||||
|
||||
pub const ShaderCache = @import("resource/shader_cache.zig");
|
||||
pub const PipelineCache = @import("resource/pipeline_cache.zig");
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub const plugin: App.plugin.Plugin = .{
|
||||
.name = "Cache",
|
||||
.build = build,
|
||||
};
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
fn build(
|
||||
_: *App.plugin.Plugin,
|
||||
app: *App,
|
||||
) !void {
|
||||
try app.schedules.add(App.stage.init, lifetime.init);
|
||||
try app.schedules.add(App.stage.deinit, lifetime.deinit);
|
||||
}
|
||||
92
src/plugins/cache/system/lifetime.zig
vendored
Normal file
92
src/plugins/cache/system/lifetime.zig
vendored
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
//! ----------------------------------------------------
|
||||
//! ----------------------------------------------------
|
||||
|
||||
const std = @import("std");
|
||||
const gtl = @import("gtl");
|
||||
const App = @import("app");
|
||||
const WGPUDevice = @import("../../device/resource/wgpu_device.zig");
|
||||
const ShaderCache = @import("../resource/shader_cache.zig");
|
||||
const PipelineCache = @import("../resource/pipeline_cache.zig");
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn init(app: *App) !void {
|
||||
// --- # ---
|
||||
const res = try app.resources.getMany(struct {
|
||||
device: *const WGPUDevice,
|
||||
});
|
||||
|
||||
// --- SHADER CACHE ---
|
||||
const shaders = try app.resources.getOrSet(ShaderCache.init(
|
||||
res.device.raw,
|
||||
app.alloc,
|
||||
));
|
||||
|
||||
// --- PIPELINE CACHE ---
|
||||
const pipelines = try app.resources.getOrSet(PipelineCache.init(
|
||||
shaders,
|
||||
res.device.queue,
|
||||
res.device.raw,
|
||||
app.alloc,
|
||||
));
|
||||
|
||||
// TODO: Remove or place it somewhere else, idk
|
||||
|
||||
// --- TEST ---
|
||||
_ = try pipelines.getOrCreate(.{});
|
||||
_ = try pipelines.getOrCreate(.{});
|
||||
|
||||
_ = try pipelines.getOrCreate(.{ .shader = .unlit });
|
||||
_ = try pipelines.getOrCreate(.{ .shader = .unlit });
|
||||
|
||||
{ // DEBUG
|
||||
std.debug.print("{s}┏━{s} PIPELINES\n", .{ gtl.ansi.blue, gtl.ansi.reset });
|
||||
for (pipelines.pipelines.items(), 0..) |entry, i| {
|
||||
// std.debug.print("\x1b[33m\x1b[0m {s:<12} {s}\n", .{ plugin.name, plugin.description });
|
||||
std.debug.print(
|
||||
\\{s}┃ ┏━{s} {}
|
||||
\\{s}┃ ┃ {s}Shader: {s}
|
||||
\\{s}┃ ┃ {s}Cull Mode: {s}
|
||||
\\{s}┃ ┃ {s}Blend Mode: {s}
|
||||
\\{s}┃ ┃ {s}Front Face: {s}
|
||||
\\{s}┃ ┃ {s}Topology: {s}
|
||||
\\
|
||||
, .{
|
||||
gtl.ansi.blue,
|
||||
gtl.ansi.reset,
|
||||
i,
|
||||
gtl.ansi.blue,
|
||||
gtl.ansi.reset,
|
||||
@tagName(entry.key.shader),
|
||||
gtl.ansi.blue,
|
||||
gtl.ansi.reset,
|
||||
@tagName(entry.key.cull_mode),
|
||||
gtl.ansi.blue,
|
||||
gtl.ansi.reset,
|
||||
@tagName(entry.key.blend_mode),
|
||||
gtl.ansi.blue,
|
||||
gtl.ansi.reset,
|
||||
@tagName(entry.key.front_face),
|
||||
gtl.ansi.blue,
|
||||
gtl.ansi.reset,
|
||||
@tagName(entry.key.topology),
|
||||
});
|
||||
std.debug.print("{s}┃ ┗━{s}\n", .{ gtl.ansi.blue, gtl.ansi.reset });
|
||||
}
|
||||
std.debug.print("{s}┗━{s}\n", .{ gtl.ansi.blue, gtl.ansi.reset });
|
||||
}
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn deinit(app: *App) !void {
|
||||
// --- # ---
|
||||
const res = try app.resources.getMany(struct {
|
||||
shaders: *ShaderCache,
|
||||
pipelines: *PipelineCache,
|
||||
});
|
||||
|
||||
// --- # ---
|
||||
res.shaders.deinit();
|
||||
res.pipelines.deinit();
|
||||
}
|
||||
52
src/plugins/common/component/material.zig
Normal file
52
src/plugins/common/component/material.zig
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
//! ----------------------------------------------------
|
||||
//! ----------------------------------------------------
|
||||
|
||||
const gtl = @import("gtl");
|
||||
const ShaderID = @import("../../cache/resource/shader_cache.zig").ShaderID;
|
||||
const Handle = gtl.Handle;
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub const Style = struct {
|
||||
albedo: @Vector(4, f32) = .{ 1, 1, 1, 1 },
|
||||
metallic: f32 = 0.0,
|
||||
roughness: f32 = 0.5,
|
||||
_pad0: [2]f32 = .{ 0, 0 },
|
||||
};
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub const Unique = struct {
|
||||
shader: ShaderID = .pbr,
|
||||
|
||||
front_face: enum {
|
||||
cw,
|
||||
ccw,
|
||||
} = .ccw,
|
||||
|
||||
cull_mode: enum {
|
||||
back,
|
||||
front,
|
||||
none,
|
||||
} = .back,
|
||||
|
||||
topology: enum {
|
||||
triangle_list,
|
||||
point_list,
|
||||
line_list,
|
||||
} = .triangle_list,
|
||||
|
||||
blend_mode: enum {
|
||||
none,
|
||||
alpha,
|
||||
additive,
|
||||
multiply,
|
||||
} = .none,
|
||||
};
|
||||
|
||||
//
|
||||
// FIELDS
|
||||
//
|
||||
|
||||
style: Style = .{},
|
||||
unique: Unique = .{},
|
||||
8
src/plugins/common/root.zig
Normal file
8
src/plugins/common/root.zig
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
//! ----------------------------------------------------
|
||||
//! ----------------------------------------------------
|
||||
|
||||
//
|
||||
// COMPONENTS
|
||||
//
|
||||
|
||||
pub const Material = @import("component/material.zig");
|
||||
28
src/plugins/renderer/root.zig
Normal file
28
src/plugins/renderer/root.zig
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
//! ----------------------------------------------------
|
||||
//! ----------------------------------------------------
|
||||
|
||||
//
|
||||
// PRIVATE
|
||||
//
|
||||
|
||||
const App = @import("app");
|
||||
|
||||
//
|
||||
// PUBLIC
|
||||
//
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub const plugin: App.plugin.Plugin = .{
|
||||
.name = "Renderer",
|
||||
.build = build,
|
||||
};
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
fn build(
|
||||
_: *App.plugin.Plugin,
|
||||
app: *App,
|
||||
) !void {
|
||||
_ = app;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue