Depth Clear

This commit is contained in:
Isaac Marovitz 2024-05-22 20:26:54 -04:00 committed by Isaac Marovitz
parent 8feee9c005
commit bd3df5f26a
5 changed files with 54 additions and 68 deletions

View file

@ -61,7 +61,7 @@ namespace Ryujinx.Graphics.Metal
public MTLScissorRect[] Scissors = []; public MTLScissorRect[] Scissors = [];
// Changes to attachments take recreation! // Changes to attachments take recreation!
public MTLTexture DepthStencil = default; public Texture DepthStencil = default;
public Texture[] RenderTargets = new Texture[Constants.MaxColorAttachments]; public Texture[] RenderTargets = new Texture[Constants.MaxColorAttachments];
public Dictionary<int, BlendDescriptor> BlendDescriptors = new(); public Dictionary<int, BlendDescriptor> BlendDescriptors = new();
public ColorF BlendColor = new(); public ColorF BlendColor = new();

View file

@ -26,6 +26,7 @@ namespace Ryujinx.Graphics.Metal
public readonly ulong IndexBufferOffset => _currentState.IndexBufferOffset; public readonly ulong IndexBufferOffset => _currentState.IndexBufferOffset;
public readonly PrimitiveTopology Topology => _currentState.Topology; public readonly PrimitiveTopology Topology => _currentState.Topology;
public readonly Texture[] RenderTargets => _currentState.RenderTargets; public readonly Texture[] RenderTargets => _currentState.RenderTargets;
public readonly Texture DepthStencil => _currentState.DepthStencil;
public EncoderStateManager(MTLDevice device, Pipeline pipeline) public EncoderStateManager(MTLDevice device, Pipeline pipeline)
{ {
@ -62,36 +63,36 @@ namespace Ryujinx.Graphics.Metal
var depthAttachment = renderPassDescriptor.DepthAttachment; var depthAttachment = renderPassDescriptor.DepthAttachment;
var stencilAttachment = renderPassDescriptor.StencilAttachment; var stencilAttachment = renderPassDescriptor.StencilAttachment;
if (_currentState.DepthStencil != IntPtr.Zero) if (_currentState.DepthStencil != null)
{ {
switch (_currentState.DepthStencil.PixelFormat) switch (_currentState.DepthStencil.MTLTexture.PixelFormat)
{ {
// Depth Only Attachment // Depth Only Attachment
case MTLPixelFormat.Depth16Unorm: case MTLPixelFormat.Depth16Unorm:
case MTLPixelFormat.Depth32Float: case MTLPixelFormat.Depth32Float:
depthAttachment.Texture = _currentState.DepthStencil; depthAttachment.Texture = _currentState.DepthStencil.MTLTexture;
depthAttachment.LoadAction = MTLLoadAction.Load; depthAttachment.LoadAction = MTLLoadAction.Load;
break; break;
// Stencil Only Attachment // Stencil Only Attachment
case MTLPixelFormat.Stencil8: case MTLPixelFormat.Stencil8:
stencilAttachment.Texture = _currentState.DepthStencil; stencilAttachment.Texture = _currentState.DepthStencil.MTLTexture;
stencilAttachment.LoadAction = MTLLoadAction.Load; stencilAttachment.LoadAction = MTLLoadAction.Load;
break; break;
// Combined Attachment // Combined Attachment
case MTLPixelFormat.Depth24UnormStencil8: case MTLPixelFormat.Depth24UnormStencil8:
case MTLPixelFormat.Depth32FloatStencil8: case MTLPixelFormat.Depth32FloatStencil8:
depthAttachment.Texture = _currentState.DepthStencil; depthAttachment.Texture = _currentState.DepthStencil.MTLTexture;
depthAttachment.LoadAction = MTLLoadAction.Load; depthAttachment.LoadAction = MTLLoadAction.Load;
var unpackedFormat = FormatTable.PackedStencilToXFormat(_currentState.DepthStencil.PixelFormat); var unpackedFormat = FormatTable.PackedStencilToXFormat(_currentState.DepthStencil.MTLTexture.PixelFormat);
var stencilView = _currentState.DepthStencil.NewTextureView(unpackedFormat); var stencilView = _currentState.DepthStencil.MTLTexture.NewTextureView(unpackedFormat);
stencilAttachment.Texture = stencilView; stencilAttachment.Texture = stencilView;
stencilAttachment.LoadAction = MTLLoadAction.Load; stencilAttachment.LoadAction = MTLLoadAction.Load;
break; break;
default: default:
Logger.Error?.PrintMsg(LogClass.Gpu, $"Unsupported Depth/Stencil Format: {_currentState.DepthStencil.PixelFormat}!"); Logger.Error?.PrintMsg(LogClass.Gpu, $"Unsupported Depth/Stencil Format: {_currentState.DepthStencil.MTLTexture.PixelFormat}!");
break; break;
} }
} }
@ -159,29 +160,29 @@ namespace Ryujinx.Graphics.Metal
} }
} }
if (_currentState.DepthStencil != IntPtr.Zero) if (_currentState.DepthStencil != null)
{ {
switch (_currentState.DepthStencil.PixelFormat) switch (_currentState.DepthStencil.MTLTexture.PixelFormat)
{ {
// Depth Only Attachment // Depth Only Attachment
case MTLPixelFormat.Depth16Unorm: case MTLPixelFormat.Depth16Unorm:
case MTLPixelFormat.Depth32Float: case MTLPixelFormat.Depth32Float:
renderPipelineDescriptor.DepthAttachmentPixelFormat = _currentState.DepthStencil.PixelFormat; renderPipelineDescriptor.DepthAttachmentPixelFormat = _currentState.DepthStencil.MTLTexture.PixelFormat;
break; break;
// Stencil Only Attachment // Stencil Only Attachment
case MTLPixelFormat.Stencil8: case MTLPixelFormat.Stencil8:
renderPipelineDescriptor.StencilAttachmentPixelFormat = _currentState.DepthStencil.PixelFormat; renderPipelineDescriptor.StencilAttachmentPixelFormat = _currentState.DepthStencil.MTLTexture.PixelFormat;
break; break;
// Combined Attachment // Combined Attachment
case MTLPixelFormat.Depth24UnormStencil8: case MTLPixelFormat.Depth24UnormStencil8:
case MTLPixelFormat.Depth32FloatStencil8: case MTLPixelFormat.Depth32FloatStencil8:
renderPipelineDescriptor.DepthAttachmentPixelFormat = _currentState.DepthStencil.PixelFormat; renderPipelineDescriptor.DepthAttachmentPixelFormat = _currentState.DepthStencil.MTLTexture.PixelFormat;
renderPipelineDescriptor.StencilAttachmentPixelFormat = _currentState.DepthStencil.PixelFormat; renderPipelineDescriptor.StencilAttachmentPixelFormat = _currentState.DepthStencil.MTLTexture.PixelFormat;
break; break;
default: default:
Logger.Error?.PrintMsg(LogClass.Gpu, $"Unsupported Depth/Stencil Format: {_currentState.DepthStencil.PixelFormat}!"); Logger.Error?.PrintMsg(LogClass.Gpu, $"Unsupported Depth/Stencil Format: {_currentState.DepthStencil.MTLTexture.PixelFormat}!");
break; break;
} }
} }
@ -262,7 +263,7 @@ namespace Ryujinx.Graphics.Metal
if (depthStencil is Texture depthTexture) if (depthStencil is Texture depthTexture)
{ {
_currentState.DepthStencil = depthTexture.MTLTexture; _currentState.DepthStencil = depthTexture;
} }
// Requires recreating pipeline // Requires recreating pipeline

View file

@ -47,33 +47,12 @@ namespace Ryujinx.Graphics.Metal
new ShaderSource(colorClearSource, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(colorClearSource, ShaderStage.Vertex, TargetLanguage.Msl)
], device); ], device);
// var colorClearFSource = ReadMsl("ColorClearF.metal"); var depthStencilClearSource = ReadMsl("DepthStencilClear.metal");
// _programColorClearF = new Program( _programDepthStencilClear = new Program(
// [ [
// new ShaderSource(colorClearFSource, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(depthStencilClearSource, ShaderStage.Fragment, TargetLanguage.Msl),
// new ShaderSource(colorClearFSource, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(depthStencilClearSource, ShaderStage.Vertex, TargetLanguage.Msl)
// ], device); ], device);
//
// var colorClearSiSource = ReadMsl("ColorClearSI.metal");
// _programColorClearSI = new Program(
// [
// new ShaderSource(colorClearSiSource, ShaderStage.Fragment, TargetLanguage.Msl),
// new ShaderSource(colorClearSiSource, ShaderStage.Vertex, TargetLanguage.Msl)
// ], device);
//
// var colorClearUiSource = ReadMsl("ColorClearUI.metal");
// _programColorClearUI = new Program(
// [
// new ShaderSource(colorClearUiSource, ShaderStage.Fragment, TargetLanguage.Msl),
// new ShaderSource(colorClearUiSource, ShaderStage.Vertex, TargetLanguage.Msl)
// ], device);
//
// var depthStencilClearSource = ReadMsl("DepthStencilClear.metal");
// _programDepthStencilClear = new Program(
// [
// new ShaderSource(depthStencilClearSource, ShaderStage.Fragment, TargetLanguage.Msl),
// new ShaderSource(depthStencilClearSource, ShaderStage.Vertex, TargetLanguage.Msl)
// ], device);
} }
private static string ReadMsl(string fileName) private static string ReadMsl(string fileName)
@ -129,34 +108,35 @@ namespace Ryujinx.Graphics.Metal
_pipeline.Finish(); _pipeline.Finish();
} }
public void ClearDepthStencil( public unsafe void ClearDepthStencil(
Texture dst, Texture dst,
float depthValue, ReadOnlySpan<float> depthValue,
bool depthMask, bool depthMask,
int stencilValue, int stencilValue,
int stencilMask, int stencilMask)
int dstWidth,
int dstHeight,
Rectangle<int> scissor)
{ {
Span<Viewport> viewports = stackalloc Viewport[1]; const int ClearColorBufferSize = 16;
viewports[0] = new Viewport( var buffer = _device.NewBuffer(ClearColorBufferSize, MTLResourceOptions.ResourceStorageModeManaged);
new Rectangle<float>(0, 0, dstWidth, dstHeight), var span = new Span<float>(buffer.Contents.ToPointer(), ClearColorBufferSize);
ViewportSwizzle.PositiveX, depthValue.CopyTo(span);
ViewportSwizzle.PositiveY,
ViewportSwizzle.PositiveZ, buffer.DidModifyRange(new NSRange
ViewportSwizzle.PositiveW, {
0f, location = 0,
1f); length = ClearColorBufferSize
});
var handle = buffer.NativePtr;
var range = new BufferRange(Unsafe.As<IntPtr, BufferHandle>(ref handle), 0, ClearColorBufferSize);
_pipeline.SetUniformBuffers([new BufferAssignment(0, range)]);
_pipeline.SetProgram(_programDepthStencilClear); _pipeline.SetProgram(_programDepthStencilClear);
// _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight); _pipeline.SetRenderTargets([], dst);
_pipeline.SetViewports(viewports);
_pipeline.SetScissors([scissor]);
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
_pipeline.SetDepthTest(new DepthTestDescriptor(true, depthMask, CompareOp.Always)); _pipeline.SetDepthTest(new DepthTestDescriptor(true, depthMask, CompareOp.Always));
_pipeline.SetStencilTest(CreateStencilTestDescriptor(stencilMask != 0, stencilValue, 0xFF, stencilMask)); // _pipeline.SetStencilTest(CreateStencilTestDescriptor(stencilMask != 0, stencilValue, 0xFF, stencilMask));
_pipeline.Draw(4, 1, 0, 0); _pipeline.Draw(4, 1, 0, 0);
_pipeline.Finish(); _pipeline.Finish();
} }

