Files
OpenVulkano/openVulkanoCpp/Vulkan/Metal/MetalTextureCache.mm
2025-01-08 15:50:10 +01:00

67 lines
2.4 KiB
Plaintext

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "MetalTextureCache.h"
#include "Vulkan/Renderer.hpp"
namespace OpenVulkano::Vulkan
{
void MetalTextureCache::Init(IRenderer* renderer)
{
if (m_resourceManager) Close();
if (!renderer) return;
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 = 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 = &m_renderer->GetResourceManager();
m_renderer->OnClose += EventHandler(this, &MetalTextureCache::Close);
}
Scene::Texture* MetalTextureCache::Get(CVPixelBufferRef pixelBuffer, MTLPixelFormat pixelFormat)
{
CVMetalTextureRef mtlTextureRef;
auto width = CVPixelBufferGetWidthOfPlane(pixelBuffer, 0);
auto height = CVPixelBufferGetHeightOfPlane(pixelBuffer, 0);
//TODO check pixel format from buffer?
CVMetalTextureCacheCreateTextureFromImage(nil, m_textureCache, pixelBuffer, nil, pixelFormat, width, height, 0, &mtlTextureRef);
id<MTLTexture> mtlTexture = CVMetalTextureGetTexture(mtlTextureRef);
CVBufferRelease(mtlTextureRef);
MetalBackedTexture& texture = m_mtlToVkTextureMap[static_cast<void*>(mtlTexture)];
if (!texture)
{ // Init texture
texture.Init(m_resourceManager, mtlTexture, false);
Logger::RENDER->info("Metal Texture Cache grew to: {}", m_mtlToVkTextureMap.size());
}
return &texture;
}
void MetalTextureCache::ReturnTexture(Scene::Texture* texture)
{
}
void MetalTextureCache::Close()
{
m_mtlToVkTextureMap.clear();
if (m_eventHandler) m_eventHandler->SetInvalid();
m_renderer = nullptr;
m_resourceManager = nullptr;
//TODO delete the texture cache object?
m_textureCache = nullptr;
}
}