coral_pipeline.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #include "coral_pipeline.h"
  2. // STD
  3. #include <iostream>
  4. #include <fstream>
  5. #include <cassert>
  6. #include "coral_mesh.h"
  7. #include "vk_initializers.h"
  8. using namespace coral_3d;
  9. coral_pipeline::coral_pipeline(
  10. coral_device& device,
  11. const std::string& vert_file_path,
  12. const std::string& frag_file_path,
  13. const PipelineConfigInfo& config_info) : device_{device}
  14. {
  15. create_graphics_pipeline(vert_file_path, frag_file_path, config_info);
  16. }
  17. coral_pipeline::~coral_pipeline()
  18. {
  19. vkDestroyShaderModule(device_.device(), vert_shader_module_, nullptr);
  20. vkDestroyShaderModule(device_.device(), frag_shader_module_, nullptr);
  21. vkDestroyPipeline(device_.device(), graphics_pipeline_, nullptr);
  22. }
  23. void coral_pipeline::bind(VkCommandBuffer command_buffer)
  24. {
  25. vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pipeline_);
  26. }
  27. void coral_pipeline::default_pipeline_config_info(PipelineConfigInfo& config_info)
  28. {
  29. // IA
  30. config_info.input_assembly_info = vkinit::input_assembly_ci(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
  31. // VIEWPORT INFO
  32. config_info.viewport_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
  33. config_info.viewport_info.pNext = nullptr;
  34. config_info.viewport_info.viewportCount = 1;
  35. config_info.viewport_info.pViewports = nullptr;
  36. config_info.viewport_info.scissorCount = 1;
  37. config_info.viewport_info.pScissors = nullptr;
  38. // RASTERIZER
  39. config_info.rasterization_info = vkinit::rasterization_state_ci(VK_POLYGON_MODE_FILL);
  40. // MULTISAMPLER
  41. config_info.multisample_info = vkinit::multisample_state_ci();
  42. // BLEND ATTACHMENT
  43. config_info.color_blend_attachment = vkinit::color_blend_attachment_state();
  44. // BLEND INFO
  45. config_info.color_blend_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
  46. config_info.color_blend_info.pNext = nullptr;
  47. config_info.color_blend_info.logicOpEnable = VK_FALSE;
  48. config_info.color_blend_info.logicOp = VK_LOGIC_OP_COPY;
  49. config_info.color_blend_info.attachmentCount = 1;
  50. config_info.color_blend_info.pAttachments = &config_info.color_blend_attachment;
  51. config_info.color_blend_info.blendConstants[0] = 0.f;
  52. config_info.color_blend_info.blendConstants[1] = 0.f;
  53. config_info.color_blend_info.blendConstants[2] = 0.f;
  54. config_info.color_blend_info.blendConstants[3] = 0.f;
  55. // DEPTH INFO
  56. config_info.depth_stencil_info = vkinit::depth_stencil_ci(true, true, VK_COMPARE_OP_LESS_OR_EQUAL);
  57. // DYNAMIC STATE
  58. config_info.dynamic_state_enables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
  59. config_info.dynamic_state_info.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
  60. config_info.dynamic_state_info.pDynamicStates = config_info.dynamic_state_enables.data();
  61. config_info.dynamic_state_info.dynamicStateCount =
  62. static_cast<uint32_t>(config_info.dynamic_state_enables.size());
  63. config_info.dynamic_state_info.flags = 0;
  64. config_info.binding_descriptions = Vertex::get_vert_desc().bindings;
  65. config_info.attribute_descriptions = Vertex::get_vert_desc().attributes;
  66. }
  67. std::vector<char> coral_pipeline::read_file(const std::string& file_path)
  68. {
  69. std::ifstream file{file_path, std::ios::ate | std::ios::binary };
  70. if (!file.is_open())
  71. throw std::runtime_error("ERROR! coral_pipeline::read_file() >> Failed to open file: " + file_path);
  72. // Create buffer sized to the file
  73. size_t file_size{ static_cast<size_t>(file.tellg()) };
  74. std::vector<char> buffer(file_size);
  75. // Read file into buffer
  76. file.seekg(0);
  77. file.read(buffer.data(), file_size);
  78. file.close();
  79. return buffer;
  80. }
  81. void coral_pipeline::create_graphics_pipeline(
  82. const std::string& vert_file_path,
  83. const std::string& frag_file_path,
  84. const PipelineConfigInfo& config_info)
  85. {
  86. assert(config_info.pipeline_layout != VK_NULL_HANDLE &&
  87. "ERROR! coral_pipeline::create_graphics_pipeline() >> no pipeline layout provided in config_info ");
  88. assert(config_info.render_pass != VK_NULL_HANDLE &&
  89. "ERROR! coral_pipeline::create_graphics_pipeline() >> no render pass provided in config_info ");
  90. auto vert_code = read_file(vert_file_path);
  91. auto frag_code = read_file(frag_file_path);
  92. create_shader_module(device_, vert_code, &vert_shader_module_);
  93. create_shader_module(device_, frag_code, &frag_shader_module_);
  94. VkPipelineShaderStageCreateInfo shader_stages[2];
  95. shader_stages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
  96. shader_stages[0].pNext = nullptr;
  97. shader_stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
  98. shader_stages[0].module = vert_shader_module_;
  99. shader_stages[0].pName = "main";
  100. shader_stages[0].flags = 0;
  101. shader_stages[0].pSpecializationInfo = nullptr;
  102. shader_stages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
  103. shader_stages[1].pNext = nullptr;
  104. shader_stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
  105. shader_stages[1].module = frag_shader_module_;
  106. shader_stages[1].pName = "main";
  107. shader_stages[1].flags = 0;
  108. shader_stages[1].pSpecializationInfo = nullptr;
  109. // VERTEX INPUT INFO
  110. auto& binding_descriptions{config_info.binding_descriptions};
  111. auto& attribute_descriptions{config_info.attribute_descriptions};
  112. VkPipelineVertexInputStateCreateInfo vertex_input_info{ vkinit::vertex_input_state_ci() };
  113. vertex_input_info.vertexAttributeDescriptionCount = static_cast<uint32_t>(attribute_descriptions.size());
  114. vertex_input_info.pVertexAttributeDescriptions = attribute_descriptions.data();
  115. vertex_input_info.vertexBindingDescriptionCount = static_cast<uint32_t>(binding_descriptions.size());
  116. vertex_input_info.pVertexBindingDescriptions = binding_descriptions.data();
  117. VkGraphicsPipelineCreateInfo pipeline_info{};
  118. pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
  119. pipeline_info.stageCount = 2;
  120. pipeline_info.pStages = shader_stages;
  121. pipeline_info.pVertexInputState = &vertex_input_info;
  122. pipeline_info.pInputAssemblyState = &config_info.input_assembly_info;
  123. pipeline_info.pViewportState = &config_info.viewport_info;
  124. pipeline_info.pRasterizationState = &config_info.rasterization_info;
  125. pipeline_info.pMultisampleState = &config_info.multisample_info;
  126. pipeline_info.pColorBlendState = &config_info.color_blend_info;
  127. pipeline_info.pDepthStencilState = &config_info.depth_stencil_info;
  128. pipeline_info.pDynamicState = &config_info.dynamic_state_info;
  129. pipeline_info.layout = config_info.pipeline_layout;
  130. pipeline_info.renderPass = config_info.render_pass;
  131. pipeline_info.subpass = config_info.subpass;
  132. pipeline_info.basePipelineIndex = -1;
  133. pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
  134. if (vkCreateGraphicsPipelines(device_.device(), VK_NULL_HANDLE, 1, &pipeline_info, nullptr, &graphics_pipeline_)
  135. != VK_SUCCESS)
  136. throw std::runtime_error("ERROR! coral_pipeline::create_graphics_pipeline() >> Failed to create graphics pipeline!");
  137. }
  138. void coral_pipeline::create_shader_module(coral_device& device, const std::vector<char>& code, VkShaderModule* shader_module)
  139. {
  140. VkShaderModuleCreateInfo create_info{};
  141. create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
  142. create_info.pNext = nullptr;
  143. create_info.codeSize = code.size();
  144. create_info.pCode = reinterpret_cast<const uint32_t*>(code.data());
  145. if(vkCreateShaderModule(device.device(), &create_info, nullptr, shader_module) != VK_SUCCESS)
  146. throw std::runtime_error("ERROR! coral_pipeline::create_shader_module() >> Failed to create shader module!");
  147. }
  148. VkPipelineLayout coral_pipeline::create_pipeline_layout(coral_device &device, std::vector<VkDescriptorSetLayout> desc_set_layouts)
  149. {
  150. VkPushConstantRange push_constant_range{};
  151. push_constant_range.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
  152. push_constant_range.offset = 0;
  153. push_constant_range.size = sizeof(PushConstant);
  154. VkPipelineLayoutCreateInfo layout_info{ vkinit::pipeline_layout_ci() };
  155. layout_info.pushConstantRangeCount = 1;
  156. layout_info.pPushConstantRanges = &push_constant_range;
  157. layout_info.setLayoutCount = static_cast<uint32_t>(desc_set_layouts.size());
  158. layout_info.pSetLayouts = desc_set_layouts.data();
  159. VkPipelineLayout pipeline_layout;
  160. if (vkCreatePipelineLayout(device.device(), &layout_info, nullptr, &pipeline_layout) != VK_SUCCESS)
  161. throw std::runtime_error("ERROR! coral_pipeline::create_pipeline_layout() >> Failed to create pipeline layout!");
  162. return pipeline_layout;
  163. }