Render resource handling for textures

This commit is contained in:
Georg Hagen
2024-08-21 13:13:43 +02:00
parent 33c8b74342
commit 3940a72084
7 changed files with 57 additions and 47 deletions

View File

@@ -12,6 +12,11 @@
namespace OpenVulkano namespace OpenVulkano
{ {
namespace Vulkan
{
class MetalBackedTexture;
}
class RenderResourcePtr; class RenderResourcePtr;
class IRenderResourceHelper class IRenderResourceHelper
@@ -19,9 +24,11 @@ namespace OpenVulkano
friend class RenderResourcePtr; friend class RenderResourcePtr;
protected: 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; virtual void Release() = 0;
}; };
@@ -32,6 +39,7 @@ namespace OpenVulkano
class RenderResourcePtr final class RenderResourcePtr final
{ {
friend class IRenderResourceHelper; friend class IRenderResourceHelper;
friend class Vulkan::MetalBackedTexture;
IRenderResourceHelper* renderObject = nullptr; IRenderResourceHelper* renderObject = nullptr;
@@ -48,7 +56,7 @@ namespace OpenVulkano
void Release() void Release()
{ {
if (!renderObject) return; if (!renderObject) return;
renderObject->Release(); renderObject->DoRelease();
renderObject = nullptr; renderObject = nullptr;
} }
@@ -61,14 +69,16 @@ namespace OpenVulkano
operator bool() const { return renderObject; } 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<Renderable API_INDEPENDENT_CLASS> template<Renderable API_INDEPENDENT_CLASS>
@@ -94,7 +104,13 @@ namespace OpenVulkano
move.m_owner = nullptr; move.m_owner = nullptr;
} }
RenderResourcePtr& GetOwnerResource() { return static_cast<RenderResourcePtr&>(*m_owner); } RenderResourcePtr* GetOwnerResource() { if (!m_owner) return nullptr; else return &static_cast<RenderResourcePtr&>(*m_owner); }
void DoRelease() final override
{
m_owner = nullptr;
Release();
}
public: public:
virtual ~IRenderResource() virtual ~IRenderResource()
@@ -136,7 +152,7 @@ namespace OpenVulkano
public: public:
operator RenderResourcePtr&() { return renderResource; } operator RenderResourcePtr&() { return renderResource; }
RenderResourcePtr& GetRenderResource() { return renderResource; } RenderResourcePtr& GetRenderResource() const { return const_cast<RenderResourceHolder*>(this)->renderResource; }
template<Renderable RT> template<Renderable RT>
operator RT() const { return renderResource; } operator RT() const { return renderResource; }

View File

