vulkan创建Graphics Pipeline

void Pipeline::createGraphicsPipeline() {
  const VkSpecializationInfo vertexSpecializationInfo{
      .mapEntryCount =
          static_cast<uint32_t>(graphicsPipelineDesc_.vertexSpecConstants_.size()),
      .pMapEntries = graphicsPipelineDesc_.vertexSpecConstants_.data(),
      .dataSize = !graphicsPipelineDesc_.vertexSpecConstants_.empty()
                      ? graphicsPipelineDesc_.vertexSpecConstants_.back().offset +
                            graphicsPipelineDesc_.vertexSpecConstants_.back().size
                      : 0,
      .pData = graphicsPipelineDesc_.vertexSpecializationData,
  };

  const VkSpecializationInfo fragmentSpecializationInfo{
      .mapEntryCount =
          static_cast<uint32_t>(graphicsPipelineDesc_.fragmentSpecConstants_.size()),
      .pMapEntries = graphicsPipelineDesc_.fragmentSpecConstants_.data(),
      .dataSize = !graphicsPipelineDesc_.fragmentSpecConstants_.empty()
                      ? graphicsPipelineDesc_.fragmentSpecConstants_.back().offset +
                            graphicsPipelineDesc_.fragmentSpecConstants_.back().size
                      : 0,
      .pData = graphicsPipelineDesc_.fragmentSpecializationData,
  };

  const auto vertShader = graphicsPipelineDesc_.vertexShader_.lock();
  ASSERT(vertShader,
         "Vertex's ShaderModule has been destroyed before being used to create "
         "a pipeline");
  const auto fragShader = graphicsPipelineDesc_.fragmentShader_.lock();
  ASSERT(fragShader,
         "Vertex's ShaderModule has been destroyed before being used to create "
         "a pipeline");
  std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages = {

      VkPipelineShaderStageCreateInfo{
          .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
          .stage = vertShader->vkShaderStageFlags(),
          .module = vertShader->vkShaderModule(),
          .pName = vertShader->entryPoint().c_str(),
          .pSpecializationInfo = !graphicsPipelineDesc_.vertexSpecConstants_.empty()
                                     ? &vertexSpecializationInfo
                                     : nullptr,
      },
      VkPipelineShaderStageCreateInfo{
          .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
          .stage = fragShader->vkShaderStageFlags(),
          .module = fragShader->vkShaderModule(),
          .pName = fragShader->entryPoint().c_str(),
          .pSpecializationInfo = !graphicsPipelineDesc_.fragmentSpecConstants_.empty()
                                     ? &fragmentSpecializationInfo
                                     : nullptr,
      },
  };

  const VkPipelineVertexInputStateCreateInfo vertexInputCreateInfo = {
      .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
      .vertexBindingDescriptionCount = 0,
      .vertexAttributeDescriptionCount = 0,
  };

  const VkPipelineInputAssemblyStateCreateInfo inputAssembly = {
      .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
      .topology = graphicsPipelineDesc_.primitiveTopology,
      .primitiveRestartEnable = VK_FALSE,
  };

  // viewport & scissor stuff
  const VkViewport viewport = graphicsPipelineDesc_.viewport.toVkViewPort();

  const VkRect2D scissor = {
      .offset =
          {
              .x = 0,
              .y = 0,
          },
      .extent = graphicsPipelineDesc_.viewport.toVkExtents(),
  };

  const VkPipelineViewportStateCreateInfo viewportState = {
      .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
      .viewportCount = 1,
      .pViewports = &viewport,
      .scissorCount = 1,
      .pScissors = &scissor,
  };

  // fixed function stuff
  const VkPipelineRasterizationStateCreateInfo rasterizer = {
      .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
      .depthClampEnable = VK_FALSE,
      .rasterizerDiscardEnable = VK_FALSE,
      .polygonMode = VK_POLYGON_MODE_FILL,
      .cullMode = VkCullModeFlags(graphicsPipelineDesc_.cullMode),
      .frontFace = graphicsPipelineDesc_.frontFace,
      .depthBiasEnable = VK_FALSE,
      .depthBiasConstantFactor = 0.0f,  // Optional
      .depthBiasClamp = 0.0f,           // Optional
      .depthBiasSlopeFactor = 0.0f,     // Optional
      .lineWidth = 1.0f,
  };

  const VkPipelineMultisampleStateCreateInfo multisampling = {
      .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
      .rasterizationSamples = graphicsPipelineDesc_.sampleCount,
      .sampleShadingEnable = VK_FALSE,
      .minSampleShading = 1.0f,           // Optional
      .pSampleMask = nullptr,             // Optional
      .alphaToCoverageEnable = VK_FALSE,  // Optional
      .alphaToOneEnable = VK_FALSE,       // Optional
  };

  std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachments;

  if (graphicsPipelineDesc_.blendAttachmentStates_.size() > 0) {
    ASSERT(graphicsPipelineDesc_.blendAttachmentStates_.size() ==
               graphicsPipelineDesc_.colorTextureFormats.size(),
           "Blend states need to be provided for all color textures");
    colorBlendAttachments = graphicsPipelineDesc_.blendAttachmentStates_;
  } else {
    colorBlendAttachments = std::vector<VkPipelineColorBlendAttachmentState>(
        graphicsPipelineDesc_.colorTextureFormats.size(),
        {
            .blendEnable = graphicsPipelineDesc_.blendEnable,
            .srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA,            // Optional
            .dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,  // Optional
            .colorBlendOp = VK_BLEND_OP_ADD,                             // Optional
            .srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA,            // Optional
            .dstAlphaBlendFactor = VK_BLEND_FACTOR_DST_ALPHA,            // Optional
            .alphaBlendOp = VK_BLEND_OP_ADD,                             // Optional
            .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
                              VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
        });
  }

  const VkPipelineColorBlendStateCreateInfo colorBlending = {
      .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
      .logicOpEnable = VK_FALSE,
      .logicOp = VK_LOGIC_OP_COPY,  // Optional
      .attachmentCount = uint32_t(colorBlendAttachments.size()),
      .pAttachments = colorBlendAttachments.data(),
      .blendConstants = {0.0f, 0.0f, 0.0f, 0.0f},  // Optional
  };

  // Descriptor Set
  initDescriptorLayout();

  // End of descriptor set layout
  // TODO: does order matter in descSetLayouts? YES!
  std::vector<VkDescriptorSetLayout> descSetLayouts(descriptorSets_.size());
  for (const auto& set : descriptorSets_) {
    descSetLayouts[set.first] = set.second.vkLayout_;
  }

  vkPipelineLayout_ =
      createPipelineLayout(descSetLayouts, graphicsPipelineDesc_.pushConstants_);

  const VkPipelineDepthStencilStateCreateInfo depthStencilState = {
      .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
      .depthTestEnable = graphicsPipelineDesc_.depthTestEnable,
      .depthWriteEnable = graphicsPipelineDesc_.depthWriteEnable,
      .depthCompareOp = graphicsPipelineDesc_.depthCompareOperation,
      .depthBoundsTestEnable = VK_FALSE,
      .stencilTestEnable = VK_FALSE,
      .front = {},
      .back = {},
      .minDepthBounds = 0.0f,
      .maxDepthBounds = 1.0f,
  };

  const VkPipelineDynamicStateCreateInfo dynamicState = {
      .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
      .dynamicStateCount =
          static_cast<uint32_t>(graphicsPipelineDesc_.dynamicStates_.size()),
      .pDynamicStates = graphicsPipelineDesc_.dynamicStates_.data(),
  };

  // only used for dynamic rendering
  const VkPipelineRenderingCreateInfo pipelineRenderingCreateInfo = {
      .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
      .colorAttachmentCount = uint32_t(graphicsPipelineDesc_.colorTextureFormats.size()),
      .pColorAttachmentFormats = graphicsPipelineDesc_.colorTextureFormats.data(),
      .depthAttachmentFormat = graphicsPipelineDesc_.depthTextureFormat,
      .stencilAttachmentFormat = graphicsPipelineDesc_.stencilTextureFormat,
  };

  const VkGraphicsPipelineCreateInfo pipelineInfo = {
      .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
      .pNext = graphicsPipelineDesc_.useDynamicRendering_ ? &pipelineRenderingCreateInfo
                                                          : nullptr,
      .stageCount = uint32_t(shaderStages.size()),
      .pStages = shaderStages.data(),
      .pVertexInputState = &graphicsPipelineDesc_.vertexInputCreateInfo,
      .pInputAssemblyState = &inputAssembly,
      .pViewportState = &viewportState,
      .pRasterizationState = &rasterizer,
      .pMultisampleState = &multisampling,
      .pDepthStencilState = &depthStencilState,  // Optional
      .pColorBlendState = &colorBlending,
      .pDynamicState = &dynamicState,
      .layout = vkPipelineLayout_,
      .renderPass = vkRenderPass_,
      .basePipelineHandle = VK_NULL_HANDLE,  // Optional
      .basePipelineIndex = -1,               // Optional
  };

  VK_CHECK(vkCreateGraphicsPipelines(context_->device(), VK_NULL_HANDLE, 1, &pipelineInfo,
                                     nullptr, &vkPipeline_));

  context_->setVkObjectname(vkPipeline_, VK_OBJECT_TYPE_PIPELINE,
                            "Graphics pipeline: " + name_);
}  // namespace VulkanCore

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值