Improved GPU command lists decoding (#499)

* Better implementation of the DMA pusher, misc fixes

* Remove some debug code

* Correct RGBX8 format

* Add support for linked Texture Sampler Control

* Attempt to fix upside down screen issue
This commit is contained in:
gdkchan 2018-11-17 02:01:31 -02:00 committed by Ac_K
parent b833183ef6
commit d2bb458b51
25 changed files with 616 additions and 395 deletions

View file

@ -1,11 +1,10 @@
using Ryujinx.Graphics.Gal;
using Ryujinx.Graphics.Memory;
using Ryujinx.Graphics.Texture;
using System;
namespace Ryujinx.Graphics
{
public class NvGpuEngine2d : INvGpuEngine
class NvGpuEngine2d : INvGpuEngine
{
private enum CopyOperation
{
@ -29,11 +28,11 @@ namespace Ryujinx.Graphics
Registers = new int[0x238];
}
public void CallMethod(NvGpuVmm Vmm, NvGpuPBEntry PBEntry)
public void CallMethod(NvGpuVmm Vmm, GpuMethodCall MethCall)
{
WriteRegister(PBEntry);
WriteRegister(MethCall);
if ((NvGpuEngine2dReg)PBEntry.Method == NvGpuEngine2dReg.BlitSrcYInt)
if ((NvGpuEngine2dReg)MethCall.Method == NvGpuEngine2dReg.BlitSrcYInt)
{
TextureCopy(Vmm);
}
@ -43,6 +42,13 @@ namespace Ryujinx.Graphics
{
CopyOperation Operation = (CopyOperation)ReadRegister(NvGpuEngine2dReg.CopyOperation);
int DstFormat = ReadRegister(NvGpuEngine2dReg.DstFormat);
bool DstLinear = ReadRegister(NvGpuEngine2dReg.DstLinear) != 0;
int DstWidth = ReadRegister(NvGpuEngine2dReg.DstWidth);
int DstHeight = ReadRegister(NvGpuEngine2dReg.DstHeight);
int DstPitch = ReadRegister(NvGpuEngine2dReg.DstPitch);
int DstBlkDim = ReadRegister(NvGpuEngine2dReg.DstBlockDimensions);
int SrcFormat = ReadRegister(NvGpuEngine2dReg.SrcFormat);
bool SrcLinear = ReadRegister(NvGpuEngine2dReg.SrcLinear) != 0;
int SrcWidth = ReadRegister(NvGpuEngine2dReg.SrcWidth);
@ -50,12 +56,13 @@ namespace Ryujinx.Graphics
int SrcPitch = ReadRegister(NvGpuEngine2dReg.SrcPitch);
int SrcBlkDim = ReadRegister(NvGpuEngine2dReg.SrcBlockDimensions);
int DstFormat = ReadRegister(NvGpuEngine2dReg.DstFormat);
bool DstLinear = ReadRegister(NvGpuEngine2dReg.DstLinear) != 0;
int DstWidth = ReadRegister(NvGpuEngine2dReg.DstWidth);
int DstHeight = ReadRegister(NvGpuEngine2dReg.DstHeight);
int DstPitch = ReadRegister(NvGpuEngine2dReg.DstPitch);
int DstBlkDim = ReadRegister(NvGpuEngine2dReg.DstBlockDimensions);
int DstBlitX = ReadRegister(NvGpuEngine2dReg.BlitDstX);
int DstBlitY = ReadRegister(NvGpuEngine2dReg.BlitDstY);
int DstBlitW = ReadRegister(NvGpuEngine2dReg.BlitDstW);
int DstBlitH = ReadRegister(NvGpuEngine2dReg.BlitDstH);
int SrcBlitX = ReadRegister(NvGpuEngine2dReg.BlitSrcXInt);
int SrcBlitY = ReadRegister(NvGpuEngine2dReg.BlitSrcYInt);
GalImageFormat SrcImgFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)SrcFormat);
GalImageFormat DstImgFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)DstFormat);
@ -86,23 +93,42 @@ namespace Ryujinx.Graphics
DstLayout,
DstImgFormat);
SrcTexture.Pitch = SrcPitch;
DstTexture.Pitch = DstPitch;
Gpu.ResourceManager.SendTexture(Vmm, SrcKey, SrcTexture);
Gpu.ResourceManager.SendTexture(Vmm, DstKey, DstTexture);
int Width = Math.Min(SrcWidth, DstWidth);
int Height = Math.Min(SrcHeight, DstHeight);
Gpu.Renderer.RenderTarget.Copy(
SrcKey,
DstKey,
0,
0,
Width,
Height,
0,
0,
Width,
Height);
SrcBlitX,
SrcBlitY,
SrcBlitX + DstBlitW,
SrcBlitY + DstBlitH,
DstBlitX,
DstBlitY,
DstBlitX + DstBlitW,
DstBlitY + DstBlitH);
//Do a guest side copy aswell. This is necessary when
//the texture is modified by the guest, however it doesn't
//work when resources that the gpu can write to are copied,
//like framebuffers.
ImageUtils.CopyTexture(
Vmm,
SrcTexture,
DstTexture,
SrcAddress,
DstAddress,
SrcBlitX,
SrcBlitY,
DstBlitX,
DstBlitY,
DstBlitW,
DstBlitH);
Vmm.IsRegionModified(DstKey, ImageUtils.GetSize(DstTexture), NvGpuBufferType.Texture);
}
private static GalMemoryLayout GetLayout(bool Linear)
@ -119,14 +145,9 @@ namespace Ryujinx.Graphics
(uint)Registers[(int)Reg + 1];
}
private void WriteRegister(NvGpuPBEntry PBEntry)
private void WriteRegister(GpuMethodCall MethCall)
{
int ArgsCount = PBEntry.Arguments.Count;
if (ArgsCount > 0)
{
Registers[PBEntry.Method] = PBEntry.Arguments[ArgsCount - 1];
}
Registers[MethCall.Method] = MethCall.Argument;
}
private int ReadRegister(NvGpuEngine2dReg Reg)