Fix VIC out of bounds copy (#3386)

* Fix VIC out of bounds copy

* Update the assert
This commit is contained in:
gdkchan 2022-06-17 12:01:52 -03:00 committed by GitHub
parent 851f56b08a
commit d987cacfb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 10 deletions

View File

@ -10,17 +10,22 @@ namespace Ryujinx.Graphics.Vic
{
static class Blender
{
public static void BlendOne(Surface dst, Surface src, ref SlotStruct slot)
public static void BlendOne(Surface dst, Surface src, ref SlotStruct slot, Rectangle targetRect)
{
if (Sse41.IsSupported && (dst.Width & 3) == 0)
int x1 = targetRect.X;
int y1 = targetRect.Y;
int x2 = Math.Min(src.Width, x1 + targetRect.Width);
int y2 = Math.Min(src.Height, y1 + targetRect.Height);
if (Sse41.IsSupported && ((x1 | x2) & 3) == 0)
{
BlendOneSse41(dst, src, ref slot);
BlendOneSse41(dst, src, ref slot, x1, y1, x2, y2);
return;
}
for (int y = 0; y < dst.Height; y++)
for (int y = y1; y < y2; y++)
{
for (int x = 0; x < dst.Width; x++)
for (int x = x1; x < x2; x++)
{
int inR = src.GetR(x, y);
int inG = src.GetG(x, y);
@ -40,9 +45,9 @@ namespace Ryujinx.Graphics.Vic
}
}
private unsafe static void BlendOneSse41(Surface dst, Surface src, ref SlotStruct slot)
private unsafe static void BlendOneSse41(Surface dst, Surface src, ref SlotStruct slot, int x1, int y1, int x2, int y2)
{
Debug.Assert((dst.Width & 3) == 0);
Debug.Assert(((x1 | x2) & 3) == 0);
ref MatrixStruct mtx = ref slot.ColorMatrixStruct;
@ -62,9 +67,9 @@ namespace Ryujinx.Graphics.Vic
Pixel* ip = srcPtr;
Pixel* op = dstPtr;
for (int y = 0; y < dst.Height; y++, ip += src.Width, op += dst.Width)
for (int y = y1; y < y2; y++, ip += src.Width, op += dst.Width)
{
for (int x = 0; x < dst.Width; x += 4)
for (int x = x1; x < x2; x += 4)
{
Vector128<int> pixel1 = Sse41.ConvertToVector128Int32((ushort*)(ip + (uint)x));
Vector128<int> pixel2 = Sse41.ConvertToVector128Int32((ushort*)(ip + (uint)x + 1));

View File

@ -0,0 +1,18 @@
namespace Ryujinx.Graphics.Vic
{
struct Rectangle
{
public readonly int X;
public readonly int Y;
public readonly int Width;
public readonly int Height;
public Rectangle(int x, int y, int width, int height)
{
X = x;
Y = y;
Width = width;
Height = height;
}
}
}

View File

@ -2,6 +2,7 @@
using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.Graphics.Vic.Image;
using Ryujinx.Graphics.Vic.Types;
using System;
using System.Collections.Generic;
namespace Ryujinx.Graphics.Vic
@ -47,7 +48,19 @@ namespace Ryujinx.Graphics.Vic
using Surface src = SurfaceReader.Read(_rm, ref slot.SlotConfig, ref slot.SlotSurfaceConfig, ref offsets);
Blender.BlendOne(output, src, ref slot);
int x1 = config.OutputConfig.TargetRectLeft;
int y1 = config.OutputConfig.TargetRectTop;
int x2 = config.OutputConfig.TargetRectRight + 1;
int y2 = config.OutputConfig.TargetRectBottom + 1;
int targetX = Math.Min(x1, x2);
int targetY = Math.Min(y1, y2);
int targetW = Math.Min(output.Width - targetX, Math.Abs(x2 - x1));
int targetH = Math.Min(output.Height - targetY, Math.Abs(y2 - y1));
Rectangle targetRect = new Rectangle(targetX, targetY, targetW, targetH);
Blender.BlendOne(output, src, ref slot, targetRect);
}
SurfaceWriter.Write(_rm, output, ref config.OutputSurfaceConfig, ref _state.State.SetOutputSurface);