2024-12-18 14:20:41 +08:00

126 lines
3.0 KiB
Plaintext

#include "RenderAPI.h"
#include "PlatformBase.h"
// Metal implementation of RenderAPI.
#if SUPPORT_METAL
#include "Unity/IUnityGraphicsMetal.h"
#import <Metal/Metal.h>
#import <Foundation/Foundation.h>
#import <MetalFX/MTLFXSpatialScaler.h>
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 <MTLFXSpatialScaler> 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<IUnityGraphicsMetal>();
}
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<DataPack*>(data);
id<MTLTexture> srctex = (__bridge id<MTLTexture>)data_pack->src;
id<MTLTexture> dsttex = (__bridge id<MTLTexture>)data_pack->dst;
id<MTLDevice> _device = metal_graphics->MetalDevice();
id<MTLCommandBuffer> cmd = (id<MTLCommandBuffer>)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 <MTLCommandQueue> _commandQueue = [_device newCommandQueue];
id <MTLCommandBuffer> 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