Vulkan Tutorial in C - 007 - App Initialization Part 3

Define Rasterization State Create Info

VkPipelineRasterizationStateCreateInfo rasterizationStateInfo =
{
    VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
    NULL,
    0,
    VK_FALSE, // depthClampEnable
    VK_FALSE, // rasterizerDiscardEnable
    VK_POLYGON_MODE_FILL, // polygonMode (solid triangles)
    VK_CULL_MODE_BACK_BIT, // cullMode
    VK_FRONT_FACE_CLOCKWISE, // frontFace
    VK_FALSE, 0, 0, 0, // no depth bias
    1.0f // lineWidth
};

Define Multisample State Create Info

VkPipelineMultisampleStateCreateInfo multisampleStateInfo =
{
    VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
    NULL,
    0,
    VK_SAMPLE_COUNT_1_BIT, // rasterizationSamples
    VK_FALSE, // sampleShadingEnable
    0, // minSampleShading
    NULL, // pSampleMask
    VK_FALSE, // alphaToCoverageEnable
    VK_FALSE, // alphaToOneEnable
};

Define Color Blend State Create Info

We're disabling color blending, so all related fields in the color blend structs are ignored. However, I've still filled them out as placeholders. This makes it easier for us later when we come back to implement color blending.
VkFlags colorWriteMask =
    VK_COLOR_COMPONENT_R_BIT |
    VK_COLOR_COMPONENT_G_BIT |
    VK_COLOR_COMPONENT_B_BIT |
    VK_COLOR_COMPONENT_A_BIT;

VkPipelineColorBlendAttachmentState colorBlendAttachment =
{
    VK_FALSE, // blendEnable
    VK_BLEND_FACTOR_ZERO,
    VK_BLEND_FACTOR_ZERO,
    VK_BLEND_OP_ADD,
    VK_BLEND_FACTOR_ZERO,
    VK_BLEND_FACTOR_ZERO,
    VK_BLEND_OP_ADD,
    colorWriteMask,
};

VkPipelineColorBlendAttachmentState
    colorBlendAttachments[] = { colorBlendAttachment };

VkPipelineColorBlendStateCreateInfo colorBlendStateInfo =
{
    VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
    NULL,
    0,
    VK_FALSE,
    VK_LOGIC_OP_CLEAR,
    array_count(colorBlendAttachments),
    colorBlendAttachments,
    {0, 0, 0, 0}
};

Create Pipeline Layout

VkPipelineLayoutCreateInfo pipelineLayoutInfo =
{
    VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
    NULL,
    0,
    0, NULL, // (no descriptor sets)
    0, NULL // (no push constant ranges)
};

if (vkCreatePipelineLayout(vk.device, &pipelineLayoutInfo, NULL,
                           &pipelineLayout) != VK_SUCCESS)
{
    assert(!"Failed to create pipeline layout!");
}

Create Graphics Pipeline

VkGraphicsPipelineCreateInfo pipelineInfo =
{
    VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
    NULL,
    0,
    array_count(shaderStageInfo),
    shaderStageInfo,
    &vertexInputStateInfo,
    &inputAssemblyStateInfo,
    NULL, // pTessellationState
    &viewportStateInfo,
    &rasterizationStateInfo,
    &multisampleStateInfo,
    NULL, // pDepthStencilState
    &colorBlendStateInfo,
    &dynamicStateInfo,
    pipelineLayout,
    renderPass,
    0, // subpass index
    NULL, 0 // (no base pipeline)
};

// Create the graphics pipeline
if (vkCreateGraphicsPipelines(vk.device, VK_NULL_HANDLE, 1,
                              &pipelineInfo, NULL,
                              &graphicsPipeline) != VK_SUCCESS)
{
    assert(!"Failed to create graphics pipeline!");
}

Destroy Shader Modules and Create Frame Fence

vkDestroyShaderModule(vk.device, vertShaderModule, NULL);
vkDestroyShaderModule(vk.device, fragShaderModule, NULL);

VkFenceCreateInfo fenceInfo =
{
    VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
    NULL,
    0
};

vkCreateFence(vk.device, &fenceInfo, NULL,
              &frameFence);
When I ported this app to Linux (Ubuntu using XLib), I encountered an issue where the app would block indefinitely while waiting on the fence. To fix this, simply pass the VK_FENCE_CREATE_SIGNALED_BIT flag in the VkFenceCreateInfo.

I haven’t updated the tutorial code yet to include this flag in all examples (I might in the future), so be sure to add it to your fence initialization to prevent blocking on the first frame. On Windows, this issue didn’t occur—at least on my machine—but it may vary depending on the driver. If your app is unresponsive, adding this flag is likely the solution.
And that’s it! This marks the end of the app’s initialization. In the next and final post of this mini-series, we’ll dive into writing the main loop.

Next

Comments

Popular Posts