aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Graphics3d/NvGpuEngine2d.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics/Graphics3d/NvGpuEngine2d.cs')
-rw-r--r--Ryujinx.Graphics/Graphics3d/NvGpuEngine2d.cs96
1 files changed, 90 insertions, 6 deletions
diff --git a/Ryujinx.Graphics/Graphics3d/NvGpuEngine2d.cs b/Ryujinx.Graphics/Graphics3d/NvGpuEngine2d.cs
index 55e3ebd4..3295f6da 100644
--- a/Ryujinx.Graphics/Graphics3d/NvGpuEngine2d.cs
+++ b/Ryujinx.Graphics/Graphics3d/NvGpuEngine2d.cs
@@ -1,3 +1,4 @@
+using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Gal;
using Ryujinx.Graphics.Memory;
using Ryujinx.Graphics.Texture;
@@ -46,6 +47,8 @@ namespace Ryujinx.Graphics.Graphics3d
bool DstLinear = ReadRegister(NvGpuEngine2dReg.DstLinear) != 0;
int DstWidth = ReadRegister(NvGpuEngine2dReg.DstWidth);
int DstHeight = ReadRegister(NvGpuEngine2dReg.DstHeight);
+ int DstDepth = ReadRegister(NvGpuEngine2dReg.DstDepth);
+ int DstLayer = ReadRegister(NvGpuEngine2dReg.DstLayer);
int DstPitch = ReadRegister(NvGpuEngine2dReg.DstPitch);
int DstBlkDim = ReadRegister(NvGpuEngine2dReg.DstBlockDimensions);
@@ -53,6 +56,8 @@ namespace Ryujinx.Graphics.Graphics3d
bool SrcLinear = ReadRegister(NvGpuEngine2dReg.SrcLinear) != 0;
int SrcWidth = ReadRegister(NvGpuEngine2dReg.SrcWidth);
int SrcHeight = ReadRegister(NvGpuEngine2dReg.SrcHeight);
+ int SrcDepth = ReadRegister(NvGpuEngine2dReg.SrcDepth);
+ int SrcLayer = ReadRegister(NvGpuEngine2dReg.SrcLayer);
int SrcPitch = ReadRegister(NvGpuEngine2dReg.SrcPitch);
int SrcBlkDim = ReadRegister(NvGpuEngine2dReg.SrcBlockDimensions);
@@ -82,26 +87,99 @@ namespace Ryujinx.Graphics.Graphics3d
long SrcKey = Vmm.GetPhysicalAddress(SrcAddress);
long DstKey = Vmm.GetPhysicalAddress(DstAddress);
+ bool IsSrcLayered = false;
+ bool IsDstLayered = false;
+
+ GalTextureTarget SrcTarget = GalTextureTarget.TwoD;
+
+ if (SrcDepth != 0)
+ {
+ SrcTarget = GalTextureTarget.TwoDArray;
+ SrcDepth++;
+ IsSrcLayered = true;
+ }
+ else
+ {
+ SrcDepth = 1;
+ }
+
+ GalTextureTarget DstTarget = GalTextureTarget.TwoD;
+
+ if (DstDepth != 0)
+ {
+ DstTarget = GalTextureTarget.TwoDArray;
+ DstDepth++;
+ IsDstLayered = true;
+ }
+ else
+ {
+ DstDepth = 1;
+ }
+
GalImage SrcTexture = new GalImage(
SrcWidth,
- SrcHeight, 1,
- SrcBlockHeight,
+ SrcHeight,
+ 1, SrcDepth, 1,
+ SrcBlockHeight, 1,
SrcLayout,
- SrcImgFormat);
+ SrcImgFormat,
+ SrcTarget);
GalImage DstTexture = new GalImage(
DstWidth,
- DstHeight, 1,
- DstBlockHeight,
+ DstHeight,
+ 1, DstDepth, 1,
+ DstBlockHeight, 1,
DstLayout,
- DstImgFormat);
+ DstImgFormat,
+ DstTarget);
SrcTexture.Pitch = SrcPitch;
DstTexture.Pitch = DstPitch;
+ long GetLayerOffset(GalImage Image, int Layer)
+ {
+ int TargetMipLevel = Image.MaxMipmapLevel <= 1 ? 1 : Image.MaxMipmapLevel - 1;
+ return ImageUtils.GetLayerOffset(Image, TargetMipLevel) * Layer;
+ }
+
+ int SrcLayerIndex = -1;
+
+ if (IsSrcLayered && Gpu.ResourceManager.TryGetTextureLayer(SrcKey, out SrcLayerIndex) && SrcLayerIndex != 0)
+ {
+ SrcKey = SrcKey - GetLayerOffset(SrcTexture, SrcLayerIndex);
+ }
+
+ int DstLayerIndex = -1;
+
+ if (IsDstLayered && Gpu.ResourceManager.TryGetTextureLayer(DstKey, out DstLayerIndex) && DstLayerIndex != 0)
+ {
+ DstKey = DstKey - GetLayerOffset(DstTexture, DstLayerIndex);
+ }
+
Gpu.ResourceManager.SendTexture(Vmm, SrcKey, SrcTexture);
Gpu.ResourceManager.SendTexture(Vmm, DstKey, DstTexture);
+ if (IsSrcLayered && SrcLayerIndex == -1)
+ {
+ for (int Layer = 0; Layer < SrcTexture.LayerCount; Layer++)
+ {
+ Gpu.ResourceManager.SetTextureArrayLayer(SrcKey + GetLayerOffset(SrcTexture, Layer), Layer);
+ }
+
+ SrcLayerIndex = 0;
+ }
+
+ if (IsDstLayered && DstLayerIndex == -1)
+ {
+ for (int Layer = 0; Layer < DstTexture.LayerCount; Layer++)
+ {
+ Gpu.ResourceManager.SetTextureArrayLayer(DstKey + GetLayerOffset(DstTexture, Layer), Layer);
+ }
+
+ DstLayerIndex = 0;
+ }
+
int SrcBlitX1 = (int)(SrcBlitX >> 32);
int SrcBlitY1 = (int)(SrcBlitY >> 32);
@@ -109,8 +187,12 @@ namespace Ryujinx.Graphics.Graphics3d
int SrcBlitY2 = (int)(SrcBlitY + DstBlitH * BlitDvDy >> 32);
Gpu.Renderer.RenderTarget.Copy(
+ SrcTexture,
+ DstTexture,
SrcKey,
DstKey,
+ SrcLayerIndex,
+ DstLayerIndex,
SrcBlitX1,
SrcBlitY1,
SrcBlitX2,
@@ -124,6 +206,8 @@ namespace Ryujinx.Graphics.Graphics3d
//the texture is modified by the guest, however it doesn't
//work when resources that the gpu can write to are copied,
//like framebuffers.
+
+ // FIXME: SUPPORT MULTILAYER CORRECTLY HERE (this will cause weird stuffs on the first layer)
ImageUtils.CopyTexture(
Vmm,
SrcTexture,