PipelineStateVK.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2024 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #include <TestFramework.h>
  5. #include <Renderer/VK/PipelineStateVK.h>
  6. #include <Renderer/VK/RendererVK.h>
  7. #include <Renderer/VK/FatalErrorIfFailedVK.h>
  8. PipelineStateVK::PipelineStateVK(RendererVK *inRenderer, const VertexShaderVK *inVertexShader, const EInputDescription *inInputDescription, uint inInputDescriptionCount, const PixelShaderVK *inPixelShader, EDrawPass inDrawPass, EFillMode inFillMode, ETopology inTopology, EDepthTest inDepthTest, EBlendMode inBlendMode, ECullMode inCullMode) :
  9. mRenderer(inRenderer),
  10. mVertexShader(inVertexShader),
  11. mPixelShader(inPixelShader)
  12. {
  13. VkPipelineShaderStageCreateInfo shader_stages[] = { inVertexShader->mStageInfo, inPixelShader->mStageInfo };
  14. // TODO: This doesn't follow the SPIR-V alignment rules
  15. Array<VkVertexInputAttributeDescription> attribute_descriptions;
  16. VkVertexInputAttributeDescription temp_vtx = { }, temp_instance = { };
  17. temp_instance.binding = 1;
  18. uint instance_alignment = 1;
  19. for (uint i = 0; i < inInputDescriptionCount; ++i)
  20. switch (inInputDescription[i])
  21. {
  22. case EInputDescription::Position:
  23. temp_vtx.format = VK_FORMAT_R32G32B32_SFLOAT;
  24. attribute_descriptions.push_back(temp_vtx);
  25. temp_vtx.offset += 3 * sizeof(float);
  26. break;
  27. case EInputDescription::Color:
  28. temp_vtx.format = VK_FORMAT_R8G8B8A8_UNORM;
  29. attribute_descriptions.push_back(temp_vtx);
  30. temp_vtx.offset += 4 * sizeof(uint8);
  31. break;
  32. case EInputDescription::Normal:
  33. temp_vtx.format = VK_FORMAT_R32G32B32_SFLOAT;
  34. attribute_descriptions.push_back(temp_vtx);
  35. temp_vtx.offset += 3 * sizeof(float);
  36. break;
  37. case EInputDescription::TexCoord:
  38. temp_vtx.format = VK_FORMAT_R32G32_SFLOAT;
  39. attribute_descriptions.push_back(temp_vtx);
  40. temp_vtx.offset += 2 * sizeof(float);
  41. break;
  42. case EInputDescription::InstanceColor:
  43. instance_alignment = max(instance_alignment, 4u);
  44. temp_instance.format = VK_FORMAT_R8G8B8A8_UNORM;
  45. attribute_descriptions.push_back(temp_instance);
  46. temp_instance.offset += 4 * sizeof(uint8);
  47. break;
  48. case EInputDescription::InstanceTransform:
  49. instance_alignment = max(instance_alignment, 16u);
  50. temp_instance.format = VK_FORMAT_R32G32B32A32_SFLOAT;
  51. for (int j = 0; j < 4; ++j)
  52. {
  53. attribute_descriptions.push_back(temp_instance);
  54. temp_instance.offset += 4 * sizeof(float);
  55. }
  56. break;
  57. case EInputDescription::InstanceInvTransform:
  58. instance_alignment = max(instance_alignment, 16u);
  59. temp_instance.format = VK_FORMAT_R32G32B32A32_SFLOAT;
  60. for (int j = 0; j < 4; ++j)
  61. {
  62. attribute_descriptions.push_back(temp_instance);
  63. temp_instance.offset += 4 * sizeof(float);
  64. }
  65. break;
  66. }
  67. for (uint32 i = 0; i < uint32(attribute_descriptions.size()); ++i)
  68. attribute_descriptions[i].location = i;
  69. VkVertexInputBindingDescription binding_description[2];
  70. binding_description[0].binding = 0;
  71. binding_description[0].stride = temp_vtx.offset;
  72. binding_description[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
  73. binding_description[1].binding = 1;
  74. binding_description[1].stride = AlignUp(temp_instance.offset, instance_alignment);
  75. binding_description[1].inputRate = VK_VERTEX_INPUT_RATE_INSTANCE;
  76. VkPipelineVertexInputStateCreateInfo vertex_input_info = {};
  77. vertex_input_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
  78. vertex_input_info.vertexBindingDescriptionCount = temp_instance.offset > 0? 2 : 1;
  79. vertex_input_info.pVertexBindingDescriptions = binding_description;
  80. vertex_input_info.vertexAttributeDescriptionCount = uint32(attribute_descriptions.size());
  81. vertex_input_info.pVertexAttributeDescriptions = attribute_descriptions.data();
  82. VkPipelineInputAssemblyStateCreateInfo input_assembly = {};
  83. input_assembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
  84. input_assembly.topology = inTopology == ETopology::Triangle? VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST : VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
  85. input_assembly.primitiveRestartEnable = VK_FALSE;
  86. VkPipelineViewportStateCreateInfo viewport_state = {};
  87. viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
  88. viewport_state.viewportCount = 1;
  89. viewport_state.scissorCount = 1;
  90. VkPipelineRasterizationStateCreateInfo rasterizer = {};
  91. rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
  92. rasterizer.depthClampEnable = VK_FALSE;
  93. rasterizer.rasterizerDiscardEnable = VK_FALSE;
  94. rasterizer.polygonMode = inFillMode == EFillMode::Solid? VK_POLYGON_MODE_FILL : VK_POLYGON_MODE_LINE;
  95. rasterizer.lineWidth = 1.0f;
  96. rasterizer.cullMode = inCullMode == ECullMode::Backface? VK_CULL_MODE_BACK_BIT : VK_CULL_MODE_FRONT_BIT;
  97. rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
  98. rasterizer.depthBiasEnable = VK_FALSE;
  99. VkPipelineMultisampleStateCreateInfo multisampling = {};
  100. multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
  101. multisampling.sampleShadingEnable = VK_FALSE;
  102. multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
  103. VkPipelineDepthStencilStateCreateInfo depth_stencil = {};
  104. depth_stencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
  105. depth_stencil.depthTestEnable = inDepthTest == EDepthTest::On? VK_TRUE : VK_FALSE;
  106. depth_stencil.depthWriteEnable = inDepthTest == EDepthTest::On? VK_TRUE : VK_FALSE;
  107. depth_stencil.depthCompareOp = VK_COMPARE_OP_GREATER; // Reverse-Z, greater is closer
  108. VkPipelineColorBlendAttachmentState color_blend_attachment = {};
  109. color_blend_attachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
  110. switch (inBlendMode)
  111. {
  112. case EBlendMode::Write:
  113. color_blend_attachment.blendEnable = VK_FALSE;
  114. break;
  115. case EBlendMode::AlphaBlend:
  116. color_blend_attachment.blendEnable = VK_TRUE;
  117. color_blend_attachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
  118. color_blend_attachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
  119. color_blend_attachment.colorBlendOp = VK_BLEND_OP_ADD;
  120. color_blend_attachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
  121. color_blend_attachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
  122. color_blend_attachment.alphaBlendOp = VK_BLEND_OP_ADD;
  123. break;
  124. }
  125. VkPipelineColorBlendStateCreateInfo color_blending = {};
  126. color_blending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
  127. color_blending.logicOpEnable = VK_FALSE;
  128. color_blending.logicOp = VK_LOGIC_OP_COPY;
  129. color_blending.attachmentCount = 1;
  130. color_blending.pAttachments = &color_blend_attachment;
  131. VkDynamicState dynamic_states[] = {
  132. VK_DYNAMIC_STATE_VIEWPORT,
  133. VK_DYNAMIC_STATE_SCISSOR
  134. };
  135. VkPipelineDynamicStateCreateInfo dynamic_state = {};
  136. dynamic_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
  137. dynamic_state.dynamicStateCount = std::size(dynamic_states);
  138. dynamic_state.pDynamicStates = dynamic_states;
  139. VkGraphicsPipelineCreateInfo pipeline_info = {};
  140. pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
  141. pipeline_info.stageCount = std::size(shader_stages);
  142. pipeline_info.pStages = shader_stages;
  143. pipeline_info.pVertexInputState = &vertex_input_info;
  144. pipeline_info.pInputAssemblyState = &input_assembly;
  145. pipeline_info.pViewportState = &viewport_state;
  146. pipeline_info.pRasterizationState = &rasterizer;
  147. pipeline_info.pMultisampleState = &multisampling;
  148. pipeline_info.pDepthStencilState = &depth_stencil;
  149. pipeline_info.pColorBlendState = &color_blending;
  150. pipeline_info.pDynamicState = &dynamic_state;
  151. pipeline_info.layout = mRenderer->GetPipelineLayout();
  152. pipeline_info.renderPass = inDrawPass == EDrawPass::Normal? mRenderer->GetRenderPass() : mRenderer->GetRenderPassShadow();
  153. FatalErrorIfFailed(vkCreateGraphicsPipelines(mRenderer->GetDevice(), VK_NULL_HANDLE, 1, &pipeline_info, nullptr, &mGraphicsPipeline));
  154. }
  155. PipelineStateVK::~PipelineStateVK()
  156. {
  157. vkDeviceWaitIdle(mRenderer->GetDevice());
  158. vkDestroyPipeline(mRenderer->GetDevice(), mGraphicsPipeline, nullptr);
  159. }
  160. void PipelineStateVK::Activate()
  161. {
  162. vkCmdBindPipeline(mRenderer->GetCommandBuffer(), VK_PIPELINE_BIND_POINT_GRAPHICS, mGraphicsPipeline);
  163. }