Create images & image views

This commit is contained in:
Przemyslaw Gasinski 2024-06-26 22:53:41 +02:00
parent 0cfb51a079
commit 5bc8af66ef
2 changed files with 69 additions and 9 deletions

View file

@ -17,3 +17,8 @@ pub const SwapchainDetails = struct {
formats: []vk.SurfaceFormatKHR, formats: []vk.SurfaceFormatKHR,
presentation_modes: []vk.PresentModeKHR, presentation_modes: []vk.PresentModeKHR,
}; };
pub const SwapchainImage = struct {
image: vk.Image,
image_view: vk.ImageView,
};

View file

@ -2,9 +2,11 @@ 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 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 SwapchainImage = Utilities.SwapchainImage;
const enable_validation_layers = builtin.mode == .Debug; 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"};
@ -36,16 +38,19 @@ pub const VulkanRenderer = struct {
window: sdl.Window, window: sdl.Window,
// Main
instance: Instance, instance: Instance,
physical_device: vk.PhysicalDevice, physical_device: vk.PhysicalDevice,
device: Device, device: Device,
graphics_queue: Queue, graphics_queue: Queue,
presentation_queue: Queue, presentation_queue: Queue,
surface: vk.SurfaceKHR, surface: vk.SurfaceKHR,
swapchain: vk.SwapchainKHR, swapchain: vk.SwapchainKHR,
swapchain_images: []SwapchainImage,
// Utilities
swapchain_image_format: vk.Format,
extent: vk.Extent2D,
debug_utils: ?vk.DebugUtilsMessengerEXT, debug_utils: ?vk.DebugUtilsMessengerEXT,
@ -65,7 +70,7 @@ pub const VulkanRenderer = struct {
try self.getPhysicalDevice(); try self.getPhysicalDevice();
try self.createLogicalDevice(); try self.createLogicalDevice();
try self.createSwapChain(); try self.createSwapchain();
return self; return self;
} }
@ -166,7 +171,7 @@ pub const VulkanRenderer = struct {
self.presentation_queue = Queue.init(queues[1], self.device.wrapper); self.presentation_queue = Queue.init(queues[1], self.device.wrapper);
} }
fn createSwapChain(self: *Self) !void { 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);
@ -221,6 +226,26 @@ pub const VulkanRenderer = struct {
} }
self.swapchain = try self.device.createSwapchainKHR(&swapchain_create_info, null); self.swapchain = try self.device.createSwapchainKHR(&swapchain_create_info, null);
self.swapchain_image_format = surface_format.format;
self.extent = extent;
// Swapchain images
var swapchain_image_count: u32 = 0;
_ = try self.device.getSwapchainImagesKHR(self.swapchain, &swapchain_image_count, null);
const images = try self.allocator.alloc(vk.Image, swapchain_image_count);
defer self.allocator.free(images);
_ = try self.device.getSwapchainImagesKHR(self.swapchain, &swapchain_image_count, images.ptr);
self.swapchain_images = try self.allocator.alloc(SwapchainImage, swapchain_image_count);
for (images, 0..) |image, i| {
self.swapchain_images[i] = .{
.image = image,
.image_view = try self.createImageView(image, self.swapchain_image_format, .{ .color_bit = true }),
};
}
} }
fn getPhysicalDevice(self: *Self) !void { fn getPhysicalDevice(self: *Self) !void {
@ -235,12 +260,12 @@ pub const VulkanRenderer = struct {
for (pdevs) |pdev| { for (pdevs) |pdev| {
if (self.checkDeviceSuitable(pdev)) { if (self.checkDeviceSuitable(pdev)) {
self.physical_device = pdev; self.physical_device = pdev;
return; break;
} }
} else {
// TODO Obviously needs to be something else
unreachable;
} }
// TODO Obviously needs to be something else
unreachable;
} }
fn getRequiredExtensions(self: Self) ![][*:0]const u8 { fn getRequiredExtensions(self: Self) ![][*:0]const u8 {
@ -410,10 +435,40 @@ pub const VulkanRenderer = struct {
}; };
} }
fn createImageView(self: Self, image: vk.Image, format: vk.Format, aspect_flags: vk.ImageAspectFlags) !vk.ImageView {
const image_view_create_info: vk.ImageViewCreateInfo = .{
.image = image,
.format = format,
.view_type = .@"2d",
.components = .{
// Used for remapping rgba values to other rgba values
.r = .identity,
.g = .identity,
.b = .identity,
.a = .identity,
},
.subresource_range = .{
.aspect_mask = aspect_flags, // Which aspect of image to view (e.g.: colour, depth, stencil, etc...)
.base_mip_level = 0, // Start mipmap level to view from
.level_count = 1, // Number of mipmap levels to view
.base_array_layer = 0, // Start array level to view from
.layer_count = 1, // Number of array levels to view
},
};
return try self.device.createImageView(&image_view_create_info, null);
}
pub fn deinit(self: *Self) void { pub fn deinit(self: *Self) void {
if (enable_validation_layers) { if (enable_validation_layers) {
self.instance.destroyDebugUtilsMessengerEXT(self.debug_utils.?, null); self.instance.destroyDebugUtilsMessengerEXT(self.debug_utils.?, null);
} }
for (self.swapchain_images) |swapchain_image| {
self.device.destroyImageView(swapchain_image.image_view, null);
}
self.allocator.free(self.swapchain_images);
self.device.destroySwapchainKHR(self.swapchain, null); self.device.destroySwapchainKHR(self.swapchain, null);
self.device.destroyDevice(null); self.device.destroyDevice(null);
self.instance.destroySurfaceKHR(self.surface, null); self.instance.destroySurfaceKHR(self.surface, null);