objloader, ozz, sdl3 all updated

This commit is contained in:
peterino2 2025-10-13 20:57:04 -07:00
parent 774feb364d
commit de6ccd211b
9 changed files with 125 additions and 117 deletions

View File

@ -11,11 +11,11 @@ pub fn loadObjBytes(bytes: []const u8, allocator: std.mem.Allocator) !ObjContent
} }
// Higher level file functions. // Higher level file functions.
pub fn loadFileAlloc(filename: []const u8, comptime alignment: usize, allocator: std.mem.Allocator) ![]const u8 { pub fn loadFileAlloc(filename: []const u8, comptime alignment: ?std.mem.Alignment, allocator: std.mem.Allocator) ![]const u8 {
var file = try std.fs.cwd().openFile(filename, .{ .mode = .read_only }); var file = try std.fs.cwd().openFile(filename, .{ .mode = .read_only });
const filesize = (try file.stat()).size; const filesize = (try file.stat()).size;
const buffer: []u8 = try allocator.alignedAlloc(u8, alignment, filesize); const buffer: []u8 = try allocator.alignedAlloc(u8, alignment, filesize);
try file.reader().readNoEof(buffer); _ = try file.read(buffer);
return buffer; return buffer;
} }
@ -368,9 +368,10 @@ pub fn fileIntoLines(file_contents: []const u8) std.mem.SplitIterator(u8, .seque
const ObjContents = struct { const ObjContents = struct {
meshes: std.ArrayList(ObjMesh), meshes: std.ArrayList(ObjMesh),
allocator: std.mem.Allocator,
pub fn load(file_path: []const u8, allocator: std.mem.Allocator) !ObjContents { pub fn load(file_path: []const u8, allocator: std.mem.Allocator) !ObjContents {
const file_contents = try loadFileAlloc(file_path, 1, allocator); const file_contents = try loadFileAlloc(file_path, .@"1", allocator);
defer allocator.free(file_contents); defer allocator.free(file_contents);
return try loadFromBytes(file_contents, allocator); return try loadFromBytes(file_contents, allocator);
@ -378,7 +379,8 @@ const ObjContents = struct {
pub fn loadFromBytes(file_contents: []const u8, allocator: std.mem.Allocator) !ObjContents { pub fn loadFromBytes(file_contents: []const u8, allocator: std.mem.Allocator) !ObjContents {
var self = ObjContents{ var self = ObjContents{
.meshes = std.ArrayList(ObjMesh).init(allocator), .meshes = .{},
.allocator = allocator,
}; };
var mesh = try ObjMesh.init("root", allocator); var mesh = try ObjMesh.init("root", allocator);
@ -389,7 +391,7 @@ const ObjContents = struct {
if (result == .object) { if (result == .object) {
if (mesh.v_positions.items.len > 0) { if (mesh.v_positions.items.len > 0) {
try self.meshes.append(mesh); try self.meshes.append(allocator, mesh);
mesh = try ObjMesh.init(result.object, allocator); mesh = try ObjMesh.init(result.object, allocator);
} else { } else {
try mesh.setName(result.object); try mesh.setName(result.object);
@ -412,7 +414,7 @@ const ObjContents = struct {
try mesh.v_uvs.append(mesh.allocator, result.texture); try mesh.v_uvs.append(mesh.allocator, result.texture);
} }
} }
try self.meshes.append(mesh); try self.meshes.append(self.allocator, mesh);
return self; return self;
} }
@ -420,7 +422,7 @@ const ObjContents = struct {
for (self.meshes.items, 0..) |_, i| { for (self.meshes.items, 0..) |_, i| {
self.meshes.items[i].deinit(); self.meshes.items[i].deinit();
} }
self.meshes.deinit(); self.meshes.deinit(self.allocator);
} }
}; };
@ -435,7 +437,7 @@ test "load_monkey_full" {
test "parse_monkey" { test "parse_monkey" {
const monkey_obj_path = "./content/monkey.obj"; const monkey_obj_path = "./content/monkey.obj";
const file_contents = try loadFileAlloc(monkey_obj_path, 1, std.testing.allocator); const file_contents = try loadFileAlloc(monkey_obj_path, .@"1", std.testing.allocator);
defer std.testing.allocator.free(file_contents); defer std.testing.allocator.free(file_contents);
var lines = fileIntoLines(file_contents); var lines = fileIntoLines(file_contents);
var count: u32 = 0; var count: u32 = 0;

24
lib/ozz/build.zig vendored
View File

@ -142,18 +142,14 @@ pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{}); const target = b.standardTargetOptions(.{});
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false; const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
const ozz_cpp = if (static_build) const ozz_cpp = b.addLibrary(.{
b.addStaticLibrary(.{ .linkage = if (static_build) .static else .dynamic,
.name = "ozz_cpp", .name = "ozz_cpp",
.root_module = b.createModule(.{
.target = target, .target = target,
.optimize = optimize, .optimize = optimize,
}) }),
else });
b.addSharedLibrary(.{
.name = "ozz_cpp",
.target = target,
.optimize = optimize,
});
b.installArtifact(ozz_cpp); b.installArtifact(ozz_cpp);
@ -206,9 +202,11 @@ pub fn build(b: *std.Build) void {
const tests = b.addTest(.{ const tests = b.addTest(.{
.name = "ozz-tests", .name = "ozz-tests",
.root_source_file = b.path("tests/test.zig"), .root_module = b.createModule(.{
.target = target, .root_source_file = b.path("tests/test.zig"),
.optimize = optimize, .target = target,
.optimize = optimize,
}),
}); });
b.installArtifact(tests); b.installArtifact(tests);

50
lib/ozz/src/ozz.zig vendored
View File

@ -13,7 +13,7 @@ pub const Skeleton = opaque {
} }
pub fn loadFromBytes(self: *@This(), bytes: []const u8) void { pub fn loadFromBytes(self: *@This(), bytes: []const u8) void {
LoadSkeletonFromBytes_c(self, @constCast(@ptrCast(bytes.ptr)), bytes.len); LoadSkeletonFromBytes_c(self, @ptrCast(@constCast(bytes.ptr)), bytes.len);
} }
pub fn getJointsList(self: *@This()) []const [*c]const u8 { pub fn getJointsList(self: *@This()) []const [*c]const u8 {
@ -39,14 +39,14 @@ pub const Skeleton = opaque {
DestroySkeleton_c(@ptrCast(self)); DestroySkeleton_c(@ptrCast(self));
} }
pub extern fn SkeletonJointRestPoses_c(s: ?*anyopaque) callconv(.C) OpaqueSpan; pub extern fn SkeletonJointRestPoses_c(s: ?*anyopaque) callconv(.c) OpaqueSpan;
pub extern fn SkeletonNumJoints_c(s: ?*anyopaque) callconv(.C) c_int; pub extern fn SkeletonNumJoints_c(s: ?*anyopaque) callconv(.c) c_int;
pub extern fn SkeletonNumSoaJoints_c(s: ?*anyopaque) callconv(.C) c_int; pub extern fn SkeletonNumSoaJoints_c(s: ?*anyopaque) callconv(.c) c_int;
pub extern fn SkeletonGetJointsList_c(s: ?*anyopaque) callconv(.C) OpaqueSpan; pub extern fn SkeletonGetJointsList_c(s: ?*anyopaque) callconv(.c) OpaqueSpan;
pub extern fn CreateSkeleton_c() callconv(.C) ?*anyopaque; pub extern fn CreateSkeleton_c() callconv(.c) ?*anyopaque;
pub extern fn DestroySkeleton_c(target: ?*anyopaque) callconv(.C) void; pub extern fn DestroySkeleton_c(target: ?*anyopaque) callconv(.c) void;
pub extern fn LoadSkeletonFromFile_c(s: ?*anyopaque, path: [*c]const u8) callconv(.C) void; pub extern fn LoadSkeletonFromFile_c(s: ?*anyopaque, path: [*c]const u8) callconv(.c) void;
pub extern fn LoadSkeletonFromBytes_c(s: ?*anyopaque, size: ?*anyopaque, size: usize) void; pub extern fn LoadSkeletonFromBytes_c(s: ?*anyopaque, size: ?*anyopaque, size: usize) void;
}; };
@ -61,7 +61,7 @@ pub const Animation = opaque {
} }
pub fn loadFromBytes(self: *@This(), bytes: []const u8) void { pub fn loadFromBytes(self: *@This(), bytes: []const u8) void {
LoadAnimationFromBytes_c(self, @constCast(@ptrCast(bytes.ptr)), bytes.len); LoadAnimationFromBytes_c(self, @ptrCast(@constCast(bytes.ptr)), bytes.len);
} }
pub fn destroy(self: *@This()) void { pub fn destroy(self: *@This()) void {
@ -72,11 +72,11 @@ pub const Animation = opaque {
return AnimationGetDuration_c(@ptrCast(self)); return AnimationGetDuration_c(@ptrCast(self));
} }
pub extern fn AnimationGetDuration_c(s: ?*anyopaque) callconv(.C) f32; pub extern fn AnimationGetDuration_c(s: ?*anyopaque) callconv(.c) f32;
pub extern fn CreateAnimation_c() callconv(.C) ?*anyopaque; pub extern fn CreateAnimation_c() callconv(.c) ?*anyopaque;
pub extern fn LoadAnimationFromFile_c(s: ?*anyopaque, path: [*c]const u8) void; pub extern fn LoadAnimationFromFile_c(s: ?*anyopaque, path: [*c]const u8) void;
pub extern fn LoadAnimationFromBytes_c(s: ?*anyopaque, size: ?*anyopaque, size: usize) void; pub extern fn LoadAnimationFromBytes_c(s: ?*anyopaque, size: ?*anyopaque, size: usize) void;
pub extern fn DestroyAnimation_c(target: ?*anyopaque) callconv(.C) void; pub extern fn DestroyAnimation_c(target: ?*anyopaque) callconv(.c) void;
}; };
pub const SamplingJob = extern struct { pub const SamplingJob = extern struct {
@ -151,20 +151,20 @@ pub const SamplingJobContext = opaque {
DestroySamplingJobContext_c(self); DestroySamplingJobContext_c(self);
} }
pub extern fn CreateSamplingJobContextCount_c(c_int) callconv(.C) ?*anyopaque; pub extern fn CreateSamplingJobContextCount_c(c_int) callconv(.c) ?*anyopaque;
pub extern fn CreateSamplingJobContext_c() callconv(.C) ?*anyopaque; pub extern fn CreateSamplingJobContext_c() callconv(.c) ?*anyopaque;
pub extern fn DestroySamplingJobContext_c(?*anyopaque) callconv(.C) void; pub extern fn DestroySamplingJobContext_c(?*anyopaque) callconv(.c) void;
pub extern fn SamplingJobContext_Resize_c(?*anyopaque, c_int) callconv(.C) void; pub extern fn SamplingJobContext_Resize_c(?*anyopaque, c_int) callconv(.c) void;
pub extern fn SamplingJobContext_Invalidate_c(?*anyopaque) callconv(.C) void; pub extern fn SamplingJobContext_Invalidate_c(?*anyopaque) callconv(.c) void;
pub extern fn SamplingJobContext_MaxTracks_c(?*anyopaque) callconv(.C) c_int; pub extern fn SamplingJobContext_MaxTracks_c(?*anyopaque) callconv(.c) c_int;
pub extern fn SamplingJobContext_MaxSoaTracks_c(?*anyopaque) callconv(.C) c_int; pub extern fn SamplingJobContext_MaxSoaTracks_c(?*anyopaque) callconv(.c) c_int;
}; };
pub extern fn testFunc() callconv(.C) void; pub extern fn testFunc() callconv(.c) void;
pub extern fn startupOzz() callconv(.C) void; pub extern fn startupOzz() callconv(.c) void;
pub extern fn shutdownOzz() callconv(.C) void; pub extern fn shutdownOzz() callconv(.c) void;
pub const SimdFloat4 = @Vector(4, f32); pub const SimdFloat4 = @Vector(4, f32);
@ -276,7 +276,7 @@ pub const LocalToModelJob = extern struct {
pub fn run(self: *@This()) bool { pub fn run(self: *@This()) bool {
return LocalToModelJob_Run_c(@ptrCast(self)); return LocalToModelJob_Run_c(@ptrCast(self));
} }
pub extern fn LocalToModelJob_Run_c(?*anyopaque) callconv(.C) bool; pub extern fn LocalToModelJob_Run_c(?*anyopaque) callconv(.c) bool;
}; };
pub const Layer = extern struct { pub const Layer = extern struct {
@ -357,8 +357,8 @@ pub const BlendingJob = extern struct {
return BlendingJob_Run_c(@ptrCast(self)); return BlendingJob_Run_c(@ptrCast(self));
} }
pub extern fn BlendingJob_Validate_c(?*anyopaque) callconv(.C) bool; pub extern fn BlendingJob_Validate_c(?*anyopaque) callconv(.c) bool;
pub extern fn BlendingJob_Run_c(?*anyopaque) callconv(.C) bool; pub extern fn BlendingJob_Run_c(?*anyopaque) callconv(.c) bool;
}; };
pub const std = @import("std"); pub const std = @import("std");

10
lib/packer/build.zig vendored
View File

@ -23,10 +23,12 @@ pub fn build(b: *std.Build) void {
mod.addImport("p2", p2mod); mod.addImport("p2", p2mod);
const test_exe = b.addTest(.{ const test_exe = b.addTest(.{
.target = target, .root_module = b.createModule(.{
.optimize = optimize, .target = target,
.root_source_file = b.path("tests/test.zig"), .optimize = optimize,
// .link_libc = true, .root_source_file = b.path("tests/test.zig"),
// .link_libc = true,
}),
}); });
test_exe.root_module.addImport("packer", mod); test_exe.root_module.addImport("packer", mod);
test_exe.root_module.addImport("p2", p2mod); test_exe.root_module.addImport("p2", p2mod);

View File

@ -4,7 +4,7 @@
const std = @import("std"); const std = @import("std");
pub const version: std.SemanticVersion = .{ .major = 3, .minor = 2, .patch = 10 }; pub const version: std.SemanticVersion = .{ .major = 3, .minor = 2, .patch = 10 };
const formatted_version = std.fmt.comptimePrint("SDL3-{}", .{version}); const formatted_version = std.fmt.comptimePrint("SDL3-{any}", .{version});
pub const vendor_info = "https://github.com/castholm/SDL 0.2.1"; pub const vendor_info = "https://github.com/castholm/SDL 0.2.1";
pub const revision = formatted_version ++ " (" ++ vendor_info ++ ")"; pub const revision = formatted_version ++ " (" ++ vendor_info ++ ")";
@ -610,7 +610,8 @@ pub fn build(b: *std.Build) void {
sdl_mod.addSystemIncludePath(path); sdl_mod.addSystemIncludePath(path);
} }
var sdl_c_flags: std.BoundedArray([]const u8, common_c_flags.len + 3) = .{}; var sdl_c_flags = std.ArrayList([]const u8).initCapacity(b.allocator, common_c_flags.len + 3) catch unreachable;
sdl_c_flags.appendSliceAssumeCapacity(&common_c_flags); sdl_c_flags.appendSliceAssumeCapacity(&common_c_flags);
if (sdl_lib.linkage.? == .dynamic) { if (sdl_lib.linkage.? == .dynamic) {
sdl_c_flags.appendAssumeCapacity("-fvisibility=hidden"); sdl_c_flags.appendAssumeCapacity("-fvisibility=hidden");
@ -627,7 +628,7 @@ pub fn build(b: *std.Build) void {
} }
sdl_mod.addCSourceFiles(.{ sdl_mod.addCSourceFiles(.{
.flags = sdl_c_flags.slice(), .flags = sdl_c_flags.items,
.files = &.{ .files = &.{
"src/SDL.c", "src/SDL.c",
"src/SDL_assert.c", "src/SDL_assert.c",
@ -800,7 +801,7 @@ pub fn build(b: *std.Build) void {
switch (sdl_lib.linkage.?) { switch (sdl_lib.linkage.?) {
.static => { .static => {
sdl_mod.addCSourceFiles(.{ sdl_mod.addCSourceFiles(.{
.flags = sdl_c_flags.slice(), .flags = sdl_c_flags.items,
.files = &sdl_uclibc_c_files, .files = &sdl_uclibc_c_files,
}); });
}, },
@ -838,7 +839,7 @@ pub fn build(b: *std.Build) void {
if (windows) { if (windows) {
sdl_mod.addCSourceFiles(.{ sdl_mod.addCSourceFiles(.{
.flags = sdl_c_flags.slice(), .flags = sdl_c_flags.items,
.files = &.{ .files = &.{
"src/audio/dummy/SDL_dummyaudio.c", "src/audio/dummy/SDL_dummyaudio.c",
"src/audio/disk/SDL_diskaudio.c", "src/audio/disk/SDL_diskaudio.c",
@ -943,7 +944,7 @@ pub fn build(b: *std.Build) void {
} }
if (linux) { if (linux) {
sdl_mod.addCSourceFiles(.{ sdl_mod.addCSourceFiles(.{
.flags = sdl_c_flags.slice(), .flags = sdl_c_flags.items,
.files = &.{ .files = &.{
"src/audio/dummy/SDL_dummyaudio.c", "src/audio/dummy/SDL_dummyaudio.c",
"src/audio/disk/SDL_diskaudio.c", "src/audio/disk/SDL_diskaudio.c",
@ -1067,7 +1068,7 @@ pub fn build(b: *std.Build) void {
}); });
if (linux_deps_values) |deps_values| { if (linux_deps_values) |deps_values| {
sdl_mod.addCSourceFiles(.{ sdl_mod.addCSourceFiles(.{
.flags = sdl_c_flags.slice(), .flags = sdl_c_flags.items,
.root = deps_values.dependency.path("."), .root = deps_values.dependency.path("."),
.files = deps_values.wayland_c_files, .files = deps_values.wayland_c_files,
}); });
@ -1075,7 +1076,7 @@ pub fn build(b: *std.Build) void {
} }
if (macos) { if (macos) {
sdl_mod.addCSourceFiles(.{ sdl_mod.addCSourceFiles(.{
.flags = sdl_c_flags.slice(), .flags = sdl_c_flags.items,
.files = &.{ .files = &.{
"src/audio/dummy/SDL_dummyaudio.c", "src/audio/dummy/SDL_dummyaudio.c",
"src/audio/disk/SDL_diskaudio.c", "src/audio/disk/SDL_diskaudio.c",
@ -1156,7 +1157,7 @@ pub fn build(b: *std.Build) void {
} }
if (emscripten) { if (emscripten) {
sdl_mod.addCSourceFiles(.{ sdl_mod.addCSourceFiles(.{
.flags = sdl_c_flags.slice(), .flags = sdl_c_flags.items,
.files = &.{ .files = &.{
"src/audio/dummy/SDL_dummyaudio.c", "src/audio/dummy/SDL_dummyaudio.c",
"src/audio/disk/SDL_diskaudio.c", "src/audio/disk/SDL_diskaudio.c",
@ -1201,7 +1202,7 @@ pub fn build(b: *std.Build) void {
}); });
if (emscripten_pthreads) { if (emscripten_pthreads) {
sdl_mod.addCSourceFiles(.{ sdl_mod.addCSourceFiles(.{
.flags = sdl_c_flags.slice(), .flags = sdl_c_flags.items,
.files = &.{ .files = &.{
"src/thread/pthread/SDL_systhread.c", "src/thread/pthread/SDL_systhread.c",
"src/thread/pthread/SDL_sysmutex.c", "src/thread/pthread/SDL_sysmutex.c",
@ -1213,7 +1214,7 @@ pub fn build(b: *std.Build) void {
}); });
} else { } else {
sdl_mod.addCSourceFiles(.{ sdl_mod.addCSourceFiles(.{
.flags = sdl_c_flags.slice(), .flags = sdl_c_flags.items,
.files = &.{ .files = &.{
"src/thread/generic/SDL_syscond.c", "src/thread/generic/SDL_syscond.c",
"src/thread/generic/SDL_sysmutex.c", "src/thread/generic/SDL_sysmutex.c",

18
lib/sdl3/build.zig vendored
View File

@ -11,9 +11,11 @@ pub fn addShaderDefinition(
// Create the spvReflect2 executable // Create the spvReflect2 executable
const spvReflect = b.addExecutable(.{ const spvReflect = b.addExecutable(.{
.name = "spvReflect2", .name = "spvReflect2",
.target = b.graph.host, .root_module = b.createModule(.{
.optimize = .ReleaseFast, .target = b.graph.host,
.root_source_file = b.path(sdl3Path ++ "/spvreflect/spvReflect2.zig"), .optimize = optimize,
.root_source_file = b.path(sdl3Path ++ "/spvreflect/spvReflect2.zig"),
}),
}); });
// Run the spvReflect2 executable // Run the spvReflect2 executable
@ -87,10 +89,12 @@ pub fn build(b: *std.Build) void {
const test_step = b.step("test", "run unit tests for sdl3"); const test_step = b.step("test", "run unit tests for sdl3");
const tests = b.addExecutable(.{ const tests = b.addExecutable(.{
.name = "hello-triangle", .name = "hello-triangle",
.target = target, .root_module = b.createModule(.{
.optimize = optimize, .target = target,
.root_source_file = b.path("src/samples/hello-triangle.zig"), .optimize = optimize,
.link_libc = true, .root_source_file = b.path("src/samples/hello-triangle.zig"),
.link_libc = true,
}),
}); });
tests.root_module.addImport("sdl3", mod); tests.root_module.addImport("sdl3", mod);

View File

@ -6,9 +6,11 @@ pub fn build(b: *std.Build) void {
const exe = b.addExecutable(.{ const exe = b.addExecutable(.{
.name = "spvReflect2", .name = "spvReflect2",
.root_source_file = b.path("spvReflect2.zig"), .root_module = b.createModule(.{
.target = target, .root_source_file = b.path("spvReflect2.zig"),
.optimize = optimize, .target = target,
.optimize = optimize,
}),
}); });
b.installArtifact(exe); b.installArtifact(exe);

View File

@ -489,6 +489,7 @@ const OutputFile = struct {
ssbos: *const SsboList, ssbos: *const SsboList,
ubos: *const UboList, ubos: *const UboList,
samplers: *const SamplersList, samplers: *const SamplersList,
allocator: std.mem.Allocator,
pub fn init( pub fn init(
allocator: std.mem.Allocator, allocator: std.mem.Allocator,
@ -498,7 +499,8 @@ const OutputFile = struct {
samplers: *const SamplersList, samplers: *const SamplersList,
) !@This() { ) !@This() {
return .{ return .{
.output = std.ArrayList(u8).init(allocator), .output = .{}, //std.ArrayList(u8).init(allocator),
.allocator = allocator,
.typeMap = typeMap, .typeMap = typeMap,
.ssbos = ssbos, .ssbos = ssbos,
.ubos = ubos, .ubos = ubos,
@ -507,7 +509,7 @@ const OutputFile = struct {
} }
pub fn finalize(self: *@This()) !void { pub fn finalize(self: *@This()) !void {
try self.output.append(0); try self.output.append(self.allocator, 0);
} }
pub fn writeOut(self: *@This(), path: []const u8) !void { pub fn writeOut(self: *@This(), path: []const u8) !void {
@ -515,20 +517,19 @@ const OutputFile = struct {
defer file.close(); defer file.close();
var ast = try std.zig.Ast.parse( var ast = try std.zig.Ast.parse(
self.output.allocator, self.allocator,
@as([:0]const u8, @ptrCast(self.output.items[0 .. self.output.items.len - 1])), @as([:0]const u8, @ptrCast(self.output.items[0 .. self.output.items.len - 1])),
.zig, .zig,
); );
// std.debug.print("output=\n{s}", .{content.items[0 .. content.items.len - 1]}); // std.debug.print("output=\n{s}", .{content.items[0 .. content.items.len - 1]});
defer ast.deinit(self.output.allocator); defer ast.deinit(self.allocator);
const out = try ast.render(self.output.allocator); const out = try ast.renderAlloc(self.allocator);
try file.writeAll(out); try file.writeAll(out);
} }
pub fn generatePreamble(self: *@This()) !void { pub fn generatePreamble(self: *@This()) !void {
var writer = self.output.writer(); try self.output.print(self.allocator,
try writer.print(
\\pub const shaderTypes = @import("shaderTypes"); \\pub const shaderTypes = @import("shaderTypes");
\\ \\
\\pub const int = shaderTypes.int; \\pub const int = shaderTypes.int;
@ -547,91 +548,87 @@ const OutputFile = struct {
} }
pub fn generateSsbos(self: *@This()) !void { pub fn generateSsbos(self: *@This()) !void {
var writer = self.output.writer();
for (self.ssbos.list.items) |ssbo| { for (self.ssbos.list.items) |ssbo| {
const ssboType = self.typeMap.typeList.items[ssbo.typeIndex]; const ssboType = self.typeMap.typeList.items[ssbo.typeIndex];
try writer.print("pub const {s} = extern struct {{\n", .{ssboType.name}); try self.output.print(self.allocator, "pub const {s} = extern struct {{\n", .{ssboType.name});
var lastFieldEnd: u32 = 0; var lastFieldEnd: u32 = 0;
var paddingCount: u32 = 0; var paddingCount: u32 = 0;
for (ssboType.fields.items) |field| { for (ssboType.fields.items) |field| {
if (lastFieldEnd != field.offset) { if (lastFieldEnd != field.offset) {
printErr("WARNING: Field {s} in ssbo {s} generated padding, expected offset {d} offset + struct size = {d}", .{ field.name, ssbo.name, field.offset, lastFieldEnd }); printErr("WARNING: Field {s} in ssbo {s} generated padding, expected offset {d} offset + struct size = {d}", .{ field.name, ssbo.name, field.offset, lastFieldEnd });
try writer.print(" pad{d}: [{d}]c_char = undefined,\n", .{ paddingCount, field.offset - lastFieldEnd }); try self.output.print(self.allocator, " pad{d}: [{d}]c_char = undefined,\n", .{ paddingCount, field.offset - lastFieldEnd });
paddingCount += 1; paddingCount += 1;
} }
try writer.print(" {s}: {s},\n", .{ field.name, field.typeName }); try self.output.print(self.allocator, " {s}: {s},\n", .{ field.name, field.typeName });
lastFieldEnd = field.offset + self.typeMap.getFieldSize(field); lastFieldEnd = field.offset + self.typeMap.getFieldSize(field);
} }
// generate buffer info // generate buffer info
try writer.print("\n pub const Buffer: BufferInfo = .{{ .storage = {d} }};\n", .{ssbo.binding}); try self.output.print(self.allocator, "\n pub const Buffer: BufferInfo = .{{ .storage = {d} }};\n", .{ssbo.binding});
try writer.print("\n pub const FieldDetails: []const shaderTypes.FieldDetail = &.{{ \n", .{}); try self.output.print(self.allocator, "\n pub const FieldDetails: []const shaderTypes.FieldDetail = &.{{ \n", .{});
for (ssboType.fields.items) |field| { for (ssboType.fields.items) |field| {
try writer.print(" " ** 8, .{}); try self.output.print(self.allocator, " " ** 8, .{});
try writer.print(".{{ .name = \"{s}\", .offset = {d}, .size = {d} }},\n", .{ field.name, field.offset, self.typeMap.getFieldSize(field) }); try self.output.print(self.allocator, ".{{ .name = \"{s}\", .offset = {d}, .size = {d} }},\n", .{ field.name, field.offset, self.typeMap.getFieldSize(field) });
} }
try writer.print(" }};\n", .{}); try self.output.print(self.allocator, " }};\n", .{});
try writer.print("}};\n", .{}); try self.output.print(self.allocator, "}};\n", .{});
} }
try writer.print("\ncomptime {{\n", .{}); try self.output.print(self.allocator, "\ncomptime {{\n", .{});
for (self.ssbos.list.items) |ssbo| { for (self.ssbos.list.items) |ssbo| {
const ssboType = self.typeMap.typeList.items[ssbo.typeIndex]; const ssboType = self.typeMap.typeList.items[ssbo.typeIndex];
try writer.print(" shaderTypes.ValidateGeneratedStruct({s});\n", .{ssboType.name}); try self.output.print(self.allocator, " shaderTypes.ValidateGeneratedStruct({s});\n", .{ssboType.name});
} }
try writer.print("}}\n", .{}); try self.output.print(self.allocator, "}}\n", .{});
} }
pub fn generateUbos(self: *@This()) !void { pub fn generateUbos(self: *@This()) !void {
var writer = self.output.writer();
for (self.ubos.list.items) |ubo| { for (self.ubos.list.items) |ubo| {
const uboType = self.typeMap.typeList.items[ubo.typeIndex]; const uboType = self.typeMap.typeList.items[ubo.typeIndex];
try writer.print("pub const Uniforms = extern struct {{\n", .{}); try self.output.print(self.allocator, "pub const Uniforms = extern struct {{\n", .{});
var lastFieldEnd: u32 = 0; var lastFieldEnd: u32 = 0;
var paddingCount: u32 = 0; var paddingCount: u32 = 0;
for (uboType.fields.items) |field| { for (uboType.fields.items) |field| {
if (lastFieldEnd != field.offset) { if (lastFieldEnd != field.offset) {
printErr("WARNING: Field {s} in ubo {s} generated padding, expected offset {d} offset + struct size = {d}", .{ field.name, ubo.name, field.offset, lastFieldEnd }); printErr("WARNING: Field {s} in ubo {s} generated padding, expected offset {d} offset + struct size = {d}", .{ field.name, ubo.name, field.offset, lastFieldEnd });
try writer.print(" pad{d}: [{d}]c_char = undefined,\n", .{ paddingCount, field.offset - lastFieldEnd }); try self.output.print(self.allocator, " pad{d}: [{d}]c_char = undefined,\n", .{ paddingCount, field.offset - lastFieldEnd });
paddingCount += 1; paddingCount += 1;
} }
try writer.print(" {s}: {s},\n", .{ field.name, field.typeName }); try self.output.print(self.allocator, " {s}: {s},\n", .{ field.name, field.typeName });
lastFieldEnd = field.offset + self.typeMap.getFieldSize(field); lastFieldEnd = field.offset + self.typeMap.getFieldSize(field);
} }
// generate buffer info using .uniform instead of .storage // generate buffer info using .uniform instead of .storage
try writer.print("\n pub const Buffer: BufferInfo = .{{ .uniform = {d} }};\n", .{ubo.binding}); try self.output.print(self.allocator, "\n pub const Buffer: BufferInfo = .{{ .uniform = {d} }};\n", .{ubo.binding});
try writer.print("\n pub const FieldDetails: []const shaderTypes.FieldDetail = &.{{ \n", .{}); try self.output.print(self.allocator, "\n pub const FieldDetails: []const shaderTypes.FieldDetail = &.{{ \n", .{});
for (uboType.fields.items) |field| { for (uboType.fields.items) |field| {
try writer.print(" " ** 8, .{}); try self.output.print(self.allocator, " " ** 8, .{});
try writer.print(".{{ .name = \"{s}\", .offset = {d}, .size = {d} }},\n", .{ field.name, field.offset, self.typeMap.getFieldSize(field) }); try self.output.print(self.allocator, ".{{ .name = \"{s}\", .offset = {d}, .size = {d} }},\n", .{ field.name, field.offset, self.typeMap.getFieldSize(field) });
} }
try writer.print(" }};\n", .{}); try self.output.print(self.allocator, " }};\n", .{});
try writer.print("}};\n", .{}); try self.output.print(self.allocator, "}};\n", .{});
} }
try writer.print("\ncomptime {{\n", .{}); try self.output.print(self.allocator, "\ncomptime {{\n", .{});
for (self.ubos.list.items) |ubo| { for (self.ubos.list.items) |ubo| {
const uboType = self.typeMap.typeList.items[ubo.typeIndex]; const uboType = self.typeMap.typeList.items[ubo.typeIndex];
_ = uboType; _ = uboType;
try writer.print(" shaderTypes.ValidateGeneratedStruct({s});\n", .{"Uniforms"}); try self.output.print(self.allocator, " shaderTypes.ValidateGeneratedStruct({s});\n", .{"Uniforms"});
} }
try writer.print("}}\n", .{}); try self.output.print(self.allocator, "}}\n", .{});
} }
pub fn generateLoadArguments(self: *@This()) !void { pub fn generateLoadArguments(self: *@This()) !void {
var writer = self.output.writer(); try self.output.print(self.allocator, "pub const LoadArgs = shaderTypes.ShaderLoadArgs {{\n", .{});
try writer.print("pub const LoadArgs = shaderTypes.ShaderLoadArgs {{\n", .{}); try self.output.print(self.allocator,
try writer.print(
\\.num_samplers = {d}, \\.num_samplers = {d},
\\.num_storage_textures = {d}, \\.num_storage_textures = {d},
\\.num_storage_buffers = {d}, \\.num_storage_buffers = {d},
@ -642,11 +639,11 @@ const OutputFile = struct {
self.ssbos.list.items.len, self.ssbos.list.items.len,
self.ubos.list.items.len, self.ubos.list.items.len,
}); });
try writer.print("}};\n", .{}); try self.output.print(self.allocator, "}};\n", .{});
} }
pub fn deinit(self: *@This()) void { pub fn deinit(self: *@This()) void {
self.output.deinit(); self.output.deinit(self.allocator);
} }
}; };

View File

@ -21,9 +21,11 @@ colorBuffer: *gpu.GPUBuffer = undefined,
colorBufferTransfer: *gpu.GPUTransferBuffer = undefined, colorBufferTransfer: *gpu.GPUTransferBuffer = undefined,
totalTime: f64 = 0.0, totalTime: f64 = 0.0,
var stdout_buffer: [1024]u8 = undefined;
pub fn print(comptime fmt: []const u8, args: anytype) void { pub fn print(comptime fmt: []const u8, args: anytype) void {
const writer = std.io.getStdOut().writer(); var stdout = std.fs.File.stdout().writer(&stdout_buffer);
writer.print(">>> " ++ fmt ++ "\n", args) catch return; stdout.interface.print(">>> " ++ fmt ++ "\n", args) catch return;
} }
pub fn create(allocator: std.mem.Allocator) !*@This() { pub fn create(allocator: std.mem.Allocator) !*@This() {
@ -105,13 +107,13 @@ pub fn startContext(self: *@This()) !void {
}); });
} }
pub fn loadFileAlloc(filename: []const u8, comptime alignment: usize, allocator: std.mem.Allocator) ![]u8 { pub fn loadFileAlloc(filename: []const u8, comptime alignment: ?std.mem.Alignment, allocator: std.mem.Allocator) ![]u8 {
var file = try std.fs.cwd().openFile(filename, .{}); var file = try std.fs.cwd().openFile(filename, .{});
defer file.close(); defer file.close();
const filesize = (try file.stat()).size + 1; // add null byte const filesize = (try file.stat()).size + 1; // add null byte
const buffer: []align(alignment) u8 = try allocator.alignedAlloc(u8, alignment, filesize); const buffer: []u8 = try allocator.alignedAlloc(u8, alignment, filesize);
errdefer allocator.free(buffer); errdefer allocator.free(buffer);
try file.reader().readNoEof(buffer[0 .. buffer.len - 1]); std.mem.copyForwards(u8, buffer, try file.readToEndAlloc(allocator, buffer.len - 1));
buffer[buffer.len - 1] = 0; buffer[buffer.len - 1] = 0;
return buffer; return buffer;
} }
@ -125,12 +127,12 @@ pub fn loadShader(
num_storage_buffers: u32, // The number of storage buffers defined in the shader. num_storage_buffers: u32, // The number of storage buffers defined in the shader.
num_uniform_buffers: u32, // The number of uniform buffers defined in the shader. num_uniform_buffers: u32, // The number of uniform buffers defined in the shader.
) !*gpu.GPUShader { ) !*gpu.GPUShader {
const spath = try std.fmt.allocPrintZ(self.allocator, "{s}/{s}{s}", .{ self.shaderpath, shaderName, self.shadersuffix }); const spath = try std.fmt.allocPrintSentinel(self.allocator, "{s}/{s}{s}", .{ self.shaderpath, shaderName, self.shadersuffix }, 0);
defer self.allocator.free(spath); defer self.allocator.free(spath);
print("loading shader {s}\n", .{spath}); print("loading shader {s}\n", .{spath});
const fileContents = try loadFileAlloc(spath, 8, self.allocator); const fileContents = try loadFileAlloc(spath, .@"8", self.allocator);
defer self.allocator.free(fileContents); defer self.allocator.free(fileContents);
const sci = gpu.GPUShaderCreateInfo{ const sci = gpu.GPUShaderCreateInfo{
.code = @ptrCast(fileContents.ptr), .code = @ptrCast(fileContents.ptr),