mirror of
https://github.com/Ryujinx/Ryujinx.git
synced 2024-12-24 06:16:01 +00:00
Maintain identity swizzle view of textures for rendering
This commit is contained in:
parent
7b9b23e500
commit
468ab8242f
2 changed files with 64 additions and 6 deletions
|
@ -101,10 +101,10 @@ namespace Ryujinx.Graphics.Metal
|
|||
|
||||
for (int i = 0; i < Constants.MaxColorAttachments; i++)
|
||||
{
|
||||
if (_currentState.RenderTargets[i] != null)
|
||||
if (_currentState.RenderTargets[i] is Texture tex)
|
||||
{
|
||||
var passAttachment = renderPassDescriptor.ColorAttachments.Object((ulong)i);
|
||||
passAttachment.Texture = _currentState.RenderTargets[i].GetHandle();
|
||||
tex.PopulateRenderPassAttachment(passAttachment);
|
||||
passAttachment.LoadAction = _currentState.ClearLoadAction ? MTLLoadAction.Clear : MTLLoadAction.Load;
|
||||
passAttachment.StoreAction = MTLStoreAction.Store;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,9 @@ namespace Ryujinx.Graphics.Metal
|
|||
[SupportedOSPlatform("macos")]
|
||||
class Texture : TextureBase, ITexture
|
||||
{
|
||||
private MTLTexture _identitySwizzleHandle;
|
||||
private bool _identityIsDifferent;
|
||||
|
||||
public Texture(MTLDevice device, MetalRenderer renderer, Pipeline pipeline, TextureCreateInfo info) : base(device, renderer, pipeline, info)
|
||||
{
|
||||
MTLPixelFormat pixelFormat = FormatTable.GetFormat(Info.Format);
|
||||
|
@ -35,9 +38,19 @@ namespace Ryujinx.Graphics.Metal
|
|||
descriptor.ArrayLength = (ulong)Info.Depth;
|
||||
}
|
||||
|
||||
descriptor.Swizzle = GetSwizzle(info, descriptor.PixelFormat);
|
||||
MTLTextureSwizzleChannels swizzle = GetSwizzle(info, descriptor.PixelFormat);
|
||||
|
||||
_mtlTexture = _device.NewTexture(descriptor);
|
||||
_identitySwizzleHandle = _device.NewTexture(descriptor);
|
||||
|
||||
if (SwizzleIsIdentity(swizzle))
|
||||
{
|
||||
_mtlTexture = _identitySwizzleHandle;
|
||||
}
|
||||
else
|
||||
{
|
||||
_mtlTexture = CreateDefaultView(_identitySwizzleHandle, swizzle, descriptor);
|
||||
_identityIsDifferent = true;
|
||||
}
|
||||
|
||||
MtlFormat = pixelFormat;
|
||||
descriptor.Dispose();
|
||||
|
@ -56,13 +69,48 @@ namespace Ryujinx.Graphics.Metal
|
|||
|
||||
var swizzle = GetSwizzle(info, pixelFormat);
|
||||
|
||||
_identitySwizzleHandle = sourceTexture.NewTextureView(pixelFormat, textureType, levels, slices);
|
||||
|
||||
if (SwizzleIsIdentity(swizzle))
|
||||
{
|
||||
_mtlTexture = _identitySwizzleHandle;
|
||||
}
|
||||
else
|
||||
{
|
||||
_mtlTexture = sourceTexture.NewTextureView(pixelFormat, textureType, levels, slices, swizzle);
|
||||
_identityIsDifferent = true;
|
||||
}
|
||||
|
||||
MtlFormat = pixelFormat;
|
||||
FirstLayer = firstLayer;
|
||||
FirstLevel = firstLevel;
|
||||
}
|
||||
|
||||
public void PopulateRenderPassAttachment(MTLRenderPassColorAttachmentDescriptor descriptor)
|
||||
{
|
||||
descriptor.Texture = _identitySwizzleHandle;
|
||||
}
|
||||
|
||||
private MTLTexture CreateDefaultView(MTLTexture texture, MTLTextureSwizzleChannels swizzle, MTLTextureDescriptor descriptor)
|
||||
{
|
||||
NSRange levels;
|
||||
levels.location = 0;
|
||||
levels.length = (ulong)Info.Levels;
|
||||
NSRange slices;
|
||||
slices.location = 0;
|
||||
slices.length = Info.Target == Target.Texture3D ? 1 : (ulong)Info.GetDepthOrLayers();
|
||||
|
||||
return texture.NewTextureView(descriptor.PixelFormat, descriptor.TextureType, levels, slices, swizzle);
|
||||
}
|
||||
|
||||
private bool SwizzleIsIdentity(MTLTextureSwizzleChannels swizzle)
|
||||
{
|
||||
return swizzle.red == MTLTextureSwizzle.Red &&
|
||||
swizzle.green == MTLTextureSwizzle.Green &&
|
||||
swizzle.blue == MTLTextureSwizzle.Blue &&
|
||||
swizzle.alpha == MTLTextureSwizzle.Alpha;
|
||||
}
|
||||
|
||||
private MTLTextureSwizzleChannels GetSwizzle(TextureCreateInfo info, MTLPixelFormat pixelFormat)
|
||||
{
|
||||
var swizzleR = Info.SwizzleR.Convert();
|
||||
|
@ -237,7 +285,7 @@ namespace Ryujinx.Graphics.Metal
|
|||
|
||||
public ITexture CreateView(TextureCreateInfo info, int firstLayer, int firstLevel)
|
||||
{
|
||||
return new Texture(_device, _renderer, _pipeline, info, _mtlTexture, firstLayer, firstLevel);
|
||||
return new Texture(_device, _renderer, _pipeline, info, _identitySwizzleHandle, firstLayer, firstLevel);
|
||||
}
|
||||
|
||||
private int GetBufferDataLength(int size)
|
||||
|
@ -521,5 +569,15 @@ namespace Ryujinx.Graphics.Metal
|
|||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void Release()
|
||||
{
|
||||
if (_identityIsDifferent)
|
||||
{
|
||||
_identitySwizzleHandle.Dispose();
|
||||
}
|
||||
|
||||
base.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue