Skip to content

Commit

Permalink
Don't recreate pipelines when resizing
Browse files Browse the repository at this point in the history
  • Loading branch information
Hjaltesorgenfrei committed Oct 12, 2022
1 parent a79d894 commit 57280ae
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 77 deletions.
38 changes: 16 additions & 22 deletions src/BehPipelines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,28 +37,6 @@ BehPipeline::BehPipeline(std::shared_ptr<BehDevice>& device, PipelineConfigurati
.primitiveRestartEnable = VK_FALSE
};

vk::Viewport viewport {
.x = 0.0f,
.y = 0.0f,
.width = static_cast<float>(config.extent.width),
.height = static_cast<float>(config.extent.height),
.minDepth = 0.0f,
.maxDepth = 1.0f
};

vk::Rect2D scissor {
.offset = {0, 0},
.extent = config.extent
};

vk::PipelineViewportStateCreateInfo viewportState {
.viewportCount = 1,
.pViewports = &viewport,
.scissorCount = 1,
.pScissors = &scissor,
};


vk::PipelineRasterizationStateCreateInfo rasterizer {
.depthClampEnable = VK_FALSE,
.rasterizerDiscardEnable = VK_FALSE,
Expand Down Expand Up @@ -109,6 +87,21 @@ BehPipeline::BehPipeline(std::shared_ptr<BehDevice>& device, PipelineConfigurati
.stencilTestEnable = VK_FALSE
};

std::vector<vk::DynamicState> dynamicStates {
vk::DynamicState::eScissor,
vk::DynamicState::eViewport
};

vk::PipelineDynamicStateCreateInfo dynamicStateCreateInfo {
.dynamicStateCount = static_cast<uint32_t>(dynamicStates.size()),
.pDynamicStates = dynamicStates.data()
};

vk::PipelineViewportStateCreateInfo viewportState {
.viewportCount = 1,
.scissorCount = 1,
};

vk::GraphicsPipelineCreateInfo pipelineInfo {
// Reference programmable stages
.stageCount = static_cast<uint32_t>(shaderStageCreateInfos.size()),
Expand All @@ -122,6 +115,7 @@ BehPipeline::BehPipeline(std::shared_ptr<BehDevice>& device, PipelineConfigurati
.pMultisampleState = &multisampling,
.pDepthStencilState = &depthStencil,
.pColorBlendState = &colorBlending,
.pDynamicState = &dynamicStateCreateInfo,

// A vulkan handle, not a struct pointer
.layout = config.pipelineLayout,
Expand Down
128 changes: 73 additions & 55 deletions src/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ void Renderer::recreateSwapchain() {
createSwapChain();
createImageViews();
createRenderPass();
createPipelines();
createColorResources();
createDepthResources();
createFramebuffers();
Expand Down Expand Up @@ -826,70 +825,89 @@ void Renderer::createCommandBuffers() {
void Renderer::recordCommandBuffer(uint32_t index, FrameInfo& frameInfo) {
vk::CommandBufferBeginInfo beginInfo {};

try {
commandBuffers[index].begin(beginInfo);
}
catch (vk::SystemError& err) {
throw std::runtime_error(std::string("failed to begin recording command buffer!") + err.what());
}
try {
commandBuffers[index].begin(beginInfo);
}
catch (vk::SystemError& err) {
throw std::runtime_error(std::string("failed to begin recording command buffer!") + err.what());
}

std::array<vk::ClearValue, 2> clearValues{};
clearValues[0].color = {std::array<float, 4>{ 0.0f, 0.0f, 0.0f, 1.0f }};
clearValues[1].depthStencil = vk::ClearDepthStencilValue {1.0f, 0};
std::array<vk::ClearValue, 2> clearValues{};
clearValues[0].color = {std::array<float, 4>{ 0.0f, 0.0f, 0.0f, 1.0f }};
clearValues[1].depthStencil = vk::ClearDepthStencilValue {1.0f, 0};

vk::RenderPassBeginInfo renderPassInfo {
.renderPass = renderPass,
.framebuffer = swapChainFramebuffers[index],
.renderArea = {
.offset = {0, 0},
.extent = swapChainExtent,
},
.clearValueCount = static_cast<uint32_t>(clearValues.size()),
.pClearValues = clearValues.data()
};

vk::RenderPassBeginInfo renderPassInfo {
.renderPass = renderPass,
.framebuffer = swapChainFramebuffers[index],
.renderArea = {
.offset = {0, 0},
.extent = swapChainExtent,
},
.clearValueCount = static_cast<uint32_t>(clearValues.size()),
.pClearValues = clearValues.data()
};
vk::Rect2D scissor {
.offset = {0, 0},
.extent = swapChainExtent
};

commandBuffers[index].beginRenderPass(renderPassInfo, vk::SubpassContents::eInline);
{
//Add commands to buffer
if(rendererMode == NORMAL) {
graphicsPipeline->bind(commandBuffers[index]);
}
else if(rendererMode == WIREFRAME) {
wireframePipeline->bind(commandBuffers[index]);
}
commandBuffers[index].bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, 1, &descriptorSets[index], 0, nullptr);
commandBuffers[index].setScissor(0, 1, &scissor);

for (const auto& model : frameInfo.objects) {
vk::Buffer vertexBuffers[] = { model->mesh->_vertexBuffer._buffer };
vk::DeviceSize offsets[] = { 0 };
commandBuffers[index].bindVertexBuffers(0, 1, vertexBuffers, offsets);
vk::Viewport viewport {
.x = 0.0f,
.y = 0.0f,
.width = static_cast<float>(swapChainExtent.width),
.height = static_cast<float>(swapChainExtent.height),
.minDepth = 0.0f,
.maxDepth = 1.0f
};

commandBuffers[index].bindIndexBuffer(model->mesh->_indexBuffer._buffer, 0, vk::IndexType::eUint32);
commandBuffers[index].setViewport(0, 1, &viewport);

commandBuffers[index].bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipelineLayout, 1, 1, &model->material.textureSet, 0, nullptr);

MeshPushConstants constants = model->transformMatrix;
commandBuffers[index].pushConstants(pipelineLayout, vk::ShaderStageFlagBits::eVertex, 0, sizeof(MeshPushConstants), &constants);

commandBuffers[index].drawIndexed(static_cast<uint32_t>(model->mesh->_indices.size()), 1, 0, 0, 0);
}
commandBuffers[index].beginRenderPass(renderPassInfo, vk::SubpassContents::eInline);
{
//Add commands to buffer
if(rendererMode == NORMAL) {
graphicsPipeline->bind(commandBuffers[index]);
}
else if(rendererMode == WIREFRAME) {
wireframePipeline->bind(commandBuffers[index]);
}
commandBuffers[index].bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, 1, &descriptorSets[index], 0, nullptr);

// Point lights
billboardPipeline->bind(commandBuffers[index]);
commandBuffers[index].bindDescriptorSets(vk::PipelineBindPoint::eGraphics, billboardPipelineLayout, 0, 1, &descriptorSets[index], 0, nullptr);
commandBuffers[index].draw(6, 1, 0, 0);
}
for (const auto& model : frameInfo.objects) {
vk::Buffer vertexBuffers[] = { model->mesh->_vertexBuffer._buffer };
vk::DeviceSize offsets[] = { 0 };
commandBuffers[index].bindVertexBuffers(0, 1, vertexBuffers, offsets);

ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), commandBuffers[index]);

commandBuffers[index].endRenderPass();
commandBuffers[index].bindIndexBuffer(model->mesh->_indexBuffer._buffer, 0, vk::IndexType::eUint32);

try {
commandBuffers[index].end();
}
catch (vk::SystemError& err) {
throw std::runtime_error(std::string("failed to record command buffer!") + err.what());
}
commandBuffers[index].bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipelineLayout, 1, 1, &model->material.textureSet, 0, nullptr);

MeshPushConstants constants = model->transformMatrix;
commandBuffers[index].pushConstants(pipelineLayout, vk::ShaderStageFlagBits::eVertex, 0, sizeof(MeshPushConstants), &constants);

commandBuffers[index].drawIndexed(static_cast<uint32_t>(model->mesh->_indices.size()), 1, 0, 0, 0);
}

// Point lights
billboardPipeline->bind(commandBuffers[index]);
commandBuffers[index].bindDescriptorSets(vk::PipelineBindPoint::eGraphics, billboardPipelineLayout, 0, 1, &descriptorSets[index], 0, nullptr);
commandBuffers[index].draw(6, 1, 0, 0);
}

ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), commandBuffers[index]);

commandBuffers[index].endRenderPass();

try {
commandBuffers[index].end();
}
catch (vk::SystemError& err) {
throw std::runtime_error(std::string("failed to record command buffer!") + err.what());
}
}

void Renderer::createSyncObjects() {
Expand Down

0 comments on commit 57280ae

Please sign in to comment.