aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2022-06-17 12:01:52 -0300
committerGitHub <noreply@github.com>2022-06-17 12:01:52 -0300
commitd987cacfb720f2f4bc18958fc26ac0893903c090 (patch)
treea166e9ec7c7efd735875fe206142465c6f169eb3
parent851f56b08a0c3b420f91143b6c6c007b429174a8 (diff)
Fix VIC out of bounds copy (#3386)1.1.148
* Fix VIC out of bounds copy * Update the assert
-rw-r--r--Ryujinx.Graphics.Vic/Blender.cs23
-rw-r--r--Ryujinx.Graphics.Vic/Rectangle.cs18
-rw-r--r--Ryujinx.Graphics.Vic/VicDevice.cs15
3 files changed, 46 insertions, 10 deletions
diff --git a/Ryujinx.Graphics.Vic/Blender.cs b/Ryujinx.Graphics.Vic/Blender.cs
index 92b641d6..b6ca35ae 100644
--- a/Ryujinx.Graphics.Vic/Blender.cs
+++ b/Ryujinx.Graphics.Vic/Blender.cs
@@ -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));
diff --git a/Ryujinx.Graphics.Vic/Rectangle.cs b/Ryujinx.Graphics.Vic/Rectangle.cs
new file mode 100644
index 00000000..2a13b95c
--- /dev/null
+++ b/Ryujinx.Graphics.Vic/Rectangle.cs
@@ -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;
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Vic/VicDevice.cs b/Ryujinx.Graphics.Vic/VicDevice.cs
index 537b8ba4..8b66727d 100644
--- a/Ryujinx.Graphics.Vic/VicDevice.cs
+++ b/Ryujinx.Graphics.Vic/VicDevice.cs
@@ -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);