From 2d08b3ab91651598bb0645c4705e7698116fdd17 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Wed, 21 Aug 2024 14:33:45 +0200 Subject: [PATCH] Add render resource handling for geometry --- openVulkanoCpp/Base/Render/RenderResource.hpp | 33 +++++++++++-- openVulkanoCpp/Scene/Geometry.cpp | 49 +++++++------------ openVulkanoCpp/Scene/Geometry.hpp | 4 +- .../Vulkan/Resources/ResourceManager.cpp | 5 +- .../Scene/SimpleDrawableVulkanEncoder.cpp | 3 +- .../Vulkan/Scene/VulkanGeometry.hpp | 33 +++---------- 6 files changed, 59 insertions(+), 68 deletions(-) diff --git a/openVulkanoCpp/Base/Render/RenderResource.hpp b/openVulkanoCpp/Base/Render/RenderResource.hpp index 9aa7edb..93e62a6 100644 --- a/openVulkanoCpp/Base/Render/RenderResource.hpp +++ b/openVulkanoCpp/Base/Render/RenderResource.hpp @@ -45,8 +45,8 @@ namespace OpenVulkano public: RenderResourcePtr() = default; - RenderResourcePtr(const RenderResourcePtr& ignored) { /* Do not copy, copy will be created by renderer */ } - RenderResourcePtr(RenderResourcePtr&& move) : renderObject(move.renderObject) { move.renderObject = nullptr; } + 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() { @@ -67,6 +67,14 @@ namespace OpenVulkano operator T() { return static_cast(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) @@ -94,7 +102,7 @@ namespace OpenVulkano IRenderResource(const IRenderResource& copy) = delete; - IRenderResource(IRenderResource&& move) + IRenderResource(IRenderResource&& move) noexcept : m_owner(move.m_owner) { if (m_owner) @@ -139,8 +147,8 @@ namespace OpenVulkano protected: RenderResourceHolder() = default; - RenderResourceHolder(const RenderResourceHolder& ignored) {} - RenderResourceHolder(RenderResourceHolder&& move) + RenderResourceHolder(const RenderResourceHolder& ignored) noexcept {} + RenderResourceHolder(RenderResourceHolder&& move) noexcept : renderResource(std::move(move.renderResource)) { if (IRenderResource* renderRes = renderResource) @@ -158,5 +166,20 @@ namespace OpenVulkano operator RT() const { return renderResource; } bool HasRenderResource() const { return renderResource; } + + RenderResourceHolder& operator =(RenderResourceHolder&& move) noexcept + { + renderResource = std::move(move.renderResource); + if (IRenderResource* renderRes = renderResource) + renderRes->UpdateAddress(static_cast(this)); + return *this; + } + + void Swap(RenderResourceHolder& other) noexcept + { + RenderResourceHolder tmp(std::move(*this)); + *this = std::move(other); + other = std::move(tmp); + } }; } diff --git a/openVulkanoCpp/Scene/Geometry.cpp b/openVulkanoCpp/Scene/Geometry.cpp index c2b28db..a5b897c 100644 --- a/openVulkanoCpp/Scene/Geometry.cpp +++ b/openVulkanoCpp/Scene/Geometry.cpp @@ -19,21 +19,18 @@ namespace OpenVulkano::Scene { - Geometry::Geometry(const Geometry& other) - { - 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]; + 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(Utils::EnumAsInt(other.indexType)) * other.indexCount) : nullptr) + , indexType(other.indexType) + , ownsMemory(other.ownsMemory), freeAfterUpload(other.freeAfterUpload) + , aabb(other.aabb) + { if (other.vertices) { std::copy(other.vertices, other.vertices + other.vertexCount, this->vertices); } - this->indices = malloc(static_cast(Utils::EnumAsInt(other.indexType)) * other.indexCount); if (other.indices) { if (other.indexType == VertexIndexType::UINT16) @@ -58,21 +55,14 @@ namespace OpenVulkano::Scene return *this; } - Geometry::Geometry(Geometry&& other) noexcept + Geometry::Geometry(Geometry&& other) noexcept + : RenderResourceHolder(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 @@ -88,11 +78,10 @@ namespace OpenVulkano::Scene this->aabb = std::move(other.aabb); this->vertices = other.vertices; this->indices = other.indices; - this->renderGeo = other.renderGeo; + RenderResourceHolder::operator=(std::move(other)); other.vertexCount = other.indexCount = 0; other.vertices = nullptr; other.indices = nullptr; - other.renderGeo = nullptr; } return *this; } @@ -103,27 +92,26 @@ namespace OpenVulkano::Scene } void Geometry::Swap(Geometry& other) noexcept - { + { + RenderResourceHolder::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(Utils::EnumAsInt(indexType)) * indexCount); - renderGeo = nullptr; } void Geometry::InitFromFile(const std::string& file) @@ -212,10 +200,9 @@ namespace OpenVulkano::Scene indexCount = 0; Free(); } - if (renderGeo) + if (HasRenderResource()) { - renderGeo->Close(); - renderGeo = nullptr; + GetRenderResource().Release(); } } diff --git a/openVulkanoCpp/Scene/Geometry.hpp b/openVulkanoCpp/Scene/Geometry.hpp index c38b9cb..4ef3dcc 100644 --- a/openVulkanoCpp/Scene/Geometry.hpp +++ b/openVulkanoCpp/Scene/Geometry.hpp @@ -7,6 +7,7 @@ #pragma once #include "Base/ICloseable.hpp" +#include "Base/Render/RenderResource.hpp" #include "Math/AABB.hpp" #include "Base/Utils.hpp" #include @@ -24,7 +25,7 @@ namespace OpenVulkano UINT16 = sizeof(uint16_t), UINT32 = sizeof(uint32_t) }; - class Geometry : public ICloseable + class Geometry : public RenderResourceHolder, public ICloseable { public: uint32_t vertexCount = 0, indexCount = 0; @@ -33,7 +34,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); diff --git a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp index 1d9042a..16e9c4b 100644 --- a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp +++ b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp @@ -153,7 +153,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,14 +162,13 @@ 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(geometry->renderGeo); + return geometry->GetRenderResource(); } void ResourceManager::PrepareMaterial(Scene::Material* material) diff --git a/openVulkanoCpp/Vulkan/Scene/SimpleDrawableVulkanEncoder.cpp b/openVulkanoCpp/Vulkan/Scene/SimpleDrawableVulkanEncoder.cpp index 45f89ea..a6b40c8 100644 --- a/openVulkanoCpp/Vulkan/Scene/SimpleDrawableVulkanEncoder.cpp +++ b/openVulkanoCpp/Vulkan/Scene/SimpleDrawableVulkanEncoder.cpp @@ -20,13 +20,12 @@ namespace OpenVulkano::Vulkan { SimpleDrawable* drawable = static_cast(instance); Geometry* mesh = drawable->GetMesh(); - VulkanGeometry* renderGeo = static_cast(mesh->renderGeo); + VulkanGeometry* renderGeo = mesh->GetRenderResource(); if (!renderGeo) renderGeo = drawContext->renderer->GetResourceManager().PrepareGeometry(mesh); renderGeo->RecordBind(drawContext->commandBuffer); if (drawable->GetBuffer()) { - VulkanUniformBuffer* vkBuffer = drawable->GetBuffer()->GetRenderResource(); if (!vkBuffer) { diff --git a/openVulkanoCpp/Vulkan/Scene/VulkanGeometry.hpp b/openVulkanoCpp/Vulkan/Scene/VulkanGeometry.hpp index eb5459f..10c5c6b 100644 --- a/openVulkanoCpp/Vulkan/Scene/VulkanGeometry.hpp +++ b/openVulkanoCpp/Vulkan/Scene/VulkanGeometry.hpp @@ -13,36 +13,21 @@ namespace OpenVulkano::Vulkan { - class VulkanGeometry final : public ICloseable + class VulkanGeometry final : public IRenderResource { - 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(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 } }; }