Start implementing the swapchain
This commit is contained in:
parent
5c50f5eb7c
commit
73a30b9d03
2 changed files with 98 additions and 37 deletions
|
@ -1,10 +1,13 @@
|
|||
const std = @import("std");
|
||||
const vk = @import("vulkan");
|
||||
|
||||
pub const device_extensions = [_][*:0]const u8{vk.extensions.khr_swapchain.name};
|
||||
|
||||
pub const QueueFamilyIndices = struct {
|
||||
graphics_family: ?u32,
|
||||
graphics_family: ?u32 = null,
|
||||
presentation_family: ?u32 = null,
|
||||
|
||||
pub fn isValid(self: QueueFamilyIndices) bool {
|
||||
return self.graphics_family != null;
|
||||
return self.graphics_family != null and self.presentation_family != null;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,26 +1,27 @@
|
|||
const std = @import("std");
|
||||
const sdl = @import("sdl2");
|
||||
const vk = @import("vulkan");
|
||||
const QueueFamilyIndices = @import("utilities.zig").QueueFamilyIndices;
|
||||
const Utilities = @import("utilities.zig");
|
||||
const QueueFamilyIndices = Utilities.QueueFamilyIndices;
|
||||
|
||||
const enable_validation_layers = true;
|
||||
const validation_layers = [_][*:0]const u8{"VK_LAYER_KHRONOS_validation"};
|
||||
|
||||
const apis: []const vk.ApiInfo = &.{
|
||||
.{
|
||||
.base_commands = .{
|
||||
.createInstance = true,
|
||||
},
|
||||
.instance_commands = .{
|
||||
.createDevice = true,
|
||||
},
|
||||
},
|
||||
// .{
|
||||
// .base_commands = .{
|
||||
// .createInstance = true,
|
||||
// },
|
||||
// .instance_commands = .{
|
||||
// .createDevice = true,
|
||||
// },
|
||||
// },
|
||||
vk.features.version_1_0,
|
||||
vk.features.version_1_1,
|
||||
vk.features.version_1_2,
|
||||
vk.features.version_1_3,
|
||||
vk.extensions.khr_surface,
|
||||
// vk.extensions.khr_swapchain,
|
||||
vk.extensions.khr_swapchain,
|
||||
vk.extensions.ext_debug_utils,
|
||||
};
|
||||
|
||||
|
@ -44,7 +45,10 @@ pub const VulkanRenderer = struct {
|
|||
instance: Instance,
|
||||
physical_device: vk.PhysicalDevice,
|
||||
device: Device,
|
||||
|
||||
graphics_queue: Queue,
|
||||
presentation_queue: Queue,
|
||||
|
||||
surface: vk.SurfaceKHR,
|
||||
|
||||
debug_utils: ?vk.DebugUtilsMessengerEXT,
|
||||
|
@ -64,12 +68,12 @@ pub const VulkanRenderer = struct {
|
|||
|
||||
self.instance = Instance.init(instance, vki);
|
||||
self.surface = try sdl.vulkan.createSurface(self.window, self.instance.handle);
|
||||
self.physical_device = try self.getPhysicalDevice();
|
||||
|
||||
if (enable_validation_layers) {
|
||||
self.debug_utils = try self.createDebugMessenger();
|
||||
}
|
||||
|
||||
self.physical_device = try self.getPhysicalDevice();
|
||||
const device = try self.createLogicalDevice();
|
||||
|
||||
const vkd = try allocator.create(DeviceDispatch);
|
||||
|
@ -77,9 +81,10 @@ pub const VulkanRenderer = struct {
|
|||
vkd.* = try DeviceDispatch.load(device, self.instance.wrapper.dispatch.vkGetDeviceProcAddr);
|
||||
|
||||
self.device = Device.init(device, vkd);
|
||||
const queue = try self.getDeviceQueues();
|
||||
const queues = try self.getDeviceQueues();
|
||||
|
||||
self.graphics_queue = Queue.init(queue, vkd);
|
||||
self.graphics_queue = Queue.init(queues[0], vkd);
|
||||
self.presentation_queue = Queue.init(queues[1], vkd);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
@ -97,7 +102,7 @@ pub const VulkanRenderer = struct {
|
|||
std.debug.print("\t- {s}\n", .{ext});
|
||||
}
|
||||
|
||||
if (!try self.checkExtensions(&extensions)) {
|
||||
if (!try self.checkInstanceExtensions(&extensions)) {
|
||||
return error.ExtensionNotPresent;
|
||||
}
|
||||
|
||||
|
@ -116,8 +121,11 @@ pub const VulkanRenderer = struct {
|
|||
};
|
||||
|
||||
if (enable_validation_layers) {
|
||||
const debug_create_info = getDebugUtilsCreateInfo();
|
||||
|
||||
instance_create_info.enabled_layer_count = @intCast(validation_layers.len);
|
||||
instance_create_info.pp_enabled_layer_names = &validation_layers;
|
||||
instance_create_info.p_next = &debug_create_info;
|
||||
}
|
||||
|
||||
return try self.vkb.createInstance(&instance_create_info, null);
|
||||
|
@ -140,7 +148,7 @@ pub const VulkanRenderer = struct {
|
|||
return extensions;
|
||||
}
|
||||
|
||||
fn checkExtensions(self: Self, required_extensions: *const [][*:0]const u8) !bool {
|
||||
fn checkInstanceExtensions(self: Self, required_extensions: *const [][*:0]const u8) !bool {
|
||||
var prop_count: u32 = 0;
|
||||
_ = try self.vkb.enumerateInstanceExtensionProperties(null, &prop_count, null);
|
||||
|
||||
|
@ -150,15 +158,39 @@ pub const VulkanRenderer = struct {
|
|||
_ = try self.vkb.enumerateInstanceExtensionProperties(null, &prop_count, props.ptr);
|
||||
|
||||
for (required_extensions.*) |required_extension| {
|
||||
var found = false;
|
||||
|
||||
for (props) |prop| {
|
||||
if (std.mem.eql(u8, std.mem.sliceTo(&prop.extension_name, 0), std.mem.span(required_extension))) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
return true;
|
||||
}
|
||||
|
||||
fn checkDeviceExtensions(self: Self, pdev: vk.PhysicalDevice) !bool {
|
||||
var prop_count: u32 = 0;
|
||||
_ = try self.instance.enumerateDeviceExtensionProperties(pdev, null, &prop_count, null);
|
||||
|
||||
if (prop_count == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std.debug.print("Ext count: {d}\n", .{prop_count});
|
||||
const props = try self.allocator.alloc(vk.ExtensionProperties, prop_count);
|
||||
defer self.allocator.free(props);
|
||||
|
||||
_ = try self.vkb.enumerateDeviceExtensionProperties(null, &prop_count, props.ptr);
|
||||
|
||||
for (Utilities.device_extensions) |device_extension| {
|
||||
for (props) |prop| {
|
||||
// std.debug.print("Ext: {s}\n", .{&prop.extension_name});
|
||||
if (std.mem.eql(u8, std.mem.sliceTo(&prop.extension_name, 0), std.mem.span(device_extension))) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -196,7 +228,9 @@ pub const VulkanRenderer = struct {
|
|||
return false;
|
||||
};
|
||||
|
||||
return queue_family_indices.isValid();
|
||||
const extension_support = self.checkDeviceExtensions(pdev) catch false;
|
||||
|
||||
return queue_family_indices.isValid() and extension_support;
|
||||
}
|
||||
|
||||
fn getQueueFamilies(self: Self, pdev: vk.PhysicalDevice) !QueueFamilyIndices {
|
||||
|
@ -215,6 +249,11 @@ pub const VulkanRenderer = struct {
|
|||
indices.graphics_family = @intCast(i);
|
||||
}
|
||||
|
||||
const presentation_support = try self.instance.getPhysicalDeviceSurfaceSupportKHR(pdev, @intCast(i), self.surface);
|
||||
if (queue_family.queue_count > 0 and presentation_support == vk.TRUE) {
|
||||
indices.presentation_family = @intCast(i);
|
||||
}
|
||||
|
||||
if (indices.isValid()) {
|
||||
return indices;
|
||||
}
|
||||
|
@ -228,25 +267,40 @@ pub const VulkanRenderer = struct {
|
|||
// 1 is the highest priority
|
||||
const priority = [_]f32{1};
|
||||
|
||||
const queue_create_info = [_]vk.DeviceQueueCreateInfo{.{
|
||||
.queue_family_index = indices.graphics_family.?,
|
||||
.queue_count = 1,
|
||||
.p_queue_priorities = &priority,
|
||||
}};
|
||||
const qci = [_]vk.DeviceQueueCreateInfo{
|
||||
.{
|
||||
.queue_family_index = indices.graphics_family.?,
|
||||
.queue_count = 1,
|
||||
.p_queue_priorities = &priority,
|
||||
},
|
||||
.{
|
||||
.queue_family_index = indices.presentation_family.?,
|
||||
.queue_count = 1,
|
||||
.p_queue_priorities = &priority,
|
||||
},
|
||||
};
|
||||
|
||||
const queue_count: u32 = if (indices.graphics_family.? == indices.presentation_family.?)
|
||||
1
|
||||
else
|
||||
2;
|
||||
|
||||
const device_create_info: vk.DeviceCreateInfo = .{
|
||||
.queue_create_info_count = 1,
|
||||
.p_queue_create_infos = &queue_create_info,
|
||||
.enabled_extension_count = 0,
|
||||
.queue_create_info_count = queue_count,
|
||||
.p_queue_create_infos = &qci,
|
||||
.pp_enabled_extension_names = &Utilities.device_extensions,
|
||||
.enabled_extension_count = @intCast(Utilities.device_extensions.len),
|
||||
};
|
||||
|
||||
return try self.instance.createDevice(self.physical_device, &device_create_info, null);
|
||||
}
|
||||
|
||||
fn getDeviceQueues(self: Self) !vk.Queue {
|
||||
fn getDeviceQueues(self: Self) ![2]vk.Queue {
|
||||
const indices = try self.getQueueFamilies(self.physical_device);
|
||||
|
||||
return self.device.getDeviceQueue(indices.graphics_family.?, 0);
|
||||
const graphics_queue = self.device.getDeviceQueue(indices.graphics_family.?, 0);
|
||||
const presentation_queue = self.device.getDeviceQueue(indices.presentation_family.?, 0);
|
||||
return .{ graphics_queue, presentation_queue };
|
||||
}
|
||||
|
||||
fn checkValidationLayersSupport(self: Self) bool {
|
||||
|
@ -274,11 +328,7 @@ pub const VulkanRenderer = struct {
|
|||
}
|
||||
|
||||
fn createDebugMessenger(self: Self) !vk.DebugUtilsMessengerEXT {
|
||||
const debug_create_info: vk.DebugUtilsMessengerCreateInfoEXT = .{
|
||||
.message_severity = .{ .verbose_bit_ext = true, .warning_bit_ext = true, .error_bit_ext = true },
|
||||
.message_type = .{ .general_bit_ext = true, .validation_bit_ext = true, .performance_bit_ext = true },
|
||||
.pfn_user_callback = debugCallback,
|
||||
};
|
||||
const debug_create_info = getDebugUtilsCreateInfo();
|
||||
|
||||
return try self.instance.createDebugUtilsMessengerEXT(&debug_create_info, null);
|
||||
}
|
||||
|
@ -296,6 +346,14 @@ pub const VulkanRenderer = struct {
|
|||
}
|
||||
};
|
||||
|
||||
fn getDebugUtilsCreateInfo() vk.DebugUtilsMessengerCreateInfoEXT {
|
||||
return vk.DebugUtilsMessengerCreateInfoEXT{
|
||||
.message_severity = .{ .verbose_bit_ext = true, .warning_bit_ext = true, .error_bit_ext = true },
|
||||
.message_type = .{ .general_bit_ext = true, .validation_bit_ext = true, .performance_bit_ext = true },
|
||||
.pfn_user_callback = debugCallback,
|
||||
};
|
||||
}
|
||||
|
||||
// message_severity: vk.DebugUtilsMessageSeverityFlagsEXT,
|
||||
// message_types: vk.DebugUtilsMessageTypeFlagsEXT,
|
||||
// p_callback_data: ?*const vk.DebugUtilsMessengerCallbackDataEXT,
|
||||
|
|
Loading…
Reference in a new issue