2022-09-19 01:20:51 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "xe_device.hpp"
|
|
|
|
|
|
|
|
#include <vulkan/vulkan.h>
|
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
#include <vulkan/vulkan_core.h>
|
|
|
|
|
|
|
|
namespace xe {
|
|
|
|
|
2022-09-25 01:16:13 +00:00
|
|
|
class SwapChain {
|
2022-09-19 01:20:51 +00:00
|
|
|
public:
|
2022-09-21 03:04:33 +00:00
|
|
|
static constexpr int MAX_FRAMES_IN_FLIGHT = 2;
|
2022-09-19 01:20:51 +00:00
|
|
|
|
2022-09-25 01:16:13 +00:00
|
|
|
SwapChain(Device &deviceRef, VkExtent2D windowExtent);
|
|
|
|
SwapChain(Device &deviceRef, VkExtent2D windowExtent, std::shared_ptr<SwapChain> previous);
|
|
|
|
~SwapChain();
|
2022-09-19 01:20:51 +00:00
|
|
|
|
2022-09-25 01:16:13 +00:00
|
|
|
SwapChain(const SwapChain &) = delete;
|
|
|
|
SwapChain operator=(const SwapChain &) = delete;
|
2022-09-19 01:20:51 +00:00
|
|
|
|
|
|
|
VkFramebuffer getFrameBuffer(int index) { return swapChainFramebuffers[index]; }
|
|
|
|
VkRenderPass getRenderPass() { return renderPass; }
|
|
|
|
VkImageView getImageView(int index) { return swapChainImageViews[index]; }
|
|
|
|
size_t imageCount() { return swapChainImages.size(); }
|
|
|
|
VkFormat getSwapChainImageFormat() { return swapChainImageFormat; }
|
|
|
|
VkExtent2D getSwapChainExtent() { return swapChainExtent; }
|
|
|
|
uint32_t width() { return swapChainExtent.width; }
|
|
|
|
uint32_t height() { return swapChainExtent.height; }
|
|
|
|
|
|
|
|
float extentAspectRatio() {
|
|
|
|
return static_cast<float>(swapChainExtent.width) / static_cast<float>(swapChainExtent.height);
|
|
|
|
}
|
|
|
|
VkFormat findDepthFormat();
|
|
|
|
|
|
|
|
VkResult acquireNextImage(uint32_t *imageIndex);
|
|
|
|
VkResult submitCommandBuffers(const VkCommandBuffer *buffers, uint32_t *imageIndex);
|
|
|
|
|
2022-09-25 01:16:13 +00:00
|
|
|
bool compareSwapFormats(const SwapChain& swapChain) const {
|
2022-09-19 01:20:51 +00:00
|
|
|
return swapChain.swapChainDepthFormat == swapChainDepthFormat &&
|
|
|
|
swapChain.swapChainImageFormat == swapChainImageFormat;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
void init();
|
|
|
|
void createSwapChain();
|
|
|
|
void createImageViews();
|
|
|
|
void createDepthResources();
|
|
|
|
void createRenderPass();
|
|
|
|
void createFramebuffers();
|
|
|
|
void createSyncObjects();
|
|
|
|
|
|
|
|
VkSurfaceFormatKHR chooseSwapSurfaceFormat(
|
|
|
|
const std::vector<VkSurfaceFormatKHR> &availableFormats);
|
|
|
|
VkPresentModeKHR chooseSwapPresentMode(
|
|
|
|
const std::vector<VkPresentModeKHR> &availablePresentModes);
|
|
|
|
VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR &capabilities);
|
|
|
|
|
|
|
|
VkFormat swapChainImageFormat;
|
|
|
|
VkFormat swapChainDepthFormat;
|
|
|
|
VkExtent2D swapChainExtent;
|
|
|
|
|
|
|
|
std::vector<VkFramebuffer> swapChainFramebuffers;
|
|
|
|
VkRenderPass renderPass;
|
|
|
|
|
|
|
|
std::vector<VkImage> depthImages;
|
|
|
|
std::vector<VkDeviceMemory> depthImageMemorys;
|
|
|
|
std::vector<VkImageView> depthImageViews;
|
|
|
|
std::vector<VkImage> swapChainImages;
|
|
|
|
std::vector<VkImageView> swapChainImageViews;
|
|
|
|
|
2022-09-25 01:16:13 +00:00
|
|
|
Device &device;
|
2022-09-19 01:20:51 +00:00
|
|
|
VkExtent2D windowExtent;
|
|
|
|
|
|
|
|
VkSwapchainKHR swapChain;
|
2022-09-25 01:16:13 +00:00
|
|
|
std::shared_ptr<SwapChain> oldSwapChain;
|
2022-09-19 01:20:51 +00:00
|
|
|
|
|
|
|
std::vector<VkSemaphore> imageAvailableSemaphores;
|
|
|
|
std::vector<VkSemaphore> renderFinishedSemaphores;
|
|
|
|
std::vector<VkFence> inFlightFences;
|
|
|
|
std::vector<VkFence> imagesInFlight;
|
|
|
|
size_t currentFrame = 0;
|
2022-09-22 22:29:34 +00:00
|
|
|
|
|
|
|
static bool initialSwapChainCreated;
|
|
|
|
|
2022-09-19 01:20:51 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|