Compare commits
4 Commits
f603bd5752
...
8769215437
| Author | SHA1 | Date |
|---|---|---|
|
|
8769215437 | |
|
|
e120b38066 | |
|
|
e55f30e7e7 | |
|
|
c16456c610 |
|
|
@ -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,11 +27,14 @@ 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)
|
||||
|
||||
target_precompile_headers(aster_core PUBLIC global.h)
|
||||
|
||||
target_include_directories(aster_core PUBLIC ${CMAKE_SOURCE_DIR})
|
||||
|
||||
target_link_libraries(aster_core PUBLIC glm::glm-header-only)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ constexpr eastl::array VALIDATION_LAYERS = {
|
|||
};
|
||||
|
||||
VKAPI_ATTR b32 VKAPI_CALL
|
||||
debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType,
|
||||
DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT *callbackData, [[maybe_unused]] void *userData)
|
||||
{
|
||||
using Severity = vk::DebugUtilsMessageSeverityFlagsEXT;
|
||||
|
|
@ -57,7 +57,7 @@ Context::Context(cstr appName, Version version, bool enableValidation)
|
|||
.messageType = vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |
|
||||
vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance |
|
||||
vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation,
|
||||
.pfnUserCallback = debugCallback,
|
||||
.pfnUserCallback = DebugCallback,
|
||||
.pUserData = nullptr,
|
||||
};
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ Context::Context(cstr appName, Version version, bool enableValidation)
|
|||
|
||||
// May throw. Irrecoverable.
|
||||
vk::Result result = vk::createInstance(&instanceCreateInfo, nullptr, &m_Instance);
|
||||
ERROR_IF(result, "Instance creation failed. Cause: {}", to_string(result))
|
||||
ERROR_IF(result, "Instance creation failed. Cause: {}", result)
|
||||
THEN_ABORT(result)
|
||||
ELSE_DEBUG("Instance Created.");
|
||||
VULKAN_HPP_DEFAULT_DISPATCHER.init(m_Instance);
|
||||
|
|
@ -94,7 +94,7 @@ Context::Context(cstr appName, Version version, bool enableValidation)
|
|||
if (enableValidation)
|
||||
{
|
||||
result = m_Instance.createDebugUtilsMessengerEXT(&debugUtilsMessengerCreateInfo, nullptr, &m_DebugMessenger);
|
||||
ERROR_IF(result, "Debug Messenger creation failed. Cause: {}", to_string(result)) // Non-critical. Continue.
|
||||
ERROR_IF(result, "Debug Messenger creation failed. Cause: {}", result) // Non-critical. Continue.
|
||||
ELSE_DEBUG("Debug Messenger Created.");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,14 +5,19 @@
|
|||
|
||||
#include "device.h"
|
||||
|
||||
#include "context.h"
|
||||
#include "physical_device.h"
|
||||
|
||||
#include <EASTL/array.h>
|
||||
#include <EASTL/fixed_vector.h>
|
||||
|
||||
constexpr eastl::array DEVICE_EXTENSIONS = {VK_KHR_SWAPCHAIN_EXTENSION_NAME};
|
||||
|
||||
Device::Device(const Context *context, PhysicalDevice *physicalDevice,
|
||||
const vk::PhysicalDeviceFeatures *enabledFeatures,
|
||||
const eastl::vector<QueueAllocation> &queueAllocations, NameString name)
|
||||
const eastl::vector<QueueAllocation> &queueAllocations, NameString &&name)
|
||||
: m_Name(std::move(name))
|
||||
, m_PhysicalDevice(physicalDevice->m_PhysicalDevice)
|
||||
{
|
||||
// Shouldn't have more than 4 deviceQueueFamilies in use anyway. Else we can heap
|
||||
eastl::fixed_vector<vk::DeviceQueueCreateInfo, 4> deviceQueueCreateInfos;
|
||||
|
|
@ -43,7 +48,7 @@ Device::Device(const Context *context, PhysicalDevice *physicalDevice,
|
|||
.pEnabledFeatures = enabledFeatures,
|
||||
};
|
||||
|
||||
vk::Result result = physicalDevice->m_PhysicalDevice.createDevice(&deviceCreateInfo, nullptr, &m_Device);
|
||||
vk::Result result = m_PhysicalDevice.createDevice(&deviceCreateInfo, nullptr, &m_Device);
|
||||
ERROR_IF(failed(result), "Could not initialize Vulkan Device. Cause: {}", result)
|
||||
THEN_ABORT(result)
|
||||
ELSE_DEBUG("{} ({}) Initialized.", m_Name, physicalDevice->m_DeviceProperties.deviceName.data());
|
||||
|
|
@ -54,8 +59,7 @@ Device::Device(const Context *context, PhysicalDevice *physicalDevice,
|
|||
};
|
||||
|
||||
const VmaAllocatorCreateInfo allocatorCreateInfo = {
|
||||
.flags = 0,
|
||||
.physicalDevice = physicalDevice->m_PhysicalDevice,
|
||||
.physicalDevice = m_PhysicalDevice,
|
||||
.device = m_Device,
|
||||
.pVulkanFunctions = &vmaVulkanFunctions,
|
||||
.instance = context->m_Instance,
|
||||
|
|
@ -63,7 +67,7 @@ Device::Device(const Context *context, PhysicalDevice *physicalDevice,
|
|||
};
|
||||
|
||||
result = cast<vk::Result>(vmaCreateAllocator(&allocatorCreateInfo, &m_Allocator));
|
||||
ERROR_IF(failed(result), "Memory allocator creation failed. Cause: {}", to_string(result))
|
||||
ERROR_IF(failed(result), "Memory allocator creation failed. Cause: {}", result)
|
||||
DO(m_Device.destroy(nullptr))
|
||||
THEN_ABORT(result)
|
||||
ELSE_VERBOSE("Memory Allocator Created");
|
||||
|
|
@ -81,4 +85,5 @@ Device::~Device()
|
|||
}
|
||||
m_Device.destroy(nullptr);
|
||||
DEBUG("Device '{}' Destroyed", m_Name);
|
||||
m_PhysicalDevice = nullptr;
|
||||
}
|
||||
|
|
@ -6,7 +6,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "global.h"
|
||||
#include "physical_device.h"
|
||||
|
||||
#include <EASTL/vector.h>
|
||||
|
||||
struct Context;
|
||||
struct PhysicalDevice;
|
||||
|
||||
struct QueueAllocation
|
||||
{
|
||||
|
|
@ -16,14 +20,12 @@ struct QueueAllocation
|
|||
|
||||
struct Device final
|
||||
{
|
||||
using NameString = eastl::fixed_string<char, 32, false>;
|
||||
|
||||
NameString m_Name;
|
||||
vk::PhysicalDevice m_PhysicalDevice = nullptr;
|
||||
vk::Device m_Device = nullptr;
|
||||
VmaAllocator m_Allocator = nullptr;
|
||||
|
||||
Device(const Context *context, PhysicalDevice *physicalDevice, const vk::PhysicalDeviceFeatures *enabledFeatures,
|
||||
const eastl::vector<QueueAllocation> &queueAllocations, NameString name);
|
||||
|
||||
const eastl::vector<QueueAllocation> &queueAllocations, NameString &&name);
|
||||
~Device();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ toCstr(const T &val)
|
|||
return buffer.c_str();
|
||||
}
|
||||
|
||||
using NameString = eastl::fixed_string<char, 32, false>;
|
||||
|
||||
// TODO: Check why inline namespaces aren't working in MSVC 19.27.29110
|
||||
using namespace std::literals::string_literals;
|
||||
using namespace std::literals::string_view_literals;
|
||||
|
|
|
|||
|
|
@ -5,53 +5,68 @@
|
|||
|
||||
#include "physical_device.h"
|
||||
|
||||
#include "context.h"
|
||||
#include "window.h"
|
||||
|
||||
[[nodiscard]] vk::SurfaceCapabilitiesKHR
|
||||
GetSurfaceCapabilities(const 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;
|
||||
}
|
||||
|
||||
[[nodiscard]] eastl::vector<vk::SurfaceFormatKHR>
|
||||
getSurfaceFormats(const vk::SurfaceKHR surface, const vk::PhysicalDevice physicalDevice)
|
||||
GetSurfaceFormats(const vk::PhysicalDevice physicalDevice, const vk::SurfaceKHR surface)
|
||||
{
|
||||
// vk::Result::eIncomplete should not occur in this function. The rest are errors. Thus, abort is allowed.
|
||||
u32 count = 0;
|
||||
vk::Result result = physicalDevice.getSurfaceFormatsKHR(surface, &count, nullptr);
|
||||
ERROR_IF(failed(result), "Could not get surface formats. Cause: {}", to_string(result))
|
||||
ERROR_IF(failed(result), "Could not get surface formats. Cause: {}", result)
|
||||
THEN_ABORT(result);
|
||||
|
||||
eastl::vector<vk::SurfaceFormatKHR> surfaceFormats(count);
|
||||
result = physicalDevice.getSurfaceFormatsKHR(surface, &count, surfaceFormats.data());
|
||||
ERROR_IF(failed(result), "Could not get surface formats. Cause: {}", to_string(result))
|
||||
ERROR_IF(failed(result), "Could not get surface formats. Cause: {}", result)
|
||||
THEN_ABORT(result);
|
||||
|
||||
return surfaceFormats;
|
||||
}
|
||||
|
||||
[[nodiscard]] eastl::vector<vk::PresentModeKHR>
|
||||
getSurfacePresentModes(const vk::SurfaceKHR surface, const vk::PhysicalDevice physicalDevice)
|
||||
GetSurfacePresentModes(const vk::PhysicalDevice physicalDevice, const vk::SurfaceKHR surface)
|
||||
{
|
||||
// vk::Result::eIncomplete should not occur in this function. The rest are errors. Thus, abort is allowed.
|
||||
u32 count = 0;
|
||||
vk::Result result = physicalDevice.getSurfacePresentModesKHR(surface, &count, nullptr);
|
||||
ERROR_IF(failed(result), "Could not get present modes. Cause: {}", to_string(result))
|
||||
ERROR_IF(failed(result), "Could not get present modes. Cause: {}", result)
|
||||
THEN_ABORT(result);
|
||||
|
||||
eastl::vector<vk::PresentModeKHR> presentModes(count);
|
||||
result = physicalDevice.getSurfacePresentModesKHR(surface, &count, presentModes.data());
|
||||
ERROR_IF(failed(result), "Could not get present modes. Cause: {}", to_string(result))
|
||||
ERROR_IF(failed(result), "Could not get present modes. Cause: {}", result)
|
||||
THEN_ABORT(result);
|
||||
|
||||
return presentModes;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool
|
||||
getQueuePresentSupport(const u32 queueFamilyIndex, vk::SurfaceKHR surface, const vk::PhysicalDevice physicalDevice)
|
||||
GetQueuePresentSupport(const u32 queueFamilyIndex, vk::SurfaceKHR surface, const vk::PhysicalDevice physicalDevice)
|
||||
{
|
||||
b32 supported = false;
|
||||
const vk::Result result = physicalDevice.getSurfaceSupportKHR(queueFamilyIndex, surface, &supported);
|
||||
ERROR_IF(failed(result), "Could not get queue family surface support. Cause: {}", to_string(result))
|
||||
ERROR_IF(failed(result), "Could not get queue family surface support. Cause: {}", result)
|
||||
THEN_ABORT(result);
|
||||
|
||||
return supported;
|
||||
}
|
||||
|
||||
[[nodiscard]] eastl::fixed_vector<vk::QueueFamilyProperties, 32>
|
||||
getQueueFamilyProperties(const vk::PhysicalDevice physicalDevice)
|
||||
GetQueueFamilyProperties(const vk::PhysicalDevice physicalDevice)
|
||||
{
|
||||
// Devices rarely have more than 32 queue families. Thus fixed vector
|
||||
u32 count = 0;
|
||||
|
|
@ -65,10 +80,10 @@ getQueueFamilyProperties(const vk::PhysicalDevice physicalDevice)
|
|||
|
||||
// Size 384 return.
|
||||
[[nodiscard]] eastl::vector<QueueFamilyInfo>
|
||||
getQueueFamilies(const vk::SurfaceKHR surface, const vk::PhysicalDevice physicalDevice)
|
||||
GetQueueFamilies(const vk::SurfaceKHR surface, const vk::PhysicalDevice physicalDevice)
|
||||
{
|
||||
|
||||
auto queueFamilyProperties = getQueueFamilyProperties(physicalDevice);
|
||||
auto queueFamilyProperties = GetQueueFamilyProperties(physicalDevice);
|
||||
|
||||
eastl::vector<QueueFamilyInfo> queueFamilyInfos;
|
||||
queueFamilyInfos.reserve(queueFamilyProperties.size());
|
||||
|
|
@ -93,7 +108,7 @@ getQueueFamilies(const vk::SurfaceKHR surface, const vk::PhysicalDevice physical
|
|||
support |= QueueSupportFlagBits::eCompute;
|
||||
}
|
||||
|
||||
if (getQueuePresentSupport(familyIndex, surface, physicalDevice))
|
||||
if (GetQueuePresentSupport(familyIndex, surface, physicalDevice))
|
||||
{
|
||||
support |= QueueSupportFlagBits::ePresent;
|
||||
}
|
||||
|
|
@ -115,24 +130,24 @@ PhysicalDevice::PhysicalDevice(const vk::SurfaceKHR surface, const vk::PhysicalD
|
|||
physicalDevice.getProperties(&m_DeviceProperties);
|
||||
physicalDevice.getFeatures(&m_DeviceFeatures);
|
||||
|
||||
m_SurfaceFormats = getSurfaceFormats(surface, physicalDevice);
|
||||
m_PresentModes = getSurfacePresentModes(surface, physicalDevice);
|
||||
m_QueueFamilies = getQueueFamilies(surface, physicalDevice);
|
||||
m_SurfaceFormats = GetSurfaceFormats(physicalDevice, surface);
|
||||
m_PresentModes = GetSurfacePresentModes(physicalDevice, surface);
|
||||
m_QueueFamilies = GetQueueFamilies(surface, physicalDevice);
|
||||
|
||||
m_PhysicalDevice = physicalDevice;
|
||||
}
|
||||
|
||||
eastl::fixed_vector<vk::PhysicalDevice, 8>
|
||||
enumeratePhysicalDevices(const vk::Instance instance)
|
||||
EnumeratePhysicalDevices(const vk::Instance instance)
|
||||
{
|
||||
u32 count = 0;
|
||||
vk::Result result = instance.enumeratePhysicalDevices(&count, nullptr);
|
||||
ERROR_IF(failed(result), "Could not fetch vulkan devices. Cause: {}", to_string(result))
|
||||
ERROR_IF(failed(result), "Could not fetch vulkan devices. Cause: {}", result)
|
||||
THEN_ABORT(result);
|
||||
|
||||
eastl::fixed_vector<vk::PhysicalDevice, 8> physicalDevices(count);
|
||||
result = instance.enumeratePhysicalDevices(&count, physicalDevices.data());
|
||||
ERROR_IF(failed(result), "Could not fetch vulkan devices. Cause: {}", to_string(result))
|
||||
ERROR_IF(failed(result), "Could not fetch vulkan devices. Cause: {}", result)
|
||||
THEN_ABORT(result);
|
||||
|
||||
return physicalDevices;
|
||||
|
|
@ -141,7 +156,7 @@ enumeratePhysicalDevices(const vk::Instance instance)
|
|||
PhysicalDevices::PhysicalDevices(const Window *window, const Context *context)
|
||||
{
|
||||
auto surface = window->m_Surface;
|
||||
auto physicalDevices = enumeratePhysicalDevices(context->m_Instance);
|
||||
auto physicalDevices = EnumeratePhysicalDevices(context->m_Instance);
|
||||
for (auto physicalDevice : physicalDevices)
|
||||
{
|
||||
this->emplace_back(surface, physicalDevice);
|
||||
|
|
|
|||
|
|
@ -6,9 +6,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "global.h"
|
||||
#include "window.h"
|
||||
#include <EASTL/fixed_vector.h>
|
||||
|
||||
struct Window;
|
||||
struct Context;
|
||||
|
||||
enum class QueueSupportFlagBits
|
||||
{
|
||||
eGraphics = 0b0001,
|
||||
|
|
@ -26,6 +28,15 @@ struct QueueFamilyInfo
|
|||
QueueSupportFlags m_Support;
|
||||
};
|
||||
|
||||
[[nodiscard]] vk::SurfaceCapabilitiesKHR
|
||||
GetSurfaceCapabilities(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface);
|
||||
|
||||
[[nodiscard]] eastl::vector<vk::SurfaceFormatKHR>
|
||||
GetSurfaceFormats(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface);
|
||||
|
||||
[[nodiscard]] eastl::vector<vk::PresentModeKHR>
|
||||
GetSurfacePresentModes(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface);
|
||||
|
||||
struct PhysicalDevice
|
||||
{
|
||||
vk::PhysicalDevice m_PhysicalDevice;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,111 @@
|
|||
/// =============================================
|
||||
// Aster: swapchain.cpp
|
||||
// Copyright (c) 2020-2024 Anish Bhobe
|
||||
// ==============================================
|
||||
|
||||
#include "swapchain.h"
|
||||
|
||||
#include "device.h"
|
||||
#include "physical_device.h"
|
||||
#include "window.h"
|
||||
|
||||
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;
|
||||
|
|
@ -37,7 +47,7 @@ Window::Window(cstr title, Context *context, vk::Extent2D extent, b8 isFullScree
|
|||
m_Window = glfwCreateWindow(cast<i32>(extent.width), cast<i32>(extent.height), m_Name.c_str(),
|
||||
isFullScreen ? monitor : nullptr, nullptr);
|
||||
ERROR_IF(m_Window == nullptr, "Window creation failed")
|
||||
ELSE_DEBUG("Window '{}' created with resolution '{}x{}'", m_Name.c_str(), extent.width, extent.height);
|
||||
ELSE_DEBUG("Window '{}' created with resolution '{}x{}'", m_Name, extent.width, extent.height);
|
||||
if (m_Window == nullptr)
|
||||
{
|
||||
auto code = GlfwContext::PostError();
|
||||
|
|
@ -55,9 +65,9 @@ Window::Window(cstr title, Context *context, vk::Extent2D extent, b8 isFullScree
|
|||
VkSurfaceKHR surface;
|
||||
auto result =
|
||||
cast<vk::Result>(glfwCreateWindowSurface(cast<VkInstance>(m_Context->m_Instance), m_Window, nullptr, &surface));
|
||||
ERROR_IF(failed(result), "Failed to create Surface with {}", to_string(result))
|
||||
ERROR_IF(failed(result), "Failed to create Surface with {}", result)
|
||||
THEN_ABORT(result)
|
||||
ELSE_DEBUG("Surface {} Created", m_Name.c_str());
|
||||
ELSE_DEBUG("Surface {} Created", m_Name);
|
||||
m_Surface = vk::SurfaceKHR(surface);
|
||||
}
|
||||
|
||||
|
|
@ -75,5 +85,5 @@ Window::~Window()
|
|||
m_Window = nullptr;
|
||||
}
|
||||
|
||||
DEBUG("Window '{}' Destroyed", m_Name.c_str());
|
||||
DEBUG("Window '{}' Destroyed", m_Name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "context.h"
|
||||
#include "global.h"
|
||||
#include <EASTL/fixed_string.h>
|
||||
|
||||
struct Context;
|
||||
|
||||
struct Window final
|
||||
{
|
||||
// fields
|
||||
|
|
@ -28,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