Refactor of vulkan structures

This commit is contained in:
Lorenzo Torres 2025-08-07 13:17:47 +02:00
parent 3199697470
commit 90cfe4d96e
8 changed files with 1300 additions and 1284 deletions

View file

@ -0,0 +1,179 @@
const std = @import("std");
const Allocator = std.mem.Allocator;
const vk = @import("vulkan.zig");
const c = vk.c;
const PhysicalDevice = @This();
const device_extensions: []const [*c]const u8 = &[_][*c]const u8{
c.VK_KHR_SWAPCHAIN_EXTENSION_NAME,
};
handle: c.VkPhysicalDevice,
pub fn pick(allocator: Allocator, instance: vk.Instance) !PhysicalDevice {
var device_count: u32 = 0;
try vk.mapError(c.vkEnumeratePhysicalDevices(instance.handle, &device_count, null));
const devices = try allocator.alloc(c.VkPhysicalDevice, device_count);
defer allocator.free(devices);
try vk.mapError(c.vkEnumeratePhysicalDevices(instance.handle, &device_count, @ptrCast(devices)));
return PhysicalDevice{ .handle = devices[0] };
}
pub fn queueFamilyProperties(self: PhysicalDevice, allocator: Allocator) ![]const c.VkQueueFamilyProperties {
var count: u32 = 0;
c.vkGetPhysicalDeviceQueueFamilyProperties(self.handle, &count, null);
const family_properties = try allocator.alloc(c.VkQueueFamilyProperties, count);
c.vkGetPhysicalDeviceQueueFamilyProperties(self.handle, &count, @ptrCast(family_properties));
return family_properties;
}
pub fn graphicsQueue(self: PhysicalDevice, allocator: Allocator) !u32 {
const queue_families = try self.queueFamilyProperties(allocator);
defer allocator.free(queue_families);
var graphics_queue: ?u32 = null;
for (queue_families, 0..) |family, index| {
if (graphics_queue) |_| {
break;
}
if ((family.queueFlags & c.VK_QUEUE_GRAPHICS_BIT) != 0x0) {
graphics_queue = @intCast(index);
}
}
return graphics_queue.?;
}
pub fn presentQueue(self: PhysicalDevice, surface: vk.Surface, allocator: Allocator) !u32 {
const queue_families = try self.queueFamilyProperties(allocator);
defer allocator.free(queue_families);
var present_queue: ?u32 = null;
for (queue_families, 0..) |_, index| {
if (present_queue) |_| {
break;
}
var support: u32 = undefined;
try vk.mapError(c.vkGetPhysicalDeviceSurfaceSupportKHR(self.handle, @intCast(index), surface.handle, &support));
if (support == c.VK_TRUE) {
present_queue = @intCast(index);
}
}
return present_queue.?;
}
pub fn create_device(self: *PhysicalDevice, surface: vk.Surface, allocator: Allocator, comptime n: usize) !vk.Device {
const graphics_queue_index = try self.graphicsQueue(allocator);
const present_queue_index = try self.presentQueue(surface, allocator);
const priorities: f32 = 1.0;
const graphics_queue_info: c.VkDeviceQueueCreateInfo = .{
.sType = c.VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
.queueFamilyIndex = graphics_queue_index,
.queueCount = 1,
.pQueuePriorities = &priorities,
};
const present_queue_info: c.VkDeviceQueueCreateInfo = .{
.sType = c.VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
.queueFamilyIndex = present_queue_index,
.queueCount = 1,
.pQueuePriorities = &priorities,
};
const queues: []const c.VkDeviceQueueCreateInfo = &.{ graphics_queue_info, present_queue_info };
var device_features: c.VkPhysicalDeviceFeatures2 = .{
.sType = c.VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
};
c.vkGetPhysicalDeviceFeatures2(self.handle, &device_features);
const device_info: c.VkDeviceCreateInfo = .{
.sType = c.VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.pNext = &device_features,
.queueCreateInfoCount = 1,
.pQueueCreateInfos = queues.ptr,
.enabledLayerCount = 0,
.enabledExtensionCount = @intCast(device_extensions.len),
.ppEnabledExtensionNames = device_extensions.ptr,
};
var device: c.VkDevice = undefined;
try vk.mapError(c.vkCreateDevice(self.handle, &device_info, null, &device));
var graphics_queue: c.VkQueue = undefined;
var present_queue: c.VkQueue = undefined;
c.vkGetDeviceQueue(device, graphics_queue_index, 0, &graphics_queue);
c.vkGetDeviceQueue(device, present_queue_index, 0, &present_queue);
const command_pool_info: c.VkCommandPoolCreateInfo = .{
.sType = c.VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
.flags = c.VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
.queueFamilyIndex = graphics_queue_index,
};
var command_pool: c.VkCommandPool = undefined;
try vk.mapError(c.vkCreateCommandPool(device, &command_pool_info, null, &command_pool));
const command_buffer_info: c.VkCommandBufferAllocateInfo = .{
.sType = c.VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
.commandPool = command_pool,
.level = c.VK_COMMAND_BUFFER_LEVEL_PRIMARY,
.commandBufferCount = n,
};
var command_buffers: [n]c.VkCommandBuffer = undefined;
try vk.mapError(c.vkAllocateCommandBuffers(device, &command_buffer_info, command_buffers[0..n].ptr));
const semaphore_info: c.VkSemaphoreCreateInfo = .{
.sType = c.VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
};
const fence_info: c.VkFenceCreateInfo = .{
.sType = c.VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
.flags = c.VK_FENCE_CREATE_SIGNALED_BIT,
};
var image_available: [n]c.VkSemaphore = undefined;
var render_finished: [n]c.VkSemaphore = undefined;
var in_flight_fence: [n]c.VkFence = undefined;
inline for (0..n) |index| {
try vk.mapError(c.vkCreateSemaphore(device, &semaphore_info, null, &image_available[index]));
try vk.mapError(c.vkCreateSemaphore(device, &semaphore_info, null, &render_finished[index]));
try vk.mapError(c.vkCreateFence(device, &fence_info, null, &in_flight_fence[index]));
}
var memory_properties: c.VkPhysicalDeviceMemoryProperties = undefined;
c.vkGetPhysicalDeviceMemoryProperties(self.handle, &memory_properties);
var device_properties: c.VkPhysicalDeviceProperties = undefined;
c.vkGetPhysicalDeviceProperties(self.handle, &device_properties);
return .{
.handle = device,
.graphics_queue = graphics_queue,
.present_queue = present_queue,
.command_pool = command_pool,
.command_buffers = command_buffers,
.image_available = image_available,
.render_finished = render_finished,
.in_flight_fence = in_flight_fence,
.graphics_family = graphics_queue_index,
.present_family = present_queue_index,
.memory_properties = memory_properties,
.device_properties = device_properties,
};
}