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.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
|
@ -21,6 +22,7 @@ namespace Ryujinx.Graphics.Metal
|
|||
private readonly ISampler _samplerLinear;
|
||||
private readonly ISampler _samplerNearest;
|
||||
private readonly IProgram _programColorBlit;
|
||||
private readonly IProgram _programColorBlitMs;
|
||||
private readonly List<IProgram> _programsColorClear = new();
|
||||
private readonly IProgram _programDepthStencilClear;
|
||||
private readonly IProgram _programStrideChange;
|
||||
|
@ -47,6 +49,13 @@ namespace Ryujinx.Graphics.Metal
|
|||
new ShaderSource(blitSource, ShaderStage.Vertex, TargetLanguage.Msl)
|
||||
], 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()
|
||||
.Add(ResourceStages.Fragment, ResourceType.UniformBuffer, 0).Build();
|
||||
|
||||
|
@ -87,8 +96,8 @@ namespace Ryujinx.Graphics.Metal
|
|||
|
||||
public unsafe void BlitColor(
|
||||
CommandBufferScoped cbs,
|
||||
ITexture src,
|
||||
ITexture dst,
|
||||
Texture src,
|
||||
Texture dst,
|
||||
Extents2D srcRegion,
|
||||
Extents2D dstRegion,
|
||||
bool linearFilter,
|
||||
|
@ -140,7 +149,23 @@ namespace Ryujinx.Graphics.Metal
|
|||
0f,
|
||||
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 dstHeight = dst.Height;
|
||||
|
|
|
@ -193,22 +193,13 @@ namespace Ryujinx.Graphics.Metal
|
|||
}
|
||||
|
||||
public void Blit(
|
||||
ITexture src,
|
||||
ITexture dst,
|
||||
Texture src,
|
||||
Texture dst,
|
||||
Extents2D srcRegion,
|
||||
Extents2D dstRegion,
|
||||
bool isDepthOrStencil,
|
||||
bool linearFilter)
|
||||
{
|
||||
if (isDepthOrStencil)
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
_renderer.HelperShader.BlitColor(Cbs, src, dst, srcRegion, dstRegion, linearFilter);
|
||||
}
|
||||
|
||||
public void Barrier()
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Shaders\Blit.metal" />
|
||||
<EmbeddedResource Include="Shaders\BlitMs.metal" />
|
||||
<EmbeddedResource Include="Shaders\ChangeBufferStride.metal" />
|
||||
<EmbeddedResource Include="Shaders\ColorClear.metal" />
|
||||
<EmbeddedResource Include="Shaders\DepthStencilClear.metal" />
|
||||
|
|
|
@ -12,7 +12,7 @@ struct TexCoords {
|
|||
};
|
||||
|
||||
struct ConstantBuffers {
|
||||
constant TexCoords* texCoord;
|
||||
constant TexCoords* tex_coord;
|
||||
};
|
||||
|
||||
struct Textures
|
||||
|
@ -27,8 +27,8 @@ vertex CopyVertexOut vertexMain(uint vid [[vertex_id]],
|
|||
|
||||
int low = vid & 1;
|
||||
int high = vid >> 1;
|
||||
out.uv.x = constant_buffers.texCoord->data[low];
|
||||
out.uv.y = constant_buffers.texCoord->data[2 + high];
|
||||
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;
|
||||
|
|
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;
|
||||
bool isDepthOrStencil = dst.Info.Format.IsDepthOrStencil();
|
||||
|
||||
if (dst.Info.IsCompressed)
|
||||
{
|
||||
Console.WriteLine("shit");
|
||||
}
|
||||
|
||||
Pipeline.Blit(this, destination, srcRegion, dstRegion, isDepthOrStencil, linearFilter);
|
||||
Pipeline.Blit(this, dst, srcRegion, dstRegion, linearFilter);
|
||||
}
|
||||
|
||||
public void CopyTo(BufferRange range, int layer, int level, int stride)
|
||||
|
|
Loading…
Reference in a new issue