diff --git a/Ryujinx.Graphics/Graphics3d/NvGpuEngine2d.cs b/Ryujinx.Graphics/Graphics3d/NvGpuEngine2d.cs index 9c236b848e..3295f6da05 100644 --- a/Ryujinx.Graphics/Graphics3d/NvGpuEngine2d.cs +++ b/Ryujinx.Graphics/Graphics3d/NvGpuEngine2d.cs @@ -139,7 +139,8 @@ namespace Ryujinx.Graphics.Graphics3d long GetLayerOffset(GalImage Image, int Layer) { - return (ImageUtils.GetGpuSize(Image) / Image.LayerCount) * Layer; + int TargetMipLevel = Image.MaxMipmapLevel <= 1 ? 1 : Image.MaxMipmapLevel - 1; + return ImageUtils.GetLayerOffset(Image, TargetMipLevel) * Layer; } int SrcLayerIndex = -1; diff --git a/Ryujinx.Graphics/Graphics3d/NvGpuEngine3d.cs b/Ryujinx.Graphics/Graphics3d/NvGpuEngine3d.cs index c05ad202b4..782ac03d6e 100644 --- a/Ryujinx.Graphics/Graphics3d/NvGpuEngine3d.cs +++ b/Ryujinx.Graphics/Graphics3d/NvGpuEngine3d.cs @@ -609,7 +609,7 @@ namespace Ryujinx.Graphics.Graphics3d { //FIXME: Some games like puyo puyo will use handles with the value 0. //This is a bug, most likely caused by sync issues. - //return (0, default(GalImage), default(GalTextureSampler)); + return (0, default(GalImage), default(GalTextureSampler)); } bool LinkedTsc = ReadRegisterBool(NvGpuEngine3dReg.LinkedTsc); diff --git a/Ryujinx.Graphics/Graphics3d/Texture/ImageUtils.cs b/Ryujinx.Graphics/Graphics3d/Texture/ImageUtils.cs index 3fb1822827..2a72996b05 100644 --- a/Ryujinx.Graphics/Graphics3d/Texture/ImageUtils.cs +++ b/Ryujinx.Graphics/Graphics3d/Texture/ImageUtils.cs @@ -252,25 +252,33 @@ namespace Ryujinx.Graphics.Texture //Note: Each row of the texture needs to be aligned to 4 bytes. int Pitch = (Width * BytesPerPixel + 3) & ~3; - byte[] Data = new byte[Height * Pitch * Depth]; - for (int Z = 0; Z < Depth; Z++) + + int DataLayerSize = Height * Pitch * Depth; + byte[] Data = new byte[DataLayerSize * Image.LayerCount]; + + int TargetMipLevel = Image.MaxMipmapLevel <= 1 ? 1 : Image.MaxMipmapLevel - 1; + int LayerOffset = ImageUtils.GetLayerOffset(Image, TargetMipLevel); + + for (int Layer = 0; Layer < Image.LayerCount; Layer++) { - for (int Y = 0; Y < Height; Y++) + for (int Z = 0; Z < Depth; Z++) { - int OutOffs = Y * Pitch + (Z * Width * Height * BytesPerPixel); - - for (int X = 0; X < Width; X++) + for (int Y = 0; Y < Height; Y++) { - long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y, Z); + int OutOffs = (DataLayerSize * Layer) + Y * Pitch + (Z * Width * Height * BytesPerPixel); - CpuMemory.ReadBytes(Position + Offset, Data, OutOffs, BytesPerPixel); + for (int X = 0; X < Width; X++) + { + long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y, Z); - OutOffs += BytesPerPixel; + CpuMemory.ReadBytes(Position + (LayerOffset * Layer) + Offset, Data, OutOffs, BytesPerPixel); + + OutOffs += BytesPerPixel; + } } } } - return Data; } @@ -369,6 +377,16 @@ namespace Ryujinx.Graphics.Texture return TextureHelper.GetSwizzle(Image).GetImageSize(Image.MaxMipmapLevel) * Image.LayerCount; } + public static int GetLayerOffset(GalImage Image, int MipLevel) + { + if (MipLevel <= 0) + { + MipLevel = 1; + } + + return TextureHelper.GetSwizzle(Image).GetMipOffset(MipLevel); + } + public static int GetPitch(GalImageFormat Format, int Width) { ImageDescriptor Desc = GetImageDescriptor(Format); diff --git a/Ryujinx.Graphics/Graphics3d/Texture/LinearSwizzle.cs b/Ryujinx.Graphics/Graphics3d/Texture/LinearSwizzle.cs index c09224c6ae..e6509baa6a 100644 --- a/Ryujinx.Graphics/Graphics3d/Texture/LinearSwizzle.cs +++ b/Ryujinx.Graphics/Graphics3d/Texture/LinearSwizzle.cs @@ -23,14 +23,18 @@ namespace Ryujinx.Graphics.Texture public int GetMipOffset(int Level) { + if (Level == 1) + return SliceSize; throw new NotImplementedException(); } public int GetImageSize(int MipsCount) { - if (MipsCount == 1) - return SliceSize; - throw new NotImplementedException(); + int Size = GetMipOffset(MipsCount); + + Size = (Size + 0x1fff) & ~0x1fff; + + return Size; } public int GetSwizzleOffset(int X, int Y, int Z)