diff --git a/pkg/opengl/Texture.zig b/pkg/opengl/Texture.zig index 833a9bb4d..4a1d61433 100644 --- a/pkg/opengl/Texture.zig +++ b/pkg/opengl/Texture.zig @@ -7,15 +7,16 @@ const glad = @import("glad.zig"); id: c.GLuint, -pub fn active(index: c_uint) !void { +pub fn active(index: c_uint) errors.Error!void { glad.context.ActiveTexture.?(index + c.GL_TEXTURE0); try errors.getError(); } /// Create a single texture. -pub fn create() !Texture { +pub fn create() errors.Error!Texture { var id: c.GLuint = undefined; glad.context.GenTextures.?(1, &id); + try errors.getError(); return .{ .id = id }; } @@ -107,7 +108,7 @@ pub const Binding = struct { glad.context.GenerateMipmap.?(@intFromEnum(b.target)); } - pub fn parameter(b: Binding, name: Parameter, value: anytype) !void { + pub fn parameter(b: Binding, name: Parameter, value: anytype) errors.Error!void { switch (@TypeOf(value)) { c.GLint => glad.context.TexParameteri.?( @intFromEnum(b.target), @@ -129,7 +130,7 @@ pub const Binding = struct { format: Format, typ: DataType, data: ?*const anyopaque, - ) !void { + ) errors.Error!void { glad.context.TexImage2D.?( @intFromEnum(b.target), level, @@ -154,7 +155,7 @@ pub const Binding = struct { format: Format, typ: DataType, data: ?*const anyopaque, - ) !void { + ) errors.Error!void { glad.context.TexSubImage2D.?( @intFromEnum(b.target), level, @@ -178,7 +179,7 @@ pub const Binding = struct { y: c.GLint, width: c.GLsizei, height: c.GLsizei, - ) !void { + ) errors.Error!void { glad.context.CopyTexSubImage2D.?( @intFromEnum(b.target), level, diff --git a/src/renderer/Metal.zig b/src/renderer/Metal.zig index a69d2e3d3..21a10d45f 100644 --- a/src/renderer/Metal.zig +++ b/src/renderer/Metal.zig @@ -284,14 +284,17 @@ pub inline fn textureOptions(self: Metal) Texture.Options { } /// Initializes a Texture suitable for the provided font atlas. -pub fn initAtlasTexture(self: *const Metal, atlas: *const font.Atlas) !Texture { +pub fn initAtlasTexture( + self: *const Metal, + atlas: *const font.Atlas, +) Texture.Error!Texture { const pixel_format: mtl.MTLPixelFormat = switch (atlas.format) { .grayscale => .r8unorm, .rgba => .bgra8unorm, else => @panic("unsupported atlas format for Metal texture"), }; - return Texture.init( + return try Texture.init( .{ .device = self.device, .pixel_format = pixel_format, diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index fe266d2ef..1d1b41f0e 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -384,7 +384,10 @@ pub inline fn textureOptions(self: OpenGL) Texture.Options { } /// Initializes a Texture suitable for the provided font atlas. -pub fn initAtlasTexture(self: *const OpenGL, atlas: *const font.Atlas) !Texture { +pub fn initAtlasTexture( + self: *const OpenGL, + atlas: *const font.Atlas, +) Texture.Error!Texture { _ = self; const format: gl.Texture.Format, const internal_format: gl.Texture.InternalFormat = switch (atlas.format) { @@ -393,7 +396,7 @@ pub fn initAtlasTexture(self: *const OpenGL, atlas: *const font.Atlas) !Texture else => @panic("unsupported atlas format for OpenGL texture"), }; - return Texture.init( + return try Texture.init( .{ .format = format, .internal_format = internal_format, diff --git a/src/renderer/metal/Texture.zig b/src/renderer/metal/Texture.zig index 6e3ae78c7..32820f8fc 100644 --- a/src/renderer/metal/Texture.zig +++ b/src/renderer/metal/Texture.zig @@ -31,13 +31,18 @@ height: usize, /// Bytes per pixel for this texture. bpp: usize, +pub const Error = error{ + /// A Metal API call failed. + MetalFailed, +}; + /// Initialize a texture pub fn init( opts: Options, width: usize, height: usize, data: ?[]const u8, -) !Self { +) Error!Self { // Create our descriptor const desc = init: { const Class = objc.getClass("MTLTextureDescriptor").?; @@ -90,7 +95,7 @@ pub fn replaceRegion( width: usize, height: usize, data: []const u8, -) !void { +) error{}!void { self.texture.msgSend( void, objc.sel("replaceRegion:mipmapLevel:withBytes:bytesPerRow:"), diff --git a/src/renderer/opengl/Texture.zig b/src/renderer/opengl/Texture.zig index d5ec816a6..07123922f 100644 --- a/src/renderer/opengl/Texture.zig +++ b/src/renderer/opengl/Texture.zig @@ -31,23 +31,28 @@ format: gl.Texture.Format, /// Target for this texture. target: gl.Texture.Target, +pub const Error = error{ + /// An OpenGL API call failed. + OpenGLFailed, +}; + /// Initialize a texture pub fn init( opts: Options, width: usize, height: usize, data: ?[]const u8, -) !Self { - const tex = try gl.Texture.create(); +) Error!Self { + const tex = gl.Texture.create() catch return error.OpenGLFailed; errdefer tex.destroy(); { - const texbind = try tex.bind(opts.target); + const texbind = tex.bind(opts.target) catch return error.OpenGLFailed; defer texbind.unbind(); - try texbind.parameter(.WrapS, gl.c.GL_CLAMP_TO_EDGE); - try texbind.parameter(.WrapT, gl.c.GL_CLAMP_TO_EDGE); - try texbind.parameter(.MinFilter, gl.c.GL_LINEAR); - try texbind.parameter(.MagFilter, gl.c.GL_LINEAR); - try texbind.image2D( + texbind.parameter(.WrapS, gl.c.GL_CLAMP_TO_EDGE) catch return error.OpenGLFailed; + texbind.parameter(.WrapT, gl.c.GL_CLAMP_TO_EDGE) catch return error.OpenGLFailed; + texbind.parameter(.MinFilter, gl.c.GL_LINEAR) catch return error.OpenGLFailed; + texbind.parameter(.MagFilter, gl.c.GL_LINEAR) catch return error.OpenGLFailed; + texbind.image2D( 0, opts.internal_format, @intCast(width), @@ -56,7 +61,7 @@ pub fn init( opts.format, .UnsignedByte, if (data) |d| @ptrCast(d.ptr) else null, - ); + ) catch return error.OpenGLFailed; } return .{ @@ -82,10 +87,10 @@ pub fn replaceRegion( width: usize, height: usize, data: []const u8, -) !void { - const texbind = try self.texture.bind(self.target); +) Error!void { + const texbind = self.texture.bind(self.target) catch return error.OpenGLFailed; defer texbind.unbind(); - try texbind.subImage2D( + texbind.subImage2D( 0, @intCast(x), @intCast(y), @@ -94,5 +99,5 @@ pub fn replaceRegion( self.format, .UnsignedByte, data.ptr, - ); + ) catch return error.OpenGLFailed; }