@@ -8,27 +8,19 @@
#include "UpdateFrequency.hpp" #include "UpdateFrequency.hpp"
#include "SamplerConfig.hpp" #include "SamplerConfig.hpp"
#include "Base/ICloseable.hpp" #include "Base/Render/RenderResource.hpp"
#include "Math/Math.hpp" #include "Math/Math.hpp"
#include "DataFormat.hpp" #include "DataFormat.hpp"
#include "Scene/Shader/DescriptorInputDescription.hpp" #include "Scene/Shader/DescriptorInputDescription.hpp"
namespace OpenVulkano::Scene namespace OpenVulkano::Scene
{ {
class Texture; class Texture : public RenderResourceHolder<Texture>
struct RenderTexture
{
Texture* m_texture = nullptr;
};
class Texture
{ {
public: public:
static Texture PLACEHOLDER; static Texture PLACEHOLDER;
static constexpr inline DescriptorSetLayoutBinding DESCRIPTOR_SET_LAYOUT_BINDING = { 0, DescriptorSetLayoutBinding::Type::TYPE_COMBINED_IMAGE_SAMPLER, 1, ShaderProgramType::ALL_GRAPHICS }; 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; void* textureBuffer = nullptr;
size_t size = 0; size_t size = 0;
Math::Vector3ui resolution = {0,0,0}; Math::Vector3ui resolution = {0,0,0};
@@ -41,13 +33,7 @@ namespace OpenVulkano::Scene
: m_samplerConfig(samplerConfig) : m_samplerConfig(samplerConfig)
{ if (placeholder) MakePlaceholder(); } { if (placeholder) MakePlaceholder(); }
~Texture() ~Texture() = default;
{
if (renderTexture)
{
renderTexture->m_texture = nullptr;
}
}
void MakePlaceholder(uint32_t width = 32, uint32_t height = 32, void MakePlaceholder(uint32_t width = 32, uint32_t height = 32,
Math::Vector4uc color1 = {248, 123, 255, 255}, Math::Vector4uc color2 = {250, 19, 255, 255}); Math::Vector4uc color1 = {248, 123, 255, 255}, Math::Vector4uc color2 = {250, 19, 255, 255});

View File

@@ -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) }; 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)); format = DataFormat::GetFromMetalPixelFormat(static_cast<int>(mtlTexture.pixelFormat));
m_vulkanTexture.m_texture = this;
m_vulkanTexture.device = resManager->GetDevice(); m_vulkanTexture.device = resManager->GetDevice();
m_vulkanTexture.format = format; m_vulkanTexture.format = format;
m_vulkanTexture.extent = reinterpret_cast<vk::Extent3D&>(resolution); m_vulkanTexture.extent = reinterpret_cast<vk::Extent3D&>(resolution);
@@ -57,7 +56,10 @@ namespace OpenVulkano::Vulkan
m_vulkanTexture.m_sampler = resManager->CreateSampler(reinterpret_cast<const vk::SamplerCreateInfo&>(Scene::SamplerConfig::DEFAULT)); m_vulkanTexture.m_sampler = resManager->CreateSampler(reinterpret_cast<const vk::SamplerCreateInfo&>(Scene::SamplerConfig::DEFAULT));
m_vulkanTexture.SetDescriptorSet(resManager, resManager->GetDescriptorLayoutSet(binding), binding); 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; if (!ownsTexture) m_metalTexture = nullptr;
} }

View File

@@ -174,7 +174,7 @@ namespace OpenVulkano::Vulkan
void ResourceManager::PrepareMaterial(Scene::Material* material) void ResourceManager::PrepareMaterial(Scene::Material* material)
{ {
if (material->texture && !material->texture->renderTexture) if (material->texture && !material->texture->HasRenderResource())
{ {
PrepareTexture(material->texture); PrepareTexture(material->texture);
} }
@@ -318,7 +318,7 @@ namespace OpenVulkano::Vulkan
VulkanTexture* ResourceManager::PrepareTexture(Scene::Texture* texture) VulkanTexture* ResourceManager::PrepareTexture(Scene::Texture* texture)
{ {
const std::unique_lock lock(mutex); 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; VulkanTexture* vkTexture;
if (texture->updateFrequency == Scene::UpdateFrequency::Never) if (texture->updateFrequency == Scene::UpdateFrequency::Never)
vkTexture = new VulkanTexture(); vkTexture = new VulkanTexture();

View File

@@ -19,7 +19,7 @@ namespace OpenVulkano::Vulkan
ArBackgroundDrawable* bgDrawable = static_cast<ArBackgroundDrawable*>(instance); ArBackgroundDrawable* bgDrawable = static_cast<ArBackgroundDrawable*>(instance);
bgDrawable->Tick(); bgDrawable->Tick();
const Texture* texture = bgDrawable->GetTexture(); const Texture* texture = bgDrawable->GetTexture();
VulkanTexture* vkTexture = static_cast<VulkanTexture*>(texture->renderTexture); VulkanTexture* vkTexture = texture->GetRenderResource();
if (!vkTexture) if (!vkTexture)
{ {
vkTexture = drawContext->renderer->GetResourceManager().PrepareTexture(const_cast<Texture*>(texture)); vkTexture = drawContext->renderer->GetResourceManager().PrepareTexture(const_cast<Texture*>(texture));

View File

@@ -39,11 +39,11 @@ namespace OpenVulkano::Vulkan
{ {
if (Texture* texture = material->texture) if (Texture* texture = material->texture)
{ {
VulkanTexture* renderTexture = static_cast<VulkanTexture*>(texture->renderTexture); VulkanTexture* renderTexture = texture->GetRenderResource();
if (!renderTexture) if (!renderTexture)
{ {
drawContext->renderer->GetResourceManager().PrepareMaterial(drawable->GetMaterial()); drawContext->renderer->GetResourceManager().PrepareMaterial(drawable->GetMaterial());
renderTexture = static_cast<VulkanTexture*>(texture->renderTexture); renderTexture = texture->GetRenderResource();
} }
renderTexture->Record(drawContext); renderTexture->Record(drawContext);
} }

View File

@@ -16,28 +16,29 @@
namespace OpenVulkano::Vulkan namespace OpenVulkano::Vulkan
{ {
class VulkanTexture : public Scene::RenderTexture, public IRecordable, public Image class VulkanTexture : public IRenderResource<Scene::Texture>, public IRecordable, public Image
{ {
public: public:
vk::Sampler m_sampler; vk::Sampler m_sampler;
vk::DescriptorSet m_descriptorSet; vk::DescriptorSet m_descriptorSet;
VulkanTexture() : IRenderResource<Scene::Texture>(nullptr) {}
virtual void Init(ResourceManager* resManager, Scene::Texture* texture, vk::DescriptorSetLayout* descriptorSetLayout, const DescriptorSetLayoutBinding& binding) 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 }); 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; texture->updated = false;
m_sampler = resManager->CreateSampler(reinterpret_cast<const vk::SamplerCreateInfo&>(*texture->m_samplerConfig)); m_sampler = resManager->CreateSampler(reinterpret_cast<const vk::SamplerCreateInfo&>(*texture->m_samplerConfig));
SetDescriptorSet(resManager, descriptorSetLayout, binding); SetDescriptorSet(resManager, descriptorSetLayout, binding);
texture->renderTexture = this; UpdateAddress(texture);
UpdateRenderResource(GetOwnerResource());
} }
void InitSharedMem(ResourceManager* resManager, Scene::Texture* texture, vk::DescriptorSetLayout* descriptorSetLayout, const DescriptorSetLayoutBinding& binding) 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); 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->updated = false;
texture->textureBuffer = Map(); texture->textureBuffer = Map();
@@ -45,7 +46,8 @@ namespace OpenVulkano::Vulkan
m_sampler = resManager->CreateSampler(reinterpret_cast<const vk::SamplerCreateInfo&>(*texture->m_samplerConfig)); m_sampler = resManager->CreateSampler(reinterpret_cast<const vk::SamplerCreateInfo&>(*texture->m_samplerConfig));
SetDescriptorSet(resManager, descriptorSetLayout, binding); SetDescriptorSet(resManager, descriptorSetLayout, binding);
texture->renderTexture = this; UpdateAddress(texture);
UpdateRenderResource(GetOwnerResource());
} }
virtual ~VulkanTexture() override virtual ~VulkanTexture() override
@@ -55,9 +57,8 @@ namespace OpenVulkano::Vulkan
void Close() override void Close() override
{ {
ResetRenderResource(GetOwnerResource());
Image::Close(); Image::Close();
if (m_texture) m_texture->renderTexture = nullptr;
m_texture = nullptr;
} }
void SetDescriptorSet(ResourceManager* resManager, vk::DescriptorSetLayout* descriptorSetLayout, const DescriptorSetLayoutBinding& binding) 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); context->commandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, context->GetShader()->pipelineLayout, setId, 1, &m_descriptorSet, 0, nullptr);
} }
void Release() override
{
//TODO
}
}; };
class VulkanTextureDynamic : public VulkanTexture class VulkanTextureDynamic : public VulkanTexture
@@ -118,20 +124,20 @@ namespace OpenVulkano::Vulkan
void Record(VulkanDrawContext* context) override void Record(VulkanDrawContext* context) override
{ {
if(m_texture->updated) if(GetOwner()->updated)
{ {
context->renderer->GetResourceManager().CopyDataToImage(m_texture->size, m_texture->textureBuffer, this); context->renderer->GetResourceManager().CopyDataToImage(GetOwner()->size, GetOwner()->textureBuffer, this);
m_texture->updated = false; GetOwner()->updated = false;
} }
VulkanTexture::Record(context); VulkanTexture::Record(context);
} }
void Record(VulkanDrawContext* context, int setId) override 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); context->renderer->GetResourceManager().CopyDataToImage(GetOwner()->size, GetOwner()->textureBuffer, this);
m_texture->updated = false; GetOwner()->updated = false;
} }
VulkanTexture::Record(context, setId); VulkanTexture::Record(context, setId);
} }