graphics_context incremental teardown

This commit is contained in:
David Allemang
2024-03-28 16:06:50 -04:00
parent 0f840a6422
commit 282e85db24
6 changed files with 155 additions and 247 deletions

75
src/gfx.zig Normal file
View File

@@ -0,0 +1,75 @@
const vk = @import("vk");
pub const BaseDispatch = vk.BaseWrapper(.{
.createInstance = true,
.getInstanceProcAddr = true,
});
pub const InstanceDispatch = vk.InstanceWrapper(.{
.destroyInstance = true,
.createDevice = true,
.destroySurfaceKHR = true,
.enumeratePhysicalDevices = true,
.getPhysicalDeviceProperties = true,
.enumerateDeviceExtensionProperties = true,
.getPhysicalDeviceSurfaceFormatsKHR = true,
.getPhysicalDeviceSurfacePresentModesKHR = true,
.getPhysicalDeviceSurfaceCapabilitiesKHR = true,
.getPhysicalDeviceQueueFamilyProperties = true,
.getPhysicalDeviceSurfaceSupportKHR = true,
.getPhysicalDeviceMemoryProperties = true,
.getDeviceProcAddr = true,
});
pub const DeviceDispatch = vk.DeviceWrapper(.{
.destroyDevice = true,
.getDeviceQueue = true,
.createSemaphore = true,
.createFence = true,
.createImageView = true,
.destroyImageView = true,
.destroySemaphore = true,
.destroyFence = true,
.getSwapchainImagesKHR = true,
.createSwapchainKHR = true,
.destroySwapchainKHR = true,
.acquireNextImageKHR = true,
.deviceWaitIdle = true,
.waitForFences = true,
.resetFences = true,
.queueSubmit = true,
.queuePresentKHR = true,
.createCommandPool = true,
.destroyCommandPool = true,
.allocateCommandBuffers = true,
.freeCommandBuffers = true,
.queueWaitIdle = true,
.createShaderModule = true,
.destroyShaderModule = true,
.createPipelineLayout = true,
.destroyPipelineLayout = true,
.createGraphicsPipelines = true,
.destroyPipeline = true,
.beginCommandBuffer = true,
.endCommandBuffer = true,
.allocateMemory = true,
.freeMemory = true,
.createBuffer = true,
.destroyBuffer = true,
.getBufferMemoryRequirements = true,
.mapMemory = true,
.unmapMemory = true,
.bindBufferMemory = true,
.cmdBeginRenderPass = true,
.cmdEndRenderPass = true,
.cmdBindPipeline = true,
.cmdDraw = true,
.cmdDrawIndexed = true,
.cmdSetViewport = true,
.cmdSetScissor = true,
.cmdBindVertexBuffers = true,
.cmdBindIndexBuffer = true,
.cmdCopyBuffer = true,
.cmdBeginRenderingKHR = true,
.cmdEndRenderingKHR = true,
});

6
src/gfx/Context.zig Normal file
View File

@@ -0,0 +1,6 @@
const std = @import("std");
const vk = @import("vk");
const d = @import("dispatch.zig");
const Self = @This();

View File

