Config style and cleanup

This commit is contained in:
abux 2026-08-19 14:47:03 +01:00
parent 15c978dc5a
commit 43eec1152f
18 changed files with 369 additions and 219 deletions

View file

@ -36,28 +36,39 @@ pub fn main(init: std.process.Init) !void {
// GFX // GFX
// //
// --- # --- var gfx: Gfx = try .init(init.gpa, init.io);
var gfx: Gfx = try .init(
init.gpa,
init.io,
);
defer gfx.deinit(); defer gfx.deinit();
// --- # ---
const instance = try gfx.makeInstance(.{ const instance = try gfx.makeInstance(.{
.vulkan = .{}, .vulkan = .{},
}); });
const surface = try gfx.makeSurface(.{ const surface = try gfx.makeSurface(.{
.window = .{
.xlib = .{ .xlib = .{
.window = @intCast(xwindow), .window = @intCast(xwindow),
.display = display.?, .display = display.?,
}, },
}, instance); },
.instance = instance,
});
const adapter = try gfx.makeAdapter(.{}, instance); const adapter = try gfx.makeAdapter(.{
const device = try gfx.makeDevice(instance, adapter, surface); .instance = instance,
const swapchain = try gfx.makeSwapchain(adapter, device, surface); });
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 // IMGUI

View file

@ -20,15 +20,12 @@ pub fn main(init: std.process.Init) !void {
// SDL // SDL
// //
// --- # ---
if (!sdl.SDL_Init(sdl.SDL_INIT_VIDEO)) return error.FailedToInitSDL; if (!sdl.SDL_Init(sdl.SDL_INIT_VIDEO)) return error.FailedToInitSDL;
defer sdl.SDL_Quit(); defer sdl.SDL_Quit();
// --- # ---
const window = sdl.SDL_CreateWindow("NYXGFX", 800, 600, 0) orelse return error.FailedTomakeWindow; const window = sdl.SDL_CreateWindow("NYXGFX", 800, 600, 0) orelse return error.FailedTomakeWindow;
defer sdl.SDL_DestroyWindow(window); defer sdl.SDL_DestroyWindow(window);
// --- # ---
const props = sdl.SDL_GetWindowProperties(window); const props = sdl.SDL_GetWindowProperties(window);
const display = sdl.SDL_GetPointerProperty(props, sdl.SDL_PROP_WINDOW_X11_DISPLAY_POINTER, null); 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); 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 // GFX
// //
// --- # --- var gfx: Gfx = try .init(init.gpa, init.io);
var gfx: Gfx = try .init(
init.gpa,
init.io,
);
defer gfx.deinit(); defer gfx.deinit();
// --- # --- //
// CORE
//
const instance = try gfx.makeInstance(.{ const instance = try gfx.makeInstance(.{
.vulkan = .{ .vulkan = .{
.api_version = .v1_3, .api_version = .v1_3,
.vk_14_features = .{ .vk_13_features = .{},
.dynamic_rendering_local_read = false,
},
}, },
}); });
const surface = try gfx.makeSurface(.{ const surface = try gfx.makeSurface(.{
.window = .{
.xlib = .{ .xlib = .{
.window = @intCast(xwindow), .window = @intCast(xwindow),
.display = display.?, .display = display.?,
}, },
}, instance); },
.instance = instance,
});
const adapter = try gfx.makeAdapter(.{}, instance); const adapter = try gfx.makeAdapter(.{
const device = try gfx.makeDevice(instance, adapter, surface); .instance = instance,
const swapchain = try gfx.makeSwapchain(adapter, device, surface); });
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(.{ const texture = try gfx.makeTexture(.{
.image = .{ .path = "examples/assets/textures/bully.jpg" }, .image = .{ .path = "examples/assets/textures/bully.jpg" },
.sampler = .{ .min_filter = .linear, .address_u = .repeat }, .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 vbuf = try gfx.makeBuffer(cmn.Square.vertices, .vertex, adapter, device);
const ibuf = try gfx.makeBuffer(cmn.Square.indices, .index, 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_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); const simple_frag = try gfx.makeShader("examples/assets/shaders/compiled/simple.frag.spv", device);
// --- PIPELINE --- //
// PIPELINES
//
const pipeline = try gfx.makePipeline(.{ const pipeline = try gfx.makePipeline(.{
.vertex_attributes = &.{ .vertex_attributes = &.{
.{ .location = 0, .format = .vec3, .offset = @offsetOf(cmn.Vertex, "pos") }, .{ .location = 0, .format = .vec3, .offset = @offsetOf(cmn.Vertex, "pos") },
@ -106,13 +130,20 @@ pub fn main(init: std.process.Init) !void {
.swapchain = swapchain, .swapchain = swapchain,
}); });
// --- MISC --- //
// MISC
//
var event: sdl.SDL_Event = undefined; var event: sdl.SDL_Event = undefined;
var running: bool = true; var running: bool = true;
var i: f32 = 0; var i: f32 = 0;
while (running) { while (running) {
// --- INPUTS ---
//
// INPUTS
//
while (sdl.SDL_PollEvent(&event)) { while (sdl.SDL_PollEvent(&event)) {
switch (event.type) { switch (event.type) {
sdl.SDL_EVENT_QUIT => running = false, sdl.SDL_EVENT_QUIT => running = false,
@ -120,17 +151,22 @@ pub fn main(init: std.process.Init) !void {
} }
} }
// --- ANIMATION ---
i += 0.001; i += 0.001;
i = @mod(i, 1); i = @mod(i, 1);
material.albedo[1] = i; material.albedo[1] = i;
try pipeline.setUniform("material", material); try pipeline.setUniform("material", material);
// --- FRAME --- //
// FRAME
//
try gfx.beginFrame(swapchain, device); try gfx.beginFrame(swapchain, device);
defer gfx.endFrame(swapchain, device) catch unreachable; defer gfx.endFrame(swapchain, device) catch unreachable;
// --- NEW PASS --- //
// PASS
//
if (gfx.beginPass(swapchain, .{ if (gfx.beginPass(swapchain, .{
.clear_color = .{ 0.01, 0.01, 0.01, 1.0 }, .clear_color = .{ 0.01, 0.01, 0.01, 1.0 },
})) |pass| { })) |pass| {
@ -143,7 +179,6 @@ pub fn main(init: std.process.Init) !void {
pass.drawIndexed(cmn.Square.indices.len, 1, 0, 0, 0); pass.drawIndexed(cmn.Square.indices.len, 1, 0, 0, 0);
} }
// --- NEW PASS ---
// if (gfx.beginPass(swapchain, .{ // if (gfx.beginPass(swapchain, .{
// .load_op = .load, // .load_op = .load,
// })) |pass| { // })) |pass| {

View file

@ -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), .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 })), .view = .lookAt(.new(.{ 1, 1, -2 }), .new(.{ 0, 0, 1 }), .new(.{ 0, 1, 0 })),
}; };
const model: Model = .{ var model: Model = .{
.matrix = math.Mat4x4.translate( .matrix = math.Mat4x4.translate(
0, 0,
0, 0,
@ -52,15 +52,12 @@ pub fn main(init: std.process.Init) !void {
// SDL // SDL
// //
// --- # ---
if (!sdl.SDL_Init(sdl.SDL_INIT_VIDEO)) return error.FailedToInitSDL; if (!sdl.SDL_Init(sdl.SDL_INIT_VIDEO)) return error.FailedToInitSDL;
defer sdl.SDL_Quit(); defer sdl.SDL_Quit();
// --- # ---
const window = sdl.SDL_CreateWindow("NYXGFX", 800, 600, 0) orelse return error.FailedTomakeWindow; const window = sdl.SDL_CreateWindow("NYXGFX", 800, 600, 0) orelse return error.FailedTomakeWindow;
defer sdl.SDL_DestroyWindow(window); defer sdl.SDL_DestroyWindow(window);
// --- # ---
const props = sdl.SDL_GetWindowProperties(window); const props = sdl.SDL_GetWindowProperties(window);
const display = sdl.SDL_GetPointerProperty(props, sdl.SDL_PROP_WINDOW_X11_DISPLAY_POINTER, null); 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); 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(); defer gfx.deinit();
//
// CORE
//
const instance = try gfx.makeInstance(.{ const instance = try gfx.makeInstance(.{
.vulkan = .{ .vulkan = .{
.api_version = .v1_3, .api_version = .v1_3,
.vk_13_features = .{},
}, },
}); });
const surface = try gfx.makeSurface(.{ const surface = try gfx.makeSurface(.{
.window = .{
.xlib = .{ .xlib = .{
.window = @intCast(xwindow), .window = @intCast(xwindow),
.display = display.?, .display = display.?,
}, },
}, instance); },
.instance = instance,
});
const adapter = try gfx.makeAdapter(.{}, instance); const adapter = try gfx.makeAdapter(.{
const device = try gfx.makeDevice(adapter, surface); .instance = instance,
const swapchain = try gfx.makeSwapchain(adapter, device, surface); });
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| { if (gfx.getAdapterInfo(adapter)) |info| {
std.debug.print("Name: {s} | Type: {s}\n", .{ info.name, @tagName(info.gpu_type) }); std.debug.print("Name: {s} | Type: {s}\n", .{ info.name, @tagName(info.gpu_type) });
} }
// --- TEXTURES --- //
const texture = try gfx.makeTexture(.{ // TEXTURES
.image = .{ .path = "examples/assets/textures/texture.jpg", .vertical_flip = true }, //
.sampler = .{ .min_filter = .linear, .address_u = .repeat },
}, adapter, device); 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 vbuf = try gfx.makeBuffer(cmn.Cube.vertices, .vertex, adapter, device);
const ibuf = try gfx.makeBuffer(cmn.Cube.indices, .index, 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_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); const simple_frag = try gfx.makeShader("examples/assets/shaders/compiled/3D.frag.spv", device);
// --- PIPELINE --- //
// PIPELINES
//
const pipeline = try gfx.makePipeline(.{ const pipeline = try gfx.makePipeline(.{
.vertex_attributes = &.{ .vertex_attributes = &.{
.{ .location = 0, .format = .vec3, .offset = @offsetOf(cmn.Vertex, "pos") }, .{ .location = 0, .format = .vec3, .offset = @offsetOf(cmn.Vertex, "pos") },
@ -137,13 +173,20 @@ pub fn main(init: std.process.Init) !void {
.swapchain = swapchain, .swapchain = swapchain,
}); });
// --- MISC --- //
// MISC
//
var event: sdl.SDL_Event = undefined; var event: sdl.SDL_Event = undefined;
var running: bool = true; var running: bool = true;
var i: f32 = 0; var i: f32 = 0;
while (running) { while (running) {
// --- INPUTS ---
//
// INPUTS
//
while (sdl.SDL_PollEvent(&event)) { while (sdl.SDL_PollEvent(&event)) {
switch (event.type) { switch (event.type) {
sdl.SDL_EVENT_QUIT => running = false, sdl.SDL_EVENT_QUIT => running = false,
@ -151,7 +194,6 @@ pub fn main(init: std.process.Init) !void {
} }
} }
// --- ANIMATION ---
i += 0.001; i += 0.001;
i = @mod(i, 1); i = @mod(i, 1);
material.albedo[1] = i; material.albedo[1] = i;
@ -160,29 +202,56 @@ pub fn main(init: std.process.Init) !void {
.projection = camera.projection.transpose(), .projection = camera.projection.transpose(),
.view = camera.view.transpose(), .view = camera.view.transpose(),
}); });
try pipeline.setUniform("model", Model{
.matrix = model.matrix.transpose(),
});
// --- FRAME --- //
// FRAME
//
try gfx.beginFrame(swapchain, device); try gfx.beginFrame(swapchain, device);
defer gfx.endFrame(swapchain, device) catch unreachable; defer gfx.endFrame(swapchain, device) catch unreachable;
// --- NEW PASS --- //
// PASS
//
if (gfx.beginPass(swapchain, .{ if (gfx.beginPass(swapchain, .{
.clear_color = .{ 0.01, 0.01, 0.01, 1.0 }, .clear_color = .{ 0.01, 0.01, 0.01, 1.0 },
.depth_enabled = true, .depth_enabled = true,
})) |pass| { })) |pass| {
defer pass.end(); defer pass.end();
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();
try vbuf.bind(); try vbuf.bind();
try ibuf.bind(); try ibuf.bind();
try pipeline.bind(); try pipeline.setUniform("model", Model{
.matrix = model.matrix.transpose(),
});
pass.drawIndexed(cmn.Cube.indices.len, 1, 0, 0, 0); pass.drawIndexed(cmn.Cube.indices.len, 1, 0, 0, 0);
} }
}
// --- NEW PASS ---
if (gfx.beginPass(swapchain, .{ if (gfx.beginPass(swapchain, .{
.load_op = .load, .load_op = .load,
})) |pass| { })) |pass| {

View file

@ -5,14 +5,14 @@ Collapsed=0
LastUsed=20260818 LastUsed=20260818
[Window][Inspector] [Window][Inspector]
Pos=87,36 Pos=65,34
Size=622,253 Size=622,253
Collapsed=0 Collapsed=0
DockId=0x00000002,0 DockId=0x00000002,0
LastUsed=20260818 LastUsed=20260818
[Window][Dear ImGui Demo] [Window][Dear ImGui Demo]
Pos=87,291 Pos=65,289
Size=622,257 Size=622,257
Collapsed=0 Collapsed=0
DockId=0x00000003,0 DockId=0x00000003,0
@ -32,7 +32,7 @@ Column 2 Width=63
LastUsed=20260814 LastUsed=20260814
[Docking][Data] [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=0x00000002 Parent=0x00000001 SizeRef=361,237 Selected=0x36DC96AB
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=361,241 Selected=0x5E5F7166 DockNode ID=0x00000003 Parent=0x00000001 SizeRef=361,241 Selected=0x5E5F7166

View file

@ -15,6 +15,9 @@ pub const Handle = gtl.Handle;
// --- CONFIGS --- // --- CONFIGS ---
pub const InstanceConfig = common.InstanceConfig; pub const InstanceConfig = common.InstanceConfig;
pub const AdapterConfig = common.AdapterConfig; 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 RenderPassConfig = common.RenderPassConfig;
pub const PipelineConfig = common.PipelineConfig; pub const PipelineConfig = common.PipelineConfig;
pub const BufferUsage = common.BufferUsage; 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()).*) { 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( pub fn makeDevice(self: *Self, config: DeviceConfig) !Handle(Device) {
self: *Self,
instance: Handle(Instance),
adapter: Handle(Adapter),
surface: Handle(Surface),
) !Handle(Device) {
return try switch ((try self.getBackend()).*) { 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( pub fn makeSurface(self: *Self, config: SurfaceConfig) !Handle(Surface) {
self: *Self,
window: Window,
instance: Handle(Instance),
) !Handle(Surface) {
return try switch ((try self.getBackend()).*) { 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( pub fn makeSwapchain(self: *Self, config: SwapchainConfig) !Handle(Swapchain) {
self: *Self,
adapter: Handle(Adapter),
device: Handle(Device),
surface: Handle(Surface),
) !Handle(Swapchain) {
return try switch ((try self.getBackend()).*) { 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( pub fn makeTexture(self: *Self, config: TextureConfig) !Handle(Texture) {
self: *Self,
config: TextureConfig,
adapter: Handle(Adapter),
device: Handle(Device),
) !Handle(Texture) {
return try switch ((try self.getBackend()).*) { return try switch ((try self.getBackend()).*) {
.vulkan => |*v| v.makeTexture(config, adapter, device), .vulkan => |*v| v.makeTexture(config),
}; };
} }

View file

@ -137,15 +137,36 @@ pub const Window = union(enum) {
pub const AdapterConfig = struct { pub const AdapterConfig = struct {
device_type: DeviceType = .discrete, device_type: DeviceType = .discrete,
index: ?u32 = null, index: ?u32 = null,
instance: Handle(Instance),
}; };
/// ---------------------------------------------------- /// ----------------------------------------------------
/// ---------------------------------------------------- /// ----------------------------------------------------
pub const DeviceConfig = struct { pub const DeviceConfig = struct {
instance: Handle(Instance),
adapter: Handle(Adapter), adapter: Handle(Adapter),
surface: Handle(Surface), 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 { pub const Format = enum {
@ -346,7 +367,7 @@ pub const BufferSharingMode = enum {
/// ---------------------------------------------------- /// ----------------------------------------------------
/// ---------------------------------------------------- /// ----------------------------------------------------
pub const PixelFormat = enum { pub const TextureFormat = enum {
rgba8_unorm, rgba8_unorm,
rgba8_srgb, rgba8_srgb,
bgra8_unorm, bgra8_unorm,
@ -398,7 +419,7 @@ pub const ImageConfig = struct {
vertical_flip: bool = false, vertical_flip: bool = false,
format: PixelFormat = .rgba8_srgb, format: TextureFormat = .rgba8_srgb,
usage: ImageUsage = .texture, usage: ImageUsage = .texture,
mip_levels: u32 = 1, mip_levels: u32 = 1,
}; };
@ -421,6 +442,9 @@ pub const SamplerConfig = struct {
pub const TextureConfig = struct { pub const TextureConfig = struct {
image: ImageConfig = .{}, image: ImageConfig = .{},
sampler: SamplerConfig = .{}, sampler: SamplerConfig = .{},
adapter: Handle(Adapter),
device: Handle(Device),
}; };
// //

56
src/rhi/vulkan/helper.zig Normal file
View file

@ -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,
};
}

View file

@ -2,9 +2,10 @@
//! `🗲` Vulkan Adapter `🗲` //! `🗲` Vulkan Adapter `🗲`
//! ---------------------------------------------------- //! ----------------------------------------------------
const vk = @import("vulkan");
const hp = @import("../helper.zig");
const std = @import("std"); const std = @import("std");
const gtl = @import("gtl"); const gtl = @import("gtl");
const vk = @import("vulkan");
const common = @import("../../common.zig"); const common = @import("../../common.zig");
const VKBackend = @import("../vulkan.zig"); const VKBackend = @import("../vulkan.zig");
const AdapterConfig = common.AdapterConfig; const AdapterConfig = common.AdapterConfig;
@ -28,14 +29,14 @@ pub fn init(
) !Self { ) !Self {
// --- GET ADAPTER COUNT --- // --- GET ADAPTER COUNT ---
var count: u32 = 0; 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 --- // --- CREATE LIST OF ADAPTERS ---
const items = try alloc.alloc(vk.VkPhysicalDevice, count); const items = try alloc.alloc(vk.VkPhysicalDevice, count);
defer alloc.free(items); defer alloc.free(items);
// --- POPULATE ADAPTERS LIST --- // --- 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 --- // --- CHECK ADAPTER ---
var raw: vk.VkPhysicalDevice = null; var raw: vk.VkPhysicalDevice = null;
@ -71,13 +72,9 @@ pub fn init(
vk.vkGetPhysicalDeviceProperties2(adapter, &props); vk.vkGetPhysicalDeviceProperties2(adapter, &props);
vk.vkGetPhysicalDeviceFeatures2(adapter, &features); vk.vkGetPhysicalDeviceFeatures2(adapter, &features);
const api_version: u32 = switch (instance.api_version) { const api_version: u32 = hp.toRawAPIVersion(
.v1_0 => vk.VK_API_VERSION_1_0, instance.api_version,
.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 adapter_type: DeviceType = switch (props.properties.deviceType) { const adapter_type: DeviceType = switch (props.properties.deviceType) {
vk.VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU => .discrete, vk.VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU => .discrete,

View file

@ -2,8 +2,9 @@
//! `🗲` Vulkan Buffer `🗲` //! `🗲` Vulkan Buffer `🗲`
//! ---------------------------------------------------- //! ----------------------------------------------------
const std = @import("std");
const vk = @import("vulkan"); const vk = @import("vulkan");
const hp = @import("../helper.zig");
const std = @import("std");
const Self = @This(); const Self = @This();
const common = @import("../../common.zig"); const common = @import("../../common.zig");
@ -35,11 +36,7 @@ pub fn init(
) !Self { ) !Self {
var info: vk.VkBufferCreateInfo = .{ var info: vk.VkBufferCreateInfo = .{
.sType = vk.VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .sType = vk.VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.usage = switch (usage) { .usage = hp.toRawBufferUsage(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,
},
.sharingMode = switch (sharing) { .sharingMode = switch (sharing) {
.exclusive => vk.VK_SHARING_MODE_EXCLUSIVE, .exclusive => vk.VK_SHARING_MODE_EXCLUSIVE,
}, },
@ -47,7 +44,7 @@ pub fn init(
}; };
var raw: vk.VkBuffer = null; 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; return error.FailedToCreateBuffer;
} }
@ -101,7 +98,7 @@ pub fn set(
.memoryTypeIndex = mem_type, .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; return error.FailedToAllocateMemory;
} }
@ -119,12 +116,11 @@ pub fn set(
&mapped, &mapped,
); );
if (result != vk.VK_SUCCESS) { if (!hp.check(result)) {
return error.FailedToMapMemory; return error.FailedToMapMemory;
} }
const dst: [*]u8 = @ptrCast(mapped.?); const dst: [*]u8 = @ptrCast(mapped.?);
const src: [*]const u8 = switch (@typeInfo(@TypeOf(value))) { const src: [*]const u8 = switch (@typeInfo(@TypeOf(value))) {
.optional => @ptrCast(value.?), .optional => @ptrCast(value.?),
.pointer => @ptrCast(value), .pointer => @ptrCast(value),
@ -132,6 +128,5 @@ pub fn set(
}; };
@memcpy(dst[0..size], src[0..size]); @memcpy(dst[0..size], src[0..size]);
vk.vkUnmapMemory(self.device.raw, self.data); vk.vkUnmapMemory(self.device.raw, self.data);
} }

View file

@ -2,8 +2,9 @@
//! `🗲` Vulkan Device `🗲` //! `🗲` Vulkan Device `🗲`
//! ---------------------------------------------------- //! ----------------------------------------------------
const std = @import("std");
const vk = @import("vulkan"); const vk = @import("vulkan");
const hp = @import("../helper.zig");
const std = @import("std");
const Self = @This(); const Self = @This();
const Instance = @import("instance.zig"); const Instance = @import("instance.zig");
@ -108,7 +109,7 @@ pub fn init(
// --- # --- // --- # ---
var device: vk.VkDevice = null; 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; return error.FailedToCreateVulkanDevice;
} }
@ -119,7 +120,7 @@ pub fn init(
.queueFamilyIndex = queue_families.graphics.?, .queueFamilyIndex = queue_families.graphics.?,
}; };
var graphics_command_pool: vk.VkCommandPool = null; 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; return error.FailedToCreateCommandPool;
} }

View file

@ -2,8 +2,9 @@
//! `🗲` Vulkan Image `🗲` //! `🗲` Vulkan Image `🗲`
//! ---------------------------------------------------- //! ----------------------------------------------------
const std = @import("std");
const vk = @import("vulkan"); const vk = @import("vulkan");
const hp = @import("../helper.zig");
const std = @import("std");
const stb = @import("stb_image"); const stb = @import("stb_image");
const common = @import("../../common.zig"); const common = @import("../../common.zig");
const Self = @This(); const Self = @This();
@ -83,12 +84,9 @@ pub fn init(
self.mip_levels = config.mip_levels; self.mip_levels = config.mip_levels;
// --- FORMAT --- // --- FORMAT ---
self.format = switch (config.format) { self.format = hp.toRawPixelFormat(
.rgba8_unorm => vk.VK_FORMAT_R8G8B8A8_UNORM, config.format,
.rgba8_srgb => vk.VK_FORMAT_R8G8B8A8_SRGB, );
.bgra8_unorm => vk.VK_FORMAT_B8G8R8A8_UNORM,
.bgra8_srgb => vk.VK_FORMAT_B8G8R8A8_SRGB,
};
// --- IMAGE --- // --- IMAGE ---
var usage: vk.VkImageUsageFlags = vk.VK_IMAGE_USAGE_TRANSFER_DST_BIT | vk.VK_IMAGE_USAGE_SAMPLED_BIT; var usage: vk.VkImageUsageFlags = vk.VK_IMAGE_USAGE_TRANSFER_DST_BIT | vk.VK_IMAGE_USAGE_SAMPLED_BIT;

View file

@ -3,6 +3,7 @@
//! ---------------------------------------------------- //! ----------------------------------------------------
const vk = @import("vulkan"); const vk = @import("vulkan");
const hp = @import("../helper.zig");
const std = @import("std"); const std = @import("std");
const cmn = @import("../../common.zig"); const cmn = @import("../../common.zig");
const gtl = @import("gtl"); const gtl = @import("gtl");
@ -93,7 +94,7 @@ pub fn init(config: cmn.VKInstanceConfig, alloc: std.mem.Allocator) !Self {
// } // }
var instance: vk.VkInstance = null; 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; return error.FailedToCreateVulkanInstance;
} }
errdefer vk.vkDestroyInstance(instance.?, null); errdefer vk.vkDestroyInstance(instance.?, null);

View file

@ -2,8 +2,9 @@
//! `🗲` Vulkan Pipeline `🗲` //! `🗲` Vulkan Pipeline `🗲`
//! ---------------------------------------------------- //! ----------------------------------------------------
const std = @import("std");
const vk = @import("vulkan"); const vk = @import("vulkan");
const hp = @import("../helper.zig");
const std = @import("std");
const gtl = @import("gtl"); const gtl = @import("gtl");
const common = @import("../../common.zig"); const common = @import("../../common.zig");
const VulkanRHI = @import("../vulkan.zig"); const VulkanRHI = @import("../vulkan.zig");
@ -14,6 +15,7 @@ const Swapchain = @import("swapchain.zig");
const VKTexture = @import("texture.zig"); const VKTexture = @import("texture.zig");
const Config = common.PipelineConfig; const Config = common.PipelineConfig;
const UniformDesc = common.UniformDesc; const UniformDesc = common.UniformDesc;
const MAX_FRAMES_IN_FLIGHT = VulkanRHI.MAX_FRAMES_IN_FLIGHT; const MAX_FRAMES_IN_FLIGHT = VulkanRHI.MAX_FRAMES_IN_FLIGHT;
const MAX_BINDINGS = 16; const MAX_BINDINGS = 16;
const MAX_TEXTURES = 16; const MAX_TEXTURES = 16;
@ -128,7 +130,7 @@ pub fn init(
.pBindings = &bindings, .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; return error.FailedToCreateDescriptorSetLayout;
} }
self.descriptor_set_layout = set_layout.?; self.descriptor_set_layout = set_layout.?;
@ -141,7 +143,7 @@ pub fn init(
}; };
var pipeline_layout: vk.VkPipelineLayout = null; 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; return error.FailedToCreatePipelineLayout;
} }
self.layout = pipeline_layout.?; self.layout = pipeline_layout.?;
@ -364,7 +366,7 @@ pub fn init(
}; };
var pipeline: vk.VkPipeline = null; 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; return error.FailedToCreateGraphicsPipelines;
} }
self.raw = pipeline.?; self.raw = pipeline.?;
@ -408,7 +410,7 @@ pub fn init(
}; };
var descriptor_pool: vk.VkDescriptorPool = null; 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; return error.FailedToCreateDescriptorPool;
} }
self.descriptor_pool = descriptor_pool.?; self.descriptor_pool = descriptor_pool.?;
@ -424,7 +426,7 @@ pub fn init(
}; };
var uniform_buffer: vk.VkBuffer = null; 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; return error.FailedToCreateUniformBuffer;
} }
self.uniform_buffers[frame] = uniform_buffer.?; self.uniform_buffers[frame] = uniform_buffer.?;
@ -454,7 +456,7 @@ pub fn init(
}; };
var uniform_memory: vk.VkDeviceMemory = null; 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; return error.FailedToAllocateUniformMemory;
} }
self.uniform_memories[frame] = uniform_memory; self.uniform_memories[frame] = uniform_memory;
@ -470,7 +472,7 @@ pub fn init(
.pSetLayouts = @ptrCast(&self.descriptor_set_layout), .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; return error.FailedToAllocateDescriptorSets;
} }
@ -564,14 +566,14 @@ pub fn setUniform(self: *Self, name: []const u8, value: anytype) !void {
} }
var mapped: ?*anyopaque = null; var mapped: ?*anyopaque = null;
if (vk.vkMapMemory( if (!hp.check(vk.vkMapMemory(
self.device.raw, self.device.raw,
uniform_memory, uniform_memory,
self.uniform_offsets[i], self.uniform_offsets[i],
uniform.size, uniform.size,
0, 0,
&mapped, &mapped,
) != vk.VK_SUCCESS) { ))) {
return error.FailedToMapMemory; return error.FailedToMapMemory;
} }

View file

@ -2,8 +2,9 @@
//! `🗲` Vulkan Sampler `🗲` //! `🗲` Vulkan Sampler `🗲`
//! ---------------------------------------------------- //! ----------------------------------------------------
const std = @import("std");
const vk = @import("vulkan"); const vk = @import("vulkan");
const hp = @import("../helper.zig");
const std = @import("std");
const common = @import("../../common.zig"); const common = @import("../../common.zig");
const Self = @This(); const Self = @This();
@ -68,7 +69,7 @@ pub fn init(
}; };
var sampler: vk.VkSampler = null; 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; return error.FailedToCreateSampler;
} }

View file

@ -2,8 +2,9 @@
//! `🗲` Vulkan Shader `🗲` //! `🗲` Vulkan Shader `🗲`
//! ---------------------------------------------------- //! ----------------------------------------------------
const std = @import("std");
const vk = @import("vulkan"); const vk = @import("vulkan");
const hp = @import("../helper.zig");
const std = @import("std");
const gtl = @import("gtl"); const gtl = @import("gtl");
const Device = @import("device.zig"); const Device = @import("device.zig");
const Self = @This(); const Self = @This();
@ -57,7 +58,7 @@ fn createModule(
}; };
var module: vk.VkShaderModule = null; 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; return error.FailedToCreateShaderModule;
} }

View file

@ -2,8 +2,9 @@
//! `🗲` Vulkan Surface `🗲` //! `🗲` Vulkan Surface `🗲`
//! ---------------------------------------------------- //! ----------------------------------------------------
const std = @import("std");
const vk = @import("vulkan"); const vk = @import("vulkan");
const hp = @import("../helper.zig");
const std = @import("std");
const Window = @import("../../common.zig").Window; const Window = @import("../../common.zig").Window;
const Self = @This(); const Self = @This();
@ -31,7 +32,7 @@ pub fn init(
.dpy = @ptrCast(v.display), .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; return error.FailedToCreateXlibSurfaceKHR;
} }

View file

@ -2,22 +2,17 @@
//! `🗲` Vulkan Swapchain `🗲` //! `🗲` Vulkan Swapchain `🗲`
//! ---------------------------------------------------- //! ----------------------------------------------------
const vk = @import("vulkan");
const hp = @import("../helper.zig");
const std = @import("std"); const std = @import("std");
const gtl = @import("gtl"); const gtl = @import("gtl");
const vk = @import("vulkan"); const cmn = @import("../../common.zig");
const Self = @This(); const Self = @This();
const Adapter = @import("adapter.zig"); const Adapter = @import("adapter.zig");
const Device = @import("device.zig"); const Device = @import("device.zig");
const Surface = @import("surface.zig"); const Surface = @import("surface.zig");
/// ----------------------------------------------------
/// ----------------------------------------------------
pub const Config = struct {
width: u32,
height: u32,
};
// //
// FIELDS // FIELDS
// //
@ -44,7 +39,7 @@ pub fn init(
adapter: *const Adapter, adapter: *const Adapter,
device: *const Device, device: *const Device,
surface: *const Surface, surface: *const Surface,
config: Config, config: cmn.SwapchainConfig,
alloc: std.mem.Allocator, alloc: std.mem.Allocator,
) !Self { ) !Self {
// --- # --- // --- # ---
@ -70,13 +65,17 @@ pub fn init(
// --- # --- // --- # ---
const extent: vk.VkExtent2D = blk: { const extent: vk.VkExtent2D = blk: {
if (capabilities.currentExtent.width != std.math.maxInt(u32)) break :blk capabilities.currentExtent; 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: { const format: vk.VkSurfaceFormatKHR = blk: {
for (formats) |v| { 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; break :blk v;
} }
} }
@ -110,7 +109,7 @@ pub fn init(
}; };
var swapchain: vk.VkSwapchainKHR = null; 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; return error.FailedToCreateSwapchainKHR;
} }

View file

@ -1,10 +1,10 @@
//! ---------------------------------------------------- //! ----------------------------------------------------
//! `🗲` Vulkan RHI 1.4 `🗲` //! `🗲` Vulkan RHI `🗲`
//! 😭 Send Help 😭
//! ---------------------------------------------------- //! ----------------------------------------------------
const std = @import("std"); const std = @import("std");
const vk = @import("vulkan"); const vk = @import("vulkan");
const hp = @import("helper.zig");
const gtl = @import("gtl"); const gtl = @import("gtl");
const common = @import("../common.zig"); const common = @import("../common.zig");
@ -47,7 +47,7 @@ const Texture = common.Texture;
const AdapterInfo = common.AdapterInfo; 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, resource: Resource,
frames: [MAX_FRAMES_IN_FLIGHT]Frame = .{ .{}, .{}, .{} }, frames: [MAX_FRAMES_IN_FLIGHT]Frame = [_]Frame{.{}} ** MAX_FRAMES_IN_FLIGHT,
current_frame: usize = 0, current_frame: usize = 0,
active_pass_target: ?Handle(Texture) = null, 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) { pub fn makeAdapter(self: *Self, config: AdapterConfig) !Handle(Adapter) {
const raw_instance = self.resource.instances.get(instance) orelse return error.InstanceNotFound; 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)); 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( pub fn makeDevice(self: *Self, config: common.DeviceConfig) !Handle(Device) {
self: *Self, const raw_instance = self.resource.instances.get(config.instance) orelse return error.InstanceNotFound;
instance: Handle(common.Instance), const raw_adapter = self.resource.adapters.get(config.adapter) orelse return error.AdapterNotFound;
adapter: Handle(Adapter), const raw_surface = self.resource.surfaces.get(config.surface) orelse return error.SurfaceNotFound;
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;
return try self.resource.devices.put(try .init(raw_instance, raw_adapter, raw_surface, self.alloc)); 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( pub fn makeSurface(self: *Self, config: common.SurfaceConfig) !Handle(Surface) {
self: *Self, const raw_instance = self.resource.instances.get(config.instance) orelse return error.InstanceNotFound;
instance: Handle(common.Instance), return try self.resource.surfaces.put(try .init(raw_instance, config.window));
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));
} }
// //
@ -261,23 +252,11 @@ pub fn makeSurface(
/// ---------------------------------------------------- /// ----------------------------------------------------
/// ---------------------------------------------------- /// ----------------------------------------------------
pub fn makeSwapchain( pub fn makeSwapchain(self: *Self, config: common.SwapchainConfig) !Handle(Swapchain) {
self: *Self, const raw_surface = self.resource.surfaces.get(config.surface) orelse return error.SurfaceNotFound;
adapter: Handle(Adapter), const raw_adapter = self.resource.adapters.get(config.adapter) orelse return error.AdapterNotFound;
device: Handle(Device), const raw_device = self.resource.devices.get(config.device) orelse return error.DeviceNotFound;
surface: Handle(Surface), return try self.resource.swapchains.put(try .init(raw_adapter, raw_device, raw_surface, config, self.alloc));
) !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,
));
} }
/// ---------------------------------------------------- /// ----------------------------------------------------
@ -387,14 +366,9 @@ pub fn makeSampler(
/// ---------------------------------------------------- /// ----------------------------------------------------
/// ---------------------------------------------------- /// ----------------------------------------------------
pub fn makeTexture( pub fn makeTexture(self: *Self, config: TextureConfig) !Handle(Texture) {
self: *Self, const raw_adapter = self.resource.adapters.get(config.adapter) orelse return error.AdapterNotFound;
config: TextureConfig, const raw_device = self.resource.devices.get(config.device) orelse return error.DeviceNotFound;
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;
return try self.resource.textures.put(try .init(config, raw_adapter, raw_device)); 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 { 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 { 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 (self.currentFrame().cmd_buf) |cmd| {
if (frame.cmd_buf) |cmd| {
vk.vkCmdDrawIndexed(cmd, index_count, instance_count, first_index, vertex_offset, first_instance); vk.vkCmdDrawIndexed(cmd, index_count, instance_count, first_index, vertex_offset, first_instance);
} }
} }