Render resource handling for textures
This commit is contained in:
@@ -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; }
|
||||||
|
|||||||
@@ -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});
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user