Texture Copys

This commit is contained in:
Isaac Marovitz 2023-07-27 22:54:24 -04:00 committed by Isaac Marovitz
parent 1e36815713
commit 70f54f23c9
4 changed files with 73 additions and 20 deletions

View file

@ -31,9 +31,7 @@ namespace Ryujinx.Graphics.Metal
_device = MTLDevice.CreateSystemDefaultDevice(); _device = MTLDevice.CreateSystemDefaultDevice();
Queue = _device.NewCommandQueue(); Queue = _device.NewCommandQueue();
var commandBuffer = Queue.CommandBuffer(); _pipeline = new Pipeline(_device, Queue);
_pipeline = new Pipeline(_device, commandBuffer);
} }
public void BackgroundContextAction(Action action, bool alwaysBackground = false) public void BackgroundContextAction(Action action, bool alwaysBackground = false)

View file

@ -11,9 +11,16 @@ namespace Ryujinx.Graphics.Metal
[SupportedOSPlatform("macos")] [SupportedOSPlatform("macos")]
public class Pipeline : IPipeline, IDisposable public class Pipeline : IPipeline, IDisposable
{ {
private MTLDevice _device; private readonly MTLDevice _device;
private readonly MTLCommandQueue _mtlCommandQueue;
private MTLCommandBuffer _commandBuffer; private MTLCommandBuffer _commandBuffer;
private MTLRenderCommandEncoder _renderCommandEncoder; private MTLRenderCommandEncoder _renderCommandEncoder;
private MTLRenderPipelineState _renderPipelineState;
private MTLBlitCommandEncoder _blitCommandEncoder;
public MTLRenderCommandEncoder RenderCommandEncoder => _renderCommandEncoder;
public MTLBlitCommandEncoder BlitCommandEncoder => _blitCommandEncoder;
private PrimitiveTopology _topology; private PrimitiveTopology _topology;
@ -21,21 +28,42 @@ namespace Ryujinx.Graphics.Metal
private MTLIndexType _indexType; private MTLIndexType _indexType;
private ulong _indexBufferOffset; private ulong _indexBufferOffset;
public Pipeline(MTLDevice device, MTLCommandBuffer commandBuffer) public Pipeline(MTLDevice device, MTLCommandQueue commandQueue)
{ {
_device = device;
_mtlCommandQueue = commandQueue;
var renderPipelineDescriptor = new MTLRenderPipelineDescriptor(); var renderPipelineDescriptor = new MTLRenderPipelineDescriptor();
var error = new NSError(IntPtr.Zero); var error = new NSError(IntPtr.Zero);
_device = device; _renderPipelineState = _device.NewRenderPipelineState(renderPipelineDescriptor, ref error);
var renderPipelineState = _device.NewRenderPipelineState(renderPipelineDescriptor, ref error);
if (error != IntPtr.Zero) if (error != IntPtr.Zero)
{ {
// throw new Exception($"Failed to create render pipeline state! {StringHelp}"); // throw new Exception($"Failed to create render pipeline state! {StringHelp}");
throw new Exception($"Failed to create render pipeline state!"); throw new Exception($"Failed to create render pipeline state!");
} }
_commandBuffer = commandBuffer; CreateCommandBuffer();
}
public void Present()
{
_renderCommandEncoder.EndEncoding();
_blitCommandEncoder.EndEncoding();
// TODO: Give command buffer a valid MTLDrawable
// _commandBuffer.PresentDrawable();
_commandBuffer.Commit();
CreateCommandBuffer();
}
public void CreateCommandBuffer()
{
_commandBuffer = _mtlCommandQueue.CommandBuffer();
_renderCommandEncoder = _commandBuffer.RenderCommandEncoder(new MTLRenderPassDescriptor()); _renderCommandEncoder = _commandBuffer.RenderCommandEncoder(new MTLRenderPassDescriptor());
_renderCommandEncoder.SetRenderPipelineState(renderPipelineState); _renderCommandEncoder.SetRenderPipelineState(_renderPipelineState);
_blitCommandEncoder = _commandBuffer.BlitCommandEncoder(new MTLBlitPassDescriptor());
} }
public void Barrier() public void Barrier()

View file

@ -10,13 +10,14 @@ namespace Ryujinx.Graphics.Metal
class Texture : ITexture, IDisposable class Texture : ITexture, IDisposable
{ {
private readonly TextureCreateInfo _info; private readonly TextureCreateInfo _info;
private readonly Pipeline _pipeline;
public MTLTexture MTLTexture; public MTLTexture MTLTexture;
public TextureCreateInfo Info => Info; public TextureCreateInfo Info => Info;
public int Width => Info.Width; public int Width => Info.Width;
public int Height => Info.Height; public int Height => Info.Height;
public Texture(MTLDevice device, TextureCreateInfo info, int firstLayer, int firstLevel) public Texture(MTLDevice device, Pipeline pipeline, TextureCreateInfo info, int firstLayer, int firstLevel)
{ {
_info = info; _info = info;
@ -27,6 +28,7 @@ namespace Ryujinx.Graphics.Metal
descriptor.Height = (ulong)Height; descriptor.Height = (ulong)Height;
descriptor.Depth = (ulong)Info.Depth; descriptor.Depth = (ulong)Info.Depth;
descriptor.SampleCount = (ulong)Info.Samples; descriptor.SampleCount = (ulong)Info.Samples;
descriptor.MipmapLevelCount = (ulong)Info.Levels;
descriptor.TextureType = Info.Target.Convert(); descriptor.TextureType = Info.Target.Convert();
descriptor.Swizzle = new MTLTextureSwizzleChannels descriptor.Swizzle = new MTLTextureSwizzleChannels
{ {
@ -37,16 +39,39 @@ namespace Ryujinx.Graphics.Metal
}; };
MTLTexture = device.NewTexture(descriptor); MTLTexture = device.NewTexture(descriptor);
_pipeline = pipeline;
} }
public void CopyTo(ITexture destination, int firstLayer, int firstLevel) public void CopyTo(ITexture destination, int firstLayer, int firstLevel)
{ {
throw new NotImplementedException(); if (destination is Texture destinationTexture)
{
_pipeline.BlitCommandEncoder.CopyFromTexture(
MTLTexture,
(ulong)firstLayer,
(ulong)firstLevel,
destinationTexture.MTLTexture,
(ulong)firstLayer,
(ulong)firstLevel,
MTLTexture.ArrayLength,
MTLTexture.MipmapLevelCount);
}
} }
public void CopyTo(ITexture destination, int srcLayer, int dstLayer, int srcLevel, int dstLevel) public void CopyTo(ITexture destination, int srcLayer, int dstLayer, int srcLevel, int dstLevel)
{ {
throw new NotImplementedException(); if (destination is Texture destinationTexture)
{
_pipeline.BlitCommandEncoder.CopyFromTexture(
MTLTexture,
(ulong)srcLayer,
(ulong)srcLevel,
destinationTexture.MTLTexture,
(ulong)dstLayer,
(ulong)dstLevel,
MTLTexture.ArrayLength,
MTLTexture.MipmapLevelCount);
}
} }
public void CopyTo(ITexture destination, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter) public void CopyTo(ITexture destination, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter)

View file

@ -1,23 +1,25 @@
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using System; using System;
using SharpMetal; using System.Runtime.Versioning;
namespace Ryujinx.Graphics.Metal namespace Ryujinx.Graphics.Metal
{ {
[SupportedOSPlatform("macos")]
public class Window : IWindow, IDisposable public class Window : IWindow, IDisposable
{ {
private readonly MetalRenderer _renderer;
public Window() public Window(MetalRenderer renderer)
{ {
/*var viewport = new MTLViewport _renderer = renderer;
{
};*/
} }
public void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback) public void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback)
{ {
throw new NotImplementedException(); if (_renderer.Pipeline is Pipeline pipeline)
{
pipeline.Present();
}
} }
public void SetSize(int width, int height) public void SetSize(int width, int height)
@ -50,4 +52,4 @@ namespace Ryujinx.Graphics.Metal
} }
} }
} }