#include "RenderAPI.h" #include "PlatformBase.h" // Metal implementation of RenderAPI. #if SUPPORT_METAL #include "Unity/IUnityGraphicsMetal.h" #import #import #import class RenderAPI_Metal : public RenderAPI { public: RenderAPI_Metal(); virtual ~RenderAPI_Metal() { } virtual void processDeviceEvent(UnityGfxDeviceEventType type, IUnityInterfaces* interfaces); virtual bool getUsesReverseZ() { return true; } virtual void initSupportFeature(); virtual void spatialUpScale(void*data); private: id mfx_spatial_scaler; IUnityGraphicsMetal* metal_graphics; }; RenderAPI* CreateRenderAPI_Metal() { return new RenderAPI_Metal(); } RenderAPI_Metal::RenderAPI_Metal() { } void RenderAPI_Metal::processDeviceEvent(UnityGfxDeviceEventType type, IUnityInterfaces* interfaces) { if (type == kUnityGfxDeviceEventInitialize) { metal_graphics = interfaces->Get(); } else if (type == kUnityGfxDeviceEventShutdown) { //@TODO: release resources } } void RenderAPI_Metal::initSupportFeature() { if (@available(iOS 16, macOS 13, *)) { support_features[GraphicsFeature::METAL_FX_SPATIAL_SR] = true; support_features[GraphicsFeature::METAL_FX_TEMPORAL_SR] = true; } } void RenderAPI_Metal::spatialUpScale(void* data) { if (@available(iOS 16, macOS 13, *)) { struct DataPack { void* src; void* dst; bool qulityChange; }; DataPack* data_pack = static_cast(data); id srctex = (__bridge id)data_pack->src; id dsttex = (__bridge id)data_pack->dst; id _device = metal_graphics->MetalDevice(); id cmd = (id)metal_graphics->CurrentCommandBuffer(); // metal_graphics->EndCurrentCommandEncoder(); cmd.label = @"Upscale Command Buffer"; if (mfx_spatial_scaler == nil || data_pack->qulityChange) { MTLFXSpatialScalerDescriptor* desc = [[MTLFXSpatialScalerDescriptor alloc]init]; desc.inputWidth = [srctex width]; desc.inputHeight = [srctex height]; desc.outputWidth = [dsttex width]; desc.outputHeight = [dsttex height]; desc.colorTextureFormat = [srctex pixelFormat]; desc.outputTextureFormat = [dsttex pixelFormat]; desc.colorProcessingMode = MTLFXSpatialScalerColorProcessingModeLinear; mfx_spatial_scaler = [desc newSpatialScalerWithDevice:_device]; if (mfx_spatial_scaler == nil) { return; } } mfx_spatial_scaler.colorTexture = srctex; mfx_spatial_scaler.outputTexture = dsttex; // if(!cmd) { id _commandQueue = [_device newCommandQueue]; id upscaleCommandBuffer = [_commandQueue commandBuffer]; upscaleCommandBuffer.label = @"Upscale Command Buffer"; [mfx_spatial_scaler encodeToCommandBuffer:upscaleCommandBuffer]; [upscaleCommandBuffer commit]; } // else { // [mfx_spatial_scaler encodeToCommandBuffer:cmd]; // [cmd commit]; } } } #endif // #if SUPPORT_METAL