NYXEngine/src/plugins/cache/resource/pipeline_cache.zig.old

333 lines
12 KiB
Zig
Raw Normal View History

//! ----------------------------------------------------
//! TODO: Move [materials, materials_gpu and GPUMaterial somewhere else]
//! Depricated
//! ----------------------------------------------------
const std = @import("std");
const gtl = @import("gtl");
const wgpu = @import("wgpu");
const Self = @This();
const Material = @import("../../renderer/template/material.zig");
const ShaderCache = @import("shader_cache.zig");
const ShaderID = ShaderCache.ShaderID;
const Vertex = @import("mesh_cache.zig").Vertex;
/// ----------------------------------------------------
/// ----------------------------------------------------
pub const GPUPipeline = struct {
raw: *wgpu.WGPURenderPipelineImpl,
layout: *wgpu.WGPUPipelineLayoutImpl,
bind_group_layouts: [3]*wgpu.WGPUBindGroupLayoutImpl,
};
/// ----------------------------------------------------
/// ----------------------------------------------------
pub const GPUMaterial = struct {
buffer: *wgpu.WGPUBufferImpl,
bind_group: *wgpu.WGPUBindGroupImpl,
dirty: bool = true,
};
/// ----------------------------------------------------
/// TODO: Mabe mabe switch to it, someday
/// ----------------------------------------------------
pub const GPUUniform = struct {
buffer: wgpu.WGPUBuffer,
bind_group: wgpu.WGPUBindGroup,
dirty: bool = true,
};
//
// FIELDS
//
pipelines: gtl.KeyedSlotMap(Material.Unique, GPUPipeline),
materials: gtl.SlotMap(Material),
materials_gpu: gtl.KeyedSlotMap(gtl.Handle(Material), GPUMaterial),
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),
2026-07-29 15:56:52 +01:00
.materials = .init(alloc),
.materials_gpu = .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.wgpuPipelineLayoutRelease(entry.value.layout);
wgpu.wgpuRenderPipelineRelease(entry.value.raw);
}
2026-07-29 15:56:52 +01:00
// --- FREE MATERIALS ---
for (self.materials_gpu.items()) |entry| {
wgpu.wgpuBufferRelease(entry.value.buffer);
wgpu.wgpuBindGroupRelease(entry.value.bind_group);
2026-07-29 15:56:52 +01:00
}
// --- # ---
self.pipelines.deinit();
2026-07-29 15:56:52 +01:00
self.materials.deinit();
self.materials_gpu.deinit();
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn getOrCreateMaterial(
self: *Self,
material_handle: gtl.Handle(Material),
) !*GPUMaterial {
return try self.materials_gpu.getOrPut(
material_handle,
blk: {
// --- # ---
if (self.materials_gpu.getByKey(material_handle)) |v| return v;
const material = self.materials.get(material_handle) orelse return error.MaterialNotFound;
// --- ENSURE PIPELINE ---
const pipeline = try self.getOrCreatePipeline(material);
// --- UNIFORM ---
const uniform = wgpu.wgpuDeviceCreateBuffer(self.device, &wgpu.WGPUBufferDescriptor{
.usage = wgpu.WGPUBufferUsage_CopyDst | wgpu.WGPUBufferUsage_Uniform,
.size = @sizeOf(Material.Style),
}) orelse return error.Buffer;
// --- WRITE TO UNIFORM ---
wgpu.wgpuQueueWriteBuffer(
self.queue,
uniform,
0,
&material.style,
@sizeOf(Material.Style),
);
// --- BIND GROUP ---
const bind_group = wgpu.wgpuDeviceCreateBindGroup(self.device, &wgpu.WGPUBindGroupDescriptor{
.layout = pipeline.bind_group_layouts[0],
.entryCount = 1,
.entries = &[_]wgpu.WGPUBindGroupEntry{
.{
.binding = 0,
.buffer = uniform,
.offset = 0,
.size = @sizeOf(Material.Style),
},
},
}) orelse return error.BindGroup;
// --- RESULT ---
break :blk .{
.buffer = uniform,
.bind_group = bind_group,
.dirty = false,
};
},
);
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn getOrCreatePipeline(
self: *Self,
material: *const Material,
) !*GPUPipeline {
return try self.pipelines.getOrPut(material.unique, blk: {
// --- # ---
if (self.pipelines.getByKey(material.unique)) |v| return v;
//
// LAYOUTS
//
// --- CAMERA ---
const camera_layout = wgpu.wgpuDeviceCreateBindGroupLayout(self.device, &wgpu.WGPUBindGroupLayoutDescriptor{
.entryCount = 1,
.entries = &[_]wgpu.WGPUBindGroupLayoutEntry{
.{
.binding = 0,
.visibility = wgpu.WGPUShaderStage_Vertex | wgpu.WGPUShaderStage_Fragment,
.buffer = .{
.type = wgpu.WGPUBufferBindingType_Uniform,
.minBindingSize = @sizeOf(Material.Style),
.hasDynamicOffset = 0,
},
},
},
}) orelse return error.BindGroupLayout;
// --- MODEL ---
const model_layout = wgpu.wgpuDeviceCreateBindGroupLayout(self.device, &wgpu.WGPUBindGroupLayoutDescriptor{
.entryCount = 1,
.entries = &[_]wgpu.WGPUBindGroupLayoutEntry{
.{
.binding = 0,
.visibility = wgpu.WGPUShaderStage_Vertex | wgpu.WGPUShaderStage_Fragment,
.buffer = .{
.type = wgpu.WGPUBufferBindingType_Uniform,
.minBindingSize = @sizeOf(Material.Style),
.hasDynamicOffset = 0,
},
},
},
}) orelse return error.BindGroupLayout;
// --- MATERIAL ---
const material_layout = wgpu.wgpuDeviceCreateBindGroupLayout(self.device, &wgpu.WGPUBindGroupLayoutDescriptor{
.entryCount = 1,
.entries = &[_]wgpu.WGPUBindGroupLayoutEntry{
.{
.binding = 0,
.visibility = wgpu.WGPUShaderStage_Vertex | wgpu.WGPUShaderStage_Fragment,
.buffer = .{
.type = wgpu.WGPUBufferBindingType_Uniform,
.minBindingSize = @sizeOf(Material.Style),
.hasDynamicOffset = 0,
},
},
},
}) orelse return error.BindGroupLayout;
var bind_group_layouts = [_]wgpu.WGPUBindGroupLayout{
camera_layout,
model_layout,
material_layout,
};
// --- PIPELINE LAYOUT ---
const pipeline_layout = wgpu.wgpuDeviceCreatePipelineLayout(
self.device,
&wgpu.WGPUPipelineLayoutDescriptor{
.bindGroupLayoutCount = 3,
.bindGroupLayouts = &bind_group_layouts,
},
) orelse return error.Layout;
// --- CREATE PIPELINE ---
const pipeline = try self.createPipeline(
material.unique,
pipeline_layout,
);
// --- RESULT ---
break :blk .{
.raw = pipeline,
.layout = pipeline_layout,
.bind_group_layouts = .{
camera_layout,
model_layout,
material_layout,
},
};
});
}
/// ----------------------------------------------------
/// ----------------------------------------------------
fn createPipeline(
self: *Self,
key: Material.Unique,
layout: *wgpu.WGPUPipelineLayoutImpl,
) !*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 },
.layout = layout,
.vertex = .{
.module = shader_module.raw,
.entryPoint = .{ .data = "vs_main", .length = wgpu.WGPU_STRLEN },
2026-07-29 01:15:31 +01:00
.bufferCount = 1,
.buffers = &wgpu.WGPUVertexBufferLayout{
.attributeCount = 3,
.attributes = &[_]wgpu.WGPUVertexAttribute{ // TODO: Mabe mabe allow for custom, mabe mabe later tho
.{
.format = wgpu.WGPUVertexFormat_Float32x3,
.offset = @offsetOf(Vertex, "position"),
.shaderLocation = 0,
},
.{
.format = wgpu.WGPUVertexFormat_Float32x3,
.offset = @offsetOf(Vertex, "normal"),
.shaderLocation = 1,
},
.{
.format = wgpu.WGPUVertexFormat_Float32x2,
.offset = @offsetOf(Vertex, "uv"),
.shaderLocation = 2,
},
2026-07-29 01:15:31 +01:00
},
.arrayStride = @sizeOf(Vertex),
2026-07-29 01:15:31 +01:00
.stepMode = wgpu.WGPUVertexStepMode_Vertex,
},
},
.fragment = &wgpu.WGPUFragmentState{
.module = shader_module.raw,
.entryPoint = .{ .data = "fs_main", .length = wgpu.WGPU_STRLEN },
.targetCount = 1,
.targets = &wgpu.WGPUColorTargetState{
2026-07-29 01:15:31 +01:00
.format = 28, // FIX: Use proper format
.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;
};
}