textures.zig (2059B)
1 const std = @import("std"); 2 const gpu = @import("mach_gpu"); 3 const Image = @import("zigimg").Image; 4 5 allocator: std.mem.Allocator, 6 texture: *gpu.Texture, 7 view: *gpu.TextureView, 8 sampler: *gpu.Sampler, 9 offset: u32 = 0, 10 11 const Self = @This(); 12 13 pub fn init(allocator: std.mem.Allocator, device: *gpu.Device) Self { 14 const tex_size = gpu.Extent3D{ 15 .width = 2048, 16 .height = 2048, 17 .depth_or_array_layers = 128, 18 }; 19 const texture = device.createTexture(&.{ 20 .size = tex_size, 21 .format = .rgba8_unorm, 22 .dimension = .dimension_2d, 23 .usage = .{ 24 .texture_binding = true, 25 .copy_dst = true, 26 .render_attachment = false, 27 }, 28 }); 29 const view = texture.createView( 30 &gpu.TextureView.Descriptor{ 31 .dimension = .dimension_2d_array, 32 }, 33 ); 34 const sampler = device.createSampler(&.{ 35 .mag_filter = .linear, 36 .min_filter = .linear, 37 }); 38 39 return .{ 40 .allocator = allocator, 41 .texture = texture, 42 .view = view, 43 .sampler = sampler, 44 }; 45 } 46 47 pub fn loadFile( 48 self: *Self, 49 path: []const u8, 50 queue: *gpu.Queue, 51 ) !u32 { 52 var image = try Image.fromFilePath(self.allocator, path); 53 defer image.deinit(); 54 55 const tex_width = 2048; 56 const tex_height = 2048; 57 const tex_size = gpu.Extent3D{ .width = tex_width, .height = tex_height }; 58 59 const data_layout = gpu.Texture.DataLayout{ 60 .bytes_per_row = tex_width * 4, 61 .rows_per_image = tex_height, 62 }; 63 const destination = gpu.ImageCopyTexture{ 64 .texture = self.texture, 65 .origin = gpu.Origin3D{ .x = 0, .y = 0, .z = self.offset }, 66 }; 67 defer self.offset += 1; 68 69 switch (image.pixels) { 70 .rgba32 => |pixels| { 71 queue.writeTexture( 72 &destination, 73 &data_layout, 74 &tex_size, 75 pixels, 76 ); 77 }, 78 else => @panic("unsupported image color format"), 79 } 80 return self.offset; 81 }