Helper Shader fixes for non float formats
This commit is contained in:
parent
4cd15cb1a6
commit
245778bc7e
5 changed files with 166 additions and 31 deletions
|
@ -21,9 +21,15 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
private readonly ISampler _samplerLinear;
|
private readonly ISampler _samplerLinear;
|
||||||
private readonly ISampler _samplerNearest;
|
private readonly ISampler _samplerNearest;
|
||||||
private readonly IProgram _programColorBlit;
|
private readonly IProgram _programColorBlitF;
|
||||||
private readonly IProgram _programColorBlitMs;
|
private readonly IProgram _programColorBlitI;
|
||||||
private readonly List<IProgram> _programsColorClear = new();
|
private readonly IProgram _programColorBlitU;
|
||||||
|
private readonly IProgram _programColorBlitMsF;
|
||||||
|
private readonly IProgram _programColorBlitMsI;
|
||||||
|
private readonly IProgram _programColorBlitMsU;
|
||||||
|
private readonly List<IProgram> _programsColorClearF = new();
|
||||||
|
private readonly List<IProgram> _programsColorClearI = new();
|
||||||
|
private readonly List<IProgram> _programsColorClearU = new();
|
||||||
private readonly IProgram _programDepthStencilClear;
|
private readonly IProgram _programDepthStencilClear;
|
||||||
private readonly IProgram _programStrideChange;
|
private readonly IProgram _programStrideChange;
|
||||||
private readonly IProgram _programDepthBlit;
|
private readonly IProgram _programDepthBlit;
|
||||||
|
@ -47,27 +53,80 @@ namespace Ryujinx.Graphics.Metal
|
||||||
.Add(ResourceStages.Fragment, ResourceType.TextureAndSampler, 0).Build();
|
.Add(ResourceStages.Fragment, ResourceType.TextureAndSampler, 0).Build();
|
||||||
|
|
||||||
var blitSource = ReadMsl("Blit.metal");
|
var blitSource = ReadMsl("Blit.metal");
|
||||||
_programColorBlit = new Program(
|
|
||||||
|
var blitSourceF = blitSource.Replace("FORMAT", "float", StringComparison.Ordinal);
|
||||||
|
_programColorBlitF = new Program(
|
||||||
[
|
[
|
||||||
new ShaderSource(blitSource, ShaderStage.Fragment, TargetLanguage.Msl),
|
new ShaderSource(blitSourceF, ShaderStage.Fragment, TargetLanguage.Msl),
|
||||||
new ShaderSource(blitSource, ShaderStage.Vertex, TargetLanguage.Msl)
|
new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl)
|
||||||
|
], blitResourceLayout, device);
|
||||||
|
|
||||||
|
var blitSourceI = blitSource.Replace("FORMAT", "int");
|
||||||
|
_programColorBlitI = new Program(
|
||||||
|
[
|
||||||
|
new ShaderSource(blitSourceI, ShaderStage.Fragment, TargetLanguage.Msl),
|
||||||
|
new ShaderSource(blitSourceI, ShaderStage.Vertex, TargetLanguage.Msl)
|
||||||
|
], blitResourceLayout, device);
|
||||||
|
|
||||||
|
var blitSourceU = blitSource.Replace("FORMAT", "uint");
|
||||||
|
_programColorBlitU = new Program(
|
||||||
|
[
|
||||||
|
new ShaderSource(blitSourceU, ShaderStage.Fragment, TargetLanguage.Msl),
|
||||||
|
new ShaderSource(blitSourceU, ShaderStage.Vertex, TargetLanguage.Msl)
|
||||||
], blitResourceLayout, device);
|
], blitResourceLayout, device);
|
||||||
|
|
||||||
var blitMsSource = ReadMsl("BlitMs.metal");
|
var blitMsSource = ReadMsl("BlitMs.metal");
|
||||||
_programColorBlitMs = new Program(
|
|
||||||
|
var blitMsSourceF = blitMsSource.Replace("FORMAT", "float");
|
||||||
|
_programColorBlitMsF = new Program(
|
||||||
[
|
[
|
||||||
new ShaderSource(blitMsSource, ShaderStage.Fragment, TargetLanguage.Msl),
|
new ShaderSource(blitMsSourceF, ShaderStage.Fragment, TargetLanguage.Msl),
|
||||||
new ShaderSource(blitSource, ShaderStage.Vertex, TargetLanguage.Msl)
|
new ShaderSource(blitMsSourceF, ShaderStage.Vertex, TargetLanguage.Msl)
|
||||||
|
], blitResourceLayout, device);
|
||||||
|
|
||||||
|
var blitMsSourceI = blitMsSource.Replace("FORMAT", "int");
|
||||||
|
_programColorBlitMsI = new Program(
|
||||||
|
[
|
||||||
|
new ShaderSource(blitMsSourceI, ShaderStage.Fragment, TargetLanguage.Msl),
|
||||||
|
new ShaderSource(blitMsSourceI, ShaderStage.Vertex, TargetLanguage.Msl)
|
||||||
|
], blitResourceLayout, device);
|
||||||
|
|
||||||
|
var blitMsSourceU = blitMsSource.Replace("FORMAT", "uint");
|
||||||
|
_programColorBlitMsU = new Program(
|
||||||
|
[
|
||||||
|
new ShaderSource(blitMsSourceU, ShaderStage.Fragment, TargetLanguage.Msl),
|
||||||
|
new ShaderSource(blitMsSourceU, ShaderStage.Vertex, TargetLanguage.Msl)
|
||||||
], blitResourceLayout, device);
|
], blitResourceLayout, device);
|
||||||
|
|
||||||
var colorClearResourceLayout = new ResourceLayoutBuilder()
|
var colorClearResourceLayout = new ResourceLayoutBuilder()
|
||||||
.Add(ResourceStages.Fragment, ResourceType.UniformBuffer, 0).Build();
|
.Add(ResourceStages.Fragment, ResourceType.UniformBuffer, 0).Build();
|
||||||
|
|
||||||
var colorClearSource = ReadMsl("ColorClear.metal");
|
var colorClearSource = ReadMsl("ColorClear.metal");
|
||||||
|
|
||||||
for (int i = 0; i < Constants.MaxColorAttachments; i++)
|
for (int i = 0; i < Constants.MaxColorAttachments; i++)
|
||||||
{
|
{
|
||||||
var crntSource = colorClearSource.Replace("COLOR_ATTACHMENT_INDEX", i.ToString());
|
var crntSource = colorClearSource.Replace("COLOR_ATTACHMENT_INDEX", i.ToString()).Replace("FORMAT", "float");
|
||||||
_programsColorClear.Add(new Program(
|
_programsColorClearF.Add(new Program(
|
||||||
|
[
|
||||||
|
new ShaderSource(crntSource, ShaderStage.Fragment, TargetLanguage.Msl),
|
||||||
|
new ShaderSource(crntSource, ShaderStage.Vertex, TargetLanguage.Msl)
|
||||||
|
], colorClearResourceLayout, device));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < Constants.MaxColorAttachments; i++)
|
||||||
|
{
|
||||||
|
var crntSource = colorClearSource.Replace("COLOR_ATTACHMENT_INDEX", i.ToString()).Replace("FORMAT", "int");
|
||||||
|
_programsColorClearI.Add(new Program(
|
||||||
|
[
|
||||||
|
new ShaderSource(crntSource, ShaderStage.Fragment, TargetLanguage.Msl),
|
||||||
|
new ShaderSource(crntSource, ShaderStage.Vertex, TargetLanguage.Msl)
|
||||||
|
], colorClearResourceLayout, device));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < Constants.MaxColorAttachments; i++)
|
||||||
|
{
|
||||||
|
var crntSource = colorClearSource.Replace("COLOR_ATTACHMENT_INDEX", i.ToString()).Replace("FORMAT", "uint");
|
||||||
|
_programsColorClearU.Add(new Program(
|
||||||
[
|
[
|
||||||
new ShaderSource(crntSource, ShaderStage.Fragment, TargetLanguage.Msl),
|
new ShaderSource(crntSource, ShaderStage.Fragment, TargetLanguage.Msl),
|
||||||
new ShaderSource(crntSource, ShaderStage.Vertex, TargetLanguage.Msl)
|
new ShaderSource(crntSource, ShaderStage.Vertex, TargetLanguage.Msl)
|
||||||
|
@ -96,28 +155,28 @@ namespace Ryujinx.Graphics.Metal
|
||||||
_programDepthBlit = new Program(
|
_programDepthBlit = new Program(
|
||||||
[
|
[
|
||||||
new ShaderSource(depthBlitSource, ShaderStage.Fragment, TargetLanguage.Msl),
|
new ShaderSource(depthBlitSource, ShaderStage.Fragment, TargetLanguage.Msl),
|
||||||
new ShaderSource(blitSource, ShaderStage.Vertex, TargetLanguage.Msl)
|
new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl)
|
||||||
], blitResourceLayout, device);
|
], blitResourceLayout, device);
|
||||||
|
|
||||||
var depthBlitMsSource = ReadMsl("DepthBlitMs.metal");
|
var depthBlitMsSource = ReadMsl("DepthBlitMs.metal");
|
||||||
_programDepthBlitMs = new Program(
|
_programDepthBlitMs = new Program(
|
||||||
[
|
[
|
||||||
new ShaderSource(depthBlitMsSource, ShaderStage.Fragment, TargetLanguage.Msl),
|
new ShaderSource(depthBlitMsSource, ShaderStage.Fragment, TargetLanguage.Msl),
|
||||||
new ShaderSource(blitSource, ShaderStage.Vertex, TargetLanguage.Msl)
|
new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl)
|
||||||
], blitResourceLayout, device);
|
], blitResourceLayout, device);
|
||||||
|
|
||||||
var stencilBlitSource = ReadMsl("StencilBlit.metal");
|
var stencilBlitSource = ReadMsl("StencilBlit.metal");
|
||||||
_programStencilBlit = new Program(
|
_programStencilBlit = new Program(
|
||||||
[
|
[
|
||||||
new ShaderSource(stencilBlitSource, ShaderStage.Fragment, TargetLanguage.Msl),
|
new ShaderSource(stencilBlitSource, ShaderStage.Fragment, TargetLanguage.Msl),
|
||||||
new ShaderSource(blitSource, ShaderStage.Vertex, TargetLanguage.Msl)
|
new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl)
|
||||||
], blitResourceLayout, device);
|
], blitResourceLayout, device);
|
||||||
|
|
||||||
var stencilBlitMsSource = ReadMsl("StencilBlitMs.metal");
|
var stencilBlitMsSource = ReadMsl("StencilBlitMs.metal");
|
||||||
_programStencilBlitMs = new Program(
|
_programStencilBlitMs = new Program(
|
||||||
[
|
[
|
||||||
new ShaderSource(stencilBlitMsSource, ShaderStage.Fragment, TargetLanguage.Msl),
|
new ShaderSource(stencilBlitMsSource, ShaderStage.Fragment, TargetLanguage.Msl),
|
||||||
new ShaderSource(blitSource, ShaderStage.Vertex, TargetLanguage.Msl)
|
new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl)
|
||||||
], blitResourceLayout, device);
|
], blitResourceLayout, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,11 +260,33 @@ namespace Ryujinx.Graphics.Metal
|
||||||
}
|
}
|
||||||
else if (src.Info.Target.IsMultisample())
|
else if (src.Info.Target.IsMultisample())
|
||||||
{
|
{
|
||||||
_pipeline.SetProgram(_programColorBlitMs);
|
if (dst.Info.Format.IsSint())
|
||||||
|
{
|
||||||
|
_pipeline.SetProgram(_programColorBlitMsI);
|
||||||
|
}
|
||||||
|
else if (dst.Info.Format.IsUint())
|
||||||
|
{
|
||||||
|
_pipeline.SetProgram(_programColorBlitMsU);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_pipeline.SetProgram(_programColorBlit);
|
_pipeline.SetProgram(_programColorBlitMsF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (dst.Info.Format.IsSint())
|
||||||
|
{
|
||||||
|
_pipeline.SetProgram(_programColorBlitI);
|
||||||
|
}
|
||||||
|
else if (dst.Info.Format.IsUint())
|
||||||
|
{
|
||||||
|
_pipeline.SetProgram(_programColorBlitU);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_pipeline.SetProgram(_programColorBlitF);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int dstWidth = dst.Width;
|
int dstWidth = dst.Width;
|
||||||
|
@ -438,7 +519,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
0f,
|
0f,
|
||||||
1f);
|
1f);
|
||||||
|
|
||||||
_pipeline.SetProgram(_programColorBlit);
|
_pipeline.SetProgram(_programColorBlitF);
|
||||||
_pipeline.SetViewports(viewports);
|
_pipeline.SetViewports(viewports);
|
||||||
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||||
_pipeline.Draw(4, 1, 0, 0);
|
_pipeline.Draw(4, 1, 0, 0);
|
||||||
|
@ -502,7 +583,8 @@ namespace Ryujinx.Graphics.Metal
|
||||||
ReadOnlySpan<float> clearColor,
|
ReadOnlySpan<float> clearColor,
|
||||||
uint componentMask,
|
uint componentMask,
|
||||||
int dstWidth,
|
int dstWidth,
|
||||||
int dstHeight)
|
int dstHeight,
|
||||||
|
Format format)
|
||||||
{
|
{
|
||||||
// Keep original scissor
|
// Keep original scissor
|
||||||
DirtyFlags clearFlags = DirtyFlags.All & (~DirtyFlags.Scissors);
|
DirtyFlags clearFlags = DirtyFlags.All & (~DirtyFlags.Scissors);
|
||||||
|
@ -536,7 +618,19 @@ namespace Ryujinx.Graphics.Metal
|
||||||
Span<uint> componentMasks = stackalloc uint[index + 1];
|
Span<uint> componentMasks = stackalloc uint[index + 1];
|
||||||
componentMasks[index] = componentMask;
|
componentMasks[index] = componentMask;
|
||||||
|
|
||||||
_pipeline.SetProgram(_programsColorClear[index]);
|
if (format.IsSint())
|
||||||
|
{
|
||||||
|
_pipeline.SetProgram(_programsColorClearI[index]);
|
||||||
|
}
|
||||||
|
else if (format.IsUint())
|
||||||
|
{
|
||||||
|
_pipeline.SetProgram(_programsColorClearU[index]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_pipeline.SetProgram(_programsColorClearF[index]);
|
||||||
|
}
|
||||||
|
|
||||||
_pipeline.SetBlendState(index, new BlendDescriptor());
|
_pipeline.SetBlendState(index, new BlendDescriptor());
|
||||||
_pipeline.SetFaceCulling(false, Face.Front);
|
_pipeline.SetFaceCulling(false, Face.Front);
|
||||||
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, CompareOp.Always));
|
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, CompareOp.Always));
|
||||||
|
@ -630,11 +724,28 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_programColorBlit.Dispose();
|
_programColorBlitF.Dispose();
|
||||||
foreach (var programColorClear in _programsColorClear)
|
_programColorBlitI.Dispose();
|
||||||
|
_programColorBlitU.Dispose();
|
||||||
|
_programColorBlitMsF.Dispose();
|
||||||
|
_programColorBlitMsI.Dispose();
|
||||||
|
_programColorBlitMsU.Dispose();
|
||||||
|
|
||||||
|
foreach (var programColorClear in _programsColorClearF)
|
||||||
{
|
{
|
||||||
programColorClear.Dispose();
|
programColorClear.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var programColorClear in _programsColorClearU)
|
||||||
|
{
|
||||||
|
programColorClear.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var programColorClear in _programsColorClearI)
|
||||||
|
{
|
||||||
|
programColorClear.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
_programDepthStencilClear.Dispose();
|
_programDepthStencilClear.Dispose();
|
||||||
_pipeline.Dispose();
|
_pipeline.Dispose();
|
||||||
_samplerLinear.Dispose();
|
_samplerLinear.Dispose();
|
||||||
|
|
|
@ -269,7 +269,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderer.HelperShader.ClearColor(index, colors, componentMask, dst.Width, dst.Height);
|
_renderer.HelperShader.ClearColor(index, colors, componentMask, dst.Width, dst.Height, dst.Info.Format);
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|
|
@ -17,7 +17,7 @@ struct ConstantBuffers {
|
||||||
|
|
||||||
struct Textures
|
struct Textures
|
||||||
{
|
{
|
||||||
texture2d<float, access::sample> texture;
|
texture2d<FORMAT, access::sample> texture;
|
||||||
sampler sampler;
|
sampler sampler;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ vertex CopyVertexOut vertexMain(uint vid [[vertex_id]],
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
fragment float4 fragmentMain(CopyVertexOut in [[stage_in]],
|
fragment FORMAT4 fragmentMain(CopyVertexOut in [[stage_in]],
|
||||||
constant Textures &textures [[buffer(TEXTURES_INDEX)]]) {
|
constant Textures &textures [[buffer(TEXTURES_INDEX)]]) {
|
||||||
return textures.texture.sample(textures.sampler, in.uv);
|
return textures.texture.sample(textures.sampler, in.uv);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,36 @@ struct CopyVertexOut {
|
||||||
float2 uv;
|
float2 uv;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Textures
|
struct TexCoords {
|
||||||
{
|
float data[4];
|
||||||
texture2d_ms<float, access::read> texture;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
fragment float4 fragmentMain(CopyVertexOut in [[stage_in]],
|
struct ConstantBuffers {
|
||||||
|
constant TexCoords* tex_coord;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Textures
|
||||||
|
{
|
||||||
|
texture2d_ms<FORMAT, access::read> texture;
|
||||||
|
};
|
||||||
|
|
||||||
|
vertex CopyVertexOut vertexMain(uint vid [[vertex_id]],
|
||||||
|
constant ConstantBuffers &constant_buffers [[buffer(CONSTANT_BUFFERS_INDEX)]]) {
|
||||||
|
CopyVertexOut out;
|
||||||
|
|
||||||
|
int low = vid & 1;
|
||||||
|
int high = vid >> 1;
|
||||||
|
out.uv.x = constant_buffers.tex_coord->data[low];
|
||||||
|
out.uv.y = constant_buffers.tex_coord->data[2 + high];
|
||||||
|
out.position.x = (float(low) - 0.5f) * 2.0f;
|
||||||
|
out.position.y = (float(high) - 0.5f) * 2.0f;
|
||||||
|
out.position.z = 0.0f;
|
||||||
|
out.position.w = 1.0f;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment FORMAT4 fragmentMain(CopyVertexOut in [[stage_in]],
|
||||||
constant Textures &textures [[buffer(TEXTURES_INDEX)]],
|
constant Textures &textures [[buffer(TEXTURES_INDEX)]],
|
||||||
uint sample_id [[sample_id]]) {
|
uint sample_id [[sample_id]]) {
|
||||||
uint2 tex_size = uint2(textures.texture.get_width(), textures.texture.get_height());
|
uint2 tex_size = uint2(textures.texture.get_width(), textures.texture.get_height());
|
||||||
|
|
|
@ -7,7 +7,7 @@ struct VertexOut {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ClearColor {
|
struct ClearColor {
|
||||||
float4 data;
|
FORMAT4 data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ConstantBuffers {
|
struct ConstantBuffers {
|
||||||
|
@ -29,7 +29,7 @@ vertex VertexOut vertexMain(ushort vid [[vertex_id]]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FragmentOut {
|
struct FragmentOut {
|
||||||
float4 color [[color(COLOR_ATTACHMENT_INDEX)]];
|
FORMAT4 color [[color(COLOR_ATTACHMENT_INDEX)]];
|
||||||
};
|
};
|
||||||
|
|
||||||
fragment FragmentOut fragmentMain(VertexOut in [[stage_in]],
|
fragment FragmentOut fragmentMain(VertexOut in [[stage_in]],
|
||||||
|
|
Loading…
Reference in a new issue