View file

@ -215,7 +215,11 @@ namespace Ryujinx.Graphics.Metal
public void ClearRenderTargetDepthStencil(int layer, int layerCount, float depthValue, bool depthMask, int stencilValue, int stencilMask) public void ClearRenderTargetDepthStencil(int layer, int layerCount, float depthValue, bool depthMask, int stencilValue, int stencilMask)
{ {
Logger.Warning?.Print(LogClass.Gpu, "Not Implemented!"); Texture target = _encoderStateManager.DepthStencil;
_encoderStateManager.SwapStates();
_helperShader.ClearDepthStencil(target, [depthValue], depthMask, stencilValue, stencilMask);
} }
public void CommandBufferBarrier() public void CommandBufferBarrier()

View file

@ -7,8 +7,8 @@ struct VertexOut {
}; };
struct FragmentOut { struct FragmentOut {
float4 color [[color(0)]];
float depth [[depth(any)]]; float depth [[depth(any)]];
uint stencil [[stencil]];
}; };
vertex VertexOut vertexMain(ushort vid [[vertex_id]]) vertex VertexOut vertexMain(ushort vid [[vertex_id]])
@ -26,12 +26,13 @@ vertex VertexOut vertexMain(ushort vid [[vertex_id]])
return out; return out;
} }
fragment float4 fragmentMain(VertexOut in [[stage_in]], fragment FragmentOut fragmentMain(VertexOut in [[stage_in]],
constant float clear_color [[buffer(0)]]) constant float& clear_color [[buffer(0)]])
{ {
Fragment out; FragmentOut out;
out.depth = clear_color; out.depth = clear_color;
// out.stencil = stencil_clear;
return out; return out;
} }