Make sure texture cache is released before destroying device
This commit is contained in:
@@ -110,7 +110,10 @@ namespace OpenVulkano::AR::ArKit
|
||||
|
||||
void ArSessionArKitInternal::SetRenderer(IRenderer* renderer)
|
||||
{
|
||||
m_textureCache.Init(renderer);
|
||||
if (renderer)
|
||||
m_textureCache.Init(renderer);
|
||||
else
|
||||
m_textureCache.Close();
|
||||
}
|
||||
|
||||
Scene::Texture* ArSessionArKitInternal::MakeTexture(ArFrame* frame)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Base/ICloseable.hpp"
|
||||
#include "MetalBackedTexture.h"
|
||||
|
||||
#import <CoreVideo/CVPixelBuffer.h>
|
||||
@@ -13,18 +14,21 @@
|
||||
|
||||
namespace OpenVulkano::Vulkan
|
||||
{
|
||||
class MetalTextureCache
|
||||
class Renderer;
|
||||
|
||||
class MetalTextureCache : public ICloseable
|
||||
{
|
||||
CVMetalTextureCacheRef m_textureCache = nullptr;
|
||||
Vulkan::ResourceManager* m_resourceManager = nullptr;
|
||||
std::map<void*, MetalBackedTexture> m_mtlToVkTextureMap;
|
||||
Renderer* m_renderer;
|
||||
|
||||
public:
|
||||
~MetalTextureCache() { if (m_resourceManager) Close(); }
|
||||
|
||||
void Init(IRenderer* renderer);
|
||||
|
||||
void Close();
|
||||
void Close() override;
|
||||
|
||||
Scene::Texture* Get(CVPixelBufferRef pixelBuffer, MTLPixelFormat pixelFormat);
|
||||
|
||||
|
||||
@@ -13,21 +13,22 @@ namespace OpenVulkano::Vulkan
|
||||
{
|
||||
if (m_resourceManager) Close();
|
||||
if (!renderer) return;
|
||||
auto vkRenderer = dynamic_cast<Vulkan::Renderer*>(renderer);
|
||||
if (!vkRenderer) throw std::invalid_argument("The Metal Texture Cache only supports Vulkan renderer!");
|
||||
m_renderer = dynamic_cast<Vulkan::Renderer*>(renderer);
|
||||
if (!m_renderer) throw std::invalid_argument("The Metal Texture Cache only supports Vulkan renderer!");
|
||||
// Setup texture cache
|
||||
VkExportMetalDeviceInfoEXT metalDeviceInfo {};
|
||||
metalDeviceInfo.sType = VK_STRUCTURE_TYPE_EXPORT_METAL_DEVICE_INFO_EXT;
|
||||
metalDeviceInfo.pNext = nullptr;
|
||||
VkExportMetalObjectsInfoEXT exportInfo { VK_STRUCTURE_TYPE_EXPORT_METAL_OBJECTS_INFO_EXT, &metalDeviceInfo };
|
||||
VkDevice vkDevice = vkRenderer->GetContext().device->device;
|
||||
VkDevice vkDevice = m_renderer->GetContext().device->device;
|
||||
vkExportMetalObjectsEXT(vkDevice, &exportInfo);
|
||||
CVReturn result = CVMetalTextureCacheCreate(nil, nil, metalDeviceInfo.mtlDevice, nil, &m_textureCache);
|
||||
if (result != kCVReturnSuccess)
|
||||
{
|
||||
Logger::AR->error("Failed to create metal texture cache! Status code: {}", result);
|
||||
}
|
||||
m_resourceManager = &vkRenderer->GetResourceManager();
|
||||
m_resourceManager = &m_renderer->GetResourceManager();
|
||||
m_renderer->RegisterCloseable(this);
|
||||
}
|
||||
|
||||
Scene::Texture* MetalTextureCache::Get(CVPixelBufferRef pixelBuffer, MTLPixelFormat pixelFormat)
|
||||
@@ -56,6 +57,8 @@ namespace OpenVulkano::Vulkan
|
||||
void MetalTextureCache::Close()
|
||||
{
|
||||
m_mtlToVkTextureMap.clear();
|
||||
m_renderer->UnregisterCloseable(this);
|
||||
m_renderer = nullptr;
|
||||
m_resourceManager = nullptr;
|
||||
//TODO delete the texture cache object?
|
||||
m_textureCache = nullptr;
|
||||
|
||||
@@ -79,6 +79,12 @@ namespace OpenVulkano::Vulkan
|
||||
{
|
||||
context.device->device.destroySemaphore(sema);
|
||||
}
|
||||
while (!closeables.empty())
|
||||
{
|
||||
ICloseable* closeable = closeables.back();
|
||||
closeables.pop_back();
|
||||
closeable->Close();
|
||||
}
|
||||
uiRenderer.Close();
|
||||
resourceManager.Close();
|
||||
commands.clear();
|
||||
|
||||
@@ -39,6 +39,7 @@ namespace OpenVulkano::Vulkan
|
||||
std::vector<std::vector<CommandHelper>> commands;
|
||||
std::vector<std::vector<vk::CommandBuffer>> submitBuffers;
|
||||
UiRenderer uiRenderer;
|
||||
std::vector<ICloseable*> closeables;
|
||||
|
||||
public:
|
||||
Renderer() = default;
|
||||
@@ -79,5 +80,9 @@ namespace OpenVulkano::Vulkan
|
||||
ResourceManager& GetResourceManager() { return resourceManager; }
|
||||
|
||||
Context& GetContext() { return context; }
|
||||
|
||||
void RegisterCloseable(ICloseable* closeable) { closeables.push_back(closeable); }
|
||||
|
||||
void UnregisterCloseable(ICloseable* closeable) { Utils::Remove(closeables, closeable); }
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user