Refactor how the vk renderer fields are set

This commit is contained in:
Przemyslaw Gasinski 2024-06-26 21:58:51 +02:00
parent b40005c7c7
commit 0cfb51a079

View file

@ -1,11 +1,12 @@
const std = @import("std"); const std = @import("std");
const sdl = @import("sdl2"); const sdl = @import("sdl2");
const vk = @import("vulkan"); const vk = @import("vulkan");
const builtin = @import("builtin");
const Utilities = @import("utilities.zig"); const Utilities = @import("utilities.zig");
const QueueFamilyIndices = Utilities.QueueFamilyIndices; const QueueFamilyIndices = Utilities.QueueFamilyIndices;
const SwapchainDetails = Utilities.SwapchainDetails; const SwapchainDetails = Utilities.SwapchainDetails;
const enable_validation_layers = true; const enable_validation_layers = builtin.mode == .Debug;
const validation_layers = [_][*:0]const u8{"VK_LAYER_KHRONOS_validation"}; const validation_layers = [_][*:0]const u8{"VK_LAYER_KHRONOS_validation"};
const apis: []const vk.ApiInfo = &.{ const apis: []const vk.ApiInfo = &.{
@ -50,44 +51,28 @@ pub const VulkanRenderer = struct {
pub fn init(window: sdl.Window, allocator: std.mem.Allocator) !Self { pub fn init(window: sdl.Window, allocator: std.mem.Allocator) !Self {
var self: Self = undefined; var self: Self = undefined;
self.window = window; self.window = window;
self.allocator = allocator; self.allocator = allocator;
self.vkb = try BaseDispatch.load(try sdl.vulkan.getVkGetInstanceProcAddr()); self.vkb = try BaseDispatch.load(try sdl.vulkan.getVkGetInstanceProcAddr());
const instance_handle = try self.createInstance(); try self.createInstance();
try self.createSurface();
const vki = try allocator.create(InstanceDispatch);
errdefer allocator.destroy(vki);
vki.* = try InstanceDispatch.load(instance_handle, self.vkb.dispatch.vkGetInstanceProcAddr);
self.instance = Instance.init(instance_handle, vki);
self.surface = try sdl.vulkan.createSurface(self.window, self.instance.handle);
if (enable_validation_layers) { if (enable_validation_layers) {
self.debug_utils = try createDebugMessenger(self.instance); self.debug_utils = try createDebugMessenger(self.instance);
} }
self.physical_device = try self.getPhysicalDevice(); try self.getPhysicalDevice();
const device_handle = try self.createLogicalDevice(); try self.createLogicalDevice();
try self.createSwapChain();
const vkd = try allocator.create(DeviceDispatch);
errdefer allocator.destroy(vkd);
vkd.* = try DeviceDispatch.load(device_handle, self.instance.wrapper.dispatch.vkGetDeviceProcAddr);
self.device = Device.init(device_handle, vkd);
const queues = try self.getDeviceQueues();
self.graphics_queue = Queue.init(queues[0], vkd);
self.presentation_queue = Queue.init(queues[1], vkd);
self.swapchain = try self.createSwapChain();
return self; return self;
} }
fn createInstance(self: Self) !vk.Instance { fn createInstance(self: *Self) !void {
if (enable_validation_layers and !self.checkValidationLayersSupport()) { if (enable_validation_layers and !self.checkValidationLayersSupport()) {
// TODO Better error
return error.LayerNotPresent; return error.LayerNotPresent;
} }
@ -125,10 +110,19 @@ pub const VulkanRenderer = struct {
instance_create_info.p_next = &debug_create_info; instance_create_info.p_next = &debug_create_info;
} }
return try self.vkb.createInstance(&instance_create_info, null); const instance_handle = try self.vkb.createInstance(&instance_create_info, null);
const vki = try self.allocator.create(InstanceDispatch);
errdefer self.allocator.destroy(vki);
vki.* = try InstanceDispatch.load(instance_handle, self.vkb.dispatch.vkGetInstanceProcAddr);
self.instance = Instance.init(instance_handle, vki);
} }
fn createLogicalDevice(self: Self) !vk.Device { fn createSurface(self: *Self) !void {
self.surface = try sdl.vulkan.createSurface(self.window, self.instance.handle);
}
fn createLogicalDevice(self: *Self) !void {
const indices = try self.getQueueFamilies(self.physical_device); const indices = try self.getQueueFamilies(self.physical_device);
// 1 is the highest priority // 1 is the highest priority
const priority = [_]f32{1}; const priority = [_]f32{1};
@ -158,10 +152,21 @@ pub const VulkanRenderer = struct {
.enabled_extension_count = @intCast(Utilities.device_extensions.len), .enabled_extension_count = @intCast(Utilities.device_extensions.len),
}; };
return try self.instance.createDevice(self.physical_device, &device_create_info, null); const device_handle = try self.instance.createDevice(self.physical_device, &device_create_info, null);
const vkd = try self.allocator.create(DeviceDispatch);
errdefer self.allocator.destroy(vkd);
vkd.* = try DeviceDispatch.load(device_handle, self.instance.wrapper.dispatch.vkGetDeviceProcAddr);
self.device = Device.init(device_handle, vkd);
const queues = try self.getDeviceQueues();
self.graphics_queue = Queue.init(queues[0], self.device.wrapper);
self.presentation_queue = Queue.init(queues[1], self.device.wrapper);
} }
fn createSwapChain(self: *Self) !vk.SwapchainKHR { fn createSwapChain(self: *Self) !void {
const swapchain_details = try self.getSwapchainDetails(self.physical_device); const swapchain_details = try self.getSwapchainDetails(self.physical_device);
defer self.allocator.free(swapchain_details.formats); defer self.allocator.free(swapchain_details.formats);
defer self.allocator.free(swapchain_details.presentation_modes); defer self.allocator.free(swapchain_details.presentation_modes);
@ -215,10 +220,10 @@ pub const VulkanRenderer = struct {
swapchain_create_info.p_queue_family_indices = &qfi; swapchain_create_info.p_queue_family_indices = &qfi;
} }
return try self.device.createSwapchainKHR(&swapchain_create_info, null); self.swapchain = try self.device.createSwapchainKHR(&swapchain_create_info, null);
} }
fn getPhysicalDevice(self: Self) !vk.PhysicalDevice { fn getPhysicalDevice(self: *Self) !void {
var pdev_count: u32 = 0; var pdev_count: u32 = 0;
_ = try self.instance.enumeratePhysicalDevices(&pdev_count, null); _ = try self.instance.enumeratePhysicalDevices(&pdev_count, null);
@ -229,7 +234,8 @@ pub const VulkanRenderer = struct {
for (pdevs) |pdev| { for (pdevs) |pdev| {
if (self.checkDeviceSuitable(pdev)) { if (self.checkDeviceSuitable(pdev)) {
return pdev; self.physical_device = pdev;
return;
} }
} }
@ -361,16 +367,12 @@ pub const VulkanRenderer = struct {
fn checkValidationLayersSupport(self: Self) bool { fn checkValidationLayersSupport(self: Self) bool {
var layer_count: u32 = undefined; var layer_count: u32 = undefined;
_ = self.vkb.enumerateInstanceLayerProperties(&layer_count, null) catch { _ = self.vkb.enumerateInstanceLayerProperties(&layer_count, null) catch return false;
return false;
};
const available_layers = self.allocator.alloc(vk.LayerProperties, layer_count) catch unreachable; const available_layers = self.allocator.alloc(vk.LayerProperties, layer_count) catch unreachable;
defer self.allocator.free(available_layers); defer self.allocator.free(available_layers);
_ = self.vkb.enumerateInstanceLayerProperties(&layer_count, available_layers.ptr) catch { _ = self.vkb.enumerateInstanceLayerProperties(&layer_count, available_layers.ptr) catch return false;
return false;
};
for (validation_layers) |validation_layer| { for (validation_layers) |validation_layer| {
for (available_layers) |available_layer| { for (available_layers) |available_layer| {