@@ -3,91 +3,21 @@ const vk = @import("vk");
const c = @import("c.zig");
const Allocator = std.mem.Allocator;
const gfx = @import("gfx.zig");
const BaseDispatch = gfx.BaseDispatch;
const InstanceDispatch = gfx.InstanceDispatch;
const DeviceDispatch = gfx.DeviceDispatch;
const required_device_extensions = [_][*:0]const u8{
vk.extension_info.khr_swapchain.name,
vk.extension_info.khr_dynamic_rendering.name,
};
const BaseDispatch = vk.BaseWrapper(.{
.createInstance = true,
.getInstanceProcAddr = true,
});
const InstanceDispatch = vk.InstanceWrapper(.{
.destroyInstance = true,
.createDevice = true,
.destroySurfaceKHR = true,
.enumeratePhysicalDevices = true,
.getPhysicalDeviceProperties = true,
.enumerateDeviceExtensionProperties = true,
.getPhysicalDeviceSurfaceFormatsKHR = true,
.getPhysicalDeviceSurfacePresentModesKHR = true,
.getPhysicalDeviceSurfaceCapabilitiesKHR = true,
.getPhysicalDeviceQueueFamilyProperties = true,
.getPhysicalDeviceSurfaceSupportKHR = true,
.getPhysicalDeviceMemoryProperties = true,
.getDeviceProcAddr = true,
});
const DeviceDispatch = vk.DeviceWrapper(.{
.destroyDevice = true,
.getDeviceQueue = true,
.createSemaphore = true,
.createFence = true,
.createImageView = true,
.destroyImageView = true,
.destroySemaphore = true,
.destroyFence = true,
.getSwapchainImagesKHR = true,
.createSwapchainKHR = true,
.destroySwapchainKHR = true,
.acquireNextImageKHR = true,
.deviceWaitIdle = true,
.waitForFences = true,
.resetFences = true,
.queueSubmit = true,
.queuePresentKHR = true,
.createCommandPool = true,
.destroyCommandPool = true,
.allocateCommandBuffers = true,
.freeCommandBuffers = true,
.queueWaitIdle = true,
.createShaderModule = true,
.destroyShaderModule = true,
.createPipelineLayout = true,
.destroyPipelineLayout = true,
.createGraphicsPipelines = true,
.destroyPipeline = true,
.beginCommandBuffer = true,
.endCommandBuffer = true,
.allocateMemory = true,
.freeMemory = true,
.createBuffer = true,
.destroyBuffer = true,
.getBufferMemoryRequirements = true,
.mapMemory = true,
.unmapMemory = true,
.bindBufferMemory = true,
.cmdBeginRenderPass = true,
.cmdEndRenderPass = true,
.cmdBindPipeline = true,
.cmdDraw = true,
.cmdDrawIndexed = true,
.cmdSetViewport = true,
.cmdSetScissor = true,
.cmdBindVertexBuffers = true,
.cmdBindIndexBuffer = true,
.cmdCopyBuffer = true,
.cmdBeginRenderingKHR = true,
.cmdEndRenderingKHR = true,
});
pub const GraphicsContext = struct {
vkb: BaseDispatch,
vki: InstanceDispatch,
vkd: DeviceDispatch,
instance: vk.Instance,
surface: vk.SurfaceKHR,
pdev: vk.PhysicalDevice,
props: vk.PhysicalDeviceProperties,
@@ -97,52 +27,28 @@ pub const GraphicsContext = struct {
graphics_queue: Queue,
present_queue: Queue,
pub fn init(allocator: Allocator, app_name: [*:0]const u8, window: *c.GLFWwindow) !GraphicsContext {
pub fn init(allocator: Allocator, instance: vk.Instance, surface: vk.SurfaceKHR, vki: InstanceDispatch) !GraphicsContext {
var self: GraphicsContext = undefined;
self.vkb = try BaseDispatch.load(c.glfwGetInstanceProcAddress);
self.vki = vki;
self.surface = surface;
var glfw_exts_count: u32 = 0;
const glfw_exts = c.glfwGetRequiredInstanceExtensions(&glfw_exts_count);
const app_info = vk.ApplicationInfo{
.p_application_name = app_name,
.application_version = vk.makeApiVersion(0, 0, 0, 0),
.p_engine_name = app_name,
.engine_version = vk.makeApiVersion(0, 0, 0, 0),
.api_version = vk.API_VERSION_1_3,
};
self.instance = try self.vkb.createInstance(&.{
.p_application_info = &app_info,
.enabled_extension_count = glfw_exts_count,
.pp_enabled_extension_names = @as([*]const [*:0]const u8, @ptrCast(glfw_exts)),
}, null);
self.vki = try InstanceDispatch.load(self.instance, self.vkb.dispatch.vkGetInstanceProcAddr);
errdefer self.vki.destroyInstance(self.instance, null);
self.surface = try createSurface(self.instance, window);
errdefer self.vki.destroySurfaceKHR(self.instance, self.surface, null);
const candidate = try pickPhysicalDevice(self.vki, self.instance, allocator, self.surface);
const candidate = try pickPhysicalDevice(vki, instance, allocator, surface);
self.pdev = candidate.pdev;
self.props = candidate.props;
self.dev = try initializeCandidate(self.vki, candidate);
self.vkd = try DeviceDispatch.load(self.dev, self.vki.dispatch.vkGetDeviceProcAddr);
self.dev = try initializeCandidate(vki, candidate);
self.vkd = try DeviceDispatch.load(self.dev, vki.dispatch.vkGetDeviceProcAddr);
errdefer self.vkd.destroyDevice(self.dev, null);
self.graphics_queue = Queue.init(self.vkd, self.dev, candidate.queues.graphics_family);
self.present_queue = Queue.init(self.vkd, self.dev, candidate.queues.present_family);
self.mem_props = self.vki.getPhysicalDeviceMemoryProperties(self.pdev);
self.mem_props = vki.getPhysicalDeviceMemoryProperties(self.pdev);
return self;
}
pub fn deinit(self: GraphicsContext) void {
self.vkd.destroyDevice(self.dev, null);
self.vki.destroySurfaceKHR(self.instance, self.surface, null);
self.vki.destroyInstance(self.instance, null);
}
pub fn deviceName(self: *const GraphicsContext) []const u8 {

View File

@@ -6,6 +6,8 @@ const GraphicsContext = @import("graphics_context.zig").GraphicsContext;
const Swapchain = @import("swapchain.zig").Swapchain;
const Allocator = std.mem.Allocator;
const gfx = @import("gfx.zig");
const app_name = "vulkan-zig triangle example";
const Vertex = extern struct {
@@ -50,7 +52,57 @@ const vertices = [_]Vertex{
const indices = [_]Index{ 4, 5, 6, 6, 5, 7 };
/// note: destroy with vki.destroyInstance(instance, null)
fn create_instance(vkb: gfx.BaseDispatch) !std.meta.Tuple(&.{ vk.Instance, gfx.InstanceDispatch }) {
var glfw_exts_count: u32 = 0;
const glfw_exts = c.glfwGetRequiredInstanceExtensions(&glfw_exts_count);
const instance = try vkb.createInstance(&vk.InstanceCreateInfo{
.p_application_info = &vk.ApplicationInfo{
.p_application_name = app_name,
.application_version = vk.makeApiVersion(0, 0, 0, 0),
.p_engine_name = app_name,
.engine_version = vk.makeApiVersion(0, 0, 0, 0),
.api_version = vk.API_VERSION_1_3,
},
.enabled_extension_count = glfw_exts_count,
.pp_enabled_extension_names = @ptrCast(glfw_exts),
}, null);
const vki = try gfx.InstanceDispatch.load(instance, vkb.dispatch.vkGetInstanceProcAddr);
return .{ instance, vki };
}
/// note: destroy with vki.destroySurfaceKHR(instance, surface, null)
fn create_surface(instance: vk.Instance, window: *c.GLFWwindow) !vk.SurfaceKHR {
var surface: vk.SurfaceKHR = undefined;
if (c.glfwCreateWindowSurface(instance, window, null, &surface) != .success) {
return error.SurfaceInitFailed;
}
return surface;
}
/// note: destroy with c.glfwDestroyWindow(window)
fn create_window(extent: vk.Extent2D, title: [*:0]const u8) !*c.GLFWwindow {
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);
return c.glfwCreateWindow(
@intCast(extent.width),
@intCast(extent.height),
title,
null,
null,
) orelse error.WindowInitFailed;
}
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
if (c.glfwInit() != c.GLFW_TRUE) return error.GlfwInitFailed;
defer c.glfwTerminate();
@@ -61,23 +113,18 @@ pub fn main() !void {
var extent = vk.Extent2D{ .width = 800, .height = 600 };
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 window = c.glfwCreateWindow(
@intCast(extent.width),
@intCast(extent.height),
app_name,
null,
null,
) orelse return error.WindowInitFailed;
const window = try create_window(extent, app_name);
defer c.glfwDestroyWindow(window);
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
const vkb = try gfx.BaseDispatch.load(c.glfwGetInstanceProcAddress);
const gc = try GraphicsContext.init(allocator, app_name, window);
const instance, const vki = try create_instance(vkb);
defer vki.destroyInstance(instance, null);
const surface = try create_surface(instance, window);
defer vki.destroySurfaceKHR(instance, surface, null);
const gc = try GraphicsContext.init(allocator, instance, surface, vki);
defer gc.deinit();
std.log.debug("Using device: {s}", .{gc.deviceName()});