Swapchain added.
This commit is contained in:
parent
c16456c610
commit
e55f30e7e7
|
|
@ -18,7 +18,8 @@ set(HEADER_FILES
|
|||
context.h
|
||||
window.h
|
||||
physical_device.h
|
||||
device.h)
|
||||
device.h
|
||||
swapchain.h)
|
||||
|
||||
set(SOURCE_FILES
|
||||
logger.cpp
|
||||
|
|
@ -26,7 +27,8 @@ set(SOURCE_FILES
|
|||
context.cpp
|
||||
window.cpp
|
||||
physical_device.cpp
|
||||
device.cpp)
|
||||
device.cpp
|
||||
swapchain.cpp)
|
||||
|
||||
add_library(aster_core STATIC ${SOURCE_FILES} ${HEADER_FILES})
|
||||
set_property(TARGET aster_core PROPERTY CXX_STANDARD 20)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,155 @@
|
|||
/// =============================================
|
||||
// Aster: swapchain.cpp
|
||||
// Copyright (c) 2020-2024 Anish Bhobe
|
||||
// ==============================================
|
||||
|
||||
#include "swapchain.h"
|
||||
|
||||
#include "device.h"
|
||||
#include "physical_device.h"
|
||||
#include "window.h"
|
||||
|
||||
vk::SurfaceCapabilitiesKHR
|
||||
getSurfaceCapabilities(vk::PhysicalDevice physicalDevice, const vk::SurfaceKHR surface)
|
||||
{
|
||||
vk::SurfaceCapabilitiesKHR surfaceCapabilities;
|
||||
|
||||
vk::Result result = physicalDevice.getSurfaceCapabilitiesKHR(surface, &surfaceCapabilities);
|
||||
ERROR_IF(failed(result), "Fetching surface capabilities failed. Cause: {}", result)
|
||||
THEN_ABORT(result);
|
||||
|
||||
return surfaceCapabilities;
|
||||
}
|
||||
|
||||
eastl::vector<vk::SurfaceFormatKHR>
|
||||
getSurfaceFormats(vk::PhysicalDevice physicalDevice, const vk::SurfaceKHR surface)
|
||||
{
|
||||
u32 count = 0;
|
||||
vk::Result result = physicalDevice.getSurfaceFormatsKHR(surface, &count, nullptr);
|
||||
ERROR_IF(failed(result), "Fetching surface formats failed. Cause: {}", result)
|
||||
THEN_ABORT(result);
|
||||
|
||||
eastl::vector<vk::SurfaceFormatKHR> surfaceFormats(count);
|
||||
result = physicalDevice.getSurfaceFormatsKHR(surface, &count, surfaceFormats.data());
|
||||
ERROR_IF(failed(result), "Fetching surface formats failed. Cause: {}", result)
|
||||
THEN_ABORT(result);
|
||||
|
||||
return surfaceFormats;
|
||||
}
|
||||
|
||||
eastl::vector<vk::PresentModeKHR>
|
||||
getSurfacePresentModes(vk::PhysicalDevice physicalDevice, const vk::SurfaceKHR surface)
|
||||
{
|
||||
u32 count = 0;
|
||||
vk::Result result = physicalDevice.getSurfacePresentModesKHR(surface, &count, nullptr);
|
||||
ERROR_IF(failed(result), "Fetching surface present modes failed. Cause: {}", result)
|
||||
THEN_ABORT(result);
|
||||
|
||||
eastl::vector<vk::PresentModeKHR> surfacePresentModes(count);
|
||||
result = physicalDevice.getSurfacePresentModesKHR(surface, &count, surfacePresentModes.data());
|
||||
ERROR_IF(failed(result), "Fetching surface present modes failed. Cause: {}", result)
|
||||
THEN_ABORT(result);
|
||||
|
||||
return surfacePresentModes;
|
||||
}
|
||||
|
||||
Swapchain::Swapchain(const Window *window, const Device *device, NameString &&name)
|
||||
: m_Device(device)
|
||||
, m_Name(std::move(name))
|
||||
{
|
||||
this->Create(window);
|
||||
}
|
||||
|
||||
Swapchain::~Swapchain()
|
||||
{
|
||||
if (m_Swapchain)
|
||||
{
|
||||
m_Device->m_Device.destroy(m_Swapchain, nullptr);
|
||||
m_Swapchain = nullptr;
|
||||
DEBUG("Swapchain '{}' destroyed.", m_Name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Swapchain::Create(const Window *window)
|
||||
{
|
||||
auto surfaceCapabilities = getSurfaceCapabilities(m_Device->m_PhysicalDevice, window->m_Surface);
|
||||
auto surfaceFormats = getSurfaceFormats(m_Device->m_PhysicalDevice, window->m_Surface);
|
||||
auto presentModes = getSurfacePresentModes(m_Device->m_PhysicalDevice, window->m_Surface);
|
||||
|
||||
vk::Format swapchainFormat = vk::Format::eUndefined;
|
||||
vk::ColorSpaceKHR swapchainColorSpace = vk::ColorSpaceKHR::eSrgbNonlinear;
|
||||
for (auto [format, colorSpace] : surfaceFormats)
|
||||
{
|
||||
if (format == vk::Format::eB8G8R8A8Srgb && colorSpace == vk::ColorSpaceKHR::eSrgbNonlinear)
|
||||
{
|
||||
swapchainFormat = format;
|
||||
swapchainColorSpace = colorSpace;
|
||||
}
|
||||
}
|
||||
if (swapchainFormat == vk::Format::eUndefined)
|
||||
{
|
||||
WARN("Preferred Swapchain format not found. Falling back.");
|
||||
auto surfaceFormat = surfaceFormats.front();
|
||||
swapchainFormat = surfaceFormat.format;
|
||||
swapchainColorSpace = surfaceFormat.colorSpace;
|
||||
}
|
||||
|
||||
vk::PresentModeKHR swapchainPresentMode = vk::PresentModeKHR::eFifo;
|
||||
for (auto presentMode : presentModes)
|
||||
{
|
||||
if (presentMode == vk::PresentModeKHR::eMailbox)
|
||||
{
|
||||
swapchainPresentMode = presentMode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
vk::Extent2D swapchainExtent;
|
||||
if (surfaceCapabilities.currentExtent.width != MaxValue<u32>)
|
||||
{
|
||||
swapchainExtent = surfaceCapabilities.currentExtent;
|
||||
}
|
||||
else
|
||||
{
|
||||
vk::Extent2D extent = window->GetSize();
|
||||
vk::Extent2D minExtent = surfaceCapabilities.minImageExtent;
|
||||
vk::Extent2D maxExtent = surfaceCapabilities.maxImageExtent;
|
||||
|
||||
swapchainExtent.width = glm::clamp(extent.width, minExtent.width, maxExtent.width);
|
||||
swapchainExtent.height = glm::clamp(extent.height, minExtent.height, maxExtent.height);
|
||||
}
|
||||
|
||||
u32 swapchainImageCount = 3;
|
||||
if (surfaceCapabilities.maxImageCount > 0)
|
||||
{
|
||||
swapchainImageCount =
|
||||
glm::clamp(swapchainImageCount, surfaceCapabilities.minImageCount, surfaceCapabilities.maxImageCount);
|
||||
}
|
||||
|
||||
// TODO: Note that different queues might need the images to be shared.
|
||||
|
||||
const vk::SwapchainCreateInfoKHR swapchainCreateInfo = {
|
||||
.surface = window->m_Surface,
|
||||
.minImageCount = swapchainImageCount,
|
||||
.imageFormat = swapchainFormat,
|
||||
.imageColorSpace = swapchainColorSpace,
|
||||
.imageExtent = swapchainExtent,
|
||||
.imageArrayLayers = 1,
|
||||
.imageUsage = vk::ImageUsageFlagBits::eColorAttachment,
|
||||
.imageSharingMode = vk::SharingMode::eExclusive,
|
||||
.preTransform = surfaceCapabilities.currentTransform,
|
||||
.compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque,
|
||||
.presentMode = swapchainPresentMode,
|
||||
.clipped = true,
|
||||
.oldSwapchain = m_Swapchain,
|
||||
};
|
||||
|
||||
vk::SwapchainKHR swapchain;
|
||||
vk::Result result = m_Device->m_Device.createSwapchainKHR(&swapchainCreateInfo, nullptr, &swapchain);
|
||||
ERROR_IF(failed(result), "Swapchain {} creation failed. Cause {}", m_Name, result)
|
||||
THEN_ABORT(result)
|
||||
ELSE_DEBUG("Created Swapchain '{}'", m_Name);
|
||||
|
||||
m_Swapchain = swapchain;
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/// =============================================
|
||||
// Aster: swapchain.h
|
||||
// Copyright (c) 2020-2024 Anish Bhobe
|
||||
// ==============================================
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "global.h"
|
||||
|
||||
struct PhysicalDevice;
|
||||
struct Window;
|
||||
struct Device;
|
||||
|
||||
struct Swapchain final
|
||||
{
|
||||
const Device *m_Device;
|
||||
vk::SwapchainKHR m_Swapchain;
|
||||
NameString m_Name;
|
||||
|
||||
Swapchain(const Window *window, const Device *device, NameString &&name);
|
||||
~Swapchain();
|
||||
void Create(const Window *window);
|
||||
};
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
// =============================================
|
||||
|
||||
#include "window.h"
|
||||
|
||||
#include "context.h"
|
||||
#include "glfw_context.h"
|
||||
#include "logger.h"
|
||||
|
|
@ -20,6 +21,15 @@ Window::SetWindowSize(const u32 width, const u32 height) const noexcept
|
|||
glfwSetWindowSize(m_Window, cast<i32>(width), cast<i32>(height));
|
||||
}
|
||||
|
||||
vk::Extent2D
|
||||
Window::GetSize() const
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
glfwGetWindowSize(m_Window, &width, &height);
|
||||
return {cast<u32>(width), cast<u32>(height)};
|
||||
}
|
||||
|
||||
Window::Window(cstr title, Context *context, vk::Extent2D extent, b8 isFullScreen)
|
||||
{
|
||||
m_Context = context;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ struct Window final
|
|||
|
||||
void SetWindowSize(const vk::Extent2D &extent) const noexcept;
|
||||
void SetWindowSize(u32 width, u32 height) const noexcept;
|
||||
[[nodiscard]] vk::Extent2D GetSize() const;
|
||||
|
||||
// Ctor/Dtor
|
||||
Window(cstr title, Context *context, vk::Extent2D extent, b8 isFullScreen = false);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
#include "aster/constants.h"
|
||||
#include "aster/context.h"
|
||||
#include "aster/device.h"
|
||||
#include "aster/glfw_context.h"
|
||||
#include "aster/physical_device.h"
|
||||
#include "aster/window.h"
|
||||
|
||||
#include "aster/global.h"
|
||||
#include "aster/swapchain.h"
|
||||
|
||||
constexpr QueueSupportFlags REQUIRED_QUEUE_SUPPORT = QueueSupportFlags{} | QueueSupportFlagBits::eGraphics |
|
||||
QueueSupportFlagBits::eCompute | QueueSupportFlagBits::ePresent |
|
||||
|
|
@ -62,7 +64,7 @@ findAppropriateQueueAllocation(const PhysicalDevice *physicalDevice)
|
|||
int
|
||||
main(int, char **)
|
||||
{
|
||||
MIN_LOG_LEVEL(Logger::LogType::eInfo);
|
||||
MIN_LOG_LEVEL(Logger::LogType::eDebug);
|
||||
|
||||
GlfwContext glfwContext = {};
|
||||
Context context = {"Aster", VERSION};
|
||||
|
|
@ -78,6 +80,8 @@ main(int, char **)
|
|||
|
||||
Device device = {&context, &deviceToUse, &features, {queueAllocation}, "Primary Device"};
|
||||
|
||||
Swapchain swapchain = {&window, &device, "Primary Chain"};
|
||||
|
||||
while (window.Poll())
|
||||
{
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue