Clone the state & flip viewport vertically (#16)

* implement texture get data

* reset all state before blit & clone state

* format

* support blit regions

* implement source region for blit

* replace bottom with top

* account for 0 size

* support image flipping

* revert presentation fixes & y flip

* revert

* flip viewport vertically

* switch face winding

* comment

* use SetBytes for texture clear

* implement missing compute builtins

* change storage and texture buffer alignment

* correct compute builtins

* don't use nullable for textures and samplers

* remove incorrect texture get data implementation

* Cleanup IntPtrs

---------

Co-authored-by: Isaac Marovitz <isaacryu@icloud.com>
This commit is contained in:
SamoZ256 2024-05-27 13:58:03 +02:00 committed by Isaac Marovitz
parent 20b1f6a6ee
commit 1f91c74a95
8 changed files with 91 additions and 69 deletions

View file

@ -2,11 +2,9 @@ using Ryujinx.Common;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Shader;
using Ryujinx.Graphics.Shader.Translation;
using SharpMetal.Foundation;
using SharpMetal.Metal;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
namespace Ryujinx.Graphics.Metal
@ -70,11 +68,9 @@ namespace Ryujinx.Graphics.Metal
});
// Save current state
_pipeline.SaveState();
_pipeline.SaveAndResetState();
_pipeline.SetProgram(_programColorBlit);
_pipeline.SetFaceCulling(false, Face.Front);
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, CompareOp.Always));
// Viewport and scissor needs to be set before render pass begin so as not to bind the old ones
_pipeline.SetViewports([]);
_pipeline.SetScissors([]);
@ -93,29 +89,21 @@ namespace Ryujinx.Graphics.Metal
{
const int ClearColorBufferSize = 16;
var buffer = _device.NewBuffer(ClearColorBufferSize, MTLResourceOptions.ResourceStorageModeManaged);
var span = new Span<float>(buffer.Contents.ToPointer(), ClearColorBufferSize);
clearColor.CopyTo(span);
buffer.DidModifyRange(new NSRange
{
location = 0,
length = ClearColorBufferSize
});
var handle = buffer.NativePtr;
var range = new BufferRange(Unsafe.As<IntPtr, BufferHandle>(ref handle), 0, ClearColorBufferSize);
// Save current state
_pipeline.SaveState();
_pipeline.SetUniformBuffers([new BufferAssignment(0, range)]);
_pipeline.SetProgram(_programsColorClear[index]);
_pipeline.SetBlendState(index, new BlendDescriptor(false, new ColorF(0f, 0f, 0f, 1f), BlendOp.Add, BlendFactor.One, BlendFactor.Zero, BlendOp.Add, BlendFactor.One, BlendFactor.Zero));
_pipeline.SetFaceCulling(false, Face.Front);
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, CompareOp.Always));
// _pipeline.SetRenderTargetColorMasks([componentMask]);
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
fixed (float* ptr = clearColor)
{
_pipeline.GetOrCreateRenderEncoder().SetFragmentBytes((IntPtr)ptr, ClearColorBufferSize, 0);
}
_pipeline.Draw(4, 1, 0, 0);
// Restore previous state
@ -123,37 +111,25 @@ namespace Ryujinx.Graphics.Metal
}
public unsafe void ClearDepthStencil(
ReadOnlySpan<float> depthValue,
float depthValue,
bool depthMask,
int stencilValue,
int stencilMask)
{
const int ClearColorBufferSize = 16;
const int ClearDepthBufferSize = 4;
var buffer = _device.NewBuffer(ClearColorBufferSize, MTLResourceOptions.ResourceStorageModeManaged);
var span = new Span<float>(buffer.Contents.ToPointer(), ClearColorBufferSize);
depthValue.CopyTo(span);
buffer.DidModifyRange(new NSRange
{
location = 0,
length = ClearColorBufferSize
});
var handle = buffer.NativePtr;
var range = new BufferRange(Unsafe.As<IntPtr, BufferHandle>(ref handle), 0, ClearColorBufferSize);
IntPtr ptr = new(&depthValue);
// Save current state
_pipeline.SaveState();
_pipeline.SetUniformBuffers([new BufferAssignment(0, range)]);
_pipeline.SetProgram(_programDepthStencilClear);
_pipeline.SetFaceCulling(false, Face.Front);
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, CompareOp.Always));
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
_pipeline.SetDepthTest(new DepthTestDescriptor(true, depthMask, CompareOp.Always));
// _pipeline.SetStencilTest(CreateStencilTestDescriptor(stencilMask != 0, stencilValue, 0xFF, stencilMask));
_pipeline.GetOrCreateRenderEncoder().SetFragmentBytes(ptr, ClearDepthBufferSize, 0);
_pipeline.Draw(4, 1, 0, 0);
// Restore previous state