Update to zig 0.16.0, update deps, Vulkan validation fixes

This commit is contained in:
2026-05-13 00:43:49 +02:00
parent 39712e359d
commit 79c62141df
16 changed files with 204 additions and 137 deletions

View File

@@ -138,11 +138,12 @@ pub fn getOrLoad(
stbi: *media.stbi,
filename: []const u8,
temp_allocator: std.mem.Allocator,
io: std.Io,
) !Id {
const key: Key = .{
// If the material already exists, then the atom must exist and the
// following line will not return any error.
.filename = try .fromString(filename),
.filename = try .fromString(filename, io),
};
// We don't use `getOrPutAssumeCapacity` method, because we might already be
@@ -154,7 +155,7 @@ pub fn getOrLoad(
const id = Id.fromIndexSafe(self.array.items.len) catch |err| switch (err) {
error.Overflow => return error.OutOfBlocks,
};
const def = try loadBlock(engine, materials, textures, stbi, filename, temp_allocator);
const def = try loadBlock(engine, materials, textures, stbi, filename, temp_allocator, io);
self.map.putAssumeCapacityNoClobber(key, id);
self.array.appendAssumeCapacity(def);
@@ -171,6 +172,7 @@ pub fn getOrLoadAtom(
stbi: *media.stbi,
filename: Atom,
temp_allocator: std.mem.Allocator,
io: std.Io,
) !Id {
const key: Key = .{
.filename = filename,
@@ -185,7 +187,7 @@ pub fn getOrLoadAtom(
const id = Id.fromIndexSafe(self.array.items.len) catch |err| switch (err) {
error.Overflow => return error.OutOfBlocks,
};
const def = try loadBlock(engine, materials, textures, stbi, filename.toString(), temp_allocator);
const def = try loadBlock(engine, materials, textures, stbi, filename.toString(), temp_allocator, io);
self.map.putAssumeCapacityNoClobber(key, id);
self.array.appendAssumeCapacity(def);
@@ -201,17 +203,18 @@ pub fn loadAll(
textures: *Textures,
stbi: *media.stbi,
temp_allocator: std.mem.Allocator,
io: std.Io,
) void {
const cwd = std.fs.cwd();
const cwd = std.Io.Dir.cwd();
var dir = cwd.openDir("assets/blocks", .{ .iterate = true }) catch |err| {
var dir = cwd.openDir(io, "assets/blocks", .{ .iterate = true }) catch |err| {
std.log.err("Error while opening block definitions directory: {s}", .{@errorName(err)});
return;
};
defer dir.close();
defer dir.close(io);
var it = dir.iterate();
while (it.next() catch |err| {
while (it.next(io) catch |err| {
std.log.err("Error while iterating over block definitions directory: {s}", .{@errorName(err)});
return;
}) |entry| {
@@ -220,7 +223,7 @@ pub fn loadAll(
continue;
}
_ = self.getOrLoad(engine, materials, textures, stbi, entry.name, temp_allocator) catch |err| {
_ = self.getOrLoad(engine, materials, textures, stbi, entry.name, temp_allocator, io) catch |err| {
std.log.err("Error while loading block definition entry {s}: {s}", .{ entry.name, @errorName(err) });
};
}
@@ -233,6 +236,7 @@ fn loadBlock(
stbi: *media.stbi,
filename: []const u8,
temp_allocator: std.mem.Allocator,
io: std.Io,
) !Definition {
const DefinitionJson = struct {
pub const Wall = struct {
@@ -248,18 +252,18 @@ fn loadBlock(
std.log.debug("Loading block \"{s}\"...", .{filename});
const cwd = std.fs.cwd();
const cwd = std.Io.Dir.cwd();
var dir = try cwd.openDir("assets/blocks", .{});
defer dir.close();
var dir = try cwd.openDir(io, "assets/blocks", .{});
defer dir.close(io);
// NOTE Buffer size approximated based on expected JSON structure.
var buffer: [1024]u8 = undefined;
const file = try dir.openFile(filename, .{});
defer file.close();
const file = try dir.openFile(io, filename, .{});
defer file.close(io);
var file_reader = file.reader(&buffer);
var file_reader = file.reader(io, &buffer);
var json_reader = std.json.Reader.init(temp_allocator, &file_reader.interface);
defer json_reader.deinit();
@@ -279,7 +283,7 @@ fn loadBlock(
return error.ParseError;
}
const material = try materials.getOrLoad(engine, textures, stbi, name, temp_allocator);
const material = try materials.getOrLoad(engine, textures, stbi, name, temp_allocator, io);
break :blk .initUniform(material);
}
@@ -289,7 +293,7 @@ fn loadBlock(
var ret: Definition.Walls = undefined;
inline for (@typeInfo(voxels.Orientation).@"enum".fields) |field| {
@field(ret, field.name) = .{
.material = try materials.getOrLoad(engine, textures, stbi, @field(walls, field.name).material, temp_allocator),
.material = try materials.getOrLoad(engine, textures, stbi, @field(walls, field.name).material, temp_allocator, io),
.transform = @field(walls, field.name).transform,
};
}

View File

@@ -149,12 +149,20 @@ pub fn getAtom(self: *const Materials, filename: Atom) ?Id {
/// deinitialized or reset after this function returns. Note that during loading
/// the engine will make its own persistent allocations, so an out of memory
/// error is not necessarily related to `temp_allocator`.
pub fn getOrLoad(self: *Materials, engine: *Engine, textures: *Textures, stbi: *media.stbi, maybe_filename: ?[]const u8, temp_allocator: std.mem.Allocator) !Id {
pub fn getOrLoad(
self: *Materials,
engine: *Engine,
textures: *Textures,
stbi: *media.stbi,
maybe_filename: ?[]const u8,
temp_allocator: std.mem.Allocator,
io: std.Io,
) !Id {
if (maybe_filename) |filename| {
const key: Key = .{
// If the material already exists, then the atom must exist and the
// following line will not return any error.
.filename = try .fromString(filename),
.filename = try .fromString(filename, io),
};
// We don't use `getOrPutAssumeCapacity` method, because we might already be
@@ -166,7 +174,7 @@ pub fn getOrLoad(self: *Materials, engine: *Engine, textures: *Textures, stbi: *
const id = Id.fromIndexSafe(self.material_count) catch |err| switch (err) {
error.Overflow => return error.OutOfMaterials,
};
try self.loadMaterial(engine, textures, stbi, filename, id.toInt(), temp_allocator);
try self.loadMaterial(engine, textures, stbi, filename, id.toInt(), temp_allocator, io);
self.map.putAssumeCapacityNoClobber(key, id);
self.material_count += 1;
@@ -189,7 +197,15 @@ pub fn getOrLoad(self: *Materials, engine: *Engine, textures: *Textures, stbi: *
/// deinitialized or reset after this function returns. Note that during loading
/// the engine will make its own persistent allocations, so an out of memory
/// error is not necessarily related to `temp_allocator`.
pub fn getOrLoadAtom(self: *Materials, engine: *Engine, textures: *Textures, stbi: *media.stbi, filename: Atom, temp_allocator: std.mem.Allocator) !Id {
pub fn getOrLoadAtom(
self: *Materials,
engine: *Engine,
textures: *Textures,
stbi: *media.stbi,
filename: Atom,
temp_allocator: std.mem.Allocator,
io: std.Io,
) !Id {
if (filename != .empty) {
const key: Key = .{
.filename = filename,
@@ -204,7 +220,7 @@ pub fn getOrLoadAtom(self: *Materials, engine: *Engine, textures: *Textures, stb
const id = Id.fromIndexSafe(self.material_count) catch |err| switch (err) {
error.Overflow => return error.OutOfMaterials,
};
try self.loadMaterial(engine, textures, stbi, filename.toString(), id.toInt(), temp_allocator);
try self.loadMaterial(engine, textures, stbi, filename.toString(), id.toInt(), temp_allocator, io);
self.map.putAssumeCapacityNoClobber(key, id);
self.material_count += 1;
@@ -251,7 +267,7 @@ pub fn loadAll(self: *Materials, engine: *Engine, textures: *Textures, stbi: *me
}
}
fn loadMaterial(self: *Materials, engine: *Engine, textures: *Textures, stbi: *media.stbi, filename: []const u8, index: u32, temp_allocator: std.mem.Allocator) !void {
fn loadMaterial(self: *Materials, engine: *Engine, textures: *Textures, stbi: *media.stbi, filename: []const u8, index: u32, temp_allocator: std.mem.Allocator, io: std.Io) !void {
const MaterialJson = struct {
baseColor: [3]f32 = .{ 1, 1, 1 },
baseColorTexture: ?[]const u8 = null,
@@ -268,18 +284,18 @@ fn loadMaterial(self: *Materials, engine: *Engine, textures: *Textures, stbi: *m
std.log.debug("Loading material \"{s}\"...", .{filename});
const cwd = std.fs.cwd();
const cwd = std.Io.Dir.cwd();
var dir = try cwd.openDir("assets/materials", .{});
defer dir.close();
var dir = try cwd.openDir(io, "assets/materials", .{});
defer dir.close(io);
// NOTE Buffer size approximated based on expected JSON structure.
var buffer: [512]u8 = undefined;
const file = try dir.openFile(filename, .{});
defer file.close();
const file = try dir.openFile(io, filename, .{});
defer file.close(io);
var file_reader = file.reader(&buffer);
var file_reader = file.reader(io, &buffer);
var json_reader = std.json.Reader.init(temp_allocator, &file_reader.interface);
defer json_reader.deinit();
@@ -303,10 +319,10 @@ fn loadMaterial(self: *Materials, engine: *Engine, textures: *Textures, stbi: *m
.normal_scale = material_json.normalScale,
.occlusion_texture_strength = material_json.occlusionTextureStrength,
.roughness = material_json.roughness,
.base_color_texture = try textures.getOrLoad(engine, stbi, material_json.baseColorTexture, .base_color),
.emissive_texture = try textures.getOrLoad(engine, stbi, material_json.emissiveTexture, .emissive),
.normal_texture = try textures.getOrLoad(engine, stbi, material_json.normalTexture, .normal),
.occlusion_roughness_metallic_texture = try textures.getOrLoad(engine, stbi, material_json.occlusionRoughnessMetallicTexture, .occlusion_roughness_metallic),
.base_color_texture = try textures.getOrLoad(engine, stbi, material_json.baseColorTexture, .base_color, io),
.emissive_texture = try textures.getOrLoad(engine, stbi, material_json.emissiveTexture, .emissive, io),
.normal_texture = try textures.getOrLoad(engine, stbi, material_json.normalTexture, .normal, io),
.occlusion_roughness_metallic_texture = try textures.getOrLoad(engine, stbi, material_json.occlusionRoughnessMetallicTexture, .occlusion_roughness_metallic, io),
},
},
});

View File

@@ -172,12 +172,19 @@ pub fn getAtom(self: *const Textures, filename: Atom, usage: Texture.Usage) ?Id
/// if necessary. Will not return any error if the texture already exists. When
/// the filename is `null`, returns an empty texture ID appropriate for given
/// usage.
pub fn getOrLoad(self: *Textures, engine: *Engine, stbi: *media.stbi, maybe_filename: ?[]const u8, usage: Texture.Usage) !Id {
pub fn getOrLoad(
self: *Textures,
engine: *Engine,
stbi: *media.stbi,
maybe_filename: ?[]const u8,
usage: Texture.Usage,
io: std.Io,
) !Id {
if (maybe_filename) |filename| {
const key: Key = .{
// If the texture already exists, then the atom must exist and the
// following line will not return any error.
.filename = try .fromString(filename),
.filename = try .fromString(filename, io),
.usage = usage,
};
@@ -190,7 +197,7 @@ pub fn getOrLoad(self: *Textures, engine: *Engine, stbi: *media.stbi, maybe_file
const id = Id.fromIndexSafe(self.array.items.len) catch |err| switch (err) {
error.Overflow => return error.OutOfTextures,
};
const texture = try loadTexture(engine, stbi, filename, usage);
const texture = try loadTexture(engine, stbi, filename, usage, io);
self.map.putAssumeCapacityNoClobber(key, id);
self.array.appendAssumeCapacity(texture);
@@ -207,7 +214,14 @@ pub fn getOrLoad(self: *Textures, engine: *Engine, stbi: *media.stbi, maybe_file
/// if necessary. Will not return any error if the texture already exists. When
/// the filename is `.empty`, returns an empty texture ID appropriate for given
/// usage.
pub fn getOrLoadAtom(self: *Textures, engine: *Engine, stbi: *media.stbi, filename: Atom, usage: Texture.Usage) !Id {
pub fn getOrLoadAtom(
self: *Textures,
engine: *Engine,
stbi: *media.stbi,
filename: Atom,
usage: Texture.Usage,
io: std.Io,
) !Id {
if (filename != .empty) {
const key: Key = .{
.filename = filename,
@@ -223,7 +237,7 @@ pub fn getOrLoadAtom(self: *Textures, engine: *Engine, stbi: *media.stbi, filena
const id = Id.fromIndexSafe(self.array.items.len) catch |err| switch (err) {
error.Overflow => return error.OutOfTextures,
};
const texture = try loadTexture(engine, stbi, filename.toString(), usage);
const texture = try loadTexture(engine, stbi, filename.toString(), usage, io);
self.map.putAssumeCapacityNoClobber(key, id);
self.array.appendAssumeCapacity(texture);
@@ -235,21 +249,27 @@ pub fn getOrLoadAtom(self: *Textures, engine: *Engine, stbi: *media.stbi, filena
}
}
fn loadTexture(engine: *Engine, stbi: *media.stbi, filename: []const u8, usage: Texture.Usage) !Texture {
fn loadTexture(
engine: *Engine,
stbi: *media.stbi,
filename: []const u8,
usage: Texture.Usage,
io: std.Io,
) !Texture {
std.log.debug("Loading texture \"{s}\" as {s}...", .{ filename, @tagName(usage) });
const cwd = std.fs.cwd();
const cwd = std.Io.Dir.cwd();
var dir = try cwd.openDir("assets/textures", .{});
defer dir.close();
var dir = try cwd.openDir(io, "assets/textures", .{});
defer dir.close(io);
var file = try dir.openFile(filename, .{});
defer file.close();
var file = try dir.openFile(io, filename, .{});
defer file.close(io);
// The textures are expected to be small; a standard block base color as a
// PNG takes well below 1 kiB.
var buf: [4096]u8 = undefined;
var reader = file.reader(&buf);
var reader = file.reader(io, &buf);
const img = try stbi.loadDynamicIo(&reader.interface);
defer stbi.freeDynamic(img);