159 lines
5.5 KiB
C++
159 lines
5.5 KiB
C++
#pragma once
|
|
|
|
#include "vertex.hpp"
|
|
|
|
#include <optional>
|
|
#include <set>
|
|
#include <unordered_map>
|
|
#include <vulkan/vulkan_core.h>
|
|
|
|
namespace gz::vk {
|
|
/**
|
|
* @name Convenience structs
|
|
* @details
|
|
* Structures and functionas making usiing the vulkan api more convenient
|
|
* @{
|
|
*/
|
|
/**
|
|
* @brief Struct containing all physical device features structs
|
|
* @details
|
|
* Make sure to call vkGetPhysicalDeviceFeatures2 with the f member, not this struct itself
|
|
*/
|
|
struct PhysicalDeviceFeatures {
|
|
/**
|
|
* @brief Initialize the structs with sType and pNext chain f -> f11 -> f12 -> f13
|
|
*/
|
|
PhysicalDeviceFeatures();
|
|
VkPhysicalDeviceFeatures2 f{};
|
|
VkPhysicalDeviceVulkan11Features f11{};
|
|
VkPhysicalDeviceVulkan12Features f12{};
|
|
VkPhysicalDeviceVulkan13Features f13{};
|
|
/**
|
|
* @brief Check if all features enabled in requiredFeatures are enabled in this
|
|
*/
|
|
bool requiredFeaturesAvailable(const PhysicalDeviceFeatures& requiredFeatures) const;
|
|
};
|
|
|
|
enum PipelineT {
|
|
PL_3D, PL_2D
|
|
};
|
|
struct Pipeline {
|
|
VkPipeline pipeline;
|
|
VkPipelineLayout layout;
|
|
void operator=(const Pipeline& other) = delete;
|
|
};
|
|
|
|
/**
|
|
* @brief Map holding pipelines
|
|
*/
|
|
class PipelineContainer {
|
|
public:
|
|
using iterator = std::unordered_map<PipelineT, Pipeline>::iterator;
|
|
Pipeline& operator[](const PipelineT& key) { return pipelines[key]; }
|
|
/**
|
|
* @brief Destroy the pipeline+layout and then remove the handles from the underlying map
|
|
*/
|
|
void erase(const PipelineT& key, VkDevice& device, const VkAllocationCallbacks* pAllocator=nullptr);
|
|
/**
|
|
* @brief Destroy the pipeline+layout and then remove the handles from the underlying map
|
|
*/
|
|
iterator erase(const iterator& it, VkDevice& device, const VkAllocationCallbacks* pAllocator=nullptr);
|
|
/**
|
|
* @brief Destroy all pipelines#layouts and then remove the handles from the underlying map
|
|
*/
|
|
void destroy(VkDevice& device, const VkAllocationCallbacks* pAllocator=nullptr);
|
|
iterator begin() { return pipelines.begin(); }
|
|
iterator end() { return pipelines.end(); }
|
|
size_t size() const { return pipelines.size(); }
|
|
private:
|
|
std::unordered_map<PipelineT, Pipeline> pipelines;
|
|
|
|
};
|
|
|
|
struct SwapChainSupport {
|
|
VkSurfaceCapabilitiesKHR capabilities;
|
|
std::vector<VkSurfaceFormatKHR> formats;
|
|
std::vector<VkPresentModeKHR> presentModes;
|
|
};
|
|
|
|
|
|
template<typename T>
|
|
concept SupportedIndexType = std::same_as<T, uint16_t> or std::same_as<T, uint32_t>;
|
|
|
|
template<SupportedIndexType T>
|
|
struct VerticesAndIndices {
|
|
std::vector<Vertex3D> vertices;
|
|
std::vector<T> indices;
|
|
constexpr VkIndexType getIndexType() const {
|
|
if (std::same_as<T, uint16_t>) {
|
|
return VK_INDEX_TYPE_UINT16;
|
|
}
|
|
else if (std::same_as<T, uint32_t>) {
|
|
return VK_INDEX_TYPE_UINT32;
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
struct QueueFamilyIndices {
|
|
std::optional<uint32_t> graphicsFamily;
|
|
std::optional<uint32_t> presentFamily;
|
|
std::optional<uint32_t> transferFamily;
|
|
|
|
bool hasNecessaryValues() {
|
|
return graphicsFamily.has_value() && presentFamily.has_value();
|
|
}
|
|
bool hasAllValues() {
|
|
return graphicsFamily.has_value() && presentFamily.has_value() && transferFamily.has_value();
|
|
}
|
|
|
|
std::string toString() const {
|
|
std::string s = "[ ";
|
|
s += "graphicsFamily: ";
|
|
if (graphicsFamily.has_value()) { s += std::to_string(graphicsFamily.value()); }
|
|
else { s += "not set"; }
|
|
s += ", presentFamily: ";
|
|
if (presentFamily.has_value()) { s += std::to_string(presentFamily.value()); }
|
|
else { s += "not set"; }
|
|
s += ", transferFamily: ";
|
|
if (transferFamily.has_value()) { s += std::to_string(transferFamily.value()); }
|
|
else { s += "not set"; }
|
|
return s + " ]";
|
|
}
|
|
};
|
|
|
|
|
|
/**
|
|
* @brief Get a VkDependencyInfo struct for a single image memory barrier
|
|
*/
|
|
VkDependencyInfo getDepInfo(const VkImageMemoryBarrier2& barrier);
|
|
/// @}
|
|
|
|
/**
|
|
* @brief Used for debugging
|
|
* @see VulkanInstance::debugLog
|
|
* @details
|
|
* Handles like VkDevice are pointers to the actual handle.
|
|
* Register the handle to a vulkan object with this struct and call updateHandles().
|
|
* The handles set will then contain the actual address of the handle, as printed by the validation layers.
|
|
* That means you can check a handle returned by a validation layer
|
|
* with this struct and see if this handle belongs to object that created this struct.
|
|
* @warning
|
|
* Every pointer you submit to this must stay valid!
|
|
* Use this struct only when debugging!
|
|
*/
|
|
struct ObjectUsingVulkan {
|
|
ObjectUsingVulkan(std::string&& name, std::vector<void*>&& ptrsToHandles, std::vector<void*>&& vectorWithPtrsToHandles);
|
|
std::string objectName;
|
|
std::vector<void*> ptrToHandle;
|
|
std::vector<std::vector<void*>*> vectorWithPtrToHandle;
|
|
std::set<uint64_t> handles;
|
|
/**
|
|
* @brief Update the handles map with the current handle (aka segfault generator)
|
|
*/
|
|
void updateHandles();
|
|
|
|
};
|
|
|
|
} // namespace gz::vk
|