13
13
#include < optional>
14
14
#include < stdexcept>
15
15
16
-
17
16
class HelloTriangleApplication {
18
17
public:
19
18
void run () {
@@ -26,20 +25,20 @@ class HelloTriangleApplication {
26
25
private:
27
26
// ///////////////////////////////////////////////////////////////
28
27
// / static values
29
- static const uint32_t WIDTH = 800 ;
30
- static const uint32_t HEIGHT = 600 ;
28
+ static constexpr uint32_t WIDTH = 800 ;
29
+ static constexpr uint32_t HEIGHT = 600 ;
31
30
32
- static constexpr std::array <const char *, 1 > validationLayers {
31
+ inline static const std::vector <const char *> validationLayers {
33
32
" VK_LAYER_KHRONOS_validation"
34
33
};
35
- static constexpr std::array <const char *, 1 > deviceExtensions {
34
+ inline static const std::vector <const char *> deviceExtensions {
36
35
VK_KHR_SWAPCHAIN_EXTENSION_NAME
37
36
};
38
37
39
38
#ifdef NDEBUG
40
- static const bool enableValidationLayers = false ;
39
+ static constexpr bool enableValidationLayers = false ;
41
40
#else
42
- static const bool enableValidationLayers = true ;
41
+ static constexpr bool enableValidationLayers = true ;
43
42
#endif
44
43
// ///////////////////////////////////////////////////////////////
45
44
@@ -61,19 +60,15 @@ class HelloTriangleApplication {
61
60
std::vector<vk::raii::ImageView> m_swapChainImageViews;
62
61
vk::raii::PipelineLayout m_pipelineLayout{ nullptr };
63
62
// ///////////////////////////////////////////////////////////////
64
-
63
+
65
64
// ///////////////////////////////////////////////////////////////
66
65
// / run()
67
66
void initWindow () {
68
- // initialize glfw lib
69
67
glfwInit ();
70
-
71
- // Configure GLFW to not use OpenGL
68
+
72
69
glfwWindowHint (GLFW_CLIENT_API, GLFW_NO_API);
73
- // Temporarily disable window resizing to simplify operations
74
70
glfwWindowHint (GLFW_RESIZABLE, GLFW_FALSE);
75
-
76
- // Create window
71
+
77
72
m_window = glfwCreateWindow (WIDTH, HEIGHT, " Vulkan" , nullptr , nullptr );
78
73
}
79
74
@@ -101,7 +96,7 @@ class HelloTriangleApplication {
101
96
// ///////////////////////////////////////////////////////////////
102
97
103
98
// ///////////////////////////////////////////////////////////////
104
- // / create instance
99
+ // / instance creation
105
100
std::vector<const char *> getRequiredExtensions () {
106
101
uint32_t glfwExtensionCount = 0 ;
107
102
const char ** glfwExtensions;
@@ -116,7 +111,6 @@ class HelloTriangleApplication {
116
111
117
112
return extensions;
118
113
}
119
-
120
114
void createInstance (){
121
115
if (enableValidationLayers && !checkValidationLayerSupport ()) {
122
116
throw std::runtime_error (" validation layers requested, but not available!" );
@@ -129,20 +123,12 @@ class HelloTriangleApplication {
129
123
1 , // engineVersion
130
124
VK_API_VERSION_1_1 // apiVersion
131
125
);
132
-
126
+
133
127
vk::InstanceCreateInfo createInfo (
134
128
{}, // vk::InstanceCreateFlags
135
129
&applicationInfo // vk::ApplicationInfo*
136
130
);
137
131
138
- // std::vector<vk::ExtensionProperties>
139
- auto extensions = m_context.enumerateInstanceExtensionProperties ();
140
- std::cout << " available extensions:\n " ;
141
-
142
- for (const auto & extension : extensions) {
143
- std::cout << ' \t ' << extension.extensionName << std::endl;
144
- }
145
-
146
132
std::vector<const char *> requiredExtensions = getRequiredExtensions ();
147
133
// special setter
148
134
createInfo.setPEnabledExtensionNames ( requiredExtensions );
@@ -155,6 +141,13 @@ class HelloTriangleApplication {
155
141
createInfo.pNext = &debugMessengerCreateInfo;
156
142
}
157
143
144
+ auto extensions = m_context.enumerateInstanceExtensionProperties ();
145
+ std::cout << " available extensions:\n " ;
146
+
147
+ for (const auto & extension : extensions) {
148
+ std::cout << ' \t ' << extension.extensionName << std::endl;
149
+ }
150
+
158
151
m_instance = m_context.createInstance ( createInfo );
159
152
}
160
153
// ///////////////////////////////////////////////////////////////
@@ -202,6 +195,14 @@ class HelloTriangleApplication {
202
195
203
196
// ///////////////////////////////////////////////////////////////
204
197
// / physical device
198
+ struct QueueFamilyIndices {
199
+ std::optional<uint32_t > graphicsFamily;
200
+ std::optional<uint32_t > presentFamily;
201
+
202
+ bool isComplete () {
203
+ return graphicsFamily.has_value () && presentFamily.has_value ();
204
+ }
205
+ };
205
206
bool checkDeviceExtensionSupport (const vk::raii::PhysicalDevice& physicalDevice) {
206
207
// std::vector<vk::ExtensionProperties>
207
208
auto availableExtensions = physicalDevice.enumerateDeviceExtensionProperties ();
@@ -241,20 +242,11 @@ class HelloTriangleApplication {
241
242
throw std::runtime_error (" failed to find a suitable GPU!" );
242
243
}
243
244
}
244
- struct QueueFamilyIndices {
245
- std::optional<uint32_t > graphicsFamily;
246
- std::optional<uint32_t > presentFamily;
247
-
248
- bool isComplete () {
249
- return graphicsFamily.has_value () && presentFamily.has_value ();
250
- }
251
- };
252
245
QueueFamilyIndices findQueueFamilies (const vk::raii::PhysicalDevice& physicalDevice) {
253
246
QueueFamilyIndices indices;
254
247
255
248
// std::vector<vk::QueueFamilyProperties>
256
249
auto queueFamilies = physicalDevice.getQueueFamilyProperties ();
257
-
258
250
for (int i = 0 ; const auto & queueFamily : queueFamilies) {
259
251
if (queueFamily.queueFlags & vk::QueueFlagBits::eGraphics) {
260
252
indices.graphicsFamily = i;
@@ -272,7 +264,7 @@ class HelloTriangleApplication {
272
264
return indices;
273
265
}
274
266
// ///////////////////////////////////////////////////////////////
275
-
267
+
276
268
// ///////////////////////////////////////////////////////////////
277
269
// / logical device
278
270
void createLogicalDevice () {
@@ -284,12 +276,10 @@ class HelloTriangleApplication {
284
276
285
277
float queuePriority = 1 .0f ;
286
278
for (uint32_t queueFamily : uniqueQueueFamilies) {
287
- queueCreateInfos.emplace_back ( vk::DeviceQueueCreateInfo (
288
- {}, // flags
289
- indices.graphicsFamily .value (), // queueFamilyIndex
290
- 1 , // queueCount
291
- &queuePriority
292
- ));
279
+ vk::DeviceQueueCreateInfo queueCreateInfo;
280
+ queueCreateInfo.queueFamilyIndex = queueFamily;
281
+ queueCreateInfo.setQueuePriorities ( queuePriority );
282
+ queueCreateInfos.emplace_back ( queueCreateInfo );
293
283
}
294
284
295
285
vk::PhysicalDeviceFeatures deviceFeatures;
@@ -298,12 +288,12 @@ class HelloTriangleApplication {
298
288
createInfo.setQueueCreateInfos ( queueCreateInfos );
299
289
createInfo.pEnabledFeatures = &deviceFeatures;
300
290
291
+ createInfo.setPEnabledExtensionNames ( deviceExtensions );
292
+
301
293
if (enableValidationLayers) {
302
294
createInfo.setPEnabledLayerNames ( validationLayers );
303
295
}
304
296
305
- createInfo.setPEnabledExtensionNames ( deviceExtensions );
306
-
307
297
m_device = m_physicalDevice.createDevice ( createInfo );
308
298
m_graphicsQueue = m_device.getQueue ( indices.graphicsFamily .value (), 0 );
309
299
m_presentQueue = m_device.getQueue ( indices.presentFamily .value (), 0 );
@@ -381,22 +371,19 @@ class HelloTriangleApplication {
381
371
vk::Extent2D extent = chooseSwapExtent ( swapChainSupport.capabilities );
382
372
383
373
uint32_t imageCount = swapChainSupport.capabilities .minImageCount + 1 ;
384
-
385
374
if (swapChainSupport.capabilities .maxImageCount > 0 &&
386
375
imageCount > swapChainSupport.capabilities .maxImageCount ) {
387
376
imageCount = swapChainSupport.capabilities .maxImageCount ;
388
377
}
389
378
390
- vk::SwapchainCreateInfoKHR createInfo (
391
- {}, // flags
392
- m_surface, // vk::Surface
393
- imageCount, // minImageCount
394
- surfaceFormat.format , // Format
395
- surfaceFormat.colorSpace , // ColorSpaceKHR
396
- extent, // Extent2D
397
- 1 , // imageArrayLayers
398
- vk::ImageUsageFlagBits::eColorAttachment // imageUsage
399
- );
379
+ vk::SwapchainCreateInfoKHR createInfo;
380
+ createInfo.surface = m_surface;
381
+ createInfo.minImageCount = imageCount;
382
+ createInfo.imageFormat = surfaceFormat.format ;
383
+ createInfo.imageColorSpace = surfaceFormat.colorSpace ;
384
+ createInfo.imageExtent = extent;
385
+ createInfo.imageArrayLayers = 1 ;
386
+ createInfo.imageUsage = vk::ImageUsageFlagBits::eColorAttachment;
400
387
401
388
QueueFamilyIndices indices = findQueueFamilies ( m_physicalDevice );
402
389
std::vector<uint32_t > queueFamilyIndices { indices.graphicsFamily .value (), indices.presentFamily .value () };
@@ -426,12 +413,10 @@ class HelloTriangleApplication {
426
413
void createImageViews () {
427
414
m_swapChainImageViews.reserve ( m_swapChainImages.size () );
428
415
for (size_t i = 0 ; i < m_swapChainImages.size (); i++) {
429
- vk::ImageViewCreateInfo createInfo (
430
- {}, // flags
431
- m_swapChainImages[i], // vk::Image
432
- vk::ImageViewType::e2D, // ImageViewType
433
- m_swapChainImageFormat // format
434
- );
416
+ vk::ImageViewCreateInfo createInfo;
417
+ createInfo.image = m_swapChainImages[i];
418
+ createInfo.viewType = vk::ImageViewType::e2D;
419
+ createInfo.format = m_swapChainImageFormat;
435
420
createInfo.subresourceRange .aspectMask = vk::ImageAspectFlagBits::eColor;
436
421
createInfo.subresourceRange .baseMipLevel = 0 ;
437
422
createInfo.subresourceRange .levelCount = 1 ;
@@ -451,23 +436,20 @@ class HelloTriangleApplication {
451
436
if (!file.is_open ()) {
452
437
throw std::runtime_error (" failed to open file!" );
453
438
}
454
-
455
439
size_t fileSize = (size_t ) file.tellg ();
456
440
std::vector<char > buffer (fileSize);
441
+
457
442
file.seekg (0 );
458
443
file.read (buffer.data (), fileSize);
459
444
file.close ();
460
445
461
446
return buffer;
462
447
}
463
448
vk::raii::ShaderModule createShaderModule (const std::vector<char >& code) {
464
- vk::ShaderModuleCreateInfo createInfo (
465
- {}, // flags
466
- code.size (), // codeSize
467
- reinterpret_cast <const uint32_t *>(code.data ()) // pCode
468
- );
469
-
470
- return m_device.createShaderModule ( createInfo );
449
+ vk::ShaderModuleCreateInfo createInfo;
450
+ createInfo.codeSize = code.size ();
451
+ createInfo.pCode = reinterpret_cast <const uint32_t *>(code.data ());
452
+ return m_device.createShaderModule (createInfo);
471
453
}
472
454
void createGraphicsPipeline () {
473
455
auto vertShaderCode = readFile (" shaders/vert.spv" );
@@ -476,22 +458,18 @@ class HelloTriangleApplication {
476
458
vk::raii::ShaderModule vertShaderModule = createShaderModule (vertShaderCode);
477
459
vk::raii::ShaderModule fragShaderModule = createShaderModule (fragShaderCode);
478
460
479
- vk::PipelineShaderStageCreateInfo vertShaderStageInfo (
480
- {}, // flags
481
- vk::ShaderStageFlagBits::eVertex, // stage
482
- vertShaderModule, // ShaderModule
483
- " main" // pName
484
- );
461
+ vk::PipelineShaderStageCreateInfo vertShaderStageInfo;
462
+ vertShaderStageInfo.stage = vk::ShaderStageFlagBits::eVertex;
463
+ vertShaderStageInfo.module = vertShaderModule;
464
+ vertShaderStageInfo.pName = " main" ;
485
465
486
- vk::PipelineShaderStageCreateInfo fragShaderStageInfo (
487
- {}, // flags
488
- vk::ShaderStageFlagBits::eFragment, // stage
489
- fragShaderModule, // ShaderModule
490
- " main" // pName
491
- );
466
+ vk::PipelineShaderStageCreateInfo fragShaderStageInfo;
467
+ fragShaderStageInfo.stage = vk::ShaderStageFlagBits::eFragment;
468
+ fragShaderStageInfo.module = fragShaderModule;
469
+ fragShaderStageInfo.pName = " main" ;
492
470
493
471
std::vector<vk::PipelineShaderStageCreateInfo> shaderStages{ vertShaderStageInfo, fragShaderStageInfo };
494
-
472
+
495
473
std::vector<vk::DynamicState> dynamicStates = {
496
474
vk::DynamicState::eViewport,
497
475
vk::DynamicState::eScissor
@@ -502,27 +480,13 @@ class HelloTriangleApplication {
502
480
503
481
vk::PipelineVertexInputStateCreateInfo vertexInputInfo;
504
482
505
- vk::PipelineInputAssemblyStateCreateInfo inputAssembly (
506
- {}, // flags
507
- vk::PrimitiveTopology::eTriangleList, // topology
508
- false // primitiveRestartEnable - default false
509
- );
510
-
511
- vk::Viewport viewport (
512
- 0 .0f , 0 .0f , // x y
513
- static_cast <float >(m_swapChainExtent.width ), // width
514
- static_cast <float >(m_swapChainExtent.height ), // height
515
- 0 .0f , 1 .0f // minDepth maxDepth
516
- );
517
-
518
- vk::Rect2D scissor (
519
- {0 , 0 }, // offset
520
- m_swapChainExtent // Extent2D
521
- );
483
+ vk::PipelineInputAssemblyStateCreateInfo inputAssembly;
484
+ inputAssembly.topology = vk::PrimitiveTopology::eTriangleList;
485
+ inputAssembly.primitiveRestartEnable = false ; // default
522
486
523
487
vk::PipelineViewportStateCreateInfo viewportState;
524
- viewportState.setViewports ( viewport ) ;
525
- viewportState.setScissors ( scissor ) ;
488
+ viewportState.viewportCount = 1 ;
489
+ viewportState.scissorCount = 1 ;
526
490
527
491
vk::PipelineRasterizationStateCreateInfo rasterizer;
528
492
rasterizer.depthClampEnable = false ;
@@ -533,23 +497,16 @@ class HelloTriangleApplication {
533
497
rasterizer.frontFace = vk::FrontFace::eClockwise;
534
498
rasterizer.depthBiasEnable = false ;
535
499
536
- vk::PipelineMultisampleStateCreateInfo multisampling (
537
- {}, // flags
538
- vk::SampleCountFlagBits::e1 , // rasterizationSamples
539
- false // sampleShadingEnable
540
- );
500
+ vk::PipelineMultisampleStateCreateInfo multisampling;
501
+ multisampling.rasterizationSamples = vk::SampleCountFlagBits::e1 ;
502
+ multisampling.sampleShadingEnable = false ; // default
541
503
542
- vk::PipelineColorBlendAttachmentState colorBlendAttachment (
543
- false , // blendEnable
544
- vk::BlendFactor::eOne, // srcColorBlendFactor - optional
545
- vk::BlendFactor::eZero, // dstColorBlendFactor - optional
546
- vk::BlendOp::eAdd, // colorBlendOp - optional
547
- vk::BlendFactor::eOne, // srcAlphaBlendFactor - optional
548
- vk::BlendFactor::eZero, // dstAlphaBlendFactor - optional
549
- vk::BlendOp::eAdd, // alphaBlendOp - optional
550
- vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG |
504
+ vk::PipelineColorBlendAttachmentState colorBlendAttachment;
505
+ colorBlendAttachment.blendEnable = false ; // default
506
+ // colorBlendAttachment.colorWriteMask = vk::FlagTraits<vk::ColorComponentFlagBits>::allFlags;
507
+ colorBlendAttachment.colorWriteMask = (
508
+ vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG |
551
509
vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA
552
- // colorWriteMask - default is RGBA
553
510
);
554
511
555
512
vk::PipelineColorBlendStateCreateInfo colorBlending;
0 commit comments