CwGraphics-Surfaces.cpp
1 #include <Clockworks/CwGraphics.hpp> 2 #include <algorithm> // Necessary for std::clamp 3 #include <cstdint> // Necessary for uint32_t 4 #include <limits> // Necessary for std::numeric_limits 5 #include <stdexcept> 6 7 VkSurfaceFormatKHR CwGraphics::ChooseSurfaceFormat(const std::vector<VkSurfaceFormatKHR> &Formats) { 8 for (const auto &Format : Formats) { 9 if (Format.format == VK_FORMAT_B8G8R8A8_SRGB && Format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) return Format; 10 } 11 return Formats[0]; 12 } 13 14 VkPresentModeKHR CwGraphics::ChoosePMode(const std::vector<VkPresentModeKHR> &PModes) { 15 for (const auto &PMode : PModes) { 16 if (PMode == VK_PRESENT_MODE_MAILBOX_KHR) return PMode; 17 std::cout << "Cw-Info: Found Mailbox PMODE\n"; 18 } 19 return VK_PRESENT_MODE_FIFO_KHR; 20 21 std::cout << "Cw-Info: Defaulting to FIFO PMode\n"; 22 } 23 24 VkExtent2D CwGraphics::ChooseExtent(const VkSurfaceCapabilitiesKHR &Capabilities) { 25 if (Capabilities.currentExtent.width != std::numeric_limits<uint32_t>::max()) { 26 return Capabilities.currentExtent; 27 } else { 28 int width{}; 29 int height{}; 30 glfwGetFramebufferSize(Window.Window, &width, &height); 31 32 VkExtent2D RealExtent{static_cast<uint32_t>(width), static_cast<uint32_t>(height)}; 33 34 RealExtent.width = std::clamp(RealExtent.width, Capabilities.minImageExtent.width, Capabilities.maxImageExtent.width); 35 RealExtent.height = std::clamp(RealExtent.height, Capabilities.minImageExtent.height, Capabilities.maxImageExtent.height); 36 37 return RealExtent; 38 } 39 } 40 void CwGraphics::CreateChain() { 41 ChainDetails ChainDetails = ChainSupport(PhysicalDev); 42 43 VkSurfaceFormatKHR SForm = ChooseSurfaceFormat(ChainDetails.formats); 44 VkPresentModeKHR PMode = ChoosePMode(ChainDetails.PModes); 45 VkExtent2D Extent = ChooseExtent(ChainDetails.Capabilities); 46 47 uint32_t ImCount = ChainDetails.Capabilities.minImageCount + 1; 48 49 if (ChainDetails.Capabilities.maxImageCount > 0 && ImCount > ChainDetails.Capabilities.maxImageCount) 50 ImCount = ChainDetails.Capabilities.maxImageCount; 51 52 VkSwapchainCreateInfoKHR CInfo{}; 53 CInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; 54 CInfo.surface = Surface; 55 CInfo.minImageCount = ImCount; 56 CInfo.imageFormat = SForm.format; 57 CInfo.imageColorSpace = SForm.colorSpace; 58 CInfo.imageExtent = Extent; 59 CInfo.imageArrayLayers = 1; 60 CInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 61 62 if (FamIndices.GraphicsFam == FamIndices.PresentFam) { 63 CInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; 64 CInfo.queueFamilyIndexCount = 0; 65 CInfo.pQueueFamilyIndices = nullptr; 66 } else { 67 CInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT; 68 CInfo.queueFamilyIndexCount = 2; 69 uint32_t FamIndicesValues[2] = {FamIndices.GraphicsFam.value(), FamIndices.PresentFam.value()}; 70 CInfo.pQueueFamilyIndices = FamIndicesValues; 71 } 72 CInfo.preTransform = ChainDetails.Capabilities.currentTransform; 73 CInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; // Look Into later! opaque is good 74 // for now 75 CInfo.presentMode = PMode; 76 CInfo.clipped = VK_TRUE; // Dont care about non-visible pixels 77 CInfo.oldSwapchain = VK_NULL_HANDLE; 78 79 if (vkCreateSwapchainKHR(Dev, &CInfo, nullptr, &SwapChain) != VK_SUCCESS) throw std::runtime_error("CW-ERROR: Couldnt create SwapChain :(\n"); 80 81 vkGetSwapchainImagesKHR(Dev, SwapChain, &ImCount, nullptr); 82 ChainImages.resize(ImCount); 83 vkGetSwapchainImagesKHR(Dev, SwapChain, &ImCount, ChainImages.data()); 84 85 ChainImageFormat = SForm.format; 86 ChainExtent = Extent; 87 }