diff --git a/examples/imgui/imgui.zig b/examples/imgui/imgui.zig index b67105c..ca589e3 100644 --- a/examples/imgui/imgui.zig +++ b/examples/imgui/imgui.zig @@ -36,28 +36,39 @@ pub fn main(init: std.process.Init) !void { // GFX // - // --- # --- - var gfx: Gfx = try .init( - init.gpa, - init.io, - ); + var gfx: Gfx = try .init(init.gpa, init.io); defer gfx.deinit(); - // --- # --- const instance = try gfx.makeInstance(.{ .vulkan = .{}, }); const surface = try gfx.makeSurface(.{ - .xlib = .{ - .window = @intCast(xwindow), - .display = display.?, + .window = .{ + .xlib = .{ + .window = @intCast(xwindow), + .display = display.?, + }, }, - }, instance); + .instance = instance, + }); - const adapter = try gfx.makeAdapter(.{}, instance); - const device = try gfx.makeDevice(instance, adapter, surface); - const swapchain = try gfx.makeSwapchain(adapter, device, surface); + const adapter = try gfx.makeAdapter(.{ + .instance = instance, + }); + + const device = try gfx.makeDevice(.{ + .instance = instance, + .adapter = adapter, + .surface = surface, + }); + + const swapchain = try gfx.makeSwapchain(.{ + .format = .rgba8_unorm, + .surface = surface, + .adapter = adapter, + .device = device, + }); // // IMGUI diff --git a/examples/simple/simple.zig b/examples/simple/simple.zig index 7cfc70b..99fd3fa 100644 --- a/examples/simple/simple.zig +++ b/examples/simple/simple.zig @@ -20,15 +20,12 @@ pub fn main(init: std.process.Init) !void { // SDL // - // --- # --- if (!sdl.SDL_Init(sdl.SDL_INIT_VIDEO)) return error.FailedToInitSDL; defer sdl.SDL_Quit(); - // --- # --- const window = sdl.SDL_CreateWindow("NYXGFX", 800, 600, 0) orelse return error.FailedTomakeWindow; defer sdl.SDL_DestroyWindow(window); - // --- # --- const props = sdl.SDL_GetWindowProperties(window); const display = sdl.SDL_GetPointerProperty(props, sdl.SDL_PROP_WINDOW_X11_DISPLAY_POINTER, null); const xwindow = sdl.SDL_GetNumberProperty(props, sdl.SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0); @@ -37,49 +34,76 @@ pub fn main(init: std.process.Init) !void { // GFX // - // --- # --- - var gfx: Gfx = try .init( - init.gpa, - init.io, - ); + var gfx: Gfx = try .init(init.gpa, init.io); defer gfx.deinit(); - // --- # --- + // + // CORE + // + const instance = try gfx.makeInstance(.{ .vulkan = .{ .api_version = .v1_3, - .vk_14_features = .{ - .dynamic_rendering_local_read = false, - }, + .vk_13_features = .{}, }, }); const surface = try gfx.makeSurface(.{ - .xlib = .{ - .window = @intCast(xwindow), - .display = display.?, + .window = .{ + .xlib = .{ + .window = @intCast(xwindow), + .display = display.?, + }, }, - }, instance); + .instance = instance, + }); - const adapter = try gfx.makeAdapter(.{}, instance); - const device = try gfx.makeDevice(instance, adapter, surface); - const swapchain = try gfx.makeSwapchain(adapter, device, surface); + const adapter = try gfx.makeAdapter(.{ + .instance = instance, + }); + + const device = try gfx.makeDevice(.{ + .instance = instance, + .adapter = adapter, + .surface = surface, + }); + + const swapchain = try gfx.makeSwapchain(.{ + .surface = surface, + .adapter = adapter, + .device = device, + }); + + // + // TEXTURES + // - // --- TEXTURES --- const texture = try gfx.makeTexture(.{ .image = .{ .path = "examples/assets/textures/bully.jpg" }, .sampler = .{ .min_filter = .linear, .address_u = .repeat }, - }, adapter, device); - // --- BUFFERS --- + .adapter = adapter, + .device = device, + }); + + // + // BUFFERS + // + const vbuf = try gfx.makeBuffer(cmn.Square.vertices, .vertex, adapter, device); const ibuf = try gfx.makeBuffer(cmn.Square.indices, .index, adapter, device); - // --- SHADERS --- + // + // SHADERS + // + const simple_vert = try gfx.makeShader("examples/assets/shaders/compiled/simple.vert.spv", device); const simple_frag = try gfx.makeShader("examples/assets/shaders/compiled/simple.frag.spv", device); - // --- PIPELINE --- + // + // PIPELINES + // + const pipeline = try gfx.makePipeline(.{ .vertex_attributes = &.{ .{ .location = 0, .format = .vec3, .offset = @offsetOf(cmn.Vertex, "pos") }, @@ -106,13 +130,20 @@ pub fn main(init: std.process.Init) !void { .swapchain = swapchain, }); - // --- MISC --- + // + // MISC + // + var event: sdl.SDL_Event = undefined; var running: bool = true; var i: f32 = 0; while (running) { - // --- INPUTS --- + + // + // INPUTS + // + while (sdl.SDL_PollEvent(&event)) { switch (event.type) { sdl.SDL_EVENT_QUIT => running = false, @@ -120,17 +151,22 @@ pub fn main(init: std.process.Init) !void { } } - // --- ANIMATION --- i += 0.001; i = @mod(i, 1); material.albedo[1] = i; try pipeline.setUniform("material", material); - // --- FRAME --- + // + // FRAME + // + try gfx.beginFrame(swapchain, device); defer gfx.endFrame(swapchain, device) catch unreachable; - // --- NEW PASS --- + // + // PASS + // + if (gfx.beginPass(swapchain, .{ .clear_color = .{ 0.01, 0.01, 0.01, 1.0 }, })) |pass| { @@ -143,7 +179,6 @@ pub fn main(init: std.process.Init) !void { pass.drawIndexed(cmn.Square.indices.len, 1, 0, 0, 0); } - // --- NEW PASS --- // if (gfx.beginPass(swapchain, .{ // .load_op = .load, // })) |pass| { diff --git a/examples/simple_3D/simple_3D.zig b/examples/simple_3D/simple_3D.zig index a0ff307..8f50aed 100644 --- a/examples/simple_3D/simple_3D.zig +++ b/examples/simple_3D/simple_3D.zig @@ -34,7 +34,7 @@ pub fn main(init: std.process.Init) !void { .projection = .perspective(std.math.degreesToRadians(90), 800.0 / 600.0, 0.01, 1000), .view = .lookAt(.new(.{ 1, 1, -2 }), .new(.{ 0, 0, 1 }), .new(.{ 0, 1, 0 })), }; - const model: Model = .{ + var model: Model = .{ .matrix = math.Mat4x4.translate( 0, 0, @@ -52,15 +52,12 @@ pub fn main(init: std.process.Init) !void { // SDL // - // --- # --- if (!sdl.SDL_Init(sdl.SDL_INIT_VIDEO)) return error.FailedToInitSDL; defer sdl.SDL_Quit(); - // --- # --- const window = sdl.SDL_CreateWindow("NYXGFX", 800, 600, 0) orelse return error.FailedTomakeWindow; defer sdl.SDL_DestroyWindow(window); - // --- # --- const props = sdl.SDL_GetWindowProperties(window); const display = sdl.SDL_GetPointerProperty(props, sdl.SDL_PROP_WINDOW_X11_DISPLAY_POINTER, null); const xwindow = sdl.SDL_GetNumberProperty(props, sdl.SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0); @@ -75,42 +72,81 @@ pub fn main(init: std.process.Init) !void { ); defer gfx.deinit(); + // + // CORE + // + const instance = try gfx.makeInstance(.{ .vulkan = .{ .api_version = .v1_3, + .vk_13_features = .{}, }, }); const surface = try gfx.makeSurface(.{ - .xlib = .{ - .window = @intCast(xwindow), - .display = display.?, + .window = .{ + .xlib = .{ + .window = @intCast(xwindow), + .display = display.?, + }, }, - }, instance); + .instance = instance, + }); - const adapter = try gfx.makeAdapter(.{}, instance); - const device = try gfx.makeDevice(adapter, surface); - const swapchain = try gfx.makeSwapchain(adapter, device, surface); + const adapter = try gfx.makeAdapter(.{ + .instance = instance, + }); + + const device = try gfx.makeDevice(.{ + .instance = instance, + .adapter = adapter, + .surface = surface, + }); + + const swapchain = try gfx.makeSwapchain(.{ + .surface = surface, + .adapter = adapter, + .device = device, + }); + + // + // DEBUG + // if (gfx.getAdapterInfo(adapter)) |info| { std.debug.print("Name: {s} | Type: {s}\n", .{ info.name, @tagName(info.gpu_type) }); } - // --- TEXTURES --- - const texture = try gfx.makeTexture(.{ - .image = .{ .path = "examples/assets/textures/texture.jpg", .vertical_flip = true }, - .sampler = .{ .min_filter = .linear, .address_u = .repeat }, - }, adapter, device); + // + // TEXTURES + // + + const texture = try gfx.makeTexture(.{ + .image = .{ .path = "examples/assets/textures/texture.jpg" }, + .sampler = .{ .min_filter = .linear, .address_u = .repeat }, + + .adapter = adapter, + .device = device, + }); + + // + // BUFFERS + // - // --- BUFFERS --- const vbuf = try gfx.makeBuffer(cmn.Cube.vertices, .vertex, adapter, device); const ibuf = try gfx.makeBuffer(cmn.Cube.indices, .index, adapter, device); - // --- SHADERS --- + // + // SHADERS + // + const simple_vert = try gfx.makeShader("examples/assets/shaders/compiled/3D.vert.spv", device); const simple_frag = try gfx.makeShader("examples/assets/shaders/compiled/3D.frag.spv", device); - // --- PIPELINE --- + // + // PIPELINES + // + const pipeline = try gfx.makePipeline(.{ .vertex_attributes = &.{ .{ .location = 0, .format = .vec3, .offset = @offsetOf(cmn.Vertex, "pos") }, @@ -137,13 +173,20 @@ pub fn main(init: std.process.Init) !void { .swapchain = swapchain, }); - // --- MISC --- + // + // MISC + // + var event: sdl.SDL_Event = undefined; var running: bool = true; var i: f32 = 0; while (running) { - // --- INPUTS --- + + // + // INPUTS + // + while (sdl.SDL_PollEvent(&event)) { switch (event.type) { sdl.SDL_EVENT_QUIT => running = false, @@ -151,7 +194,6 @@ pub fn main(init: std.process.Init) !void { } } - // --- ANIMATION --- i += 0.001; i = @mod(i, 1); material.albedo[1] = i; @@ -160,29 +202,56 @@ pub fn main(init: std.process.Init) !void { .projection = camera.projection.transpose(), .view = camera.view.transpose(), }); - try pipeline.setUniform("model", Model{ - .matrix = model.matrix.transpose(), - }); - // --- FRAME --- + // + // FRAME + // + try gfx.beginFrame(swapchain, device); defer gfx.endFrame(swapchain, device) catch unreachable; - // --- NEW PASS --- + // + // PASS + // + if (gfx.beginPass(swapchain, .{ .clear_color = .{ 0.01, 0.01, 0.01, 1.0 }, .depth_enabled = true, })) |pass| { defer pass.end(); - try vbuf.bind(); - try ibuf.bind(); + for (0..4) |x| { + model = .{ + .matrix = math.Mat4x4.translate( + 0, + 0, + @floatFromInt(x), + ) + .mul(math.Quat.fromEuler(.init( + @as(f32, @floatFromInt(x)) * 0.1, + @as(f32, @floatFromInt(x)) * 0.15, + @as(f32, @floatFromInt(x)) * 0.13, + )).toMat4()) + .mul(math.Mat4x4.scale( + 1, + 1, + 1, + )), + }; - try pipeline.bind(); - pass.drawIndexed(cmn.Cube.indices.len, 1, 0, 0, 0); + try pipeline.bind(); + + try vbuf.bind(); + try ibuf.bind(); + + try pipeline.setUniform("model", Model{ + .matrix = model.matrix.transpose(), + }); + + pass.drawIndexed(cmn.Cube.indices.len, 1, 0, 0, 0); + } } - // --- NEW PASS --- if (gfx.beginPass(swapchain, .{ .load_op = .load, })) |pass| { diff --git a/imgui.ini b/imgui.ini index fb2edcd..d42849e 100644 --- a/imgui.ini +++ b/imgui.ini @@ -5,14 +5,14 @@ Collapsed=0 LastUsed=20260818 [Window][Inspector] -Pos=87,36 +Pos=65,34 Size=622,253 Collapsed=0 DockId=0x00000002,0 LastUsed=20260818 [Window][Dear ImGui Demo] -Pos=87,291 +Pos=65,289 Size=622,257 Collapsed=0 DockId=0x00000003,0 @@ -32,7 +32,7 @@ Column 2 Width=63 LastUsed=20260814 [Docking][Data] -DockNode ID=0x00000001 Pos=87,36 Size=622,512 Split=Y +DockNode ID=0x00000001 Pos=65,34 Size=622,512 Split=Y DockNode ID=0x00000002 Parent=0x00000001 SizeRef=361,237 Selected=0x36DC96AB DockNode ID=0x00000003 Parent=0x00000001 SizeRef=361,241 Selected=0x5E5F7166 diff --git a/src/gfx.zig b/src/gfx.zig index a640cc1..302fdff 100644 --- a/src/gfx.zig +++ b/src/gfx.zig @@ -15,6 +15,9 @@ pub const Handle = gtl.Handle; // --- CONFIGS --- pub const InstanceConfig = common.InstanceConfig; pub const AdapterConfig = common.AdapterConfig; +pub const DeviceConfig = common.DeviceConfig; +pub const SurfaceConfig = common.SurfaceConfig; +pub const SwapchainConfig = common.SwapchainConfig; pub const RenderPassConfig = common.RenderPassConfig; pub const PipelineConfig = common.PipelineConfig; pub const BufferUsage = common.BufferUsage; @@ -162,9 +165,9 @@ pub fn getRawFrame(self: *Self) !RawFrame { /// ---------------------------------------------------- /// ---------------------------------------------------- -pub fn makeAdapter(self: *Self, config: AdapterConfig, instance: Handle(Instance)) !Handle(Adapter) { +pub fn makeAdapter(self: *Self, config: AdapterConfig) !Handle(Adapter) { return try switch ((try self.getBackend()).*) { - .vulkan => |*v| v.makeAdapter(config, instance), + .vulkan => |*v| v.makeAdapter(config), }; } @@ -206,14 +209,9 @@ pub fn getRawAdapter(self: *Self, adapter: Handle(Adapter)) !RawAdapter { /// ---------------------------------------------------- /// ---------------------------------------------------- -pub fn makeDevice( - self: *Self, - instance: Handle(Instance), - adapter: Handle(Adapter), - surface: Handle(Surface), -) !Handle(Device) { +pub fn makeDevice(self: *Self, config: DeviceConfig) !Handle(Device) { return try switch ((try self.getBackend()).*) { - .vulkan => |*v| v.makeDevice(instance, adapter, surface), + .vulkan => |*v| v.makeDevice(config), }; } @@ -317,13 +315,9 @@ pub fn getRawBuffer(self: *Self, buffer: Handle(Buffer)) !RawBuffer { /// ---------------------------------------------------- /// ---------------------------------------------------- -pub fn makeSurface( - self: *Self, - window: Window, - instance: Handle(Instance), -) !Handle(Surface) { +pub fn makeSurface(self: *Self, config: SurfaceConfig) !Handle(Surface) { return try switch ((try self.getBackend()).*) { - .vulkan => |*v| v.makeSurface(instance, window), + .vulkan => |*v| v.makeSurface(config), }; } @@ -333,14 +327,9 @@ pub fn makeSurface( /// ---------------------------------------------------- /// ---------------------------------------------------- -pub fn makeSwapchain( - self: *Self, - adapter: Handle(Adapter), - device: Handle(Device), - surface: Handle(Surface), -) !Handle(Swapchain) { +pub fn makeSwapchain(self: *Self, config: SwapchainConfig) !Handle(Swapchain) { return try switch ((try self.getBackend()).*) { - .vulkan => |*v| v.makeSwapchain(adapter, device, surface), + .vulkan => |*v| v.makeSwapchain(config), }; } @@ -473,14 +462,9 @@ pub fn makeSampler( /// ---------------------------------------------------- /// ---------------------------------------------------- -pub fn makeTexture( - self: *Self, - config: TextureConfig, - adapter: Handle(Adapter), - device: Handle(Device), -) !Handle(Texture) { +pub fn makeTexture(self: *Self, config: TextureConfig) !Handle(Texture) { return try switch ((try self.getBackend()).*) { - .vulkan => |*v| v.makeTexture(config, adapter, device), + .vulkan => |*v| v.makeTexture(config), }; } diff --git a/src/rhi/common.zig b/src/rhi/common.zig index 2a0174e..dc0b79a 100644 --- a/src/rhi/common.zig +++ b/src/rhi/common.zig @@ -137,15 +137,36 @@ pub const Window = union(enum) { pub const AdapterConfig = struct { device_type: DeviceType = .discrete, index: ?u32 = null, + + instance: Handle(Instance), }; /// ---------------------------------------------------- /// ---------------------------------------------------- pub const DeviceConfig = struct { + instance: Handle(Instance), adapter: Handle(Adapter), surface: Handle(Surface), }; +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub const SurfaceConfig = struct { + window: Window, + instance: Handle(Instance), +}; + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub const SwapchainConfig = struct { + format: TextureFormat = .bgra8_srgb, + size: ?[2]u32 = null, + + surface: Handle(Surface), + adapter: Handle(Adapter), + device: Handle(Device), +}; + /// ---------------------------------------------------- /// ---------------------------------------------------- pub const Format = enum { @@ -346,7 +367,7 @@ pub const BufferSharingMode = enum { /// ---------------------------------------------------- /// ---------------------------------------------------- -pub const PixelFormat = enum { +pub const TextureFormat = enum { rgba8_unorm, rgba8_srgb, bgra8_unorm, @@ -398,7 +419,7 @@ pub const ImageConfig = struct { vertical_flip: bool = false, - format: PixelFormat = .rgba8_srgb, + format: TextureFormat = .rgba8_srgb, usage: ImageUsage = .texture, mip_levels: u32 = 1, }; @@ -421,6 +442,9 @@ pub const SamplerConfig = struct { pub const TextureConfig = struct { image: ImageConfig = .{}, sampler: SamplerConfig = .{}, + + adapter: Handle(Adapter), + device: Handle(Device), }; // diff --git a/src/rhi/vulkan/helper.zig b/src/rhi/vulkan/helper.zig new file mode 100644 index 0000000..812cd2b --- /dev/null +++ b/src/rhi/vulkan/helper.zig @@ -0,0 +1,56 @@ +//! ---------------------------------------------------- +//! `🗲` Vulkan Helper `🗲` +//! ---------------------------------------------------- + +const vk = @import("vulkan"); +const cmn = @import("../common.zig"); + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub fn check(result: vk.VkResult) bool { + return result == vk.VK_SUCCESS; +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub fn toRawAPIVersion(version: cmn.VKAPIVersion) u32 { + return switch (version) { + .v1_0 => vk.VK_API_VERSION_1_0, + .v1_1 => vk.VK_API_VERSION_1_1, + .v1_2 => vk.VK_API_VERSION_1_2, + .v1_3 => vk.VK_API_VERSION_1_3, + .v1_4 => vk.VK_API_VERSION_1_4, + }; +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub fn toRawDeviceType(device_type: cmn.DeviceType) vk.VkPhysicalDeviceType { + return switch (device_type) { + .discrete => vk.VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, + .integrated => vk.VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, + .software => vk.VK_PHYSICAL_DEVICE_TYPE_CPU, + }; +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub fn toRawBufferUsage(usage: cmn.BufferUsage) vk.VkBufferUsageFlagBits { + return switch (usage) { + .vertex => vk.VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, + .index => vk.VK_BUFFER_USAGE_INDEX_BUFFER_BIT, + .image => vk.VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + }; +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub fn toRawPixelFormat(format: cmn.TextureFormat) vk.VkFormat { + return switch (format) { + .rgba8_srgb => vk.VK_FORMAT_R8G8B8A8_SRGB, + .bgra8_srgb => vk.VK_FORMAT_B8G8R8A8_SRGB, + + .rgba8_unorm => vk.VK_FORMAT_R8G8B8A8_UNORM, + .bgra8_unorm => vk.VK_FORMAT_B8G8R8A8_UNORM, + }; +} diff --git a/src/rhi/vulkan/resource/adapter.zig b/src/rhi/vulkan/resource/adapter.zig index 71fe08a..110abb4 100644 --- a/src/rhi/vulkan/resource/adapter.zig +++ b/src/rhi/vulkan/resource/adapter.zig @@ -2,9 +2,10 @@ //! `🗲` Vulkan Adapter `🗲` //! ---------------------------------------------------- +const vk = @import("vulkan"); +const hp = @import("../helper.zig"); const std = @import("std"); const gtl = @import("gtl"); -const vk = @import("vulkan"); const common = @import("../../common.zig"); const VKBackend = @import("../vulkan.zig"); const AdapterConfig = common.AdapterConfig; @@ -28,14 +29,14 @@ pub fn init( ) !Self { // --- GET ADAPTER COUNT --- var count: u32 = 0; - if (vk.vkEnumeratePhysicalDevices(instance.raw, &count, null) != vk.VK_SUCCESS) {} + if (!hp.check(vk.vkEnumeratePhysicalDevices(instance.raw, &count, null))) {} // --- CREATE LIST OF ADAPTERS --- const items = try alloc.alloc(vk.VkPhysicalDevice, count); defer alloc.free(items); // --- POPULATE ADAPTERS LIST --- - if (vk.vkEnumeratePhysicalDevices(instance.raw, &count, items.ptr) != vk.VK_SUCCESS) {} + if (!hp.check(vk.vkEnumeratePhysicalDevices(instance.raw, &count, items.ptr))) {} // --- CHECK ADAPTER --- var raw: vk.VkPhysicalDevice = null; @@ -71,13 +72,9 @@ pub fn init( vk.vkGetPhysicalDeviceProperties2(adapter, &props); vk.vkGetPhysicalDeviceFeatures2(adapter, &features); - const api_version: u32 = switch (instance.api_version) { - .v1_0 => vk.VK_API_VERSION_1_0, - .v1_1 => vk.VK_API_VERSION_1_1, - .v1_2 => vk.VK_API_VERSION_1_2, - .v1_3 => vk.VK_API_VERSION_1_3, - .v1_4 => vk.VK_API_VERSION_1_4, - }; + const api_version: u32 = hp.toRawAPIVersion( + instance.api_version, + ); const adapter_type: DeviceType = switch (props.properties.deviceType) { vk.VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU => .discrete, diff --git a/src/rhi/vulkan/resource/buffer.zig b/src/rhi/vulkan/resource/buffer.zig index e34283d..2efcce3 100644 --- a/src/rhi/vulkan/resource/buffer.zig +++ b/src/rhi/vulkan/resource/buffer.zig @@ -2,8 +2,9 @@ //! `🗲` Vulkan Buffer `🗲` //! ---------------------------------------------------- -const std = @import("std"); const vk = @import("vulkan"); +const hp = @import("../helper.zig"); +const std = @import("std"); const Self = @This(); const common = @import("../../common.zig"); @@ -35,11 +36,7 @@ pub fn init( ) !Self { var info: vk.VkBufferCreateInfo = .{ .sType = vk.VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, - .usage = switch (usage) { - .vertex => vk.VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, - .index => vk.VK_BUFFER_USAGE_INDEX_BUFFER_BIT, - .image => vk.VK_BUFFER_USAGE_TRANSFER_SRC_BIT, - }, + .usage = hp.toRawBufferUsage(usage), .sharingMode = switch (sharing) { .exclusive => vk.VK_SHARING_MODE_EXCLUSIVE, }, @@ -47,7 +44,7 @@ pub fn init( }; var raw: vk.VkBuffer = null; - if (vk.vkCreateBuffer(device.raw, &info, null, &raw) != vk.VK_SUCCESS) { + if (!hp.check(vk.vkCreateBuffer(device.raw, &info, null, &raw))) { return error.FailedToCreateBuffer; } @@ -101,7 +98,7 @@ pub fn set( .memoryTypeIndex = mem_type, }; - if (vk.vkAllocateMemory(self.device.raw, &alloc_info, null, &self.data) != vk.VK_SUCCESS) { + if (!hp.check(vk.vkAllocateMemory(self.device.raw, &alloc_info, null, &self.data))) { return error.FailedToAllocateMemory; } @@ -119,12 +116,11 @@ pub fn set( &mapped, ); - if (result != vk.VK_SUCCESS) { + if (!hp.check(result)) { return error.FailedToMapMemory; } const dst: [*]u8 = @ptrCast(mapped.?); - const src: [*]const u8 = switch (@typeInfo(@TypeOf(value))) { .optional => @ptrCast(value.?), .pointer => @ptrCast(value), @@ -132,6 +128,5 @@ pub fn set( }; @memcpy(dst[0..size], src[0..size]); - vk.vkUnmapMemory(self.device.raw, self.data); } diff --git a/src/rhi/vulkan/resource/device.zig b/src/rhi/vulkan/resource/device.zig index 1b0bbfb..847c31e 100644 --- a/src/rhi/vulkan/resource/device.zig +++ b/src/rhi/vulkan/resource/device.zig @@ -2,8 +2,9 @@ //! `🗲` Vulkan Device `🗲` //! ---------------------------------------------------- -const std = @import("std"); const vk = @import("vulkan"); +const hp = @import("../helper.zig"); +const std = @import("std"); const Self = @This(); const Instance = @import("instance.zig"); @@ -108,7 +109,7 @@ pub fn init( // --- # --- var device: vk.VkDevice = null; - if (vk.vkCreateDevice(adapter.raw, &create_info, null, &device) != vk.VK_SUCCESS) { + if (!hp.check(vk.vkCreateDevice(adapter.raw, &create_info, null, &device))) { return error.FailedToCreateVulkanDevice; } @@ -119,7 +120,7 @@ pub fn init( .queueFamilyIndex = queue_families.graphics.?, }; var graphics_command_pool: vk.VkCommandPool = null; - if (vk.vkCreateCommandPool(device, &pool_info, null, &graphics_command_pool) != vk.VK_SUCCESS) { + if (!hp.check(vk.vkCreateCommandPool(device, &pool_info, null, &graphics_command_pool))) { return error.FailedToCreateCommandPool; } diff --git a/src/rhi/vulkan/resource/image.zig b/src/rhi/vulkan/resource/image.zig index 3d86641..cc8bbde 100644 --- a/src/rhi/vulkan/resource/image.zig +++ b/src/rhi/vulkan/resource/image.zig @@ -2,8 +2,9 @@ //! `🗲` Vulkan Image `🗲` //! ---------------------------------------------------- -const std = @import("std"); const vk = @import("vulkan"); +const hp = @import("../helper.zig"); +const std = @import("std"); const stb = @import("stb_image"); const common = @import("../../common.zig"); const Self = @This(); @@ -83,12 +84,9 @@ pub fn init( self.mip_levels = config.mip_levels; // --- FORMAT --- - self.format = switch (config.format) { - .rgba8_unorm => vk.VK_FORMAT_R8G8B8A8_UNORM, - .rgba8_srgb => vk.VK_FORMAT_R8G8B8A8_SRGB, - .bgra8_unorm => vk.VK_FORMAT_B8G8R8A8_UNORM, - .bgra8_srgb => vk.VK_FORMAT_B8G8R8A8_SRGB, - }; + self.format = hp.toRawPixelFormat( + config.format, + ); // --- IMAGE --- var usage: vk.VkImageUsageFlags = vk.VK_IMAGE_USAGE_TRANSFER_DST_BIT | vk.VK_IMAGE_USAGE_SAMPLED_BIT; diff --git a/src/rhi/vulkan/resource/instance.zig b/src/rhi/vulkan/resource/instance.zig index f269979..95498e2 100644 --- a/src/rhi/vulkan/resource/instance.zig +++ b/src/rhi/vulkan/resource/instance.zig @@ -3,6 +3,7 @@ //! ---------------------------------------------------- const vk = @import("vulkan"); +const hp = @import("../helper.zig"); const std = @import("std"); const cmn = @import("../../common.zig"); const gtl = @import("gtl"); @@ -93,7 +94,7 @@ pub fn init(config: cmn.VKInstanceConfig, alloc: std.mem.Allocator) !Self { // } var instance: vk.VkInstance = null; - if (vk.vkCreateInstance(&create_info, null, &instance) != vk.VK_SUCCESS) { + if (!hp.check(vk.vkCreateInstance(&create_info, null, &instance))) { return error.FailedToCreateVulkanInstance; } errdefer vk.vkDestroyInstance(instance.?, null); diff --git a/src/rhi/vulkan/resource/pipeline.zig b/src/rhi/vulkan/resource/pipeline.zig index 00b710c..8efc3f4 100644 --- a/src/rhi/vulkan/resource/pipeline.zig +++ b/src/rhi/vulkan/resource/pipeline.zig @@ -2,8 +2,9 @@ //! `🗲` Vulkan Pipeline `🗲` //! ---------------------------------------------------- -const std = @import("std"); const vk = @import("vulkan"); +const hp = @import("../helper.zig"); +const std = @import("std"); const gtl = @import("gtl"); const common = @import("../../common.zig"); const VulkanRHI = @import("../vulkan.zig"); @@ -14,6 +15,7 @@ const Swapchain = @import("swapchain.zig"); const VKTexture = @import("texture.zig"); const Config = common.PipelineConfig; const UniformDesc = common.UniformDesc; + const MAX_FRAMES_IN_FLIGHT = VulkanRHI.MAX_FRAMES_IN_FLIGHT; const MAX_BINDINGS = 16; const MAX_TEXTURES = 16; @@ -128,7 +130,7 @@ pub fn init( .pBindings = &bindings, }; - if (vk.vkCreateDescriptorSetLayout(device.raw, &set_layout_info, null, &set_layout) != vk.VK_SUCCESS) { + if (!hp.check(vk.vkCreateDescriptorSetLayout(device.raw, &set_layout_info, null, &set_layout))) { return error.FailedToCreateDescriptorSetLayout; } self.descriptor_set_layout = set_layout.?; @@ -141,7 +143,7 @@ pub fn init( }; var pipeline_layout: vk.VkPipelineLayout = null; - if (vk.vkCreatePipelineLayout(device.raw, &pipeline_layout_info, null, &pipeline_layout) != vk.VK_SUCCESS) { + if (!hp.check(vk.vkCreatePipelineLayout(device.raw, &pipeline_layout_info, null, &pipeline_layout))) { return error.FailedToCreatePipelineLayout; } self.layout = pipeline_layout.?; @@ -364,7 +366,7 @@ pub fn init( }; var pipeline: vk.VkPipeline = null; - if (vk.vkCreateGraphicsPipelines(device.raw, null, 1, &pipeline_info, null, &pipeline) != vk.VK_SUCCESS) { + if (!hp.check(vk.vkCreateGraphicsPipelines(device.raw, null, 1, &pipeline_info, null, &pipeline))) { return error.FailedToCreateGraphicsPipelines; } self.raw = pipeline.?; @@ -408,7 +410,7 @@ pub fn init( }; var descriptor_pool: vk.VkDescriptorPool = null; - if (vk.vkCreateDescriptorPool(device.raw, &pool_info, null, &descriptor_pool) != vk.VK_SUCCESS) { + if (!hp.check(vk.vkCreateDescriptorPool(device.raw, &pool_info, null, &descriptor_pool))) { return error.FailedToCreateDescriptorPool; } self.descriptor_pool = descriptor_pool.?; @@ -424,7 +426,7 @@ pub fn init( }; var uniform_buffer: vk.VkBuffer = null; - if (vk.vkCreateBuffer(device.raw, &buffer_info, null, &uniform_buffer) != vk.VK_SUCCESS) { + if (!hp.check(vk.vkCreateBuffer(device.raw, &buffer_info, null, &uniform_buffer))) { return error.FailedToCreateUniformBuffer; } self.uniform_buffers[frame] = uniform_buffer.?; @@ -454,7 +456,7 @@ pub fn init( }; var uniform_memory: vk.VkDeviceMemory = null; - if (vk.vkAllocateMemory(device.raw, &alloc_info, null, &uniform_memory) != vk.VK_SUCCESS) { + if (!hp.check(vk.vkAllocateMemory(device.raw, &alloc_info, null, &uniform_memory))) { return error.FailedToAllocateUniformMemory; } self.uniform_memories[frame] = uniform_memory; @@ -470,7 +472,7 @@ pub fn init( .pSetLayouts = @ptrCast(&self.descriptor_set_layout), }; - if (vk.vkAllocateDescriptorSets(device.raw, &set_alloc_info, &self.descriptor_sets[frame]) != vk.VK_SUCCESS) { + if (!hp.check(vk.vkAllocateDescriptorSets(device.raw, &set_alloc_info, &self.descriptor_sets[frame]))) { return error.FailedToAllocateDescriptorSets; } @@ -564,14 +566,14 @@ pub fn setUniform(self: *Self, name: []const u8, value: anytype) !void { } var mapped: ?*anyopaque = null; - if (vk.vkMapMemory( + if (!hp.check(vk.vkMapMemory( self.device.raw, uniform_memory, self.uniform_offsets[i], uniform.size, 0, &mapped, - ) != vk.VK_SUCCESS) { + ))) { return error.FailedToMapMemory; } diff --git a/src/rhi/vulkan/resource/sampler.zig b/src/rhi/vulkan/resource/sampler.zig index 0a329f9..d9d7dd1 100644 --- a/src/rhi/vulkan/resource/sampler.zig +++ b/src/rhi/vulkan/resource/sampler.zig @@ -2,8 +2,9 @@ //! `🗲` Vulkan Sampler `🗲` //! ---------------------------------------------------- -const std = @import("std"); const vk = @import("vulkan"); +const hp = @import("../helper.zig"); +const std = @import("std"); const common = @import("../../common.zig"); const Self = @This(); @@ -68,7 +69,7 @@ pub fn init( }; var sampler: vk.VkSampler = null; - if (vk.vkCreateSampler(device.raw, &create_info, null, &sampler) != vk.VK_SUCCESS) { + if (!hp.check(vk.vkCreateSampler(device.raw, &create_info, null, &sampler))) { return error.FailedToCreateSampler; } diff --git a/src/rhi/vulkan/resource/shader.zig b/src/rhi/vulkan/resource/shader.zig index 1a5a354..d836512 100644 --- a/src/rhi/vulkan/resource/shader.zig +++ b/src/rhi/vulkan/resource/shader.zig @@ -2,8 +2,9 @@ //! `🗲` Vulkan Shader `🗲` //! ---------------------------------------------------- -const std = @import("std"); const vk = @import("vulkan"); +const hp = @import("../helper.zig"); +const std = @import("std"); const gtl = @import("gtl"); const Device = @import("device.zig"); const Self = @This(); @@ -57,7 +58,7 @@ fn createModule( }; var module: vk.VkShaderModule = null; - if (vk.vkCreateShaderModule(device.raw, &create_info, null, &module) != vk.VK_SUCCESS) { + if (!hp.check(vk.vkCreateShaderModule(device.raw, &create_info, null, &module))) { return error.FailedToCreateShaderModule; } diff --git a/src/rhi/vulkan/resource/surface.zig b/src/rhi/vulkan/resource/surface.zig index 37c1ffc..176fb76 100644 --- a/src/rhi/vulkan/resource/surface.zig +++ b/src/rhi/vulkan/resource/surface.zig @@ -2,8 +2,9 @@ //! `🗲` Vulkan Surface `🗲` //! ---------------------------------------------------- -const std = @import("std"); const vk = @import("vulkan"); +const hp = @import("../helper.zig"); +const std = @import("std"); const Window = @import("../../common.zig").Window; const Self = @This(); @@ -31,7 +32,7 @@ pub fn init( .dpy = @ptrCast(v.display), }; - if (vk.vkCreateXlibSurfaceKHR(instance.raw, &info, null, &raw) != vk.VK_SUCCESS) { + if (!hp.check(vk.vkCreateXlibSurfaceKHR(instance.raw, &info, null, &raw))) { return error.FailedToCreateXlibSurfaceKHR; } diff --git a/src/rhi/vulkan/resource/swapchain.zig b/src/rhi/vulkan/resource/swapchain.zig index ed8daa8..e238f9e 100644 --- a/src/rhi/vulkan/resource/swapchain.zig +++ b/src/rhi/vulkan/resource/swapchain.zig @@ -2,22 +2,17 @@ //! `🗲` Vulkan Swapchain `🗲` //! ---------------------------------------------------- +const vk = @import("vulkan"); +const hp = @import("../helper.zig"); const std = @import("std"); const gtl = @import("gtl"); -const vk = @import("vulkan"); +const cmn = @import("../../common.zig"); const Self = @This(); const Adapter = @import("adapter.zig"); const Device = @import("device.zig"); const Surface = @import("surface.zig"); -/// ---------------------------------------------------- -/// ---------------------------------------------------- -pub const Config = struct { - width: u32, - height: u32, -}; - // // FIELDS // @@ -44,7 +39,7 @@ pub fn init( adapter: *const Adapter, device: *const Device, surface: *const Surface, - config: Config, + config: cmn.SwapchainConfig, alloc: std.mem.Allocator, ) !Self { // --- # --- @@ -70,13 +65,17 @@ pub fn init( // --- # --- const extent: vk.VkExtent2D = blk: { if (capabilities.currentExtent.width != std.math.maxInt(u32)) break :blk capabilities.currentExtent; - break :blk .{ .width = config.width, .height = config.height }; + if (config.size) |size| break :blk .{ .width = size[0], .height = size[1] }; + break :blk .{ .width = 0, .height = 0 }; }; // --- # --- const format: vk.VkSurfaceFormatKHR = blk: { for (formats) |v| { - if (v.format == vk.VK_FORMAT_B8G8R8A8_SRGB and v.colorSpace == vk.VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) { + // if (v.format == vk.VK_FORMAT_B8G8R8A8_SRGB and v.colorSpace == vk.VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) { + // break :blk v; + // } + if (v.format == hp.toRawPixelFormat(config.format)) { break :blk v; } } @@ -110,7 +109,7 @@ pub fn init( }; var swapchain: vk.VkSwapchainKHR = null; - if (vk.vkCreateSwapchainKHR(device.raw, &create_info, null, &swapchain) != vk.VK_SUCCESS) { + if (!hp.check(vk.vkCreateSwapchainKHR(device.raw, &create_info, null, &swapchain))) { return error.FailedToCreateSwapchainKHR; } diff --git a/src/rhi/vulkan/vulkan.zig b/src/rhi/vulkan/vulkan.zig index e2c24e3..8688187 100644 --- a/src/rhi/vulkan/vulkan.zig +++ b/src/rhi/vulkan/vulkan.zig @@ -1,10 +1,10 @@ //! ---------------------------------------------------- -//! `🗲` Vulkan RHI 1.4 `🗲` -//! 😭 Send Help 😭 +//! `🗲` Vulkan RHI `🗲` //! ---------------------------------------------------- const std = @import("std"); const vk = @import("vulkan"); +const hp = @import("helper.zig"); const gtl = @import("gtl"); const common = @import("../common.zig"); @@ -47,7 +47,7 @@ const Texture = common.Texture; const AdapterInfo = common.AdapterInfo; // --- # --- -pub const MAX_FRAMES_IN_FLIGHT: usize = 3; +pub const MAX_FRAMES_IN_FLIGHT: usize = 2; /// ---------------------------------------------------- /// ---------------------------------------------------- @@ -66,7 +66,7 @@ const Frame = struct { resource: Resource, -frames: [MAX_FRAMES_IN_FLIGHT]Frame = .{ .{}, .{}, .{} }, +frames: [MAX_FRAMES_IN_FLIGHT]Frame = [_]Frame{.{}} ** MAX_FRAMES_IN_FLIGHT, current_frame: usize = 0, active_pass_target: ?Handle(Texture) = null, @@ -151,8 +151,8 @@ pub fn releaseInstance(self: *Self, instance: Handle(common.Instance)) void { /// ---------------------------------------------------- /// ---------------------------------------------------- -pub fn makeAdapter(self: *Self, config: AdapterConfig, instance: Handle(common.Instance)) !Handle(Adapter) { - const raw_instance = self.resource.instances.get(instance) orelse return error.InstanceNotFound; +pub fn makeAdapter(self: *Self, config: AdapterConfig) !Handle(Adapter) { + const raw_instance = self.resource.instances.get(config.instance) orelse return error.InstanceNotFound; return try self.resource.adapters.put(try .init(config, raw_instance, self.alloc)); } @@ -204,15 +204,10 @@ pub fn getRawAdapter(self: *Self, adapter: Handle(Adapter)) !*vk.VkPhysicalDevic /// ---------------------------------------------------- /// ---------------------------------------------------- -pub fn makeDevice( - self: *Self, - instance: Handle(common.Instance), - adapter: Handle(Adapter), - surface: Handle(Surface), -) !Handle(Device) { - const raw_instance = self.resource.instances.get(instance) orelse return error.InstanceNotFound; - const raw_adapter = self.resource.adapters.get(adapter) orelse return error.AdapterNotFound; - const raw_surface = self.resource.surfaces.get(surface) orelse return error.SurfaceNotFound; +pub fn makeDevice(self: *Self, config: common.DeviceConfig) !Handle(Device) { + const raw_instance = self.resource.instances.get(config.instance) orelse return error.InstanceNotFound; + const raw_adapter = self.resource.adapters.get(config.adapter) orelse return error.AdapterNotFound; + const raw_surface = self.resource.surfaces.get(config.surface) orelse return error.SurfaceNotFound; return try self.resource.devices.put(try .init(raw_instance, raw_adapter, raw_surface, self.alloc)); } @@ -246,13 +241,9 @@ pub fn getRawDevice(self: *Self, device: Handle(Device)) !*vk.VkDevice_T { /// ---------------------------------------------------- /// ---------------------------------------------------- -pub fn makeSurface( - self: *Self, - instance: Handle(common.Instance), - window: Window, -) !Handle(Surface) { - const raw_instance = self.resource.instances.get(instance) orelse return error.InstanceNotFound; - return try self.resource.surfaces.put(try .init(raw_instance, window)); +pub fn makeSurface(self: *Self, config: common.SurfaceConfig) !Handle(Surface) { + const raw_instance = self.resource.instances.get(config.instance) orelse return error.InstanceNotFound; + return try self.resource.surfaces.put(try .init(raw_instance, config.window)); } // @@ -261,23 +252,11 @@ pub fn makeSurface( /// ---------------------------------------------------- /// ---------------------------------------------------- -pub fn makeSwapchain( - self: *Self, - adapter: Handle(Adapter), - device: Handle(Device), - surface: Handle(Surface), -) !Handle(Swapchain) { - const raw_adapter = self.resource.adapters.get(adapter) orelse return error.AdapterNotFound; - const raw_device = self.resource.devices.get(device) orelse return error.DeviceNotFound; - const raw_surface = self.resource.surfaces.get(surface) orelse return error.SurfaceNotFound; - - return try self.resource.swapchains.put(try .init( - raw_adapter, - raw_device, - raw_surface, - .{ .width = 800, .height = 600 }, - self.alloc, - )); +pub fn makeSwapchain(self: *Self, config: common.SwapchainConfig) !Handle(Swapchain) { + const raw_surface = self.resource.surfaces.get(config.surface) orelse return error.SurfaceNotFound; + const raw_adapter = self.resource.adapters.get(config.adapter) orelse return error.AdapterNotFound; + const raw_device = self.resource.devices.get(config.device) orelse return error.DeviceNotFound; + return try self.resource.swapchains.put(try .init(raw_adapter, raw_device, raw_surface, config, self.alloc)); } /// ---------------------------------------------------- @@ -387,14 +366,9 @@ pub fn makeSampler( /// ---------------------------------------------------- /// ---------------------------------------------------- -pub fn makeTexture( - self: *Self, - config: TextureConfig, - adapter: Handle(Adapter), - device: Handle(Device), -) !Handle(Texture) { - const raw_adapter = self.resource.adapters.get(adapter) orelse return error.AdapterNotFound; - const raw_device = self.resource.devices.get(device) orelse return error.DeviceNotFound; +pub fn makeTexture(self: *Self, config: TextureConfig) !Handle(Texture) { + const raw_adapter = self.resource.adapters.get(config.adapter) orelse return error.AdapterNotFound; + const raw_device = self.resource.devices.get(config.device) orelse return error.DeviceNotFound; return try self.resource.textures.put(try .init(config, raw_adapter, raw_device)); } @@ -970,14 +944,15 @@ pub fn setUniform(self: *Self, pipeline: Handle(Pipeline), name: []const u8, val /// ---------------------------------------------------- /// ---------------------------------------------------- pub fn draw(self: *Self, vertex_count: u32, instance_count: u32, first_vertex: u32, first_instance: u32) void { - vk.vkCmdDraw(self.currentFrame().cmd_buf, vertex_count, instance_count, first_vertex, first_instance); + if (self.currentFrame().cmd_buf) |cmd| { + vk.vkCmdDraw(cmd, vertex_count, instance_count, first_vertex, first_instance); + } } /// ---------------------------------------------------- /// ---------------------------------------------------- pub fn drawIndexed(self: *Self, index_count: u32, instance_count: u32, first_index: u32, vertex_offset: i32, first_instance: u32) void { - const frame = self.currentFrame(); - if (frame.cmd_buf) |cmd| { + if (self.currentFrame().cmd_buf) |cmd| { vk.vkCmdDrawIndexed(cmd, index_count, instance_count, first_index, vertex_offset, first_instance); } }