#pragma once #include "type.h" #include "render/window.h" #include namespace vkn { class Device; struct VulkanContext; using api::TextureDesc; struct VULKAN_API VulkanWindowArgs { uint32_t frames; uint32_t width; uint32_t height; VkFormat imageFormat; VkColorSpaceKHR imageColorSpace; VkPresentModeKHR presentMode; VkImageUsageFlags imageUsage; uint32_t maxFrameInFlightCount; VkExtent2D EnableImageExtent2D(VkSurfaceCapabilitiesKHR& capabilities); static VulkanWindowArgs Default(); }; class VulkanSwapchain { private: friend class VulkanWindow; Device& mDevice; VkSwapchainKHR mPtr; int mFrames; pmr::vector mSurfaces{ GlobalPool() }; pmr::vector mCommands{ GlobalPool() }; pmr::vector mFences{ GlobalPool() }; pmr::vector mSemaphores{ GlobalPool() }; public: VulkanSwapchain(Device& device, VkSurfaceKHR surface, VulkanWindowArgs& args); void Aquire(VulkanContext& ctx); void Present(VulkanContext& ctx); int FrameCount() { return mFrames; } const pmr::vector& GetSurface() { return mSurfaces; } }; class VULKAN_API VulkanWindow : public api::Window { private: VulkanSwapchain* mSwapchain; public: void* operator new(size_t size) { return ::operator new(size, GlobalPool()); } void operator delete(void* p) {} public: using api::Window::Window; using CreatePFN = decltype(&SDL_Vulkan_CreateSurface); bool CreateRender(CreatePFN createPFN, VulkanWindowArgs& args); static VulkanWindow* Ptr() { return (VulkanWindow*)api::Window::Ptr(); } void Aquire(VulkanContext& ctx) { mSwapchain->Aquire(ctx); }; void Present(VulkanContext& ctx) { mSwapchain->Present(ctx); }; VulkanSwapchain* Swapchain() { return mSwapchain; } }; }