Prepare shaders for later use (Pipelines)
This commit is contained in:
parent
807e9c91fd
commit
660065c556
9 changed files with 202 additions and 5 deletions
17
src/assets/shaders/pbr.wgsl
Normal file
17
src/assets/shaders/pbr.wgsl
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
@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);
|
||||
}
|
||||
|
|
@ -3,3 +3,4 @@ pub const Camera = @import("camera.zig");
|
|||
|
||||
// --- MATERIALS ---
|
||||
pub const PBRMaterial = @import("pbr_material.zig");
|
||||
pub const UnlitMaterial = @import("unlit_material.zig");
|
||||
|
|
|
|||
0
src/component/unlit_material.zig
Normal file
0
src/component/unlit_material.zig
Normal file
|
|
@ -4,6 +4,7 @@
|
|||
const App = @import("app");
|
||||
const system = @import("system/root.zig");
|
||||
const resource = @import("resource/root.zig");
|
||||
const component = @import("component/root.zig");
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
|
|
@ -23,11 +24,21 @@ fn build(
|
|||
try ctx.app.resources.set(resource.Instance{});
|
||||
try ctx.app.resources.set(resource.Device{});
|
||||
try ctx.app.resources.set(resource.window{});
|
||||
try ctx.app.resources.set(resource.Cache.init(ctx.app.alloc));
|
||||
|
||||
// --- RENDER ---
|
||||
try ctx.app.resources.set(resource.RenderFrame{});
|
||||
try ctx.app.resources.set(resource.RenderQueue.init(ctx.app.alloc));
|
||||
|
||||
{ // TEST
|
||||
try ctx.app.world.spawn(.{
|
||||
component.PBRMaterial{},
|
||||
});
|
||||
try ctx.app.world.spawn(.{
|
||||
component.UnlitMaterial{},
|
||||
});
|
||||
}
|
||||
|
||||
// --- INIT ---
|
||||
try ctx.app.schedules.addMany(App.stage.Init, &.{
|
||||
system.instance.init,
|
||||
|
|
@ -35,12 +46,21 @@ fn build(
|
|||
system.device.init,
|
||||
|
||||
system.frame.begin,
|
||||
system.frame.prepare,
|
||||
});
|
||||
|
||||
// --- DEINIT ---
|
||||
try ctx.app.schedules.addMany(App.stage.Deinit, &.{
|
||||
system.frame.end,
|
||||
|
||||
struct { // TODO: Clean this shit up 🥀
|
||||
pub fn sys(_ctx: App.scheduler.Context) !void {
|
||||
if (_ctx.app.resources.getPtr(resource.Cache)) |cache| {
|
||||
cache.deinit();
|
||||
}
|
||||
}
|
||||
}.sys,
|
||||
|
||||
system.device.deinit,
|
||||
system.window.deinit,
|
||||
system.instance.deinit,
|
||||
|
|
|
|||
|
|
@ -2,9 +2,21 @@ const std = @import("std");
|
|||
const App = @import("app");
|
||||
const Platform = @import("platform_plugin");
|
||||
|
||||
//
|
||||
// PUBLIC
|
||||
//
|
||||
|
||||
pub const plugin = @import("plugin.zig").plugin;
|
||||
pub const system = @import("system/root.zig");
|
||||
pub const resource = @import("resource/root.zig");
|
||||
pub const template = @import("template/root.zig");
|
||||
|
||||
//
|
||||
// EMBEDED
|
||||
//
|
||||
|
||||
pub const PBRShader = @embedFile("assets/shaders/pbr.wgsl");
|
||||
pub const UnlitShader = @embedFile("assets/shaders/pbr.wgsl");
|
||||
|
||||
test "Main" {
|
||||
// --- APP ---
|
||||
|
|
|
|||
53
src/resource/cache.zig
Normal file
53
src/resource/cache.zig
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
//! ----------------------------------------------------
|
||||
//! ----------------------------------------------------
|
||||
|
||||
const std = @import("std");
|
||||
const App = @import("app");
|
||||
const wgpu = @import("wgpu");
|
||||
const Registry = @import("../template/registry.zig").Registry;
|
||||
const Handle = App.template.Handle;
|
||||
const Self = @This();
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub const ShaderID = union(enum) {
|
||||
pbr,
|
||||
unlit,
|
||||
custom: Handle([]const u8),
|
||||
};
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub const PipelineKey = struct {
|
||||
shader: ShaderID,
|
||||
};
|
||||
|
||||
//
|
||||
// FIELDS
|
||||
//
|
||||
|
||||
shaders: Registry(ShaderID, *wgpu.WGPUShaderModuleImpl),
|
||||
pipelines: Registry(PipelineKey, *wgpu.WGPURenderPipelineImpl),
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn init(alloc: std.mem.Allocator) Self {
|
||||
return .{
|
||||
.shaders = .init(alloc),
|
||||
.pipelines = .init(alloc),
|
||||
};
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn deinit(self: *Self) void {
|
||||
{ // SHADERS
|
||||
var it = self.shaders.iterator();
|
||||
while (it.next()) |entry| {
|
||||
wgpu.wgpuShaderModuleRelease(entry.value.*);
|
||||
}
|
||||
}
|
||||
|
||||
self.shaders.deinit();
|
||||
self.pipelines.deinit();
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
pub const Instance = @import("instance.zig");
|
||||
pub const Device = @import("device.zig");
|
||||
pub const window = @import("window.zig");
|
||||
pub const Cache = @import("cache.zig");
|
||||
|
||||
// --- DRAW ---
|
||||
pub const RenderFrame = @import("render_frame.zig");
|
||||
|
|
|
|||
|
|
@ -5,10 +5,15 @@ const std = @import("std");
|
|||
const sdl = @import("sdl");
|
||||
const wgpu = @import("wgpu");
|
||||
const App = @import("app");
|
||||
const component = @import("../component/root.zig");
|
||||
|
||||
const Window = @import("../resource/window.zig");
|
||||
const Device = @import("../resource/device.zig");
|
||||
const RenderFrame = @import("../resource/render_frame.zig");
|
||||
const Cache = @import("../resource/cache.zig");
|
||||
|
||||
const PBRShader = @import("../renderer.zig").PBRShader;
|
||||
const UnlitShader = @import("../renderer.zig").UnlitShader;
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
|
|
@ -102,3 +107,76 @@ pub fn end(ctx: App.scheduler.Context) !void {
|
|||
// --- DEBUG ---
|
||||
sdl.SDL_Delay(2000); // TODO: Remove
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn prepare(ctx: App.scheduler.Context) !void {
|
||||
// --- GET RESOURCES ---
|
||||
const res = try ctx.app.resources.getMany(struct {
|
||||
window: *Window,
|
||||
device: *Device,
|
||||
cache: *Cache,
|
||||
});
|
||||
|
||||
// 1) Prepare Shaders
|
||||
// 2) Prepare Pipelines
|
||||
|
||||
// --- QUERY ---
|
||||
{
|
||||
var query = ctx.app.world.query(struct {
|
||||
pbr_material: ?*component.PBRMaterial,
|
||||
unlit_material: ?*component.UnlitMaterial,
|
||||
}, .{});
|
||||
while (query.next()) |e| {
|
||||
|
||||
// --- GET SHADER ID ---
|
||||
const shader_id: Cache.ShaderID = blk: {
|
||||
if (e.pbr_material) |_| break :blk .pbr;
|
||||
if (e.unlit_material) |_| break :blk .unlit;
|
||||
break :blk .unlit;
|
||||
};
|
||||
|
||||
// --- ENSURE SHADER MODULE ---
|
||||
if (!res.cache.shaders.contains(shader_id)) {
|
||||
// --- GET SHADER CODE ---
|
||||
const shader_code = switch (shader_id) {
|
||||
.pbr => PBRShader,
|
||||
.unlit => UnlitShader,
|
||||
else => return error.UnknownShaderCode, // TODO: Yes
|
||||
};
|
||||
|
||||
// --- WGSL DESC ---
|
||||
var wgsl_desc: wgpu.WGPUShaderSourceWGSL = .{
|
||||
.chain = .{ .sType = wgpu.WGPUSType_ShaderSourceWGSL },
|
||||
.code = .{ .data = shader_code, .length = wgpu.WGPU_STRLEN },
|
||||
};
|
||||
|
||||
// --- SHADER MODULE ---
|
||||
const module = wgpu.wgpuDeviceCreateShaderModule(
|
||||
res.device.raw,
|
||||
&wgpu.WGPUShaderModuleDescriptor{
|
||||
.label = .{
|
||||
.data = @tagName(shader_id),
|
||||
.length = wgpu.WGPU_STRLEN,
|
||||
},
|
||||
.nextInChain = &wgsl_desc.chain,
|
||||
},
|
||||
) orelse return error.ShaderModule;
|
||||
errdefer wgpu.wgpuShaderModuleRelease(module);
|
||||
|
||||
// --- ADD NEW ---
|
||||
try res.cache.shaders.put(
|
||||
shader_id,
|
||||
module,
|
||||
);
|
||||
|
||||
// TODO: Only show on debug mode
|
||||
std.debug.print("\x1b[35m┣━ SHADER\x1b[0m {s}\n", .{@tagName(
|
||||
shader_id,
|
||||
)});
|
||||
}
|
||||
|
||||
// TODO: Pipelines
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
const std = @import("std");
|
||||
const App = @import("app");
|
||||
const Handle = App.template.Handle;
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
|
|
@ -22,6 +23,7 @@ pub fn Registry(
|
|||
pub const Entry = struct {
|
||||
key: K,
|
||||
value: V,
|
||||
handle: Handle(V),
|
||||
};
|
||||
|
||||
//
|
||||
|
|
@ -29,7 +31,7 @@ pub fn Registry(
|
|||
//
|
||||
|
||||
meta: std.ArrayList(Metadata),
|
||||
lookup: std.AutoHashMap(K, usize),
|
||||
lookup: std.AutoHashMap(K, Handle(V)),
|
||||
entries: std.ArrayList(Entry),
|
||||
alloc: std.mem.Allocator,
|
||||
|
||||
|
|
@ -110,13 +112,20 @@ pub fn Registry(
|
|||
value: V,
|
||||
metadata: Metadata,
|
||||
) !void {
|
||||
try self.entries.append(self.alloc, .{ .key = key, .value = value });
|
||||
const handle: Handle(V) = .{
|
||||
.idx = @intCast(self.entries.items.len),
|
||||
};
|
||||
|
||||
try self.entries.append(self.alloc, .{ .key = key, .value = value, .handle = handle });
|
||||
errdefer _ = self.entries.swapRemove(self.entries.items.len - 1);
|
||||
|
||||
try self.meta.append(self.alloc, metadata);
|
||||
errdefer _ = self.meta.swapRemove(self.meta.items.len - 1);
|
||||
|
||||
try self.lookup.put(key, self.entries.items.len - 1);
|
||||
try self.lookup.put(
|
||||
key,
|
||||
handle,
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -184,8 +193,14 @@ pub fn Registry(
|
|||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn getEntry(self: Self, key: K) ?*const Entry {
|
||||
const idx = self.lookup.get(key) orelse return null;
|
||||
return &self.entries.items[idx];
|
||||
const handle = self.lookup.get(key) orelse return null;
|
||||
return &self.entries.items[@intCast(handle.idx)];
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn getHandle(self: *Self, key: K) ?Handle(V) {
|
||||
return self.lookup.get(key);
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue