Compare commits
2 Commits
44173ffdbc
...
75bb1ca895
| Author | SHA1 | Date |
|---|---|---|
|
|
75bb1ca895 | |
|
|
ce4dd9b096 |
|
|
@ -0,0 +1,45 @@
|
|||
---
|
||||
Checks: 'clang-diagnostic-*,clang-analyzer-*,-*,cppcoreguidelines-pro-type-member-init,modernize-redundant-void-arg,modernize-use-bool-literals,modernize-use-default-member-init,modernize-use-nullptr,readability-braces-around-statements,readability-redundant-member-init'
|
||||
WarningsAsErrors: ''
|
||||
HeaderFilterRegex: ''
|
||||
FormatStyle: none
|
||||
CheckOptions:
|
||||
- key: cert-dcl16-c.NewSuffixes
|
||||
value: 'L;LL;LU;LLU'
|
||||
- key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField
|
||||
value: '0'
|
||||
- key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors
|
||||
value: '1'
|
||||
- key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
|
||||
value: '1'
|
||||
- key: cppcoreguidelines-pro-type-member-init.IgnoreArrays
|
||||
value: '1'
|
||||
- key: cppcoreguidelines-pro-type-member-init.UseAssignment
|
||||
value: '1'
|
||||
- key: google-readability-function-size.StatementThreshold
|
||||
value: '800'
|
||||
- key: google-readability-namespace-comments.ShortNamespaceLines
|
||||
value: '10'
|
||||
- key: google-readability-namespace-comments.SpacesBeforeComments
|
||||
value: '2'
|
||||
- key: modernize-loop-convert.MaxCopySize
|
||||
value: '16'
|
||||
- key: modernize-loop-convert.MinConfidence
|
||||
value: reasonable
|
||||
- key: modernize-loop-convert.NamingStyle
|
||||
value: CamelCase
|
||||
- key: modernize-pass-by-value.IncludeStyle
|
||||
value: llvm
|
||||
- key: modernize-replace-auto-ptr.IncludeStyle
|
||||
value: llvm
|
||||
- key: modernize-use-bool-literals.IgnoreMacros
|
||||
value: '0'
|
||||
- key: modernize-use-default-member-init.IgnoreMacros
|
||||
value: '0'
|
||||
- key: modernize-use-default-member-init.UseAssignment
|
||||
value: '1'
|
||||
- key: modernize-use-nullptr.NullMacros
|
||||
value: 'NULL'
|
||||
- key: readability-braces-around-statements.ShortStatementLines
|
||||
value: '0'
|
||||
...
|
||||
|
|
@ -10,10 +10,23 @@ find_package(Vulkan REQUIRED)
|
|||
find_package(fmt CONFIG REQUIRED)
|
||||
find_package(VulkanMemoryAllocator CONFIG REQUIRED)
|
||||
|
||||
set(HEADER_FILES constants.h config.h logger.h global.h context.h window.h
|
||||
physical_device.h)
|
||||
set(SOURCE_FILES logger.cpp global.cpp context.cpp window.cpp
|
||||
physical_device.cpp)
|
||||
set(HEADER_FILES
|
||||
constants.h
|
||||
config.h
|
||||
logger.h
|
||||
global.h
|
||||
context.h
|
||||
window.h
|
||||
physical_device.h
|
||||
device.h)
|
||||
|
||||
set(SOURCE_FILES
|
||||
logger.cpp
|
||||
global.cpp
|
||||
context.cpp
|
||||
window.cpp
|
||||
physical_device.cpp
|
||||
device.cpp)
|
||||
|
||||
add_library(aster_core STATIC ${SOURCE_FILES} ${HEADER_FILES})
|
||||
set_property(TARGET aster_core PROPERTY CXX_STANDARD 20)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@
|
|||
#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
|
||||
#define VULKAN_HPP_NO_STRUCT_CONSTRUCTORS
|
||||
|
||||
#define VMA_STATIC_VULKAN_FUNCTIONS 0
|
||||
#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1
|
||||
|
||||
#if defined(NDEBUG)
|
||||
#define USE_OPTICK (0)
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -49,21 +49,17 @@ constexpr auto ANSI_Cyan = "\u001b[36m";
|
|||
constexpr auto ANSI_White = "\u001b[37m";
|
||||
constexpr auto ANSI_Reset = "\u001b[0m";
|
||||
|
||||
using std::forward;
|
||||
using std::move;
|
||||
using std::tie;
|
||||
|
||||
template <typename T>
|
||||
using Option = std::optional<T>;
|
||||
|
||||
template <typename type_t, typename from_t>
|
||||
constexpr auto cast(from_t &&_in) {
|
||||
return static_cast<type_t>(forward<from_t>(_in));
|
||||
return static_cast<type_t>(std::forward<from_t>(_in));
|
||||
}
|
||||
|
||||
template <typename type_t, typename from_t>
|
||||
constexpr auto recast(from_t &&_in) {
|
||||
return reinterpret_cast<type_t>(forward<from_t>(_in));
|
||||
return reinterpret_cast<type_t>(std::forward<from_t>(_in));
|
||||
}
|
||||
|
||||
constexpr f32 operator""_deg(long double degrees) {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ void Context::init(const std::string_view &_app_name, const Version &_app_versio
|
|||
.applicationVersion = VK_MAKE_VERSION(_app_version.major, _app_version.minor, _app_version.patch),
|
||||
.pEngineName = PROJECT_NAME,
|
||||
.engineVersion = VK_MAKE_VERSION(VERSION.major, VERSION.minor, VERSION.patch),
|
||||
.apiVersion = VK_API_VERSION_1_2,
|
||||
.apiVersion = ASTER_API_VERSION,
|
||||
};
|
||||
|
||||
vk::DebugUtilsMessengerCreateInfoEXT debug_messenger_create_info = {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
// =============================================
|
||||
// Aster: device.h
|
||||
// Copyright (c) 2020-2024 Anish Bhobe
|
||||
// =============================================
|
||||
|
||||
#include "device.h"
|
||||
|
||||
Device::Device(const Context *_context, PhysicalDevice &&_physical_device, const vk::PhysicalDeviceFeatures *_enabled_features, const std::vector<QueueAllocation> &_queue_allocation, std::optional<std::string> _name) :
|
||||
physical_device{ std::move(_physical_device) },
|
||||
name{ std::move(_name) } {
|
||||
std::vector<vk::DeviceQueueCreateInfo> queue_create_infos;
|
||||
queue_create_infos.reserve(_queue_allocation.size());
|
||||
|
||||
u32 num_priorities = 0;
|
||||
for (auto [_, count] : _queue_allocation) {
|
||||
num_priorities = std::max(count, num_priorities);
|
||||
}
|
||||
std::vector priorities(num_priorities, 1.0f);
|
||||
|
||||
for (auto [family, count] : _queue_allocation) {
|
||||
queue_create_infos.push_back({
|
||||
.queueFamilyIndex = family,
|
||||
.queueCount = count,
|
||||
.pQueuePriorities = priorities.data(),
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
device = physical_device.device.createDevice({
|
||||
.queueCreateInfoCount = cast<u32>(queue_create_infos.size()),
|
||||
.pQueueCreateInfos = queue_create_infos.data(),
|
||||
.enabledLayerCount = _context->enable_validation_layers ? cast<u32>(_context->validation_layers.size()) : 0,
|
||||
.ppEnabledLayerNames = _context->enable_validation_layers ? _context->validation_layers.data() : nullptr,
|
||||
.enabledExtensionCount = cast<u32>(_context->device_extensions.size()),
|
||||
.ppEnabledExtensionNames = _context->device_extensions.data(),
|
||||
.pEnabledFeatures = _enabled_features,
|
||||
});
|
||||
} catch (const std::exception &_err) {
|
||||
ERROR("Could not initialize Vulkan Device. Cause: {}", _err.what());
|
||||
throw;
|
||||
}
|
||||
|
||||
INFO("{} ({}) Initialized!", name.value_or(DEFAULT_DEVICE_NAME), physical_device.properties.deviceName.data());
|
||||
|
||||
VmaVulkanFunctions vma_vulkan_functions = {
|
||||
.vkGetInstanceProcAddr = vk::defaultDispatchLoaderDynamic.vkGetInstanceProcAddr,
|
||||
.vkGetDeviceProcAddr = vk::defaultDispatchLoaderDynamic.vkGetDeviceProcAddr,
|
||||
};
|
||||
|
||||
const VmaAllocatorCreateInfo vma_allocator_create_info = {
|
||||
.flags = 0,
|
||||
.physicalDevice = physical_device.device,
|
||||
.device = device,
|
||||
.pVulkanFunctions = &vma_vulkan_functions,
|
||||
.instance = _context->instance,
|
||||
.vulkanApiVersion = ASTER_API_VERSION,
|
||||
};
|
||||
|
||||
const auto result = cast<vk::Result>(vmaCreateAllocator(&vma_allocator_create_info, &allocator));
|
||||
if (failed(result)) {
|
||||
device.destroy();
|
||||
auto _err = fmt::format("Memory allocator creation failed. Cause: {}", to_string(result));
|
||||
ERROR("{}", _err);
|
||||
throw std::runtime_error(_err);
|
||||
}
|
||||
VERBOSE("Memory Allocator Created");
|
||||
|
||||
INFO("Created '{}' Successfully", name.value_or(DEFAULT_DEVICE_NAME));
|
||||
}
|
||||
|
||||
Device::~Device() {
|
||||
if (allocator) {
|
||||
vmaDestroyAllocator(allocator);
|
||||
allocator = nullptr;
|
||||
VERBOSE("Memory Allocator Destroyed");
|
||||
}
|
||||
device.destroy();
|
||||
INFO("Device '{}' Destroyed", name.value_or(DEFAULT_DEVICE_NAME));
|
||||
name = std::nullopt;
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// =============================================
|
||||
// Aster: device.h
|
||||
// Copyright (c) 2020-2024 Anish Bhobe
|
||||
// =============================================
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "global.h"
|
||||
#include "physical_device.h"
|
||||
|
||||
constexpr std::string DEFAULT_DEVICE_NAME = "<Unnamed GPU>";
|
||||
|
||||
struct QueueAllocation {
|
||||
u32 family;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct Device final {
|
||||
vk::Device device;
|
||||
PhysicalDevice physical_device;
|
||||
VmaAllocator allocator { nullptr };
|
||||
std::optional<std::string> name { nullptr };
|
||||
|
||||
Device(const Context *_context, PhysicalDevice &&_physical_device, const vk::PhysicalDeviceFeatures *_enabled_features, const std::vector<QueueAllocation> &_queue_allocation, std::optional<std::string> _name = std::nullopt);
|
||||
|
||||
~Device();
|
||||
};
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
#include <cstdio>
|
||||
|
||||
#define VMA_IMPLEMENTATION
|
||||
#include <vma/vk_mem_alloc.h>
|
||||
#include <vk_mem_alloc.h>
|
||||
|
||||
// NOTE: Vulkan Dispatch Loader Storage - Should only appear once.
|
||||
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@
|
|||
#include <vk_mem_alloc.h>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
constexpr u32 ASTER_API_VERSION = vk::ApiVersion13;
|
||||
|
||||
#define CODE_LOC " @ " __FILE__ ":" VULKAN_HPP_STRINGIFY(__LINE__)
|
||||
[[nodiscard]] inline bool failed(const vk::Result _result) {
|
||||
return _result != vk::Result::eSuccess;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ struct Logger {
|
|||
return "[DEBUG]:";
|
||||
if constexpr (LogLevel == LogType::eVerbose)
|
||||
return "[VERB]: ";
|
||||
return "";
|
||||
}
|
||||
|
||||
template <LogType LogLevel>
|
||||
|
|
@ -52,12 +53,13 @@ struct Logger {
|
|||
return ANSI_White;
|
||||
if constexpr (LogLevel == LogType::eVerbose)
|
||||
return ANSI_Blue;
|
||||
return ANSI_White;
|
||||
}
|
||||
|
||||
template <LogType LogLevel>
|
||||
void log(const std::string_view &_message, const char *_loc, u32 _line) const {
|
||||
if (cast<u32>(LogLevel) <= minimum_logging_level) {
|
||||
fmt::println("{}{} {}{}| at {}:{}{}", to_color_cstr<LogLevel>(), to_cstr<LogLevel>(), _message.data(), ANSI_Black, _loc, _line, ANSI_Reset);
|
||||
fmt::println("{}{} {} {} at {}:{}{}", to_color_cstr<LogLevel>(), to_cstr<LogLevel>(), _message.data(), ANSI_Black, _loc, _line, ANSI_Reset);
|
||||
}
|
||||
#if !defined(NDEBUG)
|
||||
if constexpr (LogLevel == LogType::eError) {
|
||||
|
|
@ -69,7 +71,7 @@ struct Logger {
|
|||
template <LogType LogLevel>
|
||||
void log_cond(const char *_expr_str, const std::string_view &_message, const char *_loc, u32 _line) const {
|
||||
if (cast<u32>(LogLevel) <= minimum_logging_level) {
|
||||
fmt::println("{}{} ({}) {}{}| at {}:{}{}", to_color_cstr<LogLevel>(), to_cstr<LogLevel>(), _expr_str, _message.data(), ANSI_Black, _loc, _line, ANSI_Reset);
|
||||
fmt::println("{}{} ({}) {} {} at {}:{}{}", to_color_cstr<LogLevel>(), to_cstr<LogLevel>(), _expr_str, _message.data(), ANSI_Black, _loc, _line, ANSI_Reset);
|
||||
}
|
||||
#if !defined(NDEBUG)
|
||||
if constexpr (LogLevel == LogType::eError) {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
#include "aster/constants.h"
|
||||
#include "aster/device.h"
|
||||
#include "aster/glfw_context.h"
|
||||
#include "aster/physical_device.h"
|
||||
#include "aster/window.h"
|
||||
|
||||
constexpr QueueSupportFlags required_queue_support = QueueSupportFlags{} | QueueSupportFlagBits::eGraphics | QueueSupportFlagBits::eCompute | QueueSupportFlagBits::ePresent | QueueSupportFlagBits::eCompute;
|
||||
constexpr QueueSupportFlags required_queue_support = QueueSupportFlags{} | QueueSupportFlagBits::eGraphics | QueueSupportFlagBits::eCompute | QueueSupportFlagBits::ePresent | QueueSupportFlagBits::eTransfer;
|
||||
|
||||
[[nodiscard]] bool is_suitable_device(const PhysicalDevice *_physical_device) {
|
||||
const bool all_required_queues = std::ranges::any_of(_physical_device->queue_families, [](const auto &_qfp) {
|
||||
|
|
@ -28,22 +29,35 @@ PhysicalDevice find_suitable_device(const PhysicalDevices &_physical_devices) {
|
|||
throw std::runtime_error("No suitable device found.");
|
||||
}
|
||||
|
||||
int main(int, char **) {
|
||||
const auto *glfw = new GlfwContext();
|
||||
auto *context = new Context("Aster", VERSION);
|
||||
auto *window = new Window("Aster1", context, { 640, 480 });
|
||||
QueueAllocation find_appropriate_queue_allocation(const PhysicalDevice* _physical_device) {
|
||||
for (auto &_queue_info: _physical_device->queue_families) {
|
||||
if ((_queue_info.support & required_queue_support) == required_queue_support) {
|
||||
return {
|
||||
.family = _queue_info.index,
|
||||
.count = _queue_info.count,
|
||||
};
|
||||
}
|
||||
}
|
||||
throw std::runtime_error("No suitable queue family.");
|
||||
}
|
||||
|
||||
PhysicalDevices physical_devices = { window, context };
|
||||
int main(int, char **) {
|
||||
GlfwContext glfw_context = {};
|
||||
Context context = {"Aster", VERSION};
|
||||
Window window = {"Aster1", &context, { 640, 480 }};
|
||||
|
||||
PhysicalDevices physical_devices = { &window, &context };
|
||||
PhysicalDevice device_to_use = find_suitable_device(physical_devices);
|
||||
|
||||
INFO("Using {} as the primary device.", device_to_use.properties.deviceName.data());
|
||||
|
||||
while (window->poll()) {
|
||||
}
|
||||
vk::PhysicalDeviceFeatures features = {};
|
||||
QueueAllocation queue_allocation = find_appropriate_queue_allocation(&device_to_use);
|
||||
|
||||
delete window;
|
||||
delete context;
|
||||
delete glfw;
|
||||
Device device = { &context, std::move(device_to_use), &features, {queue_allocation}, "Primary Device" };
|
||||
|
||||
while (window.poll()) {
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue