Render resource handling for textures
This commit is contained in:
@@ -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<Renderable API_INDEPENDENT_CLASS>
|
||||
@@ -94,7 +104,13 @@ namespace OpenVulkano
|
||||
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:
|
||||
virtual ~IRenderResource()
|
||||
@@ -136,7 +152,7 @@ namespace OpenVulkano
|
||||
public:
|
||||
operator RenderResourcePtr&() { return renderResource; }
|
||||
|
||||
RenderResourcePtr& GetRenderResource() { return renderResource; }
|
||||
RenderResourcePtr& GetRenderResource() const { return const_cast<RenderResourceHolder*>(this)->renderResource; }
|
||||
|
||||
template<Renderable RT>
|
||||
operator RT() const { return renderResource; }
|
||||
|
||||
@@ -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});
|
||||
|
||||
@@ -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,10 @@ 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;
|
||||
//m_vulkanTexture.UpdateAddress(this);
|
||||
//UpdateRenderResource(GetOwnerResource());
|
||||
GetRenderResource().renderObject = &m_vulkanTexture;
|
||||
m_vulkanTexture.UpdateAddress(this);
|
||||
|
||||
if (!ownsTexture) m_metalTexture = nullptr;
|
||||
}
|
||||
|
||||
@@ -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<VulkanTexture*>(texture->renderTexture);
|
||||
if (texture->HasRenderResource()) return static_cast<VulkanTexture*>(texture->GetRenderResource());
|
||||
VulkanTexture* vkTexture;
|
||||
if (texture->updateFrequency == Scene::UpdateFrequency::Never)
|
||||
vkTexture = new VulkanTexture();
|
||||
|
||||
@@ -19,7 +19,7 @@ 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));
|
||||
|
||||
@@ -39,11 +39,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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user