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
vulkan创建Graphics Pipeline
最新推荐文章于 2025-03-11 14:27:53 发布