WIP: Move base, instance, device, queue setup into core.zig
This commit is contained in:
296
src/core.zig
Normal file
296
src/core.zig
Normal file
@@ -0,0 +1,296 @@
|
||||
const std = @import("std");
|
||||
const lib = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
const vk = @import("vk");
|
||||
const glfw = @cImport({
|
||||
@cDefine("GLFW_INCLUDE_NONE", {});
|
||||
@cInclude("GLFW/glfw3.h");
|
||||
});
|
||||
|
||||
const Self = @This();
|
||||
|
||||
const apis: []const vk.ApiInfo = &(.{
|
||||
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_dynamic_rendering,
|
||||
vk.extensions.khr_timeline_semaphore,
|
||||
} ++ switch (builtin.mode) {
|
||||
.Debug, .ReleaseSafe => .{
|
||||
vk.extensions.ext_debug_utils,
|
||||
},
|
||||
else => .{},
|
||||
});
|
||||
|
||||
const Base = vk.BaseWrapper(apis);
|
||||
const Instance = vk.InstanceProxy(apis);
|
||||
const Device = vk.DeviceProxy(apis);
|
||||
const Queue = vk.QueueProxy(apis);
|
||||
|
||||
alloc: std.mem.Allocator,
|
||||
win: *glfw.GLFWwindow,
|
||||
bw: *const Base,
|
||||
i: Instance,
|
||||
d: Device,
|
||||
q: Queue,
|
||||
dm: switch (builtin.mode) {
|
||||
.Debug, .ReleaseSafe => vk.DebugUtilsMessengerEXT,
|
||||
else => void,
|
||||
},
|
||||
|
||||
pub fn init(
|
||||
alloc: std.mem.Allocator,
|
||||
options: struct {
|
||||
width: u32 = 1280,
|
||||
height: u32 = 720,
|
||||
title: []const u8 = "Hello World",
|
||||
},
|
||||
) !Self {
|
||||
var arena = std.heap.ArenaAllocator.init(alloc);
|
||||
defer arena.deinit();
|
||||
const ialloc = arena.allocator();
|
||||
|
||||
const titlez = try ialloc.dupeZ(u8, options.title);
|
||||
|
||||
if (glfw.glfwInit() != glfw.GLFW_TRUE) {
|
||||
return error.GLFWInitFailed;
|
||||
}
|
||||
errdefer glfw.glfwTerminate();
|
||||
|
||||
glfw.glfwWindowHint(glfw.GLFW_CLIENT_API, glfw.GLFW_NO_API);
|
||||
glfw.glfwWindowHintString(glfw.GLFW_X11_CLASS_NAME, "floating_window");
|
||||
glfw.glfwWindowHintString(glfw.GLFW_X11_INSTANCE_NAME, "floating_window");
|
||||
const win = glfw.glfwCreateWindow(
|
||||
@intCast(options.width),
|
||||
@intCast(options.height),
|
||||
titlez,
|
||||
null,
|
||||
null,
|
||||
) orelse
|
||||
return error.GLFWWindowFailed;
|
||||
|
||||
var bw = try alloc.create(vk.BaseWrapper(apis));
|
||||
errdefer alloc.destroy(bw);
|
||||
bw.* = try vk.BaseWrapper(apis).load(glfwGetInstanceProcAddress);
|
||||
|
||||
var iexts = std.ArrayList([*:0]const u8).init(ialloc);
|
||||
var ilyrs = std.ArrayList([*:0]const u8).init(ialloc);
|
||||
|
||||
switch (builtin.mode) {
|
||||
.Debug, .ReleaseSafe => {
|
||||
try iexts.appendSlice(&.{
|
||||
vk.extensions.ext_debug_utils.name,
|
||||
});
|
||||
try ilyrs.appendSlice(&.{
|
||||
"VK_LAYER_KHRONOS_validation",
|
||||
});
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
{
|
||||
var count: u32 = undefined;
|
||||
const ptr = glfwGetRequiredInstanceExtensions(&count);
|
||||
try iexts.appendSlice(ptr[0..count]);
|
||||
}
|
||||
|
||||
var dmci = switch (builtin.mode) {
|
||||
.Debug, .ReleaseSafe => 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 = true,
|
||||
.performance_bit_ext = true,
|
||||
.validation_bit_ext = true,
|
||||
},
|
||||
.pfn_user_callback = &debug_callback,
|
||||
.p_user_data = null,
|
||||
},
|
||||
else => {},
|
||||
};
|
||||
|
||||
var ici: vk.InstanceCreateInfo = .{
|
||||
.p_application_info = &vk.ApplicationInfo{
|
||||
.api_version = vk.API_VERSION_1_3,
|
||||
.engine_version = 0,
|
||||
.application_version = 0,
|
||||
.p_application_name = titlez,
|
||||
.p_engine_name = titlez,
|
||||
},
|
||||
.enabled_extension_count = @intCast(iexts.items.len),
|
||||
.pp_enabled_extension_names = iexts.items.ptr,
|
||||
.enabled_layer_count = @intCast(ilyrs.items.len),
|
||||
.pp_enabled_layer_names = ilyrs.items.ptr,
|
||||
};
|
||||
|
||||
switch (builtin.mode) {
|
||||
.Debug, .ReleaseSafe => {
|
||||
ici.p_next = &dmci;
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
const instance = try bw.createInstance(
|
||||
&ici,
|
||||
null,
|
||||
);
|
||||
var iw = try alloc.create(vk.InstanceWrapper(apis));
|
||||
errdefer alloc.destroy(iw);
|
||||
iw.* = try vk.InstanceWrapper(apis).load(instance, bw.dispatch.vkGetInstanceProcAddr);
|
||||
errdefer iw.destroyInstance(instance, null);
|
||||
|
||||
const dm = switch (builtin.mode) {
|
||||
.Debug, .ReleaseSafe => try iw.createDebugUtilsMessengerEXT(instance, &dmci, null),
|
||||
else => {},
|
||||
};
|
||||
errdefer switch (builtin.mode) {
|
||||
.Debug, .ReleaseSafe => iw.destroyDebugUtilsMessengerEXT(instance, dm, null),
|
||||
else => {},
|
||||
};
|
||||
|
||||
// Device selection. Just use the first one.
|
||||
const pdevs: []vk.PhysicalDevice = try iw.enumeratePhysicalDevicesAlloc(instance, ialloc);
|
||||
std.debug.assert(pdevs.len >= 1);
|
||||
const pdev = pdevs[0];
|
||||
|
||||
// Queue selection. Just use the first one.
|
||||
const qci: []const vk.DeviceQueueCreateInfo = &.{
|
||||
vk.DeviceQueueCreateInfo{
|
||||
.queue_family_index = 0,
|
||||
.queue_count = 1,
|
||||
.p_queue_priorities = &.{1},
|
||||
},
|
||||
};
|
||||
|
||||
var dexts = std.ArrayList([*:0]const u8).init(ialloc);
|
||||
var dlyrs = std.ArrayList([*:0]const u8).init(ialloc);
|
||||
|
||||
_ = &dlyrs;
|
||||
|
||||
try dexts.appendSlice(&.{
|
||||
vk.extensions.khr_swapchain.name,
|
||||
vk.extensions.khr_dynamic_rendering.name,
|
||||
vk.extensions.khr_timeline_semaphore.name,
|
||||
});
|
||||
|
||||
const device = try iw.createDevice(pdev, &.{
|
||||
.enabled_extension_count = @intCast(dexts.items.len),
|
||||
.pp_enabled_extension_names = dexts.items.ptr,
|
||||
.enabled_layer_count = @intCast(dlyrs.items.len),
|
||||
.pp_enabled_layer_names = dlyrs.items.ptr,
|
||||
.queue_create_info_count = @intCast(qci.len),
|
||||
.p_queue_create_infos = qci.ptr,
|
||||
.p_next = &vk.PhysicalDeviceDynamicRenderingFeatures{
|
||||
.dynamic_rendering = vk.TRUE,
|
||||
},
|
||||
}, null);
|
||||
var dw = try alloc.create(vk.DeviceWrapper(apis));
|
||||
errdefer alloc.destroy(dw);
|
||||
dw.* = try vk.DeviceWrapper(apis).load(device, iw.dispatch.vkGetDeviceProcAddr);
|
||||
errdefer dw.destroyDevice(device, null);
|
||||
|
||||
const queue = dw.getDeviceQueue(device, 0, 0);
|
||||
|
||||
return Self{
|
||||
.alloc = alloc,
|
||||
.win = win,
|
||||
.bw = bw,
|
||||
.i = .{ .handle = instance, .wrapper = iw },
|
||||
.d = .{ .handle = device, .wrapper = dw },
|
||||
.q = .{ .handle = queue, .wrapper = dw },
|
||||
.dm = dm,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: Self) void {
|
||||
self.d.destroyDevice(null);
|
||||
self.alloc.destroy(self.d.wrapper);
|
||||
|
||||
switch (builtin.mode) {
|
||||
.Debug, .ReleaseSafe => self.i.destroyDebugUtilsMessengerEXT(self.dm, null),
|
||||
else => {},
|
||||
}
|
||||
self.i.destroyInstance(null);
|
||||
|
||||
self.alloc.destroy(self.i.wrapper);
|
||||
self.alloc.destroy(self.bw);
|
||||
glfw.glfwTerminate();
|
||||
}
|
||||
|
||||
extern fn glfwGetInstanceProcAddress(
|
||||
instance: vk.Instance,
|
||||
procname: [*:0]const u8,
|
||||
) vk.PfnVoidFunction;
|
||||
|
||||
extern fn glfwGetPhysicalDevicePresentationSupport(
|
||||
instance: vk.Instance,
|
||||
pdev: vk.PhysicalDevice,
|
||||
queuefamily: u32,
|
||||
) c_int;
|
||||
|
||||
extern fn glfwCreateWindowSurface(
|
||||
instance: vk.Instance,
|
||||
window: *glfw.GLFWwindow,
|
||||
allocation_callbacks: ?*const vk.AllocationCallbacks,
|
||||
surface: *vk.SurfaceKHR,
|
||||
) vk.Result;
|
||||
|
||||
extern fn glfwGetRequiredInstanceExtensions(
|
||||
count: *u32,
|
||||
) [*][*:0]const u8;
|
||||
|
||||
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;
|
||||
}
|
452
src/main.zig
452
src/main.zig
@@ -2,333 +2,147 @@ const std = @import("std");
|
||||
const lib = @import("zig-shape-lib");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
const glfw = @cImport({
|
||||
@cDefine("GLFW_INCLUDE_NONE", {});
|
||||
@cInclude("GLFW/glfw3.h");
|
||||
});
|
||||
|
||||
const vk = @import("vk");
|
||||
|
||||
pub const features: []const vk.ApiInfo = &.{
|
||||
vk.features.version_1_0,
|
||||
vk.features.version_1_1,
|
||||
vk.features.version_1_2,
|
||||
vk.features.version_1_3,
|
||||
};
|
||||
|
||||
pub const instance_exts: []const vk.ApiInfo = &.{
|
||||
vk.extensions.khr_surface,
|
||||
};
|
||||
|
||||
pub const device_exts: []const vk.ApiInfo = &.{
|
||||
vk.extensions.khr_swapchain,
|
||||
vk.extensions.khr_dynamic_rendering,
|
||||
vk.extensions.khr_timeline_semaphore,
|
||||
};
|
||||
|
||||
pub const apis: []const vk.ApiInfo =
|
||||
features ++ instance_exts ++ device_exts ++
|
||||
switch (builtin.mode) {
|
||||
.Debug, .ReleaseSafe => Debug.instance_exts,
|
||||
else => &.{},
|
||||
};
|
||||
|
||||
pub const layers: []const [*:0]const u8 = switch (builtin.mode) {
|
||||
.Debug, .ReleaseSafe => Debug.layers,
|
||||
else => &.{},
|
||||
};
|
||||
|
||||
pub const BaseWrapper = vk.BaseWrapper(apis);
|
||||
pub const InstanceWrapper = vk.InstanceWrapper(apis);
|
||||
pub const DeviceWrapper = vk.DeviceWrapper(apis);
|
||||
|
||||
pub const Debug = struct {
|
||||
pub const instance_exts: []const vk.ApiInfo = &.{
|
||||
vk.extensions.ext_debug_utils,
|
||||
};
|
||||
|
||||
pub const layers: []const [*:0]const u8 = &.{
|
||||
"VK_LAYER_KHRONOS_validation",
|
||||
};
|
||||
|
||||
pub const create_info: 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 = true,
|
||||
.performance_bit_ext = true,
|
||||
.validation_bit_ext = true,
|
||||
},
|
||||
.pfn_user_callback = &debug_callback,
|
||||
.p_user_data = null,
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
const Core = @import("core.zig");
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
defer _ = gpa.deinit();
|
||||
const alloc = gpa.allocator();
|
||||
|
||||
if (glfw.glfwInit() != glfw.GLFW_TRUE) std.debug.panic("GLFW Init Failed", .{});
|
||||
defer glfw.glfwTerminate();
|
||||
const core = try Core.init(alloc, .{});
|
||||
defer core.deinit();
|
||||
|
||||
const B = try BaseWrapper.load(glfwGetInstanceProcAddress);
|
||||
std.log.debug("Created instance: {any}", .{core.i.handle});
|
||||
std.log.debug("Created device: {any}", .{core.d.handle});
|
||||
std.log.debug("Created queue: {any}", .{core.q.handle});
|
||||
|
||||
var extnames = std.ArrayList([*:0]const u8).init(alloc);
|
||||
defer extnames.deinit();
|
||||
// var surface: vk.SurfaceKHR = undefined;
|
||||
// if (glfwCreateWindowSurface(instance, window, null, &surface) != vk.Result.success) {
|
||||
// return error.SurfaceCreateFailed;
|
||||
// }
|
||||
|
||||
for (instance_exts) |ext| extnames.append(ext.name) catch std.debug.panic("OOM", .{});
|
||||
var glfw_exts_count: u32 = undefined;
|
||||
const glfw_exts: [*]const [*:0]const u8 =
|
||||
glfwGetRequiredInstanceExtensions(&glfw_exts_count);
|
||||
extnames.appendSlice(glfw_exts[0..glfw_exts_count]) catch std.debug.panic("OOM", .{});
|
||||
// var caps = try I.getPhysicalDeviceSurfaceCapabilitiesKHR(pdev, surface);
|
||||
// const format = search: {
|
||||
// const formats = try I.getPhysicalDeviceSurfaceFormatsAllocKHR(pdev, surface, alloc);
|
||||
// defer alloc.free(formats);
|
||||
// for (formats) |f| {
|
||||
// if (f.color_space == .srgb_nonlinear_khr) break :search f;
|
||||
// } else break :search formats[0];
|
||||
// };
|
||||
// const mode: vk.PresentModeKHR = .fifo_khr;
|
||||
|
||||
var ci: vk.InstanceCreateInfo = .{
|
||||
.p_application_info = &vk.ApplicationInfo{
|
||||
.p_application_name = "Hello World",
|
||||
.application_version = vk.makeApiVersion(0, 0, 0, 0),
|
||||
.p_engine_name = "Hello World",
|
||||
.engine_version = vk.makeApiVersion(0, 0, 0, 0),
|
||||
.api_version = vk.features.version_1_3.version,
|
||||
},
|
||||
.enabled_extension_count = @intCast(extnames.items.len),
|
||||
.pp_enabled_extension_names = extnames.items.ptr,
|
||||
.enabled_layer_count = @intCast(layers.len),
|
||||
.pp_enabled_layer_names =layers.ptr,
|
||||
.p_next = switch (builtin.mode) {
|
||||
.Debug, .ReleaseSafe => &Debug.create_info,
|
||||
else => null,
|
||||
},
|
||||
};
|
||||
const instance = try B.createInstance(&ci, null);
|
||||
const I = try InstanceWrapper.load(instance, B.dispatch.vkGetInstanceProcAddr);
|
||||
defer I.destroyInstance(instance, null);
|
||||
// var scinfo: vk.SwapchainCreateInfoKHR = .{
|
||||
// .surface = surface,
|
||||
// .min_image_count = std.math.clamp(
|
||||
// @min(3, caps.min_image_count + 1),
|
||||
// caps.min_image_count,
|
||||
// if (caps.max_image_count > 0) caps.max_image_count else 127,
|
||||
// ),
|
||||
// .image_format = format.format,
|
||||
// .image_color_space = format.color_space,
|
||||
// .image_extent = undefined, // set in rebuild
|
||||
// .image_array_layers = 1,
|
||||
// .image_usage = .{ .color_attachment_bit = true },
|
||||
// .image_sharing_mode = .exclusive,
|
||||
// .pre_transform = .{ .identity_bit_khr = true },
|
||||
// .composite_alpha = .{ .opaque_bit_khr = true },
|
||||
// .present_mode = mode,
|
||||
// .clipped = vk.TRUE,
|
||||
// .old_swapchain = .null_handle,
|
||||
// };
|
||||
|
||||
const messenger = try I.createDebugUtilsMessengerEXT(instance, &ci, null);
|
||||
defer I.destroyDebugUtilsMessengerEXT(instance, messenger, null);
|
||||
|
||||
glfw.glfwWindowHint(glfw.GLFW_CLIENT_API, glfw.GLFW_NO_API);
|
||||
glfw.glfwWindowHintString(glfw.GLFW_X11_CLASS_NAME, "floating_window");
|
||||
glfw.glfwWindowHintString(glfw.GLFW_X11_INSTANCE_NAME, "floating_window");
|
||||
|
||||
const window = glfw.glfwCreateWindow(1280, 720, "Hello World", null, null) orelse
|
||||
return error.glfwWindowCreateFailed;
|
||||
defer glfw.glfwDestroyWindow(window);
|
||||
|
||||
const pdevs = try I.enumeratePhysicalDevicesAlloc(instance, alloc);
|
||||
defer alloc.free(pdevs);
|
||||
|
||||
// just pick the first physical device
|
||||
const pdev = pdevs[0];
|
||||
|
||||
const family: u32 = 0;
|
||||
|
||||
// just pick the first queue family
|
||||
const qcis: []const vk.DeviceQueueCreateInfo = &.{
|
||||
vk.DeviceQueueCreateInfo{
|
||||
.queue_family_index = family,
|
||||
.queue_count = 1,
|
||||
.p_queue_priorities = &.{1},
|
||||
},
|
||||
};
|
||||
|
||||
extnames.clearRetainingCapacity();
|
||||
for (device_exts) |ext| extnames.append(ext.name) catch std.debug.panic("OOM", .{});
|
||||
|
||||
const device = try I.createDevice(pdev, &.{
|
||||
.queue_create_info_count = @intCast(qcis.len),
|
||||
.p_queue_create_infos = qcis.ptr,
|
||||
.enabled_extension_count = @intCast(extnames.items.len),
|
||||
.pp_enabled_extension_names = extnames.items.ptr,
|
||||
.p_next = &vk.PhysicalDeviceDynamicRenderingFeatures{
|
||||
.dynamic_rendering = vk.TRUE,
|
||||
},
|
||||
}, null);
|
||||
const D = try DeviceWrapper.load(device, I.dispatch.vkGetDeviceProcAddr);
|
||||
defer D.destroyDevice(device, null);
|
||||
|
||||
const queue = D.getDeviceQueue(device, family, 0);
|
||||
_ = queue;
|
||||
|
||||
var surface: vk.SurfaceKHR = undefined;
|
||||
if (glfwCreateWindowSurface(instance, window, null, &surface) != vk.Result.success) {
|
||||
return error.SurfaceCreateFailed;
|
||||
}
|
||||
|
||||
var caps = try I.getPhysicalDeviceSurfaceCapabilitiesKHR(pdev, surface);
|
||||
const format = search: {
|
||||
const formats = try I.getPhysicalDeviceSurfaceFormatsAllocKHR(pdev, surface, alloc);
|
||||
defer alloc.free(formats);
|
||||
for (formats) |f| {
|
||||
if (f.color_space == .srgb_nonlinear_khr) break :search f;
|
||||
} else break :search formats[0];
|
||||
};
|
||||
const mode: vk.PresentModeKHR = .fifo_khr;
|
||||
|
||||
var scinfo: vk.SwapchainCreateInfoKHR = .{
|
||||
.surface = surface,
|
||||
.min_image_count = std.math.clamp(
|
||||
@min(3, caps.min_image_count + 1),
|
||||
caps.min_image_count,
|
||||
if (caps.max_image_count > 0) caps.max_image_count else 127,
|
||||
),
|
||||
.image_format = format.format,
|
||||
.image_color_space = format.color_space,
|
||||
.image_extent = undefined, // set in rebuild
|
||||
.image_array_layers = 1,
|
||||
.image_usage = .{ .color_attachment_bit = true },
|
||||
.image_sharing_mode = .exclusive,
|
||||
.pre_transform = .{ .identity_bit_khr = true },
|
||||
.composite_alpha = .{ .opaque_bit_khr = true },
|
||||
.present_mode = mode,
|
||||
.clipped = vk.TRUE,
|
||||
.old_swapchain = .null_handle,
|
||||
};
|
||||
|
||||
var sc: vk.SwapchainKHR = .null_handle;
|
||||
defer D.destroySwapchainKHR(device, sc, null);
|
||||
// var sc: vk.SwapchainKHR = .null_handle;
|
||||
// defer D.destroySwapchainKHR(device, sc, null);
|
||||
|
||||
// const FRAMES_IN_FLIGHT = 3;
|
||||
//
|
||||
// var pools = [FRAMES_IN_FLIGHT]vk.CommandPool;
|
||||
// var fence = [FRAMES_IN_FLIGHT]vk.Fence;
|
||||
|
||||
const pool = D.createCommandPool(device, &.{
|
||||
.queue_family_index = family,
|
||||
}, null);
|
||||
defer D.destroyCommandPool(device, pool, null);
|
||||
// const pool = D.createCommandPool(device, &.{
|
||||
// .queue_family_index = family,
|
||||
// }, null);
|
||||
// defer D.destroyCommandPool(device, pool, null);
|
||||
|
||||
var cmd: vk.CommandBuffer = undefined;
|
||||
try D.allocateCommandBuffers(device, &.{vk.CommandBufferAllocateInfo{
|
||||
.command_buffer_count = 1,
|
||||
.command_pool = pool,
|
||||
.level = .primary,
|
||||
}}, @ptrCast(&cmd));
|
||||
defer D.freeCommandBuffers(device, pool, 1, @ptrCast(&cmd));
|
||||
// var cmd: vk.CommandBuffer = undefined;
|
||||
// try D.allocateCommandBuffers(device, &.{vk.CommandBufferAllocateInfo{
|
||||
// .command_buffer_count = 1,
|
||||
// .command_pool = pool,
|
||||
// .level = .primary,
|
||||
// }}, @ptrCast(&cmd));
|
||||
// defer D.freeCommandBuffers(device, pool, 1, @ptrCast(&cmd));
|
||||
|
||||
while (glfw.glfwWindowShouldClose(window) == glfw.GLFW_FALSE) {
|
||||
if (glfw.glfwGetWindowAttrib(window, glfw.GLFW_FOCUSED) == glfw.GLFW_TRUE)
|
||||
glfw.glfwPollEvents()
|
||||
else
|
||||
glfw.glfwWaitEventsTimeout(1.0 / 60.0);
|
||||
|
||||
if (sc == .null_handle) {
|
||||
caps = try I.getPhysicalDeviceSurfaceCapabilitiesKHR(pdev, surface);
|
||||
scinfo.image_extent = caps.current_extent;
|
||||
sc = try D.createSwapchainKHR(device, &scinfo, null);
|
||||
D.destroySwapchainKHR(device, scinfo.old_swapchain, null);
|
||||
scinfo.old_swapchain = .null_handle;
|
||||
}
|
||||
|
||||
const render_area: vk.Rect2D = .{
|
||||
.offset = .{ .x = 0, .y = 0 },
|
||||
.extent = scinfo.image_extent,
|
||||
};
|
||||
|
||||
try D.resetCommandPool(device, pool, .{});
|
||||
try D.beginCommandBuffer(cmd, .{ .flags = .{ .one_time_submit_bit = true } });
|
||||
{
|
||||
D.cmdPipelineBarrier(
|
||||
cmd,
|
||||
.{ .top_of_pipe_bit = true },
|
||||
.{ .color_attachment_output_bit = true },
|
||||
.{},
|
||||
0,
|
||||
null,
|
||||
0,
|
||||
null,
|
||||
1,
|
||||
&.{
|
||||
vk.ImageMemoryBarrier{
|
||||
.src_access_mask = .{},
|
||||
.dst_access_mask = .{ .color_attachment_write_bit = true },
|
||||
.old_layout = .undefined,
|
||||
.new_layout = .color_attachment_optimal,
|
||||
.src_queue_family_index = 0,
|
||||
.dst_queue_family_index = 0,
|
||||
.image = image,
|
||||
.subresource_range = .{
|
||||
.aspect_mask = .{ .color_bit = true },
|
||||
.base_mip_level = 0,
|
||||
.level_count = 1,
|
||||
.base_array_layer = 0,
|
||||
.layer_count = 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
D.cmdPipelineBarrier(
|
||||
cmd,
|
||||
.{ .color_attachment_output_bit = true },
|
||||
.{ .bottom_of_pipe_bit = true },
|
||||
.{},
|
||||
0,
|
||||
null,
|
||||
0,
|
||||
null,
|
||||
1,
|
||||
&.{
|
||||
vk.ImageMemoryBarrier{
|
||||
// todo !
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
try D.endCommandBuffer(cmd);
|
||||
}
|
||||
// while (glfw.glfwWindowShouldClose(window) == glfw.GLFW_FALSE) {
|
||||
// if (glfw.glfwGetWindowAttrib(window, glfw.GLFW_FOCUSED) == glfw.GLFW_TRUE)
|
||||
// glfw.glfwPollEvents()
|
||||
// else
|
||||
// glfw.glfwWaitEventsTimeout(1.0 / 60.0);
|
||||
//
|
||||
// if (sc == .null_handle) {
|
||||
// caps = try I.getPhysicalDeviceSurfaceCapabilitiesKHR(pdev, surface);
|
||||
// scinfo.image_extent = caps.current_extent;
|
||||
// sc = try D.createSwapchainKHR(device, &scinfo, null);
|
||||
// D.destroySwapchainKHR(device, scinfo.old_swapchain, null);
|
||||
// scinfo.old_swapchain = .null_handle;
|
||||
// }
|
||||
//
|
||||
// const render_area: vk.Rect2D = .{
|
||||
// .offset = .{ .x = 0, .y = 0 },
|
||||
// .extent = scinfo.image_extent,
|
||||
// };
|
||||
//
|
||||
// try D.resetCommandPool(device, pool, .{});
|
||||
// try D.beginCommandBuffer(cmd, .{ .flags = .{ .one_time_submit_bit = true } });
|
||||
// {
|
||||
// D.cmdPipelineBarrier(
|
||||
// cmd,
|
||||
// .{ .top_of_pipe_bit = true },
|
||||
// .{ .color_attachment_output_bit = true },
|
||||
// .{},
|
||||
// 0,
|
||||
// null,
|
||||
// 0,
|
||||
// null,
|
||||
// 1,
|
||||
// &.{
|
||||
// vk.ImageMemoryBarrier{
|
||||
// .src_access_mask = .{},
|
||||
// .dst_access_mask = .{ .color_attachment_write_bit = true },
|
||||
// .old_layout = .undefined,
|
||||
// .new_layout = .color_attachment_optimal,
|
||||
// .src_queue_family_index = 0,
|
||||
// .dst_queue_family_index = 0,
|
||||
// .image = image,
|
||||
// .subresource_range = .{
|
||||
// .aspect_mask = .{ .color_bit = true },
|
||||
// .base_mip_level = 0,
|
||||
// .level_count = 1,
|
||||
// .base_array_layer = 0,
|
||||
// .layer_count = 1,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// );
|
||||
//
|
||||
// D.cmdPipelineBarrier(
|
||||
// cmd,
|
||||
// .{ .color_attachment_output_bit = true },
|
||||
// .{ .bottom_of_pipe_bit = true },
|
||||
// .{},
|
||||
// 0,
|
||||
// null,
|
||||
// 0,
|
||||
// null,
|
||||
// 1,
|
||||
// &.{
|
||||
// vk.ImageMemoryBarrier{
|
||||
// // todo !
|
||||
// },
|
||||
// },
|
||||
// );
|
||||
// }
|
||||
// try D.endCommandBuffer(cmd);
|
||||
// }
|
||||
}
|
||||
|
||||
test "simple test" {
|
||||
@@ -352,25 +166,3 @@ test "fuzz example" {
|
||||
};
|
||||
try std.testing.fuzz(Context{}, Context.testOne, .{});
|
||||
}
|
||||
|
||||
pub extern fn glfwGetInstanceProcAddress(
|
||||
instance: vk.Instance,
|
||||
procname: [*:0]const u8,
|
||||
) vk.PfnVoidFunction;
|
||||
|
||||
pub extern fn glfwGetPhysicalDevicePresentationSupport(
|
||||
instance: vk.Instance,
|
||||
pdev: vk.PhysicalDevice,
|
||||
queuefamily: u32,
|
||||
) c_int;
|
||||
|
||||
pub extern fn glfwCreateWindowSurface(
|
||||
instance: vk.Instance,
|
||||
window: *glfw.GLFWwindow,
|
||||
allocation_callbacks: ?*const vk.AllocationCallbacks,
|
||||
surface: *vk.SurfaceKHR,
|
||||
) vk.Result;
|
||||
|
||||
pub extern fn glfwGetRequiredInstanceExtensions(
|
||||
count: *u32,
|
||||
) [*][*:0]const u8;
|
||||
|
Reference in New Issue
Block a user