Depth Clear
This commit is contained in:
parent
8feee9c005
commit
bd3df5f26a
5 changed files with 54 additions and 68 deletions
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue