Metal: Advanced Present (#6)
* Initial DrawTexture support & Advanced Present * TODO: Get Scissors Working * Chnage scissor state management * Rebase problems… * Rebase fixes again * Update DrawTexture + Fix Topology * Fix flipping * Add clear action support * Cleanup
This commit is contained in:
parent
1f91c74a95
commit
1f29a76ea3
8 changed files with 358 additions and 63 deletions
|
@ -1,5 +1,6 @@
|
|||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Metal.Effects;
|
||||
using SharpMetal.ObjectiveCCore;
|
||||
using SharpMetal.QuartzCore;
|
||||
using System;
|
||||
|
@ -10,51 +11,196 @@ namespace Ryujinx.Graphics.Metal
|
|||
[SupportedOSPlatform("macos")]
|
||||
class Window : IWindow, IDisposable
|
||||
{
|
||||
public bool ScreenCaptureRequested { get; set; }
|
||||
|
||||
private readonly MetalRenderer _renderer;
|
||||
private readonly CAMetalLayer _metalLayer;
|
||||
|
||||
private int _width;
|
||||
private int _height;
|
||||
private bool _vsyncEnabled;
|
||||
private AntiAliasing _currentAntiAliasing;
|
||||
private bool _updateEffect;
|
||||
private IPostProcessingEffect _effect;
|
||||
private IScalingFilter _scalingFilter;
|
||||
private bool _isLinear;
|
||||
private float _scalingFilterLevel;
|
||||
private bool _updateScalingFilter;
|
||||
private ScalingFilter _currentScalingFilter;
|
||||
private bool _colorSpacePassthroughEnabled;
|
||||
|
||||
public Window(MetalRenderer renderer, CAMetalLayer metalLayer)
|
||||
{
|
||||
_renderer = renderer;
|
||||
_metalLayer = metalLayer;
|
||||
}
|
||||
|
||||
// TODO: Handle ImageCrop
|
||||
public void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback)
|
||||
{
|
||||
if (_renderer.Pipeline is Pipeline pipeline && texture is Texture tex)
|
||||
{
|
||||
var drawable = new CAMetalDrawable(ObjectiveC.IntPtr_objc_msgSend(_metalLayer, "nextDrawable"));
|
||||
pipeline.Present(drawable, tex);
|
||||
|
||||
_width = (int)drawable.Texture.Width;
|
||||
_height = (int)drawable.Texture.Height;
|
||||
|
||||
UpdateEffect();
|
||||
|
||||
if (_effect != null)
|
||||
{
|
||||
// TODO: Run Effects
|
||||
// view = _effect.Run()
|
||||
}
|
||||
|
||||
int srcX0, srcX1, srcY0, srcY1;
|
||||
|
||||
if (crop.Left == 0 && crop.Right == 0)
|
||||
{
|
||||
srcX0 = 0;
|
||||
srcX1 = tex.Width;
|
||||
}
|
||||
else
|
||||
{
|
||||
srcX0 = crop.Left;
|
||||
srcX1 = crop.Right;
|
||||
}
|
||||
|
||||
if (crop.Top == 0 && crop.Bottom == 0)
|
||||
{
|
||||
srcY0 = 0;
|
||||
srcY1 = tex.Height;
|
||||
}
|
||||
else
|
||||
{
|
||||
srcY0 = crop.Top;
|
||||
srcY1 = crop.Bottom;
|
||||
}
|
||||
|
||||
if (ScreenCaptureRequested)
|
||||
{
|
||||
// TODO: Support screen captures
|
||||
|
||||
ScreenCaptureRequested = false;
|
||||
}
|
||||
|
||||
float ratioX = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _height * crop.AspectRatioX / (_width * crop.AspectRatioY));
|
||||
float ratioY = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _width * crop.AspectRatioY / (_height * crop.AspectRatioX));
|
||||
|
||||
int dstWidth = (int)(_width * ratioX);
|
||||
int dstHeight = (int)(_height * ratioY);
|
||||
|
||||
int dstPaddingX = (_width - dstWidth) / 2;
|
||||
int dstPaddingY = (_height - dstHeight) / 2;
|
||||
|
||||
int dstX0 = crop.FlipX ? _width - dstPaddingX : dstPaddingX;
|
||||
int dstX1 = crop.FlipX ? dstPaddingX : _width - dstPaddingX;
|
||||
|
||||
int dstY0 = crop.FlipY ? _height - dstPaddingY : dstPaddingY;
|
||||
int dstY1 = crop.FlipY ? dstPaddingY : _height - dstPaddingY;
|
||||
|
||||
if (_scalingFilter != null)
|
||||
{
|
||||
// TODO: Run scaling filter
|
||||
}
|
||||
|
||||
pipeline.Present(
|
||||
drawable,
|
||||
tex,
|
||||
new Extents2D(srcX0, srcY0, srcX1, srcY1),
|
||||
new Extents2D(dstX0, dstY0, dstX1, dstY1),
|
||||
_isLinear);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetSize(int width, int height)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.Gpu, "Not Implemented!");
|
||||
// Ignore
|
||||
}
|
||||
|
||||
public void ChangeVSyncMode(bool vsyncEnabled)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.Gpu, "Not Implemented!");
|
||||
_vsyncEnabled = vsyncEnabled;
|
||||
}
|
||||
|
||||
public void SetAntiAliasing(AntiAliasing antialiasing)
|
||||
public void SetAntiAliasing(AntiAliasing effect)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.Gpu, "Not Implemented!");
|
||||
if (_currentAntiAliasing == effect && _effect != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_currentAntiAliasing = effect;
|
||||
|
||||
_updateEffect = true;
|
||||
}
|
||||
|
||||
public void SetScalingFilter(ScalingFilter type)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.Gpu, "Not Implemented!");
|
||||
if (_currentScalingFilter == type && _effect != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_currentScalingFilter = type;
|
||||
|
||||
_updateScalingFilter = true;
|
||||
}
|
||||
|
||||
public void SetScalingFilterLevel(float level)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.Gpu, "Not Implemented!");
|
||||
_scalingFilterLevel = level;
|
||||
_updateScalingFilter = true;
|
||||
}
|
||||
|
||||
public void SetColorSpacePassthrough(bool colorSpacePassThroughEnabled) { }
|
||||
public void SetColorSpacePassthrough(bool colorSpacePassThroughEnabled)
|
||||
{
|
||||
_colorSpacePassthroughEnabled = colorSpacePassThroughEnabled;
|
||||
}
|
||||
|
||||
private void UpdateEffect()
|
||||
{
|
||||
if (_updateEffect)
|
||||
{
|
||||
_updateEffect = false;
|
||||
|
||||
switch (_currentAntiAliasing)
|
||||
{
|
||||
case AntiAliasing.Fxaa:
|
||||
_effect?.Dispose();
|
||||
Logger.Warning?.PrintMsg(LogClass.Gpu, "FXAA not implemented for Metal backend!");
|
||||
break;
|
||||
case AntiAliasing.None:
|
||||
_effect?.Dispose();
|
||||
_effect = null;
|
||||
break;
|
||||
case AntiAliasing.SmaaLow:
|
||||
case AntiAliasing.SmaaMedium:
|
||||
case AntiAliasing.SmaaHigh:
|
||||
case AntiAliasing.SmaaUltra:
|
||||
var quality = _currentAntiAliasing - AntiAliasing.SmaaLow;
|
||||
Logger.Warning?.PrintMsg(LogClass.Gpu, "SMAA not implemented for Metal backend!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_updateScalingFilter)
|
||||
{
|
||||
_updateScalingFilter = false;
|
||||
|
||||
switch (_currentScalingFilter)
|
||||
{
|
||||
case ScalingFilter.Bilinear:
|
||||
case ScalingFilter.Nearest:
|
||||
_scalingFilter?.Dispose();
|
||||
_scalingFilter = null;
|
||||
_isLinear = _currentScalingFilter == ScalingFilter.Bilinear;
|
||||
break;
|
||||
case ScalingFilter.Fsr:
|
||||
Logger.Warning?.PrintMsg(LogClass.Gpu, "FSR not implemented for Metal backend!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue