Polished the initial VMA addition to have more features search for and enabled.

This commit is contained in:
Rebekah 2024-07-25 09:16:29 -04:00
parent 4f71a9849c
commit b2d22a0ac6
Signed by: oneechanhax
GPG Key ID: 0074BF373B812798

View File

@ -32,6 +32,8 @@
#include <SDL2pp/SDL2pp.hh>
#define VMA_IMPLEMENTATION
#define VMA_DEBUG_INITIALIZE_ALLOCATIONS 1 // Obviously its the C++ way, just initialize it since its ez // https://gpuopen-librariesandsdks.github.io/VulkanMemoryAllocator/html/debugging_memory_usage.html
#define VMA_DEBUG_DETECT_CORRUPTION 1 // heap overflow, enable!
#include <vk_mem_alloc.hpp>
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
@ -84,10 +86,10 @@ private:
std::optional<vk::raii::Queue> vk_queue_graphics;
std::optional<vk::raii::Queue> vk_queue_present;
public:
private:
vma::UniqueAllocator vk_allocator;
public:
private:
std::optional<vk::raii::SwapchainKHR> vk_swapchain;
vk::Format vk_swapchain_image_format;
vk::Extent2D vk_swapchain_extent;
@ -119,12 +121,15 @@ public:
bool surface_has_present_modes = false;
bool surface_has_format_modes = false;
std::optional<vk::SampleCountFlagBits> msaa_samples;
std::vector<std::string_view> supported_features_vma_device;
std::vector<vma::AllocatorCreateFlagBits> supported_features_vma_allocator;
bool IsGoodCard() const {
return this->graphics_family.has_value() && this->present_family.has_value() && this->screen_surface && surface_has_present_modes && surface_has_format_modes;
}
} vk_physical_card_info;
public:
private:
VulkanBuffer vk_buffer_vertex; // in order to get a clean destruction sequence, instantiate the DeviceMemory for the vertex buffer first // https://github.com/KhronosGroup/Vulkan-Hpp/blob/6f72ceca515d59f40d64b64cf2734f6261e1f9f2/RAII_Samples/13_InitVertexBuffer/13_InitVertexBuffer.cpp
VulkanBuffer vk_buffer_index; // used to make rendering models more efficent by sharing values
@ -179,7 +184,7 @@ public:
4, 5, 6, 6, 7, 4
};
public:
private:
// https://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/
struct UniformBufferObject { // https://docs.vulkan.org/tutorial/latest/05_Uniform_buffers/01_Descriptor_pool_and_sets.html#_alignment_requirements
alignas(16) glm::mat4 model;
@ -189,18 +194,18 @@ public:
std::vector<VulkanBuffer> vk_buffers_uniform;
std::vector<std::uint8_t*> vk_buffers_uniform_mapped;
public:
private:
vk::SampleCountFlagBits vk_msaa_samples_wanted = vk::SampleCountFlagBits::e8;
vk::SampleCountFlagBits vk_msaa_samples;
VulkanImage vk_color_image;
std::optional<vk::raii::ImageView> vk_color_view;
public:
private:
vk::Format vk_depth_format;
VulkanImage vk_depth_image;
std::optional<vk::raii::ImageView> vk_depth_view;
public:
private:
std::uint32_t vk_texture_mip_levels;
VulkanImage vk_texture_image;
std::optional<vk::raii::ImageView> vk_texture_view;
@ -350,20 +355,42 @@ public:
gfx_card_info.present_family = found_present_family_idx;
cur_score += 5;
const auto CheckDeviceExtensionSupport = [](const vk::PhysicalDevice& gfx_card) -> bool {
const auto available_extensions = gfx_card.enumerateDeviceExtensionProperties();
for (const std::string_view required_ext_name : required_vulkan_device_extensions) {
const auto find_wanted_ext = std::find_if(available_extensions.begin(), available_extensions.end(), [&](const auto& ext_to_test) { return std::string_view(ext_to_test.extensionName) == required_ext_name; });
if (find_wanted_ext == available_extensions.end())
return false;
}
return true;
const auto available_extensions = gfx_card.enumerateDeviceExtensionProperties();
const auto DeviceSupportsExtension = [&available_extensions](const std::string_view required_ext_name) -> bool {
return available_extensions.end() != std::find_if(available_extensions.begin(), available_extensions.end(), [&](const auto& ext_to_test) { return std::string_view(ext_to_test.extensionName) == required_ext_name; });
};
if (!CheckDeviceExtensionSupport(gfx_card)) {
ReturnScore();
continue;
{
bool has_all_required_extensions = true;
for (const std::string_view ext_name_required : required_vulkan_device_extensions) {
if (!DeviceSupportsExtension(ext_name_required)) {
has_all_required_extensions = false;
}
}
if (!has_all_required_extensions) {
ReturnScore();
continue;
}
cur_score += 2;
}
const auto vma_feature_sets = std::array<std::pair<std::vector<std::string_view>, vma::AllocatorCreateFlagBits>, 4> {
std::make_pair(std::vector<std::string_view> { "VK_KHR_dedicated_allocation", "VK_KHR_get_memory_requirements2" }, vma::AllocatorCreateFlagBits::eKhrDedicatedAllocation),
{ { "VK_KHR_bind_memory2" }, vma::AllocatorCreateFlagBits::eKhrBindMemory2 },
{ { "VK_KHR_maintenance4" }, vma::AllocatorCreateFlagBits::eKhrMaintenance4 },
{ { "VK_KHR_maintenance5" }, vma::AllocatorCreateFlagBits::eKhrMaintenance5 }
};
for (const auto& wanted_vma_feature_set : vma_feature_sets) {
bool has_all_required_features = true;
for (const auto& required_device_feature : wanted_vma_feature_set.first)
if (!DeviceSupportsExtension(required_device_feature))
has_all_required_features = false;
if (has_all_required_features) {
for (const auto& required_device_feature : wanted_vma_feature_set.first)
gfx_card_info.supported_features_vma_device.emplace_back(required_device_feature);
gfx_card_info.supported_features_vma_allocator.emplace_back(wanted_vma_feature_set.second);
cur_score += 2;
}
}
cur_score += 2;
if (!device_features.samplerAnisotropy) {
ReturnScore();
@ -433,14 +460,24 @@ public:
return device_queues_we_need;
}(this->vk_physical_card_info.graphics_family.value(), this->vk_physical_card_info.present_family.value());
const std::vector<const char*> enabled_extensions_device = [this]() -> std::vector<const char*> {
std::vector<const char*> enabled_extensions(required_vulkan_device_extensions.begin(), required_vulkan_device_extensions.end());
for (const auto& i : this->vk_physical_card_info.supported_features_vma_device)
enabled_extensions.emplace_back(i.data());
return enabled_extensions;
}();
constexpr vk::PhysicalDeviceFeatures device_features {
.samplerAnisotropy = vk::True
};
const vk::DeviceCreateInfo device_create_info {
.queueCreateInfoCount = static_cast<std::uint32_t>(device_queue_create_infos.size()),
.pQueueCreateInfos = device_queue_create_infos.data(),
.enabledExtensionCount = static_cast<std::uint32_t>(required_vulkan_device_extensions.size()),
.ppEnabledExtensionNames = required_vulkan_device_extensions.data(),
.enabledExtensionCount = static_cast<std::uint32_t>(enabled_extensions_device.size()),
.ppEnabledExtensionNames = enabled_extensions_device.data(),
.pEnabledFeatures = &device_features,
};
this->vk_gpu.emplace(*this->vk_gfx_card, device_create_info);
@ -471,9 +508,16 @@ public:
.vkDestroyBuffer = dispatcher_gpu->vkDestroyBuffer,
.vkCreateImage = dispatcher_gpu->vkCreateImage,
.vkDestroyImage = dispatcher_gpu->vkDestroyImage,
.vkCmdCopyBuffer = dispatcher_gpu->vkCmdCopyBuffer
.vkCmdCopyBuffer = dispatcher_gpu->vkCmdCopyBuffer,
.vkGetBufferMemoryRequirements2KHR = dispatcher_gpu->vkGetBufferMemoryRequirements2KHR,
};
const vma::AllocatorCreateInfo allocator_create_info = {
.flags = [&]() -> vma::AllocatorCreateFlags {
vma::AllocatorCreateFlags enabled_flags;
for (const auto& wanted_feature : this->vk_physical_card_info.supported_features_vma_allocator)
enabled_flags |= wanted_feature;
return enabled_flags;
}(),
.physicalDevice = **this->vk_gfx_card,
.device = **this->vk_gpu,
.pVulkanFunctions = &vulkan_functions,
@ -1130,7 +1174,9 @@ protected:
vma::AllocationCreateFlags ret;
if (wanted_properties & vk::MemoryPropertyFlagBits::eHostVisible)
ret |= vma::AllocationCreateFlagBits::eHostAccessSequentialWrite;
if (wanted_usage == vk::BufferUsageFlagBits::eUniformBuffer)
else
ret |= vma::AllocationCreateFlagBits::eDedicatedMemory;
if (wanted_usage & vk::BufferUsageFlagBits::eUniformBuffer)
ret |= vma::AllocationCreateFlagBits::eMapped;
return ret;
}
@ -1488,6 +1534,8 @@ public:
command_buffer.setViewport(0, viewport);
command_buffer.setScissor(0, scissor);
}
private:
void UpdateUniformBuffer(const std::uint32_t current_image) const {
static auto startTime = std::chrono::high_resolution_clock::now();