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++)
|
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);
|
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.LoadAction = _currentState.ClearLoadAction ? MTLLoadAction.Clear : MTLLoadAction.Load;
|
||||||
passAttachment.StoreAction = MTLStoreAction.Store;
|
passAttachment.StoreAction = MTLStoreAction.Store;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,9 @@ namespace Ryujinx.Graphics.Metal
|
||||||
[SupportedOSPlatform("macos")]
|
[SupportedOSPlatform("macos")]
|
||||||
class Texture : TextureBase, ITexture
|
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)
|
public Texture(MTLDevice device, MetalRenderer renderer, Pipeline pipeline, TextureCreateInfo info) : base(device, renderer, pipeline, info)
|
||||||
{
|
{
|
||||||
MTLPixelFormat pixelFormat = FormatTable.GetFormat(Info.Format);
|
MTLPixelFormat pixelFormat = FormatTable.GetFormat(Info.Format);
|
||||||
|
@ -34,10 +37,20 @@ namespace Ryujinx.Graphics.Metal
|
||||||
{
|
{
|
||||||
descriptor.ArrayLength = (ulong)Info.Depth;
|
descriptor.ArrayLength = (ulong)Info.Depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MTLTextureSwizzleChannels swizzle = GetSwizzle(info, descriptor.PixelFormat);
|
||||||
|
|
||||||
descriptor.Swizzle = GetSwizzle(info, descriptor.PixelFormat);
|
_identitySwizzleHandle = _device.NewTexture(descriptor);
|
||||||
|
|
||||||
_mtlTexture = _device.NewTexture(descriptor);
|
if (SwizzleIsIdentity(swizzle))
|
||||||
|
{
|
||||||
|
_mtlTexture = _identitySwizzleHandle;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_mtlTexture = CreateDefaultView(_identitySwizzleHandle, swizzle, descriptor);
|
||||||
|
_identityIsDifferent = true;
|
||||||
|
}
|
||||||
|
|
||||||
MtlFormat = pixelFormat;
|
MtlFormat = pixelFormat;
|
||||||
descriptor.Dispose();
|
descriptor.Dispose();
|
||||||
|
@ -56,13 +69,48 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
var swizzle = GetSwizzle(info, pixelFormat);
|
var swizzle = GetSwizzle(info, pixelFormat);
|
||||||
|
|
||||||
_mtlTexture = sourceTexture.NewTextureView(pixelFormat, textureType, levels, slices, swizzle);
|
_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;
|
MtlFormat = pixelFormat;
|
||||||
FirstLayer = firstLayer;
|
FirstLayer = firstLayer;
|
||||||
FirstLevel = firstLevel;
|
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)
|
private MTLTextureSwizzleChannels GetSwizzle(TextureCreateInfo info, MTLPixelFormat pixelFormat)
|
||||||
{
|
{
|
||||||
var swizzleR = Info.SwizzleR.Convert();
|
var swizzleR = Info.SwizzleR.Convert();
|
||||||
|
@ -237,7 +285,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public ITexture CreateView(TextureCreateInfo info, int firstLayer, int firstLevel)
|
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)
|
private int GetBufferDataLength(int size)
|
||||||
|
@ -521,5 +569,15 @@ namespace Ryujinx.Graphics.Metal
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Release()
|
||||||
|
{
|
||||||
|
if (_identityIsDifferent)
|
||||||
|
{
|
||||||
|
_identitySwizzleHandle.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
base.Release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue