Files
OpenVulkano/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp
2024-07-23 01:21:27 +02:00

140 lines
3.8 KiB
C++

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
// Workaround for libc++
#ifndef __cpp_lib_three_way_comparison
#define __cpp_lib_three_way_comparison 201907
#endif
#include "IShaderOwner.hpp"
#include "MemoryPool.hpp"
#include "Base/Wrapper.hpp"
#include "Base/Render/IResourceManager.hpp"
#include "Vulkan/Image.hpp"
#include "Scene/Shader/DescriptorInputDescription.hpp"
#include <vulkan/vulkan.hpp>
#include <map>
#include <memory>
#include <mutex>
namespace OpenVulkano
{
namespace Scene
{
class Node;
class Geometry;
class Material;
class Texture;
class Shader;
class Camera;
class UniformBuffer;
}
namespace Vulkan
{
class Context;
class VulkanGeometry;
class VulkanTexture;
class VulkanCamera;
class VulkanNode;
class VulkanShader;
class VulkanUniformBuffer;
class UniformBuffer;
class ManagedBuffer;
class MemoryAllocation;
class ResourceManager : public IShaderOwner, public IResourceManager
{
friend UniformBuffer;
friend VulkanTexture;
struct FrameResources;
Context* context;
vk::Device device = nullptr;
vk::Queue transferQueue = nullptr;
Array<FrameResources> frameResources;
MemoryPool memPool;
std::vector<Unique<VulkanShader>> shaders;
std::vector<Unique<VulkanGeometry>> geometries;
std::vector<Unique<VulkanNode>> nodes;
std::vector<Unique<VulkanTexture>> textures;
std::vector<Unique<VulkanCamera>> cameras;
std::vector<Unique<VulkanUniformBuffer>> uniforms;
std::mutex mutex;
vk::DeviceSize uniformBufferAlignment;
vk::DescriptorPool descriptorPool;
std::map<DescriptorSetLayoutBinding, vk::DescriptorSetLayout> descriptorSetLayoutCache;
std::map<vk::SamplerCreateInfo, vk::Sampler> samplerCache;
int currentBuffer = -1;
vk::CommandBuffer& GetCmdBuffer();
public:
static ResourceManager* INSTANCE;
ResourceManager();
virtual ~ResourceManager() noexcept;
void Init(Context* context, int buffers = 2);
void Close();
void StartFrame(uint64_t frameId);
vk::Semaphore EndFrame();
void Resize();
VulkanGeometry* PrepareGeometry(Scene::Geometry* geometry);
void PrepareMaterial(Scene::Material* material);
VulkanUniformBuffer* PrepareUniformBuffer(Scene::UniformBuffer* buffer);
VulkanNode* PrepareNode(Scene::Node* node);
VulkanTexture* PrepareTexture(Scene::Texture* texture);
VulkanCamera* PrepareCamera(Scene::Camera* camera);
void RemoveShader(VulkanShader* shader) override;
void CopyDataToImage(vk::DeviceSize size, void* data, OpenVulkano::Vulkan::Image* image);
MemoryPool::ManagedBufferPtr CreateSharedMemoryBuffer(size_t size);
[[nodiscard]] Context* GetContext() const { return context; }
[[nodiscard]] vk::Device GetDevice() const { return device; }
UniformBuffer* CreateUniformBuffer(const DescriptorSetLayoutBinding& binding, size_t size, void* data, uint32_t setId = 2, bool hostVis = false);
vk::Sampler CreateSampler(const vk::SamplerCreateInfo& samplerConfig);
[[nodiscard]] Unique<Scene::Texture> CreateSharedMemoryTexture(const Math::Vector3ui& resolution, DataFormat format) override;
protected: // Allocation management
MemoryPool::ManagedBufferPtr CreateDeviceOnlyBufferWithData(vk::DeviceSize size, vk::BufferUsageFlagBits usage, const void* data);
inline void RecordCopy(vk::Buffer src, vk::Buffer dest, vk::DeviceSize size)
{
vk::BufferCopy copyRegion = { 0, 0, size };
GetCmdBuffer().copyBuffer(src, dest, 1, &copyRegion);
}
public:
vk::DescriptorSetLayout* GetDescriptorLayoutSet(const DescriptorSetLayoutBinding& descriptorSetLayoutBinding);
VulkanShader* CreateShader(Scene::Shader* shader);
};
}
}