stuffs.
This commit is contained in:
parent
32dd4568c0
commit
d926d29dfa
|
|
@ -23,6 +23,7 @@ namespace dyn::utils {
|
||||||
|
|
||||||
namespace dyn::utils {
|
namespace dyn::utils {
|
||||||
extern const std::vector<const char*> vk_validation_layers;
|
extern const std::vector<const char*> vk_validation_layers;
|
||||||
|
extern const std::vector<const char*> vk_device_extensions;
|
||||||
|
|
||||||
VkBool32 vk_debug_message_callback(
|
VkBool32 vk_debug_message_callback(
|
||||||
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||||
|
|
@ -42,4 +43,4 @@ namespace dyn::utils {
|
||||||
|
|
||||||
#define dyn_vk_verify(f) { \
|
#define dyn_vk_verify(f) { \
|
||||||
VkResult res = f; \
|
VkResult res = f; \
|
||||||
DYN_ASSERT(res == VK_SUCCESS, "Vulkan error occured", string_VkResult(res), "at line", __LINE__, "in file", __FILE__); }
|
DYN_ASSERT(res == VK_SUCCESS, "Vulkan error occured", string_VkResult(res), "at line", __LINE__, "in file", __FILE__, "at function call", #f); }
|
||||||
|
|
@ -33,14 +33,24 @@ namespace dyn::core {
|
||||||
|
|
||||||
[[nodiscard]] static bool check_api_version_support(uint32_t api_version);
|
[[nodiscard]] static bool check_api_version_support(uint32_t api_version);
|
||||||
|
|
||||||
|
[[nodiscard]] static ref<vulkan_device> get_last_selected_logical_device() { return s_current_device; }
|
||||||
|
|
||||||
|
void single_cmd(std::function<void(VkCommandBuffer)> cmdFunc);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VkInstance _instance = nullptr;
|
VkInstance _instance = nullptr;
|
||||||
ref<vulkan_physical_device> _physical_device;
|
ref<vulkan_physical_device> _physical_device;
|
||||||
|
ref<vulkan_device> _device;
|
||||||
|
|
||||||
|
VkCommandPool _command_pool;
|
||||||
|
|
||||||
VkDebugUtilsMessengerEXT _debug_messenger = nullptr;
|
VkDebugUtilsMessengerEXT _debug_messenger = nullptr;
|
||||||
|
|
||||||
VkSurfaceKHR _surface = nullptr;
|
VkSurfaceKHR _surface = nullptr;
|
||||||
|
|
||||||
ref<window> _window;
|
ref<window> _window;
|
||||||
|
|
||||||
|
static ref<vulkan_device> s_current_device;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,12 @@ namespace dyn::core {
|
||||||
static queue_families find(const VkPhysicalDevice& physical_device, const VkSurfaceKHR& surface);
|
static queue_families find(const VkPhysicalDevice& physical_device, const VkSurfaceKHR& surface);
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] VkPhysicalDevice get_physical_device() const { return _physical_device; }
|
[[nodiscard]] VkPhysicalDevice get_handle() const { return _physical_device; }
|
||||||
|
|
||||||
[[nodiscard]] queue_families get_queue_families() const { return _queue_families; }
|
[[nodiscard]] queue_families get_queue_families() const { return _queue_families; }
|
||||||
|
|
||||||
|
[[nodiscard]] VkPhysicalDeviceProperties get_properties() const { return _device_properties; }
|
||||||
|
|
||||||
static VkPhysicalDevice determine_suitable_device(const std::vector<VkPhysicalDevice>& available_devices, const VkSurfaceKHR& surface);
|
static VkPhysicalDevice determine_suitable_device(const std::vector<VkPhysicalDevice>& available_devices, const VkSurfaceKHR& surface);
|
||||||
static uint32_t score_device(const VkPhysicalDevice& device);
|
static uint32_t score_device(const VkPhysicalDevice& device);
|
||||||
|
|
||||||
|
|
@ -37,5 +39,25 @@ namespace dyn::core {
|
||||||
VkPhysicalDevice _physical_device = nullptr;
|
VkPhysicalDevice _physical_device = nullptr;
|
||||||
queue_families _queue_families;
|
queue_families _queue_families;
|
||||||
ref<vulkan_context> _ctx;
|
ref<vulkan_context> _ctx;
|
||||||
|
VkPhysicalDeviceProperties _device_properties;
|
||||||
|
};
|
||||||
|
|
||||||
|
class vulkan_device {
|
||||||
|
public:
|
||||||
|
explicit vulkan_device(const ref<vulkan_physical_device>& physical_device, VkPhysicalDeviceFeatures device_features);
|
||||||
|
~vulkan_device();
|
||||||
|
|
||||||
|
[[nodiscard]] VkDevice get_handle() const { return _device; }
|
||||||
|
|
||||||
|
[[nodiscard]] VkQueue get_graphics_queue() const { return _graphics_queue; }
|
||||||
|
[[nodiscard]] VkQueue get_present_queue() const { return _present_queue; }
|
||||||
|
|
||||||
|
static ref<vulkan_device> create(const std::shared_ptr<vulkan_physical_device>& device, const VkPhysicalDeviceFeatures& device_features);
|
||||||
|
|
||||||
|
private:
|
||||||
|
VkDevice _device = nullptr;
|
||||||
|
|
||||||
|
VkQueue _graphics_queue = VK_NULL_HANDLE;
|
||||||
|
VkQueue _present_queue = VK_NULL_HANDLE;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
40
inc/dyn/platform/vulkan/vulkan_swapchain.h
Normal file
40
inc/dyn/platform/vulkan/vulkan_swapchain.h
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
//
|
||||||
|
// Created by Neo on 2/25/25.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <dyn/platform/vulkan/vulkan_swapchain.h>
|
||||||
|
|
||||||
|
#include "dyn/renderer/swapchain.h"
|
||||||
|
|
||||||
|
namespace dyn::core {
|
||||||
|
class vulkan_swapchain : public swapchain {
|
||||||
|
public:
|
||||||
|
explicit vulkan_swapchain(const ref<vulkan_context>& ctx);
|
||||||
|
~vulkan_swapchain() override;
|
||||||
|
|
||||||
|
void prepare() override;
|
||||||
|
void present() override;
|
||||||
|
|
||||||
|
void resize(uint32_t width, uint32_t height) override;
|
||||||
|
|
||||||
|
[[nodiscard]] VkCommandBuffer current_cmd_buffer() const { return _command_buffers[_current_frame]; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void rebuild();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct swap_image {
|
||||||
|
VkImage image;
|
||||||
|
VkImageView view;
|
||||||
|
};
|
||||||
|
std::vector<swap_image> _swap_images;
|
||||||
|
|
||||||
|
std::vector<VkCommandBuffer> _command_buffers;
|
||||||
|
uint32_t _current_frame = 0;
|
||||||
|
|
||||||
|
VkSwapchainKHR _swapchain;
|
||||||
|
ref<vulkan_context> _ctx;
|
||||||
|
};
|
||||||
|
}
|
||||||
23
inc/dyn/renderer/swapchain.h
Normal file
23
inc/dyn/renderer/swapchain.h
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
//
|
||||||
|
// Created by Neo on 2/25/25.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <dyn/core/base.h>
|
||||||
|
|
||||||
|
#include <dyn/renderer/render_context.h>
|
||||||
|
|
||||||
|
namespace dyn::core {
|
||||||
|
class swapchain {
|
||||||
|
public:
|
||||||
|
swapchain() = default;
|
||||||
|
virtual ~swapchain() = default;
|
||||||
|
|
||||||
|
virtual void resize(uint32_t width, uint32_t height) = 0;
|
||||||
|
virtual void prepare() = 0;
|
||||||
|
virtual void present() = 0;
|
||||||
|
|
||||||
|
ref<swapchain> create(const ref<render_context>& ctx);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -9,6 +9,10 @@ namespace dyn::utils {
|
||||||
"VK_LAYER_KHRONOS_validation"
|
"VK_LAYER_KHRONOS_validation"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const std::vector<const char*> vk_device_extensions = {
|
||||||
|
VK_KHR_SWAPCHAIN_EXTENSION_NAME
|
||||||
|
};
|
||||||
|
|
||||||
VkResult vkCreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT *pMessenger) {
|
VkResult vkCreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT *pMessenger) {
|
||||||
auto func = (PFN_vkCreateDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT");
|
auto func = (PFN_vkCreateDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT");
|
||||||
if (func != nullptr) {
|
if (func != nullptr) {
|
||||||
|
|
|
||||||
|
|
@ -90,11 +90,27 @@ namespace dyn::core {
|
||||||
glfwCreateWindowSurface(_instance, _window->get_window_handle(), nullptr, &_surface);
|
glfwCreateWindowSurface(_instance, _window->get_window_handle(), nullptr, &_surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
// physical device
|
// device
|
||||||
{
|
{
|
||||||
|
|
||||||
_physical_device = vulkan_physical_device::create(self);
|
_physical_device = vulkan_physical_device::create(self);
|
||||||
DYN_DEBUG_LOG("Physical Device Created");
|
DYN_DEBUG_LOG("Physical Device Created");
|
||||||
|
|
||||||
|
VkPhysicalDeviceFeatures device_features{};
|
||||||
|
device_features.samplerAnisotropy = true;
|
||||||
|
|
||||||
|
_device = vulkan_device::create(_physical_device, device_features);
|
||||||
|
s_current_device = _device;
|
||||||
|
}
|
||||||
|
|
||||||
|
// command pool
|
||||||
|
{
|
||||||
|
VkCommandPoolCreateInfo create_info{};
|
||||||
|
create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||||
|
create_info.queueFamilyIndex = _physical_device->get_queue_families().graphics_family.value();
|
||||||
|
create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
||||||
|
|
||||||
|
dyn_vk_verify(vkCreateCommandPool(_device->get_handle(), &create_info, nullptr, &_command_pool));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -121,4 +137,35 @@ namespace dyn::core {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vulkan_context::single_cmd(std::function<void(VkCommandBuffer)> cmdFunc) {
|
||||||
|
VkCommandBufferAllocateInfo cmd_allocate_info{};
|
||||||
|
cmd_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||||
|
cmd_allocate_info.commandPool = _command_pool;
|
||||||
|
cmd_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||||
|
cmd_allocate_info.commandBufferCount = 1;
|
||||||
|
|
||||||
|
VkCommandBuffer cmd_buffer;
|
||||||
|
vkAllocateCommandBuffers(_device->get_handle(), &cmd_allocate_info, &cmd_buffer);
|
||||||
|
|
||||||
|
VkCommandBufferBeginInfo begin_info{};
|
||||||
|
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
|
begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||||
|
|
||||||
|
vkBeginCommandBuffer(cmd_buffer, &begin_info);
|
||||||
|
|
||||||
|
cmdFunc(cmd_buffer);
|
||||||
|
|
||||||
|
vkEndCommandBuffer(cmd_buffer);
|
||||||
|
|
||||||
|
VkSubmitInfo submit_info{};
|
||||||
|
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
|
submit_info.commandBufferCount = 1;
|
||||||
|
submit_info.pCommandBuffers = &cmd_buffer;
|
||||||
|
|
||||||
|
vkQueueSubmit(_device->get_graphics_queue(), 1, &submit_info, VK_NULL_HANDLE);
|
||||||
|
vkQueueWaitIdle(_device->get_graphics_queue());
|
||||||
|
|
||||||
|
vkFreeCommandBuffers(_device->get_handle(), _command_pool, 1, &cmd_buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,10 @@
|
||||||
// Created by Neo on 2/24/25.
|
// Created by Neo on 2/24/25.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <set>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "dyn/platform/vulkan/vulkan.h"
|
||||||
#include "dyn/platform/vulkan/vulkan_context.h"
|
#include "dyn/platform/vulkan/vulkan_context.h"
|
||||||
#include "dyn/platform/vulkan/vulkan_devices.h"
|
#include "dyn/platform/vulkan/vulkan_devices.h"
|
||||||
|
|
||||||
|
|
@ -20,6 +22,9 @@ namespace dyn::core {
|
||||||
vkEnumeratePhysicalDevices(instance, &device_count, devices.data());
|
vkEnumeratePhysicalDevices(instance, &device_count, devices.data());
|
||||||
|
|
||||||
_physical_device = determine_suitable_device(devices, ctx->get_surface());
|
_physical_device = determine_suitable_device(devices, ctx->get_surface());
|
||||||
|
|
||||||
|
vkGetPhysicalDeviceProperties(_physical_device, &_device_properties);
|
||||||
|
|
||||||
_queue_families = queue_families::find(_physical_device, ctx->get_surface());
|
_queue_families = queue_families::find(_physical_device, ctx->get_surface());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,4 +118,63 @@ namespace dyn::core {
|
||||||
ref<vulkan_physical_device> vulkan_physical_device::create(const ref<vulkan_context>& ctx) {
|
ref<vulkan_physical_device> vulkan_physical_device::create(const ref<vulkan_context>& ctx) {
|
||||||
return create_ref<vulkan_physical_device>(ctx);
|
return create_ref<vulkan_physical_device>(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vulkan_device::vulkan_device(const ref<vulkan_physical_device> &physical_device, VkPhysicalDeviceFeatures device_Features) {
|
||||||
|
vulkan_physical_device::queue_families families = physical_device->get_queue_families();
|
||||||
|
|
||||||
|
std::set<uint32_t> queue_family_indices = {families.graphics_family.value(), families.present_family.value()};
|
||||||
|
std::vector<VkDeviceQueueCreateInfo> queue_create_infos;
|
||||||
|
|
||||||
|
float queue_priorities = 1.0f;
|
||||||
|
for (const auto &queue_family : queue_family_indices) {
|
||||||
|
VkDeviceQueueCreateInfo queue_create_info{};
|
||||||
|
queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||||
|
queue_create_info.queueFamilyIndex = queue_family;
|
||||||
|
queue_create_info.queueCount = 1;
|
||||||
|
queue_create_info.pQueuePriorities = &queue_priorities;
|
||||||
|
queue_create_infos.push_back(queue_create_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
VkDeviceCreateInfo create_info{};
|
||||||
|
create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||||
|
create_info.pEnabledFeatures = &device_Features;
|
||||||
|
|
||||||
|
auto device_extensions = std::vector(utils::vk_device_extensions);
|
||||||
|
|
||||||
|
uint32_t device_extension_count = 0;
|
||||||
|
vkEnumerateDeviceExtensionProperties(physical_device->get_handle(), 0, &device_extension_count, nullptr);
|
||||||
|
|
||||||
|
std::vector<VkExtensionProperties> device_property_exts(device_extension_count);
|
||||||
|
vkEnumerateDeviceExtensionProperties(physical_device->get_handle(), 0, &device_extension_count, device_property_exts.data());
|
||||||
|
|
||||||
|
for (const auto &extension : device_property_exts) {
|
||||||
|
if (strcmp(extension.extensionName, VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME) == 0) {
|
||||||
|
device_extensions.push_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& extension : device_extensions) {
|
||||||
|
DYN_DEBUG_LOG("Device", std::string_view(physical_device->get_properties().deviceName), "has device extension:", std::string_view{extension});
|
||||||
|
}
|
||||||
|
|
||||||
|
create_info.enabledExtensionCount = static_cast<uint32_t>(device_extensions.size());
|
||||||
|
create_info.ppEnabledExtensionNames = device_extensions.data();
|
||||||
|
|
||||||
|
create_info.queueCreateInfoCount = static_cast<uint32_t>(queue_create_infos.size());
|
||||||
|
create_info.pQueueCreateInfos = queue_create_infos.data();
|
||||||
|
|
||||||
|
dyn_vk_verify(vkCreateDevice(physical_device->get_handle(), &create_info, nullptr, &_device));
|
||||||
|
|
||||||
|
vkGetDeviceQueue(_device, families.graphics_family.value(), 0, &_graphics_queue);
|
||||||
|
vkGetDeviceQueue(_device, families.present_family.value(), 0, &_present_queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
vulkan_device::~vulkan_device() {
|
||||||
|
vkDestroyDevice(_device, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
ref<vulkan_device> vulkan_device::create(const std::shared_ptr<vulkan_physical_device> &device, const VkPhysicalDeviceFeatures& device_Features) {
|
||||||
|
return create_ref<vulkan_device>(device, device_Features);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user