Skip to content

Commit 45e8b94

Browse files
committed
port createSwapChain function
1 parent 1c40f40 commit 45e8b94

File tree

2 files changed

+148
-56
lines changed

2 files changed

+148
-56
lines changed

src/main.zig

Lines changed: 134 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,6 @@ const mem = std.mem;
44
const Allocator = mem.Allocator;
55
const c = @import("vulkan.zig");
66

7-
fn VK_MAKE_VERSION(major: u32, minor: u32, patch: u32) u32 {
8-
return ((major << u5(22)) | (minor << u5(12))) | patch;
9-
}
10-
const VK_API_VERSION_1_0 = VK_MAKE_VERSION(1, 0, 0);
11-
127
const WIDTH = 800;
138
const HEIGHT = 600;
149

@@ -27,6 +22,10 @@ var physicalDevice: c.VkPhysicalDevice = undefined;
2722
var global_device: c.VkDevice = undefined;
2823
var graphicsQueue: c.VkQueue = undefined;
2924
var presentQueue: c.VkQueue = undefined;
25+
var swapChainImages: []c.VkImage = undefined;
26+
var swapChain: c.VkSwapchainKHR = undefined;
27+
var swapChainImageFormat: c.VkFormat = undefined;
28+
var swapChainExtent: c.VkExtent2D = undefined;
3029

3130
const QueueFamilyIndices = struct {
3231
graphicsFamily: ?u32,
@@ -44,6 +43,28 @@ const QueueFamilyIndices = struct {
4443
}
4544
};
4645

