WIP vulkan-tutorial 07 - device extensions
This commit is contained in:
@@ -35,23 +35,29 @@ pub fn init(allocator: std.mem.Allocator, window: *c.GLFWwindow) !Self {
|
|||||||
self.vkb = try BaseDispatch.load(&c.glfwGetInstanceProcAddress);
|
self.vkb = try BaseDispatch.load(&c.glfwGetInstanceProcAddress);
|
||||||
const vkb = self.vkb;
|
const vkb = self.vkb;
|
||||||
|
|
||||||
var exts = std.ArrayList([*:0]const u8).init(allocator);
|
var req_exts = std.ArrayList([*:0]const u8).init(allocator);
|
||||||
defer exts.deinit();
|
defer req_exts.deinit();
|
||||||
|
|
||||||
var layers = std.ArrayList([*:0]const u8).init(allocator);
|
var req_layers = std.ArrayList([*:0]const u8).init(allocator);
|
||||||
defer layers.deinit();
|
defer req_layers.deinit();
|
||||||
|
|
||||||
|
var req_device_exts = std.ArrayList([*:0]const u8).init(allocator);
|
||||||
|
defer req_device_exts.deinit();
|
||||||
|
|
||||||
if (USE_DEBUG_LAYERS) {
|
if (USE_DEBUG_LAYERS) {
|
||||||
try layers.append("VK_LAYER_KHRONOS_validation");
|
try req_layers.append("VK_LAYER_KHRONOS_validation");
|
||||||
try exts.append("VK_EXT_debug_utils");
|
try req_exts.append("VK_EXT_debug_utils");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try req_device_exts.append("VK_KHR_swapchain");
|
||||||
|
|
||||||
var glfw_ext_count: u32 = 0;
|
var glfw_ext_count: u32 = 0;
|
||||||
const glfw_exts: [*][*:0]const u8 = @ptrCast(c.glfwGetRequiredInstanceExtensions(&glfw_ext_count));
|
const glfw_exts: [*][*:0]const u8 = @ptrCast(c.glfwGetRequiredInstanceExtensions(&glfw_ext_count));
|
||||||
try exts.appendSlice(glfw_exts[0..glfw_ext_count]);
|
try req_exts.appendSlice(glfw_exts[0..glfw_ext_count]);
|
||||||
|
|
||||||
std.log.debug("requesting extensions: {s}", .{exts.items});
|
std.log.debug("requesting extensions: {s}", .{req_exts.items});
|
||||||
std.log.debug("requesting layers: {s}", .{layers.items});
|
std.log.debug("requesting layers: {s}", .{req_layers.items});
|
||||||
|
std.log.debug("requesting device extensions: {s}", .{req_device_exts.items});
|
||||||
|
|
||||||
var available_ext_count: u32 = 0;
|
var available_ext_count: u32 = 0;
|
||||||
_ = try vkb.enumerateInstanceExtensionProperties(null, &available_ext_count, null);
|
_ = try vkb.enumerateInstanceExtensionProperties(null, &available_ext_count, null);
|
||||||
@@ -65,7 +71,7 @@ pub fn init(allocator: std.mem.Allocator, window: *c.GLFWwindow) !Self {
|
|||||||
defer allocator.free(available_layers);
|
defer allocator.free(available_layers);
|
||||||
_ = try vkb.enumerateInstanceLayerProperties(&available_layer_count, available_layers.ptr);
|
_ = try vkb.enumerateInstanceLayerProperties(&available_layer_count, available_layers.ptr);
|
||||||
|
|
||||||
for (exts.items) |name| {
|
for (req_exts.items) |name| {
|
||||||
const required_name = std.mem.sliceTo(name, 0);
|
const required_name = std.mem.sliceTo(name, 0);
|
||||||
for (available_exts) |prop| {
|
for (available_exts) |prop| {
|
||||||
const available_name = std.mem.sliceTo(&prop.extension_name, 0);
|
const available_name = std.mem.sliceTo(&prop.extension_name, 0);
|
||||||
@@ -75,7 +81,7 @@ pub fn init(allocator: std.mem.Allocator, window: *c.GLFWwindow) !Self {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (layers.items) |name| {
|
for (req_layers.items) |name| {
|
||||||
const required_name = std.mem.sliceTo(name, 0);
|
const required_name = std.mem.sliceTo(name, 0);
|
||||||
for (available_layers) |prop| {
|
for (available_layers) |prop| {
|
||||||
const available_name = std.mem.sliceTo(&prop.layer_name, 0);
|
const available_name = std.mem.sliceTo(&prop.layer_name, 0);
|
||||||
@@ -112,10 +118,10 @@ pub fn init(allocator: std.mem.Allocator, window: *c.GLFWwindow) !Self {
|
|||||||
|
|
||||||
const instance_create_info = vk.InstanceCreateInfo{
|
const instance_create_info = vk.InstanceCreateInfo{
|
||||||
.p_application_info = &app_info,
|
.p_application_info = &app_info,
|
||||||
.enabled_extension_count = @intCast(exts.items.len),
|
.enabled_extension_count = @intCast(req_exts.items.len),
|
||||||
.pp_enabled_extension_names = exts.items.ptr,
|
.pp_enabled_extension_names = req_exts.items.ptr,
|
||||||
.enabled_layer_count = @intCast(layers.items.len),
|
.enabled_layer_count = @intCast(req_layers.items.len),
|
||||||
.pp_enabled_layer_names = layers.items.ptr,
|
.pp_enabled_layer_names = req_layers.items.ptr,
|
||||||
.p_next = if (USE_DEBUG_LAYERS) &debug_create_info else null,
|
.p_next = if (USE_DEBUG_LAYERS) &debug_create_info else null,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -155,13 +161,17 @@ pub fn init(allocator: std.mem.Allocator, window: *c.GLFWwindow) !Self {
|
|||||||
defer allocator.free(devices);
|
defer allocator.free(devices);
|
||||||
_ = try vki.enumeratePhysicalDevices(self.instance, &device_count, devices.ptr);
|
_ = try vki.enumeratePhysicalDevices(self.instance, &device_count, devices.ptr);
|
||||||
|
|
||||||
|
var available_device_exts_count: u32 = 0;
|
||||||
|
var available_device_exts = std.ArrayList(vk.ExtensionProperties).init(allocator);
|
||||||
|
defer available_device_exts.deinit();
|
||||||
|
|
||||||
// todo some ranking strategy to find the most-suitable device
|
// todo some ranking strategy to find the most-suitable device
|
||||||
const Selection = struct {
|
const Selection = struct {
|
||||||
device: vk.PhysicalDevice,
|
device: vk.PhysicalDevice,
|
||||||
props: vk.PhysicalDeviceProperties,
|
props: vk.PhysicalDeviceProperties,
|
||||||
feats: vk.PhysicalDeviceFeatures,
|
feats: vk.PhysicalDeviceFeatures,
|
||||||
};
|
};
|
||||||
const selected: Selection = for (devices) |device| {
|
const selected: Selection = find_device: for (devices) |device| {
|
||||||
const props = vki.getPhysicalDeviceProperties(device);
|
const props = vki.getPhysicalDeviceProperties(device);
|
||||||
const feats = vki.getPhysicalDeviceFeatures(device);
|
const feats = vki.getPhysicalDeviceFeatures(device);
|
||||||
|
|
||||||
@@ -169,6 +179,31 @@ pub fn init(allocator: std.mem.Allocator, window: *c.GLFWwindow) !Self {
|
|||||||
|
|
||||||
// if (feats.geometry_shader == vk.FALSE) continue;
|
// if (feats.geometry_shader == vk.FALSE) continue;
|
||||||
|
|
||||||
|
_ = try vki.enumerateDeviceExtensionProperties(
|
||||||
|
device,
|
||||||
|
null,
|
||||||
|
&available_device_exts_count,
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
try available_device_exts.resize(available_device_exts_count);
|
||||||
|
_ = try vki.enumerateDeviceExtensionProperties(
|
||||||
|
device,
|
||||||
|
null,
|
||||||
|
&available_device_exts_count,
|
||||||
|
available_device_exts.items.ptr,
|
||||||
|
);
|
||||||
|
|
||||||
|
for (req_device_exts.items) |name| {
|
||||||
|
const required_name = std.mem.sliceTo(name, 0);
|
||||||
|
for (available_device_exts.items) |prop| {
|
||||||
|
const available_name = std.mem.sliceTo(&prop.extension_name, 0);
|
||||||
|
if (std.mem.eql(u8, required_name, available_name)) break;
|
||||||
|
} else {
|
||||||
|
std.log.warn("cannot find {s}\n", .{required_name});
|
||||||
|
continue :find_device;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break .{
|
break .{
|
||||||
.device = device,
|
.device = device,
|
||||||
.props = props,
|
.props = props,
|
||||||
@@ -231,7 +266,6 @@ pub fn init(allocator: std.mem.Allocator, window: *c.GLFWwindow) !Self {
|
|||||||
// group and unpack the queues, but I'm not bothering with that for now until I restructure this monolithic function
|
// group and unpack the queues, but I'm not bothering with that for now until I restructure this monolithic function
|
||||||
// in general.
|
// in general.
|
||||||
if (indices.graphics == indices.present) {
|
if (indices.graphics == indices.present) {
|
||||||
std.log.info("using one queue family", .{});
|
|
||||||
const gp_slice = gp_priorities[0..2];
|
const gp_slice = gp_priorities[0..2];
|
||||||
try queue_create_infos.append(.{
|
try queue_create_infos.append(.{
|
||||||
.queue_family_index = indices.graphics,
|
.queue_family_index = indices.graphics,
|
||||||
@@ -239,7 +273,6 @@ pub fn init(allocator: std.mem.Allocator, window: *c.GLFWwindow) !Self {
|
|||||||
.p_queue_priorities = gp_slice.ptr,
|
.p_queue_priorities = gp_slice.ptr,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
std.log.info("using two queue families", .{});
|
|
||||||
const g_slice = gp_priorities[0..1];
|
const g_slice = gp_priorities[0..1];
|
||||||
const p_slice = gp_priorities[1..2];
|
const p_slice = gp_priorities[1..2];
|
||||||
try queue_create_infos.append(.{
|
try queue_create_infos.append(.{
|
||||||
@@ -258,10 +291,10 @@ pub fn init(allocator: std.mem.Allocator, window: *c.GLFWwindow) !Self {
|
|||||||
.queue_create_info_count = @intCast(queue_create_infos.items.len),
|
.queue_create_info_count = @intCast(queue_create_infos.items.len),
|
||||||
.p_queue_create_infos = queue_create_infos.items.ptr,
|
.p_queue_create_infos = queue_create_infos.items.ptr,
|
||||||
.p_enabled_features = &selected.feats,
|
.p_enabled_features = &selected.feats,
|
||||||
// .enabled_extension_count = @intCast(exts.items.len),
|
.enabled_extension_count = @intCast(req_device_exts.items.len),
|
||||||
// .pp_enabled_extension_names = exts.items.ptr,
|
.pp_enabled_extension_names = req_device_exts.items.ptr,
|
||||||
.enabled_layer_count = @intCast(layers.items.len),
|
.enabled_layer_count = @intCast(req_layers.items.len),
|
||||||
.pp_enabled_layer_names = layers.items.ptr,
|
.pp_enabled_layer_names = req_layers.items.ptr,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.device = try vki.createDevice(
|
self.device = try vki.createDevice(
|
||||||
@@ -376,6 +409,7 @@ const InstanceDispatch = vk.InstanceWrapper(.{
|
|||||||
.getDeviceProcAddr = true,
|
.getDeviceProcAddr = true,
|
||||||
.destroySurfaceKHR = true,
|
.destroySurfaceKHR = true,
|
||||||
.getPhysicalDeviceSurfaceSupportKHR = true,
|
.getPhysicalDeviceSurfaceSupportKHR = true,
|
||||||
|
.enumerateDeviceExtensionProperties = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const DeviceDispatch = vk.DeviceWrapper(.{
|
const DeviceDispatch = vk.DeviceWrapper(.{
|
||||||
|
Reference in New Issue
Block a user