Swap Chain Recreation & Dynamic Viewports
This commit is contained in:
parent
eb484e22f8
commit
976ff14298
|
@ -48,6 +48,30 @@
|
|||
"typeinfo": "cpp",
|
||||
"fstream": "cpp",
|
||||
"set": "cpp",
|
||||
"unordered_set": "cpp"
|
||||
"unordered_set": "cpp",
|
||||
"csignal": "cpp",
|
||||
"ctime": "cpp",
|
||||
"any": "cpp",
|
||||
"strstream": "cpp",
|
||||
"bitset": "cpp",
|
||||
"chrono": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"complex": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"optional": "cpp",
|
||||
"ratio": "cpp",
|
||||
"future": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"mutex": "cpp",
|
||||
"semaphore": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"thread": "cpp",
|
||||
"cfenv": "cpp",
|
||||
"typeindex": "cpp",
|
||||
"valarray": "cpp",
|
||||
"variant": "cpp"
|
||||
}
|
||||
}
|
BIN
VulkanTest
BIN
VulkanTest
Binary file not shown.
|
@ -58,8 +58,11 @@ namespace hk
|
|||
|
||||
void FirstApp::createPipeline()
|
||||
{
|
||||
auto pipelineConfig =
|
||||
Pipeline::defaultPipelineConfigInfo(swapChain->width(), swapChain->height());
|
||||
assert(swapChain != nullptr && "Cannot create pipeline before swap chain");
|
||||
assert(pipelineLayout != nullptr && "Cannot create pipeline before pipeline layout");
|
||||
|
||||
PipelineConfigInfo pipelineConfig{};
|
||||
Pipeline::defaultPipelineConfigInfo(pipelineConfig);
|
||||
|
||||
pipelineConfig.renderPass = swapChain->getRenderPass();
|
||||
pipelineConfig.pipelineLayout = pipelineLayout;
|
||||
|
@ -80,7 +83,22 @@ namespace hk
|
|||
}
|
||||
|
||||
vkDeviceWaitIdle(device.device());
|
||||
swapChain = std::make_unique<SwapChain>(device, extent);
|
||||
|
||||
if (swapChain == nullptr)
|
||||
{
|
||||
swapChain = std::make_unique<SwapChain>(device, extent);
|
||||
}
|
||||
else
|
||||
{
|
||||
swapChain = std::make_unique<SwapChain>(device, extent, std::move(swapChain));
|
||||
if (swapChain->imageCount() != commandBuffers.size())
|
||||
{
|
||||
freeCommandBuffers();
|
||||
createCommandBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
// if render pass compatible do nothing else
|
||||
createPipeline();
|
||||
}
|
||||
|
||||
|
@ -101,6 +119,16 @@ namespace hk
|
|||
}
|
||||
}
|
||||
|
||||
void FirstApp::freeCommandBuffers()
|
||||
{
|
||||
vkFreeCommandBuffers(
|
||||
device.device(),
|
||||
device.getCommandPool(),
|
||||
static_cast<float>(commandBuffers.size()),
|
||||
commandBuffers.data());
|
||||
commandBuffers.clear();
|
||||
}
|
||||
|
||||
void FirstApp::recordCommandBuffer(int imageIndex)
|
||||
{
|
||||
VkCommandBufferBeginInfo beginInfo{};
|
||||
|
@ -126,6 +154,17 @@ namespace hk
|
|||
|
||||
vkCmdBeginRenderPass(commandBuffers[imageIndex], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
VkViewport viewport{};
|
||||
viewport.x = 0.0f;
|
||||
viewport.y = 0.0f;
|
||||
viewport.width = static_cast<float>(swapChain->getSwapChainExtent().width);
|
||||
viewport.height = static_cast<float>(swapChain->getSwapChainExtent().height);
|
||||
viewport.minDepth = 0.0f;
|
||||
viewport.maxDepth = 1.0f;
|
||||
VkRect2D scissor{{0, 0}, swapChain->getSwapChainExtent()};
|
||||
vkCmdSetViewport(commandBuffers[imageIndex], 0, 1, &viewport);
|
||||
vkCmdSetScissor(commandBuffers[imageIndex], 0, 1, &scissor);
|
||||
|
||||
pipeline->bind(commandBuffers[imageIndex]);
|
||||
model->bind(commandBuffers[imageIndex]);
|
||||
model->draw(commandBuffers[imageIndex]);
|
||||
|
@ -161,7 +200,7 @@ namespace hk
|
|||
recreateSwapChain();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (result != VK_SUCCESS)
|
||||
{
|
||||
throw std::runtime_error("failed to present swap chain image!");
|
||||
|
|
|
@ -31,6 +31,7 @@ namespace hk
|
|||
void createPipelineLayout();
|
||||
void createPipeline();
|
||||
void createCommandBuffers();
|
||||
void freeCommandBuffers();
|
||||
void drawFrame();
|
||||
void recreateSwapChain();
|
||||
void recordCommandBuffer(int imageIndex);
|
||||
|
|
|
@ -31,22 +31,17 @@ namespace hk
|
|||
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicPipeline);
|
||||
}
|
||||
|
||||
PipelineConfigInfo Pipeline::defaultPipelineConfigInfo(uint32_t width, uint32_t height)
|
||||
void Pipeline::defaultPipelineConfigInfo(PipelineConfigInfo& configInfo)
|
||||
{
|
||||
PipelineConfigInfo configInfo{};
|
||||
configInfo.inputAssemblyInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||
configInfo.inputAssemblyInfo.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
configInfo.inputAssemblyInfo.primitiveRestartEnable = VK_FALSE;
|
||||
|
||||
configInfo.viewport.x = 0.0f;
|
||||
configInfo.viewport.y = 0.0f;
|
||||
configInfo.viewport.width = static_cast<float>(width);
|
||||
configInfo.viewport.height = static_cast<float>(height);
|
||||
configInfo.viewport.minDepth = 0.0f;
|
||||
configInfo.viewport.maxDepth = 1.0f;
|
||||
|
||||
configInfo.scissor.offset = {0, 0};
|
||||
configInfo.scissor.extent = {width, height};
|
||||
configInfo.viewportInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
||||
configInfo.viewportInfo.viewportCount = 1;
|
||||
configInfo.viewportInfo.pViewports = nullptr;
|
||||
configInfo.viewportInfo.scissorCount = 1;
|
||||
configInfo.viewportInfo.pScissors = nullptr;
|
||||
|
||||
configInfo.rasterizationInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||
configInfo.rasterizationInfo.depthClampEnable = VK_FALSE;
|
||||
|
@ -100,7 +95,11 @@ namespace hk
|
|||
configInfo.depthStencilInfo.front = {}; // Optional
|
||||
configInfo.depthStencilInfo.back = {}; // Optional
|
||||
|
||||
return configInfo;
|
||||
configInfo.dynamicStateEnables = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
|
||||
configInfo.dynamicStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
|
||||
configInfo.dynamicStateInfo.pDynamicStates = configInfo.dynamicStateEnables.data();
|
||||
configInfo.dynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(configInfo.dynamicStateEnables.size());
|
||||
configInfo.dynamicStateInfo.flags = 0;
|
||||
}
|
||||
|
||||
std::vector<char> Pipeline::readFile(const std::string &filePath)
|
||||
|
@ -165,25 +164,18 @@ namespace hk
|
|||
vertexInputInfo.pVertexAttributeDescriptions = attributeDescriptions.data();
|
||||
vertexInputInfo.pVertexBindingDescriptions = bindingDescriptions.data();
|
||||
|
||||
VkPipelineViewportStateCreateInfo viewportInfo{};
|
||||
viewportInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
||||
viewportInfo.viewportCount = 1;
|
||||
viewportInfo.pViewports = &configInfo.viewport;
|
||||
viewportInfo.scissorCount = 1;
|
||||
viewportInfo.pScissors = &configInfo.scissor;
|
||||
|
||||
VkGraphicsPipelineCreateInfo pipelineInfo{};
|
||||
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
pipelineInfo.stageCount = 2;
|
||||
pipelineInfo.pStages = shaderStages;
|
||||
pipelineInfo.pVertexInputState = &vertexInputInfo;
|
||||
pipelineInfo.pInputAssemblyState = &configInfo.inputAssemblyInfo;
|
||||
pipelineInfo.pViewportState = &viewportInfo;
|
||||
pipelineInfo.pViewportState = &configInfo.viewportInfo;
|
||||
pipelineInfo.pRasterizationState = &configInfo.rasterizationInfo;
|
||||
pipelineInfo.pMultisampleState = &configInfo.multisampleInfo;
|
||||
pipelineInfo.pColorBlendState = &configInfo.colorBlendInfo;
|
||||
pipelineInfo.pDepthStencilState = &configInfo.depthStencilInfo;
|
||||
pipelineInfo.pDynamicState = nullptr;
|
||||
pipelineInfo.pDynamicState = &configInfo.dynamicStateInfo;
|
||||
|
||||
pipelineInfo.layout = configInfo.pipelineLayout;
|
||||
pipelineInfo.renderPass = configInfo.renderPass;
|
||||
|
|
|
@ -10,14 +10,18 @@ namespace hk
|
|||
{
|
||||
struct PipelineConfigInfo
|
||||
{
|
||||
VkViewport viewport;
|
||||
VkRect2D scissor;
|
||||
PipelineConfigInfo(const PipelineConfigInfo&) = delete;
|
||||
PipelineConfigInfo &operator=(const PipelineConfigInfo&) = delete;
|
||||
|
||||
VkPipelineViewportStateCreateInfo viewportInfo;
|
||||
VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo;
|
||||
VkPipelineRasterizationStateCreateInfo rasterizationInfo;
|
||||
VkPipelineMultisampleStateCreateInfo multisampleInfo;
|
||||
VkPipelineColorBlendAttachmentState colorBlendAttachment;
|
||||
VkPipelineColorBlendStateCreateInfo colorBlendInfo;
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencilInfo;
|
||||
std::vector<VkDynamicState> dynamicStateEnables;
|
||||
VkPipelineDynamicStateCreateInfo dynamicStateInfo;
|
||||
VkPipelineLayout pipelineLayout = nullptr;
|
||||
VkRenderPass renderPass = nullptr;
|
||||
uint32_t subpass = 0;
|
||||
|
@ -38,7 +42,7 @@ namespace hk
|
|||
|
||||
void bind(VkCommandBuffer commandBuffer);
|
||||
|
||||
static PipelineConfigInfo defaultPipelineConfigInfo(uint32_t width, uint32_t height);
|
||||
static void defaultPipelineConfigInfo(PipelineConfigInfo& configInfo);
|
||||
|
||||
private:
|
||||
static std::vector<char> readFile(const std::string &filePath);
|
||||
|
|
|
@ -14,6 +14,19 @@ namespace hk
|
|||
|
||||
SwapChain::SwapChain(Device &deviceRef, VkExtent2D extent)
|
||||
: device{deviceRef}, windowExtent{extent}
|
||||
{
|
||||
init();
|
||||
}
|
||||
SwapChain::SwapChain(Device &deviceRef, VkExtent2D extent, std::shared_ptr<SwapChain> previous)
|
||||
: device{deviceRef}, windowExtent{extent}, oldSwapChain{previous}
|
||||
{
|
||||
init();
|
||||
|
||||
// clean up old swap chain
|
||||
oldSwapChain = nullptr;
|
||||
}
|
||||
|
||||
void SwapChain::init()
|
||||
{
|
||||
createSwapChain();
|
||||
createImageViews();
|
||||
|
@ -179,7 +192,7 @@ namespace hk
|
|||
createInfo.presentMode = presentMode;
|
||||
createInfo.clipped = VK_TRUE;
|
||||
|
||||
createInfo.oldSwapchain = VK_NULL_HANDLE;
|
||||
createInfo.oldSwapchain = oldSwapChain == nullptr ? VK_NULL_HANDLE : oldSwapChain->swapChain;
|
||||
|
||||
if (vkCreateSwapchainKHR(device.device(), &createInfo, nullptr, &swapChain) != VK_SUCCESS)
|
||||
{
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <vulkan/vulkan.h>
|
||||
|
||||
// std lib headers
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -18,6 +19,7 @@ namespace hk
|
|||
static constexpr int MAX_FRAMES_IN_FLIGHT = 2;
|
||||
|
||||
SwapChain(Device &deviceRef, VkExtent2D windowExtent);
|
||||
SwapChain(Device &deviceRef, VkExtent2D windowExtent, std::shared_ptr<SwapChain> previous);
|
||||
~SwapChain();
|
||||
|
||||
SwapChain(const SwapChain &) = delete;
|
||||
|
@ -42,6 +44,7 @@ namespace hk
|
|||
VkResult submitCommandBuffers(const VkCommandBuffer *buffers, uint32_t *imageIndex);
|
||||
|
||||
private:
|
||||
void init();
|
||||
void createSwapChain();
|
||||
void createImageViews();
|
||||
void createDepthResources();
|
||||
|
@ -72,6 +75,7 @@ namespace hk
|
|||
VkExtent2D windowExtent;
|
||||
|
||||
VkSwapchainKHR swapChain;
|
||||
std::shared_ptr<SwapChain> oldSwapChain;
|
||||
|
||||
std::vector<VkSemaphore> imageAvailableSemaphores;
|
||||
std::vector<VkSemaphore> renderFinishedSemaphores;
|
||||
|
|
Loading…
Reference in New Issue