Seizure my beloved is working
This commit is contained in:
parent
6d722d83ba
commit
aaa140e510
5 changed files with 109 additions and 39 deletions
|
@ -4,6 +4,7 @@ using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
using SharpMetal.Foundation;
|
using SharpMetal.Foundation;
|
||||||
using SharpMetal.Metal;
|
using SharpMetal.Metal;
|
||||||
|
using SharpMetal.QuartzCore;
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
@ -14,25 +15,43 @@ namespace Ryujinx.Graphics.Metal
|
||||||
public sealed class MetalRenderer : IRenderer
|
public sealed class MetalRenderer : IRenderer
|
||||||
{
|
{
|
||||||
private readonly MTLDevice _device;
|
private readonly MTLDevice _device;
|
||||||
private readonly Window _window;
|
|
||||||
private readonly Pipeline _pipeline;
|
|
||||||
private readonly MTLCommandQueue _queue;
|
private readonly MTLCommandQueue _queue;
|
||||||
|
private readonly Func<CAMetalLayer> _getMetalLayer;
|
||||||
|
|
||||||
|
private Pipeline _pipeline;
|
||||||
|
private Window _window;
|
||||||
|
|
||||||
public event EventHandler<ScreenCaptureImageInfo> ScreenCaptured;
|
public event EventHandler<ScreenCaptureImageInfo> ScreenCaptured;
|
||||||
public bool PreferThreading => true;
|
public bool PreferThreading => true;
|
||||||
public IPipeline Pipeline => _pipeline;
|
public IPipeline Pipeline => _pipeline;
|
||||||
public IWindow Window => _window;
|
public IWindow Window => _window;
|
||||||
|
|
||||||
public MetalRenderer()
|
public MetalRenderer(Func<CAMetalLayer> metalLayer)
|
||||||
{
|
{
|
||||||
_device = MTLDevice.CreateSystemDefaultDevice();
|
_device = MTLDevice.CreateSystemDefaultDevice();
|
||||||
_queue = _device.NewCommandQueue();
|
_queue = _device.NewCommandQueue();
|
||||||
_pipeline = new Pipeline(_device, _queue);
|
_getMetalLayer = metalLayer;
|
||||||
_window = new Window(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize(GraphicsDebugLevel logLevel)
|
public void Initialize(GraphicsDebugLevel logLevel)
|
||||||
{
|
{
|
||||||
|
var layer = _getMetalLayer();
|
||||||
|
layer.Device = _device;
|
||||||
|
|
||||||
|
var captureDescriptor = new MTLCaptureDescriptor();
|
||||||
|
captureDescriptor.CaptureObject = _queue;
|
||||||
|
captureDescriptor.Destination = MTLCaptureDestination.GPUTraceDocument;
|
||||||
|
captureDescriptor.OutputURL = NSURL.FileURLWithPath(StringHelper.NSString("/Users/isaacmarovitz/Desktop/Trace.gputrace"));
|
||||||
|
var captureError = new NSError(IntPtr.Zero);
|
||||||
|
MTLCaptureManager.SharedCaptureManager().StartCapture(captureDescriptor, ref captureError);
|
||||||
|
if (captureError != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
Console.Write($"Failed to start capture! {StringHelper.String(captureError.LocalizedDescription)}");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_window = new Window(this, layer);
|
||||||
|
_pipeline = new Pipeline(_device, _queue, layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BackgroundContextAction(Action action, bool alwaysBackground = false)
|
public void BackgroundContextAction(Action action, bool alwaysBackground = false)
|
||||||
|
@ -96,7 +115,10 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public ITexture CreateTexture(TextureCreateInfo info)
|
public ITexture CreateTexture(TextureCreateInfo info)
|
||||||
{
|
{
|
||||||
return new Texture(_device, _pipeline, info);
|
var texture = new Texture(_device, _pipeline, info);
|
||||||
|
Logger.Warning?.Print(LogClass.Gpu, "Texture created!");
|
||||||
|
|
||||||
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool PrepareHostMapping(IntPtr address, ulong size)
|
public bool PrepareHostMapping(IntPtr address, ulong size)
|
||||||
|
|
|
@ -4,6 +4,7 @@ using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
using SharpMetal.Foundation;
|
using SharpMetal.Foundation;
|
||||||
using SharpMetal.Metal;
|
using SharpMetal.Metal;
|
||||||
|
using SharpMetal.QuartzCore;
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
@ -28,8 +29,10 @@ namespace Ryujinx.Graphics.Metal
|
||||||
private MTLBuffer _indexBuffer;
|
private MTLBuffer _indexBuffer;
|
||||||
private MTLIndexType _indexType;
|
private MTLIndexType _indexType;
|
||||||
private ulong _indexBufferOffset;
|
private ulong _indexBufferOffset;
|
||||||
|
private MTLClearColor _clearColor = new() { alpha = 1.0f };
|
||||||
|
private int frameCount = 0;
|
||||||
|
|
||||||
public Pipeline(MTLDevice device, MTLCommandQueue commandQueue)
|
public Pipeline(MTLDevice device, MTLCommandQueue commandQueue, CAMetalLayer metalLayer)
|
||||||
{
|
{
|
||||||
_device = device;
|
_device = device;
|
||||||
_mtlCommandQueue = commandQueue;
|
_mtlCommandQueue = commandQueue;
|
||||||
|
@ -49,13 +52,17 @@ namespace Ryujinx.Graphics.Metal
|
||||||
// TODO: Recreate descriptor and encoder state as needed
|
// TODO: Recreate descriptor and encoder state as needed
|
||||||
var renderPipelineDescriptor = new MTLRenderPipelineDescriptor();
|
var renderPipelineDescriptor = new MTLRenderPipelineDescriptor();
|
||||||
renderPipelineDescriptor.VertexFunction = vertexFunction;
|
renderPipelineDescriptor.VertexFunction = vertexFunction;
|
||||||
renderPipelineDescriptor.FragmentFunction = fragmentFunction;
|
// renderPipelineDescriptor.FragmentFunction = fragmentFunction;
|
||||||
|
// TODO: This should not be hardcoded, but a bug in SharpMetal prevents me from doing this correctly
|
||||||
|
renderPipelineDescriptor.ColorAttachments.Object(0).PixelFormat = MTLPixelFormat.BGRA8Unorm;
|
||||||
|
|
||||||
_renderEncoderState = new(_device.NewRenderPipelineState(renderPipelineDescriptor, ref error), _device);
|
var renderPipelineState = _device.NewRenderPipelineState(renderPipelineDescriptor, ref error);
|
||||||
if (error != IntPtr.Zero)
|
if (error != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
Logger.Error?.PrintMsg(LogClass.Gpu, $"Failed to create Render Pipeline State: {StringHelper.String(error.LocalizedDescription)}");
|
Logger.Error?.PrintMsg(LogClass.Gpu, $"Failed to create Render Pipeline State: {StringHelper.String(error.LocalizedDescription)}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_renderEncoderState = new RenderEncoderState(renderPipelineState, _device);
|
||||||
//
|
//
|
||||||
|
|
||||||
_commandBuffer = _mtlCommandQueue.CommandBuffer();
|
_commandBuffer = _mtlCommandQueue.CommandBuffer();
|
||||||
|
@ -68,6 +75,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
_currentEncoder.EndEncoding();
|
_currentEncoder.EndEncoding();
|
||||||
_currentEncoder = null;
|
_currentEncoder = null;
|
||||||
}
|
}
|
||||||
|
Logger.Warning?.Print(LogClass.Gpu, "Current pass ended");
|
||||||
}
|
}
|
||||||
|
|
||||||
public MTLRenderCommandEncoder BeginRenderPass()
|
public MTLRenderCommandEncoder BeginRenderPass()
|
||||||
|
@ -77,6 +85,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
var descriptor = new MTLRenderPassDescriptor();
|
var descriptor = new MTLRenderPassDescriptor();
|
||||||
var renderCommandEncoder = _commandBuffer.RenderCommandEncoder(descriptor);
|
var renderCommandEncoder = _commandBuffer.RenderCommandEncoder(descriptor);
|
||||||
_renderEncoderState.SetEncoderState(renderCommandEncoder);
|
_renderEncoderState.SetEncoderState(renderCommandEncoder);
|
||||||
|
Logger.Warning?.Print(LogClass.Gpu, "Began render pass");
|
||||||
|
|
||||||
_currentEncoder = renderCommandEncoder;
|
_currentEncoder = renderCommandEncoder;
|
||||||
return renderCommandEncoder;
|
return renderCommandEncoder;
|
||||||
|
@ -88,6 +97,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
var descriptor = new MTLBlitPassDescriptor();
|
var descriptor = new MTLBlitPassDescriptor();
|
||||||
var blitCommandEncoder = _commandBuffer.BlitCommandEncoder(descriptor);
|
var blitCommandEncoder = _commandBuffer.BlitCommandEncoder(descriptor);
|
||||||
|
Logger.Warning?.Print(LogClass.Gpu, "Began blit pass");
|
||||||
|
|
||||||
_currentEncoder = blitCommandEncoder;
|
_currentEncoder = blitCommandEncoder;
|
||||||
return blitCommandEncoder;
|
return blitCommandEncoder;
|
||||||
|
@ -99,18 +109,43 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
var descriptor = new MTLComputePassDescriptor();
|
var descriptor = new MTLComputePassDescriptor();
|
||||||
var computeCommandEncoder = _commandBuffer.ComputeCommandEncoder(descriptor);
|
var computeCommandEncoder = _commandBuffer.ComputeCommandEncoder(descriptor);
|
||||||
|
Logger.Warning?.Print(LogClass.Gpu, "Began compute pass");
|
||||||
|
|
||||||
_currentEncoder = computeCommandEncoder;
|
_currentEncoder = computeCommandEncoder;
|
||||||
return computeCommandEncoder;
|
return computeCommandEncoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Present()
|
public void Present(CAMetalDrawable drawable)
|
||||||
{
|
{
|
||||||
EndCurrentPass();
|
EndCurrentPass();
|
||||||
|
|
||||||
// TODO: Give command buffer a valid MTLDrawable
|
var descriptor = new MTLRenderPassDescriptor();
|
||||||
// _commandBuffer.PresentDrawable();
|
descriptor.ColorAttachments.Object(0).Texture = drawable.Texture;
|
||||||
// _commandBuffer.Commit();
|
descriptor.ColorAttachments.Object(0).LoadAction = MTLLoadAction.Clear;
|
||||||
|
descriptor.ColorAttachments.Object(0).ClearColor = _clearColor;
|
||||||
|
|
||||||
|
var renderCommandEncoder = _commandBuffer.RenderCommandEncoder(descriptor);
|
||||||
|
Logger.Warning?.Print(LogClass.Gpu, "Began present");
|
||||||
|
_renderEncoderState.SetEncoderState(renderCommandEncoder);
|
||||||
|
|
||||||
|
// Barry goes here
|
||||||
|
// renderCommandEncoder.SetFragmentTexture(_renderTarget, 0);
|
||||||
|
|
||||||
|
renderCommandEncoder.DrawPrimitives(MTLPrimitiveType.Triangle, 0, 6);
|
||||||
|
renderCommandEncoder.EndEncoding();
|
||||||
|
|
||||||
|
_commandBuffer.PresentDrawable(drawable);
|
||||||
|
_commandBuffer.Commit();
|
||||||
|
|
||||||
|
Logger.Warning?.Print(LogClass.Gpu, "Presented");
|
||||||
|
|
||||||
|
frameCount++;
|
||||||
|
|
||||||
|
if (frameCount >= 5)
|
||||||
|
{
|
||||||
|
MTLCaptureManager.SharedCaptureManager().StopCapture();
|
||||||
|
Logger.Warning?.Print(LogClass.Gpu, "Trace ended!");
|
||||||
|
}
|
||||||
|
|
||||||
_commandBuffer = _mtlCommandQueue.CommandBuffer();
|
_commandBuffer = _mtlCommandQueue.CommandBuffer();
|
||||||
}
|
}
|
||||||
|
@ -147,7 +182,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public void ClearRenderTargetColor(int index, int layer, int layerCount, uint componentMask, ColorF color)
|
public void ClearRenderTargetColor(int index, int layer, int layerCount, uint componentMask, ColorF color)
|
||||||
{
|
{
|
||||||
Logger.Warning?.Print(LogClass.Gpu, "Not Implemented!");
|
_clearColor = new MTLClearColor { red = color.Red, green = color.Green, blue = color.Blue, alpha = color.Alpha};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearRenderTargetDepthStencil(int layer, int layerCount, float depthValue, bool depthMask, int stencilValue,
|
public void ClearRenderTargetDepthStencil(int layer, int layerCount, float depthValue, bool depthMask, int stencilValue,
|
||||||
|
|
|
@ -17,23 +17,23 @@ namespace Ryujinx.Graphics.Metal
|
||||||
private MTLStencilDescriptor _backFaceStencil = null;
|
private MTLStencilDescriptor _backFaceStencil = null;
|
||||||
private MTLStencilDescriptor _frontFaceStencil = null;
|
private MTLStencilDescriptor _frontFaceStencil = null;
|
||||||
|
|
||||||
public MTLRenderPipelineState RenderPipelineState;
|
public MTLRenderPipelineState CopyPipeline;
|
||||||
public PrimitiveTopology Topology = PrimitiveTopology.Triangles;
|
public PrimitiveTopology Topology = PrimitiveTopology.Triangles;
|
||||||
public MTLCullMode CullMode = MTLCullMode.None;
|
public MTLCullMode CullMode = MTLCullMode.None;
|
||||||
public MTLWinding Winding = MTLWinding.Clockwise;
|
public MTLWinding Winding = MTLWinding.Clockwise;
|
||||||
|
|
||||||
public RenderEncoderState(MTLRenderPipelineState renderPipelineState, MTLDevice device)
|
public RenderEncoderState(MTLRenderPipelineState copyPipeline, MTLDevice device)
|
||||||
{
|
{
|
||||||
_device = device;
|
_device = device;
|
||||||
RenderPipelineState = renderPipelineState;
|
CopyPipeline = copyPipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetEncoderState(MTLRenderCommandEncoder renderCommandEncoder)
|
public void SetEncoderState(MTLRenderCommandEncoder renderCommandEncoder)
|
||||||
{
|
{
|
||||||
renderCommandEncoder.SetRenderPipelineState(RenderPipelineState);
|
renderCommandEncoder.SetRenderPipelineState(CopyPipeline);
|
||||||
renderCommandEncoder.SetCullMode(CullMode);
|
renderCommandEncoder.SetCullMode(CullMode);
|
||||||
renderCommandEncoder.SetFrontFacingWinding(Winding);
|
renderCommandEncoder.SetFrontFacingWinding(Winding);
|
||||||
renderCommandEncoder.SetDepthStencilState(_depthStencilState);
|
// renderCommandEncoder.SetDepthStencilState(_depthStencilState);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MTLDepthStencilState UpdateStencilState(MTLStencilDescriptor backFace, MTLStencilDescriptor frontFace)
|
public MTLDepthStencilState UpdateStencilState(MTLStencilDescriptor backFace, MTLStencilDescriptor frontFace)
|
||||||
|
|
|
@ -2,29 +2,35 @@
|
||||||
|
|
||||||
using namespace metal;
|
using namespace metal;
|
||||||
|
|
||||||
struct TexCoordIn {
|
constant float2 quadVertices[] = {
|
||||||
float4 tex_coord_in_data;
|
float2(-1, -1),
|
||||||
|
float2(-1, 1),
|
||||||
|
float2( 1, 1),
|
||||||
|
float2(-1, -1),
|
||||||
|
float2( 1, 1),
|
||||||
|
float2( 1, -1)
|
||||||
};
|
};
|
||||||
|
|
||||||
vertex float4 vertexMain(uint vertexID [[vertex_id]],
|
struct CopyVertexOut {
|
||||||
constant TexCoordIn& tex_coord_in [[buffer(1)]]) {
|
float4 position [[position]];
|
||||||
int low = vertexID & 1;
|
float2 uv;
|
||||||
int high = vertexID >> 1;
|
};
|
||||||
float2 tex_coord;
|
|
||||||
tex_coord.x = tex_coord_in.tex_coord_in_data[low];
|
|
||||||
tex_coord.y = tex_coord_in.tex_coord_in_data[2 + high];
|
|
||||||
|
|
||||||
float4 position;
|
vertex CopyVertexOut vertexMain(unsigned short vid [[vertex_id]]) {
|
||||||
position.x = (float(low) - 0.5) * 2.0;
|
float2 position = quadVertices[vid];
|
||||||
position.y = (float(high) - 0.5) * 2.0;
|
|
||||||
position.z = 0.0;
|
|
||||||
position.w = 1.0;
|
|
||||||
|
|
||||||
return position;
|
CopyVertexOut out;
|
||||||
|
|
||||||
|
out.position = float4(position, 0, 1);
|
||||||
|
out.uv = position * 0.5f + 0.5f;
|
||||||
|
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
fragment float4 fragmentMain(float2 tex_coord [[stage_in]],
|
fragment float4 fragmentMain(CopyVertexOut in [[stage_in]],
|
||||||
texture2d<float> tex [[texture(0)]]) {
|
texture2d<float> tex) {
|
||||||
float4 color = tex.sample(metal::address::clamp_to_edge, tex_coord);
|
constexpr sampler sam(min_filter::nearest, mag_filter::nearest, mip_filter::none);
|
||||||
return color;
|
|
||||||
|
float3 color = tex.sample(sam, in.uv).xyz;
|
||||||
|
return float4(color, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ using System.Runtime.Versioning;
|
||||||
namespace Ryujinx.Graphics.Metal
|
namespace Ryujinx.Graphics.Metal
|
||||||
{
|
{
|
||||||
[SupportedOSPlatform("macos")]
|
[SupportedOSPlatform("macos")]
|
||||||
class Texture : ITexture, IDisposable
|
public class Texture : ITexture, IDisposable
|
||||||
{
|
{
|
||||||
private readonly TextureCreateInfo _info;
|
private readonly TextureCreateInfo _info;
|
||||||
private readonly Pipeline _pipeline;
|
private readonly Pipeline _pipeline;
|
||||||
|
@ -23,6 +23,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public Texture(MTLDevice device, Pipeline pipeline, TextureCreateInfo info)
|
public Texture(MTLDevice device, Pipeline pipeline, TextureCreateInfo info)
|
||||||
{
|
{
|
||||||
|
Logger.Warning?.Print(LogClass.Gpu, "Texture init");
|
||||||
_device = device;
|
_device = device;
|
||||||
_pipeline = pipeline;
|
_pipeline = pipeline;
|
||||||
_info = info;
|
_info = info;
|
||||||
|
@ -50,6 +51,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public void CopyTo(ITexture destination, int firstLayer, int firstLevel)
|
public void CopyTo(ITexture destination, int firstLayer, int firstLevel)
|
||||||
{
|
{
|
||||||
|
Logger.Warning?.Print(LogClass.Gpu, "Copy to");
|
||||||
MTLBlitCommandEncoder blitCommandEncoder;
|
MTLBlitCommandEncoder blitCommandEncoder;
|
||||||
|
|
||||||
if (_pipeline.CurrentEncoder is MTLBlitCommandEncoder encoder)
|
if (_pipeline.CurrentEncoder is MTLBlitCommandEncoder encoder)
|
||||||
|
@ -77,6 +79,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
Logger.Warning?.Print(LogClass.Gpu, "Copy to");
|
||||||
MTLBlitCommandEncoder blitCommandEncoder;
|
MTLBlitCommandEncoder blitCommandEncoder;
|
||||||
|
|
||||||
if (_pipeline.CurrentEncoder is MTLBlitCommandEncoder encoder)
|
if (_pipeline.CurrentEncoder is MTLBlitCommandEncoder encoder)
|
||||||
|
@ -109,6 +112,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public void CopyTo(BufferRange range, int layer, int level, int stride)
|
public void CopyTo(BufferRange range, int layer, int level, int stride)
|
||||||
{
|
{
|
||||||
|
Logger.Warning?.Print(LogClass.Gpu, "Copy to");
|
||||||
MTLBlitCommandEncoder blitCommandEncoder;
|
MTLBlitCommandEncoder blitCommandEncoder;
|
||||||
|
|
||||||
if (_pipeline.CurrentEncoder is MTLBlitCommandEncoder encoder)
|
if (_pipeline.CurrentEncoder is MTLBlitCommandEncoder encoder)
|
||||||
|
@ -160,6 +164,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
// TODO: Handle array formats
|
// TODO: Handle array formats
|
||||||
public unsafe void SetData(SpanOrArray<byte> data)
|
public unsafe void SetData(SpanOrArray<byte> data)
|
||||||
{
|
{
|
||||||
|
Logger.Warning?.Print(LogClass.Gpu, "Set data");
|
||||||
MTLBlitCommandEncoder blitCommandEncoder;
|
MTLBlitCommandEncoder blitCommandEncoder;
|
||||||
|
|
||||||
if (_pipeline.CurrentEncoder is MTLBlitCommandEncoder encoder)
|
if (_pipeline.CurrentEncoder is MTLBlitCommandEncoder encoder)
|
||||||
|
@ -216,6 +221,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public void SetData(SpanOrArray<byte> data, int layer, int level)
|
public void SetData(SpanOrArray<byte> data, int layer, int level)
|
||||||
{
|
{
|
||||||
|
Logger.Warning?.Print(LogClass.Gpu, "Set data");
|
||||||
MTLBlitCommandEncoder blitCommandEncoder;
|
MTLBlitCommandEncoder blitCommandEncoder;
|
||||||
|
|
||||||
if (_pipeline.CurrentEncoder is MTLBlitCommandEncoder encoder)
|
if (_pipeline.CurrentEncoder is MTLBlitCommandEncoder encoder)
|
||||||
|
@ -257,6 +263,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public void SetData(SpanOrArray<byte> data, int layer, int level, Rectangle<int> region)
|
public void SetData(SpanOrArray<byte> data, int layer, int level, Rectangle<int> region)
|
||||||
{
|
{
|
||||||
|
Logger.Warning?.Print(LogClass.Gpu, "Set data");
|
||||||
MTLBlitCommandEncoder blitCommandEncoder;
|
MTLBlitCommandEncoder blitCommandEncoder;
|
||||||
|
|
||||||
if (_pipeline.CurrentEncoder is MTLBlitCommandEncoder encoder)
|
if (_pipeline.CurrentEncoder is MTLBlitCommandEncoder encoder)
|
||||||
|
|
Loading…
Reference in a new issue