don't interrupt render pass before color clear

This commit is contained in:
Samuliak 2024-05-24 15:28:16 +02:00 committed by Isaac Marovitz
parent b475a44941
commit 3ec45f73f4
3 changed files with 26 additions and 15 deletions

View file

@ -5,6 +5,7 @@ using Ryujinx.Graphics.Shader.Translation;
using SharpMetal.Foundation; using SharpMetal.Foundation;
using SharpMetal.Metal; using SharpMetal.Metal;
using System; using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.Versioning; using System.Runtime.Versioning;
@ -18,7 +19,7 @@ namespace Ryujinx.Graphics.Metal
private MTLDevice _device; private MTLDevice _device;
private readonly IProgram _programColorBlit; private readonly IProgram _programColorBlit;
private readonly IProgram _programColorClear; private readonly List<IProgram> _programsColorClear = new();
private readonly IProgram _programDepthStencilClear; private readonly IProgram _programDepthStencilClear;
public HelperShader(MTLDevice device, Pipeline pipeline) public HelperShader(MTLDevice device, Pipeline pipeline)
@ -34,11 +35,15 @@ namespace Ryujinx.Graphics.Metal
], device); ], device);
var colorClearSource = ReadMsl("ColorClear.metal"); var colorClearSource = ReadMsl("ColorClear.metal");
_programColorClear = new Program( for (int i = 0; i < Constants.MaxColorAttachments; i++)
[ {
new ShaderSource(colorClearSource, ShaderStage.Fragment, TargetLanguage.Msl), var crntSource = colorClearSource.Replace("COLOR_ATTACHMENT_INDEX", i.ToString());
new ShaderSource(colorClearSource, ShaderStage.Vertex, TargetLanguage.Msl) _programsColorClear.Add(new Program(
], device); [
new ShaderSource(crntSource, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(crntSource, ShaderStage.Vertex, TargetLanguage.Msl)
], device));
}
var depthStencilClearSource = ReadMsl("DepthStencilClear.metal"); var depthStencilClearSource = ReadMsl("DepthStencilClear.metal");
_programDepthStencilClear = new Program( _programDepthStencilClear = new Program(
@ -79,6 +84,7 @@ namespace Ryujinx.Graphics.Metal
public unsafe void ClearColor( public unsafe void ClearColor(
Texture dst, Texture dst,
int index,
ReadOnlySpan<float> clearColor) ReadOnlySpan<float> clearColor)
{ {
const int ClearColorBufferSize = 16; const int ClearColorBufferSize = 16;
@ -101,7 +107,7 @@ namespace Ryujinx.Graphics.Metal
_pipeline.SetUniformBuffers([new BufferAssignment(0, range)]); _pipeline.SetUniformBuffers([new BufferAssignment(0, range)]);
_pipeline.SetProgram(_programColorClear); _pipeline.SetProgram(_programsColorClear[index]);
_pipeline.SetRenderTargets([dst], null); _pipeline.SetRenderTargets([dst], null);
// _pipeline.SetRenderTargetColorMasks([componentMask]); // _pipeline.SetRenderTargetColorMasks([componentMask]);
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
@ -175,7 +181,10 @@ namespace Ryujinx.Graphics.Metal
public void Dispose() public void Dispose()
{ {
_programColorBlit.Dispose(); _programColorBlit.Dispose();
_programColorClear.Dispose(); foreach (var programColorClear in _programsColorClear)
{
programColorClear.Dispose();
}
_programDepthStencilClear.Dispose(); _programDepthStencilClear.Dispose();
_pipeline.Dispose(); _pipeline.Dispose();
} }

View file

@ -216,7 +216,7 @@ namespace Ryujinx.Graphics.Metal
Texture target = _encoderStateManager.RenderTargets[index]; Texture target = _encoderStateManager.RenderTargets[index];
_helperShader.ClearColor(target, colors); _helperShader.ClearColor(target, index, colors);
} }
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)

View file

@ -6,8 +6,7 @@ struct VertexOut {
float4 position [[position]]; float4 position [[position]];
}; };
vertex VertexOut vertexMain(ushort vid [[vertex_id]]) vertex VertexOut vertexMain(ushort vid [[vertex_id]]) {
{
int low = vid & 1; int low = vid & 1;
int high = vid >> 1; int high = vid >> 1;
@ -21,8 +20,11 @@ vertex VertexOut vertexMain(ushort vid [[vertex_id]])
return out; return out;
} }
fragment float4 fragmentMain(VertexOut in [[stage_in]], struct FragmentOut {
constant float4& clear_color [[buffer(0)]]) float4 color [[color(COLOR_ATTACHMENT_INDEX)]];
{ };
return clear_color;
fragment FragmentOut fragmentMain(VertexOut in [[stage_in]],
constant float4& clear_color [[buffer(0)]]) {
return {clear_color};
} }