@@ -4,11 +4,6 @@ const mem = std.mem;
4
4
const Allocator = mem .Allocator ;
5
5
const c = @import ("vulkan.zig" );
6
6
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
-
12
7
const WIDTH = 800 ;
13
8
const HEIGHT = 600 ;
14
9
@@ -27,6 +22,10 @@ var physicalDevice: c.VkPhysicalDevice = undefined;
27
22
var global_device : c.VkDevice = undefined ;
28
23
var graphicsQueue : c.VkQueue = undefined ;
29
24
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 ;
30
29
31
30
const QueueFamilyIndices = struct {
32
31
graphicsFamily : ? u32 ,
@@ -44,6 +43,28 @@ const QueueFamilyIndices = struct {
44
43
}
45
44
};
46
45
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
+
47
68
pub fn main () ! void {
48
69
if (c .glfwInit () == 0 ) return error .GlfwInitFailed ;
49
70
defer c .glfwTerminate ();
@@ -72,8 +93,8 @@ fn initVulkan(allocator: *Allocator, window: *c.GLFWwindow) !void {
72
93
try createSurface (window );
73
94
try pickPhysicalDevice (allocator );
74
95
try createLogicalDevice (allocator );
96
+ try createSwapChain (allocator );
75
97
// TODO
76
- //createSwapChain();
77
98
//createImageViews();
78
99
//createRenderPass();
79
100
//createGraphicsPipeline();
@@ -83,6 +104,110 @@ fn initVulkan(allocator: *Allocator, window: *c.GLFWwindow) !void {
83
104
//createSyncObjects();
84
105
}
85
106
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
+
86
211
fn createLogicalDevice (allocator : * Allocator ) ! void {
87
212
const indices = try findQueueFamilies (allocator , physicalDevice );
88
213
@@ -256,28 +381,6 @@ fn isDeviceSuitable(allocator: *Allocator, device: c.VkPhysicalDevice) !bool {
256
381
return indices .isComplete () and extensionsSupported and swapChainAdequate ;
257
382
}
258
383
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
-
281
384
fn querySwapChainSupport (allocator : * Allocator , device : c.VkPhysicalDevice ) ! SwapChainSupportDetails {
282
385
var details = SwapChainSupportDetails .init (allocator );
283
386
defer details .deinit ();
@@ -385,10 +488,10 @@ fn createInstance(allocator: *Allocator) !void {
385
488
const appInfo = c.VkApplicationInfo {
386
489
.sType = c .VK_STRUCTURE_TYPE_APPLICATION_INFO ,
387
490
.pApplicationName = c"Hello Triangle" ,
388
- .applicationVersion = VK_MAKE_VERSION (1 , 0 , 0 ),
491
+ .applicationVersion = c . VK_MAKE_VERSION (1 , 0 , 0 ),
389
492
.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 ,
392
495
.pNext = null ,
393
496
};
394
497
0 commit comments