remove vestigial gfx components
This commit is contained in:
@@ -1,30 +0,0 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
const vk = @import("vk");
|
||||
const c = @import("../c.zig");
|
||||
const gfx = @import("../gfx.zig");
|
||||
|
||||
const Self = @This();
|
||||
|
||||
vkb: Wrapper,
|
||||
|
||||
pub fn init() !Self {
|
||||
if (c.glfwInit() != c.GLFW_TRUE)
|
||||
return error.GLFWInitFailed;
|
||||
errdefer c.glfwTerminate();
|
||||
|
||||
if (c.glfwVulkanSupported() != c.GLFW_TRUE) {
|
||||
return error.GLFWNoVulkan;
|
||||
}
|
||||
|
||||
return .{
|
||||
.vkb = try Wrapper.load(c.glfwGetInstanceProcAddress),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(_: Self) void {
|
||||
c.glfwTerminate();
|
||||
}
|
||||
|
||||
pub const Wrapper = vk.BaseWrapper(gfx.apis);
|
@@ -1,5 +0,0 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const vk = @import("vk");
|
||||
const c = @import("../c.zig");
|
||||
const gfx = @import("../c.zig");
|
@@ -1,182 +0,0 @@
|
||||
//! The point here is to select _a_ physical device and create a logical device around it.
|
||||
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
const vk = @import("vk");
|
||||
const c = @import("../c.zig");
|
||||
const gfx = @import("../gfx.zig");
|
||||
|
||||
const Instance = @import("Instance.zig");
|
||||
const Window = @import("Window.zig");
|
||||
|
||||
const Self = @This();
|
||||
|
||||
const required_extensions: []const [*:0]const u8 = &.{
|
||||
vk.extensions.khr_swapchain.name,
|
||||
vk.extensions.khr_dynamic_rendering.name,
|
||||
};
|
||||
|
||||
const preferred_surface_format: vk.SurfaceFormatKHR = .{
|
||||
.color_space = .srgb_nonlinear_khr,
|
||||
.format = .r8g8b8a8_sint,
|
||||
};
|
||||
|
||||
const preferred_present_mode: vk.PresentModeKHR = .mailbox_khr;
|
||||
|
||||
dev: vk.Device,
|
||||
pdev: vk.PhysicalDevice,
|
||||
vkd: Wrapper,
|
||||
|
||||
inst: *const Instance,
|
||||
win: *const Window,
|
||||
|
||||
format: vk.SurfaceFormatKHR,
|
||||
mode: vk.PresentModeKHR,
|
||||
family: u32,
|
||||
queue: vk.Queue,
|
||||
|
||||
pool: vk.CommandPool,
|
||||
|
||||
pub fn init(
|
||||
ally: std.mem.Allocator,
|
||||
inst: *const Instance,
|
||||
win: *const Window,
|
||||
) !Self {
|
||||
var pdev_count: u32 = undefined;
|
||||
_ = try inst.vki.enumeratePhysicalDevices(inst.ref, &pdev_count, null);
|
||||
const pdevs = try ally.alloc(vk.PhysicalDevice, pdev_count);
|
||||
defer ally.free(pdevs);
|
||||
_ = try inst.vki.enumeratePhysicalDevices(inst.ref, &pdev_count, pdevs.ptr);
|
||||
|
||||
for (pdevs) |pdev| {
|
||||
return wrap(ally, inst, win, pdev) catch continue;
|
||||
}
|
||||
|
||||
return error.NoSuitableDevice;
|
||||
}
|
||||
|
||||
pub fn wrap(
|
||||
ally: std.mem.Allocator,
|
||||
inst: *const Instance,
|
||||
win: *const Window,
|
||||
pdev: vk.PhysicalDevice,
|
||||
) !Self {
|
||||
// TODO: Need to rank devices and select the best one
|
||||
// the new laptop doesn't have a discrete gpu.
|
||||
// const props = inst.vki.getPhysicalDeviceProperties(pdev);
|
||||
// if (props.device_type != .discrete_gpu) return error.NotDiscrete;
|
||||
|
||||
var format_count: u32 = undefined;
|
||||
_ = try inst.vki.getPhysicalDeviceSurfaceFormatsKHR(pdev, win.surface, &format_count, null);
|
||||
if (format_count == 0) return error.NoSurfaceFormat;
|
||||
const formats = try ally.alloc(vk.SurfaceFormatKHR, format_count);
|
||||
defer ally.free(formats);
|
||||
_ = try inst.vki.getPhysicalDeviceSurfaceFormatsKHR(pdev, win.surface, &format_count, formats.ptr);
|
||||
|
||||
const format = for (formats) |f| {
|
||||
if (std.meta.eql(f, preferred_surface_format))
|
||||
break f;
|
||||
} else formats[0];
|
||||
|
||||
var mode_count: u32 = undefined;
|
||||
_ = try inst.vki.getPhysicalDeviceSurfacePresentModesKHR(pdev, win.surface, &mode_count, null);
|
||||
if (mode_count == 0) return error.NoSurfaceMode;
|
||||
const modes = try ally.alloc(vk.PresentModeKHR, mode_count);
|
||||
defer ally.free(modes);
|
||||
_ = try inst.vki.getPhysicalDeviceSurfacePresentModesKHR(pdev, win.surface, &mode_count, modes.ptr);
|
||||
|
||||
const mode = for (modes) |m| {
|
||||
if (std.meta.eql(m, preferred_present_mode))
|
||||
break m;
|
||||
} else modes[0];
|
||||
|
||||
var ext_count: u32 = undefined;
|
||||
_ = try inst.vki.enumerateDeviceExtensionProperties(pdev, null, &ext_count, null);
|
||||
const exts = try ally.alloc(vk.ExtensionProperties, ext_count);
|
||||
defer ally.free(exts);
|
||||
_ = try inst.vki.enumerateDeviceExtensionProperties(pdev, null, &ext_count, exts.ptr);
|
||||
|
||||
for (required_extensions) |name| {
|
||||
for (exts) |ext| {
|
||||
if (std.mem.eql(
|
||||
u8,
|
||||
std.mem.span(name),
|
||||
std.mem.sliceTo(&ext.extension_name, 0),
|
||||
)) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
return error.MissingRequiredExtension;
|
||||
}
|
||||
}
|
||||
|
||||
var family_count: u32 = undefined;
|
||||
inst.vki.getPhysicalDeviceQueueFamilyProperties(pdev, &family_count, null);
|
||||
const families = try ally.alloc(vk.QueueFamilyProperties, family_count);
|
||||
defer ally.free(families);
|
||||
inst.vki.getPhysicalDeviceQueueFamilyProperties(pdev, &family_count, families.ptr);
|
||||
|
||||
// just find one family that does graphics and present, so we can use exclusive sharing
|
||||
// on the swapchain. apparently most hardware supports this. logic for queue allocation
|
||||
// and swapchain creation is so much simpler this way. swapchain creation needs to know
|
||||
// the list of queue family indices which will have access to the images, and there's a
|
||||
// performance penalty to allow concurrent access to multiple queue families.
|
||||
//
|
||||
// multiple _queues_ may have exclusive access, but only if they're in the smae family.
|
||||
|
||||
const family: u32 = for (families, 0..) |family, idx| {
|
||||
const graphics = family.queue_flags.graphics_bit;
|
||||
const present = try inst.vki.getPhysicalDeviceSurfaceSupportKHR(pdev, @intCast(idx), win.surface) == vk.TRUE;
|
||||
if (graphics and present) break @intCast(idx);
|
||||
} else {
|
||||
return error.NoSuitableQueueFamily;
|
||||
};
|
||||
|
||||
const qci: []const vk.DeviceQueueCreateInfo = &.{
|
||||
vk.DeviceQueueCreateInfo{
|
||||
.queue_family_index = family,
|
||||
.queue_count = 1,
|
||||
.p_queue_priorities = &[_]f32{1.0},
|
||||
},
|
||||
};
|
||||
|
||||
const dev = try inst.vki.createDevice(pdev, &.{
|
||||
.queue_create_info_count = @intCast(qci.len),
|
||||
.p_queue_create_infos = qci.ptr,
|
||||
.enabled_extension_count = @intCast(required_extensions.len),
|
||||
.pp_enabled_extension_names = required_extensions.ptr,
|
||||
.p_next = &vk.PhysicalDeviceDynamicRenderingFeaturesKHR{
|
||||
.dynamic_rendering = vk.TRUE,
|
||||
},
|
||||
}, null);
|
||||
const vkd = try Wrapper.load(dev, inst.vki.dispatch.vkGetDeviceProcAddr);
|
||||
errdefer vkd.destroyDevice(dev, null);
|
||||
|
||||
const pool = try vkd.createCommandPool(dev, &.{
|
||||
.queue_family_index = family,
|
||||
}, null);
|
||||
errdefer vkd.destroyCommandPool(dev, pool, null);
|
||||
|
||||
const queue = vkd.getDeviceQueue(dev, family, 0);
|
||||
|
||||
return .{
|
||||
.dev = dev,
|
||||
.pdev = pdev,
|
||||
.vkd = vkd,
|
||||
.inst = inst,
|
||||
.win = win,
|
||||
.format = format,
|
||||
.mode = mode,
|
||||
.pool = pool,
|
||||
.family = family,
|
||||
.queue = queue,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: Self) void {
|
||||
self.vkd.destroyCommandPool(self.dev, self.pool, null);
|
||||
self.vkd.destroyDevice(self.dev, null);
|
||||
}
|
||||
|
||||
pub const Wrapper = vk.DeviceWrapper(gfx.apis);
|
@@ -1,143 +0,0 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
const vk = @import("vk");
|
||||
const c = @import("../c.zig");
|
||||
const gfx = @import("../gfx.zig");
|
||||
|
||||
const Self = @This();
|
||||
|
||||
const app_info: vk.ApplicationInfo = .{
|
||||
.p_application_name = "zig-glfw-vulkan",
|
||||
.application_version = vk.makeApiVersion(0, 0, 0, 0),
|
||||
.p_engine_name = "zig-glfw-vulkan",
|
||||
.engine_version = vk.makeApiVersion(0, 0, 0, 0),
|
||||
.api_version = vk.API_VERSION_1_3,
|
||||
};
|
||||
|
||||
ref: vk.Instance,
|
||||
vki: Wrapper,
|
||||
base: *const gfx.Base,
|
||||
|
||||
messenger: if (gfx.use_debug_messenger) vk.DebugUtilsMessengerEXT else void,
|
||||
|
||||
pub fn init(
|
||||
base: *const gfx.Base,
|
||||
) !Self {
|
||||
var exts: std.BoundedArray([*:0]const u8, 32) = .{};
|
||||
var layers: std.BoundedArray([*:0]const u8, 32) = .{};
|
||||
|
||||
if (gfx.use_debug_messenger) {
|
||||
try exts.appendSlice(&.{
|
||||
vk.extensions.ext_debug_utils.name,
|
||||
});
|
||||
|
||||
try layers.appendSlice(&.{
|
||||
"VK_LAYER_KHRONOS_validation",
|
||||
});
|
||||
}
|
||||
|
||||
var glfw_exts_count: u32 = 0;
|
||||
const glfw_exts: [*]const [*:0]const u8 =
|
||||
@ptrCast(c.glfwGetRequiredInstanceExtensions(&glfw_exts_count));
|
||||
try exts.appendSlice(glfw_exts[0..glfw_exts_count]);
|
||||
|
||||
const mci: vk.DebugUtilsMessengerCreateInfoEXT = .{
|
||||
.message_severity = .{
|
||||
.error_bit_ext = true,
|
||||
.info_bit_ext = true,
|
||||
.verbose_bit_ext = true,
|
||||
.warning_bit_ext = true,
|
||||
},
|
||||
.message_type = .{
|
||||
.device_address_binding_bit_ext = true,
|
||||
.general_bit_ext = false,
|
||||
.performance_bit_ext = true,
|
||||
.validation_bit_ext = true,
|
||||
},
|
||||
.pfn_user_callback = &debug_callback,
|
||||
.p_user_data = null,
|
||||
};
|
||||
|
||||
const ref = try base.vkb.createInstance(&.{
|
||||
.p_application_info = &app_info,
|
||||
.enabled_extension_count = @intCast(exts.len),
|
||||
.pp_enabled_extension_names = &exts.buffer,
|
||||
.enabled_layer_count = @intCast(layers.len),
|
||||
.pp_enabled_layer_names = &layers.buffer,
|
||||
.p_next = if (gfx.use_debug_messenger) &mci else null,
|
||||
}, null);
|
||||
|
||||
const vki = try Wrapper.load(ref, base.vkb.dispatch.vkGetInstanceProcAddr);
|
||||
errdefer vki.destroyInstance(ref, null);
|
||||
|
||||
const messenger = if (gfx.use_debug_messenger)
|
||||
try vki.createDebugUtilsMessengerEXT(ref, &mci, null)
|
||||
else
|
||||
void{};
|
||||
|
||||
errdefer if (gfx.use_debug_messenger)
|
||||
vki.destroyDebugUtilsMessengerEXT(ref, messenger, null);
|
||||
|
||||
return .{
|
||||
.ref = ref,
|
||||
.vki = vki,
|
||||
.base = base,
|
||||
.messenger = messenger,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: Self) void {
|
||||
if (gfx.use_debug_messenger)
|
||||
self.vki.destroyDebugUtilsMessengerEXT(self.ref, self.messenger, null);
|
||||
self.vki.destroyInstance(self.ref, null);
|
||||
}
|
||||
|
||||
pub const Wrapper = vk.InstanceWrapper(gfx.apis);
|
||||
|
||||
pub fn debug_callback(
|
||||
msg_severity: vk.DebugUtilsMessageSeverityFlagsEXT,
|
||||
msg_type: vk.DebugUtilsMessageTypeFlagsEXT,
|
||||
p_data: ?*const vk.DebugUtilsMessengerCallbackDataEXT,
|
||||
_: ?*anyopaque,
|
||||
) callconv(vk.vulkan_call_conv) vk.Bool32 {
|
||||
// ripped from std.log.defaultLog
|
||||
|
||||
const data = p_data orelse return vk.FALSE;
|
||||
const message = data.p_message orelse return vk.FALSE;
|
||||
|
||||
const severity_prefix = if (msg_severity.verbose_bit_ext)
|
||||
"verbose:"
|
||||
else if (msg_severity.info_bit_ext)
|
||||
"info:"
|
||||
else if (msg_severity.warning_bit_ext)
|
||||
"warning:"
|
||||
else if (msg_severity.error_bit_ext)
|
||||
"error:"
|
||||
else
|
||||
"?:";
|
||||
|
||||
const type_prefix = if (msg_type.general_bit_ext)
|
||||
""
|
||||
else if (msg_type.validation_bit_ext)
|
||||
"validation:"
|
||||
else if (msg_type.performance_bit_ext)
|
||||
"performance:"
|
||||
else if (msg_type.device_address_binding_bit_ext)
|
||||
"device_address_binding:"
|
||||
else
|
||||
"?:";
|
||||
|
||||
const stderr = std.io.getStdErr().writer();
|
||||
var bw = std.io.bufferedWriter(stderr);
|
||||
const writer = bw.writer();
|
||||
|
||||
std.debug.lockStdErr();
|
||||
defer std.debug.unlockStdErr();
|
||||
nosuspend {
|
||||
writer.print("vk-{s}{s} {s}\n", .{ severity_prefix, type_prefix, message }) catch return vk.FALSE;
|
||||
bw.flush() catch return vk.FALSE;
|
||||
}
|
||||
|
||||
return vk.FALSE;
|
||||
}
|
@@ -1,41 +0,0 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
const vk = @import("vk");
|
||||
const c = @import("../c.zig");
|
||||
|
||||
const Base = @import("Base.zig");
|
||||
const Instance = @import("Instance.zig");
|
||||
|
||||
const Self = @This();
|
||||
|
||||
ref: *c.GLFWwindow,
|
||||
surface: vk.SurfaceKHR,
|
||||
|
||||
inst: *const Instance,
|
||||
|
||||
pub fn init(inst: *const Instance, title: [*:0]const u8, extent: vk.Extent2D) !Self {
|
||||
c.glfwWindowHintString(c.GLFW_X11_CLASS_NAME, "floating_window");
|
||||
c.glfwWindowHintString(c.GLFW_X11_INSTANCE_NAME, "floating_window");
|
||||
c.glfwWindowHint(c.GLFW_CLIENT_API, c.GLFW_NO_API);
|
||||
|
||||
const ref = c.glfwCreateWindow(@intCast(extent.width), @intCast(extent.height), title, null, null) orelse
|
||||
return error.GLFWWindowCreateFailed;
|
||||
errdefer c.glfwDestroyWindow(ref);
|
||||
|
||||
var surface: vk.SurfaceKHR = undefined;
|
||||
if (c.glfwCreateWindowSurface(inst.ref, ref, null, &surface) != .success)
|
||||
return error.GLFWWindowSurfaceFailed;
|
||||
errdefer inst.vki.destroySurfaceKHR(inst.ref, surface, null);
|
||||
|
||||
return .{
|
||||
.ref = ref,
|
||||
.surface = surface,
|
||||
.inst = inst,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: Self) void {
|
||||
self.inst.vki.destroySurfaceKHR(self.inst.ref, self.surface, null);
|
||||
c.glfwDestroyWindow(self.ref);
|
||||
}
|
Reference in New Issue
Block a user