From 3940a720848dc0987790bbb1c7f7f2851f266ed5 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Wed, 21 Aug 2024 13:13:43 +0200 Subject: [PATCH] Render resource handling for textures --- openVulkanoCpp/Base/Render/RenderResource.hpp | 34 ++++++++++++++----- openVulkanoCpp/Scene/Texture.hpp | 20 ++--------- .../Vulkan/Metal/MetalBackedTexture.mm | 6 ++-- .../Vulkan/Resources/ResourceManager.cpp | 4 +-- .../ArBackgroundDrawableVulkanEncoder.cpp | 2 +- .../Scene/SimpleDrawableVulkanEncoder.cpp | 4 +-- openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp | 34 +++++++++++-------- 7 files changed, 57 insertions(+), 47 deletions(-) diff --git a/openVulkanoCpp/Base/Render/RenderResource.hpp b/openVulkanoCpp/Base/Render/RenderResource.hpp index 78141e6..9aa7edb 100644 --- a/openVulkanoCpp/Base/Render/RenderResource.hpp +++ b/openVulkanoCpp/Base/Render/RenderResource.hpp @@ -12,6 +12,11 @@ namespace OpenVulkano { + namespace Vulkan + { + class MetalBackedTexture; + } + class RenderResourcePtr; class IRenderResourceHelper @@ -19,9 +24,11 @@ namespace OpenVulkano friend class RenderResourcePtr; protected: - void UpdateRenderResource(RenderResourcePtr& resource); + void UpdateRenderResource(RenderResourcePtr* resource); - void ResetRenderResource(RenderResourcePtr& resource); + void ResetRenderResource(RenderResourcePtr* resource); + + virtual void DoRelease() = 0; virtual void Release() = 0; }; @@ -32,6 +39,7 @@ namespace OpenVulkano class RenderResourcePtr final { friend class IRenderResourceHelper; + friend class Vulkan::MetalBackedTexture; IRenderResourceHelper* renderObject = nullptr; @@ -48,7 +56,7 @@ namespace OpenVulkano void Release() { if (!renderObject) return; - renderObject->Release(); + renderObject->DoRelease(); renderObject = nullptr; } @@ -61,14 +69,16 @@ namespace OpenVulkano operator bool() const { return renderObject; } }; - inline void IRenderResourceHelper::UpdateRenderResource(RenderResourcePtr& resource) + inline void IRenderResourceHelper::UpdateRenderResource(RenderResourcePtr* resource) { - resource.renderObject = this; + if (resource) + resource->renderObject = this; } - inline void IRenderResourceHelper::ResetRenderResource(RenderResourcePtr& resource) + inline void IRenderResourceHelper::ResetRenderResource(RenderResourcePtr* resource) { - resource.renderObject = nullptr; + if (resource) + resource->renderObject = nullptr; } template @@ -94,7 +104,13 @@ namespace OpenVulkano move.m_owner = nullptr; } - RenderResourcePtr& GetOwnerResource() { return static_cast(*m_owner); } + RenderResourcePtr* GetOwnerResource() { if (!m_owner) return nullptr; else return &static_cast(*m_owner); } + + void DoRelease() final override + { + m_owner = nullptr; + Release(); + } public: virtual ~IRenderResource() @@ -136,7 +152,7 @@ namespace OpenVulkano public: operator RenderResourcePtr&() { return renderResource; } - RenderResourcePtr& GetRenderResource() { return renderResource; } + RenderResourcePtr& GetRenderResource() const { return const_cast(this)->renderResource; } template operator RT() const { return renderResource; } diff --git a/openVulkanoCpp/Scene/Texture.hpp b/openVulkanoCpp/Scene/Texture.hpp index e65a1ce..3565105 100644 --- a/openVulkanoCpp/Scene/Texture.hpp +++ b/openVulkanoCpp/Scene/Texture.hpp @@ -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 { 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}); diff --git a/openVulkanoCpp/Vulkan/Metal/MetalBackedTexture.mm b/openVulkanoCpp/Vulkan/Metal/MetalBackedTexture.mm index f3ffc79..10f23d3 100644 --- a/openVulkanoCpp/Vulkan/Metal/MetalBackedTexture.mm +++ b/openVulkanoCpp/Vulkan/Metal/MetalBackedTexture.mm @@ -19,7 +19,6 @@ namespace OpenVulkano::Vulkan resolution = { static_cast(mtlTexture.width), static_cast(mtlTexture.height), static_cast(mtlTexture.depth) }; format = DataFormat::GetFromMetalPixelFormat(static_cast(mtlTexture.pixelFormat)); - m_vulkanTexture.m_texture = this; m_vulkanTexture.device = resManager->GetDevice(); m_vulkanTexture.format = format; m_vulkanTexture.extent = reinterpret_cast(resolution); @@ -57,7 +56,10 @@ namespace OpenVulkano::Vulkan m_vulkanTexture.m_sampler = resManager->CreateSampler(reinterpret_cast(Scene::SamplerConfig::DEFAULT)); m_vulkanTexture.SetDescriptorSet(resManager, resManager->GetDescriptorLayoutSet(binding), binding); - renderTexture = &m_vulkanTexture; + //m_vulkanTexture.UpdateAddress(this); + //UpdateRenderResource(GetOwnerResource()); + GetRenderResource().renderObject = &m_vulkanTexture; + m_vulkanTexture.UpdateAddress(this); if (!ownsTexture) m_metalTexture = nullptr; } diff --git a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp index 7f40247..e370336 100644 --- a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp +++ b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp @@ -174,7 +174,7 @@ namespace OpenVulkano::Vulkan void ResourceManager::PrepareMaterial(Scene::Material* material) { - if (material->texture && !material->texture->renderTexture) + if (material->texture && !material->texture->HasRenderResource()) { PrepareTexture(material->texture); } @@ -318,7 +318,7 @@ namespace OpenVulkano::Vulkan VulkanTexture* ResourceManager::PrepareTexture(Scene::Texture* texture) { const std::unique_lock lock(mutex); - if (texture->renderTexture) return static_cast(texture->renderTexture); + if (texture->HasRenderResource()) return static_cast(texture->GetRenderResource()); VulkanTexture* vkTexture; if (texture->updateFrequency == Scene::UpdateFrequency::Never) vkTexture = new VulkanTexture(); diff --git a/openVulkanoCpp/Vulkan/Scene/ArBackgroundDrawableVulkanEncoder.cpp b/openVulkanoCpp/Vulkan/Scene/ArBackgroundDrawableVulkanEncoder.cpp index dcdb1b1..229319f 100644 --- a/openVulkanoCpp/Vulkan/Scene/ArBackgroundDrawableVulkanEncoder.cpp +++ b/openVulkanoCpp/Vulkan/Scene/ArBackgroundDrawableVulkanEncoder.cpp @@ -19,7 +19,7 @@ namespace OpenVulkano::Vulkan ArBackgroundDrawable* bgDrawable = static_cast(instance); bgDrawable->Tick(); const Texture* texture = bgDrawable->GetTexture(); - VulkanTexture* vkTexture = static_cast(texture->renderTexture); + VulkanTexture* vkTexture = texture->GetRenderResource(); if (!vkTexture) { vkTexture = drawContext->renderer->GetResourceManager().PrepareTexture(const_cast(texture)); diff --git a/openVulkanoCpp/Vulkan/Scene/SimpleDrawableVulkanEncoder.cpp b/openVulkanoCpp/Vulkan/Scene/SimpleDrawableVulkanEncoder.cpp index c943b89..45f89ea 100644 --- a/openVulkanoCpp/Vulkan/Scene/SimpleDrawableVulkanEncoder.cpp +++ b/openVulkanoCpp/Vulkan/Scene/SimpleDrawableVulkanEncoder.cpp @@ -39,11 +39,11 @@ namespace OpenVulkano::Vulkan { if (Texture* texture = material->texture) { - VulkanTexture* renderTexture = static_cast(texture->renderTexture); + VulkanTexture* renderTexture = texture->GetRenderResource(); if (!renderTexture) { drawContext->renderer->GetResourceManager().PrepareMaterial(drawable->GetMaterial()); - renderTexture = static_cast(texture->renderTexture); + renderTexture = texture->GetRenderResource(); } renderTexture->Record(drawContext); } diff --git a/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp b/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp index 5a079d4..84e3530 100644 --- a/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp +++ b/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp @@ -16,28 +16,29 @@ namespace OpenVulkano::Vulkan { - class VulkanTexture : public Scene::RenderTexture, public IRecordable, public Image + class VulkanTexture : public IRenderResource, public IRecordable, public Image { public: vk::Sampler m_sampler; vk::DescriptorSet m_descriptorSet; + VulkanTexture() : IRenderResource(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(*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(*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) @@ -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); }