mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-24 08:00:14 +00:00
Vulcan Nightmare
Experimentally bringing up vulcan support
This commit is contained in:
parent
863a786c48
commit
83b576e8d9
189 changed files with 12147 additions and 7820 deletions
271
src/rendering/vk_pipeline.cpp
Normal file
271
src/rendering/vk_pipeline.cpp
Normal file
|
|
@ -0,0 +1,271 @@
|
|||
#include "rendering/vk_pipeline.hpp"
|
||||
#include "core/logger.hpp"
|
||||
|
||||
namespace wowee {
|
||||
namespace rendering {
|
||||
|
||||
PipelineBuilder::PipelineBuilder() {
|
||||
// Default: one blend attachment with blending disabled
|
||||
colorBlendAttachments_.push_back(blendDisabled());
|
||||
|
||||
// Default dynamic states: viewport + scissor (almost always dynamic)
|
||||
dynamicStates_ = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
|
||||
}
|
||||
|
||||
PipelineBuilder& PipelineBuilder::setShaders(
|
||||
VkPipelineShaderStageCreateInfo vert, VkPipelineShaderStageCreateInfo frag)
|
||||
{
|
||||
shaderStages_ = {vert, frag};
|
||||
return *this;
|
||||
}
|
||||
|
||||
PipelineBuilder& PipelineBuilder::setVertexInput(
|
||||
const std::vector<VkVertexInputBindingDescription>& bindings,
|
||||
const std::vector<VkVertexInputAttributeDescription>& attributes)
|
||||
{
|
||||
vertexBindings_ = bindings;
|
||||
vertexAttributes_ = attributes;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PipelineBuilder& PipelineBuilder::setNoVertexInput() {
|
||||
vertexBindings_.clear();
|
||||
vertexAttributes_.clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
PipelineBuilder& PipelineBuilder::setTopology(VkPrimitiveTopology topology,
|
||||
VkBool32 primitiveRestart)
|
||||
{
|
||||
topology_ = topology;
|
||||
primitiveRestart_ = primitiveRestart;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PipelineBuilder& PipelineBuilder::setRasterization(VkPolygonMode polygonMode,
|
||||
VkCullModeFlags cullMode, VkFrontFace frontFace)
|
||||
{
|
||||
polygonMode_ = polygonMode;
|
||||
cullMode_ = cullMode;
|
||||
frontFace_ = frontFace;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PipelineBuilder& PipelineBuilder::setDepthTest(bool enable, bool writeEnable,
|
||||
VkCompareOp compareOp)
|
||||
{
|
||||
depthTestEnable_ = enable;
|
||||
depthWriteEnable_ = writeEnable;
|
||||
depthCompareOp_ = compareOp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PipelineBuilder& PipelineBuilder::setNoDepthTest() {
|
||||
depthTestEnable_ = false;
|
||||
depthWriteEnable_ = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PipelineBuilder& PipelineBuilder::setDepthBias(float constantFactor, float slopeFactor) {
|
||||
depthBiasEnable_ = true;
|
||||
depthBiasConstant_ = constantFactor;
|
||||
depthBiasSlope_ = slopeFactor;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PipelineBuilder& PipelineBuilder::setColorBlendAttachment(
|
||||
VkPipelineColorBlendAttachmentState blendState)
|
||||
{
|
||||
colorBlendAttachments_ = {blendState};
|
||||
return *this;
|
||||
}
|
||||
|
||||
PipelineBuilder& PipelineBuilder::setNoColorAttachment() {
|
||||
colorBlendAttachments_.clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
PipelineBuilder& PipelineBuilder::setMultisample(VkSampleCountFlagBits samples) {
|
||||
msaaSamples_ = samples;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PipelineBuilder& PipelineBuilder::setLayout(VkPipelineLayout layout) {
|
||||
pipelineLayout_ = layout;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PipelineBuilder& PipelineBuilder::setRenderPass(VkRenderPass renderPass, uint32_t subpass) {
|
||||
renderPass_ = renderPass;
|
||||
subpass_ = subpass;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PipelineBuilder& PipelineBuilder::setDynamicStates(const std::vector<VkDynamicState>& states) {
|
||||
dynamicStates_ = states;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VkPipeline PipelineBuilder::build(VkDevice device) const {
|
||||
// Vertex input
|
||||
VkPipelineVertexInputStateCreateInfo vertexInput{};
|
||||
vertexInput.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||
vertexInput.vertexBindingDescriptionCount = static_cast<uint32_t>(vertexBindings_.size());
|
||||
vertexInput.pVertexBindingDescriptions = vertexBindings_.data();
|
||||
vertexInput.vertexAttributeDescriptionCount = static_cast<uint32_t>(vertexAttributes_.size());
|
||||
vertexInput.pVertexAttributeDescriptions = vertexAttributes_.data();
|
||||
|
||||
// Input assembly
|
||||
VkPipelineInputAssemblyStateCreateInfo inputAssembly{};
|
||||
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||
inputAssembly.topology = topology_;
|
||||
inputAssembly.primitiveRestartEnable = primitiveRestart_;
|
||||
|
||||
// Viewport / scissor (dynamic, so just specify count)
|
||||
VkPipelineViewportStateCreateInfo viewportState{};
|
||||
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
||||
viewportState.viewportCount = 1;
|
||||
viewportState.scissorCount = 1;
|
||||
|
||||
// Rasterization
|
||||
VkPipelineRasterizationStateCreateInfo rasterizer{};
|
||||
rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||
rasterizer.depthClampEnable = VK_FALSE;
|
||||
rasterizer.rasterizerDiscardEnable = VK_FALSE;
|
||||
rasterizer.polygonMode = polygonMode_;
|
||||
rasterizer.lineWidth = 1.0f;
|
||||
rasterizer.cullMode = cullMode_;
|
||||
rasterizer.frontFace = frontFace_;
|
||||
rasterizer.depthBiasEnable = depthBiasEnable_ ? VK_TRUE : VK_FALSE;
|
||||
rasterizer.depthBiasConstantFactor = depthBiasConstant_;
|
||||
rasterizer.depthBiasSlopeFactor = depthBiasSlope_;
|
||||
|
||||
// Multisampling
|
||||
VkPipelineMultisampleStateCreateInfo multisampling{};
|
||||
multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||
multisampling.sampleShadingEnable = VK_FALSE;
|
||||
multisampling.rasterizationSamples = msaaSamples_;
|
||||
|
||||
// Depth/stencil
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencil{};
|
||||
depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
||||
depthStencil.depthTestEnable = depthTestEnable_ ? VK_TRUE : VK_FALSE;
|
||||
depthStencil.depthWriteEnable = depthWriteEnable_ ? VK_TRUE : VK_FALSE;
|
||||
depthStencil.depthCompareOp = depthCompareOp_;
|
||||
depthStencil.depthBoundsTestEnable = VK_FALSE;
|
||||
depthStencil.stencilTestEnable = VK_FALSE;
|
||||
|
||||
// Color blending
|
||||
VkPipelineColorBlendStateCreateInfo colorBlending{};
|
||||
colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
||||
colorBlending.logicOpEnable = VK_FALSE;
|
||||
colorBlending.attachmentCount = static_cast<uint32_t>(colorBlendAttachments_.size());
|
||||
colorBlending.pAttachments = colorBlendAttachments_.data();
|
||||
|
||||
// Dynamic state
|
||||
VkPipelineDynamicStateCreateInfo dynamicState{};
|
||||
dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
|
||||
dynamicState.dynamicStateCount = static_cast<uint32_t>(dynamicStates_.size());
|
||||
dynamicState.pDynamicStates = dynamicStates_.data();
|
||||
|
||||
// Create pipeline
|
||||
VkGraphicsPipelineCreateInfo pipelineInfo{};
|
||||
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
pipelineInfo.stageCount = static_cast<uint32_t>(shaderStages_.size());
|
||||
pipelineInfo.pStages = shaderStages_.data();
|
||||
pipelineInfo.pVertexInputState = &vertexInput;
|
||||
pipelineInfo.pInputAssemblyState = &inputAssembly;
|
||||
pipelineInfo.pViewportState = &viewportState;
|
||||
pipelineInfo.pRasterizationState = &rasterizer;
|
||||
pipelineInfo.pMultisampleState = &multisampling;
|
||||
pipelineInfo.pDepthStencilState = &depthStencil;
|
||||
pipelineInfo.pColorBlendState = colorBlendAttachments_.empty() ? nullptr : &colorBlending;
|
||||
pipelineInfo.pDynamicState = dynamicStates_.empty() ? nullptr : &dynamicState;
|
||||
pipelineInfo.layout = pipelineLayout_;
|
||||
pipelineInfo.renderPass = renderPass_;
|
||||
pipelineInfo.subpass = subpass_;
|
||||
|
||||
VkPipeline pipeline = VK_NULL_HANDLE;
|
||||
if (vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo,
|
||||
nullptr, &pipeline) != VK_SUCCESS)
|
||||
{
|
||||
LOG_ERROR("Failed to create graphics pipeline");
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
VkPipelineColorBlendAttachmentState PipelineBuilder::blendDisabled() {
|
||||
VkPipelineColorBlendAttachmentState state{};
|
||||
state.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
|
||||
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
state.blendEnable = VK_FALSE;
|
||||
return state;
|
||||
}
|
||||
|
||||
VkPipelineColorBlendAttachmentState PipelineBuilder::blendAlpha() {
|
||||
VkPipelineColorBlendAttachmentState state{};
|
||||
state.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
|
||||
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
state.blendEnable = VK_TRUE;
|
||||
state.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||
state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
state.colorBlendOp = VK_BLEND_OP_ADD;
|
||||
state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||
state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
state.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||
return state;
|
||||
}
|
||||
|
||||
VkPipelineColorBlendAttachmentState PipelineBuilder::blendAdditive() {
|
||||
VkPipelineColorBlendAttachmentState state{};
|
||||
state.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
|
||||
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
state.blendEnable = VK_TRUE;
|
||||
state.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||
state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||
state.colorBlendOp = VK_BLEND_OP_ADD;
|
||||
state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||
state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||
state.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||
return state;
|
||||
}
|
||||
|
||||
VkPipelineLayout createPipelineLayout(VkDevice device,
|
||||
const std::vector<VkDescriptorSetLayout>& setLayouts,
|
||||
const std::vector<VkPushConstantRange>& pushConstants)
|
||||
{
|
||||
VkPipelineLayoutCreateInfo layoutInfo{};
|
||||
layoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||
layoutInfo.setLayoutCount = static_cast<uint32_t>(setLayouts.size());
|
||||
layoutInfo.pSetLayouts = setLayouts.data();
|
||||
layoutInfo.pushConstantRangeCount = static_cast<uint32_t>(pushConstants.size());
|
||||
layoutInfo.pPushConstantRanges = pushConstants.data();
|
||||
|
||||
VkPipelineLayout layout = VK_NULL_HANDLE;
|
||||
if (vkCreatePipelineLayout(device, &layoutInfo, nullptr, &layout) != VK_SUCCESS) {
|
||||
LOG_ERROR("Failed to create pipeline layout");
|
||||
}
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
VkDescriptorSetLayout createDescriptorSetLayout(VkDevice device,
|
||||
const std::vector<VkDescriptorSetLayoutBinding>& bindings)
|
||||
{
|
||||
VkDescriptorSetLayoutCreateInfo layoutInfo{};
|
||||
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||
layoutInfo.bindingCount = static_cast<uint32_t>(bindings.size());
|
||||
layoutInfo.pBindings = bindings.data();
|
||||
|
||||
VkDescriptorSetLayout layout = VK_NULL_HANDLE;
|
||||
if (vkCreateDescriptorSetLayout(device, &layoutInfo, nullptr, &layout) != VK_SUCCESS) {
|
||||
LOG_ERROR("Failed to create descriptor set layout");
|
||||
}
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
} // namespace rendering
|
||||
} // namespace wowee
|
||||
Loading…
Add table
Add a link
Reference in a new issue