46+
const SwapChainSupportDetails = struct {
47+
capabilities: c.VkSurfaceCapabilitiesKHR,
48+
formats: std.ArrayList(c.VkSurfaceFormatKHR),
49+
presentModes: std.ArrayList(c.VkPresentModeKHR),
50+
51+
fn init(allocator: *Allocator) SwapChainSupportDetails {
52+
var result = SwapChainSupportDetails{
53+
.capabilities = undefined,
54+
.formats = std.ArrayList(c.VkSurfaceFormatKHR).init(allocator),
55+
.presentModes = std.ArrayList(c.VkPresentModeKHR).init(allocator),
56+
};
57+
const slice = @sliceToBytes((*[1]c.VkSurfaceCapabilitiesKHR)(&result.capabilities)[0..1]);
58+
std.mem.set(u8, slice, 0);
59+
return result;
60+
}
61+
62+
fn deinit(self: *SwapChainSupportDetails) void {
63+
self.formats.deinit();
64+
self.presentModes.deinit();
65+
}
66+
};
67+
4768
pub fn main() !void {
4869
if (c.glfwInit() == 0) return error.GlfwInitFailed;
4970
defer c.glfwTerminate();
@@ -72,8 +93,8 @@ fn initVulkan(allocator: *Allocator, window: *c.GLFWwindow) !void {
7293
try createSurface(window);
7394
try pickPhysicalDevice(allocator);
7495
try createLogicalDevice(allocator);
96+
try createSwapChain(allocator);
7597
// TODO
76-
//createSwapChain();
7798
//createImageViews();
7899
//createRenderPass();
79100
//createGraphicsPipeline();
@@ -83,6 +104,110 @@ fn initVulkan(allocator: *Allocator, window: *c.GLFWwindow) !void {
83104
//createSyncObjects();
84105
}
85106

107+
fn chooseSwapSurfaceFormat(availableFormats: []c.VkSurfaceFormatKHR) c.VkSurfaceFormatKHR {
108+
if (availableFormats.len == 1 and availableFormats[0].format == c.VK_FORMAT_UNDEFINED) {
109+
return c.VkSurfaceFormatKHR{
110+
.format = c.VK_FORMAT_B8G8R8A8_UNORM,
111+
.colorSpace = c.VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
112+
};
113+
}
114+
115+
for (availableFormats) |availableFormat| {
116+
if (availableFormat.format == c.VK_FORMAT_B8G8R8A8_UNORM and
117+
availableFormat.colorSpace == c.VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
118+
{
119+
return availableFormat;
120+
}
121+
}
122+
123+
return availableFormats[0];
124+
}
125+
126+
fn chooseSwapPresentMode(availablePresentModes: []c.VkPresentModeKHR) c.VkPresentModeKHR {
127+
var bestMode: c.VkPresentModeKHR = c.VK_PRESENT_MODE_FIFO_KHR;
128+
129+
for (availablePresentModes) |availablePresentMode| {
130+
if (availablePresentMode == c.VK_PRESENT_MODE_MAILBOX_KHR) {
131+
return availablePresentMode;
132+
} else if (availablePresentMode == c.VK_PRESENT_MODE_IMMEDIATE_KHR) {
133+
bestMode = availablePresentMode;
134+
}
135+
}
136+
137+
return bestMode;
138+
}
139+
140+
fn chooseSwapExtent(capabilities: *const c.VkSurfaceCapabilitiesKHR) c.VkExtent2D {
141+
if (capabilities.currentExtent.width != @maxValue(u32)) {
142+
return capabilities.currentExtent;
143+
} else {
144+
var actualExtent = c.VkExtent2D{
145+
.width = WIDTH,
146+
.height = HEIGHT,
147+
};
148+
149+
actualExtent.width = std.math.max(capabilities.minImageExtent.width, std.math.min(capabilities.maxImageExtent.width, actualExtent.width));
150+
actualExtent.height = std.math.max(capabilities.minImageExtent.height, std.math.min(capabilities.maxImageExtent.height, actualExtent.height));
151+
152+
return actualExtent;
153+
}
154+
}
155+
156+
fn createSwapChain(allocator: *Allocator) !void {
157+
const swapChainSupport = try querySwapChainSupport(allocator, physicalDevice);
158+
159+
const surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats.toSlice());
160+
const presentMode = chooseSwapPresentMode(swapChainSupport.presentModes.toSlice());
161+
const extent = chooseSwapExtent(swapChainSupport.capabilities);
162+
163+
var imageCount: u32 = swapChainSupport.capabilities.minImageCount + 1;
164+
if (swapChainSupport.capabilities.maxImageCount > 0 and
165+
imageCount > swapChainSupport.capabilities.maxImageCount)
166+
{
167+
imageCount = swapChainSupport.capabilities.maxImageCount;
168+
}
169+
170+
const indices = try findQueueFamilies(allocator, physicalDevice);
171+
const queueFamilyIndices = []u32{ indices.graphicsFamily.?, indices.presentFamily.? };
172+
173+
const different_families = indices.graphicsFamily.? != indices.presentFamily.?;
174+
175+
var createInfo = c.VkSwapchainCreateInfoKHR{
176+
.sType = c.VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
177+
.surface = surface,
178+
179+
.minImageCount = imageCount,
180+
.imageFormat = surfaceFormat.format,
181+
.imageColorSpace = surfaceFormat.colorSpace,
182+
.imageExtent = extent,
183+
.imageArrayLayers = 1,
184+
.imageUsage = c.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
185+
186+
.imageSharingMode = if (different_families) c.VK_SHARING_MODE_CONCURRENT else c.VK_SHARING_MODE_EXCLUSIVE,
187+
.queueFamilyIndexCount = if (different_families) u32(2) else u32(0),
188+
.pQueueFamilyIndices = if (different_families) &queueFamilyIndices else &([]u32{ 0, 0 }),
189+
190+
.preTransform = swapChainSupport.capabilities.currentTransform,
191+
.compositeAlpha = c.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
192+
.presentMode = presentMode,
193+
.clipped = c.VK_TRUE,
194+
195+
.oldSwapchain = null,
196+
197+
.pNext = null,
198+
.flags = 0,
199+
};
200+
201+
try checkSuccess(c.vkCreateSwapchainKHR(global_device, &createInfo, null, &swapChain));
202+
203+
try checkSuccess(c.vkGetSwapchainImagesKHR(global_device, swapChain, &imageCount, null));
204+
swapChainImages = try allocator.alloc(c.VkImage, imageCount);
205+
try checkSuccess(c.vkGetSwapchainImagesKHR(global_device, swapChain, &imageCount, swapChainImages.ptr));
206+
207+
swapChainImageFormat = surfaceFormat.format;
208+
swapChainExtent = extent;
209+
}
210+
86211
fn createLogicalDevice(allocator: *Allocator) !void {
87212
const indices = try findQueueFamilies(allocator, physicalDevice);
88213

@@ -256,28 +381,6 @@ fn isDeviceSuitable(allocator: *Allocator, device: c.VkPhysicalDevice) !bool {
256381
return indices.isComplete() and extensionsSupported and swapChainAdequate;
257382
}
258383

259-
const SwapChainSupportDetails = struct {
260-
capabilities: c.VkSurfaceCapabilitiesKHR,
261-
formats: std.ArrayList(c.VkSurfaceFormatKHR),
262-
presentModes: std.ArrayList(c.VkPresentModeKHR),
263-
264-
fn init(allocator: *Allocator) SwapChainSupportDetails {
265-
var result = SwapChainSupportDetails{
266-
.capabilities = undefined,
267-
.formats = std.ArrayList(c.VkSurfaceFormatKHR).init(allocator),
268-
.presentModes = std.ArrayList(c.VkPresentModeKHR).init(allocator),
269-
};
270-
const slice = @sliceToBytes((*[1]c.VkSurfaceCapabilitiesKHR)(&result.capabilities)[0..1]);
271-
std.mem.set(u8, slice, 0);
272-
return result;
273-
}
274-
275-
fn deinit(self: *SwapChainSupportDetails) void {
276-
self.formats.deinit();
277-
self.presentModes.deinit();
278-
}
279-
};
280-
281384
fn querySwapChainSupport(allocator: *Allocator, device: c.VkPhysicalDevice) !SwapChainSupportDetails {
282385
var details = SwapChainSupportDetails.init(allocator);
283386
defer details.deinit();
@@ -385,10 +488,10 @@ fn createInstance(allocator: *Allocator) !void {
385488
const appInfo = c.VkApplicationInfo{
386489
.sType = c.VK_STRUCTURE_TYPE_APPLICATION_INFO,
387490
.pApplicationName = c"Hello Triangle",
388-
.applicationVersion = VK_MAKE_VERSION(1, 0, 0),
491+
.applicationVersion = c.VK_MAKE_VERSION(1, 0, 0),
389492
.pEngineName = c"No Engine",
390-
.engineVersion = VK_MAKE_VERSION(1, 0, 0),
391-
.apiVersion = VK_API_VERSION_1_0,
493+
.engineVersion = c.VK_MAKE_VERSION(1, 0, 0),
494+
.apiVersion = c.VK_API_VERSION_1_0,
392495
.pNext = null,
393496
};
394497

src/vulkan.zig

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1426,8 +1426,6 @@ pub const VK_SHARING_MODE_MAX_ENUM = enum_VkSharingMode.VK_SHARING_MODE_MAX_ENUM
14261426
pub const enum_VkSharingMode = extern enum {
14271427
VK_SHARING_MODE_EXCLUSIVE = 0,
14281428
VK_SHARING_MODE_CONCURRENT = 1,
1429-
VK_SHARING_MODE_BEGIN_RANGE = 0,
1430-
VK_SHARING_MODE_END_RANGE = 1,
14311429
VK_SHARING_MODE_RANGE_SIZE = 2,
14321430
VK_SHARING_MODE_MAX_ENUM = 2147483647,
14331431
};
@@ -2262,26 +2260,15 @@ pub const enum_VkFormatFeatureFlagBits = extern enum {
22622260
};
22632261
pub const VkFormatFeatureFlagBits = enum_VkFormatFeatureFlagBits;
22642262
pub const VkFormatFeatureFlags = VkFlags;
2265-
pub const VK_IMAGE_USAGE_TRANSFER_SRC_BIT = enum_VkImageUsageFlagBits.VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2266-
pub const VK_IMAGE_USAGE_TRANSFER_DST_BIT = enum_VkImageUsageFlagBits.VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2267-
pub const VK_IMAGE_USAGE_SAMPLED_BIT = enum_VkImageUsageFlagBits.VK_IMAGE_USAGE_SAMPLED_BIT;
2268-
pub const VK_IMAGE_USAGE_STORAGE_BIT = enum_VkImageUsageFlagBits.VK_IMAGE_USAGE_STORAGE_BIT;
2269-
pub const VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT = enum_VkImageUsageFlagBits.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2270-
pub const VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = enum_VkImageUsageFlagBits.VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
2271-
pub const VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = enum_VkImageUsageFlagBits.VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
2272-
pub const VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = enum_VkImageUsageFlagBits.VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
2273-
pub const VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = enum_VkImageUsageFlagBits.VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM;
2274-
pub const enum_VkImageUsageFlagBits = extern enum {
2275-
VK_IMAGE_USAGE_TRANSFER_SRC_BIT = 1,
2276-
VK_IMAGE_USAGE_TRANSFER_DST_BIT = 2,
2277-
VK_IMAGE_USAGE_SAMPLED_BIT = 4,
2278-
VK_IMAGE_USAGE_STORAGE_BIT = 8,
2279-
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT = 16,
2280-
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 32,
2281-
VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 64,
2282-
VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 128,
2283-
VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 2147483647,
2284-
};
2263+
pub const VK_IMAGE_USAGE_TRANSFER_SRC_BIT = 1;
2264+
pub const VK_IMAGE_USAGE_TRANSFER_DST_BIT = 2;
2265+
pub const VK_IMAGE_USAGE_SAMPLED_BIT = 4;
2266+
pub const VK_IMAGE_USAGE_STORAGE_BIT = 8;
2267+
pub const VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT = 16;
2268+
pub const VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 32;
2269+
pub const VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 64;
2270+
pub const VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 128;
2271+
pub const enum_VkImageUsageFlagBits = c_int;
22852272
pub const VkImageUsageFlagBits = enum_VkImageUsageFlagBits;
22862273
pub const VkImageUsageFlags = VkFlags;
22872274
pub const VK_IMAGE_CREATE_SPARSE_BINDING_BIT = enum_VkImageCreateFlagBits.VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
@@ -5319,9 +5306,9 @@ pub const PFN_vkGetDeviceGroupPresentCapabilitiesKHR = ?extern fn (VkDevice, ?[*
53195306
pub const PFN_vkGetDeviceGroupSurfacePresentModesKHR = ?extern fn (VkDevice, VkSurfaceKHR, ?[*]VkDeviceGroupPresentModeFlagsKHR) VkResult;
53205307
pub const PFN_vkGetPhysicalDevicePresentRectanglesKHR = ?extern fn (VkPhysicalDevice, VkSurfaceKHR, ?[*]u32, ?[*]VkRect2D) VkResult;
53215308
pub const PFN_vkAcquireNextImage2KHR = ?extern fn (VkDevice, ?[*]const VkAcquireNextImageInfoKHR, ?[*]u32) VkResult;
5322-
pub extern fn vkCreateSwapchainKHR(device: VkDevice, pCreateInfo: ?[*]const VkSwapchainCreateInfoKHR, pAllocator: ?[*]const VkAllocationCallbacks, pSwapchain: ?[*]VkSwapchainKHR) VkResult;
5309+
pub extern fn vkCreateSwapchainKHR(device: VkDevice, pCreateInfo: *const VkSwapchainCreateInfoKHR, pAllocator: ?[*]const VkAllocationCallbacks, pSwapchain: *VkSwapchainKHR) VkResult;
53235310
pub extern fn vkDestroySwapchainKHR(device: VkDevice, swapchain: VkSwapchainKHR, pAllocator: ?[*]const VkAllocationCallbacks) void;
5324-
pub extern fn vkGetSwapchainImagesKHR(device: VkDevice, swapchain: VkSwapchainKHR, pSwapchainImageCount: ?[*]u32, pSwapchainImages: ?[*]VkImage) VkResult;
5311+
pub extern fn vkGetSwapchainImagesKHR(device: VkDevice, swapchain: VkSwapchainKHR, pSwapchainImageCount: *u32, pSwapchainImages: ?[*]VkImage) VkResult;
53255312
pub extern fn vkAcquireNextImageKHR(device: VkDevice, swapchain: VkSwapchainKHR, timeout: u64, semaphore: VkSemaphore, fence: VkFence, pImageIndex: ?[*]u32) VkResult;
53265313
pub extern fn vkQueuePresentKHR(queue: VkQueue, pPresentInfo: ?[*]const VkPresentInfoKHR) VkResult;
53275314
pub extern fn vkGetDeviceGroupPresentCapabilitiesKHR(device: VkDevice, pDeviceGroupPresentCapabilities: ?[*]VkDeviceGroupPresentCapabilitiesKHR) VkResult;
@@ -7175,7 +7162,9 @@ pub extern fn glfwGetRequiredInstanceExtensions(count: *u32) [*]const [*]const u
71757162
pub extern fn glfwGetInstanceProcAddress(instance: VkInstance, procname: ?[*]const u8) GLFWvkproc;
71767163
pub extern fn glfwGetPhysicalDevicePresentationSupport(instance: VkInstance, device: VkPhysicalDevice, queuefamily: u32) c_int;
71777164
pub extern fn glfwCreateWindowSurface(instance: VkInstance, window: *GLFWwindow, allocator: ?*const VkAllocationCallbacks, surface: *VkSurfaceKHR) VkResult;
7178-
pub fn zig_VK_MAKE_VERSION(major: u32, minor: u32, patch: u32) u32 {
7165+
pub const VK_API_VERSION_1_0 = VK_MAKE_VERSION(1, 0, 0);
7166+
7167+
pub fn VK_MAKE_VERSION(major: u32, minor: u32, patch: u32) u32 {
71797168
return ((major << u5(22)) | (minor << u5(12))) | patch;
71807169
}
71817170
pub const __BIGGEST_ALIGNMENT__ = 16;

0 commit comments

Comments
 (0)