Add render resource handling for geometry
This commit is contained in:
@@ -45,8 +45,8 @@ namespace OpenVulkano
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
RenderResourcePtr() = default;
|
RenderResourcePtr() = default;
|
||||||
RenderResourcePtr(const RenderResourcePtr& ignored) { /* Do not copy, copy will be created by renderer */ }
|
RenderResourcePtr(const RenderResourcePtr& ignored) noexcept { /* Do not copy, copy will be created by renderer */ }
|
||||||
RenderResourcePtr(RenderResourcePtr&& move) : renderObject(move.renderObject) { move.renderObject = nullptr; }
|
RenderResourcePtr(RenderResourcePtr&& move) noexcept : renderObject(move.renderObject) { move.renderObject = nullptr; }
|
||||||
|
|
||||||
~RenderResourcePtr()
|
~RenderResourcePtr()
|
||||||
{
|
{
|
||||||
@@ -67,6 +67,14 @@ namespace OpenVulkano
|
|||||||
operator T() { return static_cast<T>(renderObject); }
|
operator T() { return static_cast<T>(renderObject); }
|
||||||
|
|
||||||
operator bool() const { return 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)
|
inline void IRenderResourceHelper::UpdateRenderResource(RenderResourcePtr* resource)
|
||||||
@@ -94,7 +102,7 @@ namespace OpenVulkano
|
|||||||
|
|
||||||
IRenderResource(const IRenderResource<API_INDEPENDENT_CLASS>& copy) = delete;
|
IRenderResource(const IRenderResource<API_INDEPENDENT_CLASS>& copy) = delete;
|
||||||
|
|
||||||
IRenderResource(IRenderResource<API_INDEPENDENT_CLASS>&& move)
|
IRenderResource(IRenderResource<API_INDEPENDENT_CLASS>&& move) noexcept
|
||||||
: m_owner(move.m_owner)
|
: m_owner(move.m_owner)
|
||||||
{
|
{
|
||||||
if (m_owner)
|
if (m_owner)
|
||||||
@@ -139,8 +147,8 @@ namespace OpenVulkano
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
RenderResourceHolder() = default;
|
RenderResourceHolder() = default;
|
||||||
RenderResourceHolder(const RenderResourceHolder& ignored) {}
|
RenderResourceHolder(const RenderResourceHolder& ignored) noexcept {}
|
||||||
RenderResourceHolder(RenderResourceHolder&& move)
|
RenderResourceHolder(RenderResourceHolder&& move) noexcept
|
||||||
: renderResource(std::move(move.renderResource))
|
: renderResource(std::move(move.renderResource))
|
||||||
{
|
{
|
||||||
if (IRenderResource<T>* renderRes = renderResource)
|
if (IRenderResource<T>* renderRes = renderResource)
|
||||||
@@ -158,5 +166,20 @@ namespace OpenVulkano
|
|||||||
operator RT() const { return renderResource; }
|
operator RT() const { return renderResource; }
|
||||||
|
|
||||||
bool HasRenderResource() 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);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,20 +20,17 @@
|
|||||||
namespace OpenVulkano::Scene
|
namespace OpenVulkano::Scene
|
||||||
{
|
{
|
||||||
Geometry::Geometry(const Geometry& other)
|
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)
|
if (other.vertices)
|
||||||
{
|
{
|
||||||
std::copy(other.vertices, other.vertices + other.vertexCount, this->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.indices)
|
||||||
{
|
{
|
||||||
if (other.indexType == VertexIndexType::UINT16)
|
if (other.indexType == VertexIndexType::UINT16)
|
||||||
@@ -59,20 +56,13 @@ namespace OpenVulkano::Scene
|
|||||||
}
|
}
|
||||||
|
|
||||||
Geometry::Geometry(Geometry&& other) noexcept
|
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.vertexCount = other.indexCount = 0;
|
||||||
other.vertices = nullptr;
|
other.vertices = nullptr;
|
||||||
other.indices = nullptr;
|
other.indices = nullptr;
|
||||||
other.renderGeo = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Geometry& Geometry::operator=(Geometry&& other) noexcept
|
Geometry& Geometry::operator=(Geometry&& other) noexcept
|
||||||
@@ -88,11 +78,10 @@ namespace OpenVulkano::Scene
|
|||||||
this->aabb = std::move(other.aabb);
|
this->aabb = std::move(other.aabb);
|
||||||
this->vertices = other.vertices;
|
this->vertices = other.vertices;
|
||||||
this->indices = other.indices;
|
this->indices = other.indices;
|
||||||
this->renderGeo = other.renderGeo;
|
RenderResourceHolder<Geometry>::operator=(std::move(other));
|
||||||
other.vertexCount = other.indexCount = 0;
|
other.vertexCount = other.indexCount = 0;
|
||||||
other.vertices = nullptr;
|
other.vertices = nullptr;
|
||||||
other.indices = nullptr;
|
other.indices = nullptr;
|
||||||
other.renderGeo = nullptr;
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -104,26 +93,25 @@ namespace OpenVulkano::Scene
|
|||||||
|
|
||||||
void Geometry::Swap(Geometry& other) noexcept
|
void Geometry::Swap(Geometry& other) noexcept
|
||||||
{
|
{
|
||||||
|
RenderResourceHolder<Geometry>::Swap(other);
|
||||||
std::swap(this->vertexCount, other.vertexCount);
|
std::swap(this->vertexCount, other.vertexCount);
|
||||||
std::swap(this->indexCount, other.indexCount);
|
std::swap(this->indexCount, other.indexCount);
|
||||||
std::swap(this->aabb, other.aabb);
|
std::swap(this->aabb, other.aabb);
|
||||||
std::swap(this->indexType, other.indexType);
|
std::swap(this->indexType, other.indexType);
|
||||||
std::swap(this->vertices, other.vertices);
|
std::swap(this->vertices, other.vertices);
|
||||||
std::swap(this->indices, other.indices);
|
std::swap(this->indices, other.indices);
|
||||||
std::swap(this->renderGeo, other.renderGeo);
|
|
||||||
std::swap(this->ownsMemory, other.ownsMemory);
|
std::swap(this->ownsMemory, other.ownsMemory);
|
||||||
std::swap(this->freeAfterUpload, other.freeAfterUpload);
|
std::swap(this->freeAfterUpload, other.freeAfterUpload);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Geometry::Init(uint32_t vertexCount, uint32_t indexCount)
|
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->vertexCount = vertexCount;
|
||||||
this->indexCount = indexCount;
|
this->indexCount = indexCount;
|
||||||
indexType = (vertexCount > UINT16_MAX) ? VertexIndexType::UINT32 : VertexIndexType::UINT16;
|
indexType = (vertexCount > UINT16_MAX) ? VertexIndexType::UINT32 : VertexIndexType::UINT16;
|
||||||
vertices = new Vertex[vertexCount];
|
vertices = new Vertex[vertexCount];
|
||||||
indices = malloc(static_cast<size_t>(Utils::EnumAsInt(indexType)) * indexCount);
|
indices = malloc(static_cast<size_t>(Utils::EnumAsInt(indexType)) * indexCount);
|
||||||
renderGeo = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Geometry::InitFromFile(const std::string& file)
|
void Geometry::InitFromFile(const std::string& file)
|
||||||
@@ -212,10 +200,9 @@ namespace OpenVulkano::Scene
|
|||||||
indexCount = 0;
|
indexCount = 0;
|
||||||
Free();
|
Free();
|
||||||
}
|
}
|
||||||
if (renderGeo)
|
if (HasRenderResource())
|
||||||
{
|
{
|
||||||
renderGeo->Close();
|
GetRenderResource().Release();
|
||||||
renderGeo = nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Base/ICloseable.hpp"
|
#include "Base/ICloseable.hpp"
|
||||||
|
#include "Base/Render/RenderResource.hpp"
|
||||||
#include "Math/AABB.hpp"
|
#include "Math/AABB.hpp"
|
||||||
#include "Base/Utils.hpp"
|
#include "Base/Utils.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -24,7 +25,7 @@ namespace OpenVulkano
|
|||||||
UINT16 = sizeof(uint16_t), UINT32 = sizeof(uint32_t)
|
UINT16 = sizeof(uint16_t), UINT32 = sizeof(uint32_t)
|
||||||
};
|
};
|
||||||
|
|
||||||
class Geometry : public ICloseable
|
class Geometry : public RenderResourceHolder<Geometry>, public ICloseable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
uint32_t vertexCount = 0, indexCount = 0;
|
uint32_t vertexCount = 0, indexCount = 0;
|
||||||
@@ -33,7 +34,6 @@ namespace OpenVulkano
|
|||||||
VertexIndexType indexType = VertexIndexType::UINT16;
|
VertexIndexType indexType = VertexIndexType::UINT16;
|
||||||
bool ownsMemory = true, freeAfterUpload = true;
|
bool ownsMemory = true, freeAfterUpload = true;
|
||||||
Math::AABB aabb;
|
Math::AABB aabb;
|
||||||
ICloseable* renderGeo = nullptr;
|
|
||||||
public:
|
public:
|
||||||
Geometry() = default;
|
Geometry() = default;
|
||||||
Geometry(const Geometry& other);
|
Geometry(const Geometry& other);
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ namespace OpenVulkano::Vulkan
|
|||||||
VulkanGeometry* ResourceManager::PrepareGeometry(Scene::Geometry* geometry)
|
VulkanGeometry* ResourceManager::PrepareGeometry(Scene::Geometry* geometry)
|
||||||
{
|
{
|
||||||
const std::unique_lock lock(mutex);
|
const std::unique_lock lock(mutex);
|
||||||
if(!geometry->renderGeo)
|
if(!geometry->HasRenderResource())
|
||||||
{
|
{
|
||||||
ManagedBuffer::Ptr vertexBuffer =
|
ManagedBuffer::Ptr vertexBuffer =
|
||||||
CreateDeviceOnlyBufferWithData(sizeof(Vertex) * geometry->GetVertexCount(), vk::BufferUsageFlagBits::eVertexBuffer, geometry->GetVertices());
|
CreateDeviceOnlyBufferWithData(sizeof(Vertex) * geometry->GetVertexCount(), vk::BufferUsageFlagBits::eVertexBuffer, geometry->GetVertices());
|
||||||
@@ -162,14 +162,13 @@ namespace OpenVulkano::Vulkan
|
|||||||
indexBuffer = CreateDeviceOnlyBufferWithData(Utils::EnumAsInt(geometry->indexType) * geometry->GetIndexCount(), vk::BufferUsageFlagBits::eIndexBuffer, geometry->GetIndices());
|
indexBuffer = CreateDeviceOnlyBufferWithData(Utils::EnumAsInt(geometry->indexType) * geometry->GetIndexCount(), vk::BufferUsageFlagBits::eIndexBuffer, geometry->GetIndices());
|
||||||
VulkanGeometry* vkGeo = new VulkanGeometry(geometry, vertexBuffer, indexBuffer);
|
VulkanGeometry* vkGeo = new VulkanGeometry(geometry, vertexBuffer, indexBuffer);
|
||||||
geometries.emplace_back(vkGeo);
|
geometries.emplace_back(vkGeo);
|
||||||
geometry->renderGeo = vkGeo;
|
|
||||||
if (geometry->ownsMemory && geometry->freeAfterUpload)
|
if (geometry->ownsMemory && geometry->freeAfterUpload)
|
||||||
{
|
{
|
||||||
geometry->Free();
|
geometry->Free();
|
||||||
}
|
}
|
||||||
return vkGeo;
|
return vkGeo;
|
||||||
}
|
}
|
||||||
return dynamic_cast<VulkanGeometry*>(geometry->renderGeo);
|
return geometry->GetRenderResource();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceManager::PrepareMaterial(Scene::Material* material)
|
void ResourceManager::PrepareMaterial(Scene::Material* material)
|
||||||
|
|||||||
@@ -20,13 +20,12 @@ namespace OpenVulkano::Vulkan
|
|||||||
{
|
{
|
||||||
SimpleDrawable* drawable = static_cast<SimpleDrawable*>(instance);
|
SimpleDrawable* drawable = static_cast<SimpleDrawable*>(instance);
|
||||||
Geometry* mesh = drawable->GetMesh();
|
Geometry* mesh = drawable->GetMesh();
|
||||||
VulkanGeometry* renderGeo = static_cast<VulkanGeometry*>(mesh->renderGeo);
|
VulkanGeometry* renderGeo = mesh->GetRenderResource();
|
||||||
if (!renderGeo) renderGeo = drawContext->renderer->GetResourceManager().PrepareGeometry(mesh);
|
if (!renderGeo) renderGeo = drawContext->renderer->GetResourceManager().PrepareGeometry(mesh);
|
||||||
renderGeo->RecordBind(drawContext->commandBuffer);
|
renderGeo->RecordBind(drawContext->commandBuffer);
|
||||||
|
|
||||||
if (drawable->GetBuffer())
|
if (drawable->GetBuffer())
|
||||||
{
|
{
|
||||||
|
|
||||||
VulkanUniformBuffer* vkBuffer = drawable->GetBuffer()->GetRenderResource();
|
VulkanUniformBuffer* vkBuffer = drawable->GetBuffer()->GetRenderResource();
|
||||||
if (!vkBuffer)
|
if (!vkBuffer)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,36 +13,21 @@
|
|||||||
|
|
||||||
namespace OpenVulkano::Vulkan
|
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_vertexBuffer;
|
||||||
ManagedBuffer::Ptr m_indexBuffer;
|
ManagedBuffer::Ptr m_indexBuffer;
|
||||||
vk::IndexType m_indexType;
|
vk::IndexType m_indexType;
|
||||||
vk::DeviceSize m_offsets = 0;
|
vk::DeviceSize m_offsets = 0;
|
||||||
|
|
||||||
public:
|
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)
|
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)
|
, m_indexType((geo->indexType == Scene::VertexIndexType::UINT16) ? vk::IndexType::eUint16 : vk::IndexType::eUint32)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
~VulkanGeometry() override
|
~VulkanGeometry() override = default;
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RecordBind(vk::CommandBuffer& cmdBuffer)
|
void RecordBind(vk::CommandBuffer& cmdBuffer)
|
||||||
{
|
{
|
||||||
@@ -52,15 +37,13 @@ namespace OpenVulkano::Vulkan
|
|||||||
|
|
||||||
void RecordDraw(vk::CommandBuffer& cmdBuffer)
|
void RecordDraw(vk::CommandBuffer& cmdBuffer)
|
||||||
{
|
{
|
||||||
if (m_geometry->GetIndexCount()) { cmdBuffer.drawIndexed(m_geometry->GetIndexCount(), 1, 0, 0, 0); }
|
if (GetOwner()->GetIndexCount()) { cmdBuffer.drawIndexed(GetOwner()->GetIndexCount(), 1, 0, 0, 0); }
|
||||||
else { cmdBuffer.draw(m_geometry->GetVertexCount(), 1, 0, 0); }
|
else { cmdBuffer.draw(GetOwner()->GetVertexCount(), 1, 0, 0); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void Close() override
|
void Release() override
|
||||||
{
|
{
|
||||||
m_geometry->renderGeo = nullptr;
|
//TODO
|
||||||
m_vertexBuffer.reset();
|
|
||||||
m_indexBuffer.reset();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user