Support multi layer with mip map in ReadTexture

This commit is contained in:
Thog 2019-02-17 17:21:32 +01:00
parent 5eda7ae7a8
commit 065d3b89bb
No known key found for this signature in database
GPG key ID: 0CD291558FAFDBC6
4 changed files with 38 additions and 15 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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)