Size hints for copy regions and viewport dimensions to avoid data loss (#1686)
* Size hints for copy regions and viewport dimensions to avoid data loss * Reword comment. * Use info for the rule rather than calculating aligned size. * Reorder min/max, remove spaces
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Gpu.Image;
|
||||
using Ryujinx.Graphics.Gpu.State;
|
||||
using Ryujinx.Graphics.Texture;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Engine
|
||||
@ -19,9 +20,30 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||
var dstCopyTexture = state.Get<CopyTexture>(MethodOffset.CopyDstTexture);
|
||||
var srcCopyTexture = state.Get<CopyTexture>(MethodOffset.CopySrcTexture);
|
||||
|
||||
var region = state.Get<CopyRegion>(MethodOffset.CopyRegion);
|
||||
|
||||
var control = state.Get<CopyTextureControl>(MethodOffset.CopyTextureControl);
|
||||
|
||||
int srcX1 = (int)(region.SrcXF >> 32);
|
||||
int srcY1 = (int)(region.SrcYF >> 32);
|
||||
|
||||
int srcX2 = (int)((region.SrcXF + region.SrcWidthRF * region.DstWidth) >> 32);
|
||||
int srcY2 = (int)((region.SrcYF + region.SrcHeightRF * region.DstHeight) >> 32);
|
||||
|
||||
int dstX1 = region.DstX;
|
||||
int dstY1 = region.DstY;
|
||||
|
||||
int dstX2 = region.DstX + region.DstWidth;
|
||||
int dstY2 = region.DstY + region.DstHeight;
|
||||
|
||||
// The source and destination textures should at least be as big as the region being requested.
|
||||
// The hints will only resize within alignment constraints, so out of bound copies won't resize in most cases.
|
||||
var srcHint = new Size(srcX2, srcY2, 1);
|
||||
var dstHint = new Size(dstX2, dstY2, 1);
|
||||
|
||||
var srcCopyTextureFormat = srcCopyTexture.Format.Convert();
|
||||
|
||||
Texture srcTexture = TextureManager.FindOrCreateTexture(srcCopyTexture, srcCopyTextureFormat);
|
||||
Texture srcTexture = TextureManager.FindOrCreateTexture(srcCopyTexture, srcCopyTextureFormat, true, srcHint);
|
||||
|
||||
if (srcTexture == null)
|
||||
{
|
||||
@ -42,7 +64,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||
dstCopyTextureFormat = dstCopyTexture.Format.Convert();
|
||||
}
|
||||
|
||||
Texture dstTexture = TextureManager.FindOrCreateTexture(dstCopyTexture, dstCopyTextureFormat, srcTexture.ScaleMode == TextureScaleMode.Scaled);
|
||||
Texture dstTexture = TextureManager.FindOrCreateTexture(dstCopyTexture, dstCopyTextureFormat, srcTexture.ScaleMode == TextureScaleMode.Scaled, dstHint);
|
||||
|
||||
if (dstTexture == null)
|
||||
{
|
||||
@ -54,22 +76,6 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||
srcTexture.PropagateScale(dstTexture);
|
||||
}
|
||||
|
||||
var control = state.Get<CopyTextureControl>(MethodOffset.CopyTextureControl);
|
||||
|
||||
var region = state.Get<CopyRegion>(MethodOffset.CopyRegion);
|
||||
|
||||
int srcX1 = (int)(region.SrcXF >> 32);
|
||||
int srcY1 = (int)(region.SrcYF >> 32);
|
||||
|
||||
int srcX2 = (int)((region.SrcXF + region.SrcWidthRF * region.DstWidth) >> 32);
|
||||
int srcY2 = (int)((region.SrcYF + region.SrcHeightRF * region.DstHeight) >> 32);
|
||||
|
||||
int dstX1 = region.DstX;
|
||||
int dstY1 = region.DstY;
|
||||
|
||||
int dstX2 = region.DstX + region.DstWidth;
|
||||
int dstY2 = region.DstY + region.DstHeight;
|
||||
|
||||
float scale = srcTexture.ScaleFactor; // src and dest scales are identical now.
|
||||
|
||||
Extents2D srcRegion = new Extents2D(
|
||||
@ -100,7 +106,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||
{
|
||||
srcCopyTexture.Height++;
|
||||
|
||||
srcTexture = TextureManager.FindOrCreateTexture(srcCopyTexture, srcCopyTextureFormat, srcTexture.ScaleMode == TextureScaleMode.Scaled);
|
||||
srcTexture = TextureManager.FindOrCreateTexture(srcCopyTexture, srcCopyTextureFormat, srcTexture.ScaleMode == TextureScaleMode.Scaled, srcHint);
|
||||
if (srcTexture.ScaleFactor != dstTexture.ScaleFactor)
|
||||
{
|
||||
srcTexture.PropagateScale(dstTexture);
|
||||
|
@ -5,6 +5,7 @@ using Ryujinx.Graphics.Gpu.Memory;
|
||||
using Ryujinx.Graphics.Gpu.Shader;
|
||||
using Ryujinx.Graphics.Gpu.State;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
using Ryujinx.Graphics.Texture;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
@ -354,6 +355,9 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||
int samplesInX = msaaMode.SamplesInX();
|
||||
int samplesInY = msaaMode.SamplesInY();
|
||||
|
||||
var extents = state.Get<ViewportExtents>(MethodOffset.ViewportExtents, 0);
|
||||
Size sizeHint = new Size(extents.X + extents.Width, extents.Y + extents.Height, 1);
|
||||
|
||||
bool changedScale = false;
|
||||
|
||||
for (int index = 0; index < Constants.TotalRenderTargets; index++)
|
||||
@ -369,7 +373,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||
continue;
|
||||
}
|
||||
|
||||
Texture color = TextureManager.FindOrCreateTexture(colorState, samplesInX, samplesInY);
|
||||
Texture color = TextureManager.FindOrCreateTexture(colorState, samplesInX, samplesInY, sizeHint);
|
||||
|
||||
changedScale |= TextureManager.SetRenderTargetColor(index, color);
|
||||
|
||||
@ -388,7 +392,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||
var dsState = state.Get<RtDepthStencilState>(MethodOffset.RtDepthStencilState);
|
||||
var dsSize = state.Get<Size3D>(MethodOffset.RtDepthStencilSize);
|
||||
|
||||
depthStencil = TextureManager.FindOrCreateTexture(dsState, dsSize, samplesInX, samplesInY);
|
||||
depthStencil = TextureManager.FindOrCreateTexture(dsState, dsSize, samplesInX, samplesInY, sizeHint);
|
||||
}
|
||||
|
||||
changedScale |= TextureManager.SetRenderTargetDepthStencil(depthStencil);
|
||||
|
Reference in New Issue
Block a user