/* * 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; auto vkRenderer = dynamic_cast(renderer); if (!vkRenderer) 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; 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(); } 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 = CVMetalTextureGetTexture(mtlTextureRef); CVBufferRelease(mtlTextureRef); MetalBackedTexture& texture = m_mtlToVkTextureMap[static_cast(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(); m_resourceManager = nullptr; //TODO delete the texture cache object? m_textureCache = nullptr; } }