forked from mirror/vulkan-zig
update example with new proxying wrappers
This commit is contained in:
@@ -27,23 +27,30 @@ const BaseDispatch = vk.BaseWrapper(apis);
|
|||||||
const InstanceDispatch = vk.InstanceWrapper(apis);
|
const InstanceDispatch = vk.InstanceWrapper(apis);
|
||||||
const DeviceDispatch = vk.DeviceWrapper(apis);
|
const DeviceDispatch = vk.DeviceWrapper(apis);
|
||||||
|
|
||||||
pub const GraphicsContext = struct {
|
// Also create some proxying wrappers, which also have the respective handles
|
||||||
vkb: BaseDispatch,
|
const Instance = vk.InstanceProxy(apis);
|
||||||
vki: InstanceDispatch,
|
const Device = vk.DeviceProxy(apis);
|
||||||
vkd: DeviceDispatch,
|
|
||||||
|
|
||||||
instance: vk.Instance,
|
pub const GraphicsContext = struct {
|
||||||
|
pub const CommandBuffer = vk.CommandBufferProxy(apis);
|
||||||
|
|
||||||
|
allocator: Allocator,
|
||||||
|
|
||||||
|
vkb: BaseDispatch,
|
||||||
|
|
||||||
|
instance: Instance,
|
||||||
surface: vk.SurfaceKHR,
|
surface: vk.SurfaceKHR,
|
||||||
pdev: vk.PhysicalDevice,
|
pdev: vk.PhysicalDevice,
|
||||||
props: vk.PhysicalDeviceProperties,
|
props: vk.PhysicalDeviceProperties,
|
||||||
mem_props: vk.PhysicalDeviceMemoryProperties,
|
mem_props: vk.PhysicalDeviceMemoryProperties,
|
||||||
|
|
||||||
dev: vk.Device,
|
dev: Device,
|
||||||
graphics_queue: Queue,
|
graphics_queue: Queue,
|
||||||
present_queue: Queue,
|
present_queue: Queue,
|
||||||
|
|
||||||
pub fn init(allocator: Allocator, app_name: [*:0]const u8, window: *c.GLFWwindow) !GraphicsContext {
|
pub fn init(allocator: Allocator, app_name: [*:0]const u8, window: *c.GLFWwindow) !GraphicsContext {
|
||||||
var self: GraphicsContext = undefined;
|
var self: GraphicsContext = undefined;
|
||||||
|
self.allocator = allocator;
|
||||||
self.vkb = try BaseDispatch.load(c.glfwGetInstanceProcAddress);
|
self.vkb = try BaseDispatch.load(c.glfwGetInstanceProcAddress);
|
||||||
|
|
||||||
var glfw_exts_count: u32 = 0;
|
var glfw_exts_count: u32 = 0;
|
||||||
@@ -57,37 +64,49 @@ pub const GraphicsContext = struct {
|
|||||||
.api_version = vk.API_VERSION_1_2,
|
.api_version = vk.API_VERSION_1_2,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.instance = try self.vkb.createInstance(&.{
|
const instance = try self.vkb.createInstance(&.{
|
||||||
.p_application_info = &app_info,
|
.p_application_info = &app_info,
|
||||||
.enabled_extension_count = glfw_exts_count,
|
.enabled_extension_count = glfw_exts_count,
|
||||||
.pp_enabled_extension_names = @as([*]const [*:0]const u8, @ptrCast(glfw_exts)),
|
.pp_enabled_extension_names = @ptrCast(glfw_exts),
|
||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
self.vki = try InstanceDispatch.load(self.instance, self.vkb.dispatch.vkGetInstanceProcAddr);
|
const vki = try allocator.create(InstanceDispatch);
|
||||||
errdefer self.vki.destroyInstance(self.instance, null);
|
errdefer allocator.destroy(vki);
|
||||||
|
vki.* = try InstanceDispatch.load(instance, self.vkb.dispatch.vkGetInstanceProcAddr);
|
||||||
|
self.instance = Instance.init(instance, vki);
|
||||||
|
errdefer self.instance.destroyInstance(null);
|
||||||
|
|
||||||
self.surface = try createSurface(self.instance, window);
|
self.surface = try createSurface(self.instance, window);
|
||||||
errdefer self.vki.destroySurfaceKHR(self.instance, self.surface, null);
|
errdefer self.instance.destroySurfaceKHR(self.surface, null);
|
||||||
|
|
||||||
const candidate = try pickPhysicalDevice(self.vki, self.instance, allocator, self.surface);
|
const candidate = try pickPhysicalDevice(self.instance, allocator, self.surface);
|
||||||
self.pdev = candidate.pdev;
|
self.pdev = candidate.pdev;
|
||||||
self.props = candidate.props;
|
self.props = candidate.props;
|
||||||
self.dev = try initializeCandidate(self.vki, candidate);
|
|
||||||
self.vkd = try DeviceDispatch.load(self.dev, self.vki.dispatch.vkGetDeviceProcAddr);
|
|
||||||
errdefer self.vkd.destroyDevice(self.dev, null);
|
|
||||||
|
|
||||||
self.graphics_queue = Queue.init(self.vkd, self.dev, candidate.queues.graphics_family);
|
const dev = try initializeCandidate(self.instance, candidate);
|
||||||
self.present_queue = Queue.init(self.vkd, self.dev, candidate.queues.present_family);
|
|
||||||
|
|
||||||
self.mem_props = self.vki.getPhysicalDeviceMemoryProperties(self.pdev);
|
const vkd = try allocator.create(DeviceDispatch);
|
||||||
|
errdefer allocator.destroy(vkd);
|
||||||
|
vkd.* = try DeviceDispatch.load(dev, self.instance.wrapper.dispatch.vkGetDeviceProcAddr);
|
||||||
|
self.dev = Device.init(dev, vkd);
|
||||||
|
errdefer self.dev.destroyDevice(null);
|
||||||
|
|
||||||
|
self.graphics_queue = Queue.init(self.dev, candidate.queues.graphics_family);
|
||||||
|
self.present_queue = Queue.init(self.dev, candidate.queues.present_family);
|
||||||
|
|
||||||
|
self.mem_props = self.instance.getPhysicalDeviceMemoryProperties(self.pdev);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: GraphicsContext) void {
|
pub fn deinit(self: GraphicsContext) void {
|
||||||
self.vkd.destroyDevice(self.dev, null);
|
self.dev.destroyDevice(null);
|
||||||
self.vki.destroySurfaceKHR(self.instance, self.surface, null);
|
self.instance.destroySurfaceKHR(self.surface, null);
|
||||||
self.vki.destroyInstance(self.instance, null);
|
self.instance.destroyInstance(null);
|
||||||
|
|
||||||
|
// Don't forget to free the tables to prevent a memory leak.
|
||||||
|
self.allocator.destroy(self.dev.wrapper);
|
||||||
|
self.allocator.destroy(self.instance.wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deviceName(self: *const GraphicsContext) []const u8 {
|
pub fn deviceName(self: *const GraphicsContext) []const u8 {
|
||||||
@@ -105,7 +124,7 @@ pub const GraphicsContext = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn allocate(self: GraphicsContext, requirements: vk.MemoryRequirements, flags: vk.MemoryPropertyFlags) !vk.DeviceMemory {
|
pub fn allocate(self: GraphicsContext, requirements: vk.MemoryRequirements, flags: vk.MemoryPropertyFlags) !vk.DeviceMemory {
|
||||||
return try self.vkd.allocateMemory(self.dev, &.{
|
return try self.dev.allocateMemory(&.{
|
||||||
.allocation_size = requirements.size,
|
.allocation_size = requirements.size,
|
||||||
.memory_type_index = try self.findMemoryTypeIndex(requirements.memory_type_bits, flags),
|
.memory_type_index = try self.findMemoryTypeIndex(requirements.memory_type_bits, flags),
|
||||||
}, null);
|
}, null);
|
||||||
@@ -116,24 +135,24 @@ pub const Queue = struct {
|
|||||||
handle: vk.Queue,
|
handle: vk.Queue,
|
||||||
family: u32,
|
family: u32,
|
||||||
|
|
||||||
fn init(vkd: DeviceDispatch, dev: vk.Device, family: u32) Queue {
|
fn init(device: Device, family: u32) Queue {
|
||||||
return .{
|
return .{
|
||||||
.handle = vkd.getDeviceQueue(dev, family, 0),
|
.handle = device.getDeviceQueue(family, 0),
|
||||||
.family = family,
|
.family = family,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fn createSurface(instance: vk.Instance, window: *c.GLFWwindow) !vk.SurfaceKHR {
|
fn createSurface(instance: Instance, window: *c.GLFWwindow) !vk.SurfaceKHR {
|
||||||
var surface: vk.SurfaceKHR = undefined;
|
var surface: vk.SurfaceKHR = undefined;
|
||||||
if (c.glfwCreateWindowSurface(instance, window, null, &surface) != .success) {
|
if (c.glfwCreateWindowSurface(instance.handle, window, null, &surface) != .success) {
|
||||||
return error.SurfaceInitFailed;
|
return error.SurfaceInitFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initializeCandidate(vki: InstanceDispatch, candidate: DeviceCandidate) !vk.Device {
|
fn initializeCandidate(instance: Instance, candidate: DeviceCandidate) !vk.Device {
|
||||||
const priority = [_]f32{1};
|
const priority = [_]f32{1};
|
||||||
const qci = [_]vk.DeviceQueueCreateInfo{
|
const qci = [_]vk.DeviceQueueCreateInfo{
|
||||||
.{
|
.{
|
||||||
@@ -153,11 +172,11 @@ fn initializeCandidate(vki: InstanceDispatch, candidate: DeviceCandidate) !vk.De
|
|||||||
else
|
else
|
||||||
2;
|
2;
|
||||||
|
|
||||||
return try vki.createDevice(candidate.pdev, &.{
|
return try instance.createDevice(candidate.pdev, &.{
|
||||||
.queue_create_info_count = queue_count,
|
.queue_create_info_count = queue_count,
|
||||||
.p_queue_create_infos = &qci,
|
.p_queue_create_infos = &qci,
|
||||||
.enabled_extension_count = required_device_extensions.len,
|
.enabled_extension_count = required_device_extensions.len,
|
||||||
.pp_enabled_extension_names = @as([*]const [*:0]const u8, @ptrCast(&required_device_extensions)),
|
.pp_enabled_extension_names = @ptrCast(&required_device_extensions),
|
||||||
}, null);
|
}, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,21 +192,20 @@ const QueueAllocation = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
fn pickPhysicalDevice(
|
fn pickPhysicalDevice(
|
||||||
vki: InstanceDispatch,
|
instance: Instance,
|
||||||
instance: vk.Instance,
|
|
||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
surface: vk.SurfaceKHR,
|
surface: vk.SurfaceKHR,
|
||||||
) !DeviceCandidate {
|
) !DeviceCandidate {
|
||||||
var device_count: u32 = undefined;
|
var device_count: u32 = undefined;
|
||||||
_ = try vki.enumeratePhysicalDevices(instance, &device_count, null);
|
_ = try instance.enumeratePhysicalDevices(&device_count, null);
|
||||||
|
|
||||||
const pdevs = try allocator.alloc(vk.PhysicalDevice, device_count);
|
const pdevs = try allocator.alloc(vk.PhysicalDevice, device_count);
|
||||||
defer allocator.free(pdevs);
|
defer allocator.free(pdevs);
|
||||||
|
|
||||||
_ = try vki.enumeratePhysicalDevices(instance, &device_count, pdevs.ptr);
|
_ = try instance.enumeratePhysicalDevices(&device_count, pdevs.ptr);
|
||||||
|
|
||||||
for (pdevs) |pdev| {
|
for (pdevs) |pdev| {
|
||||||
if (try checkSuitable(vki, pdev, allocator, surface)) |candidate| {
|
if (try checkSuitable(instance, pdev, allocator, surface)) |candidate| {
|
||||||
return candidate;
|
return candidate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -196,22 +214,21 @@ fn pickPhysicalDevice(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn checkSuitable(
|
fn checkSuitable(
|
||||||
vki: InstanceDispatch,
|
instance: Instance,
|
||||||
pdev: vk.PhysicalDevice,
|
pdev: vk.PhysicalDevice,
|
||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
surface: vk.SurfaceKHR,
|
surface: vk.SurfaceKHR,
|
||||||
) !?DeviceCandidate {
|
) !?DeviceCandidate {
|
||||||
const props = vki.getPhysicalDeviceProperties(pdev);
|
if (!try checkExtensionSupport(instance, pdev, allocator)) {
|
||||||
|
|
||||||
if (!try checkExtensionSupport(vki, pdev, allocator)) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!try checkSurfaceSupport(vki, pdev, surface)) {
|
if (!try checkSurfaceSupport(instance, pdev, surface)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (try allocateQueues(vki, pdev, allocator, surface)) |allocation| {
|
if (try allocateQueues(instance, pdev, allocator, surface)) |allocation| {
|
||||||
|
const props = instance.getPhysicalDeviceProperties(pdev);
|
||||||
return DeviceCandidate{
|
return DeviceCandidate{
|
||||||
.pdev = pdev,
|
.pdev = pdev,
|
||||||
.props = props,
|
.props = props,
|
||||||
@@ -222,13 +239,13 @@ fn checkSuitable(
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn allocateQueues(vki: InstanceDispatch, pdev: vk.PhysicalDevice, allocator: Allocator, surface: vk.SurfaceKHR) !?QueueAllocation {
|
fn allocateQueues(instance: Instance, pdev: vk.PhysicalDevice, allocator: Allocator, surface: vk.SurfaceKHR) !?QueueAllocation {
|
||||||
var family_count: u32 = undefined;
|
var family_count: u32 = undefined;
|
||||||
vki.getPhysicalDeviceQueueFamilyProperties(pdev, &family_count, null);
|
instance.getPhysicalDeviceQueueFamilyProperties(pdev, &family_count, null);
|
||||||
|
|
||||||
const families = try allocator.alloc(vk.QueueFamilyProperties, family_count);
|
const families = try allocator.alloc(vk.QueueFamilyProperties, family_count);
|
||||||
defer allocator.free(families);
|
defer allocator.free(families);
|
||||||
vki.getPhysicalDeviceQueueFamilyProperties(pdev, &family_count, families.ptr);
|
instance.getPhysicalDeviceQueueFamilyProperties(pdev, &family_count, families.ptr);
|
||||||
|
|
||||||
var graphics_family: ?u32 = null;
|
var graphics_family: ?u32 = null;
|
||||||
var present_family: ?u32 = null;
|
var present_family: ?u32 = null;
|
||||||
@@ -240,7 +257,7 @@ fn allocateQueues(vki: InstanceDispatch, pdev: vk.PhysicalDevice, allocator: All
|
|||||||
graphics_family = family;
|
graphics_family = family;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (present_family == null and (try vki.getPhysicalDeviceSurfaceSupportKHR(pdev, family, surface)) == vk.TRUE) {
|
if (present_family == null and (try instance.getPhysicalDeviceSurfaceSupportKHR(pdev, family, surface)) == vk.TRUE) {
|
||||||
present_family = family;
|
present_family = family;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -255,28 +272,28 @@ fn allocateQueues(vki: InstanceDispatch, pdev: vk.PhysicalDevice, allocator: All
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn checkSurfaceSupport(vki: InstanceDispatch, pdev: vk.PhysicalDevice, surface: vk.SurfaceKHR) !bool {
|
fn checkSurfaceSupport(instance: Instance, pdev: vk.PhysicalDevice, surface: vk.SurfaceKHR) !bool {
|
||||||
var format_count: u32 = undefined;
|
var format_count: u32 = undefined;
|
||||||
_ = try vki.getPhysicalDeviceSurfaceFormatsKHR(pdev, surface, &format_count, null);
|
_ = try instance.getPhysicalDeviceSurfaceFormatsKHR(pdev, surface, &format_count, null);
|
||||||
|
|
||||||
var present_mode_count: u32 = undefined;
|
var present_mode_count: u32 = undefined;
|
||||||
_ = try vki.getPhysicalDeviceSurfacePresentModesKHR(pdev, surface, &present_mode_count, null);
|
_ = try instance.getPhysicalDeviceSurfacePresentModesKHR(pdev, surface, &present_mode_count, null);
|
||||||
|
|
||||||
return format_count > 0 and present_mode_count > 0;
|
return format_count > 0 and present_mode_count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn checkExtensionSupport(
|
fn checkExtensionSupport(
|
||||||
vki: InstanceDispatch,
|
instance: Instance,
|
||||||
pdev: vk.PhysicalDevice,
|
pdev: vk.PhysicalDevice,
|
||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
) !bool {
|
) !bool {
|
||||||
var count: u32 = undefined;
|
var count: u32 = undefined;
|
||||||
_ = try vki.enumerateDeviceExtensionProperties(pdev, null, &count, null);
|
_ = try instance.enumerateDeviceExtensionProperties(pdev, null, &count, null);
|
||||||
|
|
||||||
const propsv = try allocator.alloc(vk.ExtensionProperties, count);
|
const propsv = try allocator.alloc(vk.ExtensionProperties, count);
|
||||||
defer allocator.free(propsv);
|
defer allocator.free(propsv);
|
||||||
|
|
||||||
_ = try vki.enumerateDeviceExtensionProperties(pdev, null, &count, propsv.ptr);
|
_ = try instance.enumerateDeviceExtensionProperties(pdev, null, &count, propsv.ptr);
|
||||||
|
|
||||||
for (required_device_extensions) |ext| {
|
for (required_device_extensions) |ext| {
|
||||||
for (propsv) |props| {
|
for (propsv) |props| {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ pub const Swapchain = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn initRecycle(gc: *const GraphicsContext, allocator: Allocator, extent: vk.Extent2D, old_handle: vk.SwapchainKHR) !Swapchain {
|
pub fn initRecycle(gc: *const GraphicsContext, allocator: Allocator, extent: vk.Extent2D, old_handle: vk.SwapchainKHR) !Swapchain {
|
||||||
const caps = try gc.vki.getPhysicalDeviceSurfaceCapabilitiesKHR(gc.pdev, gc.surface);
|
const caps = try gc.instance.getPhysicalDeviceSurfaceCapabilitiesKHR(gc.pdev, gc.surface);
|
||||||
const actual_extent = findActualExtent(caps, extent);
|
const actual_extent = findActualExtent(caps, extent);
|
||||||
if (actual_extent.width == 0 or actual_extent.height == 0) {
|
if (actual_extent.width == 0 or actual_extent.height == 0) {
|
||||||
return error.InvalidSurfaceDimensions;
|
return error.InvalidSurfaceDimensions;
|
||||||
@@ -46,7 +46,7 @@ pub const Swapchain = struct {
|
|||||||
else
|
else
|
||||||
.exclusive;
|
.exclusive;
|
||||||
|
|
||||||
const handle = try gc.vkd.createSwapchainKHR(gc.dev, &.{
|
const handle = try gc.dev.createSwapchainKHR(&.{
|
||||||
.surface = gc.surface,
|
.surface = gc.surface,
|
||||||
.min_image_count = image_count,
|
.min_image_count = image_count,
|
||||||
.image_format = surface_format.format,
|
.image_format = surface_format.format,
|
||||||
@@ -63,11 +63,11 @@ pub const Swapchain = struct {
|
|||||||
.clipped = vk.TRUE,
|
.clipped = vk.TRUE,
|
||||||
.old_swapchain = old_handle,
|
.old_swapchain = old_handle,
|
||||||
}, null);
|
}, null);
|
||||||
errdefer gc.vkd.destroySwapchainKHR(gc.dev, handle, null);
|
errdefer gc.dev.destroySwapchainKHR(handle, null);
|
||||||
|
|
||||||
if (old_handle != .null_handle) {
|
if (old_handle != .null_handle) {
|
||||||
// Apparently, the old swapchain handle still needs to be destroyed after recreating.
|
// Apparently, the old swapchain handle still needs to be destroyed after recreating.
|
||||||
gc.vkd.destroySwapchainKHR(gc.dev, old_handle, null);
|
gc.dev.destroySwapchainKHR(old_handle, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
const swap_images = try initSwapchainImages(gc, handle, surface_format.format, allocator);
|
const swap_images = try initSwapchainImages(gc, handle, surface_format.format, allocator);
|
||||||
@@ -76,10 +76,10 @@ pub const Swapchain = struct {
|
|||||||
allocator.free(swap_images);
|
allocator.free(swap_images);
|
||||||
}
|
}
|
||||||
|
|
||||||
var next_image_acquired = try gc.vkd.createSemaphore(gc.dev, &.{}, null);
|
var next_image_acquired = try gc.dev.createSemaphore(&.{}, null);
|
||||||
errdefer gc.vkd.destroySemaphore(gc.dev, next_image_acquired, null);
|
errdefer gc.dev.destroySemaphore(next_image_acquired, null);
|
||||||
|
|
||||||
const result = try gc.vkd.acquireNextImageKHR(gc.dev, handle, std.math.maxInt(u64), next_image_acquired, .null_handle);
|
const result = try gc.dev.acquireNextImageKHR(handle, std.math.maxInt(u64), next_image_acquired, .null_handle);
|
||||||
if (result.result != .success) {
|
if (result.result != .success) {
|
||||||
return error.ImageAcquireFailed;
|
return error.ImageAcquireFailed;
|
||||||
}
|
}
|
||||||
@@ -101,7 +101,7 @@ pub const Swapchain = struct {
|
|||||||
fn deinitExceptSwapchain(self: Swapchain) void {
|
fn deinitExceptSwapchain(self: Swapchain) void {
|
||||||
for (self.swap_images) |si| si.deinit(self.gc);
|
for (self.swap_images) |si| si.deinit(self.gc);
|
||||||
self.allocator.free(self.swap_images);
|
self.allocator.free(self.swap_images);
|
||||||
self.gc.vkd.destroySemaphore(self.gc.dev, self.next_image_acquired, null);
|
self.gc.dev.destroySemaphore(self.next_image_acquired, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn waitForAllFences(self: Swapchain) !void {
|
pub fn waitForAllFences(self: Swapchain) !void {
|
||||||
@@ -110,7 +110,7 @@ pub const Swapchain = struct {
|
|||||||
|
|
||||||
pub fn deinit(self: Swapchain) void {
|
pub fn deinit(self: Swapchain) void {
|
||||||
self.deinitExceptSwapchain();
|
self.deinitExceptSwapchain();
|
||||||
self.gc.vkd.destroySwapchainKHR(self.gc.dev, self.handle, null);
|
self.gc.dev.destroySwapchainKHR(self.handle, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recreate(self: *Swapchain, new_extent: vk.Extent2D) !void {
|
pub fn recreate(self: *Swapchain, new_extent: vk.Extent2D) !void {
|
||||||
@@ -150,11 +150,11 @@ pub const Swapchain = struct {
|
|||||||
// Step 1: Make sure the current frame has finished rendering
|
// Step 1: Make sure the current frame has finished rendering
|
||||||
const current = self.currentSwapImage();
|
const current = self.currentSwapImage();
|
||||||
try current.waitForFence(self.gc);
|
try current.waitForFence(self.gc);
|
||||||
try self.gc.vkd.resetFences(self.gc.dev, 1, @ptrCast(¤t.frame_fence));
|
try self.gc.dev.resetFences(1, @ptrCast(¤t.frame_fence));
|
||||||
|
|
||||||
// Step 2: Submit the command buffer
|
// Step 2: Submit the command buffer
|
||||||
const wait_stage = [_]vk.PipelineStageFlags{.{ .top_of_pipe_bit = true }};
|
const wait_stage = [_]vk.PipelineStageFlags{.{ .top_of_pipe_bit = true }};
|
||||||
try self.gc.vkd.queueSubmit(self.gc.graphics_queue.handle, 1, &[_]vk.SubmitInfo{.{
|
try self.gc.dev.queueSubmit(self.gc.graphics_queue.handle, 1, &[_]vk.SubmitInfo{.{
|
||||||
.wait_semaphore_count = 1,
|
.wait_semaphore_count = 1,
|
||||||
.p_wait_semaphores = @ptrCast(¤t.image_acquired),
|
.p_wait_semaphores = @ptrCast(¤t.image_acquired),
|
||||||
.p_wait_dst_stage_mask = &wait_stage,
|
.p_wait_dst_stage_mask = &wait_stage,
|
||||||
@@ -165,17 +165,16 @@ pub const Swapchain = struct {
|
|||||||
}}, current.frame_fence);
|
}}, current.frame_fence);
|
||||||
|
|
||||||
// Step 3: Present the current frame
|
// Step 3: Present the current frame
|
||||||
_ = try self.gc.vkd.queuePresentKHR(self.gc.present_queue.handle, &.{
|
_ = try self.gc.dev.queuePresentKHR(self.gc.present_queue.handle, &.{
|
||||||
.wait_semaphore_count = 1,
|
.wait_semaphore_count = 1,
|
||||||
.p_wait_semaphores = @as([*]const vk.Semaphore, @ptrCast(¤t.render_finished)),
|
.p_wait_semaphores = @ptrCast(¤t.render_finished),
|
||||||
.swapchain_count = 1,
|
.swapchain_count = 1,
|
||||||
.p_swapchains = @as([*]const vk.SwapchainKHR, @ptrCast(&self.handle)),
|
.p_swapchains = @ptrCast(&self.handle),
|
||||||
.p_image_indices = @as([*]const u32, @ptrCast(&self.image_index)),
|
.p_image_indices = @ptrCast(&self.image_index),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Step 4: Acquire next frame
|
// Step 4: Acquire next frame
|
||||||
const result = try self.gc.vkd.acquireNextImageKHR(
|
const result = try self.gc.dev.acquireNextImageKHR(
|
||||||
self.gc.dev,
|
|
||||||
self.handle,
|
self.handle,
|
||||||
std.math.maxInt(u64),
|
std.math.maxInt(u64),
|
||||||
self.next_image_acquired,
|
self.next_image_acquired,
|
||||||
@@ -201,7 +200,7 @@ const SwapImage = struct {
|
|||||||
frame_fence: vk.Fence,
|
frame_fence: vk.Fence,
|
||||||
|
|
||||||
fn init(gc: *const GraphicsContext, image: vk.Image, format: vk.Format) !SwapImage {
|
fn init(gc: *const GraphicsContext, image: vk.Image, format: vk.Format) !SwapImage {
|
||||||
const view = try gc.vkd.createImageView(gc.dev, &.{
|
const view = try gc.dev.createImageView(&.{
|
||||||
.image = image,
|
.image = image,
|
||||||
.view_type = .@"2d",
|
.view_type = .@"2d",
|
||||||
.format = format,
|
.format = format,
|
||||||
@@ -214,16 +213,16 @@ const SwapImage = struct {
|
|||||||
.layer_count = 1,
|
.layer_count = 1,
|
||||||
},
|
},
|
||||||
}, null);
|
}, null);
|
||||||
errdefer gc.vkd.destroyImageView(gc.dev, view, null);
|
errdefer gc.dev.destroyImageView(view, null);
|
||||||
|
|
||||||
const image_acquired = try gc.vkd.createSemaphore(gc.dev, &.{}, null);
|
const image_acquired = try gc.dev.createSemaphore(&.{}, null);
|
||||||
errdefer gc.vkd.destroySemaphore(gc.dev, image_acquired, null);
|
errdefer gc.dev.destroySemaphore(image_acquired, null);
|
||||||
|
|
||||||
const render_finished = try gc.vkd.createSemaphore(gc.dev, &.{}, null);
|
const render_finished = try gc.dev.createSemaphore(&.{}, null);
|
||||||
errdefer gc.vkd.destroySemaphore(gc.dev, render_finished, null);
|
errdefer gc.dev.destroySemaphore(render_finished, null);
|
||||||
|
|
||||||
const frame_fence = try gc.vkd.createFence(gc.dev, &.{ .flags = .{ .signaled_bit = true } }, null);
|
const frame_fence = try gc.dev.createFence(&.{ .flags = .{ .signaled_bit = true } }, null);
|
||||||
errdefer gc.vkd.destroyFence(gc.dev, frame_fence, null);
|
errdefer gc.dev.destroyFence(frame_fence, null);
|
||||||
|
|
||||||
return SwapImage{
|
return SwapImage{
|
||||||
.image = image,
|
.image = image,
|
||||||
@@ -236,23 +235,23 @@ const SwapImage = struct {
|
|||||||
|
|
||||||
fn deinit(self: SwapImage, gc: *const GraphicsContext) void {
|
fn deinit(self: SwapImage, gc: *const GraphicsContext) void {
|
||||||
self.waitForFence(gc) catch return;
|
self.waitForFence(gc) catch return;
|
||||||
gc.vkd.destroyImageView(gc.dev, self.view, null);
|
gc.dev.destroyImageView(self.view, null);
|
||||||
gc.vkd.destroySemaphore(gc.dev, self.image_acquired, null);
|
gc.dev.destroySemaphore(self.image_acquired, null);
|
||||||
gc.vkd.destroySemaphore(gc.dev, self.render_finished, null);
|
gc.dev.destroySemaphore(self.render_finished, null);
|
||||||
gc.vkd.destroyFence(gc.dev, self.frame_fence, null);
|
gc.dev.destroyFence(self.frame_fence, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn waitForFence(self: SwapImage, gc: *const GraphicsContext) !void {
|
fn waitForFence(self: SwapImage, gc: *const GraphicsContext) !void {
|
||||||
_ = try gc.vkd.waitForFences(gc.dev, 1, @ptrCast(&self.frame_fence), vk.TRUE, std.math.maxInt(u64));
|
_ = try gc.dev.waitForFences(1, @ptrCast(&self.frame_fence), vk.TRUE, std.math.maxInt(u64));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fn initSwapchainImages(gc: *const GraphicsContext, swapchain: vk.SwapchainKHR, format: vk.Format, allocator: Allocator) ![]SwapImage {
|
fn initSwapchainImages(gc: *const GraphicsContext, swapchain: vk.SwapchainKHR, format: vk.Format, allocator: Allocator) ![]SwapImage {
|
||||||
var count: u32 = undefined;
|
var count: u32 = undefined;
|
||||||
_ = try gc.vkd.getSwapchainImagesKHR(gc.dev, swapchain, &count, null);
|
_ = try gc.dev.getSwapchainImagesKHR(swapchain, &count, null);
|
||||||
const images = try allocator.alloc(vk.Image, count);
|
const images = try allocator.alloc(vk.Image, count);
|
||||||
defer allocator.free(images);
|
defer allocator.free(images);
|
||||||
_ = try gc.vkd.getSwapchainImagesKHR(gc.dev, swapchain, &count, images.ptr);
|
_ = try gc.dev.getSwapchainImagesKHR(swapchain, &count, images.ptr);
|
||||||
|
|
||||||
const swap_images = try allocator.alloc(SwapImage, count);
|
const swap_images = try allocator.alloc(SwapImage, count);
|
||||||
errdefer allocator.free(swap_images);
|
errdefer allocator.free(swap_images);
|
||||||
@@ -275,10 +274,10 @@ fn findSurfaceFormat(gc: *const GraphicsContext, allocator: Allocator) !vk.Surfa
|
|||||||
};
|
};
|
||||||
|
|
||||||
var count: u32 = undefined;
|
var count: u32 = undefined;
|
||||||
_ = try gc.vki.getPhysicalDeviceSurfaceFormatsKHR(gc.pdev, gc.surface, &count, null);
|
_ = try gc.instance.getPhysicalDeviceSurfaceFormatsKHR(gc.pdev, gc.surface, &count, null);
|
||||||
const surface_formats = try allocator.alloc(vk.SurfaceFormatKHR, count);
|
const surface_formats = try allocator.alloc(vk.SurfaceFormatKHR, count);
|
||||||
defer allocator.free(surface_formats);
|
defer allocator.free(surface_formats);
|
||||||
_ = try gc.vki.getPhysicalDeviceSurfaceFormatsKHR(gc.pdev, gc.surface, &count, surface_formats.ptr);
|
_ = try gc.instance.getPhysicalDeviceSurfaceFormatsKHR(gc.pdev, gc.surface, &count, surface_formats.ptr);
|
||||||
|
|
||||||
for (surface_formats) |sfmt| {
|
for (surface_formats) |sfmt| {
|
||||||
if (std.meta.eql(sfmt, preferred)) {
|
if (std.meta.eql(sfmt, preferred)) {
|
||||||
@@ -291,10 +290,10 @@ fn findSurfaceFormat(gc: *const GraphicsContext, allocator: Allocator) !vk.Surfa
|
|||||||
|
|
||||||
fn findPresentMode(gc: *const GraphicsContext, allocator: Allocator) !vk.PresentModeKHR {
|
fn findPresentMode(gc: *const GraphicsContext, allocator: Allocator) !vk.PresentModeKHR {
|
||||||
var count: u32 = undefined;
|
var count: u32 = undefined;
|
||||||
_ = try gc.vki.getPhysicalDeviceSurfacePresentModesKHR(gc.pdev, gc.surface, &count, null);
|
_ = try gc.instance.getPhysicalDeviceSurfacePresentModesKHR(gc.pdev, gc.surface, &count, null);
|
||||||
const present_modes = try allocator.alloc(vk.PresentModeKHR, count);
|
const present_modes = try allocator.alloc(vk.PresentModeKHR, count);
|
||||||
defer allocator.free(present_modes);
|
defer allocator.free(present_modes);
|
||||||
_ = try gc.vki.getPhysicalDeviceSurfacePresentModesKHR(gc.pdev, gc.surface, &count, present_modes.ptr);
|
_ = try gc.instance.getPhysicalDeviceSurfacePresentModesKHR(gc.pdev, gc.surface, &count, present_modes.ptr);
|
||||||
|
|
||||||
const preferred = [_]vk.PresentModeKHR{
|
const preferred = [_]vk.PresentModeKHR{
|
||||||
.mailbox_khr,
|
.mailbox_khr,
|
||||||
|
|||||||
@@ -73,39 +73,39 @@ pub fn main() !void {
|
|||||||
var swapchain = try Swapchain.init(&gc, allocator, extent);
|
var swapchain = try Swapchain.init(&gc, allocator, extent);
|
||||||
defer swapchain.deinit();
|
defer swapchain.deinit();
|
||||||
|
|
||||||
const pipeline_layout = try gc.vkd.createPipelineLayout(gc.dev, &.{
|
const pipeline_layout = try gc.dev.createPipelineLayout(&.{
|
||||||
.flags = .{},
|
.flags = .{},
|
||||||
.set_layout_count = 0,
|
.set_layout_count = 0,
|
||||||
.p_set_layouts = undefined,
|
.p_set_layouts = undefined,
|
||||||
.push_constant_range_count = 0,
|
.push_constant_range_count = 0,
|
||||||
.p_push_constant_ranges = undefined,
|
.p_push_constant_ranges = undefined,
|
||||||
}, null);
|
}, null);
|
||||||
defer gc.vkd.destroyPipelineLayout(gc.dev, pipeline_layout, null);
|
defer gc.dev.destroyPipelineLayout(pipeline_layout, null);
|
||||||
|
|
||||||
const render_pass = try createRenderPass(&gc, swapchain);
|
const render_pass = try createRenderPass(&gc, swapchain);
|
||||||
defer gc.vkd.destroyRenderPass(gc.dev, render_pass, null);
|
defer gc.dev.destroyRenderPass(render_pass, null);
|
||||||
|
|
||||||
const pipeline = try createPipeline(&gc, pipeline_layout, render_pass);
|
const pipeline = try createPipeline(&gc, pipeline_layout, render_pass);
|
||||||
defer gc.vkd.destroyPipeline(gc.dev, pipeline, null);
|
defer gc.dev.destroyPipeline(pipeline, null);
|
||||||
|
|
||||||
var framebuffers = try createFramebuffers(&gc, allocator, render_pass, swapchain);
|
var framebuffers = try createFramebuffers(&gc, allocator, render_pass, swapchain);
|
||||||
defer destroyFramebuffers(&gc, allocator, framebuffers);
|
defer destroyFramebuffers(&gc, allocator, framebuffers);
|
||||||
|
|
||||||
const pool = try gc.vkd.createCommandPool(gc.dev, &.{
|
const pool = try gc.dev.createCommandPool(&.{
|
||||||
.queue_family_index = gc.graphics_queue.family,
|
.queue_family_index = gc.graphics_queue.family,
|
||||||
}, null);
|
}, null);
|
||||||
defer gc.vkd.destroyCommandPool(gc.dev, pool, null);
|
defer gc.dev.destroyCommandPool(pool, null);
|
||||||
|
|
||||||
const buffer = try gc.vkd.createBuffer(gc.dev, &.{
|
const buffer = try gc.dev.createBuffer(&.{
|
||||||
.size = @sizeOf(@TypeOf(vertices)),
|
.size = @sizeOf(@TypeOf(vertices)),
|
||||||
.usage = .{ .transfer_dst_bit = true, .vertex_buffer_bit = true },
|
.usage = .{ .transfer_dst_bit = true, .vertex_buffer_bit = true },
|
||||||
.sharing_mode = .exclusive,
|
.sharing_mode = .exclusive,
|
||||||
}, null);
|
}, null);
|
||||||
defer gc.vkd.destroyBuffer(gc.dev, buffer, null);
|
defer gc.dev.destroyBuffer(buffer, null);
|
||||||
const mem_reqs = gc.vkd.getBufferMemoryRequirements(gc.dev, buffer);
|
const mem_reqs = gc.dev.getBufferMemoryRequirements(buffer);
|
||||||
const memory = try gc.allocate(mem_reqs, .{ .device_local_bit = true });
|
const memory = try gc.allocate(mem_reqs, .{ .device_local_bit = true });
|
||||||
defer gc.vkd.freeMemory(gc.dev, memory, null);
|
defer gc.dev.freeMemory(memory, null);
|
||||||
try gc.vkd.bindBufferMemory(gc.dev, buffer, memory, 0);
|
try gc.dev.bindBufferMemory(buffer, memory, 0);
|
||||||
|
|
||||||
try uploadVertices(&gc, pool, buffer);
|
try uploadVertices(&gc, pool, buffer);
|
||||||
|
|
||||||
@@ -164,24 +164,24 @@ pub fn main() !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try swapchain.waitForAllFences();
|
try swapchain.waitForAllFences();
|
||||||
try gc.vkd.deviceWaitIdle(gc.dev);
|
try gc.dev.deviceWaitIdle();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn uploadVertices(gc: *const GraphicsContext, pool: vk.CommandPool, buffer: vk.Buffer) !void {
|
fn uploadVertices(gc: *const GraphicsContext, pool: vk.CommandPool, buffer: vk.Buffer) !void {
|
||||||
const staging_buffer = try gc.vkd.createBuffer(gc.dev, &.{
|
const staging_buffer = try gc.dev.createBuffer(&.{
|
||||||
.size = @sizeOf(@TypeOf(vertices)),
|
.size = @sizeOf(@TypeOf(vertices)),
|
||||||
.usage = .{ .transfer_src_bit = true },
|
.usage = .{ .transfer_src_bit = true },
|
||||||
.sharing_mode = .exclusive,
|
.sharing_mode = .exclusive,
|
||||||
}, null);
|
}, null);
|
||||||
defer gc.vkd.destroyBuffer(gc.dev, staging_buffer, null);
|
defer gc.dev.destroyBuffer(staging_buffer, null);
|
||||||
const mem_reqs = gc.vkd.getBufferMemoryRequirements(gc.dev, staging_buffer);
|
const mem_reqs = gc.dev.getBufferMemoryRequirements(staging_buffer);
|
||||||
const staging_memory = try gc.allocate(mem_reqs, .{ .host_visible_bit = true, .host_coherent_bit = true });
|
const staging_memory = try gc.allocate(mem_reqs, .{ .host_visible_bit = true, .host_coherent_bit = true });
|
||||||
defer gc.vkd.freeMemory(gc.dev, staging_memory, null);
|
defer gc.dev.freeMemory(staging_memory, null);
|
||||||
try gc.vkd.bindBufferMemory(gc.dev, staging_buffer, staging_memory, 0);
|
try gc.dev.bindBufferMemory(staging_buffer, staging_memory, 0);
|
||||||
|
|
||||||
{
|
{
|
||||||
const data = try gc.vkd.mapMemory(gc.dev, staging_memory, 0, vk.WHOLE_SIZE, .{});
|
const data = try gc.dev.mapMemory(staging_memory, 0, vk.WHOLE_SIZE, .{});
|
||||||
defer gc.vkd.unmapMemory(gc.dev, staging_memory);
|
defer gc.dev.unmapMemory(staging_memory);
|
||||||
|
|
||||||
const gpu_vertices: [*]Vertex = @ptrCast(@alignCast(data));
|
const gpu_vertices: [*]Vertex = @ptrCast(@alignCast(data));
|
||||||
@memcpy(gpu_vertices, vertices[0..]);
|
@memcpy(gpu_vertices, vertices[0..]);
|
||||||
@@ -191,15 +191,17 @@ fn uploadVertices(gc: *const GraphicsContext, pool: vk.CommandPool, buffer: vk.B
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn copyBuffer(gc: *const GraphicsContext, pool: vk.CommandPool, dst: vk.Buffer, src: vk.Buffer, size: vk.DeviceSize) !void {
|
fn copyBuffer(gc: *const GraphicsContext, pool: vk.CommandPool, dst: vk.Buffer, src: vk.Buffer, size: vk.DeviceSize) !void {
|
||||||
var cmdbuf: vk.CommandBuffer = undefined;
|
var cmdbuf_handle: vk.CommandBuffer = undefined;
|
||||||
try gc.vkd.allocateCommandBuffers(gc.dev, &.{
|
try gc.dev.allocateCommandBuffers(&.{
|
||||||
.command_pool = pool,
|
.command_pool = pool,
|
||||||
.level = .primary,
|
.level = .primary,
|
||||||
.command_buffer_count = 1,
|
.command_buffer_count = 1,
|
||||||
}, @ptrCast(&cmdbuf));
|
}, @ptrCast(&cmdbuf_handle));
|
||||||
defer gc.vkd.freeCommandBuffers(gc.dev, pool, 1, @ptrCast(&cmdbuf));
|
defer gc.dev.freeCommandBuffers(pool, 1, @ptrCast(&cmdbuf_handle));
|
||||||
|
|
||||||
try gc.vkd.beginCommandBuffer(cmdbuf, &.{
|
const cmdbuf = GraphicsContext.CommandBuffer.init(cmdbuf_handle, gc.dev.wrapper);
|
||||||
|
|
||||||
|
try cmdbuf.beginCommandBuffer(&.{
|
||||||
.flags = .{ .one_time_submit_bit = true },
|
.flags = .{ .one_time_submit_bit = true },
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -208,17 +210,17 @@ fn copyBuffer(gc: *const GraphicsContext, pool: vk.CommandPool, dst: vk.Buffer,
|
|||||||
.dst_offset = 0,
|
.dst_offset = 0,
|
||||||
.size = size,
|
.size = size,
|
||||||
};
|
};
|
||||||
gc.vkd.cmdCopyBuffer(cmdbuf, src, dst, 1, @ptrCast(®ion));
|
cmdbuf.copyBuffer(src, dst, 1, @ptrCast(®ion));
|
||||||
|
|
||||||
try gc.vkd.endCommandBuffer(cmdbuf);
|
try cmdbuf.endCommandBuffer();
|
||||||
|
|
||||||
const si = vk.SubmitInfo{
|
const si = vk.SubmitInfo{
|
||||||
.command_buffer_count = 1,
|
.command_buffer_count = 1,
|
||||||
.p_command_buffers = @ptrCast(&cmdbuf),
|
.p_command_buffers = (&cmdbuf.handle)[0..1],
|
||||||
.p_wait_dst_stage_mask = undefined,
|
.p_wait_dst_stage_mask = undefined,
|
||||||
};
|
};
|
||||||
try gc.vkd.queueSubmit(gc.graphics_queue.handle, 1, @ptrCast(&si), .null_handle);
|
try gc.dev.queueSubmit(gc.graphics_queue.handle, 1, @ptrCast(&si), .null_handle);
|
||||||
try gc.vkd.queueWaitIdle(gc.graphics_queue.handle);
|
try gc.dev.queueWaitIdle(gc.graphics_queue.handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn createCommandBuffers(
|
fn createCommandBuffers(
|
||||||
@@ -234,12 +236,12 @@ fn createCommandBuffers(
|
|||||||
const cmdbufs = try allocator.alloc(vk.CommandBuffer, framebuffers.len);
|
const cmdbufs = try allocator.alloc(vk.CommandBuffer, framebuffers.len);
|
||||||
errdefer allocator.free(cmdbufs);
|
errdefer allocator.free(cmdbufs);
|
||||||
|
|
||||||
try gc.vkd.allocateCommandBuffers(gc.dev, &.{
|
try gc.dev.allocateCommandBuffers(&.{
|
||||||
.command_pool = pool,
|
.command_pool = pool,
|
||||||
.level = .primary,
|
.level = .primary,
|
||||||
.command_buffer_count = @as(u32, @truncate(cmdbufs.len)),
|
.command_buffer_count = @intCast(cmdbufs.len),
|
||||||
}, cmdbufs.ptr);
|
}, cmdbufs.ptr);
|
||||||
errdefer gc.vkd.freeCommandBuffers(gc.dev, pool, @truncate(cmdbufs.len), cmdbufs.ptr);
|
errdefer gc.dev.freeCommandBuffers(pool, @intCast(cmdbufs.len), cmdbufs.ptr);
|
||||||
|
|
||||||
const clear = vk.ClearValue{
|
const clear = vk.ClearValue{
|
||||||
.color = .{ .float_32 = .{ 0, 0, 0, 1 } },
|
.color = .{ .float_32 = .{ 0, 0, 0, 1 } },
|
||||||
@@ -248,8 +250,8 @@ fn createCommandBuffers(
|
|||||||
const viewport = vk.Viewport{
|
const viewport = vk.Viewport{
|
||||||
.x = 0,
|
.x = 0,
|
||||||
.y = 0,
|
.y = 0,
|
||||||
.width = @as(f32, @floatFromInt(extent.width)),
|
.width = @floatFromInt(extent.width),
|
||||||
.height = @as(f32, @floatFromInt(extent.height)),
|
.height = @floatFromInt(extent.height),
|
||||||
.min_depth = 0,
|
.min_depth = 0,
|
||||||
.max_depth = 1,
|
.max_depth = 1,
|
||||||
};
|
};
|
||||||
@@ -260,10 +262,10 @@ fn createCommandBuffers(
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (cmdbufs, framebuffers) |cmdbuf, framebuffer| {
|
for (cmdbufs, framebuffers) |cmdbuf, framebuffer| {
|
||||||
try gc.vkd.beginCommandBuffer(cmdbuf, &.{});
|
try gc.dev.beginCommandBuffer(cmdbuf, &.{});
|
||||||
|
|
||||||
gc.vkd.cmdSetViewport(cmdbuf, 0, 1, @ptrCast(&viewport));
|
gc.dev.cmdSetViewport(cmdbuf, 0, 1, @ptrCast(&viewport));
|
||||||
gc.vkd.cmdSetScissor(cmdbuf, 0, 1, @ptrCast(&scissor));
|
gc.dev.cmdSetScissor(cmdbuf, 0, 1, @ptrCast(&scissor));
|
||||||
|
|
||||||
// This needs to be a separate definition - see https://github.com/ziglang/zig/issues/7627.
|
// This needs to be a separate definition - see https://github.com/ziglang/zig/issues/7627.
|
||||||
const render_area = vk.Rect2D{
|
const render_area = vk.Rect2D{
|
||||||
@@ -271,28 +273,28 @@ fn createCommandBuffers(
|
|||||||
.extent = extent,
|
.extent = extent,
|
||||||
};
|
};
|
||||||
|
|
||||||
gc.vkd.cmdBeginRenderPass(cmdbuf, &.{
|
gc.dev.cmdBeginRenderPass(cmdbuf, &.{
|
||||||
.render_pass = render_pass,
|
.render_pass = render_pass,
|
||||||
.framebuffer = framebuffer,
|
.framebuffer = framebuffer,
|
||||||
.render_area = render_area,
|
.render_area = render_area,
|
||||||
.clear_value_count = 1,
|
.clear_value_count = 1,
|
||||||
.p_clear_values = @as([*]const vk.ClearValue, @ptrCast(&clear)),
|
.p_clear_values = @ptrCast(&clear),
|
||||||
}, .@"inline");
|
}, .@"inline");
|
||||||
|
|
||||||
gc.vkd.cmdBindPipeline(cmdbuf, .graphics, pipeline);
|
gc.dev.cmdBindPipeline(cmdbuf, .graphics, pipeline);
|
||||||
const offset = [_]vk.DeviceSize{0};
|
const offset = [_]vk.DeviceSize{0};
|
||||||
gc.vkd.cmdBindVertexBuffers(cmdbuf, 0, 1, @ptrCast(&buffer), &offset);
|
gc.dev.cmdBindVertexBuffers(cmdbuf, 0, 1, @ptrCast(&buffer), &offset);
|
||||||
gc.vkd.cmdDraw(cmdbuf, vertices.len, 1, 0, 0);
|
gc.dev.cmdDraw(cmdbuf, vertices.len, 1, 0, 0);
|
||||||
|
|
||||||
gc.vkd.cmdEndRenderPass(cmdbuf);
|
gc.dev.cmdEndRenderPass(cmdbuf);
|
||||||
try gc.vkd.endCommandBuffer(cmdbuf);
|
try gc.dev.endCommandBuffer(cmdbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
return cmdbufs;
|
return cmdbufs;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn destroyCommandBuffers(gc: *const GraphicsContext, pool: vk.CommandPool, allocator: Allocator, cmdbufs: []vk.CommandBuffer) void {
|
fn destroyCommandBuffers(gc: *const GraphicsContext, pool: vk.CommandPool, allocator: Allocator, cmdbufs: []vk.CommandBuffer) void {
|
||||||
gc.vkd.freeCommandBuffers(gc.dev, pool, @truncate(cmdbufs.len), cmdbufs.ptr);
|
gc.dev.freeCommandBuffers(pool, @truncate(cmdbufs.len), cmdbufs.ptr);
|
||||||
allocator.free(cmdbufs);
|
allocator.free(cmdbufs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,13 +303,13 @@ fn createFramebuffers(gc: *const GraphicsContext, allocator: Allocator, render_p
|
|||||||
errdefer allocator.free(framebuffers);
|
errdefer allocator.free(framebuffers);
|
||||||
|
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
errdefer for (framebuffers[0..i]) |fb| gc.vkd.destroyFramebuffer(gc.dev, fb, null);
|
errdefer for (framebuffers[0..i]) |fb| gc.dev.destroyFramebuffer(fb, null);
|
||||||
|
|
||||||
for (framebuffers) |*fb| {
|
for (framebuffers) |*fb| {
|
||||||
fb.* = try gc.vkd.createFramebuffer(gc.dev, &.{
|
fb.* = try gc.dev.createFramebuffer(&.{
|
||||||
.render_pass = render_pass,
|
.render_pass = render_pass,
|
||||||
.attachment_count = 1,
|
.attachment_count = 1,
|
||||||
.p_attachments = @as([*]const vk.ImageView, @ptrCast(&swapchain.swap_images[i].view)),
|
.p_attachments = @ptrCast(&swapchain.swap_images[i].view),
|
||||||
.width = swapchain.extent.width,
|
.width = swapchain.extent.width,
|
||||||
.height = swapchain.extent.height,
|
.height = swapchain.extent.height,
|
||||||
.layers = 1,
|
.layers = 1,
|
||||||
@@ -319,7 +321,7 @@ fn createFramebuffers(gc: *const GraphicsContext, allocator: Allocator, render_p
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn destroyFramebuffers(gc: *const GraphicsContext, allocator: Allocator, framebuffers: []const vk.Framebuffer) void {
|
fn destroyFramebuffers(gc: *const GraphicsContext, allocator: Allocator, framebuffers: []const vk.Framebuffer) void {
|
||||||
for (framebuffers) |fb| gc.vkd.destroyFramebuffer(gc.dev, fb, null);
|
for (framebuffers) |fb| gc.dev.destroyFramebuffer(fb, null);
|
||||||
allocator.free(framebuffers);
|
allocator.free(framebuffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,11 +348,11 @@ fn createRenderPass(gc: *const GraphicsContext, swapchain: Swapchain) !vk.Render
|
|||||||
.p_color_attachments = @ptrCast(&color_attachment_ref),
|
.p_color_attachments = @ptrCast(&color_attachment_ref),
|
||||||
};
|
};
|
||||||
|
|
||||||
return try gc.vkd.createRenderPass(gc.dev, &.{
|
return try gc.dev.createRenderPass(&.{
|
||||||
.attachment_count = 1,
|
.attachment_count = 1,
|
||||||
.p_attachments = @as([*]const vk.AttachmentDescription, @ptrCast(&color_attachment)),
|
.p_attachments = @ptrCast(&color_attachment),
|
||||||
.subpass_count = 1,
|
.subpass_count = 1,
|
||||||
.p_subpasses = @as([*]const vk.SubpassDescription, @ptrCast(&subpass)),
|
.p_subpasses = @ptrCast(&subpass),
|
||||||
}, null);
|
}, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,17 +361,17 @@ fn createPipeline(
|
|||||||
layout: vk.PipelineLayout,
|
layout: vk.PipelineLayout,
|
||||||
render_pass: vk.RenderPass,
|
render_pass: vk.RenderPass,
|
||||||
) !vk.Pipeline {
|
) !vk.Pipeline {
|
||||||
const vert = try gc.vkd.createShaderModule(gc.dev, &.{
|
const vert = try gc.dev.createShaderModule(&.{
|
||||||
.code_size = shaders.triangle_vert.len,
|
.code_size = shaders.triangle_vert.len,
|
||||||
.p_code = @as([*]const u32, @ptrCast(&shaders.triangle_vert)),
|
.p_code = @ptrCast(&shaders.triangle_vert),
|
||||||
}, null);
|
}, null);
|
||||||
defer gc.vkd.destroyShaderModule(gc.dev, vert, null);
|
defer gc.dev.destroyShaderModule(vert, null);
|
||||||
|
|
||||||
const frag = try gc.vkd.createShaderModule(gc.dev, &.{
|
const frag = try gc.dev.createShaderModule(&.{
|
||||||
.code_size = shaders.triangle_frag.len,
|
.code_size = shaders.triangle_frag.len,
|
||||||
.p_code = @as([*]const u32, @ptrCast(&shaders.triangle_frag)),
|
.p_code = @ptrCast(&shaders.triangle_frag),
|
||||||
}, null);
|
}, null);
|
||||||
defer gc.vkd.destroyShaderModule(gc.dev, frag, null);
|
defer gc.dev.destroyShaderModule(frag, null);
|
||||||
|
|
||||||
const pssci = [_]vk.PipelineShaderStageCreateInfo{
|
const pssci = [_]vk.PipelineShaderStageCreateInfo{
|
||||||
.{
|
.{
|
||||||
@@ -471,8 +473,7 @@ fn createPipeline(
|
|||||||
};
|
};
|
||||||
|
|
||||||
var pipeline: vk.Pipeline = undefined;
|
var pipeline: vk.Pipeline = undefined;
|
||||||
_ = try gc.vkd.createGraphicsPipelines(
|
_ = try gc.dev.createGraphicsPipelines(
|
||||||
gc.dev,
|
|
||||||
.null_handle,
|
.null_handle,
|
||||||
1,
|
1,
|
||||||
@ptrCast(&gpci),
|
@ptrCast(&gpci),
|
||||||
|
|||||||
Reference in New Issue
Block a user