Multisample Blits
Partially fixes Sonic Colors Ultimate
This commit is contained in:
parent
b434cae2c2
commit
aa6e87e8a6
6 changed files with 81 additions and 25 deletions
|
@ -1,4 +1,5 @@
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
|
@ -21,6 +22,7 @@ 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 _programColorBlit;
|
||||||
|
private readonly IProgram _programColorBlitMs;
|
||||||
private readonly List<IProgram> _programsColorClear = new();
|
private readonly List<IProgram> _programsColorClear = new();
|
||||||
private readonly IProgram _programDepthStencilClear;
|
private readonly IProgram _programDepthStencilClear;
|
||||||
private readonly IProgram _programStrideChange;
|
private readonly IProgram _programStrideChange;
|
||||||
|
@ -47,6 +49,13 @@ namespace Ryujinx.Graphics.Metal
|
||||||
new ShaderSource(blitSource, ShaderStage.Vertex, TargetLanguage.Msl)
|
new ShaderSource(blitSource, ShaderStage.Vertex, TargetLanguage.Msl)
|
||||||
], blitResourceLayout, device);
|
], blitResourceLayout, device);
|
||||||
|
|
||||||
|
var blitMsSource = ReadMsl("BlitMs.metal");
|
||||||
|
_programColorBlitMs = new Program(
|
||||||
|
[
|
||||||
|
new ShaderSource(blitMsSource, ShaderStage.Fragment, TargetLanguage.Msl),
|
||||||
|
new ShaderSource(blitMsSource, ShaderStage.Vertex, TargetLanguage.Msl)
|
||||||
|
], blitResourceLayout, device);
|
||||||
|
|
||||||
var colorClearResourceLayout = new ResourceLayoutBuilder()
|
var colorClearResourceLayout = new ResourceLayoutBuilder()
|
||||||
.Add(ResourceStages.Fragment, ResourceType.UniformBuffer, 0).Build();
|
.Add(ResourceStages.Fragment, ResourceType.UniformBuffer, 0).Build();
|
||||||
|
|
||||||
|
@ -87,8 +96,8 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public unsafe void BlitColor(
|
public unsafe void BlitColor(
|
||||||
CommandBufferScoped cbs,
|
CommandBufferScoped cbs,
|
||||||
ITexture src,
|
Texture src,
|
||||||
ITexture dst,
|
Texture dst,
|
||||||
Extents2D srcRegion,
|
Extents2D srcRegion,
|
||||||
Extents2D dstRegion,
|
Extents2D dstRegion,
|
||||||
bool linearFilter,
|
bool linearFilter,
|
||||||
|
@ -140,7 +149,23 @@ namespace Ryujinx.Graphics.Metal
|
||||||
0f,
|
0f,
|
||||||
1f);
|
1f);
|
||||||
|
|
||||||
_pipeline.SetProgram(_programColorBlit);
|
bool dstIsDepthOrStencil = dst.Info.Format.IsDepthOrStencil();
|
||||||
|
|
||||||
|
if (dstIsDepthOrStencil)
|
||||||
|
{
|
||||||
|
// TODO: Depth & stencil blit!
|
||||||
|
Logger.Warning?.PrintMsg(LogClass.Gpu, "Requested a depth or stencil blit!");
|
||||||
|
_pipeline.SwapState(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (src.Info.Target.IsMultisample())
|
||||||
|
{
|
||||||
|
_pipeline.SetProgram(_programColorBlitMs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_pipeline.SetProgram(_programColorBlit);
|
||||||
|
}
|
||||||
|
|
||||||
int dstWidth = dst.Width;
|
int dstWidth = dst.Width;
|
||||||
int dstHeight = dst.Height;
|
int dstHeight = dst.Height;
|
||||||
|
|
|
@ -193,22 +193,13 @@ namespace Ryujinx.Graphics.Metal
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Blit(
|
public void Blit(
|
||||||
ITexture src,
|
Texture src,
|
||||||
ITexture dst,
|
Texture dst,
|
||||||
Extents2D srcRegion,
|
Extents2D srcRegion,
|
||||||
Extents2D dstRegion,
|
Extents2D dstRegion,
|
||||||
bool isDepthOrStencil,
|
|
||||||
bool linearFilter)
|
bool linearFilter)
|
||||||
{
|
{
|
||||||
if (isDepthOrStencil)
|
_renderer.HelperShader.BlitColor(Cbs, src, dst, srcRegion, dstRegion, linearFilter);
|
||||||
{
|
|
||||||
// TODO: Depth & stencil blit!
|
|
||||||
Logger.Warning?.PrintMsg(LogClass.Gpu, "Requested a depth or stencil blit!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_renderer.HelperShader.BlitColor(Cbs, src, dst, srcRegion, dstRegion, linearFilter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Barrier()
|
public void Barrier()
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="Shaders\Blit.metal" />
|
<EmbeddedResource Include="Shaders\Blit.metal" />
|
||||||
|
<EmbeddedResource Include="Shaders\BlitMs.metal" />
|
||||||
<EmbeddedResource Include="Shaders\ChangeBufferStride.metal" />
|
<EmbeddedResource Include="Shaders\ChangeBufferStride.metal" />
|
||||||
<EmbeddedResource Include="Shaders\ColorClear.metal" />
|
<EmbeddedResource Include="Shaders\ColorClear.metal" />
|
||||||
<EmbeddedResource Include="Shaders\DepthStencilClear.metal" />
|
<EmbeddedResource Include="Shaders\DepthStencilClear.metal" />
|
||||||
|
|
|
@ -12,7 +12,7 @@ struct TexCoords {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ConstantBuffers {
|
struct ConstantBuffers {
|
||||||
constant TexCoords* texCoord;
|
constant TexCoords* tex_coord;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Textures
|
struct Textures
|
||||||
|
@ -27,8 +27,8 @@ vertex CopyVertexOut vertexMain(uint vid [[vertex_id]],
|
||||||
|
|
||||||
int low = vid & 1;
|
int low = vid & 1;
|
||||||
int high = vid >> 1;
|
int high = vid >> 1;
|
||||||
out.uv.x = constant_buffers.texCoord->data[low];
|
out.uv.x = constant_buffers.tex_coord->data[low];
|
||||||
out.uv.y = constant_buffers.texCoord->data[2 + high];
|
out.uv.y = constant_buffers.tex_coord->data[2 + high];
|
||||||
out.position.x = (float(low) - 0.5f) * 2.0f;
|
out.position.x = (float(low) - 0.5f) * 2.0f;
|
||||||
out.position.y = (float(high) - 0.5f) * 2.0f;
|
out.position.y = (float(high) - 0.5f) * 2.0f;
|
||||||
out.position.z = 0.0f;
|
out.position.z = 0.0f;
|
||||||
|
|
45
src/Ryujinx.Graphics.Metal/Shaders/BlitMs.metal
Normal file
45
src/Ryujinx.Graphics.Metal/Shaders/BlitMs.metal
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#include <metal_stdlib>
|
||||||
|
|
||||||
|
using namespace metal;
|
||||||
|
|
||||||
|
struct CopyVertexOut {
|
||||||
|
float4 position [[position]];
|
||||||
|
float2 uv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TexCoords {
|
||||||
|
float data[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ConstantBuffers {
|
||||||
|
constant TexCoords* tex_coord;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Textures
|
||||||
|
{
|
||||||
|
texture2d_ms<float, access::read> texture;
|
||||||
|
};
|
||||||
|
|
||||||
|
vertex CopyVertexOut vertexMain(uint vid [[vertex_id]],
|
||||||
|
constant ConstantBuffers &constant_buffers [[buffer(20)]]) {
|
||||||
|
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 float4 fragmentMain(CopyVertexOut in [[stage_in]],
|
||||||
|
constant Textures &textures [[buffer(22)]],
|
||||||
|
uint sample_id [[sample_id]]) {
|
||||||
|
uint2 tex_size = uint2(textures.texture.get_width(), textures.texture.get_height());
|
||||||
|
uint2 tex_coord = uint2(in.uv * float2(tex_size));
|
||||||
|
return textures.texture.read(tex_coord, sample_id);
|
||||||
|
}
|
|
@ -249,14 +249,8 @@ namespace Ryujinx.Graphics.Metal
|
||||||
}
|
}
|
||||||
|
|
||||||
var dst = (Texture)destination;
|
var dst = (Texture)destination;
|
||||||
bool isDepthOrStencil = dst.Info.Format.IsDepthOrStencil();
|
|
||||||
|
|
||||||
if (dst.Info.IsCompressed)
|
Pipeline.Blit(this, dst, srcRegion, dstRegion, linearFilter);
|
||||||
{
|
|
||||||
Console.WriteLine("shit");
|
|
||||||
}
|
|
||||||
|
|
||||||
Pipeline.Blit(this, destination, srcRegion, dstRegion, isDepthOrStencil, linearFilter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CopyTo(BufferRange range, int layer, int level, int stride)
|
public void CopyTo(BufferRange range, int layer, int level, int stride)
|
||||||
|
|
Loading…
Reference in a new issue