Skip to content

Commit

Permalink
mesh shading pipeline creation setup
Browse files Browse the repository at this point in the history
  • Loading branch information
Kingstom committed Nov 21, 2023
1 parent f91a142 commit 8723aae
Showing 1 changed file with 98 additions and 78 deletions.
176 changes: 98 additions & 78 deletions engine/api/vulkan/pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class VulkanPipelineBuilder final
VulkanPipelineBuilder& stencilAttachmentFormat(VkFormat format);

VkResult build(Device* pDevice, VkPipelineCache pipelineCache, VkPipelineLayout pipelineLayout,
VkPipeline* outPipeline) noexcept;
VkPipeline* outPipeline, PipelineType type) noexcept;

static uint32_t getNumPipelinesCreated() { return numPipelinesCreated_; }

Expand Down Expand Up @@ -290,7 +290,7 @@ VulkanPipelineBuilder& VulkanPipelineBuilder::stencilMasks(VkStencilFaceFlags fa
}

VkResult VulkanPipelineBuilder::build(Device* pDevice, VkPipelineCache pipelineCache, VkPipelineLayout pipelineLayout,
VkPipeline* outPipeline) noexcept
VkPipeline* outPipeline, PipelineType type) noexcept
{
const VkPipelineDynamicStateCreateInfo dynamicState = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
Expand Down Expand Up @@ -322,14 +322,15 @@ VkResult VulkanPipelineBuilder::build(Device* pDevice, VkPipelineCache pipelineC
.stencilAttachmentFormat = stencilAttachmentFormat_,
};

bool isGeometryPipeline = type == PipelineType::Geometry;
const VkGraphicsPipelineCreateInfo ci = {
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.pNext = &renderingInfo,
.flags = 0,
.stageCount = static_cast<uint32_t>(shaderStages_.size()),
.pStages = shaderStages_.data(),
.pVertexInputState = &vertexInputState_,
.pInputAssemblyState = &inputAssembly_,
.pVertexInputState = isGeometryPipeline ? &vertexInputState_ : nullptr,
.pInputAssemblyState = isGeometryPipeline ? &inputAssembly_ : nullptr,
.pTessellationState = nullptr,
.pViewportState = &viewportState,
.pRasterizationState = &rasterizationState_,
Expand Down Expand Up @@ -426,43 +427,11 @@ Pipeline* PipelineAllocator::create(const GraphicsPipelineCreateInfo& createInfo
auto& pProgram = createInfo.pProgram;
APH_ASSERT(pProgram);

shaderStages.push_back(init::pipelineShaderStageCreateInfo(VK_SHADER_STAGE_VERTEX_BIT,
pProgram->getShader(ShaderStage::VS)->getHandle()));
shaderStages.push_back(init::pipelineShaderStageCreateInfo(VK_SHADER_STAGE_FRAGMENT_BIT,
pProgram->getShader(ShaderStage::FS)->getHandle()));

// create rps
std::vector<VkVertexInputBindingDescription> vkBindings;
std::vector<VkVertexInputAttributeDescription> vkAttributes;

const VertexInput& vstate = createInfo.vertexInput;
vkAttributes.resize(vstate.attributes.size());
SmallVector<bool> bufferAlreadyBound(vstate.bindings.size());

for(uint32_t i = 0; i != vkAttributes.size(); i++)
{
const auto& attr = vstate.attributes[i];

vkAttributes[i] = {.location = attr.location,
.binding = attr.binding,
.format = utils::VkCast(attr.format),
.offset = (uint32_t)attr.offset};

if(!bufferAlreadyBound[attr.binding])
{
bufferAlreadyBound[attr.binding] = true;
vkBindings.push_back({.binding = attr.binding,
.stride = vstate.bindings[attr.binding].stride,
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX});
}
}

// Not all attachments are valid. We need to create color blend attachments only for active attachments
const uint32_t numColorAttachments = createInfo.color.size();

std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentStates{numColorAttachments};
std::vector<VkFormat> colorAttachmentFormats{numColorAttachments};

for(uint32_t i = 0; i != numColorAttachments; i++)
{
const auto& attachment = createInfo.color[i];
Expand Down Expand Up @@ -498,50 +467,101 @@ Pipeline* PipelineAllocator::create(const GraphicsPipelineCreateInfo& createInfo
}
}

const VkPipelineVertexInputStateCreateInfo ciVertexInputState = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = static_cast<uint32_t>(vkBindings.size()),
.pVertexBindingDescriptions = !vkBindings.empty() ? vkBindings.data() : nullptr,
.vertexAttributeDescriptionCount = static_cast<uint32_t>(vkAttributes.size()),
.pVertexAttributeDescriptions = !vkAttributes.empty() ? vkAttributes.data() : nullptr,
};

VkPipeline handle;

VulkanPipelineBuilder()
// from Vulkan 1.0
.dynamicState(VK_DYNAMIC_STATE_VIEWPORT)
.dynamicState(VK_DYNAMIC_STATE_SCISSOR)
.dynamicState(VK_DYNAMIC_STATE_DEPTH_BIAS)
.dynamicState(VK_DYNAMIC_STATE_BLEND_CONSTANTS)
// from Vulkan 1.3
.dynamicState(VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE)
.dynamicState(VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE)
.dynamicState(VK_DYNAMIC_STATE_DEPTH_COMPARE_OP)
.primitiveTopology(utils::VkCast(createInfo.topology))
.depthBiasEnable(createInfo.dynamicState.depthBiasEnable)
.rasterizationSamples(aph::vk::utils::getSampleCountFlags(createInfo.samplesCount))
.polygonMode(utils::VkCast(createInfo.polygonMode))
.stencilStateOps(VK_STENCIL_FACE_FRONT_BIT, utils::VkCast(createInfo.frontFaceStencil.stencilFailureOp),
utils::VkCast(createInfo.frontFaceStencil.depthStencilPassOp),
utils::VkCast(createInfo.frontFaceStencil.depthFailureOp),
utils::VkCast(createInfo.frontFaceStencil.stencilCompareOp))
.stencilStateOps(VK_STENCIL_FACE_BACK_BIT, utils::VkCast(createInfo.backFaceStencil.stencilFailureOp),
utils::VkCast(createInfo.backFaceStencil.depthStencilPassOp),
utils::VkCast(createInfo.backFaceStencil.depthFailureOp),
utils::VkCast(createInfo.backFaceStencil.stencilCompareOp))
.stencilMasks(VK_STENCIL_FACE_FRONT_BIT, 0xFF, createInfo.frontFaceStencil.writeMask,
createInfo.frontFaceStencil.readMask)
.stencilMasks(VK_STENCIL_FACE_BACK_BIT, 0xFF, createInfo.backFaceStencil.writeMask,
createInfo.backFaceStencil.readMask)
.shaderStage(shaderStages)
.cullMode(utils::VkCast(createInfo.cullMode))
.frontFace(utils::VkCast(createInfo.frontFaceWinding))
.vertexInputState(ciVertexInputState)
.colorAttachments(colorBlendAttachmentStates.data(), colorAttachmentFormats.data(), numColorAttachments)
.depthAttachmentFormat(utils::VkCast(createInfo.depthFormat))
.stencilAttachmentFormat(utils::VkCast(createInfo.stencilFormat))
.build(m_pDevice, VK_NULL_HANDLE, pProgram->getPipelineLayout(), &handle);
auto builder =
VulkanPipelineBuilder()
// from Vulkan 1.0
.dynamicState(VK_DYNAMIC_STATE_VIEWPORT)
.dynamicState(VK_DYNAMIC_STATE_SCISSOR)
.dynamicState(VK_DYNAMIC_STATE_DEPTH_BIAS)
.dynamicState(VK_DYNAMIC_STATE_BLEND_CONSTANTS)
// from Vulkan 1.3
.dynamicState(VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE)
.dynamicState(VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE)
.dynamicState(VK_DYNAMIC_STATE_DEPTH_COMPARE_OP)
.depthBiasEnable(createInfo.dynamicState.depthBiasEnable)
.rasterizationSamples(aph::vk::utils::getSampleCountFlags(createInfo.samplesCount))
.polygonMode(utils::VkCast(createInfo.polygonMode))
.stencilStateOps(VK_STENCIL_FACE_FRONT_BIT, utils::VkCast(createInfo.frontFaceStencil.stencilFailureOp),
utils::VkCast(createInfo.frontFaceStencil.depthStencilPassOp),
utils::VkCast(createInfo.frontFaceStencil.depthFailureOp),
utils::VkCast(createInfo.frontFaceStencil.stencilCompareOp))
.stencilStateOps(VK_STENCIL_FACE_BACK_BIT, utils::VkCast(createInfo.backFaceStencil.stencilFailureOp),
utils::VkCast(createInfo.backFaceStencil.depthStencilPassOp),
utils::VkCast(createInfo.backFaceStencil.depthFailureOp),
utils::VkCast(createInfo.backFaceStencil.stencilCompareOp))
.stencilMasks(VK_STENCIL_FACE_FRONT_BIT, 0xFF, createInfo.frontFaceStencil.writeMask,
createInfo.frontFaceStencil.readMask)
.stencilMasks(VK_STENCIL_FACE_BACK_BIT, 0xFF, createInfo.backFaceStencil.writeMask,
createInfo.backFaceStencil.readMask)
.cullMode(utils::VkCast(createInfo.cullMode))
.frontFace(utils::VkCast(createInfo.frontFaceWinding))
.colorAttachments(colorBlendAttachmentStates.data(), colorAttachmentFormats.data(), numColorAttachments)
.depthAttachmentFormat(utils::VkCast(createInfo.depthFormat))
.stencilAttachmentFormat(utils::VkCast(createInfo.stencilFormat));

std::vector<VkVertexInputBindingDescription> vkBindings;
std::vector<VkVertexInputAttributeDescription> vkAttributes;
switch(createInfo.type)
{
case PipelineType::Geometry:
{
shaderStages.push_back(init::pipelineShaderStageCreateInfo(VK_SHADER_STAGE_VERTEX_BIT,
pProgram->getShader(ShaderStage::VS)->getHandle()));
const VertexInput& vstate = createInfo.vertexInput;
vkAttributes.resize(vstate.attributes.size());
SmallVector<bool> bufferAlreadyBound(vstate.bindings.size());

for(uint32_t i = 0; i != vkAttributes.size(); i++)
{
const auto& attr = vstate.attributes[i];

vkAttributes[i] = {.location = attr.location,
.binding = attr.binding,
.format = utils::VkCast(attr.format),
.offset = (uint32_t)attr.offset};

if(!bufferAlreadyBound[attr.binding])
{
bufferAlreadyBound[attr.binding] = true;
vkBindings.push_back({.binding = attr.binding,
.stride = vstate.bindings[attr.binding].stride,
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX});
}
}
const VkPipelineVertexInputStateCreateInfo ciVertexInputState = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = static_cast<uint32_t>(vkBindings.size()),
.pVertexBindingDescriptions = !vkBindings.empty() ? vkBindings.data() : nullptr,
.vertexAttributeDescriptionCount = static_cast<uint32_t>(vkAttributes.size()),
.pVertexAttributeDescriptions = !vkAttributes.empty() ? vkAttributes.data() : nullptr,
};
builder.primitiveTopology(utils::VkCast(createInfo.topology));
builder.vertexInputState(ciVertexInputState);
}
break;
case PipelineType::Mesh:
{
shaderStages.push_back(init::pipelineShaderStageCreateInfo(VK_SHADER_STAGE_MESH_BIT_EXT,
pProgram->getShader(ShaderStage::MS)->getHandle()));
if(auto taskShader = pProgram->getShader(ShaderStage::TS); taskShader != nullptr)
{
shaderStages.push_back(
init::pipelineShaderStageCreateInfo(VK_SHADER_STAGE_TASK_BIT_EXT, taskShader->getHandle()));
}
}
break;
case PipelineType::Compute:
case PipelineType::RayTracing:
APH_ASSERT(false);
return nullptr;
}

shaderStages.push_back(init::pipelineShaderStageCreateInfo(VK_SHADER_STAGE_FRAGMENT_BIT,
pProgram->getShader(ShaderStage::FS)->getHandle()));
builder.shaderStage(shaderStages);
builder.build(m_pDevice, VK_NULL_HANDLE, pProgram->getPipelineLayout(), &handle, createInfo.type);

pPipeline = m_pool.allocate(m_pDevice, createInfo, handle, pProgram);
return pPipeline;
Expand Down

0 comments on commit 8723aae

Please sign in to comment.