2
2
// Created by Piasy on 26/06/2017.
3
3
//
4
4
5
+ #include < set>
6
+ #include < algorithm>
7
+ #include < stdexcept>
8
+ #include < cstring>
9
+ #include < functional>
10
+
5
11
#include " vulkan_triangle.h"
6
12
7
13
const int WIDTH = 800 ;
@@ -215,14 +221,20 @@ void HelloTriangleApplication::initVulkan() {
215
221
createLogicalDevice ();
216
222
createSwapchain ();
217
223
createImageViews ();
224
+ createRenderPass ();
225
+ createGraphicsPipeline ();
218
226
}
219
227
220
228
void HelloTriangleApplication::mainLoop () {
221
229
222
230
}
223
231
224
232
void HelloTriangleApplication::cleanUp () {
225
- for (const auto & imageView : swapchainImageViews) {
233
+ vkDestroyPipeline (device, graphicsPipeline, nullptr );
234
+ vkDestroyPipelineLayout (device, pipelineLayout, nullptr );
235
+ vkDestroyRenderPass (device, renderPass, nullptr );
236
+
237
+ for (const auto &imageView : swapchainImageViews) {
226
238
vkDestroyImageView (device, imageView, nullptr );
227
239
}
228
240
@@ -412,8 +424,8 @@ void HelloTriangleApplication::createSwapchain() {
412
424
swapchainImages.resize (imageCount);
413
425
vkGetSwapchainImagesKHR (device, swapchain, &imageCount, swapchainImages.data ());
414
426
415
- swapChainImageFormat = surfaceFormat.format ;
416
- swapChainExtent = extent;
427
+ swapchainImageFormat = surfaceFormat.format ;
428
+ swapchainExtent = extent;
417
429
}
418
430
419
431
void HelloTriangleApplication::createImageViews () {
@@ -424,7 +436,7 @@ void HelloTriangleApplication::createImageViews() {
424
436
createInfo.image = swapchainImages[i];
425
437
426
438
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
427
- createInfo.format = swapChainImageFormat ;
439
+ createInfo.format = swapchainImageFormat ;
428
440
429
441
createInfo.components .r = VK_COMPONENT_SWIZZLE_IDENTITY;
430
442
createInfo.components .g = VK_COMPONENT_SWIZZLE_IDENTITY;
@@ -444,6 +456,184 @@ void HelloTriangleApplication::createImageViews() {
444
456
}
445
457
}
446
458
459
+ void HelloTriangleApplication::createRenderPass () {
460
+ VkAttachmentDescription colorAttachment = {};
461
+ colorAttachment.format = swapchainImageFormat;
462
+ colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
463
+ colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
464
+ colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
465
+ colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
466
+ colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
467
+ colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
468
+ colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
469
+
470
+ VkAttachmentReference colorAttachmentRef = {};
471
+ colorAttachmentRef.attachment = 0 ;
472
+ colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
473
+
474
+ VkSubpassDescription subpass = {};
475
+ subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
476
+ subpass.colorAttachmentCount = 1 ;
477
+ subpass.pColorAttachments = &colorAttachmentRef;
478
+
479
+ VkRenderPassCreateInfo renderPassInfo = {};
480
+ renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
481
+ renderPassInfo.attachmentCount = 1 ;
482
+ renderPassInfo.pAttachments = &colorAttachment;
483
+ renderPassInfo.subpassCount = 1 ;
484
+ renderPassInfo.pSubpasses = &subpass;
485
+
486
+ if (vkCreateRenderPass (device, &renderPassInfo, nullptr , &renderPass) != VK_SUCCESS) {
487
+ throw std::runtime_error (" failed to create render pass!" );
488
+ }
489
+ }
490
+
491
+ void HelloTriangleApplication::createGraphicsPipeline () {
492
+ auto vertexShaderCode = readAsset (vertexShader);
493
+ auto fragmentShaderCode = readAsset (fragmentShader);
494
+
495
+ VkShaderModule vertexShaderModule = createShaderModule (vertexShaderCode);
496
+ VkShaderModule fragmentShaderModule = createShaderModule (fragmentShaderCode);
497
+
498
+ VkPipelineShaderStageCreateInfo vertexShaderStageInfo = {};
499
+ vertexShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
500
+ vertexShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
501
+ vertexShaderStageInfo.module = vertexShaderModule;
502
+ vertexShaderStageInfo.pName = " main" ;
503
+
504
+ VkPipelineShaderStageCreateInfo fragmentShaderStageInfo = {};
505
+ fragmentShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
506
+ fragmentShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
507
+ fragmentShaderStageInfo.module = fragmentShaderModule;
508
+ fragmentShaderStageInfo.pName = " main" ;
509
+
510
+ VkPipelineShaderStageCreateInfo shaderStages[] = {
511
+ vertexShaderStageInfo, fragmentShaderStageInfo
512
+ };
513
+
514
+ VkPipelineVertexInputStateCreateInfo vertexInputInfo = {};
515
+ vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
516
+ vertexInputInfo.vertexBindingDescriptionCount = 0 ;
517
+ vertexInputInfo.vertexAttributeDescriptionCount = 0 ;
518
+
519
+ VkPipelineInputAssemblyStateCreateInfo inputAssembly = {};
520
+ inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
521
+ inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
522
+ inputAssembly.primitiveRestartEnable = VK_FALSE;
523
+
524
+ VkViewport viewport = {};
525
+ viewport.x = 0 .0f ;
526
+ viewport.y = 0 .0f ;
527
+ viewport.width = (float ) swapchainExtent.width ;
528
+ viewport.height = (float ) swapchainExtent.height ;
529
+ viewport.minDepth = 0 .0f ;
530
+ viewport.maxDepth = 1 .0f ;
531
+
532
+ VkRect2D scissor = {};
533
+ scissor.offset = {0 , 0 };
534
+ scissor.extent = swapchainExtent;
535
+
536
+ VkPipelineViewportStateCreateInfo viewportState = {};
537
+ viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
538
+ viewportState.viewportCount = 1 ;
539
+ viewportState.pViewports = &viewport;
540
+ viewportState.scissorCount = 1 ;
541
+ viewportState.pScissors = &scissor;
542
+
543
+ VkPipelineRasterizationStateCreateInfo rasterizer = {};
544
+ rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
545
+ rasterizer.depthClampEnable = VK_FALSE;
546
+ rasterizer.rasterizerDiscardEnable = VK_FALSE;
547
+ rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
548
+ rasterizer.lineWidth = 1 .0f ;
549
+ rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
550
+ rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;
551
+ rasterizer.depthBiasEnable = VK_FALSE;
552
+
553
+ VkPipelineMultisampleStateCreateInfo multisampling = {};
554
+ multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
555
+ multisampling.sampleShadingEnable = VK_FALSE;
556
+ multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
557
+
558
+ VkPipelineColorBlendAttachmentState colorBlendAttachment = {};
559
+ colorBlendAttachment.colorWriteMask =
560
+ VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT |
561
+ VK_COLOR_COMPONENT_A_BIT;
562
+ colorBlendAttachment.blendEnable = VK_FALSE;
563
+
564
+ VkPipelineColorBlendStateCreateInfo colorBlending = {};
565
+ colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
566
+ colorBlending.logicOpEnable = VK_FALSE;
567
+ colorBlending.logicOp = VK_LOGIC_OP_COPY;
568
+ colorBlending.attachmentCount = 1 ;
569
+ colorBlending.pAttachments = &colorBlendAttachment;
570
+ colorBlending.blendConstants [0 ] = 0 .0f ;
571
+ colorBlending.blendConstants [1 ] = 0 .0f ;
572
+ colorBlending.blendConstants [2 ] = 0 .0f ;
573
+ colorBlending.blendConstants [3 ] = 0 .0f ;
574
+
575
+ VkPipelineLayoutCreateInfo pipelineLayoutInfo = {};
576
+ pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
577
+ pipelineLayoutInfo.setLayoutCount = 0 ;
578
+ pipelineLayoutInfo.pushConstantRangeCount = 0 ;
579
+
580
+ if (vkCreatePipelineLayout (device, &pipelineLayoutInfo, nullptr , &pipelineLayout) !=
581
+ VK_SUCCESS) {
582
+ throw std::runtime_error (" failed to create pipeline layout!" );
583
+ }
584
+
585
+ VkGraphicsPipelineCreateInfo pipelineInfo = {};
586
+ pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
587
+ pipelineInfo.stageCount = 2 ;
588
+ pipelineInfo.pStages = shaderStages;
589
+ pipelineInfo.pVertexInputState = &vertexInputInfo;
590
+ pipelineInfo.pInputAssemblyState = &inputAssembly;
591
+ pipelineInfo.pViewportState = &viewportState;
592
+ pipelineInfo.pRasterizationState = &rasterizer;
593
+ pipelineInfo.pMultisampleState = &multisampling;
594
+ pipelineInfo.pColorBlendState = &colorBlending;
595
+ pipelineInfo.layout = pipelineLayout;
596
+ pipelineInfo.renderPass = renderPass;
597
+ pipelineInfo.subpass = 0 ;
598
+ pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
599
+
600
+ if (vkCreateGraphicsPipelines (device, VK_NULL_HANDLE, 1 , &pipelineInfo, nullptr ,
601
+ &graphicsPipeline) != VK_SUCCESS) {
602
+ throw std::runtime_error (" failed to create graphics pipeline!" );
603
+ }
604
+
605
+ vkDestroyShaderModule (device, vertexShaderModule, nullptr );
606
+ vkDestroyShaderModule (device, fragmentShaderModule, nullptr );
607
+ }
608
+
609
+ std::vector<char > HelloTriangleApplication::readAsset (const char *name) {
610
+ AAsset *file = AAssetManager_open (assetManager, name, AASSET_MODE_BUFFER);
611
+ size_t len = AAsset_getLength (file);
612
+ std::vector<char > buffer (len);
613
+
614
+ AAsset_read (file, buffer.data (), len);
615
+
616
+ AAsset_close (file);
617
+
618
+ LOGI (" read asset %s, length %d" , name, len);
619
+
620
+ return buffer;
621
+ }
622
+
623
+ VkShaderModule HelloTriangleApplication::createShaderModule (const std::vector<char > &code) {
624
+ VkShaderModuleCreateInfo createInfo = {};
625
+ createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
626
+ createInfo.codeSize = code.size ();
627
+ createInfo.pCode = reinterpret_cast <const uint32_t *>(code.data ());
628
+
629
+ VkShaderModule shaderModule;
630
+ if (vkCreateShaderModule (device, &createInfo, nullptr , &shaderModule) != VK_SUCCESS) {
631
+ throw std::runtime_error (" failed to create shader module!" );
632
+ }
633
+
634
+ return shaderModule;
635
+ }
636
+
447
637
bool HelloTriangleApplication::isDeviceSuitable (VkPhysicalDevice device) {
448
638
bool extensionsSupported = checkDeviceExtensionSupport (device);
449
639
@@ -531,26 +721,3 @@ SwapchainSupportDetails HelloTriangleApplication::querySwapchainSupport(VkPhysic
531
721
532
722
return details;
533
723
}
534
-
535
- extern " C" {
536
- JNIEXPORT void JNICALL
537
- Java_com_github_piasy_vulkantutorial_MainActivity_runVulkan (
538
- JNIEnv *env, jobject instance, jobject surface) {
539
- LOGI (" Vulkan app start" );
540
-
541
- ANativeWindow *window = ANativeWindow_fromSurface (env, surface);
542
- if (window == nullptr ) {
543
- LOGE (" get window from surface fail!" );
544
- return ;
545
- }
546
-
547
- HelloTriangleApplication app;
548
- try {
549
- app.run (window);
550
- } catch (const std::runtime_error &e) {
551
- LOGE (" runtime error: %s" , e.what ());
552
- }
553
-
554
- LOGI (" Vulkan app exit" );
555
- }
556
- }
0 commit comments