Merge branch 'wip'
This commit is contained in:
185
openVulkanoCpp/Base/Render/RenderResource.hpp
Normal file
185
openVulkanoCpp/Base/Render/RenderResource.hpp
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
#include <concepts>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
|
||||
namespace OpenVulkano
|
||||
{
|
||||
namespace Vulkan
|
||||
{
|
||||
class MetalBackedTexture;
|
||||
}
|
||||
|
||||
class RenderResourcePtr;
|
||||
|
||||
class IRenderResourceHelper
|
||||
{
|
||||
friend class RenderResourcePtr;
|
||||
|
||||
protected:
|
||||
void UpdateRenderResource(RenderResourcePtr* resource);
|
||||
|
||||
void ResetRenderResource(RenderResourcePtr* resource);
|
||||
|
||||
virtual void DoRelease() = 0;
|
||||
|
||||
virtual void Release() = 0;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
concept Renderable = std::is_convertible_v<T, RenderResourcePtr&>;
|
||||
|
||||
class RenderResourcePtr final
|
||||
{
|
||||
friend class IRenderResourceHelper;
|
||||
friend class Vulkan::MetalBackedTexture;
|
||||
|
||||
IRenderResourceHelper* renderObject = nullptr;
|
||||
|
||||
public:
|
||||
RenderResourcePtr() = default;
|
||||
RenderResourcePtr(const RenderResourcePtr& ignored) noexcept { /* Do not copy, copy will be created by renderer */ }
|
||||
RenderResourcePtr(RenderResourcePtr&& move) noexcept : renderObject(move.renderObject) { move.renderObject = nullptr; }
|
||||
|
||||
~RenderResourcePtr()
|
||||
{
|
||||
Release();
|
||||
}
|
||||
|
||||
void Release()
|
||||
{
|
||||
if (!renderObject) return;
|
||||
renderObject->DoRelease();
|
||||
renderObject = nullptr;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T* As() { return static_cast<T*>(renderObject); }
|
||||
|
||||
template<class T>
|
||||
operator T() { return static_cast<T>(renderObject); }
|
||||
|
||||
operator bool() const { return renderObject; }
|
||||
|
||||
RenderResourcePtr& operator =(RenderResourcePtr&& move) noexcept
|
||||
{
|
||||
if (renderObject) renderObject->Release();
|
||||
renderObject = move.renderObject;
|
||||
move.renderObject = nullptr;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
inline void IRenderResourceHelper::UpdateRenderResource(RenderResourcePtr* resource)
|
||||
{
|
||||
if (resource)
|
||||
resource->renderObject = this;
|
||||
}
|
||||
|
||||
inline void IRenderResourceHelper::ResetRenderResource(RenderResourcePtr* resource)
|
||||
{
|
||||
if (resource)
|
||||
resource->renderObject = nullptr;
|
||||
}
|
||||
|
||||
template<Renderable API_INDEPENDENT_CLASS>
|
||||
class IRenderResource : public IRenderResourceHelper
|
||||
{
|
||||
API_INDEPENDENT_CLASS* m_owner;
|
||||
|
||||
protected:
|
||||
IRenderResource(API_INDEPENDENT_CLASS* owner) : m_owner(owner)
|
||||
{
|
||||
if (m_owner) UpdateRenderResource(GetOwnerResource());
|
||||
}
|
||||
|
||||
IRenderResource(const IRenderResource<API_INDEPENDENT_CLASS>& copy) = delete;
|
||||
|
||||
IRenderResource(IRenderResource<API_INDEPENDENT_CLASS>&& move) noexcept
|
||||
: m_owner(move.m_owner)
|
||||
{
|
||||
if (m_owner)
|
||||
{
|
||||
UpdateRenderResource(GetOwnerResource());
|
||||
}
|
||||
move.m_owner = nullptr;
|
||||
}
|
||||
|
||||
RenderResourcePtr* GetOwnerResource() { if (!m_owner) return nullptr; else return &static_cast<RenderResourcePtr&>(*m_owner); }
|
||||
|
||||
void DoRelease() final override
|
||||
{
|
||||
m_owner = nullptr;
|
||||
Release();
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~IRenderResource()
|
||||
{
|
||||
if (m_owner) ResetRenderResource(GetOwnerResource());
|
||||
}
|
||||
|
||||
void UpdateAddress(API_INDEPENDENT_CLASS* owner)
|
||||
{
|
||||
m_owner = owner;
|
||||
}
|
||||
|
||||
operator API_INDEPENDENT_CLASS*() const { return m_owner; }
|
||||
|
||||
API_INDEPENDENT_CLASS* GetOwner() const { return m_owner; }
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a convenience class to create a Renderable class.
|
||||
* You can also just create a RenderResource instance a conversion operator inside your own class to make it Renderable; and you probably want to delete your move constructor in that case.
|
||||
*/
|
||||
template <class T>
|
||||
class RenderResourceHolder
|
||||
{
|
||||
RenderResourcePtr renderResource;
|
||||
|
||||
protected:
|
||||
RenderResourceHolder() = default;
|
||||
RenderResourceHolder(const RenderResourceHolder& ignored) noexcept {}
|
||||
RenderResourceHolder(RenderResourceHolder&& move) noexcept
|
||||
: renderResource(std::move(move.renderResource))
|
||||
{
|
||||
if (IRenderResource<T>* renderRes = renderResource)
|
||||
renderRes->UpdateAddress(static_cast<T*>(this));
|
||||
}
|
||||
|
||||
~RenderResourceHolder() = default;
|
||||
|
||||
public:
|
||||
operator RenderResourcePtr&() { return renderResource; }
|
||||
|
||||
RenderResourcePtr& GetRenderResource() const { return const_cast<RenderResourceHolder*>(this)->renderResource; }
|
||||
|
||||
template<Renderable RT>
|
||||
operator RT() const { return renderResource; }
|
||||
|
||||
bool HasRenderResource() const { return renderResource; }
|
||||
|
||||
RenderResourceHolder& operator =(RenderResourceHolder&& move) noexcept
|
||||
{
|
||||
renderResource = std::move(move.renderResource);
|
||||
if (IRenderResource<T>* renderRes = renderResource)
|
||||
renderRes->UpdateAddress(static_cast<T*>(this));
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Swap(RenderResourceHolder& other) noexcept
|
||||
{
|
||||
RenderResourceHolder tmp(std::move(*this));
|
||||
*this = std::move(other);
|
||||
other = std::move(tmp);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -13,10 +13,9 @@
|
||||
|
||||
namespace OpenVulkano::Scene
|
||||
{
|
||||
class Camera : public Node
|
||||
class Camera : public RenderResourceHolder<Camera>, public Node
|
||||
{
|
||||
public:
|
||||
ICloseable* renderCamera = nullptr;
|
||||
static constexpr inline size_t SIZE = sizeof(Math::Matrix4f) * 3 + sizeof(Math::Vector4f) + sizeof(float) * 12;
|
||||
static constexpr inline DescriptorSetLayoutBinding DESCRIPTOR_SET_LAYOUT_BINDING = { 0, DescriptorSetLayoutBinding::Type::TYPE_UNIFORM_BUFFER_DYNAMIC, 1, ShaderProgramType::ALL_GRAPHICS };
|
||||
|
||||
@@ -36,10 +35,7 @@ namespace OpenVulkano::Scene
|
||||
{
|
||||
}
|
||||
|
||||
~Camera() override
|
||||
{
|
||||
//if (renderCamera) renderCamera->Close();
|
||||
}
|
||||
~Camera() override = default;
|
||||
|
||||
void Init(float width, float height, float nearPlane, float farPlane)
|
||||
{
|
||||
@@ -152,6 +148,10 @@ namespace OpenVulkano::Scene
|
||||
float GetWidth() const { return m_width; }
|
||||
float GetHeight() const { return m_height; }
|
||||
Math::Vector2f GetSize() const { return { m_width, m_height }; }
|
||||
|
||||
using RenderResourceHolder<Camera>::GetRenderResource;
|
||||
using RenderResourceHolder<Camera>::HasRenderResource;
|
||||
using RenderResourceHolder<Camera>::operator RenderResourcePtr&;
|
||||
};
|
||||
|
||||
class PerspectiveCamera : public Camera
|
||||
|
||||
@@ -12,20 +12,17 @@
|
||||
namespace OpenVulkano::Scene
|
||||
{
|
||||
Geometry::Geometry(const Geometry& other)
|
||||
: vertexCount(other.vertexCount), indexCount(other.indexCount)
|
||||
, vertices(other.vertices ? new Vertex[other.vertexCount] : nullptr)
|
||||
, indices(other.indices ? malloc(static_cast<size_t>(Utils::EnumAsInt(other.indexType)) * other.indexCount) : nullptr)
|
||||
, indexType(other.indexType)
|
||||
, ownsMemory(other.ownsMemory), freeAfterUpload(other.freeAfterUpload)
|
||||
, aabb(other.aabb)
|
||||
{
|
||||
this->vertexCount = other.vertexCount;
|
||||
this->indexCount = other.indexCount;
|
||||
this->indexType = other.indexType;
|
||||
this->aabb = other.aabb;
|
||||
this->ownsMemory = other.ownsMemory;
|
||||
this->freeAfterUpload = other.freeAfterUpload;
|
||||
this->renderGeo = nullptr;
|
||||
this->vertices = new Vertex[vertexCount];
|
||||
if (other.vertices)
|
||||
{
|
||||
std::copy(other.vertices, other.vertices + other.vertexCount, this->vertices);
|
||||
}
|
||||
this->indices = malloc(static_cast<size_t>(Utils::EnumAsInt(other.indexType)) * other.indexCount);
|
||||
if (other.indices)
|
||||
{
|
||||
if (other.indexType == VertexIndexType::UINT16)
|
||||
@@ -51,20 +48,13 @@ namespace OpenVulkano::Scene
|
||||
}
|
||||
|
||||
Geometry::Geometry(Geometry&& other) noexcept
|
||||
: RenderResourceHolder<Geometry>(std::move(other)), vertexCount(other.vertexCount), indexCount(other.indexCount)
|
||||
, vertices(other.vertices), indices(other.indices), indexType(other.indexType)
|
||||
, ownsMemory(other.ownsMemory), freeAfterUpload(other.freeAfterUpload), aabb(other.aabb)
|
||||
{
|
||||
this->vertexCount = other.vertexCount;
|
||||
this->indexCount = other.indexCount;
|
||||
this->indexType = other.indexType;
|
||||
this->ownsMemory = other.ownsMemory;
|
||||
this->freeAfterUpload = other.freeAfterUpload;
|
||||
this->aabb = std::move(other.aabb);
|
||||
this->vertices = other.vertices;
|
||||
this->indices = other.indices;
|
||||
this->renderGeo = other.renderGeo;
|
||||
other.vertexCount = other.indexCount = 0;
|
||||
other.vertices = nullptr;
|
||||
other.indices = nullptr;
|
||||
other.renderGeo = nullptr;
|
||||
}
|
||||
|
||||
Geometry& Geometry::operator=(Geometry&& other) noexcept
|
||||
@@ -80,11 +70,10 @@ namespace OpenVulkano::Scene
|
||||
this->aabb = std::move(other.aabb);
|
||||
this->vertices = other.vertices;
|
||||
this->indices = other.indices;
|
||||
this->renderGeo = other.renderGeo;
|
||||
RenderResourceHolder<Geometry>::operator=(std::move(other));
|
||||
other.vertexCount = other.indexCount = 0;
|
||||
other.vertices = nullptr;
|
||||
other.indices = nullptr;
|
||||
other.renderGeo = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -96,26 +85,25 @@ namespace OpenVulkano::Scene
|
||||
|
||||
void Geometry::Swap(Geometry& other) noexcept
|
||||
{
|
||||
RenderResourceHolder<Geometry>::Swap(other);
|
||||
std::swap(this->vertexCount, other.vertexCount);
|
||||
std::swap(this->indexCount, other.indexCount);
|
||||
std::swap(this->aabb, other.aabb);
|
||||
std::swap(this->indexType, other.indexType);
|
||||
std::swap(this->vertices, other.vertices);
|
||||
std::swap(this->indices, other.indices);
|
||||
std::swap(this->renderGeo, other.renderGeo);
|
||||
std::swap(this->ownsMemory, other.ownsMemory);
|
||||
std::swap(this->freeAfterUpload, other.freeAfterUpload);
|
||||
}
|
||||
|
||||
void Geometry::Init(uint32_t vertexCount, uint32_t indexCount)
|
||||
{
|
||||
if (this->vertexCount || this->indexCount) throw std::runtime_error("Geometry is already initialized.");
|
||||
if (HasRenderResource() || this->vertexCount || this->indexCount) throw std::runtime_error("Geometry is already initialized.");
|
||||
this->vertexCount = vertexCount;
|
||||
this->indexCount = indexCount;
|
||||
indexType = (vertexCount > UINT16_MAX) ? VertexIndexType::UINT32 : VertexIndexType::UINT16;
|
||||
vertices = new Vertex[vertexCount];
|
||||
indices = malloc(static_cast<size_t>(Utils::EnumAsInt(indexType)) * indexCount);
|
||||
renderGeo = nullptr;
|
||||
}
|
||||
|
||||
void Geometry::SetIndices(const uint32_t* data, uint32_t size, uint32_t dstOffset) const
|
||||
@@ -140,10 +128,9 @@ namespace OpenVulkano::Scene
|
||||
indexCount = 0;
|
||||
Free();
|
||||
}
|
||||
if (renderGeo)
|
||||
if (HasRenderResource())
|
||||
{
|
||||
renderGeo->Close();
|
||||
renderGeo = nullptr;
|
||||
GetRenderResource().Release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "Base/ICloseable.hpp"
|
||||
#include "Base/Render/RenderResource.hpp"
|
||||
#include "Math/AABB.hpp"
|
||||
#include "Base/Utils.hpp"
|
||||
#include "Vertex.hpp"
|
||||
@@ -21,7 +22,7 @@ namespace OpenVulkano
|
||||
UINT16 = sizeof(uint16_t), UINT32 = sizeof(uint32_t)
|
||||
};
|
||||
|
||||
class Geometry : public ICloseable
|
||||
class Geometry : public RenderResourceHolder<Geometry>, public ICloseable
|
||||
{
|
||||
friend class MeshLoader;
|
||||
public:
|
||||
@@ -31,7 +32,6 @@ namespace OpenVulkano
|
||||
VertexIndexType indexType = VertexIndexType::UINT16;
|
||||
bool ownsMemory = true, freeAfterUpload = true;
|
||||
Math::AABB aabb;
|
||||
ICloseable* renderGeo = nullptr;
|
||||
public:
|
||||
Geometry() = default;
|
||||
Geometry(const Geometry& other);
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace OpenVulkano::Scene
|
||||
void Node::Close()
|
||||
{
|
||||
children.clear();
|
||||
if (renderNode) renderNode->Close();
|
||||
GetRenderResource().Release();
|
||||
parent = nullptr;
|
||||
scene = nullptr;
|
||||
enabled = false;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "Base/ICloseable.hpp"
|
||||
#include "Base/Render/RenderResource.hpp"
|
||||
#include "Math/Math.hpp"
|
||||
#include "Math/Pose.hpp"
|
||||
#include "Drawable.hpp"
|
||||
@@ -19,7 +20,7 @@ namespace OpenVulkano::Scene
|
||||
{
|
||||
class Scene;
|
||||
|
||||
class Node : public ICloseable
|
||||
class Node : public RenderResourceHolder<Node>, public ICloseable
|
||||
{
|
||||
friend Scene;
|
||||
|
||||
@@ -33,7 +34,6 @@ namespace OpenVulkano::Scene
|
||||
std::vector<Node*> children;
|
||||
std::vector<Drawable*> drawables;
|
||||
UpdateFrequency matrixUpdateFrequency = UpdateFrequency::Never;
|
||||
ICloseable* renderNode = nullptr;
|
||||
bool enabled = true;
|
||||
|
||||
public:
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "Base/ICloseable.hpp"
|
||||
#include "Base/Utils.hpp"
|
||||
#include "Base/Render/RenderResource.hpp"
|
||||
#include "VertexInputDescription.hpp"
|
||||
#include "ShaderProgramType.hpp"
|
||||
#include "DescriptorInputDescription.hpp"
|
||||
@@ -81,7 +82,7 @@ namespace OpenVulkano::Scene
|
||||
|
||||
|
||||
|
||||
class Shader final : public ICloseable
|
||||
class Shader final : public RenderResourceHolder<Shader>, public ICloseable
|
||||
{
|
||||
public:
|
||||
std::vector<ShaderProgram> shaderPrograms{};
|
||||
@@ -90,7 +91,6 @@ namespace OpenVulkano::Scene
|
||||
std::vector<PushConstantRange> pushConstantRanges;
|
||||
Topology topology = Topology::TRIANGLE_LIST;
|
||||
CullMode cullMode = CullMode::BACK;
|
||||
ICloseable* renderShader = nullptr;
|
||||
CompareOp depthCompareOp = CompareOp::LESS;
|
||||
bool alphaBlend = false; // TODO allow fine control over blending
|
||||
bool depthTest = true;
|
||||
@@ -98,7 +98,7 @@ namespace OpenVulkano::Scene
|
||||
bool dynamicViewport = true; // If disabled the swapchains fullscreen viewport will always be used, regardless of framebuffer or viewport
|
||||
|
||||
Shader() = default;
|
||||
~Shader() override { if (renderShader) Shader::Close(); }
|
||||
~Shader() override { Shader::Close(); }
|
||||
|
||||
Shader& AddShaderProgram(const ShaderProgram& shaderProgram)
|
||||
{
|
||||
@@ -165,14 +165,14 @@ namespace OpenVulkano::Scene
|
||||
|
||||
void Close() override
|
||||
{
|
||||
renderShader->Close();
|
||||
renderShader = nullptr;
|
||||
if (HasRenderResource())
|
||||
GetRenderResource().Release();
|
||||
}
|
||||
|
||||
private:
|
||||
void CheckShaderInitState() const
|
||||
{
|
||||
if (renderShader) throw std::runtime_error("Shader already initialized!");
|
||||
if (HasRenderResource()) throw std::runtime_error("Shader already initialized!");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,27 +8,19 @@
|
||||
|
||||
#include "UpdateFrequency.hpp"
|
||||
#include "SamplerConfig.hpp"
|
||||
#include "Base/ICloseable.hpp"
|
||||
#include "Base/Render/RenderResource.hpp"
|
||||
#include "Math/Math.hpp"
|
||||
#include "DataFormat.hpp"
|
||||
#include "Scene/Shader/DescriptorInputDescription.hpp"
|
||||
|
||||
namespace OpenVulkano::Scene
|
||||
{
|
||||
class Texture;
|
||||
|
||||
struct RenderTexture
|
||||
{
|
||||
Texture* m_texture = nullptr;
|
||||
};
|
||||
|
||||
class Texture
|
||||
class Texture : public RenderResourceHolder<Texture>
|
||||
{
|
||||
public:
|
||||
static Texture PLACEHOLDER;
|
||||
static constexpr inline DescriptorSetLayoutBinding DESCRIPTOR_SET_LAYOUT_BINDING = { 0, DescriptorSetLayoutBinding::Type::TYPE_COMBINED_IMAGE_SAMPLER, 1, ShaderProgramType::ALL_GRAPHICS };
|
||||
|
||||
RenderTexture* renderTexture = nullptr;
|
||||
void* textureBuffer = nullptr;
|
||||
size_t size = 0;
|
||||
Math::Vector3ui resolution = {0,0,0};
|
||||
@@ -41,13 +33,7 @@ namespace OpenVulkano::Scene
|
||||
: m_samplerConfig(samplerConfig)
|
||||
{ if (placeholder) MakePlaceholder(); }
|
||||
|
||||
~Texture()
|
||||
{
|
||||
if (renderTexture)
|
||||
{
|
||||
renderTexture->m_texture = nullptr;
|
||||
}
|
||||
}
|
||||
~Texture() = default;
|
||||
|
||||
void MakePlaceholder(uint32_t width = 32, uint32_t height = 32,
|
||||
Math::Vector4uc color1 = {248, 123, 255, 255}, Math::Vector4uc color2 = {250, 19, 255, 255});
|
||||
|
||||
@@ -6,20 +6,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Base/ICloseable.hpp"
|
||||
#include "Base/Render/RenderResource.hpp"
|
||||
#include "Scene/Shader/DescriptorInputDescription.hpp"
|
||||
#include "Scene/UpdateFrequency.hpp"
|
||||
|
||||
namespace OpenVulkano::Scene
|
||||
{
|
||||
class UniformBuffer
|
||||
class UniformBuffer : public RenderResourceHolder<UniformBuffer>
|
||||
{
|
||||
public:
|
||||
static constexpr inline DescriptorSetLayoutBinding DESCRIPTOR_SET_LAYOUT_BINDING = { 0, DescriptorSetLayoutBinding::Type::TYPE_UNIFORM_BUFFER, 1, ShaderProgramType::ALL_GRAPHICS };
|
||||
|
||||
DescriptorSetLayoutBinding binding;
|
||||
uint32_t setId;
|
||||
ICloseable* renderBuffer = nullptr;
|
||||
size_t size = 0;
|
||||
const void* data = nullptr;
|
||||
UpdateFrequency updateFrequency = UpdateFrequency::Never;
|
||||
|
||||
@@ -19,7 +19,6 @@ namespace OpenVulkano::Vulkan
|
||||
resolution = { static_cast<uint32_t>(mtlTexture.width), static_cast<uint32_t>(mtlTexture.height), static_cast<uint32_t>(mtlTexture.depth) };
|
||||
format = DataFormat::GetFromMetalPixelFormat(static_cast<int>(mtlTexture.pixelFormat));
|
||||
|
||||
m_vulkanTexture.m_texture = this;
|
||||
m_vulkanTexture.device = resManager->GetDevice();
|
||||
m_vulkanTexture.format = format;
|
||||
m_vulkanTexture.extent = reinterpret_cast<vk::Extent3D&>(resolution);
|
||||
@@ -57,7 +56,8 @@ namespace OpenVulkano::Vulkan
|
||||
m_vulkanTexture.m_sampler = resManager->CreateSampler(reinterpret_cast<const vk::SamplerCreateInfo&>(Scene::SamplerConfig::DEFAULT));
|
||||
m_vulkanTexture.SetDescriptorSet(resManager, resManager->GetDescriptorLayoutSet(binding), binding);
|
||||
|
||||
renderTexture = &m_vulkanTexture;
|
||||
GetRenderResource().renderObject = &m_vulkanTexture;
|
||||
m_vulkanTexture.UpdateAddress(this);
|
||||
|
||||
if (!ownsTexture) m_metalTexture = nullptr;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace OpenVulkano::Vulkan
|
||||
|
||||
~ManagedBuffer()
|
||||
{
|
||||
allocation->device.destroy(buffer);
|
||||
if (allocation) [[likely]] allocation->device.destroy(buffer);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsLast() const
|
||||
|
||||
@@ -23,6 +23,8 @@ namespace OpenVulkano::Vulkan
|
||||
{
|
||||
if (memPool->FreeBuffer(buffer)) return;
|
||||
}
|
||||
Logger::RENDER->error("Attempted to released buffer to pool, but owning pool no longer exists!");
|
||||
buffer->allocation = nullptr; // Allocation is no longer valid since owning pool is gone already
|
||||
delete buffer;
|
||||
}
|
||||
|
||||
|
||||
@@ -98,6 +98,7 @@ namespace OpenVulkano::Vulkan
|
||||
{
|
||||
transferQueue.waitIdle();
|
||||
transferQueue = nullptr;
|
||||
OnShutdown(this); // Notify all custom resources that it's time to die
|
||||
geometries.clear();
|
||||
nodes.clear();
|
||||
textures.clear();
|
||||
@@ -153,7 +154,7 @@ namespace OpenVulkano::Vulkan
|
||||
VulkanGeometry* ResourceManager::PrepareGeometry(Scene::Geometry* geometry)
|
||||
{
|
||||
const std::unique_lock lock(mutex);
|
||||
if(!geometry->renderGeo)
|
||||
if(!geometry->HasRenderResource())
|
||||
{
|
||||
ManagedBuffer::Ptr vertexBuffer =
|
||||
CreateDeviceOnlyBufferWithData(sizeof(Vertex) * geometry->GetVertexCount(), vk::BufferUsageFlagBits::eVertexBuffer, geometry->GetVertices());
|
||||
@@ -162,19 +163,18 @@ namespace OpenVulkano::Vulkan
|
||||
indexBuffer = CreateDeviceOnlyBufferWithData(Utils::EnumAsInt(geometry->indexType) * geometry->GetIndexCount(), vk::BufferUsageFlagBits::eIndexBuffer, geometry->GetIndices());
|
||||
VulkanGeometry* vkGeo = new VulkanGeometry(geometry, vertexBuffer, indexBuffer);
|
||||
geometries.emplace_back(vkGeo);
|
||||
geometry->renderGeo = vkGeo;
|
||||
if (geometry->ownsMemory && geometry->freeAfterUpload)
|
||||
{
|
||||
geometry->Free();
|
||||
}
|
||||
return vkGeo;
|
||||
}
|
||||
return dynamic_cast<VulkanGeometry*>(geometry->renderGeo);
|
||||
return geometry->GetRenderResource();
|
||||
}
|
||||
|
||||
void ResourceManager::PrepareMaterial(Scene::Material* material)
|
||||
{
|
||||
if (material->texture && !material->texture->renderTexture)
|
||||
if (material->texture && !material->texture->HasRenderResource())
|
||||
{
|
||||
PrepareTexture(material->texture);
|
||||
}
|
||||
@@ -183,7 +183,7 @@ namespace OpenVulkano::Vulkan
|
||||
VulkanNode* ResourceManager::PrepareNode(Scene::Node* node)
|
||||
{
|
||||
const std::unique_lock lock(mutex);
|
||||
if (!node->renderNode)
|
||||
if (!node->HasRenderResource())
|
||||
{
|
||||
UniformBuffer* uBuffer = new UniformBuffer();
|
||||
ManagedBuffer::Ptr buffer;
|
||||
@@ -193,29 +193,28 @@ namespace OpenVulkano::Vulkan
|
||||
if (node->GetUpdateFrequency() != Scene::UpdateFrequency::Never)
|
||||
{
|
||||
frameSize = allocSize;
|
||||
vkNode = new VulkanNodeDynamic();
|
||||
vkNode = new VulkanNodeDynamic(node, uBuffer);
|
||||
const uint32_t imgs = context->swapChain.GetImageCount();
|
||||
buffer = memPool.CreateBuffer(imgs * allocSize, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible);
|
||||
buffer->Map();
|
||||
}
|
||||
else
|
||||
{
|
||||
vkNode = new VulkanNode();
|
||||
buffer = CreateDeviceOnlyBufferWithData(Scene::Node::SIZE, vk::BufferUsageFlagBits::eUniformBuffer, &node->worldMat);
|
||||
vkNode = new VulkanNode(node, uBuffer);
|
||||
}
|
||||
|
||||
uBuffer->Init(std::move(buffer), frameSize, allocSize, GetDescriptorLayoutSet(Scene::Node::DESCRIPTOR_SET_LAYOUT_BINDING), Scene::Node::DESCRIPTOR_SET_LAYOUT_BINDING, 0);
|
||||
vkNode->Init(node, uBuffer);
|
||||
node->renderNode = vkNode;
|
||||
nodes.emplace_back(vkNode);
|
||||
return vkNode;
|
||||
}
|
||||
return static_cast<VulkanNode*>(node->renderNode);
|
||||
return node->GetRenderResource();
|
||||
}
|
||||
|
||||
VulkanCamera* ResourceManager::PrepareCamera(Scene::Camera* camera)
|
||||
{
|
||||
const std::unique_lock lock(mutex);
|
||||
if (!camera->renderCamera)
|
||||
if (!camera->HasRenderResource())
|
||||
{
|
||||
const vk::DeviceSize allocSize = Utils::Align(Scene::Camera::SIZE, uniformBufferAlignment);
|
||||
const uint32_t imgs = context->swapChain.GetImageCount();
|
||||
@@ -223,12 +222,10 @@ namespace OpenVulkano::Vulkan
|
||||
buffer->Map();
|
||||
UniformBuffer* uBuffer = new UniformBuffer();
|
||||
uBuffer->Init(std::move(buffer), allocSize, allocSize, GetDescriptorLayoutSet(Scene::Camera::DESCRIPTOR_SET_LAYOUT_BINDING), Scene::Camera::DESCRIPTOR_SET_LAYOUT_BINDING, 1);
|
||||
VulkanCamera* vkCam = new VulkanCamera();
|
||||
vkCam->Init(camera, uBuffer);
|
||||
VulkanCamera* vkCam = new VulkanCamera(camera, uBuffer);
|
||||
cameras.emplace_back(vkCam);
|
||||
camera->renderCamera = vkCam;
|
||||
}
|
||||
return static_cast<VulkanCamera*>(camera->renderCamera);
|
||||
return static_cast<VulkanCamera*>(camera->GetRenderResource());
|
||||
}
|
||||
|
||||
UniformBuffer* ResourceManager::CreateUniformBuffer(const DescriptorSetLayoutBinding& binding, size_t size, void* data, uint32_t setId, bool hostVis)
|
||||
@@ -278,6 +275,7 @@ namespace OpenVulkano::Vulkan
|
||||
find_if(shaders.begin(), shaders.end(),
|
||||
[&](auto& obj){ return obj.get() == shader; }
|
||||
);
|
||||
object->get()->owner = nullptr;
|
||||
shaders.erase(object);
|
||||
}
|
||||
|
||||
@@ -309,9 +307,8 @@ namespace OpenVulkano::Vulkan
|
||||
VulkanShader* ResourceManager::CreateShader(Scene::Shader* shader)
|
||||
{
|
||||
const std::unique_lock lock(mutex);
|
||||
if (shader->renderShader) return static_cast<VulkanShader*>(shader->renderShader);
|
||||
VulkanShader* vkShader = new VulkanShader();
|
||||
vkShader->Init(context, shader, this);
|
||||
if (shader->HasRenderResource()) return static_cast<VulkanShader*>(shader->GetRenderResource());
|
||||
VulkanShader* vkShader = new VulkanShader(context, shader, this);
|
||||
shaders.emplace_back(vkShader);
|
||||
return vkShader;
|
||||
}
|
||||
@@ -319,7 +316,7 @@ namespace OpenVulkano::Vulkan
|
||||
VulkanTexture* ResourceManager::PrepareTexture(Scene::Texture* texture)
|
||||
{
|
||||
const std::unique_lock lock(mutex);
|
||||
if (texture->renderTexture) return static_cast<VulkanTexture*>(texture->renderTexture);
|
||||
if (texture->HasRenderResource()) return static_cast<VulkanTexture*>(texture->GetRenderResource());
|
||||
VulkanTexture* vkTexture;
|
||||
if (texture->updateFrequency == Scene::UpdateFrequency::Never)
|
||||
vkTexture = new VulkanTexture();
|
||||
@@ -336,31 +333,29 @@ namespace OpenVulkano::Vulkan
|
||||
VulkanUniformBuffer* ResourceManager::PrepareUniformBuffer(Scene::UniformBuffer* buffer)
|
||||
{
|
||||
const std::unique_lock lock(mutex);
|
||||
if (buffer->renderBuffer) return static_cast<VulkanUniformBuffer*>(buffer->renderBuffer);
|
||||
if (buffer->HasRenderResource()) return static_cast<VulkanUniformBuffer*>(buffer->GetRenderResource());
|
||||
|
||||
VulkanUniformBuffer* vkBuffer;
|
||||
ManagedBuffer::Ptr mBuffer;
|
||||
const vk::DeviceSize allocSize = Utils::Align(buffer->size, uniformBufferAlignment);
|
||||
UniformBuffer* uBuffer = new UniformBuffer();
|
||||
if (buffer->GetUpdateFrequency() != Scene::UpdateFrequency::Never)
|
||||
{
|
||||
vkBuffer = new VulkanUniformBufferDynamic();
|
||||
const uint32_t imgs = context->swapChain.GetImageCount();
|
||||
mBuffer = memPool.CreateBuffer(imgs * allocSize, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible);
|
||||
mBuffer->Map();
|
||||
vkBuffer = new VulkanUniformBufferDynamic(buffer, uBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
vkBuffer = new VulkanUniformBuffer();
|
||||
mBuffer = CreateDeviceOnlyBufferWithData(buffer->size, vk::BufferUsageFlagBits::eUniformBuffer, buffer->data);
|
||||
buffer->updated = false;
|
||||
vkBuffer = new VulkanUniformBuffer(buffer, uBuffer);
|
||||
}
|
||||
|
||||
|
||||
UniformBuffer* uBuffer = new UniformBuffer();
|
||||
const uint64_t s = mBuffer->size;
|
||||
uBuffer->Init(std::move(mBuffer), 0, s, GetDescriptorLayoutSet(buffer->binding), buffer->binding, buffer->setId);
|
||||
|
||||
vkBuffer->Init(buffer, uBuffer);
|
||||
uniforms.emplace_back(vkBuffer);
|
||||
return vkBuffer;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "IShaderOwner.hpp"
|
||||
#include "MemoryPool.hpp"
|
||||
#include "Base/Wrapper.hpp"
|
||||
#include "Base/Event.hpp"
|
||||
#include "Base/Render/IResourceManager.hpp"
|
||||
#include "Vulkan/Image.hpp"
|
||||
#include "Scene/Shader/DescriptorInputDescription.hpp"
|
||||
@@ -134,6 +135,8 @@ namespace OpenVulkano
|
||||
vk::DescriptorSetLayout* GetDescriptorLayoutSet(const DescriptorSetLayoutBinding& descriptorSetLayoutBinding);
|
||||
|
||||
VulkanShader* CreateShader(Scene::Shader* shader);
|
||||
|
||||
Event<ResourceManager*> OnShutdown;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,12 +19,12 @@ namespace OpenVulkano::Vulkan
|
||||
ArBackgroundDrawable* bgDrawable = static_cast<ArBackgroundDrawable*>(instance);
|
||||
bgDrawable->Tick();
|
||||
const Texture* texture = bgDrawable->GetTexture();
|
||||
VulkanTexture* vkTexture = static_cast<VulkanTexture*>(texture->renderTexture);
|
||||
VulkanTexture* vkTexture = texture->GetRenderResource();
|
||||
if (!vkTexture)
|
||||
{
|
||||
vkTexture = drawContext->renderer->GetResourceManager().PrepareTexture(const_cast<Texture*>(texture));
|
||||
}
|
||||
VulkanUniformBuffer* vkBuffer = static_cast<VulkanUniformBuffer*>(bgDrawable->GetBuffer().renderBuffer);
|
||||
VulkanUniformBuffer* vkBuffer = bgDrawable->GetBuffer().GetRenderResource();
|
||||
if (!vkBuffer)
|
||||
{
|
||||
vkBuffer = drawContext->renderer->GetResourceManager().PrepareUniformBuffer(&bgDrawable->GetBuffer());
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "Scene/SimpleDrawable.hpp"
|
||||
#include "Scene/Material.hpp"
|
||||
#include "Scene/UniformBuffer.hpp"
|
||||
#include "VulkanGeometry.hpp"
|
||||
#include "VulkanNode.hpp"
|
||||
#include "Vulkan/VulkanDrawContext.hpp"
|
||||
@@ -21,14 +20,13 @@ namespace OpenVulkano::Vulkan
|
||||
{
|
||||
SimpleDrawable* drawable = static_cast<SimpleDrawable*>(instance);
|
||||
Geometry* mesh = drawable->GetMesh();
|
||||
VulkanGeometry* renderGeo = static_cast<VulkanGeometry*>(mesh->renderGeo);
|
||||
VulkanGeometry* renderGeo = mesh->GetRenderResource();
|
||||
if (!renderGeo) renderGeo = drawContext->renderer->GetResourceManager().PrepareGeometry(mesh);
|
||||
renderGeo->RecordBind(drawContext->commandBuffer);
|
||||
|
||||
if (drawable->GetBuffer())
|
||||
{
|
||||
|
||||
VulkanUniformBuffer* vkBuffer = static_cast<VulkanUniformBuffer*>(drawable->GetBuffer()->renderBuffer);
|
||||
VulkanUniformBuffer* vkBuffer = drawable->GetBuffer()->GetRenderResource();
|
||||
if (!vkBuffer)
|
||||
{
|
||||
vkBuffer = drawContext->renderer->GetResourceManager().PrepareUniformBuffer(drawable->GetBuffer());
|
||||
@@ -40,11 +38,11 @@ namespace OpenVulkano::Vulkan
|
||||
{
|
||||
if (Texture* texture = material->texture)
|
||||
{
|
||||
VulkanTexture* renderTexture = static_cast<VulkanTexture*>(texture->renderTexture);
|
||||
VulkanTexture* renderTexture = texture->GetRenderResource();
|
||||
if (!renderTexture)
|
||||
{
|
||||
drawContext->renderer->GetResourceManager().PrepareMaterial(drawable->GetMaterial());
|
||||
renderTexture = static_cast<VulkanTexture*>(texture->renderTexture);
|
||||
renderTexture = texture->GetRenderResource();
|
||||
}
|
||||
renderTexture->Record(drawContext);
|
||||
}
|
||||
|
||||
@@ -6,41 +6,34 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Base/ICloseable.hpp"
|
||||
#include "Scene/Camera.hpp"
|
||||
#include "IRecordable.hpp"
|
||||
#include "Vulkan/Resources/UniformBuffer.hpp"
|
||||
|
||||
namespace OpenVulkano::Vulkan
|
||||
{
|
||||
class VulkanCamera : public ICloseable, public IRecordable
|
||||
class VulkanCamera : public IRenderResource<Scene::Camera>, public IRecordable
|
||||
{
|
||||
Scene::Camera* m_camera = nullptr;
|
||||
UniformBuffer* m_buffer = nullptr;
|
||||
const Unique<UniformBuffer> m_buffer;
|
||||
|
||||
public:
|
||||
~VulkanCamera() override { if (m_camera) VulkanCamera::Close(); }
|
||||
VulkanCamera(Scene::Camera* camera, UniformBuffer* uniformBuffer)
|
||||
: IRenderResource<Scene::Camera>(camera), m_buffer(uniformBuffer)
|
||||
{}
|
||||
|
||||
void Init(Scene::Camera* camera, UniformBuffer* uniformBuffer)
|
||||
{
|
||||
m_camera = camera;
|
||||
m_buffer = uniformBuffer;
|
||||
}
|
||||
~VulkanCamera() override = default;
|
||||
|
||||
void Record(VulkanDrawContext* context) override
|
||||
{
|
||||
m_buffer->Update(m_camera->GetData(), Scene::Camera::SIZE, context->currentImageId);
|
||||
m_buffer->Update(GetCamera()->GetData(), Scene::Camera::SIZE, context->currentImageId);
|
||||
m_buffer->Record(context);
|
||||
}
|
||||
|
||||
void Close() override
|
||||
{
|
||||
m_camera->renderCamera = nullptr;
|
||||
m_buffer->Close();
|
||||
m_camera = nullptr;
|
||||
delete m_buffer;
|
||||
}
|
||||
[[nodiscard]] Scene::Camera* GetCamera() const { return GetOwner(); }
|
||||
|
||||
[[nodiscard]] Scene::Camera* GetCamera() const { return m_camera; }
|
||||
void Release() override
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -13,36 +13,21 @@
|
||||
|
||||
namespace OpenVulkano::Vulkan
|
||||
{
|
||||
class VulkanGeometry final : public ICloseable
|
||||
class VulkanGeometry final : public IRenderResource<Scene::Geometry>
|
||||
{
|
||||
Scene::Geometry* m_geometry;
|
||||
ManagedBuffer::Ptr m_vertexBuffer;
|
||||
ManagedBuffer::Ptr m_indexBuffer;
|
||||
vk::IndexType m_indexType;
|
||||
vk::DeviceSize m_offsets = 0;
|
||||
|
||||
public:
|
||||
VulkanGeometry() : m_geometry(nullptr), m_vertexBuffer(nullptr)
|
||||
, m_indexBuffer(nullptr), m_indexType(vk::IndexType::eUint32)
|
||||
{}
|
||||
|
||||
VulkanGeometry(Scene::Geometry* geo, ManagedBuffer::Ptr& vertexBuffer, ManagedBuffer::Ptr& indexBuffer)
|
||||
: m_geometry(geo), m_vertexBuffer(std::move(vertexBuffer)), m_indexBuffer(std::move(indexBuffer))
|
||||
: IRenderResource<Scene::Geometry>(geo)
|
||||
, m_vertexBuffer(std::move(vertexBuffer)), m_indexBuffer(std::move(indexBuffer))
|
||||
, m_indexType((geo->indexType == Scene::VertexIndexType::UINT16) ? vk::IndexType::eUint16 : vk::IndexType::eUint32)
|
||||
{}
|
||||
|
||||
~VulkanGeometry() override
|
||||
{
|
||||
if (m_vertexBuffer) VulkanGeometry::Close();
|
||||
}
|
||||
|
||||
void Init(Scene::Geometry* geo, ManagedBuffer::Ptr& vertexBuffer, ManagedBuffer::Ptr& indexBuffer)
|
||||
{
|
||||
m_geometry = geo;
|
||||
m_vertexBuffer = std::move(vertexBuffer);
|
||||
m_indexBuffer = std::move(indexBuffer);
|
||||
m_indexType = (geo->indexType == Scene::VertexIndexType::UINT16) ? vk::IndexType::eUint16 : vk::IndexType::eUint32;
|
||||
}
|
||||
~VulkanGeometry() override = default;
|
||||
|
||||
void RecordBind(vk::CommandBuffer& cmdBuffer)
|
||||
{
|
||||
@@ -52,15 +37,13 @@ namespace OpenVulkano::Vulkan
|
||||
|
||||
void RecordDraw(vk::CommandBuffer& cmdBuffer)
|
||||
{
|
||||
if (m_geometry->GetIndexCount()) { cmdBuffer.drawIndexed(m_geometry->GetIndexCount(), 1, 0, 0, 0); }
|
||||
else { cmdBuffer.draw(m_geometry->GetVertexCount(), 1, 0, 0); }
|
||||
if (GetOwner()->GetIndexCount()) { cmdBuffer.drawIndexed(GetOwner()->GetIndexCount(), 1, 0, 0, 0); }
|
||||
else { cmdBuffer.draw(GetOwner()->GetVertexCount(), 1, 0, 0); }
|
||||
}
|
||||
|
||||
void Close() override
|
||||
void Release() override
|
||||
{
|
||||
m_geometry->renderGeo = nullptr;
|
||||
m_vertexBuffer.reset();
|
||||
m_indexBuffer.reset();
|
||||
//TODO
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,28 +6,23 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Base/ICloseable.hpp"
|
||||
#include "Base/Render/RenderResource.hpp"
|
||||
#include "IRecordable.hpp"
|
||||
#include "Scene/Camera.hpp"
|
||||
#include "Vulkan/Resources/UniformBuffer.hpp"
|
||||
|
||||
namespace OpenVulkano::Vulkan
|
||||
{
|
||||
class VulkanNode : public IRecordable, public ICloseable
|
||||
class VulkanNode : public IRenderResource<Scene::Node>, public IRecordable
|
||||
{
|
||||
public:
|
||||
Scene::Node* node = nullptr;
|
||||
UniformBuffer* buffer = nullptr;
|
||||
Unique<UniformBuffer> buffer = nullptr;
|
||||
|
||||
~VulkanNode() override
|
||||
{
|
||||
if (node) VulkanNode::Close();
|
||||
}
|
||||
~VulkanNode() override = default;
|
||||
|
||||
virtual void Init(Scene::Node* node, UniformBuffer* uniformBuffer)
|
||||
VulkanNode(Scene::Node* node, UniformBuffer* uniformBuffer)
|
||||
: IRenderResource<Scene::Node>(node), buffer(uniformBuffer)
|
||||
{
|
||||
this->node = node;
|
||||
this->buffer = uniformBuffer;
|
||||
}
|
||||
|
||||
void Record(VulkanDrawContext* context) override
|
||||
@@ -35,12 +30,9 @@ namespace OpenVulkano::Vulkan
|
||||
buffer->Record(context);
|
||||
}
|
||||
|
||||
void Close() override
|
||||
void Release() override
|
||||
{
|
||||
if (node) node->renderNode = nullptr;
|
||||
delete buffer;
|
||||
node = nullptr;
|
||||
buffer = nullptr;
|
||||
//TODO
|
||||
}
|
||||
};
|
||||
|
||||
@@ -48,18 +40,16 @@ namespace OpenVulkano::Vulkan
|
||||
{
|
||||
//uint32_t lastUpdate = -1;
|
||||
|
||||
void Init(Scene::Node* node, UniformBuffer* uniformBuffer) override
|
||||
{
|
||||
VulkanNode::Init(node, uniformBuffer);
|
||||
//lastUpdate = -1;
|
||||
}
|
||||
VulkanNodeDynamic(Scene::Node* node, UniformBuffer* uniformBuffer)
|
||||
: VulkanNode(node, uniformBuffer)
|
||||
{}
|
||||
|
||||
void Record(VulkanDrawContext* context) override
|
||||
{
|
||||
//if(context->currentImageId != lastUpdate) //TODO fix
|
||||
{
|
||||
//lastUpdate = bufferId;
|
||||
buffer->Update(&node->worldMat, sizeof(Math::Matrix4f), context->currentImageId);
|
||||
buffer->Update(&GetOwner()->worldMat, sizeof(Math::Matrix4f), context->currentImageId);
|
||||
}
|
||||
buffer->Record(context);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@ namespace OpenVulkano::Vulkan
|
||||
|
||||
VulkanShader::~VulkanShader()
|
||||
{
|
||||
if (shader) Close();
|
||||
if (owner) owner->RemoveShader(this);
|
||||
owner = nullptr;
|
||||
device.destroyPipeline(pipeline);
|
||||
for(auto& shaderModule : shaderModules)
|
||||
{
|
||||
@@ -28,12 +29,9 @@ namespace OpenVulkano::Vulkan
|
||||
device.destroyDescriptorSetLayout(descriptorSetLayout);
|
||||
}
|
||||
|
||||
void VulkanShader::Init(Context* context, Scene::Shader* shader, IShaderOwner* owner)
|
||||
VulkanShader::VulkanShader(Context* context, Scene::Shader* shader, IShaderOwner* owner)
|
||||
: IRenderResource<Scene::Shader>(shader), device(context->device->device), owner(owner), context(context)
|
||||
{
|
||||
this->device = context->device->device;
|
||||
this->shader = shader;
|
||||
this->owner = owner;
|
||||
this->context = context;
|
||||
shaderModules.reserve(shader->shaderPrograms.size());
|
||||
shaderStageCreateInfo.resize(shader->shaderPrograms.size());
|
||||
int i = 0;
|
||||
@@ -45,11 +43,11 @@ namespace OpenVulkano::Vulkan
|
||||
i++;
|
||||
}
|
||||
BuildPipeline();
|
||||
shader->renderShader = this;
|
||||
}
|
||||
|
||||
void VulkanShader::BuildPipeline()
|
||||
{
|
||||
Scene::Shader* shader = GetOwner();
|
||||
std::vector<vk::VertexInputBindingDescription> vertexBindDesc;
|
||||
std::vector<vk::VertexInputAttributeDescription> attributeDescriptions;
|
||||
vertexBindDesc.reserve(shader->vertexInputDescriptions.size());
|
||||
@@ -129,14 +127,6 @@ namespace OpenVulkano::Vulkan
|
||||
context->commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline);
|
||||
}
|
||||
|
||||
void VulkanShader::Close()
|
||||
{
|
||||
shader->renderShader = nullptr;
|
||||
shader = nullptr;
|
||||
if (owner) owner->RemoveShader(this);
|
||||
owner = nullptr;
|
||||
}
|
||||
|
||||
void VulkanShader::CreatePipelineLayout()
|
||||
{
|
||||
if (!descriptorSetLayouts.empty())
|
||||
@@ -150,6 +140,7 @@ namespace OpenVulkano::Vulkan
|
||||
descriptorSetLayouts.push_back(device.createDescriptorSetLayout({ {}, layoutBindings1.size(), layoutBindings1.data() }));
|
||||
descriptorSetLayouts.push_back(device.createDescriptorSetLayout({ {}, layoutBindings2.size(), layoutBindings2.data() }));
|
||||
|
||||
Scene::Shader* shader = GetOwner();
|
||||
for(const auto& set : shader->descriptorSets)
|
||||
{
|
||||
vk::DescriptorSetLayoutCreateInfo createInfo { {}, static_cast<uint32_t>(set.size()), reinterpret_cast<const vk::DescriptorSetLayoutBinding*>(set.data()) };
|
||||
@@ -159,4 +150,9 @@ namespace OpenVulkano::Vulkan
|
||||
vk::PipelineLayoutCreateInfo plci = {{}, static_cast<uint32_t>(descriptorSetLayouts.size()), descriptorSetLayouts.data(), static_cast<uint32_t>(shader->pushConstantRanges.size()), pcRanges };
|
||||
pipelineLayout = this->device.createPipelineLayout(plci);
|
||||
}
|
||||
|
||||
void VulkanShader::Release()
|
||||
{
|
||||
if (owner) owner->RemoveShader(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,26 +7,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "IRecordable.hpp"
|
||||
#include "Base/ICloseable.hpp"
|
||||
#include "Scene/Shader/Shader.hpp"
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace OpenVulkano
|
||||
{
|
||||
namespace Scene
|
||||
{
|
||||
class Shader;
|
||||
}
|
||||
|
||||
namespace Vulkan
|
||||
{
|
||||
class Context;
|
||||
class IShaderOwner;
|
||||
|
||||
class VulkanShader final : public ICloseable, public IRecordable
|
||||
class VulkanShader final : public IRenderResource<Scene::Shader>, public IRecordable
|
||||
{
|
||||
public:
|
||||
Scene::Shader* shader = nullptr;
|
||||
vk::Device device;
|
||||
std::vector<vk::ShaderModule> shaderModules; // TODO manage live time somewhere else to allow sharing of shader programs
|
||||
std::vector<vk::PipelineShaderStageCreateInfo> shaderStageCreateInfo;
|
||||
@@ -36,17 +30,15 @@ namespace OpenVulkano
|
||||
IShaderOwner* owner = nullptr;
|
||||
Context* context = nullptr;
|
||||
|
||||
VulkanShader() = default;
|
||||
VulkanShader(Context* context, Scene::Shader* shader, IShaderOwner* owner);
|
||||
|
||||
~VulkanShader() override;
|
||||
|
||||
void Init(Context* context, Scene::Shader* shader, IShaderOwner* owner);
|
||||
|
||||
void Resize();
|
||||
|
||||
void Record(VulkanDrawContext* context) override;
|
||||
|
||||
void Close() override;
|
||||
void Release() override;
|
||||
|
||||
private:
|
||||
void BuildPipeline();
|
||||
|
||||
@@ -16,28 +16,29 @@
|
||||
|
||||
namespace OpenVulkano::Vulkan
|
||||
{
|
||||
class VulkanTexture : public Scene::RenderTexture, public IRecordable, public Image
|
||||
class VulkanTexture : public IRenderResource<Scene::Texture>, public IRecordable, public Image
|
||||
{
|
||||
public:
|
||||
vk::Sampler m_sampler;
|
||||
vk::DescriptorSet m_descriptorSet;
|
||||
|
||||
VulkanTexture() : IRenderResource<Scene::Texture>(nullptr) {}
|
||||
|
||||
virtual void Init(ResourceManager* resManager, Scene::Texture* texture, vk::DescriptorSetLayout* descriptorSetLayout, const DescriptorSetLayoutBinding& binding)
|
||||
{
|
||||
m_texture = texture;
|
||||
Image::Init(resManager->GetContext()->device.get(), texture->format, { texture->resolution.x, texture->resolution.y, texture->resolution.z });
|
||||
resManager->CopyDataToImage(m_texture->size, m_texture->textureBuffer, this);
|
||||
resManager->CopyDataToImage(texture->size, texture->textureBuffer, this);
|
||||
texture->updated = false;
|
||||
|
||||
m_sampler = resManager->CreateSampler(reinterpret_cast<const vk::SamplerCreateInfo&>(*texture->m_samplerConfig));
|
||||
SetDescriptorSet(resManager, descriptorSetLayout, binding);
|
||||
|
||||
texture->renderTexture = this;
|
||||
UpdateAddress(texture);
|
||||
UpdateRenderResource(GetOwnerResource());
|
||||
}
|
||||
|
||||
void InitSharedMem(ResourceManager* resManager, Scene::Texture* texture, vk::DescriptorSetLayout* descriptorSetLayout, const DescriptorSetLayoutBinding& binding)
|
||||
{
|
||||
m_texture = texture;
|
||||
Image::Init(resManager->GetContext()->device.get(), texture->format, { texture->resolution.x, texture->resolution.y, texture->resolution.z }, vk::MemoryPropertyFlagBits::eDeviceLocal | vk::MemoryPropertyFlagBits::eHostVisible);
|
||||
texture->updated = false;
|
||||
texture->textureBuffer = Map();
|
||||
@@ -45,7 +46,8 @@ namespace OpenVulkano::Vulkan
|
||||
m_sampler = resManager->CreateSampler(reinterpret_cast<const vk::SamplerCreateInfo&>(*texture->m_samplerConfig));
|
||||
SetDescriptorSet(resManager, descriptorSetLayout, binding);
|
||||
|
||||
texture->renderTexture = this;
|
||||
UpdateAddress(texture);
|
||||
UpdateRenderResource(GetOwnerResource());
|
||||
}
|
||||
|
||||
virtual ~VulkanTexture() override
|
||||
@@ -55,9 +57,8 @@ namespace OpenVulkano::Vulkan
|
||||
|
||||
void Close() override
|
||||
{
|
||||
ResetRenderResource(GetOwnerResource());
|
||||
Image::Close();
|
||||
if (m_texture) m_texture->renderTexture = nullptr;
|
||||
m_texture = nullptr;
|
||||
}
|
||||
|
||||
void SetDescriptorSet(ResourceManager* resManager, vk::DescriptorSetLayout* descriptorSetLayout, const DescriptorSetLayoutBinding& binding)
|
||||
@@ -75,7 +76,7 @@ namespace OpenVulkano::Vulkan
|
||||
void Record(VulkanDrawContext* context) override
|
||||
{
|
||||
int setId = -1, i = 0;
|
||||
for (const auto& descriptorSet : context->GetShader()->shader->descriptorSets)
|
||||
for (const auto& descriptorSet : context->GetShader()->GetOwner()->descriptorSets)
|
||||
{
|
||||
for (const auto& descriptor : descriptorSet)
|
||||
{
|
||||
@@ -106,6 +107,11 @@ namespace OpenVulkano::Vulkan
|
||||
{
|
||||
context->commandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, context->GetShader()->pipelineLayout, setId, 1, &m_descriptorSet, 0, nullptr);
|
||||
}
|
||||
|
||||
void Release() override
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
};
|
||||
|
||||
class VulkanTextureDynamic : public VulkanTexture
|
||||
@@ -118,20 +124,20 @@ namespace OpenVulkano::Vulkan
|
||||
|
||||
void Record(VulkanDrawContext* context) override
|
||||
{
|
||||
if(m_texture->updated)
|
||||
if(GetOwner()->updated)
|
||||
{
|
||||
context->renderer->GetResourceManager().CopyDataToImage(m_texture->size, m_texture->textureBuffer, this);
|
||||
m_texture->updated = false;
|
||||
context->renderer->GetResourceManager().CopyDataToImage(GetOwner()->size, GetOwner()->textureBuffer, this);
|
||||
GetOwner()->updated = false;
|
||||
}
|
||||
VulkanTexture::Record(context);
|
||||
}
|
||||
|
||||
void Record(VulkanDrawContext* context, int setId) override
|
||||
{
|
||||
if(m_texture->updated)
|
||||
if(GetOwner()->updated)
|
||||
{
|
||||
context->renderer->GetResourceManager().CopyDataToImage(m_texture->size, m_texture->textureBuffer, this);
|
||||
m_texture->updated = false;
|
||||
context->renderer->GetResourceManager().CopyDataToImage(GetOwner()->size, GetOwner()->textureBuffer, this);
|
||||
GetOwner()->updated = false;
|
||||
}
|
||||
VulkanTexture::Record(context, setId);
|
||||
}
|
||||
|
||||
@@ -6,42 +6,31 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Base/ICloseable.hpp"
|
||||
#include "IRecordable.hpp"
|
||||
#include "Scene/UniformBuffer.hpp"
|
||||
#include "Vulkan/Resources/UniformBuffer.hpp"
|
||||
|
||||
namespace OpenVulkano::Vulkan
|
||||
{
|
||||
class VulkanUniformBuffer : public IRecordable, public ICloseable
|
||||
class VulkanUniformBuffer : public IRenderResource<Scene::UniformBuffer>, public IRecordable
|
||||
{
|
||||
public:
|
||||
Scene::UniformBuffer* uBuffer = nullptr;
|
||||
UniformBuffer* buffer = nullptr;
|
||||
Unique<UniformBuffer> buffer = nullptr;
|
||||
|
||||
~VulkanUniformBuffer() override
|
||||
{
|
||||
if (uBuffer) VulkanUniformBuffer::Close();
|
||||
}
|
||||
~VulkanUniformBuffer() override = default;
|
||||
|
||||
virtual void Init(Scene::UniformBuffer* uBuffer, UniformBuffer* uniformBuffer)
|
||||
{
|
||||
this->uBuffer = uBuffer;
|
||||
this->buffer = uniformBuffer;
|
||||
uBuffer->renderBuffer = this;
|
||||
}
|
||||
VulkanUniformBuffer(Scene::UniformBuffer* sceneBuffer, UniformBuffer* uniformBuffer)
|
||||
: IRenderResource<Scene::UniformBuffer>(sceneBuffer), buffer(uniformBuffer)
|
||||
{}
|
||||
|
||||
void Record(VulkanDrawContext* context) override
|
||||
{
|
||||
buffer->Record(context);
|
||||
}
|
||||
|
||||
void Close() override
|
||||
void Release() override
|
||||
{
|
||||
if (uBuffer) uBuffer->renderBuffer = nullptr;
|
||||
delete buffer;
|
||||
uBuffer = nullptr;
|
||||
buffer = nullptr;
|
||||
//TODO
|
||||
}
|
||||
};
|
||||
|
||||
@@ -49,18 +38,16 @@ namespace OpenVulkano::Vulkan
|
||||
{
|
||||
uint32_t lastUpdate = 0;
|
||||
|
||||
void Init(Scene::UniformBuffer* buffer, UniformBuffer* uniformBuffer) override
|
||||
{
|
||||
VulkanUniformBuffer::Init(buffer, uniformBuffer);
|
||||
lastUpdate = -1;
|
||||
}
|
||||
VulkanUniformBufferDynamic(Scene::UniformBuffer* sceneBuffer, UniformBuffer* uniformBuffer)
|
||||
: VulkanUniformBuffer(sceneBuffer, uniformBuffer)
|
||||
{}
|
||||
|
||||
void Record(VulkanDrawContext* context) override
|
||||
{
|
||||
if(uBuffer->updated) //TODO fix
|
||||
if(GetOwner()->updated) //TODO fix
|
||||
{
|
||||
uBuffer->updated = false;
|
||||
buffer->Update(uBuffer->data, uBuffer->size, context->currentImageId);
|
||||
GetOwner()->updated = false;
|
||||
buffer->Update(GetOwner()->data, GetOwner()->size, context->currentImageId);
|
||||
}
|
||||
buffer->Record(context);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace OpenVulkano::Vulkan
|
||||
{
|
||||
void VulkanDrawContext::EncodeShader(Scene::Shader* shader)
|
||||
{
|
||||
VulkanShader* vkShader = static_cast<VulkanShader*>(shader->renderShader);
|
||||
VulkanShader* vkShader = shader->GetRenderResource();
|
||||
if (!vkShader)
|
||||
{
|
||||
vkShader = renderer->GetResourceManager().CreateShader(shader);
|
||||
@@ -34,7 +34,7 @@ namespace OpenVulkano::Vulkan
|
||||
|
||||
void VulkanDrawContext::EncodeNode(Scene::Node* node)
|
||||
{
|
||||
VulkanNode* vkNode = static_cast<VulkanNode*>(node->renderNode);
|
||||
VulkanNode* vkNode = node->GetRenderResource();
|
||||
if (!vkNode)
|
||||
{
|
||||
vkNode = renderer->GetResourceManager().PrepareNode(node);
|
||||
@@ -44,8 +44,8 @@ namespace OpenVulkano::Vulkan
|
||||
|
||||
void VulkanDrawContext::SetCamera(Scene::Camera* camera)
|
||||
{
|
||||
if (!camera->renderCamera) m_lastCamera = ResourceManager::INSTANCE->PrepareCamera(camera);
|
||||
else m_lastCamera = static_cast<VulkanCamera*>(camera->renderCamera);
|
||||
if (!camera->HasRenderResource()) m_lastCamera = ResourceManager::INSTANCE->PrepareCamera(camera);
|
||||
else m_lastCamera = camera->GetRenderResource();
|
||||
if (m_lastShader) m_lastCamera->Record(this);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user